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

     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 */

mercurial