1 /*
2 * Copyright © 2017 Collabora Ltd.
3 *
4 * This file is part of vkmark.
5 *
6 * vkmark is free software: you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation, either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * vkmark is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with vkmark. If not, see <http://www.gnu.org/licenses/>.
18 *
19 * Authors:
20 * Alexandros Frantzis <alexandros.frantzis@collabora.com>
21 */
22
23 #include "src/options.h"
24 #include "src/util.h"
25
26 #include "catch.hpp"
27 #include <memory>
28
29 using namespace Catch::Matchers;
30
31 SCENARIO("options prints window system help", "")
32 {
33 Options options;
34
35 GIVEN("Options with window system help")
36 {
37 std::string const ws1_help{"WINDOW SYSTEM HELP 1\n"};
38 std::string const ws2_help{"WINDOW SYSTEM HELP 2\n"};
39
40 options.add_window_system_help(ws1_help);
41 options.add_window_system_help(ws2_help);
42
43 WHEN("getting the help string")
44 {
45 auto const help = options.help_string();
46
47 THEN("the window system help is contained")
48 {
49 REQUIRE_THAT(help, Contains(ws1_help));
50 REQUIRE_THAT(help, Contains(ws2_help));
51 }
52 }
53 }
54 }
55
56 namespace
57 {
58
argv_from_vector(std::vector<std::string> & vec)59 std::unique_ptr<char*[]> argv_from_vector(std::vector<std::string>& vec)
60 {
61 auto argv = std::make_unique<char*[]>(vec.size() + 1);
62
63 for (size_t i = 0; i < vec.size(); ++i)
64 argv[i] = &vec[i][0];
65
66 argv[vec.size()] = nullptr;
67
68 return argv;
69 }
70
71 }
72
73 SCENARIO("options parses command line arguments", "")
74 {
75 Options options;
76
77 GIVEN("A command line with invalid options fails")
78 {
79 std::vector<std::string> args{"vkmark", "--invalid"};
80 auto argv = argv_from_vector(args);
81
82 WHEN("parsing the args")
83 {
84 auto const result = options.parse_args(args.size(), argv.get());
85
86 THEN("the parsing fails")
87 {
88 REQUIRE_FALSE(result);
89 }
90 }
91 }
92 GIVEN("A command line with -b and --benchmark")
93 {
94 std::string const bench1{"scene1:opt1=val1"};
95 std::string const bench2{"scene2"};
96 std::vector<std::string> args{"vkmark", "-b", bench1, "--benchmark", bench2};
97 auto argv = argv_from_vector(args);
98
99 WHEN("parsing the args")
100 {
101 REQUIRE(options.parse_args(args.size(), argv.get()));
102
103 THEN("the benchmarks are parsed")
104 {
105 REQUIRE_THAT(options.benchmarks,
106 Equals(std::vector<std::string>{bench1, bench2}));
107 }
108 }
109 }
110
111 GIVEN("A command line with -s")
112 {
113 int const width = 123;
114 int const height = 456;
115 std::vector<std::string> args{
116 "vkmark", "-s", std::to_string(width) + "x" + std::to_string(height)};
117 auto argv = argv_from_vector(args);
118
119 WHEN("parsing the args")
120 {
121 REQUIRE(options.parse_args(args.size(), argv.get()));
122
123 THEN("the size is parsed")
124 {
125 REQUIRE(options.size.first == width);
126 REQUIRE(options.size.second == height);
127 }
128 }
129 }
130
131 GIVEN("A command line with --size")
132 {
133 int const width = 123;
134 int const height = 456;
135 std::vector<std::string> args{
136 "vkmark", "--size", std::to_string(width) + "x" + std::to_string(height)};
137 auto argv = argv_from_vector(args);
138
139 WHEN("parsing the args")
140 {
141 REQUIRE(options.parse_args(args.size(), argv.get()));
142
143 THEN("the size is parsed")
144 {
145 REQUIRE(options.size.first == width);
146 REQUIRE(options.size.second == height);
147 }
148 }
149 }
150
151 GIVEN("A command line with --fullscreen")
152 {
153 std::vector<std::string> args{"vkmark", "--fullscreen"};
154 auto argv = argv_from_vector(args);
155
156 WHEN("parsing the args")
157 {
158 REQUIRE(options.parse_args(args.size(), argv.get()));
159
160 THEN("the fullscreen option is parsed")
161 {
162 REQUIRE(options.size.first == -1);
163 REQUIRE(options.size.second == -1);
164 }
165 }
166 }
167
168 GIVEN("A command line with --present-mode")
169 {
170 std::vector<std::string> args{"vkmark", "--present-mode", "fifo"};
171 auto argv = argv_from_vector(args);
172
173 WHEN("parsing the args")
174 {
175 REQUIRE(options.parse_args(args.size(), argv.get()));
176
177 THEN("the present mode is parsed")
178 {
179 REQUIRE(options.present_mode == vk::PresentModeKHR::eFifo);
180 }
181 }
182 }
183
184 GIVEN("A command line with --list-scenes")
185 {
186 std::vector<std::string> args{"vkmark", "--list-scenes"};
187 auto argv = argv_from_vector(args);
188
189 WHEN("parsing the args")
190 {
191 REQUIRE_FALSE(options.list_scenes);
192 REQUIRE(options.parse_args(args.size(), argv.get()));
193
194 THEN("the list-scenes option is parsed")
195 {
196 REQUIRE(options.list_scenes);
197 }
198 }
199 }
200
201 GIVEN("A command line with --show-all-options")
202 {
203 std::vector<std::string> args{"vkmark", "--show-all-options"};
204 auto argv = argv_from_vector(args);
205
206 WHEN("parsing the args")
207 {
208 REQUIRE_FALSE(options.show_all_options);
209 REQUIRE(options.parse_args(args.size(), argv.get()));
210
211 THEN("the show-all-options option is parsed")
212 {
213 REQUIRE(options.show_all_options);
214 }
215 }
216 }
217
218 GIVEN("A command line with --winsys-dir")
219 {
220 std::string const winsys_dir{"bla/winsys"};
221 std::vector<std::string> args{"vkmark", "--winsys-dir", winsys_dir};
222 auto argv = argv_from_vector(args);
223
224 WHEN("parsing the args")
225 {
226 REQUIRE(options.parse_args(args.size(), argv.get()));
227
228 THEN("the window system dir is parsed")
229 {
230 REQUIRE(options.window_system_dir == winsys_dir);
231 }
232 }
233 }
234
235 GIVEN("A command line with --data-dir")
236 {
237 std::string const data_dir{"bla/data"};
238 std::vector<std::string> args{"vkmark", "--data-dir", data_dir};
239 auto argv = argv_from_vector(args);
240
241 WHEN("parsing the args")
242 {
243 REQUIRE(options.parse_args(args.size(), argv.get()));
244
245 THEN("the data dir is parsed")
246 {
247 REQUIRE(options.data_dir == data_dir);
248 }
249 }
250 }
251
252 GIVEN("A command line with --winsys")
253 {
254 std::string const winsys{"mywinsys"};
255 std::vector<std::string> args{"vkmark", "--winsys", winsys};
256 auto argv = argv_from_vector(args);
257
258 WHEN("parsing the args")
259 {
260 REQUIRE(options.window_system.empty());
261 REQUIRE(options.parse_args(args.size(), argv.get()));
262
263 THEN("the winsys is parsed")
264 {
265 REQUIRE(options.window_system == winsys);
266 }
267 }
268 }
269
270 GIVEN("A command line with --winsys-options")
271 {
272 std::string const winsys_options{"opt1=v1:opt2=v2"};
273 std::vector<std::string> args{"vkmark", "--winsys-options", winsys_options};
274 auto argv = argv_from_vector(args);
275
276 WHEN("parsing the args")
277 {
278 REQUIRE(options.parse_args(args.size(), argv.get()));
279
280 THEN("the data dir is parsed")
281 {
282 REQUIRE(options.window_system_options.size() == 2);
283 REQUIRE(options.window_system_options[0].name == "opt1");
284 REQUIRE(options.window_system_options[0].value == "v1");
285 REQUIRE(options.window_system_options[1].name == "opt2");
286 REQUIRE(options.window_system_options[1].value == "v2");
287 }
288 }
289 }
290
291 GIVEN("A command line with -d")
292 {
293 std::vector<std::string> args{"vkmark", "-d"};
294 auto argv = argv_from_vector(args);
295
296 WHEN("parsing the args")
297 {
298 REQUIRE_FALSE(options.show_debug);
299 REQUIRE(options.parse_args(args.size(), argv.get()));
300
301 THEN("the debug option is parsed")
302 {
303 REQUIRE(options.show_debug);
304 }
305 }
306 }
307
308 GIVEN("A command line with --debug")
309 {
310 std::vector<std::string> args{"vkmark", "--debug"};
311 auto argv = argv_from_vector(args);
312
313 WHEN("parsing the args")
314 {
315 REQUIRE_FALSE(options.show_debug);
316 REQUIRE(options.parse_args(args.size(), argv.get()));
317
318 THEN("the debug option is parsed")
319 {
320 REQUIRE(options.show_debug);
321 }
322 }
323 }
324
325 GIVEN("A command line with -h")
326 {
327 std::vector<std::string> args{"vkmark", "-h"};
328 auto argv = argv_from_vector(args);
329
330 WHEN("parsing the args")
331 {
332 REQUIRE_FALSE(options.show_help);
333 REQUIRE(options.parse_args(args.size(), argv.get()));
334
335 THEN("the help option is parsed")
336 {
337 REQUIRE(options.show_help);
338 }
339 }
340 }
341
342 GIVEN("A command line with --help")
343 {
344 std::vector<std::string> args{"vkmark", "--help"};
345 auto argv = argv_from_vector(args);
346
347 WHEN("parsing the args")
348 {
349 REQUIRE_FALSE(options.show_help);
350 REQUIRE(options.parse_args(args.size(), argv.get()));
351
352 THEN("the help option is parsed")
353 {
354 REQUIRE(options.show_help);
355 }
356 }
357 }
358
359 GIVEN("A command line with --run-forever")
360 {
361 std::vector<std::string> args{"vkmark", "--run-forever"};
362 auto argv = argv_from_vector(args);
363
364 WHEN("parsing the args")
365 {
366 REQUIRE_FALSE(options.run_forever);
367 REQUIRE(options.parse_args(args.size(), argv.get()));
368
369 THEN("the run-forever option is parsed")
370 {
371 REQUIRE(options.run_forever);
372 }
373 }
374 }
375
376 GIVEN("A complex command line")
377 {
378 std::vector<std::string> args{
379 "vkmark",
380 "--benchmark=scene1:opt=val",
381 "-s", "111x222",
382 "--data-dir=data",
383 "--winsys-dir=build/src",
384 "-p", "fiforelaxed"};
385 auto argv = argv_from_vector(args);
386
387 WHEN("parsing the args")
388 {
389 REQUIRE_FALSE(options.show_help);
390 REQUIRE(options.parse_args(args.size(), argv.get()));
391
392 THEN("all options are parsed")
393 {
394 REQUIRE(options.benchmarks.size() == 1);
395 REQUIRE(options.benchmarks[0] == "scene1:opt=val");
396 REQUIRE(options.size.first == 111);
397 REQUIRE(options.size.second == 222);
398 REQUIRE(options.data_dir == "data");
399 REQUIRE(options.window_system_dir == "build/src");
400 REQUIRE(options.present_mode == vk::PresentModeKHR::eFifoRelaxed);
401 }
402 }
403 }
404 }
405