Logo AND Algorithmique Numérique Distribuée

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