/ src / secp256k1 / src / unit_test.h
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 */