GCC Code Coverage Report


Directory: ./
File: src/iguana/tests/iguana_test.cc
Date: 2025-01-05 09:03:17
Exec Total Coverage
Lines: 118 145 81.4%
Functions: 7 10 70.0%
Branches: 114 229 49.8%

Line Branch Exec Source
1 #include <getopt.h>
2
3 #include "TestAlgorithm.h"
4 #include "TestMultithreading.h"
5 #include "TestConfig.h"
6 #include "TestLogger.h"
7 #include "TestValidator.h"
8
9 29 int main(int argc, char** argv)
10 {
11 // user parameters
12 29 std::string command = "";
13
1/2
✓ Branch 0 taken 29 times.
✗ Branch 1 not taken.
29 std::string data_file = "";
14 29 int num_events = 10;
15
1/2
✓ Branch 0 taken 29 times.
✗ Branch 1 not taken.
29 std::string algo_name = "";
16 int test_num = 0;
17 29 int num_threads = 0;
18
1/2
✓ Branch 0 taken 29 times.
✗ Branch 1 not taken.
29 std::string concurrency_model = "";
19 bool vary_run = false;
20
2/4
✓ Branch 0 taken 29 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 29 times.
✗ Branch 3 not taken.
29 std::string output_dir = "";
21 bool verbose = false;
22 std::vector<std::string> bank_names;
23 std::vector<std::string> prerequisite_algos;
24
25 // get the command
26
1/2
✓ Branch 0 taken 29 times.
✗ Branch 1 not taken.
29 auto exe = std::string(argv[0]);
27 1 auto UsageCommands = [&](int exit_code)
28 {
29 1 fmt::print("\nUSAGE: {} [COMMAND] [OPTIONS]...\n", exe);
30 1 fmt::print("\n COMMANDS:\n\n");
31 1 fmt::print(" {:<20} {}\n", "algorithm", "call `Run` on an algorithm");
32 1 fmt::print(" {:<20} {}\n", "multithreading", "call `Run` on an algorithm, multithreaded");
33 1 fmt::print(" {:<20} {}\n", "validator", "run an algorithm's validator");
34 1 fmt::print(" {:<20} {}\n", "unit", "call `Test` on an algorithm, for unit tests");
35 1 fmt::print(" {:<20} {}\n", "config", "test config file parsing");
36 1 fmt::print(" {:<20} {}\n", "logger", "test Logger");
37 1 fmt::print("\n OPTIONS:\n\n");
38 1 fmt::print(" Each command has its own set of OPTIONS; either provide no OPTIONS\n");
39 1 fmt::print(" or use the --help option for more usage information about a specific command\n");
40 1 fmt::print("\n");
41 1 return exit_code;
42 29 };
43
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 28 times.
29 if(argc <= 1)
44
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 return UsageCommands(2);
45
1/2
✓ Branch 0 taken 28 times.
✗ Branch 1 not taken.
28 command = std::string(argv[1]);
46
2/4
✓ Branch 0 taken 28 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 28 times.
28 if(command == "--help" || command == "-h")
47 return UsageCommands(0);
48 // omit the command, for getopt
49 28 argv++;
50 28 argc--;
51
52 // usage options
53 // clang-format off
54
1/2
✓ Branch 0 taken 5 times.
✗ Branch 1 not taken.
5 auto UsageOptions = [&](int exit_code)
55 {
56 std::unordered_map<std::string, std::function<void()>> print_option = {
57 {"f", [&]()
58 {
59 3 fmt::print(" {:<20} {}\n", "-f FILE", "input data file");
60 }},
61
1/2
✓ Branch 0 taken 5 times.
✗ Branch 1 not taken.
8 {"n", [&]()
62 {
63 3 fmt::print(" {:<20} {}\n", "-n NUM_EVENTS", "number of events from the data file");
64 3 fmt::print(" {:<20} set to 0 to process ALL events\n", "");
65 3 fmt::print(" {:<20} default: {}\n", "", num_events);
66 3 }},
67
68 {"a-algo", [&]()
69 {
70 2 fmt::print(" {:<20} {}\n", "-a ALGORITHM", "the name of the algorithm");
71 }},
72 {"a-vdor", [&]()
73 {
74 1 fmt::print(" {:<20} {}\n", "-a VALIDATOR", "the name of the validator");
75 }},
76 3 {"b", [&]()
77 {
78 3 fmt::print(" {:<20} {}\n", "-b BANKS", "add a single bank to process");
79 3 fmt::print(" {:<20} you may add as many banks as you need (-b BANK1 -b BANK2 ...)\n", "");
80 3 fmt::print(" {:<20} default: if you do not add any banks, ALL of them will be used\n", "");
81 3 }},
82 2 {"p", [&]()
83 {
84 2 fmt::print(" {:<20} {}\n", "-p PREREQUISITE_ALGOS", "add a prerequisite algorithm");
85 2 fmt::print(" {:<20} these are the algorithms needed upstream of ALGORITHM\n", "");
86 2 fmt::print(" {:<20} this option is repeatable\n", "");
87 2 fmt::print(" {:<20} default: no prerequisites\n", "");
88 2 }},
89 {"t", [&]()
90 {
91 1 fmt::print(" {:<20} {}\n", "-t TESTNUM", "test number");
92 }},
93
1/2
✓ Branch 0 taken 5 times.
✗ Branch 1 not taken.
5 {"j", [&]()
94 {
95 fmt::print(" {:<20} {}\n", "-j NUM_THREADS", "number of threads to run");
96 fmt::print(" {:<20} - if = 0: run with `std::thread::hardware_concurrency()` threads\n", "");
97 fmt::print(" {:<20} - if > 0: run with NUM_THREADS threads\n", "");
98 fmt::print(" {:<20} default: {}\n", "", num_threads);
99 }},
100 {"m", [&]()
101 {
102 fmt::print(" {:<20} {}\n", "-m CONCURRENCY_MODEL", "concurrency model");
103 fmt::print(" {:<20} 'memoize' is currently the only option\n", "");
104 }},
105 {"V", [&]()
106 {
107 fmt::print(" {:<20} {}\n", "-V", "randomly vary the run number");
108 fmt::print(" {:<20} this is for testing run-dependent configuration thread safety\n", "");
109 }},
110
1/2
✓ Branch 0 taken 5 times.
✗ Branch 1 not taken.
5 {"o", [&]()
111 {
112
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 fmt::print(" {:<20} {}\n", "-o OUTPUT_DIR", fmt::format("if specified, {} output will write to this directory;", command));
113 1 fmt::print(" {:<20} if not specified, output will not be written\n", "");
114 1 }},
115 {"v", [&]()
116 {
117 4 fmt::print(" {:<20} {}\n", "-v", "increase verbosity");
118
2/4
✓ Branch 0 taken 60 times.
✓ Branch 1 taken 5 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
65 }}};
119 std::map<std::string, std::vector<std::string>> available_options = {
120 {"algorithm", {"f", "n", "a-algo", "b", "p"}},
121 {"unit", {"f", "n", "a-algo", "b", "p"}},
122 {"multithreading", {"f", "n", "a-algo", "b", "p", "j", "m", "V"}},
123 {"validator", {"f", "n", "a-vdor", "b", "o"}},
124 {"config", {"t"}},
125 {"logger", {}}
126
14/28
✓ Branch 0 taken 5 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 5 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 5 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 5 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 5 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 5 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 5 times.
✗ Branch 13 not taken.
✓ Branch 14 taken 5 times.
✗ Branch 15 not taken.
✓ Branch 16 taken 5 times.
✗ Branch 17 not taken.
✓ Branch 18 taken 5 times.
✗ Branch 19 not taken.
✓ Branch 20 taken 5 times.
✗ Branch 21 not taken.
✗ Branch 22 not taken.
✓ Branch 23 taken 5 times.
✓ Branch 24 taken 30 times.
✓ Branch 25 taken 5 times.
✗ Branch 26 not taken.
✗ Branch 27 not taken.
65 };
127
2/2
✓ Branch 0 taken 30 times.
✓ Branch 1 taken 5 times.
35 for(auto& it : available_options)
128
1/2
✓ Branch 0 taken 30 times.
✗ Branch 1 not taken.
60 it.second.push_back("v");
129
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 1 times.
5 if(auto it{available_options.find(command)}; it != available_options.end()) {
130
2/4
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
4 fmt::print("\nUSAGE: {} {} [OPTIONS]...\n", exe, command);
131 4 fmt::print("\n OPTIONS:\n\n");
132
2/2
✓ Branch 0 taken 20 times.
✓ Branch 1 taken 4 times.
24 for(auto available_opt : it->second) {
133 print_option.at(available_opt)();
134 20 fmt::print("\n");
135 }
136 4 return exit_code;
137 }
138 else {
139
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 fmt::print(stderr, "ERROR: unknown command '{}'\n", command);
140 1 return 1;
141 }
142
6/16
✓ Branch 0 taken 5 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 5 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 5 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 5 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 5 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 5 times.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
30 };
143 // clang-format on
144
145
4/6
✓ Branch 0 taken 22 times.
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 22 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 6 times.
✗ Branch 5 not taken.
28 auto first_option = argc >= 2 ? std::string(argv[1]) : "";
146
2/4
✓ Branch 0 taken 28 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 28 times.
✗ Branch 3 not taken.
28 if(first_option == "--help" || first_option == "-h")
147 return UsageOptions(0);
148
4/4
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 22 times.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 5 times.
28 if(argc <= 2 && command != "logger")
149
1/2
✓ Branch 0 taken 5 times.
✗ Branch 1 not taken.
5 return UsageOptions(2);
150
151 // parse option arguments
152 int opt;
153
2/2
✓ Branch 0 taken 100 times.
✓ Branch 1 taken 23 times.
123 while((opt = getopt(argc, argv, "hf:n:a:b:p:t:j:m:Vo:v|")) != -1) {
154
8/13
✗ Branch 0 not taken.
✓ Branch 1 taken 19 times.
✓ Branch 2 taken 19 times.
✓ Branch 3 taken 19 times.
✓ Branch 4 taken 26 times.
✓ Branch 5 taken 3 times.
✓ Branch 6 taken 3 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✓ Branch 9 taken 8 times.
✓ Branch 10 taken 3 times.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
100 switch(opt) {
155 case 'h':
156 return UsageOptions(0);
157 case 'f':
158
1/2
✓ Branch 0 taken 19 times.
✗ Branch 1 not taken.
19 data_file = std::string(optarg);
159 19 break;
160 case 'n':
161
1/2
✓ Branch 0 taken 19 times.
✗ Branch 1 not taken.
38 num_events = std::stoi(optarg);
162 19 break;
163 case 'a':
164
1/2
✓ Branch 0 taken 19 times.
✗ Branch 1 not taken.
19 algo_name = std::string(optarg);
165 19 break;
166 case 'b':
167
1/2
✓ Branch 0 taken 26 times.
✗ Branch 1 not taken.
26 bank_names.push_back(std::string(optarg));
168 26 break;
169 case 'p':
170
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 prerequisite_algos.push_back(std::string(optarg));
171 3 break;
172 case 't':
173
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 test_num = std::stoi(optarg);
174 3 break;
175 case 'j':
176 num_threads = std::stoi(optarg);
177 if(num_threads == 0)
178 num_threads = std::thread::hardware_concurrency();
179 break;
180 case 'm':
181 concurrency_model = std::string(optarg);
182 break;
183 case 'V':
184 vary_run = true;
185 break;
186 case 'o':
187
1/2
✓ Branch 0 taken 8 times.
✗ Branch 1 not taken.
8 output_dir = std::string(optarg);
188 8 break;
189 3 case 'v':
190 verbose = true;
191 3 break;
192 default:
193 return UsageOptions(2);
194 }
195 }
196
197 // list of ALL banks needed by the algorithms and validators; we need all of them here,
198 // so that the caller does not have to specifiy the banks
199 std::vector<std::string> const all_bank_names = {
200 "RUN::config",
201 "REC::Particle",
202 "REC::Calorimeter",
203 "REC::Track",
204 "REC::Scintillator",
205
3/4
✓ Branch 0 taken 23 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✓ Branch 3 taken 11 times.
46 "REC::Traj"};
206
2/2
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 11 times.
23 if(bank_names.empty())
207
1/2
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
12 bank_names = all_bank_names;
208
209
1/2
✓ Branch 0 taken 23 times.
✗ Branch 1 not taken.
23 fmt::print("TEST IGUANA:\n");
210
1/2
✓ Branch 0 taken 23 times.
✗ Branch 1 not taken.
23 fmt::print(" {:>20} = {}\n", "command", command);
211
1/2
✓ Branch 0 taken 23 times.
✗ Branch 1 not taken.
23 fmt::print(" {:>20} = {}\n", "data_file", data_file);
212
1/2
✓ Branch 0 taken 23 times.
✗ Branch 1 not taken.
23 fmt::print(" {:>20} = {}\n", "num_events", num_events);
213
1/2
✓ Branch 0 taken 23 times.
✗ Branch 1 not taken.
23 fmt::print(" {:>20} = {}\n", "algo_name", algo_name);
214
1/2
✓ Branch 0 taken 23 times.
✗ Branch 1 not taken.
23 fmt::print(" {:>20} = {}\n", "banks", fmt::join(bank_names, ", "));
215
1/2
✓ Branch 0 taken 23 times.
✗ Branch 1 not taken.
23 fmt::print(" {:>20} = {}\n", "prerequisite_algos", fmt::join(prerequisite_algos, ", "));
216
1/2
✓ Branch 0 taken 23 times.
✗ Branch 1 not taken.
23 fmt::print(" {:>20} = {}\n", "test_num", test_num);
217
1/2
✓ Branch 0 taken 23 times.
✗ Branch 1 not taken.
23 fmt::print(" {:>20} = {}\n", "num_threads", num_threads);
218
1/2
✓ Branch 0 taken 23 times.
✗ Branch 1 not taken.
23 fmt::print(" {:>20} = {}\n", "concurrency_model", concurrency_model);
219
1/2
✓ Branch 0 taken 23 times.
✗ Branch 1 not taken.
23 fmt::print(" {:>20} = {}\n", "vary_run", vary_run);
220
1/2
✓ Branch 0 taken 23 times.
✗ Branch 1 not taken.
23 fmt::print(" {:>20} = {}\n", "output_dir", output_dir);
221 23 fmt::print("\n");
222
223 // run test
224
3/4
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 11 times.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
23 if(command == "algorithm" || command == "unit")
225
4/8
✓ Branch 0 taken 11 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 11 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 11 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 11 times.
✗ Branch 7 not taken.
44 return TestAlgorithm(command, algo_name, prerequisite_algos, bank_names, data_file, num_events, verbose);
226
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 12 times.
12 if(command == "multithreading")
227 return TestMultithreading(command, algo_name, prerequisite_algos, bank_names, data_file, num_events, num_threads, concurrency_model, vary_run, verbose);
228
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 4 times.
12 else if(command == "validator")
229
4/8
✓ Branch 0 taken 8 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 8 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 8 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 8 times.
✗ Branch 7 not taken.
40 return TestValidator(algo_name, bank_names, data_file, num_events, output_dir, verbose);
230
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 1 times.
4 else if(command == "config")
231
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 return TestConfig(test_num, verbose);
232
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 else if(command == "logger")
233
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 return TestLogger();
234 else {
235 fmt::print(stderr, "ERROR: unknown command '{}'\n", command);
236 return 1;
237 }
238 return 0;
239 29 }
240