tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

testutil.h (13435B)


      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(PKIX_PL_Object_DecRef((PKIX_PL_Object *)(obj), plContext)); \
    108            obj = NULL;                                                                           \
    109        }                                                                                         \
    110    } while (0)
    111 
    112 /*
    113 * PKIX_TEST_DECREF_AC is a convenience macro which should only be called
    114 * AFTER the "cleanup" label ("AC"). If the input parameter is non-NULL, it
    115 * DecRefs the input parameter. A pkixTestTempResult variable is used to prevent
    116 * incorrectly overwriting pkixTestErrorResult with NULL.
    117 * In the case DecRef succeeds, pkixTestTempResult will be NULL, and we won't
    118 * overwrite a previously set pkixTestErrorResult (if any). If DecRef fails,
    119 * then we do want to overwrite a previously set pkixTestErrorResult since a
    120 * DecRef failure is fatal and may be indicative of memory corruption.
    121 */
    122 
    123 #define PKIX_TEST_DECREF_AC(obj)                                           \
    124    do {                                                                   \
    125        if (obj) {                                                         \
    126            PKIX_Error *pkixTestTempResult = NULL;                         \
    127            pkixTestTempResult =                                           \
    128                PKIX_PL_Object_DecRef((PKIX_PL_Object *)(obj), plContext); \
    129            if (pkixTestTempResult)                                        \
    130                pkixTestErrorResult = pkixTestTempResult;                  \
    131            obj = NULL;                                                    \
    132        }                                                                  \
    133    } while (0)
    134 
    135 /*
    136 * PKIX_TEST_RETURN must always be AFTER the "cleanup" label. It does nothing
    137 * if everything went as expected. However, if there were unexpected results,
    138 * PKIX_TEST_RETURN calls testError, which displays a standard failure message
    139 * and increments the number of subtests that have failed. In the case
    140 * of an unexpected error, testError is called using the error's description
    141 * as an input and the error is DecRef'd. In the case of unexpected success
    142 * testError is called with a standard string.
    143 */
    144 #define PKIX_TEST_RETURN()                                                   \
    145    {                                                                        \
    146        if (pkixTestErrorMsg) {                                              \
    147            testError(pkixTestErrorMsg);                                     \
    148        } else if (pkixTestErrorResult) {                                    \
    149            pkixTestErrorMsg =                                               \
    150                PKIX_Error2ASCII(pkixTestErrorResult, plContext);            \
    151            if (pkixTestErrorMsg) {                                          \
    152                testError(pkixTestErrorMsg);                                 \
    153                PKIX_PL_Free((PKIX_PL_Object *)pkixTestErrorMsg,             \
    154                             plContext);                                     \
    155            } else {                                                         \
    156                testError("PKIX_Error2ASCII Failed");                        \
    157            }                                                                \
    158            if (pkixTestErrorResult != PKIX_ALLOC_ERROR()) {                 \
    159                PKIX_PL_Object_DecRef((PKIX_PL_Object *)pkixTestErrorResult, \
    160                                      plContext);                            \
    161                pkixTestErrorResult = NULL;                                  \
    162            }                                                                \
    163        }                                                                    \
    164    }
    165 
    166 /*
    167 * PKIX_TEST_EQ_HASH_TOSTR_DUP is a convenience macro which executes the
    168 * standard set of operations that test the Equals, Hashcode, ToString, and
    169 * Duplicate functions of an object type. The goodObj, equalObj, and diffObj
    170 * are as the names suggest. The expAscii parameter is the expected result of
    171 * calling ToString on the goodObj. If expAscii is NULL, then ToString will
    172 * not be called on the goodObj. The checkDuplicate parameter is treated as
    173 * a Boolean to indicate whether the Duplicate function should be tested. If
    174 * checkDuplicate is NULL, then Duplicate will not be called on the goodObj.
    175 * The type is the name of the function's family. For example, if the type is
    176 * Cert, this macro will call PKIX_PL_Cert_Equals, PKIX_PL_Cert_Hashcode, and
    177 * PKIX_PL_Cert_ToString.
    178 *
    179 * Note: If goodObj uses the default Equals and Hashcode functions, then
    180 * for goodObj and equalObj to be equal, they must have the same pointer value.
    181 */
    182 #define PKIX_TEST_EQ_HASH_TOSTR_DUP(goodObj, equalObj, diffObj,        \
    183                                    expAscii, type, checkDuplicate)    \
    184    do {                                                               \
    185        subTest("PKIX_PL_" #type "_Equals   <match>");                 \
    186        testEqualsHelper((PKIX_PL_Object *)(goodObj),                  \
    187                         (PKIX_PL_Object *)(equalObj),                 \
    188                         PKIX_TRUE,                                    \
    189                         plContext);                                   \
    190        subTest("PKIX_PL_" #type "_Hashcode <match>");                 \
    191        testHashcodeHelper((PKIX_PL_Object *)(goodObj),                \
    192                           (PKIX_PL_Object *)(equalObj),               \
    193                           PKIX_TRUE,                                  \
    194                           plContext);                                 \
    195        subTest("PKIX_PL_" #type "_Equals   <non-match>");             \
    196        testEqualsHelper((PKIX_PL_Object *)(goodObj),                  \
    197                         (PKIX_PL_Object *)(diffObj),                  \
    198                         PKIX_FALSE,                                   \
    199                         plContext);                                   \
    200        subTest("PKIX_PL_" #type "_Hashcode <non-match>");             \
    201        testHashcodeHelper((PKIX_PL_Object *)(goodObj),                \
    202                           (PKIX_PL_Object *)(diffObj),                \
    203                           PKIX_FALSE,                                 \
    204                           plContext);                                 \
    205        if (expAscii) {                                                \
    206            subTest("PKIX_PL_" #type "_ToString");                     \
    207            testToStringHelper((PKIX_PL_Object *)(goodObj),            \
    208                               (expAscii),                             \
    209                               plContext);                             \
    210        }                                                              \
    211        if (checkDuplicate) {                                          \
    212            subTest("PKIX_PL_" #type "_Duplicate");                    \
    213            testDuplicateHelper((PKIX_PL_Object *)goodObj, plContext); \
    214        }                                                              \
    215    } while (0)
    216 
    217 /*
    218 * PKIX_TEST_DECREF_BC is a convenience macro which should only be called
    219 * BEFORE the "cleanup" label ("BC"). If the input parameter is non-NULL, it
    220 * DecRefs the input parameter and wraps the function with
    221 * PKIX_TEST_EXPECT_NO_ERROR, which executes "goto cleanup" upon error.
    222 * This macro MUST NOT be called after the "cleanup" label.
    223 */
    224 
    225 #define PKIX_TEST_ABORT_ON_NULL(obj) \
    226    do {                             \
    227        if (!obj) {                  \
    228            goto cleanup;            \
    229        }                            \
    230    } while (0)
    231 
    232 #define PKIX_TEST_ARENAS_ARG(arena) \
    233    (arena ? (PORT_Strcmp(arena, "arenas") ? PKIX_FALSE : (j++, PKIX_TRUE)) : PKIX_FALSE)
    234 
    235 #define PKIX_TEST_ERROR_RECEIVED (pkixTestErrorMsg || pkixTestErrorResult)
    236 
    237 /* see source file for function documentation */
    238 
    239 void startTests(char *testName);
    240 
    241 void endTests(char *testName);
    242 
    243 void subTest(char *subTestName);
    244 
    245 void testError(char *msg);
    246 
    247 extern PKIX_Error *
    248 _ErrorCheck(PKIX_Error *errorResult);
    249 
    250 extern PKIX_Error *
    251 _OutputError(PKIX_Error *errorResult);
    252 
    253 char *PKIX_String2ASCII(PKIX_PL_String *string, void *plContext);
    254 
    255 char *PKIX_Error2ASCII(PKIX_Error *error, void *plContext);
    256 
    257 char *PKIX_Object2ASCII(PKIX_PL_Object *object);
    258 
    259 char *PKIX_Cert2ASCII(PKIX_PL_Cert *cert);
    260 
    261 void
    262 testHashcodeHelper(
    263    PKIX_PL_Object *goodObject,
    264    PKIX_PL_Object *otherObject,
    265    PKIX_Boolean match,
    266    void *plContext);
    267 
    268 void
    269 testToStringHelper(
    270    PKIX_PL_Object *goodObject,
    271    char *expected,
    272    void *plContext);
    273 
    274 void
    275 testEqualsHelper(
    276    PKIX_PL_Object *goodObject,
    277    PKIX_PL_Object *otherObject,
    278    PKIX_Boolean match,
    279    void *plContext);
    280 
    281 void
    282 testDuplicateHelper(
    283    PKIX_PL_Object *object,
    284    void *plContext);
    285 void
    286 testErrorUndo(char *msg);
    287 
    288 #ifdef __cplusplus
    289 }
    290 #endif
    291 
    292 #endif /* TESTUTIL_H */