security/nss/cmd/libpkix/testutil/testutil.h

Wed, 31 Dec 2014 06:55:50 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:55:50 +0100
changeset 2
7e26c7da4463
permissions
-rwxr-xr-x

Added tag UPSTREAM_283F7C6 for changeset ca08bd8f51b2

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

mercurial