1 #include <dirent.h>
2 #include <fcntl.h>
3 #include <sys/stat.h>
4 #include <sys/types.h>
5 #include <unistd.h>
6
7 #include "igt.h"
8
9 #include "settings.h"
10 #include "job_list.h"
11 #include "executor.h"
12
13 /*
14 * NOTE: this test is using a lot of variables that are changed in igt_fixture,
15 * igt_subtest_group and igt_subtests blocks but defined outside of them.
16 *
17 * Such variables have to be either non-local or volatile, otherwise their
18 * contents is undefined due to longjmps the framework performs.
19 */
20
21 static const char testdatadir[] = TESTDATA_DIRECTORY;
22
igt_assert_eqstr(const char * one,const char * two)23 static void igt_assert_eqstr(const char *one, const char *two)
24 {
25 if (one == NULL && two == NULL)
26 return;
27
28 igt_assert_f(one != NULL && two != NULL, "Strings differ (one is NULL): %s vs %s\n", one, two);
29
30 igt_assert_f(!strcmp(one, two), "Strings differ: '%s' vs '%s'\n", one, two);
31 }
32
debug_print_executions(struct job_list * list)33 static void debug_print_executions(struct job_list *list)
34 {
35 size_t i;
36 int k;
37
38 igt_debug("Executions:\n");
39 for (i = 0; i < list->size; i++) {
40 struct job_list_entry *entry = &list->entries[i];
41 igt_debug(" %s\n", entry->binary);
42 for (k = 0; k < entry->subtest_count; ++k) {
43 igt_debug(" %s\n", entry->subtests[k]);
44 }
45 }
46
47 }
48
dump_file(int dirfd,const char * name)49 static char *dump_file(int dirfd, const char *name)
50 {
51 int fd = openat(dirfd, name, O_RDONLY);
52 ssize_t s;
53 char *buf = malloc(256);
54
55 if (fd < 0) {
56 free(buf);
57 return NULL;
58 }
59
60 s = read(fd, buf, 255);
61 close(fd);
62
63 if (s < 0) {
64 free(buf);
65 return NULL;
66 }
67
68 buf[s] = '\0';
69 return buf;
70 }
71
job_list_filter_test(const char * name,const char * filterarg1,const char * filterarg2,size_t expected_normal,size_t expected_multiple)72 static void job_list_filter_test(const char *name, const char *filterarg1, const char *filterarg2,
73 size_t expected_normal, size_t expected_multiple)
74 {
75 int multiple;
76 struct settings *settings = malloc(sizeof(*settings));
77
78 igt_fixture
79 init_settings(settings);
80
81 for (multiple = 0; multiple < 2; multiple++) {
82 igt_subtest_f("job-list-filters-%s-%s", name, multiple ? "multiple" : "normal") {
83 struct job_list list;
84 const char *argv[] = { "runner",
85 /* Ugly but does the trick */
86 multiple ? "--multiple-mode" : "--sync",
87 filterarg1, filterarg2,
88 testdatadir,
89 "path-to-results",
90 };
91 bool success = false;
92 size_t size;
93
94 init_job_list(&list);
95 igt_assert(parse_options(ARRAY_SIZE(argv), (char**)argv, settings));
96
97 success = create_job_list(&list, settings);
98 size = list.size;
99
100 if (success)
101 debug_print_executions(&list);
102
103 free_job_list(&list);
104
105 igt_assert_f(success, "Job list creation failed\n");
106 igt_assert_eq(size, multiple ? expected_multiple : expected_normal);
107 }
108 }
109
110 igt_fixture {
111 free_settings(settings);
112 free(settings);
113 }
114 }
115
clear_directory_fd(int dirfd)116 static void clear_directory_fd(int dirfd)
117 {
118 DIR* d;
119 struct dirent *dirent;
120
121 d = fdopendir(dirfd);
122
123 if (dirfd < 0 || d == NULL) {
124 return;
125 }
126
127 while ((dirent = readdir(d)) != NULL) {
128 if (strcmp(dirent->d_name, ".") &&
129 strcmp(dirent->d_name, "..")) {
130 if (dirent->d_type == DT_REG) {
131 unlinkat(dirfd, dirent->d_name, 0);
132 } else if (dirent->d_type == DT_DIR) {
133 clear_directory_fd(openat(dirfd, dirent->d_name, O_DIRECTORY | O_RDONLY));
134 unlinkat(dirfd, dirent->d_name, AT_REMOVEDIR);
135 }
136 }
137 }
138
139 closedir(d);
140 }
141
clear_directory(char * name)142 static void clear_directory(char *name)
143 {
144 int dirfd = open(name, O_DIRECTORY | O_RDONLY);
145 clear_directory_fd(dirfd);
146 rmdir(name);
147 }
148
assert_settings_equal(struct settings * one,struct settings * two)149 static void assert_settings_equal(struct settings *one, struct settings *two)
150 {
151 /*
152 * Regex lists are not serialized, and thus won't be compared
153 * here.
154 */
155 igt_assert_eq(one->abort_mask, two->abort_mask);
156 igt_assert_eqstr(one->test_list, two->test_list);
157 igt_assert_eqstr(one->name, two->name);
158 igt_assert_eq(one->dry_run, two->dry_run);
159 igt_assert_eq(one->sync, two->sync);
160 igt_assert_eq(one->log_level, two->log_level);
161 igt_assert_eq(one->overwrite, two->overwrite);
162 igt_assert_eq(one->multiple_mode, two->multiple_mode);
163 igt_assert_eq(one->inactivity_timeout, two->inactivity_timeout);
164 igt_assert_eq(one->use_watchdog, two->use_watchdog);
165 igt_assert_eqstr(one->test_root, two->test_root);
166 igt_assert_eqstr(one->results_path, two->results_path);
167 igt_assert_eq(one->piglit_style_dmesg, two->piglit_style_dmesg);
168 igt_assert_eq(one->dmesg_warn_level, two->dmesg_warn_level);
169 }
170
assert_job_list_equal(struct job_list * one,struct job_list * two)171 static void assert_job_list_equal(struct job_list *one, struct job_list *two)
172 {
173 size_t i, k;
174
175 igt_assert_eq(one->size, two->size);
176
177 for (i = 0; i < one->size; i++) {
178 struct job_list_entry *eone = &one->entries[i];
179 struct job_list_entry *etwo = &two->entries[i];
180
181 igt_assert_eqstr(eone->binary, etwo->binary);
182 igt_assert_eq(eone->subtest_count, etwo->subtest_count);
183
184 for (k = 0; k < eone->subtest_count; k++) {
185 igt_assert_eqstr(eone->subtests[k], etwo->subtests[k]);
186 }
187 }
188 }
189
assert_execution_created(int dirfd,const char * name)190 static void assert_execution_created(int dirfd, const char *name)
191 {
192 int fd;
193
194 igt_assert_f((fd = openat(dirfd, name, O_RDONLY)) >= 0,
195 "Execute didn't create %s\n", name);
196 close(fd);
197 }
198
assert_execution_results_exist(int dirfd)199 static void assert_execution_results_exist(int dirfd)
200 {
201 assert_execution_created(dirfd, "journal.txt");
202 assert_execution_created(dirfd, "out.txt");
203 assert_execution_created(dirfd, "err.txt");
204 assert_execution_created(dirfd, "dmesg.txt");
205 }
206
207 igt_main
208 {
209 struct settings *settings = malloc(sizeof(*settings));
210
211 igt_fixture {
212 int i;
213
214 /*
215 * Let's close all the non-standard fds ahead of executing
216 * anything, so we can test for descriptor leakage caused by
217 * any of the igt_runner code-paths exercised here.
218 *
219 * See file-descriptor-leakage subtest at the end.
220 *
221 * Some libraries (looking at you, GnuTLS) may leave fds opened
222 * after the implicitly called library constructor. We don't
223 * have full control over them as they may be dependencies of
224 * our dependencies and may get pulled in if the user's and
225 * distribution's compile/configure/USE are just right.
226 */
227 for (i = 3; i < 400; i++)
228 close(i);
229
230 init_settings(settings);
231 }
232
233 igt_subtest("default-settings") {
234 const char *argv[] = { "runner",
235 "test-root-dir",
236 "path-to-results",
237 };
238
239 igt_assert(parse_options(ARRAY_SIZE(argv), (char**)argv, settings));
240
241 igt_assert_eq(settings->abort_mask, 0);
242 igt_assert(!settings->test_list);
243 igt_assert_eqstr(settings->name, "path-to-results");
244 igt_assert(!settings->dry_run);
245 igt_assert_eq(settings->include_regexes.size, 0);
246 igt_assert_eq(settings->exclude_regexes.size, 0);
247 igt_assert(!settings->sync);
248 igt_assert_eq(settings->log_level, LOG_LEVEL_NORMAL);
249 igt_assert(!settings->overwrite);
250 igt_assert(!settings->multiple_mode);
251 igt_assert_eq(settings->inactivity_timeout, 0);
252 igt_assert_eq(settings->overall_timeout, 0);
253 igt_assert(!settings->use_watchdog);
254 igt_assert(strstr(settings->test_root, "test-root-dir") != NULL);
255 igt_assert(strstr(settings->results_path, "path-to-results") != NULL);
256
257 igt_assert(!settings->piglit_style_dmesg);
258 igt_assert_eq(settings->dmesg_warn_level, 4);
259 }
260
261 igt_subtest_group {
262 char *cwd;
263 char *path;
264
265 igt_fixture {
266 igt_require((cwd = realpath(".", NULL)) != NULL);
267 path = NULL;
268 }
269
270 igt_subtest("absolute-path-converter") {
271 char paths[][15] = { "simple-name", "foo/bar", "." };
272 size_t i;
273
274 for (i = 0; i < ARRAY_SIZE(paths); i++) {
275 free(path);
276 path = absolute_path(paths[i]);
277
278 igt_assert(path[0] == '/');
279 igt_debug("Got path %s for %s\n", path, paths[i]);
280 igt_assert(strstr(path, cwd) == path);
281 if (strcmp(paths[i], ".")) {
282 igt_assert(strstr(path, paths[i]) != NULL);
283 }
284 }
285 }
286
287 igt_fixture {
288 free(cwd);
289 free(path);
290 }
291 }
292
293 igt_subtest_group {
294 const char tmptestlist[] = "tmp.testlist";
295 char dirname[] = "tmpdirXXXXXX";
296 char pathtotestlist[64];
297 volatile char *path;
298
299 igt_fixture {
300 int dirfd, fd;
301
302 path = NULL;
303
304 igt_require(mkdtemp(dirname) != NULL);
305 igt_require((dirfd = open(dirname, O_DIRECTORY | O_RDONLY)) >= 0);
306 igt_require((fd = openat(dirfd, tmptestlist, O_CREAT | O_EXCL | O_WRONLY, 0660)) >= 0);
307 close(fd);
308 close(dirfd);
309
310 strcpy(pathtotestlist, dirname);
311 strcat(pathtotestlist, "/");
312 strcat(pathtotestlist, tmptestlist);
313 }
314
315 igt_subtest("absolute-path-usage") {
316 const char *argv[] = { "runner",
317 "--test-list", pathtotestlist,
318 testdatadir,
319 dirname,
320 };
321
322 igt_assert(parse_options(ARRAY_SIZE(argv), (char**)argv, settings));
323
324 path = realpath(testdatadir, NULL);
325 igt_assert(path != NULL);
326 igt_assert_eqstr(settings->test_root, (char*)path);
327 free((void*)path);
328 path = realpath(dirname, NULL);
329 igt_assert(path != NULL);
330 igt_assert_eqstr(settings->results_path, (char*)path);
331 free((void*)path);
332 path = realpath(pathtotestlist, NULL);
333 igt_assert(path != NULL);
334 igt_assert_eqstr(settings->test_list, (char*)path);
335 }
336
337 igt_fixture {
338 int dirfd;
339
340 igt_require((dirfd = open(dirname, O_DIRECTORY | O_RDONLY)) >= 0);
341 unlinkat(dirfd, tmptestlist, 0);
342 close(dirfd);
343 rmdir(dirname);
344
345 free((void*)path);
346 }
347 }
348
349 igt_subtest("environment-overrides-test-root-flag") {
350 const char *argv[] = { "runner",
351 "test-root-dir",
352 "path-to-results",
353 };
354
355 setenv("IGT_TEST_ROOT", testdatadir, 1);
356 igt_assert(parse_options(ARRAY_SIZE(argv), (char**)argv, settings));
357
358 igt_assert_eq(settings->abort_mask, 0);
359 igt_assert(!settings->test_list);
360 igt_assert_eqstr(settings->name, "path-to-results");
361 igt_assert(!settings->dry_run);
362 igt_assert_eq(settings->include_regexes.size, 0);
363 igt_assert_eq(settings->exclude_regexes.size, 0);
364 igt_assert(!settings->sync);
365 igt_assert_eq(settings->log_level, LOG_LEVEL_NORMAL);
366 igt_assert(!settings->overwrite);
367 igt_assert(!settings->multiple_mode);
368 igt_assert_eq(settings->inactivity_timeout, 0);
369 igt_assert_eq(settings->overall_timeout, 0);
370 igt_assert(!settings->use_watchdog);
371 igt_assert(strstr(settings->test_root, testdatadir) != NULL);
372 igt_assert(strstr(settings->results_path, "path-to-results") != NULL);
373 igt_assert(!settings->piglit_style_dmesg);
374 }
375
376 igt_fixture {
377 unsetenv("IGT_TEST_ROOT");
378 }
379
380 igt_subtest("parse-all-settings") {
381 char blacklist_name[PATH_MAX], blacklist2_name[PATH_MAX];
382 const char *argv[] = { "runner",
383 "-n", "foo",
384 "--abort-on-monitored-error=taint,lockdep",
385 "--test-list", "path-to-test-list",
386 "--ignore-missing",
387 "--dry-run",
388 "-t", "pattern1",
389 "-t", "pattern2",
390 "-x", "xpattern1",
391 "-x", "xpattern2",
392 "-b", blacklist_name,
393 "--blacklist", blacklist2_name,
394 "-s",
395 "-l", "verbose",
396 "--overwrite",
397 "--multiple-mode",
398 "--inactivity-timeout", "27",
399 "--overall-timeout", "360",
400 "--use-watchdog",
401 "--piglit-style-dmesg",
402 "--dmesg-warn-level=3",
403 "test-root-dir",
404 "path-to-results",
405 };
406
407 sprintf(blacklist_name, "%s/test-blacklist.txt", testdatadir);
408 sprintf(blacklist2_name, "%s/test-blacklist2.txt", testdatadir);
409
410 igt_assert(parse_options(ARRAY_SIZE(argv), (char**)argv, settings));
411
412 igt_assert_eq(settings->abort_mask, ABORT_TAINT | ABORT_LOCKDEP);
413 igt_assert(strstr(settings->test_list, "path-to-test-list") != NULL);
414 igt_assert_eqstr(settings->name, "foo");
415 igt_assert(settings->dry_run);
416 igt_assert_eq(settings->include_regexes.size, 2);
417 igt_assert_eqstr(settings->include_regexes.regex_strings[0], "pattern1");
418 igt_assert_eqstr(settings->include_regexes.regex_strings[1], "pattern2");
419 igt_assert_eq(settings->exclude_regexes.size, 4);
420 igt_assert_eqstr(settings->exclude_regexes.regex_strings[0], "xpattern1");
421 igt_assert_eqstr(settings->exclude_regexes.regex_strings[1], "xpattern2");
422 igt_assert_eqstr(settings->exclude_regexes.regex_strings[2], "xpattern3"); /* From blacklist */
423 igt_assert_eqstr(settings->exclude_regexes.regex_strings[3], "xpattern4"); /* From blacklist2 */
424 igt_assert(settings->sync);
425 igt_assert_eq(settings->log_level, LOG_LEVEL_VERBOSE);
426 igt_assert(settings->overwrite);
427 igt_assert(settings->multiple_mode);
428 igt_assert_eq(settings->inactivity_timeout, 27);
429 igt_assert_eq(settings->overall_timeout, 360);
430 igt_assert(settings->use_watchdog);
431 igt_assert(strstr(settings->test_root, "test-root-dir") != NULL);
432 igt_assert(strstr(settings->results_path, "path-to-results") != NULL);
433
434 igt_assert(settings->piglit_style_dmesg);
435 igt_assert_eq(settings->dmesg_warn_level, 3);
436 }
437 igt_subtest("parse-list-all") {
438 const char *argv[] = { "runner",
439 "--list-all",
440 "test-root-dir"};
441
442 igt_assert(parse_options(ARRAY_SIZE(argv), (char**)argv, settings));
443 igt_assert_eq(settings->list_all, 1);
444 }
445
446 igt_subtest("dmesg-warn-level-inferred") {
447 const char *argv[] = { "runner",
448 "test-root-dir",
449 "path-to-results",
450 };
451
452 igt_assert(parse_options(ARRAY_SIZE(argv), (char**)argv, settings));
453
454 igt_assert(!settings->piglit_style_dmesg);
455 igt_assert_eq(settings->dmesg_warn_level, 4);
456 }
457
458 igt_subtest("dmesg-warn-level-inferred-with-piglit-style") {
459 const char *argv[] = { "runner",
460 "--piglit-style-dmesg",
461 "test-root-dir",
462 "path-to-results",
463 };
464
465 igt_assert(parse_options(ARRAY_SIZE(argv), (char**)argv, settings));
466
467 igt_assert(settings->piglit_style_dmesg);
468 igt_assert_eq(settings->dmesg_warn_level, 5);
469 }
470
471 igt_subtest("dmesg-warn-level-overridable-with-piglit-style") {
472 const char *argv[] = { "runner",
473 "--piglit-style-dmesg",
474 "--dmesg-warn-level=3",
475 "test-root-dir",
476 "path-to-results",
477 };
478
479 igt_assert(parse_options(ARRAY_SIZE(argv), (char**)argv, settings));
480
481 igt_assert(settings->piglit_style_dmesg);
482 igt_assert_eq(settings->dmesg_warn_level, 3);
483 }
484
485 igt_subtest("invalid-option") {
486 const char *argv[] = { "runner",
487 "--no-such-option",
488 "test-root-dir",
489 "results-path",
490 };
491
492 igt_assert(!parse_options(ARRAY_SIZE(argv), (char**)argv, settings));
493 }
494
495 igt_subtest("paths-missing") {
496 const char *argv[] = { "runner",
497 "-o",
498 };
499 igt_assert(!parse_options(ARRAY_SIZE(argv), (char**)argv, settings));
500 }
501
502 igt_subtest("log-levels") {
503 const char *argv[] = { "runner",
504 "-l", "normal",
505 "test-root-dir",
506 "results-path",
507 };
508
509 igt_assert(parse_options(ARRAY_SIZE(argv), (char**)argv, settings));
510 igt_assert_eq(settings->log_level, LOG_LEVEL_NORMAL);
511
512 argv[2] = "quiet";
513 igt_assert(parse_options(ARRAY_SIZE(argv), (char**)argv, settings));
514 igt_assert_eq(settings->log_level, LOG_LEVEL_QUIET);
515
516 argv[2] = "verbose";
517 igt_assert(parse_options(ARRAY_SIZE(argv), (char**)argv, settings));
518 igt_assert_eq(settings->log_level, LOG_LEVEL_VERBOSE);
519 }
520
521 igt_subtest("abort-conditions") {
522 const char *argv[] = { "runner",
523 "--abort-on-monitored-error=taint",
524 "test-root-dir",
525 "results-path",
526 };
527
528 igt_assert(parse_options(ARRAY_SIZE(argv), (char**)argv, settings));
529 igt_assert_eq(settings->abort_mask, ABORT_TAINT);
530
531 argv[1] = "--abort-on-monitored-error=lockdep";
532 igt_assert(parse_options(ARRAY_SIZE(argv), (char**)argv, settings));
533 igt_assert_eq(settings->abort_mask, ABORT_LOCKDEP);
534
535 argv[1] = "--abort-on-monitored-error=taint";
536 igt_assert(parse_options(ARRAY_SIZE(argv), (char**)argv, settings));
537 igt_assert_eq(settings->abort_mask, ABORT_TAINT);
538
539 argv[1] = "--abort-on-monitored-error=lockdep,taint";
540 igt_assert(parse_options(ARRAY_SIZE(argv), (char**)argv, settings));
541 igt_assert_eq(settings->abort_mask, ABORT_TAINT | ABORT_LOCKDEP);
542
543 argv[1] = "--abort-on-monitored-error=taint,lockdep";
544 igt_assert(parse_options(ARRAY_SIZE(argv), (char**)argv, settings));
545 igt_assert_eq(settings->abort_mask, ABORT_TAINT | ABORT_LOCKDEP);
546
547 argv[1] = "--abort-on-monitored-error=all";
548 igt_assert(parse_options(ARRAY_SIZE(argv), (char**)argv, settings));
549 igt_assert_eq(settings->abort_mask, ABORT_ALL);
550
551 argv[1] = "--abort-on-monitored-error=";
552 igt_assert(parse_options(ARRAY_SIZE(argv), (char**)argv, settings));
553 igt_assert_eq(settings->abort_mask, 0);
554
555 argv[1] = "--abort-on-monitored-error=doesnotexist";
556 igt_assert(!parse_options(ARRAY_SIZE(argv), (char**)argv, settings));
557
558 }
559
560 igt_subtest("parse-clears-old-data") {
561 const char *argv[] = { "runner",
562 "-n", "foo",
563 "--dry-run",
564 "test-root-dir",
565 "results-path",
566 };
567
568 igt_assert(parse_options(ARRAY_SIZE(argv), (char**)argv, settings));
569
570 igt_assert_eqstr(settings->name, "foo");
571 igt_assert(settings->dry_run);
572 igt_assert(!settings->test_list);
573 igt_assert(!settings->sync);
574
575 argv[1] = "--test-list";
576 argv[3] = "--sync";
577
578 igt_assert(parse_options(ARRAY_SIZE(argv), (char**)argv, settings));
579
580 igt_assert_eqstr(settings->name, "results-path");
581 igt_assert(!settings->dry_run);
582 igt_assert(strstr(settings->test_list, "foo") != NULL);
583 igt_assert(settings->sync);
584 }
585
586 igt_subtest_group {
587 char filename[] = "tmplistXXXXXX";
588
589 igt_fixture {
590 int fd;
591 igt_require((fd = mkstemp(filename)) >= 0);
592 close(fd);
593 }
594
595 igt_subtest("validate-ok") {
596 const char *argv[] = { "runner",
597 "--test-list", filename,
598 testdatadir,
599 "path-to-results",
600 };
601
602 igt_assert(parse_options(ARRAY_SIZE(argv), (char**)argv, settings));
603
604 igt_assert(validate_settings(settings));
605 }
606
607 igt_fixture {
608 unlink(filename);
609 }
610 }
611
612 igt_subtest("validate-no-test-list") {
613 const char *nosuchfile = "no-such-file";
614 const char *argv[] = { "runner",
615 "--test-list", nosuchfile,
616 testdatadir,
617 "path-to-results",
618 };
619
620 igt_assert_lt(open(nosuchfile, O_RDONLY), 0);
621 igt_assert(parse_options(ARRAY_SIZE(argv), (char**)argv, settings));
622
623 igt_assert(!validate_settings(settings));
624 }
625
626 igt_subtest_group {
627 char dirname[] = "tmpdirXXXXXX";
628 struct job_list *list = malloc(sizeof(*list));
629
630 igt_fixture {
631 igt_require(mkdtemp(dirname) != NULL);
632 init_job_list(list);
633 }
634
635 igt_subtest("job-list-no-test-list-txt") {
636 const char *argv[] = { "runner",
637 dirname,
638 "path-to-results",
639 };
640
641 igt_assert(parse_options(ARRAY_SIZE(argv), (char**)argv, settings));
642
643 igt_assert(!create_job_list(list, settings));
644 }
645
646 igt_fixture {
647 rmdir(dirname);
648 free_job_list(list);
649 free(list);
650 }
651 }
652
653 job_list_filter_test("nofilters", "-n", "placeholderargs", 5, 3);
654 job_list_filter_test("binary-include", "-t", "successtest", 2, 1);
655 job_list_filter_test("binary-exclude", "-x", "successtest", 3, 2);
656 job_list_filter_test("subtest-include", "-t", "first-subtest", 1, 1);
657 job_list_filter_test("subtest-exclude", "-x", "second-subtest", 4, 3);
658 job_list_filter_test("piglit-names", "-t", "igt@successtest", 2, 1);
659 job_list_filter_test("piglit-names-subtest", "-t", "igt@successtest@first", 1, 1);
660
661 igt_subtest_group {
662 char filename[] = "tmplistXXXXXX";
663 const char testlisttext[] = "igt@successtest@first-subtest\n"
664 "igt@successtest@second-subtest\n"
665 "igt@nosubtests\n";
666 int multiple;
667 struct job_list *list = malloc(sizeof(*list));
668
669 igt_fixture {
670 int fd;
671 igt_require((fd = mkstemp(filename)) >= 0);
672 igt_require(write(fd, testlisttext, strlen(testlisttext)) == strlen(testlisttext));
673 close(fd);
674 init_job_list(list);
675 }
676
677 for (multiple = 0; multiple < 2; multiple++) {
678 igt_subtest_f("job-list-testlist-%s", multiple ? "multiple" : "normal") {
679 const char *argv[] = { "runner",
680 "--test-list", filename,
681 multiple ? "--multiple-mode" : "--sync",
682 testdatadir,
683 "path-to-results",
684 };
685
686 igt_assert(parse_options(ARRAY_SIZE(argv), (char**)argv, settings));
687 igt_assert(create_job_list(list, settings));
688
689 igt_assert_eq(list->size, multiple ? 2 : 3);
690
691 igt_assert_eqstr(list->entries[0].binary, "successtest");
692 if (!multiple) igt_assert_eqstr(list->entries[1].binary, "successtest");
693 igt_assert_eqstr(list->entries[multiple ? 1 : 2].binary, "nosubtests");
694
695 igt_assert_eq(list->entries[0].subtest_count, multiple ? 2 : 1);
696 igt_assert_eq(list->entries[1].subtest_count, multiple ? 0 : 1);
697 if (!multiple) igt_assert_eq(list->entries[2].subtest_count, 0);
698
699 igt_assert_eqstr(list->entries[0].subtests[0], "first-subtest");
700 igt_assert_eqstr(list->entries[multiple ? 0 : 1].subtests[multiple ? 1 : 0], "second-subtest");
701 }
702
703 igt_subtest_f("job-list-testlist-filtered-%s", multiple ? "multiple" : "normal") {
704 const char *argv[] = { "runner",
705 "--test-list", filename,
706 multiple ? "--multiple-mode" : "--sync",
707 "-t", "successtest",
708 "-x", "first",
709 testdatadir,
710 "path-to-results",
711 };
712
713 igt_assert(parse_options(ARRAY_SIZE(argv), (char**)argv, settings));
714 igt_assert(create_job_list(list, settings));
715
716 igt_assert_eq(list->size, 1);
717 igt_assert_eqstr(list->entries[0].binary, "successtest");
718
719 igt_assert_eq(list->entries[0].subtest_count, 1);
720 igt_assert_eqstr(list->entries[0].subtests[0], "second-subtest");
721 }
722 }
723
724 igt_fixture {
725 unlink(filename);
726 free_job_list(list);
727 free(list);
728 }
729 }
730
731 igt_subtest_group {
732 char dirname[] = "tmpdirXXXXXX";
733 volatile int dirfd = -1, fd = -1;
734 struct settings *cmp_settings = malloc(sizeof(*cmp_settings));
735
736 igt_fixture {
737 igt_require(mkdtemp(dirname) != NULL);
738 rmdir(dirname);
739 init_settings(cmp_settings);
740 }
741
742 igt_subtest("settings-serialize") {
743 const char *argv[] = { "runner",
744 "-n", "foo",
745 "--abort-on-monitored-error",
746 "--test-list", "path-to-test-list",
747 "--ignore-missing",
748 "--dry-run",
749 "-t", "pattern1",
750 "-t", "pattern2",
751 "-x", "xpattern1",
752 "-x", "xpattern2",
753 "-s",
754 "-l", "verbose",
755 "--overwrite",
756 "--multiple-mode",
757 "--inactivity-timeout", "27",
758 "--overall-timeout", "360",
759 "--use-watchdog",
760 "--piglit-style-dmesg",
761 testdatadir,
762 dirname,
763 };
764
765 igt_assert(parse_options(ARRAY_SIZE(argv), (char**)argv, settings));
766
767 igt_assert(serialize_settings(settings));
768
769 dirfd = open(dirname, O_DIRECTORY, O_RDONLY);
770 igt_assert_f(dirfd >= 0, "Serialization did not create the results directory\n");
771
772 igt_assert_f((fd = openat(dirfd, "metadata.txt", O_RDONLY)),
773 "Opening %s/metadata.txt failed\n", dirname);
774 close(fd);
775
776 igt_assert_f(read_settings_from_dir(cmp_settings, dirfd), "Reading settings failed\n");
777 assert_settings_equal(settings, cmp_settings);
778 }
779
780 igt_fixture {
781 close(fd);
782 close(dirfd);
783 clear_directory(dirname);
784 free_settings(cmp_settings);
785 free(cmp_settings);
786 }
787 }
788
789 igt_subtest_group {
790 char dirname[] = "tmpdirXXXXXX";
791 volatile int dirfd = -1, fd = -1;
792 struct job_list *list, *cmp_list;
793 int multiple;
794
795 list = malloc(sizeof(*list));
796 cmp_list = malloc(sizeof(*cmp_list));
797
798 igt_fixture {
799 init_job_list(list);
800 init_job_list(cmp_list);
801 igt_require(mkdtemp(dirname) != NULL);
802 rmdir(dirname);
803 }
804
805 for (multiple = 0; multiple < 2; multiple++) {
806 igt_subtest_f("job-list-serialize-%s", multiple ? "multiple" : "normal") {
807 const char *argv[] = { "runner",
808 /* Ugly */
809 multiple ? "--multiple-mode" : "--sync",
810 testdatadir,
811 dirname,
812 };
813
814 igt_assert(parse_options(ARRAY_SIZE(argv), (char**)argv, settings));
815 igt_assert(create_job_list(list, settings));
816
817 igt_assert(serialize_settings(settings));
818 igt_assert(serialize_job_list(list, settings));
819
820 dirfd = open(dirname, O_DIRECTORY, O_RDONLY);
821 igt_assert_f(dirfd >= 0, "Serialization did not create the results directory\n");
822
823 igt_assert_f((fd = openat(dirfd, "joblist.txt", O_RDONLY)) >= 0,
824 "Opening %s/joblist.txt failed\n", dirname);
825 close(fd);
826 fd = -1;
827
828 igt_assert_f(read_job_list(cmp_list, dirfd), "Reading job list failed\n");
829 assert_job_list_equal(list, cmp_list);
830 }
831
832 igt_fixture {
833 close(fd);
834 close(dirfd);
835 clear_directory(dirname);
836 free_job_list(cmp_list);
837 free_job_list(list);
838 }
839 }
840
841 igt_fixture {
842 free(cmp_list);
843 free(list);
844 }
845 }
846
847 igt_subtest_group {
848 char dirname[] = "tmpdirXXXXXX";
849 struct job_list *list = malloc(sizeof(*list));
850 volatile int dirfd = -1, subdirfd = -1, fd = -1;
851
852 igt_fixture {
853 init_job_list(list);
854 igt_require(mkdtemp(dirname) != NULL);
855 rmdir(dirname);
856 }
857
858 igt_subtest("dry-run-option") {
859 struct execute_state state;
860 const char *argv[] = { "runner",
861 "--dry-run",
862 testdatadir,
863 dirname,
864 };
865
866 igt_assert(parse_options(ARRAY_SIZE(argv), (char**)argv, settings));
867 igt_assert(create_job_list(list, settings));
868
869 igt_assert(initialize_execute_state(&state, settings, list));
870 igt_assert_eq(state.next, 0);
871 igt_assert(state.dry);
872 igt_assert_eq(list->size, 5);
873
874 igt_assert_f((dirfd = open(dirname, O_DIRECTORY | O_RDONLY)) >= 0,
875 "Dry run initialization didn't create the results directory.\n");
876
877 /* Execute from just initialize_execute_state should fail */
878 igt_assert(execute(&state, settings, list));
879 igt_assert_f(openat(dirfd, "0", O_DIRECTORY | O_RDONLY) < 0,
880 "Dry run executed when it should not have.\n");
881 igt_assert_f((fd = openat(dirfd, "metadata.txt", O_RDONLY)) >= 0,
882 "Dry run initialization didn't serialize settings.\n");
883 close(fd);
884 igt_assert_f((fd = openat(dirfd, "joblist.txt", O_RDONLY)) >= 0,
885 "Dry run initialization didn't serialize the job list.\n");
886 close(fd);
887 igt_assert_f((fd = openat(dirfd, "uname.txt", O_RDONLY)) < 0,
888 "Dry run initialization created uname.txt.\n");
889
890 igt_assert(initialize_execute_state_from_resume(dirfd, &state, settings, list));
891 igt_assert_eq(state.next, 0);
892 igt_assert(!state.dry);
893 igt_assert_eq(list->size, 5);
894 /* initialize_execute_state_from_resume() closes the dirfd */
895 igt_assert_f((dirfd = open(dirname, O_DIRECTORY | O_RDONLY)) >= 0,
896 "Dry run resume somehow deleted the results directory.\n");
897
898 /* Execute from resume should work */
899 igt_assert(execute(&state, settings, list));
900 igt_assert_f((fd = openat(dirfd, "uname.txt", O_RDONLY)) >= 0,
901 "Dry run resume didn't create uname.txt.\n");
902 close(fd);
903 igt_assert_f((subdirfd = openat(dirfd, "0", O_DIRECTORY | O_RDONLY)) >= 0,
904 "Dry run resume didn't create result directory.\n");
905 igt_assert_f((fd = openat(subdirfd, "journal.txt", O_RDONLY)) >= 0,
906 "Dry run resume didn't create a journal.\n");
907 }
908
909 igt_fixture {
910 close(fd);
911 close(dirfd);
912 close(subdirfd);
913 clear_directory(dirname);
914 free_job_list(list);
915 free(list);
916 }
917 }
918
919 igt_subtest_group {
920 char dirname[] = "tmpdirXXXXXX";
921 struct job_list *list = malloc(sizeof(*list));
922 volatile int dirfd = -1, fd = -1;
923
924 igt_fixture {
925 init_job_list(list);
926 igt_require(mkdtemp(dirname) != NULL);
927 rmdir(dirname);
928 }
929
930 igt_subtest("execute-initialize-new-run") {
931 struct execute_state state;
932 const char *argv[] = { "runner",
933 testdatadir,
934 dirname,
935 };
936
937 igt_assert(parse_options(ARRAY_SIZE(argv), (char**)argv, settings));
938 igt_assert(create_job_list(list, settings));
939
940 igt_assert(initialize_execute_state(&state, settings, list));
941
942 igt_assert_eq(state.next, 0);
943 igt_assert_eq(list->size, 5);
944 igt_assert_f((dirfd = open(dirname, O_DIRECTORY | O_RDONLY)) >= 0,
945 "Execute state initialization didn't create the results directory.\n");
946 igt_assert_f((fd = openat(dirfd, "metadata.txt", O_RDONLY)) >= 0,
947 "Execute state initialization didn't serialize settings.\n");
948 close(fd);
949 igt_assert_f((fd = openat(dirfd, "joblist.txt", O_RDONLY)) >= 0,
950 "Execute state initialization didn't serialize the job list.\n");
951 close(fd);
952 igt_assert_f((fd = openat(dirfd, "journal.txt", O_RDONLY)) < 0,
953 "Execute state initialization created a journal.\n");
954 igt_assert_f((fd = openat(dirfd, "uname.txt", O_RDONLY)) < 0,
955 "Execute state initialization created uname.txt.\n");
956 }
957
958 igt_fixture {
959 close(fd);
960 close(dirfd);
961 clear_directory(dirname);
962 free_job_list(list);
963 free(list);
964 }
965 }
966
967 igt_subtest_group {
968 char dirname[] = "tmpdirXXXXXX";
969 struct job_list *list = malloc(sizeof(*list));
970 volatile int dirfd = -1, subdirfd = -1, fd = -1;
971
972 igt_fixture {
973 init_job_list(list);
974 igt_require(mkdtemp(dirname) != NULL);
975 }
976
977 igt_subtest("execute-initialize-subtest-started") {
978 struct execute_state state;
979 const char *argv[] = { "runner",
980 "--multiple-mode",
981 "-t", "successtest",
982 testdatadir,
983 dirname,
984 };
985 const char journaltext[] = "first-subtest\n";
986 const char excludestring[] = "!first-subtest";
987
988 igt_assert(parse_options(ARRAY_SIZE(argv), (char**)argv, settings));
989 igt_assert(create_job_list(list, settings));
990 igt_assert(list->size == 1);
991 igt_assert(list->entries[0].subtest_count == 0);
992
993 igt_assert(serialize_settings(settings));
994 igt_assert(serialize_job_list(list, settings));
995
996 igt_assert((dirfd = open(dirname, O_DIRECTORY | O_RDONLY)) >= 0);
997 igt_assert(mkdirat(dirfd, "0", 0770) == 0);
998 igt_assert((subdirfd = openat(dirfd, "0", O_DIRECTORY | O_RDONLY)) >= 0);
999 igt_assert((fd = openat(subdirfd, "journal.txt", O_CREAT | O_WRONLY | O_EXCL, 0660)) >= 0);
1000 igt_assert(write(fd, journaltext, strlen(journaltext)) == strlen(journaltext));
1001
1002 free_job_list(list);
1003 free_settings(settings);
1004 igt_assert(initialize_execute_state_from_resume(dirfd, &state, settings, list));
1005
1006 igt_assert_eq(state.next, 0);
1007 igt_assert_eq(list->size, 1);
1008 igt_assert_eq(list->entries[0].subtest_count, 2);
1009 igt_assert_eqstr(list->entries[0].subtests[0], "*");
1010 igt_assert_eqstr(list->entries[0].subtests[1], excludestring);
1011 }
1012
1013 igt_fixture {
1014 close(fd);
1015 close(subdirfd);
1016 close(dirfd);
1017 clear_directory(dirname);
1018 free_job_list(list);
1019 free(list);
1020 }
1021 }
1022
1023 igt_subtest_group {
1024 char dirname[] = "tmpdirXXXXXX";
1025 struct job_list *list = malloc(sizeof(*list));
1026 volatile int dirfd = -1, subdirfd = -1, fd = -1;
1027
1028 igt_fixture {
1029 init_job_list(list);
1030 igt_require(mkdtemp(dirname) != NULL);
1031 }
1032
1033 igt_subtest("execute-initialize-all-subtests-started") {
1034 struct execute_state state;
1035 const char *argv[] = { "runner",
1036 "--multiple-mode",
1037 "-t", "successtest@first-subtest",
1038 "-t", "successtest@second-subtest",
1039 testdatadir,
1040 dirname,
1041 };
1042 const char journaltext[] = "first-subtest\nsecond-subtest\n";
1043
1044 igt_assert(parse_options(ARRAY_SIZE(argv), (char**)argv, settings));
1045 igt_assert(create_job_list(list, settings));
1046 igt_assert(list->size == 1);
1047 igt_assert(list->entries[0].subtest_count == 2);
1048
1049 igt_assert(serialize_settings(settings));
1050 igt_assert(serialize_job_list(list, settings));
1051
1052 igt_assert((dirfd = open(dirname, O_DIRECTORY | O_RDONLY)) >= 0);
1053 igt_assert(mkdirat(dirfd, "0", 0770) == 0);
1054 igt_assert((subdirfd = openat(dirfd, "0", O_DIRECTORY | O_RDONLY)) >= 0);
1055 igt_assert((fd = openat(subdirfd, "journal.txt", O_CREAT | O_WRONLY | O_EXCL, 0660)) >= 0);
1056 igt_assert(write(fd, journaltext, strlen(journaltext)) == strlen(journaltext));
1057
1058 free_job_list(list);
1059 free_settings(settings);
1060 igt_assert(initialize_execute_state_from_resume(dirfd, &state, settings, list));
1061
1062 /* All subtests are in journal, the entry should be considered completed */
1063 igt_assert_eq(state.next, 1);
1064 igt_assert_eq(list->size, 1);
1065 igt_assert_eq(list->entries[0].subtest_count, 4);
1066 }
1067
1068 igt_fixture {
1069 close(fd);
1070 close(subdirfd);
1071 close(dirfd);
1072 clear_directory(dirname);
1073 free_job_list(list);
1074 free(list);
1075 }
1076 }
1077
1078 igt_subtest_group {
1079 char dirname[] = "tmpdirXXXXXX";
1080 struct job_list *list = malloc(sizeof(*list));
1081 volatile int dirfd = -1, subdirfd = -1, fd = -1;
1082
1083 igt_fixture {
1084 init_job_list(list);
1085 igt_require(mkdtemp(dirname) != NULL);
1086 }
1087
1088 igt_subtest("execute-initialize-subtests-complete") {
1089 struct execute_state state;
1090 const char *argv[] = { "runner",
1091 "--multiple-mode",
1092 testdatadir,
1093 dirname,
1094 };
1095 const char journaltext[] = "first-subtest\nsecond-subtest\nexit:0\n";
1096
1097 igt_assert(parse_options(ARRAY_SIZE(argv), (char**)argv, settings));
1098 igt_assert(create_job_list(list, settings));
1099 igt_assert(list->size == 3);
1100
1101 if (!strcmp(list->entries[0].binary, "no-subtests")) {
1102 struct job_list_entry tmp = list->entries[0];
1103 list->entries[0] = list->entries[1];
1104 list->entries[1] = tmp;
1105 }
1106
1107 igt_assert(list->entries[0].subtest_count == 0);
1108
1109 igt_assert(serialize_settings(settings));
1110 igt_assert(serialize_job_list(list, settings));
1111
1112 igt_assert_lte(0, dirfd = open(dirname, O_DIRECTORY | O_RDONLY));
1113 igt_assert_eq(mkdirat(dirfd, "0", 0770), 0);
1114 igt_assert((subdirfd = openat(dirfd, "0", O_DIRECTORY | O_RDONLY)) >= 0);
1115 igt_assert_lte(0, fd = openat(subdirfd, "journal.txt", O_CREAT | O_WRONLY | O_EXCL, 0660));
1116 igt_assert_eq(write(fd, journaltext, sizeof(journaltext)), sizeof(journaltext));
1117
1118 free_job_list(list);
1119 free_settings(settings);
1120 igt_assert(initialize_execute_state_from_resume(dirfd, &state, settings, list));
1121
1122 igt_assert_eq(state.next, 1);
1123 igt_assert_eq(list->size, 3);
1124 }
1125
1126 igt_fixture {
1127 close(fd);
1128 close(subdirfd);
1129 close(dirfd);
1130 clear_directory(dirname);
1131 free_job_list(list);
1132 free(list);
1133 }
1134 }
1135
1136 igt_subtest_group {
1137 struct job_list *list = malloc(sizeof(*list));
1138 volatile int dirfd = -1, subdirfd = -1, fd = -1;
1139 int multiple;
1140
1141 igt_fixture {
1142 init_job_list(list);
1143 }
1144
1145 for (multiple = 0; multiple < 2; multiple++) {
1146 char dirname[] = "tmpdirXXXXXX";
1147
1148 igt_fixture {
1149 igt_require(mkdtemp(dirname) != NULL);
1150 rmdir(dirname);
1151 }
1152
1153 igt_subtest_f("execute-subtests-%s", multiple ? "multiple" : "normal") {
1154 struct execute_state state;
1155 const char *argv[] = { "runner",
1156 multiple ? "--multiple-mode" : "--sync",
1157 "-t", "-subtest",
1158 testdatadir,
1159 dirname,
1160 };
1161 char testdirname[16];
1162 size_t expected_tests = multiple ? 2 : 3;
1163 size_t i;
1164
1165 igt_assert(parse_options(ARRAY_SIZE(argv), (char**)argv, settings));
1166 igt_assert(create_job_list(list, settings));
1167 igt_assert(initialize_execute_state(&state, settings, list));
1168
1169 igt_assert(execute(&state, settings, list));
1170 igt_assert_f((dirfd = open(dirname, O_DIRECTORY | O_RDONLY)) >= 0,
1171 "Execute didn't create the results directory\n");
1172
1173 igt_assert_f((fd = openat(dirfd, "uname.txt", O_RDONLY)) >= 0,
1174 "Execute didn't create uname.txt\n");
1175 close(fd);
1176 fd = -1;
1177
1178 for (i = 0; i < expected_tests; i++) {
1179 snprintf(testdirname, 16, "%zd", i);
1180
1181 igt_assert_f((subdirfd = openat(dirfd, testdirname, O_DIRECTORY | O_RDONLY)) >= 0,
1182 "Execute didn't create result directory '%s'\n", testdirname);
1183 assert_execution_results_exist(subdirfd);
1184 close(subdirfd);
1185 }
1186
1187 snprintf(testdirname, 16, "%zd", expected_tests);
1188 igt_assert_f((subdirfd = openat(dirfd, testdirname, O_DIRECTORY | O_RDONLY)) < 0,
1189 "Execute created too many directories\n");
1190 }
1191
1192 igt_fixture {
1193 close(fd);
1194 close(subdirfd);
1195 close(dirfd);
1196 clear_directory(dirname);
1197 free_job_list(list);
1198 }
1199 }
1200
1201 igt_fixture
1202 free(list);
1203 }
1204
1205 igt_subtest_group {
1206 igt_subtest("metadata-read-old-style-infer-dmesg-warn-piglit-style") {
1207 char metadata[] = "piglit_style_dmesg : 1\n";
1208 FILE *f = fmemopen(metadata, strlen(metadata), "r");
1209 igt_assert(f);
1210
1211 igt_assert(read_settings_from_file(settings, f));
1212
1213 igt_assert(settings->piglit_style_dmesg);
1214 igt_assert_eq(settings->dmesg_warn_level, 5);
1215
1216 fclose(f);
1217 }
1218
1219 igt_subtest("metadata-read-overrides-dmesg-warn-piglit-style") {
1220 char metadata[] = "piglit_style_dmesg : 1\ndmesg_warn_level : 3";
1221 FILE *f = fmemopen(metadata, strlen(metadata), "r");
1222 igt_assert(f);
1223
1224 igt_assert(read_settings_from_file(settings, f));
1225
1226 igt_assert(settings->piglit_style_dmesg);
1227 igt_assert_eq(settings->dmesg_warn_level, 3);
1228
1229 fclose(f);
1230 }
1231
1232 igt_subtest("metadata-read-old-style-infer-dmesg-warn-default") {
1233 char metadata[] = "piglit_style_dmesg : 0\n";
1234 FILE *f = fmemopen(metadata, strlen(metadata), "r");
1235 igt_assert(f);
1236
1237 igt_assert(read_settings_from_file(settings, f));
1238
1239 igt_assert(!settings->piglit_style_dmesg);
1240 igt_assert_eq(settings->dmesg_warn_level, 4);
1241
1242 fclose(f);
1243 }
1244
1245 igt_subtest("metadata-read-overrides-dmesg-warn-default") {
1246 char metadata[] = "piglit_style_dmesg : 0\ndmesg_warn_level : 3";
1247 FILE *f = fmemopen(metadata, strlen(metadata), "r");
1248 igt_assert(f);
1249
1250 igt_assert(read_settings_from_file(settings, f));
1251
1252 igt_assert(!settings->piglit_style_dmesg);
1253 igt_assert_eq(settings->dmesg_warn_level, 3);
1254
1255 fclose(f);
1256 }
1257 }
1258
1259 igt_subtest_group {
1260 struct job_list *list = malloc(sizeof(*list));
1261 volatile int dirfd = -1, subdirfd = -1, fd = -1;
1262 int multiple;
1263
1264 igt_fixture {
1265 init_job_list(list);
1266 }
1267
1268 for (multiple = 0; multiple < 2; multiple++) {
1269 char dirname[] = "tmpdirXXXXXX";
1270
1271 igt_fixture {
1272 igt_require(mkdtemp(dirname) != NULL);
1273 rmdir(dirname);
1274 }
1275
1276 igt_subtest_f("execute-skipper-journal-%s", multiple ? "multiple" : "normal") {
1277 struct execute_state state;
1278 const char *argv[] = { "runner",
1279 multiple ? "--multiple-mode" : "--sync",
1280 "-t", "skippers",
1281 testdatadir,
1282 dirname,
1283 };
1284 char *dump;
1285 const char *expected_0 = multiple ?
1286 "skip-one\nskip-two\nexit:77 (" :
1287 "skip-one\nexit:77 (";
1288 const char *expected_1 = "skip-two\nexit:77 (";
1289
1290 igt_assert(parse_options(ARRAY_SIZE(argv), (char**)argv, settings));
1291 igt_assert(create_job_list(list, settings));
1292 igt_assert(initialize_execute_state(&state, settings, list));
1293
1294 igt_assert(execute(&state, settings, list));
1295 igt_assert_f((dirfd = open(dirname, O_DIRECTORY | O_RDONLY)) >= 0,
1296 "Execute didn't create the results directory\n");
1297
1298 igt_assert_f((fd = openat(dirfd, "uname.txt", O_RDONLY)) >= 0,
1299 "Execute didn't create uname.txt\n");
1300 close(fd);
1301 fd = -1;
1302
1303 igt_assert_f((subdirfd = openat(dirfd, "0", O_DIRECTORY | O_RDONLY)) >= 0,
1304 "Execute didn't create result directory '0'\n");
1305 dump = dump_file(subdirfd, "journal.txt");
1306 igt_assert_f(dump != NULL,
1307 "Execute didn't create the journal\n");
1308 /* Trim out the runtime */
1309 dump[strlen(expected_0)] = '\0';
1310 igt_assert_eqstr(dump, expected_0);
1311 free(dump);
1312 close(subdirfd);
1313 subdirfd = -1;
1314
1315 if (!multiple) {
1316 igt_assert_f((subdirfd = openat(dirfd, "1", O_DIRECTORY | O_RDONLY)) >= 0,
1317 "Execute didn't create result directory '1'\n");
1318 dump = dump_file(subdirfd, "journal.txt");
1319 igt_assert_f(dump != NULL,
1320 "Execute didn't create the journal\n");
1321 dump[strlen(expected_1)] = '\0';
1322 igt_assert_eqstr(dump, expected_1);
1323 free(dump);
1324 close(subdirfd);
1325 subdirfd = -1;
1326 }
1327 }
1328
1329 igt_fixture {
1330 close(fd);
1331 close(subdirfd);
1332 close(dirfd);
1333 clear_directory(dirname);
1334 free_job_list(list);
1335 }
1336 }
1337
1338 igt_fixture
1339 free(list);
1340 }
1341
1342 igt_subtest("file-descriptor-leakage") {
1343 int i;
1344
1345 /*
1346 * This is a build-time test, and it's expected that
1347 * all subtests are normally run. Keep this one at the
1348 * end.
1349 *
1350 * Try to close some number of fds after stderr and
1351 * expect EBADF for each one.
1352 */
1353 for (i = 3; i < 400; i++) {
1354 errno = 0;
1355 igt_assert_neq(close(i), 0);
1356 igt_assert_eq(errno, EBADF);
1357 }
1358 }
1359
1360 igt_fixture {
1361 free_settings(settings);
1362 free(settings);
1363 }
1364 }
1365