GCC Code Coverage Report


Directory: ./
File: src/iguana/tests/iguana_test.cc
Date: 2025-11-25 17:57:04
Coverage Exec Excl Total
Lines: 82.6% 128 0 155
Functions: 70.0% 7 0 10
Branches: 42.7% 137 0 321

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