Skip to content
This repository has been archived by the owner on Nov 7, 2022. It is now read-only.

Commit

Permalink
tests: run under Xvfb by default (if available) (#2951)
Browse files Browse the repository at this point in the history
This shaves off two seconds of wall-clock time (10s → 8s).
  • Loading branch information
stapelberg committed Oct 13, 2017
1 parent 28ca1e8 commit 44a6efb
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 7 deletions.
6 changes: 2 additions & 4 deletions docs/testsuite
Expand Up @@ -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+
---------------------------------------
Expand Down
44 changes: 43 additions & 1 deletion testcases/complete-run.pl.in
Expand Up @@ -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 "@_" }
Expand All @@ -55,6 +57,7 @@ my %options = (
xtrace => 0,
coverage => 0,
restart => 0,
xvfb => 1,
);
my $keep_xserver_output = 0;

Expand All @@ -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,
Expand Down Expand Up @@ -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;

Expand Down Expand Up @@ -379,7 +421,7 @@ sub take_job {

sub cleanup {
my $exitcode = $?;
$_->() for our @CLEANUP;
$_->() for @CLEANUP;
exit $exitcode;
}

Expand Down
4 changes: 2 additions & 2 deletions travis/run-tests.sh
Expand Up @@ -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

0 comments on commit 44a6efb

Please sign in to comment.