@@ -38,6 +38,8 @@ binmode STDERR, ':utf8';
38
38
# subshell or situations like that.
39
39
AnyEvent::Util::close_all_fds_except(0, 1, 2);
40
40
41
+ our @CLEANUP ;
42
+
41
43
# convenience wrapper to write to the log file
42
44
my $log ;
43
45
sub Log { say $log " @_ " }
@@ -55,6 +57,7 @@ my %options = (
55
57
xtrace => 0,
56
58
coverage => 0,
57
59
restart => 0,
60
+ xvfb => 1,
58
61
);
59
62
my $keep_xserver_output = 0;
60
63
@@ -64,6 +67,7 @@ my $result = GetOptions(
64
67
" valgrind" => \$options {valgrind },
65
68
" strace" => \$options {strace },
66
69
" xtrace" => \$options {xtrace },
70
+ " xvfb" => \$options {xvfb },
67
71
" display=s" => \@displays ,
68
72
" parallel=i" => \$parallel ,
69
73
" help|?" => \$help ,
@@ -112,6 +116,44 @@ $ENV{PATH} = join(':',
112
116
qx( Xephyr -help 2>&1) ;
113
117
die " Xephyr was not found in your path. Please install Xephyr (xserver-xephyr on Debian)." if $? ;
114
118
119
+ qx( xvfb-run --help 2>&1) ;
120
+ if ($? && $options {xvfb }) {
121
+ say " xvfb-run not found, not running tests under xvfb. Install the xvfb package to speed up tests" ;
122
+ $options {xvfb } = 0;
123
+ }
124
+
125
+ if ($options {xvfb }) {
126
+ for (my $n = 99; $n < 120; $n ++) {
127
+ my $path = File::Temp::tmpnam($ENV {TMPDIR } // " /tmp" , " i3-testsXXXXXX" );
128
+ if (!defined (POSIX::mkfifo($path , 0600))) {
129
+ die " mkfifo: $! " ;
130
+ }
131
+ my $pid = fork // die " fork: $! " ;
132
+ if ($pid == 0) {
133
+ # Child
134
+
135
+ # Xvfb checks whether the parent ignores USR1 and sends USR1 to the
136
+ # parent when ready, so that the wait call will be interrupted. We
137
+ # can’t implement this in Perl, as Perl’s waitpid transparently
138
+ # handles -EINTR.
139
+ exec (' /bin/sh' , ' -c' , qq| trap "exit" INT; trap : USR1; (trap '' USR1; exec Xvfb :$n -screen 0 640x480x8 -nolisten tcp) & PID=\$ !; wait; if ! kill -0 \$ PID 2>/dev/null; then echo 1:\$ PID > $path ; else echo 0:\$ PID > $path ; wait \$ PID; fi| );
140
+ die " exec: $! " ;
141
+ }
142
+ chomp (my $kill = slurp($path ));
143
+ unlink ($path );
144
+ my ($code , $xvfbpid ) = ($kill =~ m , ^([0-1]):(.*)$ , );
145
+ next unless $code eq ' 0' ;
146
+
147
+ $ENV {DISPLAY } = " :$n " ;
148
+ say " Running tests under Xvfb display $ENV {DISPLAY}" ;
149
+
150
+ push (@CLEANUP , sub {
151
+ kill (15, $xvfbpid );
152
+ });
153
+ last ;
154
+ }
155
+ }
156
+
115
157
@displays = split (/ ,/ , join (' ,' , @displays ));
116
158
@displays = map { s / // g ; $_ } @displays ;
117
159
@@ -379,7 +421,7 @@ sub take_job {
379
421
380
422
sub cleanup {
381
423
my $exitcode = $? ;
382
- $_ -> () for our @CLEANUP ;
424
+ $_ -> () for @CLEANUP ;
383
425
exit $exitcode ;
384
426
}
385
427
0 commit comments