Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
78b2f5797dc4e3e65068c7070f730fc172cc5c6a
[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 "xbt/cunit.h"
32 #include "xbt/ex.h"
33 #include "xbt/log.h"
34
35 XBT_LOG_NEW_CATEGORY(test,"This test");
36
37 XBT_TEST_UNIT(test_expected_failure) {
38     xbt_test0("Skipped test");
39     xbt_test_skip();
40
41     xbt_test0("EXPECTED FAILURE");
42     xbt_test_expect_failure();
43     xbt_test_log2("%s %s","Test","log");
44     xbt_test_fail0("EXPECTED FAILURE");
45 }
46
47 XBT_TEST_UNIT(test_controlflow) {
48     xbt_ex_t ex;
49     volatile int n=1;
50
51     xbt_test0("basic nested control flow");
52
53     TRY {
54         if (n != 1)
55             xbt_test_fail1("M1: n=%d (!= 1)", n);
56         n++;
57         TRY {
58             if (n != 2)
59                 xbt_test_fail1("M2: n=%d (!= 2)", n);
60             n++;
61             THROW0(unknown_error,0,"something");
62         } CATCH (ex) {
63             if (n != 3)
64                 xbt_test_fail1("M3: n=%d (!= 1)", n);
65             n++;
66             RETHROW;
67         }
68         xbt_test_fail1("MX: n=%d (shouldn't reach this point)", n);
69     }
70     CATCH(ex) {
71         if (n != 4)
72             xbt_test_fail1("M4: n=%d (!= 4)", n);
73         n++;
74         xbt_ex_free(ex);
75     }
76     if (n != 5)
77         xbt_test_fail1("M5: n=%d (!= 5)", n);
78 }
79
80 XBT_TEST_UNIT(test_value) {
81     xbt_ex_t ex;
82
83     TRY {
84         THROW0(unknown_error, 2, "toto");
85     } CATCH(ex) {
86         xbt_test0("exception value passing");
87         if (ex.category != unknown_error)
88             xbt_test_fail1("category=%d (!= 1)", ex.category);
89         if (ex.value != 2)
90             xbt_test_fail1("value=%d (!= 2)", ex.value);
91         if (strcmp(ex.msg,"toto"))
92             xbt_test_fail1("message=%s (!= toto)", ex.msg);
93         xbt_ex_free(ex);
94     }
95 }
96
97 XBT_TEST_UNIT(test_variables) {
98     xbt_ex_t ex;
99     int r1, r2;
100     volatile int v1, v2;
101
102     r1 = r2 = v1 = v2 = 1234;
103     TRY {
104         r2 = 5678;
105         v2 = 5678;
106         THROW0(unknown_error, 0, "toto");
107     } CATCH(ex) {
108         xbt_test0("variable preservation");
109         if (r1 != 1234)
110             xbt_test_fail1("r1=%d (!= 1234)", r1);
111         if (v1 != 1234)
112             xbt_test_fail1("v1=%d (!= 1234)", v1);
113         /* r2 is allowed to be destroyed because not volatile */
114         if (v2 != 5678)
115             xbt_test_fail1("v2=%d (!= 5678)", v2);
116         xbt_ex_free(ex);
117     }
118 }
119
120 XBT_TEST_UNIT(test_cleanup) {
121     xbt_ex_t ex;
122     volatile int v1;
123     int c;
124
125     xbt_test0("cleanup handling");
126
127     v1 = 1234;
128     c = 0;
129     TRY {
130         v1 = 5678;
131         THROW0(1, 2, "blah");
132     } CLEANUP {
133         if (v1 != 5678)
134             xbt_test_fail1("v1 = %d (!= 5678)", v1);
135         c = 1;
136     } CATCH(ex) {
137         if (v1 != 5678)
138             xbt_test_fail1("v1 = %d (!= 5678)", v1);
139         if (!(ex.category == 1 && ex.value == 2 && !strcmp(ex.msg,"blah")))
140             xbt_test_fail0("unexpected exception contents");
141         xbt_ex_free(ex);
142     }
143     if (!c)
144         xbt_test_fail0("xbt_ex_free not executed");
145 }
146
147 int main(int argc, char *argv[]) {
148     xbt_test_suite_t suite;
149
150     suite = xbt_test_suite_new("Testsuite Autotest");
151     xbt_test_suite_push(suite, test_expected_failure, "expected failures");
152     
153     suite = xbt_test_suite_new("Exception Handling");
154     xbt_test_suite_push(suite, test_controlflow, "basic nested control flow");
155     xbt_test_suite_push(suite, test_value,       "exception value passing");
156     xbt_test_suite_push(suite, test_variables,   "variable value preservation");
157     xbt_test_suite_push(suite, test_cleanup,     "cleanup handling");
158
159     return xbt_test_run();
160 }
161
162
163 /*
164  * The following is the example included in the documentation. It's a good 
165  * idea to check its syntax even if we don't try to run it.
166  * And actually, it allows to put comments in the code despite doxygen.
167  */ 
168 static char *mallocex(int size) {
169   return NULL;
170 }
171 #define SMALLAMOUNT 10
172 #define TOOBIG 100000000
173
174 #if 0 /* this contains syntax errors, actually */
175 static void bad_example(void) {
176   struct {char*first;} *globalcontext;
177   ex_t ex;
178
179   /* BAD_EXAMPLE */
180   TRY {
181     char *cp1, *cp2, *cp3;
182     
183     cp1 = mallocex(SMALLAMOUNT);
184     globalcontext->first = cp1;
185     cp2 = mallocex(TOOBIG);
186     cp3 = mallocex(SMALLAMOUNT);
187     strcpy(cp1, "foo");
188     strcpy(cp2, "bar");
189   } CLEANUP {
190     if (cp3 != NULL) free(cp3);
191     if (cp2 != NULL) free(cp2);
192     if (cp1 != NULL) free(cp1);
193   } CATCH(ex) {
194     printf("cp3=%s", cp3);
195     RETHROW;
196   }
197   /* end_of_bad_example */
198 }
199 #endif
200
201 static void good_example(void) {
202   struct {char*first;} *globalcontext;
203   xbt_ex_t ex;
204
205   /* GOOD_EXAMPLE */
206   { /*01*/
207     char * volatile /*03*/ cp1 = NULL /*02*/;
208     char * volatile /*03*/ cp2 = NULL /*02*/;
209     char * volatile /*03*/ cp3 = NULL /*02*/;
210     TRY {
211       cp1 = mallocex(SMALLAMOUNT);
212       globalcontext->first = cp1;
213       cp1 = NULL /*05 give away*/;
214       cp2 = mallocex(TOOBIG);
215       cp3 = mallocex(SMALLAMOUNT);
216       strcpy(cp1, "foo");
217       strcpy(cp2, "bar");
218     } CLEANUP { /*04*/
219       printf("cp3=%s", cp3 == NULL /*02*/ ? "" : cp3);
220       if (cp3 != NULL)
221         free(cp3);
222       if (cp2 != NULL)
223         free(cp2);
224       /*05 cp1 was given away */
225     } CATCH(ex) {
226       /*05 global context untouched */
227       RETHROW;
228     }
229   }
230   /* end_of_good_example */
231 }