#!/usr/bin/perl -w # Copyright (C) 2007 Apple Inc. All rights reserved. # Copyright (C) 2007 Eric Seidel # # 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 COMPUTER, INC. ``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 COMPUTER, INC. OR # 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 Getopt::Long; use File::Basename; use Cwd; my $showHelp = 0; my $runShark = 0; my $jsShellPath; my $testsPattern; my $testRuns = 5; # This number may be different from what ./sunspider defaults to (that's OK) my $programName = basename($0); my $usage = < \$testRuns, 'shell=s' => \$jsShellPath, 'shark' => \$runShark, 'tests=s' => \$testsPattern, 'help' => \$showHelp); $testRuns = 1 if $runShark; if (!$jsShellPath || $showHelp) { print STDERR $usage; exit 1; } sub dumpToFile($$) { my ($contents, $path) = @_; open FILE, ">", $path or die; print FILE $contents; close FILE; } # FIXME: these globals are rather poor abstraction my @tests = (); my @categories = (); my %uniqueCategories = (); sub loadTestsList() { open TESTLIST, "<", "tests/LIST" or die; while () { chomp; next unless !$testsPattern || /$testsPattern/; push @tests, $_; my $category = $_; $category =~ s/-.*//; if (!$uniqueCategories{$category}) { push @categories, $category; $uniqueCategories{$category} = $category; } } close TESTLIST; } sub writePrefixFile() { my $prefix = "var tests = [ " . join(", ", map { '"' . $_ . '"' } @tests) . " ];\n"; $prefix .= "var categories = [ " . join(", ", map { '"' . $_ . '"' } @categories) . " ];\n"; mkdir "tmp"; dumpToFile($prefix, "tmp/sunspider-test-prefix.js"); } sub runTestsOnce($) { my ($useShark) = @_; my $shellArgs = "-f tmp/sunspider-test-prefix.js -f resources/sunspider-standalone-driver.js 2> /dev/null"; my $output; if ($useShark) { $output = `shark -i -1 -q "$jsShellPath" $shellArgs`; } else { $output = `"$jsShellPath" $shellArgs | grep -v break`; } return $output; } loadTestsList(); if ($testsPattern) { print STDERR "Found " . scalar(@tests) . " tests matching '" . $testsPattern . "'\n"; } else { print STDERR "Found " . scalar(@tests) . " tests\n"; } die "No tests to run" unless scalar(@tests); print STDERR "Running SunSpider once for warmup, then $testRuns time" . ($testRuns == 1 ? "" : "s") . ($runShark ? " under Shark" : "") . "\n"; writePrefixFile(); runTestsOnce(0); print "Discarded first run.\n"; my $result; my $count = 0; my @results = (); my $total = 0; print "["; while ($count++ < $testRuns) { $result = runTestsOnce($runShark); chomp $result; push @results, $result; print $result; print ",\n" unless ($count == $testRuns); } print "]\n"; my $output = "var output = [\n" . join(",\n", @results) . "\n];\n"; dumpToFile($output, "tmp/sunspider-results.js"); system("$jsShellPath", "-f", "tmp/sunspider-test-prefix.js", "-f", "tmp/sunspider-results.js", "-f", "resources/sunspider-analyze-results.js"); if ($runShark) { my $newestAge = 0; my $newestMShark = 0; opendir DIR, "." or die; for my $file (readdir DIR) { if ($file =~ /\.mshark$/) { my $age = -M $file; if ($age < $newestAge) { $newestMShark = $file; $newestAge = $age; } } } closedir DIR; exec "/usr/bin/open", $newestMShark if $newestMShark; }