Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
fix memleaks
[simgrid.git] / testsuite / xbt / ex_test.c
1 /*
2 **  OSSP ex - Exception Handling
3 **  Copyright (c) 2002-2004 Ralf S. Engelschall <rse@engelschall.com>
4 **  Copyright (c) 2002-2004 The OSSP Project <http://www.ossp.org/>
5 **  Copyright (c) 2002-2004 Cable & Wireless <http://www.cw.com/>
6 **
7 **  This file is part of OSSP ex, an exception handling library
8 **  which can be found at http://www.ossp.org/pkg/lib/ex/.
9 **
10 **  Permission to use, copy, modify, and distribute this software for
11 **  any purpose with or without fee is hereby granted, provided that
12 **  the above copyright notice and this permission notice appear in all
13 **  copies.
14 **
15 **  THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
16 **  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
17 **  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18 **  IN NO EVENT SHALL THE AUTHORS AND COPYRIGHT HOLDERS AND THEIR
19 **  CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
20 **  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
21 **  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
22 **  USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 **  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
24 **  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
25 **  OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 **  SUCH DAMAGE.
27 **
28 **  ex_test.c: exception handling test suite
29 */
30
31 #include <stdio.h>
32 #include <stdlib.h>
33 #include <time.h>
34 #include <string.h>
35
36 #include "ex_test_ts.h"
37 #include "xbt/ex.h"
38 #include "xbt/log.h"
39
40 XBT_LOG_NEW_CATEGORY(test,"This test");
41
42 TS_TEST(test_controlflow)
43 {
44     xbt_ex_t ex;
45     volatile int n;
46
47     ts_test_check(TS_CTX, "basic nested control flow");
48     n = 1;
49     TRY {
50         if (n != 1)
51             ts_test_fail(TS_CTX, "M1: n=%d (!= 1)", n);
52         n++;
53         TRY {
54             if (n != 2)
55                 ts_test_fail(TS_CTX, "M2: n=%d (!= 2)", n);
56             n++;
57             THROW0(unknown_error,0,"something");
58         } CATCH (ex) {
59             if (n != 3)
60                 ts_test_fail(TS_CTX, "M3: n=%d (!= 1)", n);
61             n++;
62             RETHROW;
63         }
64         ts_test_fail(TS_CTX, "MX: n=%d (expected: not reached)", n);
65     }
66     CATCH(ex) {
67         if (n != 4)
68             ts_test_fail(TS_CTX, "M4: n=%d (!= 4)", n);
69         n++;
70         xbt_ex_free(ex);
71     }
72     if (n != 5)
73         ts_test_fail(TS_CTX, "M5: n=%d (!= 5)", n);
74 }
75
76 TS_TEST(test_value)
77 {
78     xbt_ex_t ex;
79
80     TRY {
81         THROW0(unknown_error, 2, "toto");
82     } CATCH(ex) {
83         ts_test_check(TS_CTX, "exception value passing");
84         if (ex.category != unknown_error)
85             ts_test_fail(TS_CTX, "category=%d (!= 1)", ex.category);
86         if (ex.value != 2)
87             ts_test_fail(TS_CTX, "value=%d (!= 2)", ex.value);
88         if (strcmp(ex.msg,"toto"))
89             ts_test_fail(TS_CTX, "message=%s (!= toto)", ex.msg);
90         xbt_ex_free(ex);
91     }
92 }
93
94 TS_TEST(test_variables)
95 {
96     xbt_ex_t ex;
97     int r1, r2;
98     volatile int v1, v2;
99
100     r1 = r2 = v1 = v2 = 1234;
101     TRY {
102         r2 = 5678;
103         v2 = 5678;
104         THROW0(unknown_error, 0, "toto");
105     } CATCH(ex) {
106         ts_test_check(TS_CTX, "variable preservation");
107         if (r1 != 1234)
108             ts_test_fail(TS_CTX, "r1=%d (!= 1234)", r1);
109         if (v1 != 1234)
110             ts_test_fail(TS_CTX, "v1=%d (!= 1234)", v1);
111         /* r2 is allowed to be destroyed because not volatile */
112         if (v2 != 5678)
113             ts_test_fail(TS_CTX, "v2=%d (!= 5678)", v2);
114         xbt_ex_free(ex);
115     }
116 }
117
118 TS_TEST(test_cleanup)
119 {
120     xbt_ex_t ex;
121     volatile int v1;
122     int c;
123
124     ts_test_check(TS_CTX, "cleanup handling");
125
126     v1 = 1234;
127     c = 0;
128     TRY {
129         v1 = 5678;
130         THROW0(1, 2, "blah");
131     } CLEANUP {
132         if (v1 != 5678)
133             ts_test_fail(TS_CTX, "v1 = %d (!= 5678)", v1);
134         c = 1;
135     } CATCH(ex) {
136         if (v1 != 5678)
137             ts_test_fail(TS_CTX, "v1 = %d (!= 5678)", v1);
138         if (!(ex.category == 1 && ex.value == 2 && !strcmp(ex.msg,"blah")))
139             ts_test_fail(TS_CTX, "unexpected exception contents");
140         xbt_ex_free(ex);
141     }
142     if (!c)
143         ts_test_fail(TS_CTX, "ex_cleanup not executed");
144 }
145
146 int main(int argc, char *argv[])
147 {
148     ts_suite_t *ts;
149     int n;
150
151     ts = ts_suite_new("OSSP ex (Exception Handling)");
152     ts_suite_test(ts, test_controlflow, "basic nested control flow");
153     ts_suite_test(ts, test_value,       "exception value passing");
154     ts_suite_test(ts, test_variables,   "variable value preservation");
155     ts_suite_test(ts, test_cleanup,     "cleanup handling");
156     n = ts_suite_run(ts);
157     ts_suite_free(ts);
158     return n;
159 }
160
161
162 /*
163  * The following is the example included in the documentation. It's a good 
164  * idea to check its syntax even if we don't try to run it.
165  * And actually, it allows to put comments in the code despite doxygen.
166  */ 
167 static char *mallocex(int size) {
168   return NULL;
169 }
170 #define SMALLAMOUNT 10
171 #define TOOBIG 100000000
172
173 #if 0 /* this contains syntax errors, actually */
174 static void bad_example(void) {
175   struct {char*first;} *globalcontext;
176   ex_t ex;
177
178   /* BAD_EXAMPLE */
179   TRY {
180     char *cp1, *cp2, *cp3;
181     
182     cp1 = mallocex(SMALLAMOUNT);
183     globalcontext->first = cp1;
184     cp2 = mallocex(TOOBIG);
185     cp3 = mallocex(SMALLAMOUNT);
186     strcpy(cp1, "foo");
187     strcpy(cp2, "bar");
188   } CLEANUP {
189     if (cp3 != NULL) free(cp3);
190     if (cp2 != NULL) free(cp2);
191     if (cp1 != NULL) free(cp1);
192   } CATCH(ex) {
193     printf("cp3=%s", cp3);
194     RETHROW;
195   }
196   /* end_of_bad_example */
197 }
198 #endif
199
200 static void good_example(void) {
201   struct {char*first;} *globalcontext;
202   xbt_ex_t ex;
203
204   /* GOOD_EXAMPLE */
205   { /*01*/
206     char * volatile /*03*/ cp1 = NULL /*02*/;
207     char * volatile /*03*/ cp2 = NULL /*02*/;
208     char * volatile /*03*/ cp3 = NULL /*02*/;
209     TRY {
210       cp1 = mallocex(SMALLAMOUNT);
211       globalcontext->first = cp1;
212       cp1 = NULL /*05 give away*/;
213       cp2 = mallocex(TOOBIG);
214       cp3 = mallocex(SMALLAMOUNT);
215       strcpy(cp1, "foo");
216       strcpy(cp2, "bar");
217     } CLEANUP { /*04*/
218       printf("cp3=%s", cp3 == NULL /*02*/ ? "" : cp3);
219       if (cp3 != NULL)
220         free(cp3);
221       if (cp2 != NULL)
222         free(cp2);
223       /*05 cp1 was given away */
224     } CATCH(ex) {
225       /*05 global context untouched */
226       RETHROW;
227     }
228   }
229   /* end_of_good_example */
230 }