]> git.sur5r.net Git - i3/i3/commitdiff
tests: run under Xvfb by default (if available) (#2951)
authorMichael Stapelberg <stapelberg@users.noreply.github.com>
Fri, 13 Oct 2017 07:18:49 +0000 (00:18 -0700)
committerGitHub <noreply@github.com>
Fri, 13 Oct 2017 07:18:49 +0000 (00:18 -0700)
This shaves off two seconds of wall-clock time (10s → 8s).

docs/testsuite
testcases/complete-run.pl.in
travis/run-tests.sh

index bf85cb1fbe34411cffa0c19b71d79dd4b6ea6193..b535e7c141ca994b9f453771097868e9150c8104 100644 (file)
@@ -113,10 +113,8 @@ containing the appropriate i3 logfile for each testcase. The latest folder can
 always be found under the symlink +latest/+. Unless told differently, it will
 run the tests on a separate X server instance (using Xephyr).
 
-Xephyr will open a window where you can inspect the running test. You can run
-the tests without an X session with Xvfb, such as with +xvfb-run
-./complete-run+. This will also speed up the tests significantly especially on
-machines without a powerful video card.
+Xephyr will open a window where you can inspect the running test. By default,
+tests are run under Xvfb.
 
 .Example invocation of +complete-run.pl+
 ---------------------------------------
index ddd6ccadf992596d1b02672028fe239c4c42fd3b..b7b398720e283a150dfd47fdd4ab82192e2267e6 100755 (executable)
@@ -38,6 +38,8 @@ binmode STDERR, ':utf8';
 # subshell or situations like that.
 AnyEvent::Util::close_all_fds_except(0, 1, 2);
 
+our @CLEANUP;
+
 # convenience wrapper to write to the log file
 my $log;
 sub Log { say $log "@_" }
@@ -55,6 +57,7 @@ my %options = (
     xtrace => 0,
     coverage => 0,
     restart => 0,
+    xvfb => 1,
 );
 my $keep_xserver_output = 0;
 
@@ -64,6 +67,7 @@ my $result = GetOptions(
     "valgrind" => \$options{valgrind},
     "strace" => \$options{strace},
     "xtrace" => \$options{xtrace},
+    "xvfb" => \$options{xvfb},
     "display=s" => \@displays,
     "parallel=i" => \$parallel,
     "help|?" => \$help,
@@ -112,6 +116,44 @@ $ENV{PATH} = join(':',
 qx(Xephyr -help 2>&1);
 die "Xephyr was not found in your path. Please install Xephyr (xserver-xephyr on Debian)." if $?;
 
+qx(xvfb-run --help 2>&1);
+if ($? && $options{xvfb}) {
+    say "xvfb-run not found, not running tests under xvfb. Install the xvfb package to speed up tests";
+    $options{xvfb} = 0;
+}
+
+if ($options{xvfb}) {
+    for (my $n = 99; $n < 120; $n++) {
+       my $path = File::Temp::tmpnam($ENV{TMPDIR} // "/tmp", "i3-testsXXXXXX");
+       if (!defined(POSIX::mkfifo($path, 0600))) {
+           die "mkfifo: $!";
+       }
+       my $pid = fork // die "fork: $!";
+       if ($pid == 0) {
+           # Child
+
+           # Xvfb checks whether the parent ignores USR1 and sends USR1 to the
+           # parent when ready, so that the wait call will be interrupted.  We
+           # can’t implement this in Perl, as Perl’s waitpid transparently
+           # handles -EINTR.
+           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|);
+           die "exec: $!";
+       }
+       chomp(my $kill = slurp($path));
+       unlink($path);
+       my ($code, $xvfbpid) = ($kill =~ m,^([0-1]):(.*)$,);
+       next unless $code eq '0';
+
+       $ENV{DISPLAY} = ":$n";
+       say "Running tests under Xvfb display $ENV{DISPLAY}";
+
+       push(@CLEANUP, sub {
+           kill(15, $xvfbpid);
+       });
+       last;
+    }
+}
+
 @displays = split(/,/, join(',', @displays));
 @displays = map { s/ //g; $_ } @displays;
 
@@ -379,7 +421,7 @@ sub take_job {
 
 sub cleanup {
     my $exitcode = $?;
-    $_->() for our @CLEANUP;
+    $_->() for @CLEANUP;
     exit $exitcode;
 }
 
index 44df81d2ffbdf257fdb0c428999290c56c711db5..eac2ea8a37715f340f27e17969419ff55bceb4b0 100755 (executable)
@@ -26,7 +26,7 @@ fi
 
 # Try running the tests in parallel so that the common case (tests pass) is
 # quick, but fall back to running them in sequence to make debugging easier.
-if ! xvfb-run make check
+if ! make check
 then
-       xvfb-run ./testcases/complete-run.pl --parallel=1 || (cat latest/complete-run.log; false)
+       ./testcases/complete-run.pl --parallel=1 || (cat latest/complete-run.log; false)
 fi