Logo AND Algorithmique Numérique Distribuée

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