|
1 /* This Source Code Form is subject to the terms of the Mozilla Public |
|
2 * License, v. 2.0. If a copy of the MPL was not distributed with this |
|
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
|
4 /* |
|
5 * testutil.h |
|
6 * |
|
7 * Utility functions for handling test errors |
|
8 * |
|
9 */ |
|
10 |
|
11 #ifndef _TESTUTIL_H |
|
12 #define _TESTUTIL_H |
|
13 |
|
14 #include "pkix.h" |
|
15 #include "plstr.h" |
|
16 #include "prprf.h" |
|
17 #include "prlong.h" |
|
18 #include "pkix_pl_common.h" |
|
19 #include "secutil.h" |
|
20 #include <stdio.h> |
|
21 #include <ctype.h> |
|
22 |
|
23 #ifdef __cplusplus |
|
24 extern "C" { |
|
25 #endif |
|
26 |
|
27 /* |
|
28 * In order to have a consistent format for displaying test information, |
|
29 * all tests are REQUIRED to use the functions provided by this library |
|
30 * (libtestutil.a) for displaying their information. |
|
31 * |
|
32 * A test using this library begins with a call to startTests with the test |
|
33 * name as the arg (which is used only for formatting). Before the first |
|
34 * subtest, a call to subTest should be made with the subtest name as the arg |
|
35 * (again, for formatting). If the subTest is successful, then no action |
|
36 * is needed. However, if the subTest is not successful, then a call |
|
37 * to testError should be made with a descriptive error message as the arg. |
|
38 * Note that a subTest MUST NOT call testError more than once. |
|
39 * Finally, a call to endTests is made with the test name as the arg (for |
|
40 * formatting). Note that most of these macros assume that a variable named |
|
41 * "plContext" of type (void *) has been defined by the test. As such, it |
|
42 * is essential that the test satisfy this condition. |
|
43 */ |
|
44 |
|
45 /* |
|
46 * PKIX_TEST_STD_VARS should be called at the beginning of every function |
|
47 * that uses PKIX_TEST_RETURN (e.g. subTests), but it should be called only |
|
48 * AFTER declaring local variables (so we don't get compiler warnings about |
|
49 * declarations after statements). PKIX_TEST_STD_VARS declares and initializes |
|
50 * several variables needed by the other test macros. |
|
51 */ |
|
52 #define PKIX_TEST_STD_VARS() \ |
|
53 PKIX_Error *pkixTestErrorResult = NULL; \ |
|
54 char *pkixTestErrorMsg = NULL; |
|
55 |
|
56 /* |
|
57 * PKIX_TEST_EXPECT_NO_ERROR should be used to wrap a standard PKIX function |
|
58 * call (one which returns a pointer to PKIX_Error) that is expected to return |
|
59 * NULL (i.e. to succeed). If "pkixTestErrorResult" is not NULL, |
|
60 * "goto cleanup" is executed, where a testError call is made if there were |
|
61 * unexpected results. This macro MUST NOT be called after the "cleanup" label. |
|
62 * |
|
63 * Example Usage: PKIX_TEST_EXPECT_NO_ERROR(pkixFunc_expected_to_succeed(...)); |
|
64 */ |
|
65 |
|
66 #define PKIX_TEST_EXPECT_NO_ERROR(func) \ |
|
67 do { \ |
|
68 pkixTestErrorResult = (func); \ |
|
69 if (pkixTestErrorResult) { \ |
|
70 goto cleanup; \ |
|
71 } \ |
|
72 } while (0) |
|
73 |
|
74 /* |
|
75 * PKIX_TEST_EXPECT_ERROR should be used to wrap a standard PKIX function call |
|
76 * (one which returns a pointer to PKIX_Error) that is expected to return |
|
77 * a non-NULL value (i.e. to fail). If "pkixTestErrorResult" is NULL, |
|
78 * "pkixTestErrorMsg" is set to a standard string and "goto cleanup" |
|
79 * is executed, where a testError call is made if there were unexpected |
|
80 * results. This macro MUST NOT be called after the "cleanup" label. |
|
81 * |
|
82 * Example Usage: PKIX_TEST_EXPECT_ERROR(pkixFunc_expected_to_fail(...)); |
|
83 */ |
|
84 |
|
85 #define PKIX_TEST_EXPECT_ERROR(func) \ |
|
86 do { \ |
|
87 pkixTestErrorResult = (func); \ |
|
88 if (!pkixTestErrorResult){ \ |
|
89 pkixTestErrorMsg = \ |
|
90 "Should have thrown an error here."; \ |
|
91 goto cleanup; \ |
|
92 } \ |
|
93 PKIX_TEST_DECREF_BC(pkixTestErrorResult); \ |
|
94 } while (0) |
|
95 |
|
96 /* |
|
97 * PKIX_TEST_DECREF_BC is a convenience macro which should only be called |
|
98 * BEFORE the "cleanup" label ("BC"). If the input parameter is non-NULL, it |
|
99 * DecRefs the input parameter and wraps the function with |
|
100 * PKIX_TEST_EXPECT_NO_ERROR, which executes "goto cleanup" upon error. |
|
101 * This macro MUST NOT be called after the "cleanup" label. |
|
102 */ |
|
103 |
|
104 #define PKIX_TEST_DECREF_BC(obj) \ |
|
105 do { \ |
|
106 if (obj){ \ |
|
107 PKIX_TEST_EXPECT_NO_ERROR \ |
|
108 (PKIX_PL_Object_DecRef \ |
|
109 ((PKIX_PL_Object*)(obj), plContext)); \ |
|
110 obj = NULL; \ |
|
111 } \ |
|
112 } while (0) |
|
113 |
|
114 /* |
|
115 * PKIX_TEST_DECREF_AC is a convenience macro which should only be called |
|
116 * AFTER the "cleanup" label ("AC"). If the input parameter is non-NULL, it |
|
117 * DecRefs the input parameter. A pkixTestTempResult variable is used to prevent |
|
118 * incorrectly overwriting pkixTestErrorResult with NULL. |
|
119 * In the case DecRef succeeds, pkixTestTempResult will be NULL, and we won't |
|
120 * overwrite a previously set pkixTestErrorResult (if any). If DecRef fails, |
|
121 * then we do want to overwrite a previously set pkixTestErrorResult since a |
|
122 * DecRef failure is fatal and may be indicative of memory corruption. |
|
123 */ |
|
124 |
|
125 #define PKIX_TEST_DECREF_AC(obj) \ |
|
126 do { \ |
|
127 if (obj){ \ |
|
128 PKIX_Error *pkixTestTempResult = NULL; \ |
|
129 pkixTestTempResult = \ |
|
130 PKIX_PL_Object_DecRef \ |
|
131 ((PKIX_PL_Object*)(obj), plContext); \ |
|
132 if (pkixTestTempResult) \ |
|
133 pkixTestErrorResult = pkixTestTempResult; \ |
|
134 obj = NULL; \ |
|
135 } \ |
|
136 } while (0) |
|
137 |
|
138 /* |
|
139 * PKIX_TEST_RETURN must always be AFTER the "cleanup" label. It does nothing |
|
140 * if everything went as expected. However, if there were unexpected results, |
|
141 * PKIX_TEST_RETURN calls testError, which displays a standard failure message |
|
142 * and increments the number of subtests that have failed. In the case |
|
143 * of an unexpected error, testError is called using the error's description |
|
144 * as an input and the error is DecRef'd. In the case of unexpected success |
|
145 * testError is called with a standard string. |
|
146 */ |
|
147 #define PKIX_TEST_RETURN() \ |
|
148 { \ |
|
149 if (pkixTestErrorMsg){ \ |
|
150 testError(pkixTestErrorMsg); \ |
|
151 } else if (pkixTestErrorResult){ \ |
|
152 pkixTestErrorMsg = \ |
|
153 PKIX_Error2ASCII \ |
|
154 (pkixTestErrorResult, plContext); \ |
|
155 if (pkixTestErrorMsg) { \ |
|
156 testError(pkixTestErrorMsg); \ |
|
157 PKIX_PL_Free \ |
|
158 ((PKIX_PL_Object *)pkixTestErrorMsg, \ |
|
159 plContext); \ |
|
160 } else { \ |
|
161 testError("PKIX_Error2ASCII Failed"); \ |
|
162 } \ |
|
163 if (pkixTestErrorResult != PKIX_ALLOC_ERROR()){ \ |
|
164 PKIX_PL_Object_DecRef \ |
|
165 ((PKIX_PL_Object*)pkixTestErrorResult, \ |
|
166 plContext); \ |
|
167 pkixTestErrorResult = NULL; \ |
|
168 } \ |
|
169 } \ |
|
170 } |
|
171 |
|
172 /* |
|
173 * PKIX_TEST_EQ_HASH_TOSTR_DUP is a convenience macro which executes the |
|
174 * standard set of operations that test the Equals, Hashcode, ToString, and |
|
175 * Duplicate functions of an object type. The goodObj, equalObj, and diffObj |
|
176 * are as the names suggest. The expAscii parameter is the expected result of |
|
177 * calling ToString on the goodObj. If expAscii is NULL, then ToString will |
|
178 * not be called on the goodObj. The checkDuplicate parameter is treated as |
|
179 * a Boolean to indicate whether the Duplicate function should be tested. If |
|
180 * checkDuplicate is NULL, then Duplicate will not be called on the goodObj. |
|
181 * The type is the name of the function's family. For example, if the type is |
|
182 * Cert, this macro will call PKIX_PL_Cert_Equals, PKIX_PL_Cert_Hashcode, and |
|
183 * PKIX_PL_Cert_ToString. |
|
184 * |
|
185 * Note: If goodObj uses the default Equals and Hashcode functions, then |
|
186 * for goodObj and equalObj to be equal, they must have the same pointer value. |
|
187 */ |
|
188 #define PKIX_TEST_EQ_HASH_TOSTR_DUP(goodObj, equalObj, diffObj, \ |
|
189 expAscii, type, checkDuplicate) \ |
|
190 do { \ |
|
191 subTest("PKIX_PL_" #type "_Equals <match>"); \ |
|
192 testEqualsHelper \ |
|
193 ((PKIX_PL_Object *)(goodObj), \ |
|
194 (PKIX_PL_Object *)(equalObj), \ |
|
195 PKIX_TRUE, \ |
|
196 plContext); \ |
|
197 subTest("PKIX_PL_" #type "_Hashcode <match>"); \ |
|
198 testHashcodeHelper \ |
|
199 ((PKIX_PL_Object *)(goodObj), \ |
|
200 (PKIX_PL_Object *)(equalObj), \ |
|
201 PKIX_TRUE, \ |
|
202 plContext); \ |
|
203 subTest("PKIX_PL_" #type "_Equals <non-match>"); \ |
|
204 testEqualsHelper \ |
|
205 ((PKIX_PL_Object *)(goodObj), \ |
|
206 (PKIX_PL_Object *)(diffObj), \ |
|
207 PKIX_FALSE, \ |
|
208 plContext); \ |
|
209 subTest("PKIX_PL_" #type "_Hashcode <non-match>"); \ |
|
210 testHashcodeHelper \ |
|
211 ((PKIX_PL_Object *)(goodObj), \ |
|
212 (PKIX_PL_Object *)(diffObj), \ |
|
213 PKIX_FALSE, \ |
|
214 plContext); \ |
|
215 if (expAscii){ \ |
|
216 subTest("PKIX_PL_" #type "_ToString"); \ |
|
217 testToStringHelper \ |
|
218 ((PKIX_PL_Object *)(goodObj), \ |
|
219 (expAscii), \ |
|
220 plContext); } \ |
|
221 if (checkDuplicate){ \ |
|
222 subTest("PKIX_PL_" #type "_Duplicate"); \ |
|
223 testDuplicateHelper \ |
|
224 ((PKIX_PL_Object *)goodObj, plContext); } \ |
|
225 } while (0) |
|
226 |
|
227 /* |
|
228 * PKIX_TEST_DECREF_BC is a convenience macro which should only be called |
|
229 * BEFORE the "cleanup" label ("BC"). If the input parameter is non-NULL, it |
|
230 * DecRefs the input parameter and wraps the function with |
|
231 * PKIX_TEST_EXPECT_NO_ERROR, which executes "goto cleanup" upon error. |
|
232 * This macro MUST NOT be called after the "cleanup" label. |
|
233 */ |
|
234 |
|
235 #define PKIX_TEST_ABORT_ON_NULL(obj) \ |
|
236 do { \ |
|
237 if (!obj){ \ |
|
238 goto cleanup; \ |
|
239 } \ |
|
240 } while (0) |
|
241 |
|
242 #define PKIX_TEST_ARENAS_ARG(arena) \ |
|
243 (arena? \ |
|
244 (PORT_Strcmp(arena, "arenas") ? PKIX_FALSE : (j++, PKIX_TRUE)): \ |
|
245 PKIX_FALSE) |
|
246 |
|
247 #define PKIX_TEST_ERROR_RECEIVED (pkixTestErrorMsg || pkixTestErrorResult) |
|
248 |
|
249 /* see source file for function documentation */ |
|
250 |
|
251 void startTests(char *testName); |
|
252 |
|
253 void endTests(char *testName); |
|
254 |
|
255 void subTest(char *subTestName); |
|
256 |
|
257 void testError(char *msg); |
|
258 |
|
259 extern PKIX_Error * |
|
260 _ErrorCheck(PKIX_Error *errorResult); |
|
261 |
|
262 extern PKIX_Error * |
|
263 _OutputError(PKIX_Error *errorResult); |
|
264 |
|
265 char* PKIX_String2ASCII(PKIX_PL_String *string, void *plContext); |
|
266 |
|
267 char* PKIX_Error2ASCII(PKIX_Error *error, void *plContext); |
|
268 |
|
269 char* PKIX_Object2ASCII(PKIX_PL_Object *object); |
|
270 |
|
271 char *PKIX_Cert2ASCII(PKIX_PL_Cert *cert); |
|
272 |
|
273 void |
|
274 testHashcodeHelper( |
|
275 PKIX_PL_Object *goodObject, |
|
276 PKIX_PL_Object *otherObject, |
|
277 PKIX_Boolean match, |
|
278 void *plContext); |
|
279 |
|
280 void |
|
281 testToStringHelper( |
|
282 PKIX_PL_Object *goodObject, |
|
283 char *expected, |
|
284 void *plContext); |
|
285 |
|
286 void |
|
287 testEqualsHelper( |
|
288 PKIX_PL_Object *goodObject, |
|
289 PKIX_PL_Object *otherObject, |
|
290 PKIX_Boolean match, |
|
291 void *plContext); |
|
292 |
|
293 void |
|
294 testDuplicateHelper( |
|
295 PKIX_PL_Object *object, |
|
296 void *plContext); |
|
297 void |
|
298 testErrorUndo(char *msg); |
|
299 |
|
300 #ifdef __cplusplus |
|
301 } |
|
302 #endif |
|
303 |
|
304 #endif /* TESTUTIL_H */ |