use TAP::Parser;
use TAP::Parser::Aggregator;
use Time::HiRes qw(time);
+use IO::Handle;
# these are shipped with the testsuite
use lib qw(lib);
use StartXDummy;
my %options = (
valgrind => 0,
strace => 0,
+ xtrace => 0,
coverage => 0,
restart => 0,
);
+my $keep_xdummy_output = 0;
my $result = GetOptions(
"coverage-testing" => \$options{coverage},
+ "keep-xdummy-output" => \$keep_xdummy_output,
"valgrind" => \$options{valgrind},
"strace" => \$options{strace},
+ "xtrace" => \$options{xtrace},
"display=s" => \@displays,
"parallel=i" => \$parallel,
"help|?" => \$help,
pod2usage(-verbose => 2, -exitcode => 0) if $help;
+# Check for missing executables
+my @binaries = qw(
+ ../i3
+ ../i3bar/i3bar
+ ../i3-config-wizard/i3-config-wizard
+ ../i3-dump-log/i3-dump-log
+ ../i3-input/i3-input
+ ../i3-msg/i3-msg
+ ../i3-nagbar/i3-nagbar
+ );
+
+foreach my $binary (@binaries) {
+ die "$binary executable not found" unless -e $binary;
+ die "$binary is not an executable" unless -x $binary;
+}
+
@displays = split(/,/, join(',', @displays));
@displays = map { s/ //g; $_ } @displays;
my $numtests = scalar @testfiles;
-# When the user specifies displays, we don’t run multi-monitor tests at all
-# (because we don’t know which displaynumber is the X-Server with multiple
-# monitors).
-my $multidpy = undef;
-
# No displays specified, let’s start some Xdummy instances.
if (@displays == 0) {
- my $dpyref;
- ($dpyref, $multidpy) = start_xdummy($parallel, $numtests);
- @displays = @$dpyref;
+ @displays = start_xdummy($parallel, $numtests, $keep_xdummy_output);
}
# 1: create an output directory for this test-run
}
}
-my @multi_worker;
-if (defined($multidpy)) {
- my $x = X11::XCB::Connection->new(display => $multidpy);
- if ($x->has_error) {
- die "Could not connect to multi-monitor display $multidpy\n";
- } else {
- push @multi_worker, worker($multidpy, $x, $outdir, \%options);
- }
-}
-
# Read previous timing information, if available. We will be able to roughly
# predict the test duration and schedule a good order for the tests.
my $timingsjson = StartXDummy::slurp('.last_run_timings.json');
my $logfile = "$outdir/complete-run.log";
open $log, '>', $logfile or die "Could not create '$logfile': $!";
+$log->autoflush(1);
say "Writing logfile to '$logfile'...";
# 3: run all tests
my $num = @testfiles;
my $harness = TAP::Harness->new({ });
-my @single_monitor_tests = grep { m,^t/([0-9]+)-, && $1 < 500 } @testfiles;
-my @multi_monitor_tests = grep { m,^t/([0-9]+)-, && $1 >= 500 } @testfiles;
-
my $aggregator = TAP::Parser::Aggregator->new();
$aggregator->start();
-status_init(displays => [ @displays, $multidpy ], tests => $num);
+status_init(displays => \@displays, tests => $num);
my $single_cv = AE::cv;
-my $multi_cv = AE::cv;
# We start tests concurrently: For each display, one test gets started. Every
# test starts another test after completing.
for (@single_worker) {
$single_cv->begin;
- take_job($_, $single_cv, \@single_monitor_tests);
-}
-for (@multi_worker) {
- $multi_cv->begin;
- take_job($_, $multi_cv, \@multi_monitor_tests);
+ take_job($_, $single_cv, \@testfiles);
}
$single_cv->recv;
-$multi_cv->recv;
$aggregator->stop();
for (1 .. $lines) {
my $result = $parser->next;
- if (defined($result) and $result->is_test) {
+ next unless defined($result);
+ if ($result->is_test) {
$tests_completed++;
status($display, "$test: [$tests_completed/??] ");
+ } elsif ($result->is_bailout) {
+ Log status($display, "$test: BAILOUT");
+ status_completed(scalar @done);
+ say "";
+ say "test $test bailed out: " . $result->explanation;
+ exit 1;
}
}
Runs i3 under strace to trace system calls. The output will be available in
C<latest/strace-for-$test.log>.
+=item B<--xtrace>
+
+Runs i3 under xtrace to trace X11 requests/replies. The output will be
+available in C<latest/xtrace-for-$test.log>.
+
=item B<--coverage-testing>
Exits i3 cleanly (instead of kill -9) to make coverage testing work properly.