valFuzz 1.0
Loading...
Searching...
No Matches
valfuzz.hpp
Go to the documentation of this file.
1/*
2 * MIT License
3 *
4 * Copyright (c) 2024 Giovanni Santini
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to deal
8 * in the Software without restriction, including without limitation the rights
9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 * copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in
14 all
15 * copies or substantial portions of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23 * SOFTWARE.
24 *
25 */
26
27#pragma once
28
29#include <algorithm>
30#include <any>
31#include <atomic>
32#include <cstdlib>
33#include <ctime>
34#include <deque>
35#include <functional>
36#include <iostream>
37#include <limits>
38#include <mutex>
39#include <optional>
40#include <print>
41#include <string>
42#include <thread>
43#include <tuple>
44#include <type_traits>
45#include <typeinfo>
46#include <utility>
47#include <vector>
48
49namespace valfuzz
50{
51
52/* Assertions */
53
54#define ASSERT(cond) \
55 if (!(cond)) \
56 { \
57 std::lock_guard<std::mutex> lock(valfuzz::get_stream_mutex()); \
58 std::cerr << "test: " << test_name << ", line: " << __LINE__ << ", "; \
59 std::cerr << "Assertion failed: " << #cond << std::endl; \
60 }
61
62#define ASSERT_EQ(a, b) \
63 if ((a) != (b)) \
64 { \
65 std::lock_guard<std::mutex> lock(valfuzz::get_stream_mutex()); \
66 std::cerr << "test: " << test_name << ", line: " << __LINE__ << ", "; \
67 std::cerr << "Assertion failed: " << #a << " != " << #b << std::endl; \
68 }
69
70#define ASSERT_NE(a, b) \
71 if ((a) == (b)) \
72 { \
73 std::lock_guard<std::mutex> lock(valfuzz::get_stream_mutex()); \
74 std::cerr << "test: " << test_name << ", line: " << __LINE__ << ", "; \
75 std::cerr << "Assertion failed: " << #a << " == " << #b << std::endl; \
76 }
77
78#define ASSERT_LT(a, b) \
79 if ((a) >= (b)) \
80 { \
81 std::lock_guard<std::mutex> lock(valfuzz::get_stream_mutex()); \
82 std::cerr << "test: " << test_name << ", line: " << __LINE__ << ", "; \
83 std::cerr << "Assertion failed: " << #a << " < " << #b << std::endl; \
84 }
85
86#define ASSERT_LE(a, b) \
87 if ((a) > (b)) \
88 { \
89 std::lock_guard<std::mutex> lock(valfuzz::get_stream_mutex()); \
90 std::cerr << "test: " << test_name << ", line: " << __LINE__ << ", "; \
91 std::cerr << "Assertion failed: " << #a << " <= " << #b << std::endl; \
92 }
93
94#define ASSERT_GT(a, b) \
95 if ((a) <= (b)) \
96 { \
97 std::lock_guard<std::mutex> lock(valfuzz::get_stream_mutex()); \
98 std::cerr << "test: " << test_name << ", line: " << __LINE__ << ", "; \
99 std::cerr << "Assertion failed: " << #a << " > " << #b << std::endl; \
100 }
101
102#define ASSERT_GE(a, b) \
103 if ((a) < (b)) \
104 { \
105 std::lock_guard<std::mutex> lock(valfuzz::get_stream_mutex()); \
106 std::cerr << "test: " << test_name << ", line: " << __LINE__ << ", "; \
107 std::cerr << "Assertion failed: " << #a << " >= " << #b << std::endl; \
108 }
109
110#define ASSERT_THROW(expr, exception) \
111 { \
112 bool exception_thrown = false; \
113 try \
114 { \
115 expr; \
116 } \
117 catch (const exception &e) \
118 { \
119 exception_thrown = true; \
120 } \
121 if (!exception_thrown) \
122 { \
123 std::lock_guard<std::mutex> lock(valfuzz::get_stream_mutex()); \
124 std::cerr << "test: " << test_name << ", line: " << __LINE__ \
125 << ", "; \
126 std::cerr << "Exception not thrown: " << #exception << std::endl; \
127 } \
128 }
129
130#define ASSERT_NO_THROW(expr) \
131 { \
132 try \
133 { \
134 expr; \
135 } \
136 catch (...) \
137 { \
138 std::lock_guard<std::mutex> lock(valfuzz::get_stream_mutex()); \
139 std::cerr << "test: " << test_name << ", line: " << __LINE__ \
140 << ", "; \
141 std::cerr << "Exception thrown" << std::endl; \
142 } \
143 }
144
145std::mutex &get_stream_mutex();
146std::atomic<long unsigned int> &get_max_num_threads();
147std::atomic<bool> &get_is_threaded();
148std::atomic<bool> &get_verbose();
149std::atomic<bool> &get_header();
150std::atomic<bool> &get_do_fuzzing();
151std::optional<std::string> &get_test_one();
152std::optional<std::string> &get_fuzz_one();
153
154void set_multithreaded(bool is_threaded);
155void set_max_num_threads(long unsigned int max_num_threads);
156void set_verbose(bool verbose);
157void set_header(bool header);
158void set_do_fuzzing(bool do_fuzzing);
159void set_test_one(const std::string &test_one);
160void set_fuzz_one(const std::string &fuzz_one);
161
162void parse_args(int argc, char *argv[]);
163void print_header();
164
165/* Tests */
166
167typedef std::function<void(std::string)> test_function;
168typedef std::pair<std::string, test_function> test_pair;
169
170std::deque<test_pair> &get_tests();
171std::vector<std::thread> &get_thread_pool();
172std::mutex &get_test_mutex();
173long unsigned int get_num_tests();
174
175std::function<void()> &get_function_execute_before();
176std::function<void()> &get_function_execute_after();
177
178void set_function_execute_before(std::function<void()> f);
179void set_function_execute_after(std::function<void()> f);
180
181void add_test(const std::string &name, test_function test);
182
183std::optional<test_pair> pop_test_or_null();
184void run_one_test(const std::string &name);
185void _run_tests();
186void run_tests();
187
188#define TEST(name, pretty_name) \
189 void name([[maybe_unused]] const std::string &test_name); \
190 static struct name##_register \
191 { \
192 name##_register() \
193 { \
194 valfuzz::add_test(pretty_name, name); \
195 } \
196 } name##_register_instance; \
197 void name([[maybe_unused]] const std::string &test_name)
198
199#define BEFORE() \
200 void before(); \
201 static struct before##_register \
202 { \
203 before##_register() \
204 { \
205 valfuzz::set_function_execute_before(before); \
206 } \
207 } before##_register_instance; \
208 void before()
209
210#define AFTER() \
211 void after(); \
212 static struct after##_register \
213 { \
214 after##_register() \
215 { \
216 valfuzz::set_function_execute_after(after); \
217 } \
218 } after##_register_instance; \
219 void after()
220
221/* Fuzzer */
222
223#define MAX_RANDOM_STRING_LEN 1024
224
225template <typename T> T get_random()
226{
227 return T();
228}
229
230#define FUZZME(fun_name, pretty_name) \
231 void fun_name([[maybe_unused]] const std::string &test_name); \
232 static struct fun_name##_register \
233 { \
234 fun_name##_register() \
235 { \
236 valfuzz::add_fuzz_test(pretty_name, fun_name); \
237 } \
238 } fun_name##_register_instance; \
239 void fun_name([[maybe_unused]] const std::string &test_name)
240
241typedef std::function<void(std::string)> fuzz_function;
242typedef std::pair<std::string, fuzz_function> fuzz_pair;
243
244std::deque<fuzz_pair> &get_fuzz_tests();
245std::atomic<long unsigned int> &get_iterations();
246long unsigned int get_num_fuzz_tests();
247
249std::optional<fuzz_pair> pop_fuzz_or_null();
250void add_fuzz_test(const std::string &name, fuzz_function test);
251void run_one_fuzz(const std::string &name);
252void _run_fuzz_tests();
253void run_fuzz_tests();
254
255} // namespace valfuzz
std::pair< std::string, fuzz_function > fuzz_pair
Definition valfuzz.hpp:242
std::atomic< bool > & get_header()
Definition valfuzz.cpp:98
void run_fuzz_tests()
Definition valfuzz.cpp:353
long unsigned int get_num_fuzz_tests()
Definition valfuzz.cpp:122
std::function< void()> & get_function_execute_after()
Definition valfuzz.cpp:50
std::atomic< long unsigned int > & get_iterations()
Definition valfuzz.cpp:273
std::atomic< long unsigned int > & get_max_num_threads()
Definition valfuzz.cpp:86
void set_function_execute_before(std::function< void()> f)
Definition valfuzz.cpp:152
void _run_tests()
Definition valfuzz.cpp:236
std::deque< test_pair > & get_tests()
Definition valfuzz.cpp:32
long unsigned int get_num_tests()
Definition valfuzz.cpp:68
void _run_fuzz_tests()
Definition valfuzz.cpp:329
std::vector< std::thread > & get_thread_pool()
Definition valfuzz.cpp:80
void run_tests()
Definition valfuzz.cpp:251
std::atomic< bool > & get_verbose()
Definition valfuzz.cpp:92
void run_one_fuzz(const std::string &name)
Definition valfuzz.cpp:300
void run_one_test(const std::string &name)
Definition valfuzz.cpp:211
void increment_iterations()
Definition valfuzz.cpp:279
std::atomic< bool > & get_do_fuzzing()
Definition valfuzz.cpp:104
void print_header()
Definition valfuzz.cpp:451
void set_function_execute_after(std::function< void()> f)
Definition valfuzz.cpp:158
void add_fuzz_test(const std::string &name, fuzz_function test)
Definition valfuzz.cpp:189
std::mutex & get_test_mutex()
void set_do_fuzzing(bool do_fuzzing)
Definition valfuzz.cpp:164
void set_fuzz_one(const std::string &fuzz_one)
Definition valfuzz.cpp:176
std::optional< std::string > & get_fuzz_one()
Definition valfuzz.cpp:116
void set_test_one(const std::string &test_one)
Definition valfuzz.cpp:170
std::pair< std::string, test_function > test_pair
Definition valfuzz.hpp:168
void set_multithreaded(bool is_threaded)
Definition valfuzz.cpp:128
std::atomic< bool > & get_is_threaded()
Definition valfuzz.cpp:74
std::function< void(std::string)> test_function
Definition valfuzz.hpp:167
void set_header(bool header)
Definition valfuzz.cpp:146
void set_max_num_threads(long unsigned int max_num_threads)
Definition valfuzz.cpp:134
std::function< void()> & get_function_execute_before()
Definition valfuzz.cpp:44
std::optional< std::string > & get_test_one()
Definition valfuzz.cpp:110
void add_test(const std::string &name, test_function test)
Definition valfuzz.cpp:182
void parse_args(int argc, char *argv[])
Definition valfuzz.cpp:375
std::optional< fuzz_pair > pop_fuzz_or_null()
Definition valfuzz.cpp:285
T get_random()
Definition valfuzz.hpp:225
void set_verbose(bool verbose)
Definition valfuzz.cpp:140
std::deque< fuzz_pair > & get_fuzz_tests()
std::function< void(std::string)> fuzz_function
Definition valfuzz.hpp:241
std::mutex & get_stream_mutex()
Definition valfuzz.cpp:62
std::optional< test_pair > pop_test_or_null()
Definition valfuzz.cpp:196