Skip to content

Commit cb76d69

Browse files
committed
tests: introduce mini unit test framework
Lightweight unit testing framework, providing a structured way to define, execute, and report tests. It includes a central test registry, a flexible command-line argument parser of the form "-key=value" (facilitating future framework extensions), ability to run tests in parallel and accumulated test time logging reports. So far the supported command-line args are: - "-jobs=<num>" to specify the number of parallel workers. - "-seed=<hex>" to specify the context seed (random if not set). - "-iterations=<value>" to specify the number of iterations. Compatibility Note: To stay compatible with previous versions, the framework also supports the two original positional arguments: the iteration count and the context seed (in that order).
1 parent 746c931 commit cb76d69

File tree

4 files changed

+399
-122
lines changed

4 files changed

+399
-122
lines changed

Makefile.am

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ noinst_HEADERS += src/precomputed_ecmult.h
4545
noinst_HEADERS += src/precomputed_ecmult_gen.h
4646
noinst_HEADERS += src/assumptions.h
4747
noinst_HEADERS += src/checkmem.h
48+
noinst_HEADERS += src/tests.c
4849
noinst_HEADERS += src/testutil.h
4950
noinst_HEADERS += src/util.h
5051
noinst_HEADERS += src/util_local_visibility.h
@@ -119,7 +120,7 @@ TESTS =
119120
if USE_TESTS
120121
TESTS += noverify_tests
121122
noinst_PROGRAMS += noverify_tests
122-
noverify_tests_SOURCES = src/tests.c
123+
noverify_tests_SOURCES = src/unit_test.c
123124
noverify_tests_CPPFLAGS = $(SECP_CONFIG_DEFINES)
124125
noverify_tests_LDADD = $(COMMON_LIB) $(PRECOMPUTED_LIB)
125126
noverify_tests_LDFLAGS = -static

src/CMakeLists.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -134,11 +134,11 @@ if(SECP256K1_BUILD_BENCHMARK)
134134
endif()
135135

136136
if(SECP256K1_BUILD_TESTS)
137-
add_executable(noverify_tests tests.c)
137+
add_executable(noverify_tests unit_test.c)
138138
target_link_libraries(noverify_tests secp256k1_precomputed secp256k1_asm)
139139
add_test(NAME secp256k1_noverify_tests COMMAND noverify_tests)
140140
if(NOT CMAKE_BUILD_TYPE STREQUAL "Coverage")
141-
add_executable(tests tests.c)
141+
add_executable(tests unit_test.c)
142142
target_compile_definitions(tests PRIVATE VERIFY)
143143
target_link_libraries(tests secp256k1_precomputed secp256k1_asm)
144144
add_test(NAME secp256k1_tests COMMAND tests)

src/tests.c

Lines changed: 89 additions & 119 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@
44
* file COPYING or https://www.opensource.org/licenses/mit-license.php.*
55
***********************************************************************/
66

7+
#ifndef SECP256K1_TESTS_C
8+
#define SECP256K1_TESTS_C
9+
710
#include <stdio.h>
811
#include <stdlib.h>
912
#include <string.h>
@@ -227,6 +230,12 @@ static void run_static_context_tests(int use_prealloc) {
227230
}
228231
}
229232

233+
static void run_all_static_context_tests(void)
234+
{
235+
run_static_context_tests(0);
236+
run_static_context_tests(1);
237+
}
238+
230239
static void run_proper_context_tests(int use_prealloc) {
231240
int32_t dummy = 0;
232241
secp256k1_context *my_ctx, *my_ctx_fresh;
@@ -349,6 +358,12 @@ static void run_proper_context_tests(int use_prealloc) {
349358
secp256k1_context_preallocated_destroy(NULL);
350359
}
351360

361+
static void run_all_proper_context_tests(void)
362+
{
363+
run_proper_context_tests(0);
364+
run_proper_context_tests(1);
365+
}
366+
352367
static void run_scratch_tests(void) {
353368
const size_t adj_alloc = ((500 + ALIGNMENT - 1) / ALIGNMENT) * ALIGNMENT;
354369

@@ -7666,179 +7681,134 @@ static void run_cmov_tests(void) {
76667681
ge_storage_cmov_test();
76677682
}
76687683

7669-
int main(int argc, char **argv) {
7670-
/* Disable buffering for stdout to improve reliability of getting
7671-
* diagnostic information. Happens right at the start of main because
7672-
* setbuf must be used before any other operation on the stream. */
7673-
setbuf(stdout, NULL);
7674-
/* Also disable buffering for stderr because it's not guaranteed that it's
7675-
* unbuffered on all systems. */
7676-
setbuf(stderr, NULL);
7677-
7678-
/* find iteration count */
7679-
if (argc > 1) {
7680-
COUNT = strtol(argv[1], NULL, 0);
7681-
} else {
7682-
const char* env = getenv("SECP256K1_TEST_ITERS");
7683-
if (env && strlen(env) > 0) {
7684-
COUNT = strtol(env, NULL, 0);
7685-
}
7686-
}
7687-
if (COUNT <= 0) {
7688-
fputs("An iteration count of 0 or less is not allowed.\n", stderr);
7689-
return EXIT_FAILURE;
7690-
}
7691-
printf("test count = %i\n", COUNT);
7684+
typedef void (*test_fn)(void);
76927685

7693-
/* run test RNG tests (must run before we really initialize the test RNG) */
7694-
run_xoshiro256pp_tests();
7695-
7696-
/* find random seed */
7697-
testrand_init(argc > 2 ? argv[2] : NULL);
7698-
7699-
/*** Setup test environment ***/
7700-
7701-
/* Create a global context available to all tests */
7702-
CTX = secp256k1_context_create(SECP256K1_CONTEXT_NONE);
7703-
/* Randomize the context only with probability 15/16
7704-
to make sure we test without context randomization from time to time.
7705-
TODO Reconsider this when recalibrating the tests. */
7706-
if (testrand_bits(4)) {
7707-
unsigned char rand32[32];
7708-
testrand256(rand32);
7709-
CHECK(secp256k1_context_randomize(CTX, rand32));
7710-
}
7711-
/* Make a writable copy of secp256k1_context_static in order to test the effect of API functions
7712-
that write to the context. The API does not support cloning the static context, so we use
7713-
memcpy instead. The user is not supposed to copy a context but we should still ensure that
7714-
the API functions handle copies of the static context gracefully. */
7715-
STATIC_CTX = malloc(sizeof(*secp256k1_context_static));
7716-
CHECK(STATIC_CTX != NULL);
7717-
memcpy(STATIC_CTX, secp256k1_context_static, sizeof(secp256k1_context));
7718-
CHECK(!secp256k1_context_is_proper(STATIC_CTX));
7686+
struct test_entry {
7687+
const char* name;
7688+
test_fn func;
7689+
};
77197690

7720-
/*** Run actual tests ***/
7691+
/* --- Context Independent - Test registry --- */
7692+
static struct test_entry tests_no_ctx[] = {
7693+
{"xoshiro256pp_tests", run_xoshiro256pp_tests},
7694+
{NULL, NULL}
7695+
};
77217696

7697+
/* --- Test registry --- */
7698+
static struct test_entry tests[] = {
77227699
/* selftest tests */
7723-
run_selftest_tests();
7700+
{"selftest_tests", run_selftest_tests},
77247701

77257702
/* context tests */
7726-
run_proper_context_tests(0); run_proper_context_tests(1);
7727-
run_static_context_tests(0); run_static_context_tests(1);
7728-
run_deprecated_context_flags_test();
7703+
{"all_proper_context_tests", run_all_proper_context_tests},
7704+
{"all_static_context_tests", run_all_static_context_tests},
7705+
{"deprecated_context_flags_test", run_deprecated_context_flags_test},
77297706

77307707
/* scratch tests */
7731-
run_scratch_tests();
7708+
{"scratch_tests", run_scratch_tests},
77327709

77337710
/* integer arithmetic tests */
77347711
#ifdef SECP256K1_WIDEMUL_INT128
7735-
run_int128_tests();
7712+
{"int128_tests", run_int128_tests},
77367713
#endif
7737-
run_ctz_tests();
7738-
run_modinv_tests();
7739-
run_inverse_tests();
7714+
{"ctz_tests", run_ctz_tests},
7715+
{"modinv_tests", run_modinv_tests},
7716+
{"inverse_tests", run_inverse_tests},
77407717

77417718
/* sorting tests */
7742-
run_hsort_tests();
7719+
{"hsort_tests", run_hsort_tests},
77437720

77447721
/* hash tests */
7745-
run_sha256_known_output_tests();
7746-
run_sha256_counter_tests();
7747-
run_hmac_sha256_tests();
7748-
run_rfc6979_hmac_sha256_tests();
7749-
run_tagged_sha256_tests();
7722+
{"sha256_known_output_tests", run_sha256_known_output_tests},
7723+
{"sha256_counter_tests", run_sha256_counter_tests},
7724+
{"hmac_sha256_tests", run_hmac_sha256_tests},
7725+
{"rfc6979_hmac_sha256_tests", run_rfc6979_hmac_sha256_tests},
7726+
{"tagged_sha256_tests", run_tagged_sha256_tests},
77507727

77517728
/* scalar tests */
7752-
run_scalar_tests();
7729+
{"scalar_tests", run_scalar_tests},
77537730

77547731
/* field tests */
7755-
run_field_half();
7756-
run_field_misc();
7757-
run_field_convert();
7758-
run_field_be32_overflow();
7759-
run_fe_mul();
7760-
run_sqr();
7761-
run_sqrt();
7732+
{"field_half", run_field_half},
7733+
{"field_misc", run_field_misc},
7734+
{"field_convert", run_field_convert},
7735+
{"field_be32_overflow", run_field_be32_overflow},
7736+
{"fe_mul", run_fe_mul},
7737+
{"sqr", run_sqr},
7738+
{"sqrt", run_sqrt},
77627739

77637740
/* group tests */
7764-
run_ge();
7765-
run_gej();
7766-
run_group_decompress();
7741+
{"ge", run_ge},
7742+
{"gej", run_gej},
7743+
{"group_decompress", run_group_decompress},
77677744

77687745
/* ecmult tests */
7769-
run_ecmult_pre_g();
7770-
run_wnaf();
7771-
run_point_times_order();
7772-
run_ecmult_near_split_bound();
7773-
run_ecmult_chain();
7774-
run_ecmult_constants();
7775-
run_ecmult_gen_blind();
7776-
run_ecmult_const_tests();
7777-
run_ecmult_multi_tests();
7778-
run_ec_combine();
7746+
{"ecmult_pre_g", run_ecmult_pre_g},
7747+
{"wnaf", run_wnaf},
7748+
{"point_times_order", run_point_times_order},
7749+
{"ecmult_near_split_bound", run_ecmult_near_split_bound},
7750+
{"ecmult_chain", run_ecmult_chain},
7751+
{"ecmult_constants", run_ecmult_constants},
7752+
{"ecmult_gen_blind", run_ecmult_gen_blind},
7753+
{"ecmult_const_tests", run_ecmult_const_tests},
7754+
{"ecmult_multi_tests", run_ecmult_multi_tests},
7755+
{"ec_combine", run_ec_combine},
77797756

77807757
/* endomorphism tests */
7781-
run_endomorphism_tests();
7758+
{"endomorphism_tests", run_endomorphism_tests},
77827759

77837760
/* EC point parser test */
7784-
run_ec_pubkey_parse_test();
7761+
{"ec_pubkey_parse_test", run_ec_pubkey_parse_test},
77857762

77867763
/* EC key edge cases */
7787-
run_eckey_edge_case_test();
7764+
{"eckey_edge_case_test", run_eckey_edge_case_test},
77887765

77897766
/* EC key arithmetic test */
7790-
run_eckey_negate_test();
7767+
{"eckey_negate_test", run_eckey_negate_test},
77917768

77927769
#ifdef ENABLE_MODULE_ECDH
77937770
/* ecdh tests */
7794-
run_ecdh_tests();
7771+
{"ecdh_tests", run_ecdh_tests},
77957772
#endif
77967773

77977774
/* ecdsa tests */
7798-
run_ec_illegal_argument_tests();
7799-
run_pubkey_comparison();
7800-
run_pubkey_sort();
7801-
run_random_pubkeys();
7802-
run_ecdsa_der_parse();
7803-
run_ecdsa_sign_verify();
7804-
run_ecdsa_end_to_end();
7805-
run_ecdsa_edge_cases();
7806-
run_ecdsa_wycheproof();
7775+
{"ec_illegal_argument_tests", run_ec_illegal_argument_tests},
7776+
{"pubkey_comparison", run_pubkey_comparison},
7777+
{"pubkey_sort", run_pubkey_sort},
7778+
{"random_pubkeys", run_random_pubkeys},
7779+
{"ecdsa_der_parse", run_ecdsa_der_parse},
7780+
{"ecdsa_sign_verify", run_ecdsa_sign_verify},
7781+
{"ecdsa_end_to_end", run_ecdsa_end_to_end},
7782+
{"ecdsa_edge_cases", run_ecdsa_edge_cases},
7783+
{"ecdsa_wycheproof", run_ecdsa_wycheproof},
78077784

78087785
#ifdef ENABLE_MODULE_RECOVERY
78097786
/* ECDSA pubkey recovery tests */
7810-
run_recovery_tests();
7787+
{"recovery_tests", run_recovery_tests},
78117788
#endif
78127789

78137790
#ifdef ENABLE_MODULE_EXTRAKEYS
7814-
run_extrakeys_tests();
7791+
{"extrakeys_tests", run_extrakeys_tests},
78157792
#endif
78167793

78177794
#ifdef ENABLE_MODULE_SCHNORRSIG
7818-
run_schnorrsig_tests();
7795+
{"schnorrsig_tests", run_schnorrsig_tests},
78197796
#endif
78207797

78217798
#ifdef ENABLE_MODULE_MUSIG
7822-
run_musig_tests();
7799+
{"musig_tests", run_musig_tests},
78237800
#endif
78247801

78257802
#ifdef ENABLE_MODULE_ELLSWIFT
7826-
run_ellswift_tests();
7803+
{"ellswift_tests", run_ellswift_tests},
78277804
#endif
78287805

78297806
/* util tests */
7830-
run_secp256k1_memczero_test();
7831-
run_secp256k1_is_zero_array_test();
7832-
run_secp256k1_byteorder_tests();
7833-
7834-
run_cmov_tests();
7835-
7836-
/*** Tear down test environment ***/
7837-
free(STATIC_CTX);
7838-
secp256k1_context_destroy(CTX);
7839-
7840-
testrand_finish();
7807+
{"secp256k1_memczero_test", run_secp256k1_memczero_test},
7808+
{"secp256k1_is_zero_array_test", run_secp256k1_is_zero_array_test},
7809+
{"secp256k1_byteorder_tests", run_secp256k1_byteorder_tests},
7810+
{"cmov_tests", run_cmov_tests},
7811+
{NULL, NULL}
7812+
};
78417813

7842-
printf("no problems found\n");
7843-
return EXIT_SUCCESS;
7844-
}
7814+
#endif /* SECP256K1_TESTS_C */

0 commit comments

Comments
 (0)