use POSIX ();
+use Errno qw(EAGAIN);
+
use Exporter 'import';
our @EXPORT = qw(worker worker_next);
$worker->{ipc} = $ipc_child;
+ # Preload the i3test module: reduces user CPU from 25s to 18s
require i3test;
- # TODO: recycle $x
- # unfortunately this fails currently with:
- # Could not get reply for: xcb_intern_atom_reply at X11/XCB/Atom.pm line 22.
- # $i3test::x = bless $x, 'i3test::X11';
worker_wait($worker, $outdir);
exit 23;
my $ipc = $self->{ipc};
my $ipc_fd = fileno($ipc);
- while (defined(my $file = $ipc->getline)) {
+ while (1) {
+ my $file = $ipc->getline;
+ if (!defined($file)) {
+ next if $! == EAGAIN;
+ last;
+ }
chomp $file;
exit unless $file;
- die "tried to launch nonexistend testfile $file: $!\n"
+ die "tried to launch nonexistent testfile $file: $!\n"
unless -e $file;
# start a new and self contained process:
- # whatever happens in the testfile should *NOT* effect us.
+ # whatever happens in the testfile should *NOT* affect us.
my $pid = fork // die "could not fork: $!";
if ($pid == 0) {
$0 = $file;
+ # Re-seed rand() so that File::Temp’s tempnam produces different
+ # results, making a TOCTOU between e.g. t/175-startup-notification.t
+ # and t/180-fd-leaks.t less likely.
+ srand(time ^ $$);
+
POSIX::dup2($ipc_fd, 0);
POSIX::dup2($ipc_fd, 1);
POSIX::dup2(1, 2);
$test->failure_output(\*STDERR);
$test->todo_output(\*STDOUT);
- @ENV{qw(DISPLAY TESTNAME OUTDIR VALGRIND STRACE COVERAGE RESTART)}
- = ($self->{display},
+ @ENV{qw(HOME DISPLAY TESTNAME OUTDIR VALGRIND STRACE XTRACE COVERAGE RESTART)}
+ = ($outdir,
+ $self->{display},
basename($file),
$outdir,
$options->{valgrind},
$options->{strace},
+ $options->{xtrace},
$options->{coverage},
$options->{restart});
package main;
local $@;
- do "./$file";
+ do $file;
$test->ok(undef, "$@") if $@;
# XXX hack, we need to trigger the read watcher once more