123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340 |
- #!/usr/bin/perl -w
- # Copyright (C) 2010, 2011, 2012 Apple Inc. All rights reserved.
- #
- # Redistribution and use in source and binary forms, with or without
- # modification, are permitted provided that the following conditions
- # are met:
- # 1. Redistributions of source code must retain the above copyright
- # notice, this list of conditions and the following disclaimer.
- # 2. Redistributions in binary form must reproduce the above copyright
- # notice, this list of conditions and the following disclaimer in the
- # documentation and/or other materials provided with the distribution.
- #
- # THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
- # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- # THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- # PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
- # BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
- # THE POSSIBILITY OF SUCH DAMAGE.
- use strict;
- use warnings;
- use File::Basename;
- use FindBin;
- use Getopt::Long qw(:config pass_through);
- use IPC::Open3;
- use lib $FindBin::Bin;
- use webkitdirs;
- use VCSUtils;
- sub buildTestTool();
- sub dumpTestsBySuite(\@);
- sub listAllTests();
- sub runTest($$$);
- sub runTestsBySuite(\@$);
- sub prepareEnvironmentForRunningTestTool();
- sub testToolPath();
- # Defined in VCSUtils.
- sub possiblyColored($$);
- # Timeout for individual test, in sec
- my $timeout = 10;
- my $showHelp = 0;
- my $verbose = 0;
- my $dumpTests = 0;
- my $build = 1;
- my $root;
- my $buildDefault = $build ? "build" : "do not build";
- my @testsFailed;
- my @testsTimedOut;
- my $programName = basename($0);
- my $usage = <<EOF;
- Usage: $programName [options] [suite or test prefixes]
- --help Show this help message
- -v|--verbose Verbose output
- -d|--dump-tests Dump the names of testcases without running them
- --[no-]build Build (or do not build) unit tests prior to running (default: $buildDefault)
- --root= Path to the pre-built root containing TestWebKitAPI
- EOF
- GetOptions(
- 'help' => \$showHelp,
- 'verbose|v' => \$verbose,
- 'dump|d' => \$dumpTests,
- 'build!' => \$build,
- 'root=s' => \$root
- );
- if ($showHelp) {
- print STDERR $usage;
- exit 1;
- }
- setConfiguration();
- setConfigurationProductDir(Cwd::abs_path($root)) if (defined($root));
- buildTestTool() if $build && !defined($root);
- setPathForRunningWebKitApp(\%ENV);
- my @testsToRun = listAllTests();
- @testsToRun = grep { my $test = $_; grep { $test =~ m/^\Q$_\E/ } @ARGV; } @testsToRun if @ARGV;
- if ($dumpTests) {
- dumpTestsBySuite(@testsToRun);
- exit 0;
- }
- exit runTestsBySuite(@testsToRun, $verbose);
- sub isSupportedPlatform()
- {
- return isAppleMacWebKit() || isAppleWinWebKit();
- }
- sub dumpTestsBySuite(\@)
- {
- my ($tests) = @_;
- print "Dumping test cases\n";
- print "------------------\n";
- my $lastSuite = "";
- for my $suiteAndTest (sort @$tests) {
- my ($suite, $test) = split(/\./, $suiteAndTest);
- if ($lastSuite ne $suite) {
- $lastSuite = $suite;
- print "$suite:\n";
- }
- print " $test\n";
- }
- print "------------------\n";
- }
- sub runTestsBySuite(\@$)
- {
- my ($tests, $verbose) = @_;
- my $anyFailures = 0;
- my $lastSuite = "";
- for my $suiteAndTest (sort @$tests) {
- my ($suite, $test) = split(/\./, $suiteAndTest);
- if ($lastSuite ne $suite) {
- $lastSuite = $suite;
- print "Suite: $suite\n" unless $verbose;
- }
- my $failed = runTest($suite, $test, $verbose);
- $anyFailures ||= $failed;
- }
-
- if ($verbose) {
- if (@testsFailed) {
- print "Tests that failed:\n";
- for my $test (@testsFailed) {
- print " $test\n";
- }
- }
- if (@testsTimedOut) {
- print "Tests that timed out:\n";
- for my $test (@testsTimedOut) {
- print " $test\n";
- }
- }
- }
- return $anyFailures;
- }
- sub runTest($$$)
- {
- my ($suite, $testName, $verbose) = @_;
- my $test = $suite . "." . $testName;
- my $gtestArg = "--gtest_filter=" . $test;
- print " Test: $testName -> " unless $verbose;
- my $result = 0;
- my $timedOut = 0;
- die "run-api-tests is not supported on this platform.\n" unless isSupportedPlatform();
- prepareEnvironmentForRunningTestTool();
- local *DEVNULL;
- my ($childIn, $childOut, $childErr);
- if ($verbose) {
- $childOut = ">&STDERR";
- $childErr = ">&STDERR";
- } else {
- open(DEVNULL, ">", File::Spec->devnull()) or die "Failed to open /dev/null";
- $childOut = ">&DEVNULL";
- $childErr = ">&DEVNULL";
- }
- my $pid;
- if (isAppleMacWebKit() && architecture()) {
- $pid = open3($childIn, $childOut, $childErr, "arch", "-" . architecture(), testToolPath(), $gtestArg, @ARGV) or die "Failed to run test: $test.";
- } else {
- $pid = open3($childIn, $childOut, $childErr, testToolPath(), $gtestArg, @ARGV) or die "Failed to run test: $test.";
- }
- close($childIn);
- close($childOut);
- close($childErr);
- close(DEVNULL) unless ($verbose);
- eval {
- local $SIG{ALRM} = sub { die "alarm\n" };
- alarm $timeout;
- waitpid($pid, 0);
- alarm 0;
- $result = $?;
- };
- if ($@) {
- die unless $@ eq "alarm\n";
- kill SIGTERM, $pid or kill SIGKILL, $pid;
- $timedOut = 1;
- }
- if ($result) {
- push @testsFailed, $test;
- }
- if ($timedOut) {
- push @testsTimedOut, $test;
- print possiblyColored("bold yellow", "Timeout"), "\n";
- } elsif (!$verbose) {
- if ($result) {
- print possiblyColored("bold red", "Failed"), "\n";
- } else {
- print possiblyColored("bold green", "Passed"), "\n";
- }
- }
- return $timedOut || $result;
- }
- sub listAllTests()
- {
- my @toolOutput;
- my $timedOut;
- die "run-api-tests is not supported on this platform.\n" unless isSupportedPlatform();
- prepareEnvironmentForRunningTestTool();
- local *DEVNULL;
- my ($childIn, $childOut, $childErr);
- if ($verbose) {
- $childErr = ">&STDERR";
- } else {
- open(DEVNULL, ">", File::Spec->devnull()) or die "Failed to open /dev/null";
- $childErr = ">&DEVNULL";
- }
- my $pid;
- if (isAppleMacWebKit() && architecture()) {
- $pid = open3($childIn, $childOut, $childErr, "arch", "-" . architecture(), testToolPath(), "--gtest_list_tests") or die "Failed to build list of tests!";
- } else {
- $pid = open3($childIn, $childOut, $childErr, testToolPath(), "--gtest_list_tests") or die "Failed to build list of tests!";
- }
- close($childIn);
- @toolOutput = <$childOut>;
- close($childOut);
- close($childErr);
- close(DEVNULL) unless ($verbose);
- waitpid($pid, 0);
- my $result = $?;
- if ($result) {
- print STDERR "Failed to build list of tests!\n";
- exit exitStatus($result);
- }
- my @tests = ();
- my $suite;
- for my $line (@toolOutput) {
- $line =~ s/[\r\n]*$//;
- if ($line =~ m/\.$/) {
- $suite = $line; # "SuiteName."
- } else {
- # Disabling WebKit2 API test on Windows since we will be disabling WebKit2 on Windows.
- next if (isAppleWinWebKit() && $suite =~ m/WebKit2*/);
- $line =~ s/^\s*//; # "TestName"
- push @tests, $suite . $line; # "SuiteName.TestName"
- }
- }
- return @tests;
- }
- sub buildTestTool()
- {
- my $originalCwd = getcwd();
- chdirWebKit();
- my $buildTestTool = "build-api-tests";
- print STDERR "Running $buildTestTool\n";
- local *DEVNULL;
- my ($childIn, $childOut, $childErr);
- if ($verbose) {
- # When not quiet, let the child use our stdout/stderr.
- $childOut = ">&STDOUT";
- $childErr = ">&STDERR";
- } else {
- open(DEVNULL, ">", File::Spec->devnull()) or die "Failed to open /dev/null";
- $childOut = ">&DEVNULL";
- $childErr = ">&DEVNULL";
- }
- my @args = argumentsForConfiguration();
- my $pathToBuildTestTool = File::Spec->catfile("Tools", "Scripts", $buildTestTool);
- my $buildProcess = open3($childIn, $childOut, $childErr, "perl", $pathToBuildTestTool, @args) or die "Failed to run " . $buildTestTool;
- close($childIn);
- close($childOut);
- close($childErr);
- close(DEVNULL) unless ($verbose);
- waitpid($buildProcess, 0);
- my $buildResult = $?;
- if ($buildResult) {
- print STDERR "Compiling TestWebKitAPI failed!\n";
- exit exitStatus($buildResult);
- }
- chdir $originalCwd;
- }
- sub prepareEnvironmentForRunningTestTool()
- {
- return unless isAppleMacWebKit();
- $ENV{DYLD_FRAMEWORK_PATH} = productDir();
- $ENV{WEBKIT_UNSET_DYLD_FRAMEWORK_PATH} = "YES";
- }
- sub testToolPath()
- {
- my $path = File::Spec->catfile(productDir(), "TestWebKitAPI");
- return $path unless isAppleWinWebKit();
- my $suffix;
- if (configurationForVisualStudio() eq "Debug_All") {
- $suffix = "_debug";
- } else {
- $suffix = "";
- }
- return "$path$suffix.exe";
- }
|