2025-09-03 10:59:37 -04:00
|
|
|
/***********************************************************************
|
|
|
|
|
* Distributed under the MIT software license, see the accompanying *
|
|
|
|
|
* file COPYING or https://www.opensource.org/licenses/mit-license.php.*
|
|
|
|
|
***********************************************************************/
|
|
|
|
|
|
|
|
|
|
#ifndef SECP256K1_UNIT_TEST_H
|
|
|
|
|
#define SECP256K1_UNIT_TEST_H
|
|
|
|
|
|
2026-02-16 23:47:51 +01:00
|
|
|
#include "util.h"
|
|
|
|
|
|
2025-09-03 10:59:37 -04:00
|
|
|
/* --------------------------------------------------------- */
|
|
|
|
|
/* Configurable constants */
|
|
|
|
|
/* --------------------------------------------------------- */
|
|
|
|
|
|
|
|
|
|
/* Maximum number of command-line arguments.
|
|
|
|
|
* Must be at least as large as the total number of tests
|
|
|
|
|
* to allow specifying all tests individually. */
|
|
|
|
|
#define MAX_ARGS 150
|
|
|
|
|
/* Maximum number of parallel jobs */
|
|
|
|
|
#define MAX_SUBPROCESSES 16
|
|
|
|
|
|
|
|
|
|
/* --------------------------------------------------------- */
|
|
|
|
|
/* Test Framework Registry Macros */
|
|
|
|
|
/* --------------------------------------------------------- */
|
|
|
|
|
|
|
|
|
|
#define CASE(name) { #name, run_##name }
|
2025-09-09 11:45:17 -04:00
|
|
|
#define CASE1(name) { #name, name }
|
2025-09-03 10:59:37 -04:00
|
|
|
|
|
|
|
|
#define MAKE_TEST_MODULE(name) { \
|
|
|
|
|
#name, \
|
|
|
|
|
tests_##name, \
|
2026-02-16 23:47:51 +01:00
|
|
|
ARRAY_SIZE(tests_##name) \
|
2025-09-03 10:59:37 -04:00
|
|
|
}
|
|
|
|
|
|
2025-09-09 11:45:17 -04:00
|
|
|
/* Macro to wrap a test internal function with a COUNT loop (iterations number) */
|
|
|
|
|
#define REPEAT_TEST(fn) REPEAT_TEST_MULT(fn, 1)
|
|
|
|
|
#define REPEAT_TEST_MULT(fn, multiplier) \
|
|
|
|
|
static void fn(void) { \
|
|
|
|
|
int i; \
|
|
|
|
|
int repeat = COUNT * (multiplier); \
|
|
|
|
|
for (i = 0; i < repeat; i++) \
|
|
|
|
|
fn##_internal(); \
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2025-09-03 10:59:37 -04:00
|
|
|
/* --------------------------------------------------------- */
|
|
|
|
|
/* Test Framework API */
|
|
|
|
|
/* --------------------------------------------------------- */
|
|
|
|
|
|
|
|
|
|
typedef void (*test_fn)(void);
|
|
|
|
|
|
|
|
|
|
struct tf_test_entry {
|
|
|
|
|
const char* name;
|
|
|
|
|
test_fn func;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
struct tf_test_module {
|
|
|
|
|
const char* name;
|
|
|
|
|
const struct tf_test_entry* data;
|
|
|
|
|
int size;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
typedef int (*setup_ctx_fn)(void);
|
|
|
|
|
typedef int (*teardown_fn)(void);
|
2025-09-09 11:02:05 -04:00
|
|
|
typedef void (*run_test_fn)(const struct tf_test_entry*);
|
2025-09-03 10:59:37 -04:00
|
|
|
|
2025-09-03 17:18:23 -04:00
|
|
|
struct tf_targets {
|
|
|
|
|
/* Target tests indexes */
|
|
|
|
|
const struct tf_test_entry* slots[MAX_ARGS];
|
|
|
|
|
/* Next available slot */
|
|
|
|
|
int size;
|
|
|
|
|
};
|
2025-09-03 10:59:37 -04:00
|
|
|
|
|
|
|
|
/* --- Command-line args --- */
|
|
|
|
|
struct tf_args {
|
|
|
|
|
/* 0 => sequential; 1..MAX_SUBPROCESSES => parallel workers */
|
|
|
|
|
int num_processes;
|
|
|
|
|
/* Specific RNG seed */
|
|
|
|
|
const char* custom_seed;
|
2025-09-03 15:27:23 -04:00
|
|
|
/* Whether to print the help msg */
|
|
|
|
|
int help;
|
2025-09-08 14:17:12 -04:00
|
|
|
/* Whether to print the tests list msg */
|
|
|
|
|
int list_tests;
|
2025-09-03 17:18:23 -04:00
|
|
|
/* Target tests indexes */
|
|
|
|
|
struct tf_targets targets;
|
2025-09-09 11:02:05 -04:00
|
|
|
/* Enable test execution logging */
|
|
|
|
|
int logging;
|
2025-09-03 10:59:37 -04:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/* --------------------------------------------------------- */
|
|
|
|
|
/* Public API */
|
|
|
|
|
/* --------------------------------------------------------- */
|
|
|
|
|
|
|
|
|
|
struct tf_framework {
|
|
|
|
|
/* Command-line args */
|
|
|
|
|
struct tf_args args;
|
|
|
|
|
/* Test modules registry */
|
|
|
|
|
const struct tf_test_module* registry_modules;
|
|
|
|
|
/* Num of modules */
|
|
|
|
|
int num_modules;
|
|
|
|
|
/* Registry for tests that require no RNG init */
|
|
|
|
|
const struct tf_test_module* registry_no_rng;
|
|
|
|
|
/* Specific context setup and teardown functions */
|
|
|
|
|
setup_ctx_fn fn_setup;
|
|
|
|
|
teardown_fn fn_teardown;
|
2025-09-09 11:02:05 -04:00
|
|
|
/* Test runner function (can be customized) */
|
|
|
|
|
run_test_fn fn_run_test;
|
2025-09-03 10:59:37 -04:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Initialize the test framework.
|
|
|
|
|
*
|
|
|
|
|
* Must be called before tf_run() and before any output is performed to
|
|
|
|
|
* stdout or stderr, because this function disables buffering on both
|
|
|
|
|
* streams to ensure reliable diagnostic output.
|
|
|
|
|
*
|
|
|
|
|
* Parses command-line arguments and configures the framework context.
|
|
|
|
|
* The caller must initialize the following members of 'tf' before calling:
|
|
|
|
|
* - tf->registry_modules
|
|
|
|
|
* - tf->num_modules
|
|
|
|
|
*
|
|
|
|
|
* Side effects:
|
|
|
|
|
* - stdout and stderr are set to unbuffered mode via setbuf().
|
|
|
|
|
* This allows immediate flushing of diagnostic messages but may
|
|
|
|
|
* affect performance for other output operations.
|
|
|
|
|
*
|
|
|
|
|
* Returns:
|
|
|
|
|
* EXIT_SUCCESS (0) on success,
|
|
|
|
|
* EXIT_FAILURE (non-zero) on error.
|
|
|
|
|
*/
|
|
|
|
|
static int tf_init(struct tf_framework* tf, int argc, char** argv);
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Run tests based on the provided test framework context.
|
|
|
|
|
*
|
|
|
|
|
* This function uses the configuration stored in the tf_framework
|
|
|
|
|
* (targets, number of processes, iteration count, etc.) to determine
|
|
|
|
|
* which tests to execute and how to execute them.
|
|
|
|
|
*
|
|
|
|
|
* Returns:
|
|
|
|
|
* EXIT_SUCCESS (0) if all tests passed,
|
|
|
|
|
* EXIT_FAILURE (non-zero) otherwise.
|
|
|
|
|
*/
|
|
|
|
|
static int tf_run(struct tf_framework* tf);
|
|
|
|
|
|
|
|
|
|
#endif /* SECP256K1_UNIT_TEST_H */
|