Wed, 31 Dec 2014 06:55:50 +0100
Added tag UPSTREAM_283F7C6 for changeset ca08bd8f51b2
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 */
11 #ifndef _TESTUTIL_H
12 #define _TESTUTIL_H
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>
23 #ifdef __cplusplus
24 extern "C" {
25 #endif
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 */
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;
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 */
66 #define PKIX_TEST_EXPECT_NO_ERROR(func) \
67 do { \
68 pkixTestErrorResult = (func); \
69 if (pkixTestErrorResult) { \
70 goto cleanup; \
71 } \
72 } while (0)
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 */
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)
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 */
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)
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 */
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)
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 }
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)
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 */
235 #define PKIX_TEST_ABORT_ON_NULL(obj) \
236 do { \
237 if (!obj){ \
238 goto cleanup; \
239 } \
240 } while (0)
242 #define PKIX_TEST_ARENAS_ARG(arena) \
243 (arena? \
244 (PORT_Strcmp(arena, "arenas") ? PKIX_FALSE : (j++, PKIX_TRUE)): \
245 PKIX_FALSE)
247 #define PKIX_TEST_ERROR_RECEIVED (pkixTestErrorMsg || pkixTestErrorResult)
249 /* see source file for function documentation */
251 void startTests(char *testName);
253 void endTests(char *testName);
255 void subTest(char *subTestName);
257 void testError(char *msg);
259 extern PKIX_Error *
260 _ErrorCheck(PKIX_Error *errorResult);
262 extern PKIX_Error *
263 _OutputError(PKIX_Error *errorResult);
265 char* PKIX_String2ASCII(PKIX_PL_String *string, void *plContext);
267 char* PKIX_Error2ASCII(PKIX_Error *error, void *plContext);
269 char* PKIX_Object2ASCII(PKIX_PL_Object *object);
271 char *PKIX_Cert2ASCII(PKIX_PL_Cert *cert);
273 void
274 testHashcodeHelper(
275 PKIX_PL_Object *goodObject,
276 PKIX_PL_Object *otherObject,
277 PKIX_Boolean match,
278 void *plContext);
280 void
281 testToStringHelper(
282 PKIX_PL_Object *goodObject,
283 char *expected,
284 void *plContext);
286 void
287 testEqualsHelper(
288 PKIX_PL_Object *goodObject,
289 PKIX_PL_Object *otherObject,
290 PKIX_Boolean match,
291 void *plContext);
293 void
294 testDuplicateHelper(
295 PKIX_PL_Object *object,
296 void *plContext);
297 void
298 testErrorUndo(char *msg);
300 #ifdef __cplusplus
301 }
302 #endif
304 #endif /* TESTUTIL_H */