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 | 31 | int main(int argc, char** argv) | |
10 | { | ||
11 | // user parameters | ||
12 | 31 | std::string command = ""; | |
13 |
1/2✓ Branch 0 (3→4) taken 31 times.
✗ Branch 1 (3→216) not taken.
|
31 | std::string data_file = ""; |
14 | 31 | int num_events = 10; | |
15 |
1/2✓ Branch 0 (4→5) taken 31 times.
✗ Branch 1 (4→214) not taken.
|
31 | std::string algo_name = ""; |
16 | int test_num = 0; | ||
17 | 31 | int num_threads = 0; | |
18 |
1/2✓ Branch 0 (5→6) taken 31 times.
✗ Branch 1 (5→212) not taken.
|
31 | std::string concurrency_model = ""; |
19 | bool vary_run = false; | ||
20 |
2/4✓ Branch 0 (6→7) taken 31 times.
✗ Branch 1 (6→210) not taken.
✓ Branch 2 (7→8) taken 31 times.
✗ Branch 3 (7→204) not taken.
|
31 | 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 (7→8) taken 31 times.
✗ Branch 1 (7→204) not taken.
|
31 | 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 | 31 | }; | |
43 |
2/2✓ Branch 0 (8→9) taken 1 times.
✓ Branch 1 (8→10) taken 30 times.
|
31 | if(argc <= 1) |
44 |
1/2✓ Branch 0 (9→149) taken 1 times.
✗ Branch 1 (9→202) not taken.
|
1 | return UsageCommands(2); |
45 |
1/2✓ Branch 0 (10→11) taken 30 times.
✗ Branch 1 (10→202) not taken.
|
30 | command = std::string(argv[1]); |
46 |
2/4✓ Branch 0 (13→14) taken 30 times.
✗ Branch 1 (13→15) not taken.
✗ Branch 2 (14→15) not taken.
✓ Branch 3 (14→16) taken 30 times.
|
30 | if(command == "--help" || command == "-h") |
47 | ✗ | return UsageCommands(0); | |
48 | // omit the command, for getopt | ||
49 | 30 | argv++; | |
50 | 30 | argc--; | |
51 | |||
52 | // usage options | ||
53 | // clang-format off | ||
54 |
1/2✓ Branch 0 (2→3) taken 5 times.
✗ Branch 1 (2→85) 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 (3→4) taken 5 times.
✗ Branch 1 (3→85) 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 (9→10) taken 5 times.
✗ Branch 1 (9→85) 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 (12→13) taken 5 times.
✗ Branch 1 (12→85) not taken.
|
5 | {"o", [&]() |
111 | { | ||
112 |
1/2✓ Branch 0 (3→4) taken 1 times.
✗ Branch 1 (3→7) 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 (18→19) taken 60 times.
✓ Branch 1 (18→20) taken 5 times.
✗ Branch 2 (82→83) not taken.
✗ Branch 3 (82→84) 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 (20→21) taken 5 times.
✗ Branch 1 (20→118) not taken.
✓ Branch 2 (21→22) taken 5 times.
✗ Branch 3 (21→116) not taken.
✓ Branch 4 (23→24) taken 5 times.
✗ Branch 5 (23→114) not taken.
✓ Branch 6 (24→25) taken 5 times.
✗ Branch 7 (24→112) not taken.
✓ Branch 8 (26→27) taken 5 times.
✗ Branch 9 (26→110) not taken.
✓ Branch 10 (27→28) taken 5 times.
✗ Branch 11 (27→108) not taken.
✓ Branch 12 (29→30) taken 5 times.
✗ Branch 13 (29→106) not taken.
✓ Branch 14 (30→31) taken 5 times.
✗ Branch 15 (30→104) not taken.
✓ Branch 16 (32→33) taken 5 times.
✗ Branch 17 (32→102) not taken.
✓ Branch 18 (33→34) taken 5 times.
✗ Branch 19 (33→100) not taken.
✓ Branch 20 (35→36) taken 5 times.
✗ Branch 21 (35→98) not taken.
✗ Branch 22 (37→38) not taken.
✓ Branch 23 (37→39) taken 5 times.
✓ Branch 24 (40→41) taken 30 times.
✓ Branch 25 (40→44) taken 5 times.
✗ Branch 26 (89→90) not taken.
✗ Branch 27 (89→93) not taken.
|
65 | }; |
127 |
2/2✓ Branch 0 (61→57) taken 30 times.
✓ Branch 1 (61→62) taken 5 times.
|
35 | for(auto& it : available_options) |
128 |
1/2✓ Branch 0 (57→58) taken 30 times.
✗ Branch 1 (57→128) not taken.
|
60 | it.second.push_back("v"); |
129 |
2/2✓ Branch 0 (62→63) taken 4 times.
✓ Branch 1 (62→77) taken 1 times.
|
5 | if(auto it{available_options.find(command)}; it != available_options.end()) { |
130 |
2/4✓ Branch 0 (63→64) taken 4 times.
✗ Branch 1 (63→128) not taken.
✓ Branch 2 (64→65) taken 4 times.
✗ Branch 3 (64→128) not taken.
|
4 | fmt::print("\nUSAGE: {} {} [OPTIONS]...\n", exe, command); |
131 | 4 | fmt::print("\n OPTIONS:\n\n"); | |
132 |
2/2✓ Branch 0 (75→66) taken 20 times.
✓ Branch 1 (75→76) 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 (77→78) taken 1 times.
✗ Branch 1 (77→128) not taken.
|
1 | fmt::print(stderr, "ERROR: unknown command '{}'\n", command); |
140 | 1 | return 1; | |
141 | } | ||
142 |
6/16✓ Branch 0 (22→23) taken 5 times.
✗ Branch 1 (22→114) not taken.
✓ Branch 2 (25→26) taken 5 times.
✗ Branch 3 (25→110) not taken.
✓ Branch 4 (28→29) taken 5 times.
✗ Branch 5 (28→106) not taken.
✓ Branch 6 (31→32) taken 5 times.
✗ Branch 7 (31→102) not taken.
✓ Branch 8 (34→35) taken 5 times.
✗ Branch 9 (34→98) not taken.
✓ Branch 10 (36→37) taken 5 times.
✗ Branch 11 (36→94) not taken.
✗ Branch 12 (86→87) not taken.
✗ Branch 13 (86→88) not taken.
✗ Branch 14 (119→120) not taken.
✗ Branch 15 (119→123) not taken.
|
30 | }; |
143 | // clang-format on | ||
144 | |||
145 |
4/6✓ Branch 0 (16→17) taken 24 times.
✓ Branch 1 (16→18) taken 6 times.
✓ Branch 2 (17→19) taken 24 times.
✗ Branch 3 (17→202) not taken.
✓ Branch 4 (18→19) taken 6 times.
✗ Branch 5 (18→202) not taken.
|
30 | auto first_option = argc >= 2 ? std::string(argv[1]) : ""; |
146 |
2/4✓ Branch 0 (19→20) taken 30 times.
✗ Branch 1 (19→22) not taken.
✓ Branch 2 (20→21) taken 30 times.
✗ Branch 3 (20→22) not taken.
|
30 | if(first_option == "--help" || first_option == "-h") |
147 | ✗ | return UsageOptions(0); | |
148 |
4/4✓ Branch 0 (21→23) taken 6 times.
✓ Branch 1 (21→24) taken 24 times.
✓ Branch 2 (23→24) taken 1 times.
✓ Branch 3 (23→25) taken 5 times.
|
30 | if(argc <= 2 && command != "logger") |
149 |
1/2✓ Branch 0 (25→147) taken 5 times.
✗ Branch 1 (25→200) not taken.
|
5 | return UsageOptions(2); |
150 | |||
151 | // parse option arguments | ||
152 | int opt; | ||
153 |
2/2✓ Branch 0 (73→26) taken 108 times.
✓ Branch 1 (73→74) taken 25 times.
|
133 | while((opt = getopt(argc, argv, "hf:n:a:b:p:t:j:m:Vo:v|")) != -1) { |
154 |
8/13✗ Branch 0 (26→27) not taken.
✓ Branch 1 (26→28) taken 21 times.
✓ Branch 2 (26→32) taken 21 times.
✓ Branch 3 (26→36) taken 21 times.
✓ Branch 4 (26→40) taken 26 times.
✓ Branch 5 (26→44) taken 4 times.
✓ Branch 6 (26→49) taken 3 times.
✗ Branch 7 (26→53) not taken.
✗ Branch 8 (26→59) not taken.
✓ Branch 9 (26→64) taken 9 times.
✓ Branch 10 (26→68) taken 3 times.
✗ Branch 11 (26→69) not taken.
✗ Branch 12 (26→71) not taken.
|
108 | switch(opt) { |
155 | ✗ | case 'h': | |
156 | ✗ | return UsageOptions(0); | |
157 | case 'f': | ||
158 |
1/2✓ Branch 0 (28→29) taken 21 times.
✗ Branch 1 (28→200) not taken.
|
21 | data_file = std::string(optarg); |
159 | 21 | break; | |
160 | case 'n': | ||
161 |
1/2✓ Branch 0 (32→33) taken 21 times.
✗ Branch 1 (32→200) not taken.
|
42 | num_events = std::stoi(optarg); |
162 | 21 | break; | |
163 | case 'a': | ||
164 |
1/2✓ Branch 0 (36→37) taken 21 times.
✗ Branch 1 (36→200) not taken.
|
21 | algo_name = std::string(optarg); |
165 | 21 | break; | |
166 | case 'b': | ||
167 |
1/2✓ Branch 0 (40→41) taken 26 times.
✗ Branch 1 (40→200) not taken.
|
26 | bank_names.push_back(std::string(optarg)); |
168 | 26 | break; | |
169 | case 'p': | ||
170 |
1/2✓ Branch 0 (44→45) taken 4 times.
✗ Branch 1 (44→200) not taken.
|
4 | prerequisite_algos.push_back(std::string(optarg)); |
171 | 4 | break; | |
172 | case 't': | ||
173 |
1/2✓ Branch 0 (49→50) taken 3 times.
✗ Branch 1 (49→200) 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 (64→65) taken 9 times.
✗ Branch 1 (64→200) not taken.
|
9 | output_dir = std::string(optarg); |
188 | 9 | 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 (74→75) taken 25 times.
✗ Branch 1 (74→200) not taken.
✓ Branch 2 (75→76) taken 14 times.
✓ Branch 3 (75→77) taken 11 times.
|
50 | "REC::Traj"}; |
206 |
2/2✓ Branch 0 (75→76) taken 14 times.
✓ Branch 1 (75→77) taken 11 times.
|
25 | if(bank_names.empty()) |
207 |
1/2✓ Branch 0 (76→77) taken 14 times.
✗ Branch 1 (76→198) not taken.
|
14 | bank_names = all_bank_names; |
208 | |||
209 |
1/2✓ Branch 0 (78→79) taken 25 times.
✗ Branch 1 (78→198) not taken.
|
25 | fmt::print("TEST IGUANA:\n"); |
210 |
1/2✓ Branch 0 (79→80) taken 25 times.
✗ Branch 1 (79→198) not taken.
|
25 | fmt::print(" {:>20} = {}\n", "command", command); |
211 |
1/2✓ Branch 0 (80→81) taken 25 times.
✗ Branch 1 (80→198) not taken.
|
25 | fmt::print(" {:>20} = {}\n", "data_file", data_file); |
212 |
1/2✓ Branch 0 (81→82) taken 25 times.
✗ Branch 1 (81→198) not taken.
|
25 | fmt::print(" {:>20} = {}\n", "num_events", num_events); |
213 |
1/2✓ Branch 0 (82→83) taken 25 times.
✗ Branch 1 (82→198) not taken.
|
25 | fmt::print(" {:>20} = {}\n", "algo_name", algo_name); |
214 |
1/2✓ Branch 0 (83→84) taken 25 times.
✗ Branch 1 (83→198) not taken.
|
25 | fmt::print(" {:>20} = {}\n", "banks", fmt::join(bank_names, ", ")); |
215 |
1/2✓ Branch 0 (84→85) taken 25 times.
✗ Branch 1 (84→198) not taken.
|
25 | fmt::print(" {:>20} = {}\n", "prerequisite_algos", fmt::join(prerequisite_algos, ", ")); |
216 |
1/2✓ Branch 0 (85→86) taken 25 times.
✗ Branch 1 (85→198) not taken.
|
25 | fmt::print(" {:>20} = {}\n", "test_num", test_num); |
217 |
1/2✓ Branch 0 (86→87) taken 25 times.
✗ Branch 1 (86→198) not taken.
|
25 | fmt::print(" {:>20} = {}\n", "num_threads", num_threads); |
218 |
1/2✓ Branch 0 (87→88) taken 25 times.
✗ Branch 1 (87→198) not taken.
|
25 | fmt::print(" {:>20} = {}\n", "concurrency_model", concurrency_model); |
219 |
1/2✓ Branch 0 (88→89) taken 25 times.
✗ Branch 1 (88→198) not taken.
|
25 | fmt::print(" {:>20} = {}\n", "vary_run", vary_run); |
220 |
1/2✓ Branch 0 (89→90) taken 25 times.
✗ Branch 1 (89→198) not taken.
|
25 | fmt::print(" {:>20} = {}\n", "output_dir", output_dir); |
221 | 25 | fmt::print("\n"); | |
222 | |||
223 | // run test | ||
224 |
3/4✓ Branch 0 (90→91) taken 13 times.
✓ Branch 1 (90→93) taken 12 times.
✓ Branch 2 (91→92) taken 13 times.
✗ Branch 3 (91→93) not taken.
|
25 | if(command == "algorithm" || command == "unit") |
225 |
4/8✓ Branch 0 (93→94) taken 12 times.
✗ Branch 1 (93→198) not taken.
✓ Branch 2 (95→96) taken 12 times.
✗ Branch 3 (95→176) not taken.
✓ Branch 4 (96→97) taken 12 times.
✗ Branch 5 (96→174) not taken.
✓ Branch 6 (101→102) taken 12 times.
✗ Branch 7 (101→168) not taken.
|
48 | return TestAlgorithm(command, algo_name, prerequisite_algos, bank_names, data_file, num_events, verbose); |
226 |
1/2✗ Branch 0 (92→108) not taken.
✓ Branch 1 (92→126) taken 13 times.
|
13 | 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 (126→127) taken 9 times.
✓ Branch 1 (126→140) taken 4 times.
|
13 | else if(command == "validator") |
229 |
4/8✓ Branch 0 (127→128) taken 9 times.
✗ Branch 1 (127→198) not taken.
✓ Branch 2 (129→130) taken 9 times.
✗ Branch 3 (129→196) not taken.
✓ Branch 4 (131→132) taken 9 times.
✗ Branch 5 (131→194) not taken.
✓ Branch 6 (134→135) taken 9 times.
✗ Branch 7 (134→190) not taken.
|
45 | return TestValidator(algo_name, bank_names, data_file, num_events, output_dir, verbose); |
230 |
2/2✓ Branch 0 (140→141) taken 3 times.
✓ Branch 1 (140→142) taken 1 times.
|
4 | else if(command == "config") |
231 |
1/2✓ Branch 0 (141→146) taken 3 times.
✗ Branch 1 (141→198) not taken.
|
3 | return TestConfig(test_num, verbose); |
232 |
1/2✓ Branch 0 (142→143) taken 1 times.
✗ Branch 1 (142→144) not taken.
|
1 | else if(command == "logger") |
233 |
1/2✓ Branch 0 (143→146) taken 1 times.
✗ Branch 1 (143→198) not taken.
|
1 | return TestLogger(); |
234 | else { | ||
235 | ✗ | fmt::print(stderr, "ERROR: unknown command '{}'\n", command); | |
236 | ✗ | return 1; | |
237 | } | ||
238 | return 0; | ||
239 | 31 | } | |
240 |