1 # vim:ts=4:sw=4:sts=4:expandtab
3 use strict; use warnings;
6 use Socket qw(AF_UNIX SOCK_DGRAM PF_UNSPEC);
7 use IO::Handle; # for ->autoflush
13 use Exporter 'import';
14 our @EXPORT = qw(worker worker_next);
16 use File::Basename qw(basename);
21 my ($display, $x, $outdir, $optref) = @_;
23 # make sure $x hangs around
26 # store the options hashref
29 socketpair(my $ipc_child, my $ipc, AF_UNIX, SOCK_DGRAM, PF_UNSPEC)
30 or die "socketpair: $!";
33 $ipc_child->autoflush(1);
40 my $pid = fork // die "could not fork: $!";
44 undef @complete_run::CLEANUP;
45 # reap dead test children
46 $SIG{CHLD} = sub { waitpid -1, POSIX::WNOHANG };
48 $worker->{ipc} = $ipc_child;
50 # Preload the i3test module: reduces user CPU from 25s to 18s
53 worker_wait($worker, $outdir);
59 push @complete_run::CLEANUP, sub {
60 # signal via empty line to exit itself
61 syswrite($ipc, "\n") or kill('TERM', $pid);
69 our $EOF = "# end of file\n";
71 my ($self, $outdir) = @_;
73 my $ipc = $self->{ipc};
74 my $ipc_fd = fileno($ipc);
77 my $file = $ipc->getline;
78 if (!defined($file)) {
86 die "tried to launch nonexistent testfile $file: $!\n"
89 # start a new and self contained process:
90 # whatever happens in the testfile should *NOT* affect us.
92 my $pid = fork // die "could not fork: $!";
94 undef @complete_run::CLEANUP;
99 # Re-seed rand() so that File::Temp’s tempnam produces different
100 # results, making a TOCTOU between e.g. t/175-startup-notification.t
101 # and t/180-fd-leaks.t less likely.
104 POSIX::dup2($ipc_fd, 0);
105 POSIX::dup2($ipc_fd, 1);
108 # get Test::Builder singleton
109 my $test = Test::Builder->new;
111 # Test::Builder dups stdout/stderr while loading.
112 # we need to reset them here to point to $ipc
113 $test->output(\*STDOUT);
114 $test->failure_output(\*STDERR);
115 $test->todo_output(\*STDOUT);
117 @ENV{qw(HOME DISPLAY TESTNAME OUTDIR VALGRIND STRACE XTRACE COVERAGE RESTART)}
122 $options->{valgrind},
125 $options->{coverage},
126 $options->{restart});
131 $test->ok(undef, "$@") if $@;
133 # XXX hack, we need to trigger the read watcher once more
134 # to signal eof to TAP::Parser
143 my ($self, $file) = @_;
145 my $ipc = $self->{ipc};
146 syswrite $ipc, "$file\n" or die "syswrite: $!";