valFuzz 1.2.0
Loading...
Searching...
No Matches
valfuzz.cpp
Go to the documentation of this file.
1// SPDX-License-Identifier: MIT
2// Author: Giovanni Santini
3// Mail: giovanni.santini@proton.me
4// Github: @San7o
5
6#include <random>
7#include <valfuzz/valfuzz.hpp>
8
9namespace valfuzz
10{
11
12std::atomic<bool> &get_header()
13{
14#if __cplusplus >= 202002L // C++20
15 constinit
16#endif
17 static std::atomic<bool>
18 header = true;
19 return header;
20}
21
22std::atomic<bool> &get_do_fuzzing()
23{
24#if __cplusplus >= 202002L // C++20
25 constinit
26#endif
27 static std::atomic<bool>
28 do_fuzzing = false;
29 return do_fuzzing;
30}
31
32std::optional<std::string> &get_test_one()
33{
34#if __cplusplus >= 202002L // C++20
35 constinit
36#endif
37 static std::optional<std::string>
38 test_one = std::nullopt;
39 return test_one;
40}
41
42std::optional<std::string> &get_fuzz_one()
43{
44#if __cplusplus >= 202002L // C++20
45 constinit
46#endif
47 static std::optional<std::string>
48 fuzz_one = std::nullopt;
49 return fuzz_one;
50}
51
52std::atomic<long unsigned int> &get_seed()
53{
54 static std::atomic<long unsigned int> seed =
55 (long unsigned int) std::time(nullptr);
56 return seed;
57}
58
59void set_multithreaded(bool is_threaded)
60{
61 auto &is_threaded_ref = get_is_threaded();
62 is_threaded_ref = is_threaded;
63}
64
65void set_max_num_threads(long unsigned int max_num_threads)
66{
67 auto &max_num_threads_ref = get_max_num_threads();
68 max_num_threads_ref = max_num_threads;
69}
70
71void set_verbose(bool verbose)
72{
73 auto &verbose_ref = get_verbose();
74 verbose_ref = verbose;
75}
76
77void set_header(bool header)
78{
79 auto &header_ref = get_header();
80 header_ref = header;
81}
82
83void set_do_fuzzing(bool do_fuzzing)
84{
85 auto &do_fuzzing_ref = get_do_fuzzing();
86 do_fuzzing_ref = do_fuzzing;
87}
88
89void set_test_one(const std::string &test_one)
90{
91 auto &test_one_ref = get_test_one();
92 test_one_ref = test_one;
93}
94
95void set_fuzz_one(const std::string &fuzz_one)
96{
97 auto &fuzz_one_ref = get_fuzz_one();
98 fuzz_one_ref = fuzz_one;
99}
100
101void set_seed(long unsigned int new_seed)
102{
103 auto &seed = get_seed();
104 seed = new_seed;
105}
106
107char valfuzz_banner[] = " _ _____ \n"
108 " __ ____ _| | ___| _ ________\n"
109 " \\ \\ / / _` | | |_ | | | |_ /_ /\n"
110 " \\ V / (_| | | _|| |_| |/ / / / \n"
111 " \\_/ \\__,_|_|_| \\__,_/___/___|\n"
112 " \n"
113 "A modern testing & fuzzing library for C++\n";
114
116{
117 bool verbose = get_verbose();
118 bool is_threaded = get_is_threaded();
119 bool do_fuzzing = get_do_fuzzing();
120 bool do_benchmarks = get_do_benchmarks();
121 long unsigned int max_num_threads = get_max_num_threads();
122 std::string reporter_id = get_reporter();
123 std::lock_guard<std::mutex> lock(get_stream_mutex());
124 std::cout << valfuzz_banner;
125 std::cout << "Settings:\n";
126 std::cout << " - Multithreaded: " << is_threaded << "\n";
127 std::cout << " - Max threads: " << max_num_threads << "\n";
128 std::cout << " - Run Fuzzs: " << do_fuzzing << "\n";
129 std::cout << " - Run Benchmarks: " << do_benchmarks << "\n";
130 std::cout << " - Verbose: " << verbose << "\n";
131 std::cout << " - Reporter: " << reporter_id << "\n";
132 std::cout << "\n";
133}
134
135void parse_args(int argc, char *argv[])
136{
137 for (int i = 1; i < argc; i++)
138 {
139 if (std::string(argv[i]) == "--test")
140 {
141 if (i + 1 < argc)
142 {
143 set_test_one(argv[i + 1]);
144 i++;
145 }
146 else
147 {
148 std::cerr << "Test name not provided\n";
149 std::exit(1);
150 }
151 }
152 else if (std::string(argv[i]) == "--fuzz")
153 {
154 set_do_fuzzing(true);
155 }
156 else if (std::string(argv[i]) == "--fuzz-one")
157 {
158 if (i + 1 < argc)
159 {
160 set_do_fuzzing(true);
161 set_fuzz_one(argv[i + 1]);
162 i++;
163 }
164 else
165 {
166 std::cerr << "Fuzz test name not provided\n";
167 std::exit(1);
168 }
169 }
170 else if (std::string(argv[i]) == "--benchmark")
171 {
172 set_do_benchmarks(true);
173 }
174 else if (std::string(argv[i]) == "--num-iterations")
175 {
176 if (i + 1 < argc)
177 {
178 set_num_iterations_benchmark(std::stoi(argv[i + 1]));
179 i++;
180 }
181 else
182 {
183 std::cerr << "Number of iterations not provided\n";
184 std::exit(1);
185 }
186 }
187 else if (std::string(argv[i]) == "--run-one-benchmark")
188 {
189 if (i + 1 < argc)
190 {
191 bool found = false;
192 for (auto b : get_benchmarks())
193 {
194 if (b.first == argv[i + 1])
195 {
196 found = true;
197 break;
198 }
199 }
200 if (!found)
201 {
202 std::cerr << "Benchmark \"" << argv[i + 1] << "\" not found\n";
203 std::exit(1);
204 }
205 set_do_benchmarks(true);
207 set_one_benchmark(argv[i + 1]);
208 i++;
209 }
210 }
211 else if (std::string(argv[i]) == "--report")
212 {
213 set_save_to_file(true);
214 if (i + 1 < argc)
215 {
216 set_save_file(argv[i + 1]);
217 i++;
218 }
219 else
220 {
221 std::cerr << "Report file not provided\n";
222 std::exit(1);
223 }
224 }
225 else if (std::string(argv[i]) == "--reporter")
226 {
227 if (i + 1 < argc && reporter_eg.has(argv[i + 1]))
228 {
229 set_reporter(argv[i + 1]);
230 i++;
231 }
232 else
233 {
234 std::cerr << "Reporter " << argv[i + 1] << " unrecognised\n";
235 std::exit(1);
236 }
237 }
238 else if (std::string(argv[i]) == "--no-multithread")
239 {
240 set_multithreaded(false);
241 }
242 else if (std::string(argv[i]) == "--verbose")
243 {
244 set_verbose(true);
245 }
246 else if (std::string(argv[i]) == "--max-threads")
247 {
248 if (i + 1 < argc)
249 {
250 set_max_num_threads(std::stoul(argv[i + 1]));
251 i++;
252 }
253 else
254 {
255 std::cerr << "Number of threads not provided\n";
256 std::exit(1);
257 }
258 }
259 else if (std::string(argv[i]) == "--no-header")
260 {
261 set_header(false);
262 }
263 else if (std::string(argv[i]) == "--seed")
264 {
265 if (i + 1 < argc)
266 {
267 set_seed(std::stoul(argv[i + 1]));
268 i++;
269 }
270 else
271 {
272 std::cerr << "Seed not provided\n";
273 std::exit(1);
274 }
275 }
276 else if (std::string(argv[i]) == "--help")
277 {
278 std::cout << valfuzz_banner << "\n";
279 std::cout << "Usage: valfuzz [options]\n";
280 std::cout << "Options:\n";
281 std::cout << "\n";
282 std::cout << " TESTS \n";
283 std::cout << " --test <name>: run a specific test\n";
284 std::cout << " --no-multithread: run tests in a single thread\n";
285 std::cout << " --max-threads <num>: set the maximum number of threads\n";
286 std::cout << "\n";
287 std::cout << " FUZZING \n";
288 std::cout << " --fuzz: run fuzz tests\n";
289 std::cout << " --fuzz-one <name>: run a specific fuzz test\n";
290 std::cout << "\n";
291 std::cout << " BENCHMARK \n";
292 std::cout << " --benchmark: run benchmarks\n";
293 std::cout << " --num-iterations <num>: set the number of "
294 "iterations for benchmarks\n";
295 std::cout << " --run-one-benchmark <name>: run a specific benchmark\n";
296 std::cout << " --report <file>: save benchmark results to a file\n";
297 std::cout
298 << " --reporter <name>: use a custom reporter, currently supported\n";
299 std::cout << " are default, csv, none\n";
300 std::cout << "\n";
301 std::cout << " GENERAL \n";
302 std::cout << " --verbose: print test names\n";
303 std::cout << " --no-header: do not print the header at the start\n";
304 std::cout << " --seed <seed>: set the seed for PRNG\n";
305 std::cout << " --help: print this help message\n";
306 std::exit(0);
307 }
308 else
309 {
310 std::cerr << "Unknown option: " << argv[i] << "\n";
311 std::exit(1);
312 }
313 }
314}
315
316int main(int argc, char **argv)
317{
318 valfuzz::parse_args(argc, argv);
321
322 auto &seed = valfuzz::get_seed();
323 std::srand((unsigned int) seed);
324
325 std::mt19937 gen = valfuzz::get_random_engine();
326 gen.seed(seed.load());
327
329
331 {
332 {
333 std::lock_guard<std::mutex> lock(valfuzz::get_stream_mutex());
334 std::cout << "Seed: " << seed << "\n";
335 std::cout << "Running " << valfuzz::get_num_benchmarks()
336 << " benchmarks...\n";
337 }
340 {
341 std::lock_guard<std::mutex> lock(valfuzz::get_stream_mutex());
342 std::cout << "Saved results to file \n";
343 valfuzz::get_save_file().close();
344 }
345 }
346 else if (!valfuzz::get_do_fuzzing())
347 {
348 if (valfuzz::get_test_one().has_value())
349 {
351 }
352 else
353 {
354 {
355 std::lock_guard<std::mutex> lock(valfuzz::get_stream_mutex());
356 std::cout << "Seed: " << seed << "\n";
357 std::cout << "Running " << valfuzz::get_num_tests() << " tests...\n";
358 }
360 }
361 }
362 else
363 {
364 if (valfuzz::get_fuzz_one().has_value())
365 {
367 }
368 else
369 {
370 std::lock_guard<std::mutex> lock(valfuzz::get_stream_mutex());
371 std::cout << "Seed: " << seed << "\n";
372 std::cout << "Running " << valfuzz::get_num_fuzz_tests()
373 << " fuzz tests...\n";
374 }
376 }
377
379
381 {
382 std::cerr << "Failed\n";
383 return 1;
384 }
385 else
386 {
387 std::cout << "Done\n";
388 }
389
390 return 0;
391}
392
393} // namespace valfuzz
bool has(std::string id)
Definition reporter.hpp:65
std::atomic< bool > & get_header()
Definition valfuzz.cpp:12
bool & get_do_benchmarks()
Definition benchmark.cpp:62
void run_fuzz_tests()
Definition fuzz.cpp:168
void set_save_file(const std::filesystem::path &save_to_file_path)
long unsigned int get_num_fuzz_tests()
Definition fuzz.cpp:71
void set_reporter(std::string rep)
Definition reporter.cpp:26
std::function< void()> & get_function_execute_after()
Definition test.cpp:39
void set_num_iterations_benchmark(int num_iterations_benchmark)
std::atomic< long unsigned int > & get_max_num_threads()
Definition common.cpp:30
void set_save_to_file(bool save_to_file)
long unsigned int get_num_tests()
Definition test.cpp:17
int main(int argc, char **argv)
Definition valfuzz.cpp:316
void run_tests()
Definition test.cpp:125
std::atomic< bool > & get_verbose()
Definition common.cpp:20
void run_one_fuzz(const std::string &name)
Definition fuzz.cpp:115
void run_one_test(const std::string &name)
Definition test.cpp:85
std::atomic< bool > & get_do_fuzzing()
Definition valfuzz.cpp:22
char valfuzz_banner[]
Definition valfuzz.cpp:107
void print_header()
Definition valfuzz.cpp:115
void set_do_fuzzing(bool do_fuzzing)
Definition valfuzz.cpp:83
void set_fuzz_one(const std::string &fuzz_one)
Definition valfuzz.cpp:95
std::optional< std::string > & get_fuzz_one()
Definition valfuzz.cpp:42
void set_test_one(const std::string &test_one)
Definition valfuzz.cpp:89
void set_one_benchmark(const std::string &one_benchmark)
void set_multithreaded(bool is_threaded)
Definition valfuzz.cpp:59
std::ofstream & get_save_file()
std::atomic< bool > & get_is_threaded()
Definition common.cpp:49
void set_do_benchmarks(bool do_benchmarks)
void set_header(bool header)
Definition valfuzz.cpp:77
unsigned long get_num_benchmarks()
Definition benchmark.cpp:86
void run_benchmarks()
std::atomic< bool > & get_save_to_file()
Definition benchmark.cpp:11
reporter_engine reporter_eg
Definition reporter.cpp:10
void set_max_num_threads(long unsigned int max_num_threads)
Definition valfuzz.cpp:65
std::atomic< bool > & get_has_failed_once()
Definition test.cpp:23
void set_seed(long unsigned int new_seed)
Definition valfuzz.cpp:101
std::function< void()> & get_function_execute_before()
Definition test.cpp:33
std::atomic< long unsigned int > & get_seed()
Definition valfuzz.cpp:52
std::optional< std::string > & get_test_one()
Definition valfuzz.cpp:32
void parse_args(int argc, char *argv[])
Definition valfuzz.cpp:135
std::mt19937 & get_random_engine()
Definition fuzz.cpp:11
std::deque< benchmark_pair > & get_benchmarks()
Definition benchmark.cpp:71
void set_verbose(bool verbose)
Definition valfuzz.cpp:71
void set_run_one_benchmark(bool run_one_benchmark)
std::mutex & get_stream_mutex()
Definition common.cpp:11
std::string & get_reporter()
Definition reporter.cpp:20