#!/usr/bin/env perl
# vim:ts=4:sw=4:expandtab
-# © 2010-2012 Michael Stapelberg and contributors
+# © 2010 Michael Stapelberg and contributors
package complete_run;
use strict;
use warnings;
use utf8;
# the following are modules which ship with Perl (>= 5.10):
use Pod::Usage;
-use Cwd qw(abs_path);
use File::Temp qw(tempfile tempdir);
use Getopt::Long;
use POSIX ();
use TAP::Parser::Aggregator;
use Time::HiRes qw(time);
use IO::Handle;
+
+my $dirname;
+
+BEGIN {
+ use File::Basename;
+ use Cwd qw(abs_path);
+
+ # fileparse()[1] contains the directory portion of the specified path.
+ # See File::Basename(3p) for more details.
+ $dirname = (fileparse(abs_path($0)))[1];
+}
+
# these are shipped with the testsuite
-use lib qw(lib);
+use lib $dirname . 'lib';
+use i3test::Util qw(slurp);
use StartXServer;
use StatusLine;
use TestWorker;
# subshell or situations like that.
AnyEvent::Util::close_all_fds_except(0, 1, 2);
-# convinience wrapper to write to the log file
+# convenience wrapper to write to the log file
my $log;
sub Log { say $log "@_" }
pod2usage(-verbose => 2, -exitcode => 0) if $help;
+chdir $dirname or die "Could not chdir into $dirname";
+
# Check for missing executables
my @binaries = qw(
../i3
die "$binary is not an executable" unless -x $binary;
}
+if ($options{coverage}) {
+ qx(command -v lcov &> /dev/null);
+ die "Cannot find lcov needed for coverage testing." if $?;
+ qx(command -v genhtml &> /dev/null);
+ die "Cannot find genhtml needed for coverage testing." if $?;
+
+ # clean out the counters that may be left over from previous tests.
+ qx(lcov -d ../ --zerocounters &> /dev/null);
+}
+
qx(Xephyr -help 2>&1);
die "Xephyr was not found in your path. Please install Xephyr (xserver-xephyr on Debian)." if $?;
# 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 = StartXServer::slurp('.last_run_timings.json');
+my $timingsjson = slurp('.last_run_timings.json') if -e '.last_run_timings.json';
%timings = %{decode_json($timingsjson)} if length($timingsjson) > 0;
# Re-order the files so that those which took the longest time in the previous
$aggregator->stop();
-# print empty lines to seperate failed tests from statuslines
+# print empty lines to separate failed tests from statuslines
print "\n\n";
for (@done) {
if ($numtests == 1) {
say '';
say 'Test output:';
- say StartXServer::slurp($logfile);
+ say slurp($logfile);
}
END { cleanup() }
-exit 0;
+if ($options{coverage}) {
+ print("\nGenerating test coverage report...\n");
+ qx(lcov -d ../ -b ../ --capture -o latest/i3-coverage.info);
+ qx(genhtml -o latest/i3-coverage latest/i3-coverage.info);
+ if ($?) {
+ print("Could not generate test coverage html. Did you compile i3 with test coverage support?\n");
+ } else {
+ print("Test coverage report generated in latest/i3-coverage\n");
+ }
+}
+
+# Report logfiles that match “(Leak|Address)Sanitizer:”.
+my @logs_with_leaks;
+for my $log (<$outdir/i3-log-for-*>) {
+ if (slurp($log) =~ /(Leak|Address)Sanitizer:/) {
+ push @logs_with_leaks, $log;
+ }
+}
+if (scalar @logs_with_leaks > 0) {
+ say "\nThe following test logfiles contain AddressSanitizer or LeakSanitizer reports:";
+ for my $log (sort @logs_with_leaks) {
+ say "\t$log";
+ }
+}
+
+exit ($aggregator->failed > 0);
#
# Takes a test from the beginning of @testfiles and runs it.
}
sub cleanup {
+ my $exitcode = $?;
$_->() for our @CLEANUP;
- exit;
+ exit $exitcode;
}
# must be in a begin block because we C<exit 0> above
=item B<--coverage-testing>
-Exits i3 cleanly (instead of kill -9) to make coverage testing work properly.
+Generates a test coverage report at C<latest/i3-coverage>. Exits i3 cleanly
+during tests (instead of kill -9) to make coverage testing work properly.
=item B<--parallel>
-Number of Xephyr instances to start (if you don’t want to start num_cores * 2
+Number of Xephyr instances to start (if you don't want to start num_cores * 2
instances for some reason).
# Run all tests on a single Xephyr instance
./complete-run.pl -p 1
+
+=back