34 static std::deque<test_pair> registered_tests = {};
35 return registered_tests;
40 static std::deque<fuzz_pair> registered_fuzzs = {};
41 return registered_fuzzs;
46 static std::function<void()> function_execute_before = []() {};
47 return function_execute_before;
52 static std::function<void()> function_execute_after = []() {};
53 return function_execute_after;
58 constinit static std::mutex tests_mutex;
64 constinit static std::mutex stream_mutex;
76 constinit static std::atomic<bool> is_threaded =
true;
82 constinit static std::vector<std::thread> thread_pool;
88 constinit static std::atomic<long unsigned int> max_num_threads = 4;
89 return max_num_threads;
94 constinit static std::atomic<bool> verbose =
false;
100 constinit static std::atomic<bool> header =
true;
106 constinit static std::atomic<bool> do_fuzzing =
false;
112 constinit static std::optional<std::string> test_one = std::nullopt;
118 constinit static std::optional<std::string> fuzz_one = std::nullopt;
131 is_threaded_ref = is_threaded;
137 max_num_threads_ref = max_num_threads;
143 verbose_ref = verbose;
155 function_execute_before = f;
161 function_execute_after = f;
167 do_fuzzing_ref = do_fuzzing;
173 test_one_ref = test_one;
179 fuzz_one_ref = fuzz_one;
186 tests.push_back({name, test});
193 fuzzs.push_back({name, fuzz});
201 std::lock_guard<std::mutex> lock(tests_mutex);
215 for (
auto &test : tests)
217 if (test.first == name)
221 std::print(
"Running test: {}\n", test.first);
224 test.second(test.first);
231 std::print(
"Test \"{}\" not found\n", name);
238 auto test = std::optional<test_pair>{};
245 std::print(
"Running test: \"{}\"\n", test.value().first);
247 test.value().second(test.value().first);
257 for (
long unsigned int i = 0;
260 thread_pool.push_back(std::thread(
_run_tests));
275 constinit static std::atomic<long unsigned int> iterations = 0;
290 std::lock_guard<std::mutex> lock(fuzzs_mutex);
303 std::deque<fuzz_pair> the_fuzz;
304 std::for_each(fuzzs.begin(), fuzzs.end(),
307 if (fuzz.first == name)
309 for (long unsigned int i = 0;
310 i < get_max_num_threads(); i++)
312 the_fuzz.push_back(fuzz);
316 if (the_fuzz.empty())
319 std::print(
"Fuzz test \"{}\" not found\n", name);
325 std::print(
"Running fuzz test: {}\n", name);
331 auto fuzz = std::optional<fuzz_pair>{};
337 std::print(
"Running fuzz: \"{}\"\n", fuzz.value().first);
339 fuzz.value().second(fuzz.value().first);
343 if (iterations % 1000000 == 0)
346 std::print(
"Iterations: {}\n", iterations);
359 for (
long unsigned int i = 0;
377 for (
int i = 1; i < argc; i++)
379 if (std::string(argv[i]) ==
"--test")
387 else if (std::string(argv[i]) ==
"--fuzz")
391 else if (std::string(argv[i]) ==
"--fuzz-one")
400 else if (std::string(argv[i]) ==
"--no-multithread")
404 else if (std::string(argv[i]) ==
"--verbose")
408 else if (std::string(argv[i]) ==
"--max-threads")
416 else if (std::string(argv[i]) ==
"--no-header")
420 else if (std::string(argv[i]) ==
"--help")
422 std::print(
"Usage: valfuzz [options]\n");
423 std::print(
"Options:\n");
424 std::print(
" --test <name>: run a specific test\n");
425 std::print(
" --fuzz: run fuzz tests\n");
426 std::print(
" --fuzz-one <name>: run a specific fuzz test\n");
427 std::print(
" --no-multithread: run tests in a single thread\n");
428 std::print(
" --verbose: print test names\n");
430 " --max-threads <num>: set the maximum number of threads\n");
431 std::print(
" --no-header: do not print the header at the start\n");
432 std::print(
" --help: print this help message\n");
437 std::print(
"Unknown option: {}\n", argv[i]);
444 " __ ____ _| | ___| _ ________\n"
445 " \\ \\ / / _` | | |_ | | | |_ /_ /\n"
446 " \\ V / (_| | | _|| |_| |/ / / / \n"
447 " \\_/ \\__,_|_|_| \\__,_/___/___|\n"
449 "A modern testing & fuzzing library for C++\n";
458 std::print(
"Settings:\n");
459 std::print(
" - Multithreaded: {}\n", is_threaded);
460 std::print(
" - Max threads: {}\n", max_num_threads);
461 std::print(
" - Verbose: {}\n", verbose);
465template <>
int get_random<int>()
470template <>
float get_random<float>()
472 return static_cast<float>(std::rand());
475template <>
double get_random<double>()
478 static_cast<double>(std::rand()) /
static_cast<double>(RAND_MAX);
479 return static_cast<double>(std::rand()) + dot;
482template <>
char get_random<char>()
484 return static_cast<char>(std::rand() % 256);
487template <>
bool get_random<bool>()
489 return static_cast<bool>(std::rand() % 2);
492template <> std::string get_random<std::string>()
495 std::string random_string =
"";
496 for (
int i = 0; i < len; i++)
498 random_string += get_random<char>();
500 return random_string;
511 unsigned int seed = (
unsigned int) std::time(
nullptr);
526 std::print(
"Seed: {}\n", seed);
541 std::print(
"Seed: {}\n", seed);
542 std::print(
"Running {} fuzz tests...\n",
549 std::print(
"Done\n");
std::pair< std::string, fuzz_function > fuzz_pair
std::atomic< bool > & get_header()
long unsigned int get_num_fuzz_tests()
std::function< void()> & get_function_execute_after()
std::atomic< long unsigned int > & get_iterations()
std::deque< fuzz_pair > & get_fuzzs()
std::atomic< long unsigned int > & get_max_num_threads()
void set_function_execute_before(std::function< void()> f)
std::deque< test_pair > & get_tests()
long unsigned int get_num_tests()
std::vector< std::thread > & get_thread_pool()
std::mutex & get_tests_mutex()
std::atomic< bool > & get_verbose()
void run_one_fuzz(const std::string &name)
void run_one_test(const std::string &name)
void increment_iterations()
std::atomic< bool > & get_do_fuzzing()
void set_function_execute_after(std::function< void()> f)
void add_fuzz_test(const std::string &name, fuzz_function test)
void set_do_fuzzing(bool do_fuzzing)
void set_fuzz_one(const std::string &fuzz_one)
std::optional< std::string > & get_fuzz_one()
void set_test_one(const std::string &test_one)
std::pair< std::string, test_function > test_pair
void set_multithreaded(bool is_threaded)
std::atomic< bool > & get_is_threaded()
std::function< void(std::string)> test_function
void set_header(bool header)
void set_max_num_threads(long unsigned int max_num_threads)
std::function< void()> & get_function_execute_before()
std::optional< std::string > & get_test_one()
void add_test(const std::string &name, test_function test)
void parse_args(int argc, char *argv[])
std::optional< fuzz_pair > pop_fuzz_or_null()
void set_verbose(bool verbose)
std::function< void(std::string)> fuzz_function
std::mutex & get_stream_mutex()
std::optional< test_pair > pop_test_or_null()
int main(int argc, char **argv)
#define MAX_RANDOM_STRING_LEN