unit_test.h
1 /*********************************************************************** 2 * Distributed under the MIT software license, see the accompanying * 3 * file COPYING or https://www.opensource.org/licenses/mit-license.php.* 4 ***********************************************************************/ 5 6 #ifndef SECP256K1_UNIT_TEST_H 7 #define SECP256K1_UNIT_TEST_H 8 9 #include "util.h" 10 11 /* --------------------------------------------------------- */ 12 /* Configurable constants */ 13 /* --------------------------------------------------------- */ 14 15 /* Maximum number of command-line arguments. 16 * Must be at least as large as the total number of tests 17 * to allow specifying all tests individually. */ 18 #define MAX_ARGS 150 19 /* Maximum number of parallel jobs */ 20 #define MAX_SUBPROCESSES 16 21 22 /* --------------------------------------------------------- */ 23 /* Test Framework Registry Macros */ 24 /* --------------------------------------------------------- */ 25 26 #define CASE(name) { #name, run_##name } 27 #define CASE1(name) { #name, name } 28 29 #define MAKE_TEST_MODULE(name) { \ 30 #name, \ 31 tests_##name, \ 32 ARRAY_SIZE(tests_##name) \ 33 } 34 35 /* Macro to wrap a test internal function with a COUNT loop (iterations number) */ 36 #define REPEAT_TEST(fn) REPEAT_TEST_MULT(fn, 1) 37 #define REPEAT_TEST_MULT(fn, multiplier) \ 38 static void fn(void) { \ 39 int i; \ 40 int repeat = COUNT * (multiplier); \ 41 for (i = 0; i < repeat; i++) \ 42 fn##_internal(); \ 43 } 44 45 46 47 /* --------------------------------------------------------- */ 48 /* Test Framework API */ 49 /* --------------------------------------------------------- */ 50 51 typedef void (*test_fn)(void); 52 53 struct tf_test_entry { 54 const char* name; 55 test_fn func; 56 }; 57 58 struct tf_test_module { 59 const char* name; 60 const struct tf_test_entry* data; 61 int size; 62 }; 63 64 typedef int (*setup_ctx_fn)(void); 65 typedef int (*teardown_fn)(void); 66 typedef void (*run_test_fn)(const struct tf_test_entry*); 67 68 struct tf_targets { 69 /* Target tests indexes */ 70 const struct tf_test_entry* slots[MAX_ARGS]; 71 /* Next available slot */ 72 int size; 73 }; 74 75 /* --- Command-line args --- */ 76 struct tf_args { 77 /* 0 => sequential; 1..MAX_SUBPROCESSES => parallel workers */ 78 int num_processes; 79 /* Specific RNG seed */ 80 const char* custom_seed; 81 /* Whether to print the help msg */ 82 int help; 83 /* Whether to print the tests list msg */ 84 int list_tests; 85 /* Target tests indexes */ 86 struct tf_targets targets; 87 /* Enable test execution logging */ 88 int logging; 89 }; 90 91 /* --------------------------------------------------------- */ 92 /* Public API */ 93 /* --------------------------------------------------------- */ 94 95 struct tf_framework { 96 /* Command-line args */ 97 struct tf_args args; 98 /* Test modules registry */ 99 const struct tf_test_module* registry_modules; 100 /* Num of modules */ 101 int num_modules; 102 /* Registry for tests that require no RNG init */ 103 const struct tf_test_module* registry_no_rng; 104 /* Specific context setup and teardown functions */ 105 setup_ctx_fn fn_setup; 106 teardown_fn fn_teardown; 107 /* Test runner function (can be customized) */ 108 run_test_fn fn_run_test; 109 }; 110 111 /* 112 * Initialize the test framework. 113 * 114 * Must be called before tf_run() and before any output is performed to 115 * stdout or stderr, because this function disables buffering on both 116 * streams to ensure reliable diagnostic output. 117 * 118 * Parses command-line arguments and configures the framework context. 119 * The caller must initialize the following members of 'tf' before calling: 120 * - tf->registry_modules 121 * - tf->num_modules 122 * 123 * Side effects: 124 * - stdout and stderr are set to unbuffered mode via setbuf(). 125 * This allows immediate flushing of diagnostic messages but may 126 * affect performance for other output operations. 127 * 128 * Returns: 129 * EXIT_SUCCESS (0) on success, 130 * EXIT_FAILURE (non-zero) on error. 131 */ 132 static int tf_init(struct tf_framework* tf, int argc, char** argv); 133 134 /* 135 * Run tests based on the provided test framework context. 136 * 137 * This function uses the configuration stored in the tf_framework 138 * (targets, number of processes, iteration count, etc.) to determine 139 * which tests to execute and how to execute them. 140 * 141 * Returns: 142 * EXIT_SUCCESS (0) if all tests passed, 143 * EXIT_FAILURE (non-zero) otherwise. 144 */ 145 static int tf_run(struct tf_framework* tf); 146 147 #endif /* SECP256K1_UNIT_TEST_H */