summaryrefslogtreecommitdiffstats
path: root/WebKitTools/BuildSlaveSupport
diff options
context:
space:
mode:
authorCary Clark <>2009-04-14 06:33:00 -0700
committerThe Android Open Source Project <initial-contribution@android.com>2009-04-14 06:33:00 -0700
commit563af33bc48281d19dce701398dbb88cb54fd7ec (patch)
tree395b4502f029dea8b25b342d66dc06b5d8f99985 /WebKitTools/BuildSlaveSupport
parent5cfedfef172691d0f4bcf2be5ca3cddd8c9a47f4 (diff)
downloadexternal_webkit-563af33bc48281d19dce701398dbb88cb54fd7ec.zip
external_webkit-563af33bc48281d19dce701398dbb88cb54fd7ec.tar.gz
external_webkit-563af33bc48281d19dce701398dbb88cb54fd7ec.tar.bz2
AI 146110: add missing files to webkit
brings it in sync with webkit svn cl 42046 Automated import of CL 146110
Diffstat (limited to 'WebKitTools/BuildSlaveSupport')
-rwxr-xr-xWebKitTools/BuildSlaveSupport/build-launcher-app120
-rwxr-xr-xWebKitTools/BuildSlaveSupport/build-launcher-dmg118
-rw-r--r--WebKitTools/BuildSlaveSupport/build.webkit.org-config/Makefile19
-rw-r--r--WebKitTools/BuildSlaveSupport/build.webkit.org-config/buildbot.css116
-rw-r--r--WebKitTools/BuildSlaveSupport/build.webkit.org-config/buildbot.tac10
-rw-r--r--WebKitTools/BuildSlaveSupport/build.webkit.org-config/master.cfg22
-rw-r--r--WebKitTools/BuildSlaveSupport/build.webkit.org-config/webkit/__init__.py5
-rw-r--r--WebKitTools/BuildSlaveSupport/build.webkit.org-config/webkit/auth.py9
-rw-r--r--WebKitTools/BuildSlaveSupport/build.webkit.org-config/webkit/basesteps.py51
-rw-r--r--WebKitTools/BuildSlaveSupport/build.webkit.org-config/webkit/builders.py51
-rw-r--r--WebKitTools/BuildSlaveSupport/build.webkit.org-config/webkit/factories.py109
-rw-r--r--WebKitTools/BuildSlaveSupport/build.webkit.org-config/webkit/schedulers.py16
-rw-r--r--WebKitTools/BuildSlaveSupport/build.webkit.org-config/webkit/status.py19
-rw-r--r--WebKitTools/BuildSlaveSupport/build.webkit.org-config/webkit/steps.py262
-rwxr-xr-xWebKitTools/BuildSlaveSupport/run-performance-tests80
15 files changed, 1007 insertions, 0 deletions
diff --git a/WebKitTools/BuildSlaveSupport/build-launcher-app b/WebKitTools/BuildSlaveSupport/build-launcher-app
new file mode 100755
index 0000000..117b008
--- /dev/null
+++ b/WebKitTools/BuildSlaveSupport/build-launcher-app
@@ -0,0 +1,120 @@
+#!/usr/bin/perl -w
+
+# Copyright (C) 2006 Apple Computer, Inc. All rights reserved.
+# Copyright (C) 2006 Mark Rowe <opendarwin.org@bdash.net.nz>. 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.
+# 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+# its contributors may be used to endorse or promote products derived
+# from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY APPLE 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 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.
+
+# Creates the launcher WebKit.app with bundled frameworks.
+
+use strict;
+
+use FindBin;
+use lib "$FindBin::Bin/../Scripts";
+use webkitdirs;
+
+my @xcodeBuildArguments = XcodeOptions();
+my $nightlyLauncherTemplatePath = "$FindBin::Bin/../WebKitLauncher";
+my $nightlyLauncherStagingPath = productDir() . "/WebKit.app";
+
+sub buildNightlyLauncher
+{
+ chdir($nightlyLauncherTemplatePath);
+ system("xcodebuild", "clean", "-alltargets", @xcodeBuildArguments, @ARGV) == 0 or die "Failed cleaning WebKitLauncher project";
+ system("xcodebuild", @xcodeBuildArguments, @ARGV) == 0 or die "Failed building WebKitLauncher project";
+ chdirWebKit();
+}
+
+sub currentRevision
+{
+ my $sourceDir = sourceDir();
+ if (isSVNDirectory($sourceDir)) {
+ return currentSVNRevision();
+ } elsif (isGitDirectory($sourceDir)) {
+ my $gitLog = `cd $sourceDir && LC_ALL=C git log --grep='git-svn-id: ' -n 1 | grep git-svn-id:`;
+ (my $revision) = ($gitLog =~ m/ +git-svn-id: .+@(\d+) /g);
+ return $revision;
+ }
+}
+
+sub currentBranch
+{
+ my $sourceDir = sourceDir();
+ my ($url, $branch);
+ if (isSVNDirectory($sourceDir)) {
+ my $svnInfo = `LC_ALL=C svn info $sourceDir | grep URL:`;
+ ($url) = ($svnInfo =~ m/URL: (.+)/g);
+ } elsif (isGitDirectory($sourceDir)) {
+ my $gitLog = `cd $sourceDir && LC_ALL=C git log --grep='git-svn-id: ' -n 1 | grep git-svn-id:`;
+ ($url) = ($gitLog =~ m/ +git-svn-id: (.+)@\d+ /g);
+ }
+ ($branch) = ($url =~ m/\/webkit\/(trunk|branches\/[^\/]+)/);
+ die "Unable to determine current SVN branch in $sourceDir" unless (defined $branch);
+ $branch =~ s/^branches\///;
+ return $branch;
+}
+
+sub copyNightlyLauncher
+{
+ my $revision = currentRevision();
+ my $branch = currentBranch();
+
+ my $infoPlist = "$nightlyLauncherStagingPath/Contents/Info.plist";
+ my $versionFile = "$nightlyLauncherStagingPath/Contents/Resources/VERSION";
+ my $branchFile = "$nightlyLauncherStagingPath/Contents/Resources/BRANCH";
+ my $data;
+ open(IN, $infoPlist) or die "Couldn't open Info.plist in built application for reading";
+ {
+ undef $/;
+ $data = <IN>;
+ }
+ close(IN);
+ open(OUT, ">$infoPlist") or die "Couldn't open Info.plist in built application for writing";
+ $data =~ s/VERSION/$revision/g;
+ print OUT $data;
+ close(OUT);
+
+ open(OUT, ">$versionFile") or die "Couldn't open VERSION in built application for writing";
+ print OUT "$revision\n";
+ close(OUT);
+
+ open(OUT, ">$branchFile") or die "Couldn't open BRANCH in built application for writing";
+ print OUT "$branch\n";
+ close(OUT);
+
+ my @frameworks = ("JavaScriptCore", "JavaScriptGlue", "WebCore", "WebKit");
+ for my $framework (@frameworks) {
+ system("ditto", productDir() . "/$framework.framework", "$nightlyLauncherStagingPath/Contents/Resources/$framework.framework") == 0 or die "Failed copying $framework.framework into $nightlyLauncherStagingPath";
+ }
+}
+
+my $b = currentBranch();
+my $r = currentRevision();
+print "Branch: ", $b, "\n";
+print "Revision: ", $r, "\n";
+
+chdirWebKit();
+buildNightlyLauncher();
+copyNightlyLauncher();
diff --git a/WebKitTools/BuildSlaveSupport/build-launcher-dmg b/WebKitTools/BuildSlaveSupport/build-launcher-dmg
new file mode 100755
index 0000000..4dce7fb
--- /dev/null
+++ b/WebKitTools/BuildSlaveSupport/build-launcher-dmg
@@ -0,0 +1,118 @@
+#!/usr/bin/perl -w
+
+# Copyright (C) 2006 Apple Computer, Inc. All rights reserved.
+# Copyright (C) 2006 Mark Rowe <opendarwin.org@bdash.net.nz>. 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.
+# 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+# its contributors may be used to endorse or promote products derived
+# from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY APPLE 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 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.
+
+# Script used by build slaves to create a disk-image containing WebKit.app.
+
+use strict;
+
+use File::Basename;
+use Getopt::Long;
+use FindBin;
+use lib "$FindBin::Bin/../Scripts";
+use webkitdirs;
+
+my $nightlyLauncherStagingPath = productDir() . "/WebKit.app";
+my $droseraStagingPath = productDir() . "/DroseraLauncher.app";
+my $nightlyLauncherDiskImagePath;
+
+my $nightlyRemoteHost = 'webkit-nightlies@live.nightly.webkit.org';
+my $nightlyRemotePath = "/home/webkit-nightlies";
+my $nightlyRemoteLatestPath = "$nightlyRemotePath/update-latest.sh";
+
+sub buildDiskImage
+{
+ my $revision = currentSVNRevision();
+ my $productDir = productDir();
+ $nightlyLauncherDiskImagePath = productDir() . "/WebKit-SVN-r$revision.dmg";
+
+ print "Removing previous temp source directory (if any)...\n";
+ `rm -rf /tmp/WebKitNightly`;
+ die "Removing previous temp source directory failed" if $?;
+
+ print "Making a new temp source directory...\n";
+ `mkdir /tmp/WebKitNightly`;
+ die "Making a new temp source directory failed" if $?;
+
+ print "Copying WebKit.app to temp source directory...\n";
+ `cp -R \"$nightlyLauncherStagingPath\" /tmp/WebKitNightly/WebKit.app`;
+ die "Copying WebKit.app to temp source directory failed" if $?;
+
+ print "Copying Drosera.app to temp source directory...\n";
+ `cp -R \"$droseraStagingPath\" /tmp/WebKitNightly/Drosera.app`;
+ die "Copying Drosera.app to temp source directory failed" if $?;
+
+ print "Creating disk image...\n";
+ `hdiutil create \"$nightlyLauncherDiskImagePath\" -ov -srcfolder /tmp/WebKitNightly -fs HFS+ -volname \"WebKit\"`;
+ die "Creating disk image failed" if $?;
+
+ print "Removing temp source directory...\n";
+ `rm -rf /tmp/WebKitNightly`;
+ die "Removing temp source directory failed" if $?;
+
+ print "Compressing disk image...\n";
+ system("mv", "-f", $nightlyLauncherDiskImagePath, "$nightlyLauncherDiskImagePath.uncompressed.dmg") == 0 or die "Renaming disk image failed";
+ system("hdiutil", "convert", "-quiet", "$nightlyLauncherDiskImagePath.uncompressed.dmg", "-format", "UDBZ", "-imagekey", "zlib-level=9", "-o", "$nightlyLauncherDiskImagePath");
+ die "Compressing disk image failed" if $?;
+
+ unlink "$nightlyLauncherDiskImagePath.uncompressed.dmg";
+}
+
+sub uploadNightlyDiskImage
+{
+ my $buildTag = shift(@_);
+ my $nightlyRemoteDiskImagePath = "$nightlyRemotePath/builds/$buildTag/mac/" . basename($nightlyLauncherDiskImagePath);
+ my $revision = currentSVNRevision();
+ system("rsync", "-vP", $nightlyLauncherDiskImagePath, "$nightlyRemoteHost:$nightlyRemoteDiskImagePath") == 0 or die "Failed uploading disk image";
+ system("ssh", $nightlyRemoteHost, $nightlyRemoteLatestPath, $buildTag, "mac", $nightlyRemoteDiskImagePath, $revision) == 0 or die "Failed linking disk image to latest";
+}
+
+sub uploadBuildSlaveDiskImage
+{
+ my $remoteDiskImagePath = shift(@_) . basename($nightlyLauncherDiskImagePath);
+ system("rsync", "-vP", $nightlyLauncherDiskImagePath, $remoteDiskImagePath) == 0 or die "Failed uploading disk image";
+}
+
+
+my $uploadTo;
+my $nightlyBuild = 0;
+my $buildTag = 'trunk';
+GetOptions('upload-to-host=s' => \$uploadTo,
+ 'upload-as-nightly!' => \$nightlyBuild,
+ 'tag=s' => \$buildTag);
+
+chdirWebKit();
+buildDiskImage($buildTag);
+
+if ($nightlyBuild) {
+ uploadNightlyDiskImage($buildTag);
+} elsif ($uploadTo) {
+ uploadBuildSlaveDiskImage($uploadTo);
+} else {
+ print "Disk image left at $nightlyLauncherDiskImagePath\n";
+}
diff --git a/WebKitTools/BuildSlaveSupport/build.webkit.org-config/Makefile b/WebKitTools/BuildSlaveSupport/build.webkit.org-config/Makefile
new file mode 100644
index 0000000..c3a935f
--- /dev/null
+++ b/WebKitTools/BuildSlaveSupport/build.webkit.org-config/Makefile
@@ -0,0 +1,19 @@
+# -*- makefile -*-
+
+# This is a simple makefile which lives in a buildmaster/buildslave
+# directory (next to the buildbot.tac file). It allows you to start/stop the
+# master or slave by doing 'make start' or 'make stop'.
+
+# The 'reconfig' target will tell a buildmaster to reload its config file.
+
+start:
+ twistd --no_save -y buildbot.tac
+
+stop:
+ kill `cat twistd.pid`
+
+reconfig:
+ kill -HUP `cat twistd.pid`
+
+log:
+ tail -f twistd.log
diff --git a/WebKitTools/BuildSlaveSupport/build.webkit.org-config/buildbot.css b/WebKitTools/BuildSlaveSupport/build.webkit.org-config/buildbot.css
new file mode 100644
index 0000000..534de25
--- /dev/null
+++ b/WebKitTools/BuildSlaveSupport/build.webkit.org-config/buildbot.css
@@ -0,0 +1,116 @@
+* {
+ font-family: Verdana, Cursor;
+ font-size: 10px;
+ font-weight: bold;
+}
+
+a:link,a:visited,a:active {
+ color: #444;
+}
+a:hover {
+ color: #FFFFFF;
+}
+
+table {
+ border-spacing: 1px 1px;
+}
+
+table td {
+ padding: 3px 0px 3px 0px;
+ text-align: center;
+}
+
+.Project {
+ width: 100px;
+}
+
+.LastBuild, .Activity {
+ width: 230px;
+ padding: 0 0 0 4px;
+}
+
+td.Time {
+ color: #000;
+ border-bottom: 1px solid #aaa;
+ background-color: #eee;
+}
+
+td.Activity, td.Change, td.Builder {
+ color: #333333;
+ background-color: #CCCCCC;
+}
+
+td.Change {
+ border-radius: 5px;
+ -webkit-border-radius: 5px;
+ -moz-border-radius: 5px;
+}
+td.Event {
+ color: #777;
+ background-color: #ddd;
+ border-radius: 5px;
+ -webkit-border-radius: 5px;
+ -moz-border-radius: 5px;
+}
+
+td.Activity {
+ border-top-left-radius: 10px;
+ -webkit-border-top-left-radius: 10px;
+ -moz-border-radius-topleft: 10px;
+ min-height: 20px;
+ padding: 8px 0 8px 0;
+}
+
+td.idle, td.waiting, td.offline, td.building {
+ border-top-left-radius: 0px;
+ -webkit-border-top-left-radius: 0px;
+ -moz-border-radius-topleft: 0px;
+}
+
+.LastBuild {
+ border-top-left-radius: 5px;
+ -webkit-border-top-left-radius: 5px;
+ -moz-border-radius-topleft: 5px;
+ border-top-right-radius: 5px;
+ -webkit-border-top-right-radius: 5px;
+ -moz-border-radius-topright: 5px;
+}
+
+/* LastBuild, BuildStep states */
+.success {
+ color: #FFFFFF;
+ background-color: #8fdf5f;
+}
+
+.failure {
+ color: #FFFFFF;
+ background-color: #e98080;
+}
+
+.warnings {
+ color: #FFFFFF;
+ background-color: #ffc343;
+}
+
+.exception, td.offline {
+ color: #FFFFFF;
+ background-color: #e0b0ff;
+}
+
+.start,.running, td.building {
+ color: #666666;
+ background-color: #fffc6c;
+}
+
+.start {
+ border-bottom-left-radius: 10px;
+ -webkit-border-bottom-left-radius: 10px;
+ -moz-border-radius-bottomleft: 10px;
+ border-bottom-right-radius: 10px;
+ -webkit-border-bottom-right-radius: 10px;
+ -moz-border-radius-bottomright: 10px;
+}
+
+td.Project a:hover, td.start a:hover {
+ color: #000;
+}
diff --git a/WebKitTools/BuildSlaveSupport/build.webkit.org-config/buildbot.tac b/WebKitTools/BuildSlaveSupport/build.webkit.org-config/buildbot.tac
new file mode 100644
index 0000000..f66e068
--- /dev/null
+++ b/WebKitTools/BuildSlaveSupport/build.webkit.org-config/buildbot.tac
@@ -0,0 +1,10 @@
+
+from twisted.application import service
+from buildbot.master import BuildMaster
+
+basedir = r'/home/mrowe/sites/build.webkit.org/buildbot'
+configfile = r'master.cfg'
+
+application = service.Application('buildmaster')
+BuildMaster(basedir, configfile).setServiceParent(application)
+
diff --git a/WebKitTools/BuildSlaveSupport/build.webkit.org-config/master.cfg b/WebKitTools/BuildSlaveSupport/build.webkit.org-config/master.cfg
new file mode 100644
index 0000000..677e82a
--- /dev/null
+++ b/WebKitTools/BuildSlaveSupport/build.webkit.org-config/master.cfg
@@ -0,0 +1,22 @@
+# -*- python -*-
+
+import os
+from twisted.web import static
+static.File.contentTypes = static.loadMimeTypes(['/etc/mime.types', os.path.join(basedir, 'mime.types')])
+
+from buildbot.changes.pb import PBChangeSource
+import webkit
+reload(webkit)
+
+c = BuildmasterConfig = {}
+
+c['slaves'] = webkit.auth.getSlaveAuthenticationDetails()
+c['change_source'] = [PBChangeSource()]
+c['builders'] = webkit.builders.getBuilders()
+c['schedulers'] = webkit.schedulers.getSchedulers(c['builders'])
+c['status'] = webkit.status.getStatusListeners()
+
+c['slavePortnum'] = 9989
+c['projectName'] = "WebKit"
+c['projectURL'] = "http://webkit.org/"
+c['buildbotURL'] = "http://build.webkit.org/"
diff --git a/WebKitTools/BuildSlaveSupport/build.webkit.org-config/webkit/__init__.py b/WebKitTools/BuildSlaveSupport/build.webkit.org-config/webkit/__init__.py
new file mode 100644
index 0000000..f81fcae
--- /dev/null
+++ b/WebKitTools/BuildSlaveSupport/build.webkit.org-config/webkit/__init__.py
@@ -0,0 +1,5 @@
+from webkit import auth, status, builders, schedulers
+reload(auth)
+reload(status)
+reload(builders)
+reload(schedulers)
diff --git a/WebKitTools/BuildSlaveSupport/build.webkit.org-config/webkit/auth.py b/WebKitTools/BuildSlaveSupport/build.webkit.org-config/webkit/auth.py
new file mode 100644
index 0000000..b182e16
--- /dev/null
+++ b/WebKitTools/BuildSlaveSupport/build.webkit.org-config/webkit/auth.py
@@ -0,0 +1,9 @@
+from buildbot.buildslave import BuildSlave
+
+def getSlaveAuthenticationDetails():
+ def createBuildSlave((name, password)):
+ return BuildSlave(name, password, max_builds=1)
+ return map(createBuildSlave, _getSlaveAuthenticationDetails())
+
+def _getSlaveAuthenticationDetails():
+ return [("slave-name", "password")]
diff --git a/WebKitTools/BuildSlaveSupport/build.webkit.org-config/webkit/basesteps.py b/WebKitTools/BuildSlaveSupport/build.webkit.org-config/webkit/basesteps.py
new file mode 100644
index 0000000..8bba881
--- /dev/null
+++ b/WebKitTools/BuildSlaveSupport/build.webkit.org-config/webkit/basesteps.py
@@ -0,0 +1,51 @@
+from buildbot.steps import shell, source
+import os
+
+
+def buildStepWithDefaultTimeout(klass, default_timeout=75*60):
+ class Step(klass):
+ timeout = default_timeout
+ def __init__(self, *args, **kwargs):
+ kwargs['timeout'] = self.timeout
+ klass.__init__(self, *args, **kwargs)
+
+ return Step
+
+
+Test = buildStepWithDefaultTimeout(shell.Test)
+Compile = buildStepWithDefaultTimeout(shell.Compile)
+ShellCommand = buildStepWithDefaultTimeout(shell.ShellCommand)
+SVN = buildStepWithDefaultTimeout(source.SVN)
+
+
+class UploadCommand:
+ def initializeForUpload(self):
+ try:
+ try:
+ umask = os.umask(0)
+ os.makedirs(self.getDestinationPath(), 042770)
+ except OSError, e:
+ if e.errno != 17:
+ raise
+ finally:
+ os.umask(umask)
+
+ def getDestinationPath(self):
+ return "/home/buildresults%s" % (self.getURLPath(), )
+
+ def getRemotePath(self):
+ return "buildresults@build.webkit.org:%s" % (self.getDestinationPath(), )
+
+ def getURLPath(self):
+ return '/results/%s/%s/' % (self.getBuild().builder.name, self.getBuild().getProperty("buildnumber"), )
+
+ def getBuild(self):
+ return self.build
+
+
+ def getText(self, cmd, results):
+ return self.getText2(cmd, results)
+
+ def getText2(self, cmd, results):
+ return ['<a href="%s">%s</a>' % (self.getURLPath(), self.name)]
+
diff --git a/WebKitTools/BuildSlaveSupport/build.webkit.org-config/webkit/builders.py b/WebKitTools/BuildSlaveSupport/build.webkit.org-config/webkit/builders.py
new file mode 100644
index 0000000..a79011c
--- /dev/null
+++ b/WebKitTools/BuildSlaveSupport/build.webkit.org-config/webkit/builders.py
@@ -0,0 +1,51 @@
+from webkit.factories import *
+
+allWinBuilders = ['apple-slave-7', 'apple-slave-2'] # pewtermoose-slave-1
+allMacPPCBuilders = ['apple-slave-1', 'apple-slave-3', 'apple-slave-6']
+allMacIntelBuilders = ['bdash-slave-1', 'bdash-slave-2']
+macIntelPixelBuilders = ['apple-slave-8']
+allQtLinuxBuilders = ['webtroll-slave-1']
+allQtWinBuilders = ['qt-slave-2']
+allGtkLinuxBuilders = ['zecke-slave-1']
+allWxMacBuilders = ['kollivier-slave-1']
+
+# apple-slave-4 is currently giving incomprehensible ICEs when compiling:
+# WebKit/History/WebBackForwardList.mm: In function 'WebHistoryItem* -[WebBackForwardList currentItem](WebBackForwardList*, objc_selector*)':
+# WebKit/History/WebBackForwardList.mm:178: internal compiler error: Bus error
+
+# apple-slave-5 is currently giving incomprehensible link errors:
+# WebKitBuild/JavaScriptCore.build/Release/JavaScriptCore.build/Objects-normal/ppc/pcre_tables.o r_address (0x34a10d) field of relocation entry 12 in section (__DWARFA,__debug_info) out of range
+# /usr/bin/libtool: internal link edit command failed
+
+
+_builders = [('trunk-mac-ppc-release', StandardBuildFactory, allMacPPCBuilders, False),
+ ('trunk-mac-intel-release', StandardBuildFactory, allMacIntelBuilders, False),
+# ('trunk-mac-ppc-debug', LeakBuildFactory, allMacPPCBuilders, False),
+ ('trunk-mac-intel-debug', LeakBuildFactory, allMacIntelBuilders, False),
+ ('trunk-mac-intel-pixel', PixelTestBuildFactory, macIntelPixelBuilders, False),
+# ('trunk-win-release', Win32BuildFactory, allWinBuilders, False),
+ ('trunk-win-debug', Win32BuildFactory, allWinBuilders, False),
+ ('trunk-qt-linux-release', QtBuildFactory, allQtLinuxBuilders, False),
+ ('trunk-qt-win-release', QtBuildFactory, allQtWinBuilders, False),
+ ('trunk-gtk-linux-release', GtkBuildFactory, allGtkLinuxBuilders, False),
+ ('trunk-wx-mac-debug', WxBuildFactory, allWxMacBuilders, False),
+
+# ('trunk-mac-intel-coverage', CoverageDataBuildFactory, ['bdash-slave-1'], True),
+# ('trunk-mac-intel-nosvg', NoSVGBuildFactory, ['bdash-slave-2'], True),
+
+# ('stable-mac-ppc-release', StandardBuildFactory, allMacPPCBuilders, False),
+# ('stable-mac-intel-release', StandardBuildFactory, allMacIntelBuilders, False),
+# ('stable-mac-ppc-debug', LeakBuildFactory, allMacPPCBuilders, False),
+# ('stable-mac-intel-debug', LeakBuildFactory, allMacIntelBuilders, False),
+# ('stable-win-release', Win32BuildFactory, allWinBuilders, False),
+ ]
+
+def getBuilders():
+ result = []
+ for name, factory, slaves, periodic in _builders:
+ result.append({'name': name,
+ 'slavenames': slaves,
+ 'builddir': name,
+ 'factory': factory(),
+ 'periodic': periodic})
+ return result
diff --git a/WebKitTools/BuildSlaveSupport/build.webkit.org-config/webkit/factories.py b/WebKitTools/BuildSlaveSupport/build.webkit.org-config/webkit/factories.py
new file mode 100644
index 0000000..59eb9cd
--- /dev/null
+++ b/WebKitTools/BuildSlaveSupport/build.webkit.org-config/webkit/factories.py
@@ -0,0 +1,109 @@
+from webkit.steps import *
+from buildbot.process import factory
+
+s = factory.s
+
+class BuildFactory(factory.BuildFactory):
+ useProgress = False
+ def __init__(self):
+ factory.BuildFactory.__init__(self, [s(CheckOutSource)])
+
+class StandardBuildFactory(BuildFactory):
+ def __init__(self):
+ BuildFactory.__init__(self)
+ self.steps.append(s(SetConfiguration, configuration="release"))
+ self.addCompileStep()
+ self.addJavaScriptCoreTestStep()
+ self.addLayoutTestStep()
+ self.steps.append(s(UploadLayoutResults))
+# self.steps.append(s(UploadDiskImage))
+
+ def addCompileStep(self):
+ self.steps.append(s(CompileWebKit, configuration="release"))
+
+ def addJavaScriptCoreTestStep(self):
+ self.steps.append(s(JavaScriptCoreTest))
+
+ def addLayoutTestStep(self):
+ self.steps.append(s(LayoutTest))
+
+
+class NoSVGBuildFactory(StandardBuildFactory):
+ def addCompileStep(self):
+ self.steps.append(s(CompileWebKitNoSVG, configuration="release"))
+
+
+class PixelTestBuildFactory(BuildFactory):
+ def __init__(self):
+ BuildFactory.__init__(self)
+ self.steps.append(s(SetConfiguration, configuration="release"))
+ self.steps.append(s(CompileWebKit, configuration="release"))
+ self.steps.append(s(PixelLayoutTest))
+ self.steps.append(s(UploadLayoutResults))
+
+
+class LeakBuildFactory(BuildFactory):
+ def __init__(self):
+ BuildFactory.__init__(self)
+ self.steps.append(s(SetConfiguration, configuration="debug"))
+ self.steps.append(s(CompileWebKit, configuration="debug"))
+ self.steps.append(s(JavaScriptCoreTest))
+ self.steps.append(s(LeakTest))
+ self.steps.append(s(UploadLayoutResults))
+# self.steps.append(s(UploadDiskImage))
+
+
+class PageLoadTestBuildFactory(BuildFactory):
+ def __init__(self):
+ BuildFactory.__init__(self)
+ self.steps.append(s(CompileWebKit, configuration="release"))
+ self.steps.append(s(PageLoadTest))
+
+
+class Win32BuildFactory(StandardBuildFactory):
+ def addCompileStep(self):
+ self.steps.append(s(InstallWin32Dependencies))
+ self.steps.append(s(SetConfiguration, configuration="debug"))
+ self.steps.append(s(CompileWebKitWindows, configuration="debug"))
+
+ def addLayoutTestStep(self):
+ self.steps.append(s(LayoutTestWindows))
+
+class GtkBuildFactory(StandardBuildFactory):
+ def addCompileStep(self):
+# self.steps.append(s(CleanWebKitGtk, configuration="release"))
+ self.steps.append(s(CompileWebKitGtk, configuration="release"))
+
+ def addJavaScriptCoreTestStep(self):
+ self.steps.append(s(JavaScriptCoreTestGtk))
+
+ def addLayoutTestStep(self):
+ pass
+
+
+class WxBuildFactory(StandardBuildFactory):
+ def addCompileStep(self):
+ self.steps.append(s(CleanWebKitWx, configuration="release"))
+ self.steps.append(s(CompileWebKitWx, configuration="release"))
+
+ def addJavaScriptCoreTestStep(self):
+ self.steps.append(s(JavaScriptCoreTestWx))
+
+ def addLayoutTestStep(self):
+ pass
+
+
+class QtBuildFactory(StandardBuildFactory):
+ def addCompileStep(self):
+ self.steps.append(s(CleanWebKit, configuration="release"))
+ self.steps.append(s(CompileWebKit, configuration="release"))
+
+ def addLayoutTestStep(self):
+ pass # self.steps.append(s(LayoutTestQt))
+
+
+class CoverageDataBuildFactory(BuildFactory):
+ def __init__(self):
+ BuildFactory.__init__(self)
+ self.steps.append(s(GenerateCoverageData))
+ self.steps.append(s(UploadCoverageData))
diff --git a/WebKitTools/BuildSlaveSupport/build.webkit.org-config/webkit/schedulers.py b/WebKitTools/BuildSlaveSupport/build.webkit.org-config/webkit/schedulers.py
new file mode 100644
index 0000000..4bece4f
--- /dev/null
+++ b/WebKitTools/BuildSlaveSupport/build.webkit.org-config/webkit/schedulers.py
@@ -0,0 +1,16 @@
+from buildbot.scheduler import AnyBranchScheduler, Periodic
+
+def getSchedulers(builders):
+ builders = map(lambda builder: (builder['name'], builder['periodic']), builders)
+ trunkBuilders = [name for name, periodic in builders if name.startswith('trunk-') and not periodic]
+ trunkBuilders.sort()
+ stableBuilders = [name for name, periodic in builders if name.startswith('stable-') and not periodic]
+ stableBuilders.sort()
+ periodicBuilders = [name for name, periodic in builders if periodic]
+ periodicBuilders.sort()
+
+ trunk = AnyBranchScheduler(name="trunk", branches=['trunk'], treeStableTimer=90, builderNames=trunkBuilders)
+# stable = AnyBranchScheduler(name="stable", branches=['branches/Safari-3-1-branch'], treeStableTimer=90, builderNames=stableBuilders)
+ periodic = Periodic("periodic", periodicBuilders, 6 * 60 * 60)
+
+ return [trunk, periodic]
diff --git a/WebKitTools/BuildSlaveSupport/build.webkit.org-config/webkit/status.py b/WebKitTools/BuildSlaveSupport/build.webkit.org-config/webkit/status.py
new file mode 100644
index 0000000..a7228ef
--- /dev/null
+++ b/WebKitTools/BuildSlaveSupport/build.webkit.org-config/webkit/status.py
@@ -0,0 +1,19 @@
+from buildbot.status import html, mail, words
+
+web = html.WebStatus(http_port=8010)
+
+allBuildsEmail = mail.MailNotifier(fromaddr="buildbot@webkit.org",
+ extraRecipients=["mark+webkit-builds@bdash.net.nz"],
+ sendToInterestedUsers=False)
+breakageEmail = mail.MailNotifier(fromaddr="buildbot@webkit.org",
+ lookup=mail.Domain("webkit.org"),
+ mode="failing")
+
+IRC = words.IRC(host="irc.freenode.net",
+ nick="webkit-build",
+ channels=["#webkit-build"],
+# announceAllBuilds=True
+ )
+
+def getStatusListeners():
+ return [web, allBuildsEmail, IRC]
diff --git a/WebKitTools/BuildSlaveSupport/build.webkit.org-config/webkit/steps.py b/WebKitTools/BuildSlaveSupport/build.webkit.org-config/webkit/steps.py
new file mode 100644
index 0000000..e518c2c
--- /dev/null
+++ b/WebKitTools/BuildSlaveSupport/build.webkit.org-config/webkit/steps.py
@@ -0,0 +1,262 @@
+from webkit.basesteps import ShellCommand, SVN, Test, Compile, UploadCommand
+from buildbot.status.builder import SUCCESS, FAILURE, WARNINGS
+
+class CheckOutSource(SVN):
+ baseURL = "http://svn.webkit.org/repository/webkit/"
+ mode = "update"
+ def __init__(self, *args, **kwargs):
+ SVN.__init__(self, baseURL=self.baseURL, defaultBranch="trunk", mode=self.mode, *args, **kwargs)
+
+class SetConfiguration(ShellCommand):
+ command = ["perl", "./WebKitTools/Scripts/set-webkit-configuration"]
+
+ def __init__(self, *args, **kwargs):
+ configuration = kwargs.pop('configuration')
+ self.command = self.command + ['--' + configuration]
+ self.name = "set-configuration-%s" % (configuration, )
+ self.description = ["set configuration %s" % (configuration, )]
+ self.descriptionDone = ["set configuration %s" % (configuration, )]
+ ShellCommand.__init__(self, *args, **kwargs)
+
+
+class LayoutTest(Test):
+ name = "layout-test"
+ description = ["layout-tests running"]
+ descriptionDone = ["layout-tests"]
+ command = ["perl", "./WebKitTools/Scripts/run-webkit-tests", "--no-launch-safari", "--no-new-test-results", "--no-sample-on-timeout", "--results-directory", "layout-test-results"]
+
+ def commandComplete(self, cmd):
+ Test.commandComplete(self, cmd)
+
+ logText = cmd.logs['stdio'].getText()
+ incorrectLayoutLines = [line for line in logText.splitlines() if line.find('had incorrect layout') >= 0 or (line.find('test case') >= 0 and (line.find(' crashed') >= 0 or line.find(' timed out') >= 0))]
+ self.incorrectLayoutLines = incorrectLayoutLines
+
+ def evaluateCommand(self, cmd):
+ if self.incorrectLayoutLines or cmd.rc != 0:
+ return FAILURE
+
+ return SUCCESS
+
+ def getText(self, cmd, results):
+ return self.getText2(cmd, results)
+
+ def getText2(self, cmd, results):
+ if results != SUCCESS and self.incorrectLayoutLines:
+ return self.incorrectLayoutLines
+
+ return [self.name]
+
+
+class JavaScriptCoreTest(Test):
+ name = "jscore-test"
+ description = ["jscore-tests running"]
+ descriptionDone = ["jscore-tests"]
+ command = ["perl", "./WebKitTools/Scripts/run-javascriptcore-tests"]
+ logfiles = {'results': 'JavaScriptCore/tests/mozilla/actual.html'}
+
+ def commandComplete(self, cmd):
+ Test.commandComplete(self, cmd)
+
+ logText = cmd.logs['stdio'].getText()
+ statusLines = [line for line in logText.splitlines() if line.find('regression') >= 0 and line.find(' found.') >= 0]
+ if statusLines and statusLines[0].split()[0] != '0':
+ self.regressionLine = statusLines[0]
+ else:
+ self.regressionLine = None
+
+ def evaluateCommand(self, cmd):
+ if self.regressionLine:
+ return FAILURE
+
+ if cmd.rc != 0:
+ return FAILURE
+
+ return SUCCESS
+
+ def getText(self, cmd, results):
+ return self.getText2(cmd, results)
+
+ def getText2(self, cmd, results):
+ if results != SUCCESS and self.regressionLine:
+ return [self.name, self.regressionLine]
+
+ return [self.name]
+
+class PixelLayoutTest(LayoutTest):
+ name = "pixel-layout-test"
+ description = ["pixel-layout-tests running"]
+ descriptionDone = ["pixel-layout-tests"]
+ command = LayoutTest.command + ["--pixel", "--tolerance", "0.1"]
+
+
+class LeakTest(LayoutTest):
+ command = ["perl", "./WebKitTools/Scripts/run-webkit-tests", "--no-launch-safari", "--no-sample-on-timeout", "--leaks", "--results-directory", "layout-test-results"]
+
+ def commandComplete(self, cmd):
+ LayoutTest.commandComplete(self, cmd)
+
+ logText = cmd.logs['stdio'].getText()
+ lines = logText.splitlines()
+ leakLines = [line for line in lines if line.find('total leaks found!') >= 0]
+ leakLines += [line for line in lines if line.find('LEAK: ') >= 0]
+ leakLines = [' '.join(x.split()[1:]) for x in leakLines]
+
+ leakSummary = {}
+ for line in leakLines:
+ count, key = line.split(' ', 1)
+ if key.find('total leaks found!') >= 0:
+ key = 'allocations found by "leaks" tool'
+
+ leakSummary[key] = leakSummary.get(key, 0) + int(count)
+
+ leakSummaryLines = []
+ for key in sorted(leakSummary.keys()):
+ leakSummaryLines.append('%s %s' % (leakSummary[key], key))
+
+ self.incorrectLayoutLines += leakSummaryLines
+
+
+class UploadLayoutResults(UploadCommand, ShellCommand):
+ name = "upload-results"
+ description = ["uploading results"]
+ descriptionDone = ["uploaded-results"]
+ command = "echo Disabled for now"
+
+ def __init__(self, *args, **kwargs):
+ ShellCommand.__init__(self, *args, **kwargs)
+
+ def setBuild(self, build):
+ ShellCommand.setBuild(self, build)
+ self.initializeForUpload()
+
+ self.command = '''
+ if [[ -d layout-test-results ]]; then \
+ find layout-test-results -type d -print0 | xargs -0 chmod ug+rx; \
+ find layout-test-results -type f -print0 | xargs -0 chmod ug+r; \
+ rsync -rlvzP --rsync-path=/home/buildresults/bin/rsync layout-test-results/ %s && rm -rf layout-test-results; \
+ fi; \
+ CRASH_LOG=~/Library/Logs/CrashReporter/DumpRenderTree*.crash*; \
+ if [[ -f $(ls -1 $CRASH_LOG | head -n 1 ) ]]; then \
+ chmod ug+r $CRASH_LOG; \
+ rsync -rlvzP --rsync-path=/home/buildresults/bin/rsync $CRASH_LOG %s && rm -rf $CRASH_LOG; \
+ fi; ''' % (self.getRemotePath(), self.getRemotePath())
+
+ self.addFactoryArguments(command=self.command)
+
+
+class CompileWebKit(Compile):
+ command = ["perl", "./WebKitTools/Scripts/build-webkit"]
+ env = {'WEBKITSUPPORTLIBRARIESZIPDIR': 'C:\\cygwin\\home\\buildbot', 'MFLAGS':''}
+ def __init__(self, *args, **kwargs):
+ configuration = kwargs.pop('configuration')
+
+ self.name = "compile-" + configuration
+ self.description = ["compiling " + configuration]
+ self.descriptionDone = ["compiled " + configuration]
+
+ Compile.__init__(self, env=self.env, *args, **kwargs)
+
+class CleanWebKit(CompileWebKit):
+ command = CompileWebKit.command + ['--clean']
+ description = ['cleaning']
+ descriptionDone = ['cleaned']
+
+class CompileWebKitNoSVG(CompileWebKit):
+ command = 'rm -rf WebKitBuild && perl ./WebKitTools/Scripts/build-webkit --no-svg'
+
+class CompileWebKitGtk(CompileWebKit):
+ command = ['perl', './WebKitTools/Scripts/build-webkit', '--gtk', '--qmake=qmake-qt4']
+
+class CleanWebKitGtk(CompileWebKitGtk):
+ command = CompileWebKitGtk.command + ['--clean']
+ description = ['cleaning']
+ descriptionDone = ['cleaned']
+
+class CompileWebKitWx(CompileWebKit):
+ command = ['perl', './WebKitTools/Scripts/build-webkit', '--wx']
+
+class CleanWebKitWx(CompileWebKitWx):
+ command = CompileWebKitWx.command + ['--clean']
+ description = ['cleaning']
+ descriptionDone = ['cleaned']
+
+class CompileWebKitWindows(UploadCommand, CompileWebKit):
+ def setBuild(self, build):
+ CompileWebKit.setBuild(self, build)
+ self.initializeForUpload()
+
+ self.command = '''\
+ ./WebKitTools/Scripts/build-webkit; \
+ RESULT=$?
+ for log in $(find WebKitBuild/*/*/*/*.htm); do \
+ chmod ug+r $log; \
+ REMOTE_NAME=$(echo $log | sed -e 's|WebKitBuild/obj/||' -e 's|/Release/|-|' -e 's|/Debug/|-|'); \
+ rsync -rlvzP --rsync-path="/home/buildresults/bin/rsync" $log %s/$REMOTE_NAME && rm $log; \
+ done; \
+ exit $RESULT;''' % (self.getRemotePath(), )
+
+ self.addFactoryArguments(command=self.command)
+
+class LayoutTestWindows(LayoutTest):
+ env = {'WEBKIT_TESTFONTS': 'C:\\cygwin\\home\\buildbot\\WebKitTestFonts'}
+
+ def __init__(self, *args, **kwargs):
+ return LayoutTest.__init__(self, env=self.env, *args, **kwargs)
+
+
+class JavaScriptCoreTestGtk(JavaScriptCoreTest):
+ command = JavaScriptCoreTest.command + ['--gtk']
+
+class JavaScriptCoreTestWx(JavaScriptCoreTest):
+ command = JavaScriptCoreTest.command + ['--wx']
+
+class LayoutTestQt(LayoutTest):
+ command = LayoutTest.command + ['--qt']
+
+class InstallWin32Dependencies(ShellCommand):
+ description = ["installing Windows dependencies"]
+ descriptionDone = ["installed Windows dependencies"]
+ command = ["perl", "./WebKitTools/Scripts/update-webkit-auxiliary-libs"]
+
+
+# class UploadDiskImage(UploadCommand, ShellCommand):
+# description = ["uploading disk image"]
+# descriptionDone = ["uploaded disk image"]
+# name = "upload-disk-image"
+
+# def __init__(self, *args, **kwargs):
+# UploadCommand.__init__(self, *args, **kwargs)
+# self.command = 'umask 002 && ./WebKitTools/BuildSlaveSupport/build-launcher-app && ./WebKitTools/BuildSlaveSupport/build-launcher-dmg --upload-to-host %s' % (self.getRemotePath(), )
+# ShellCommand.__init__(self, *args, **kwargs)
+
+class GenerateCoverageData(Compile):
+ command = ["perl", "./WebKitTools/Scripts/generate-coverage-data"]
+ description = ["generating coverage data"]
+ descriptionDone = ["generated coverage data"]
+
+
+class UploadCoverageData(UploadCommand, ShellCommand):
+ name = "upload-coverage-data"
+ description = ["uploading coverage data"]
+ descriptionDone = ["uploaded-coverage-data"]
+ command = "echo Disabled for now"
+
+ def __init__(self, *args, **kwargs):
+ ShellCommand.__init__(self, *args, **kwargs)
+
+ def setBuild(self, build):
+ ShellCommand.setBuild(self, build)
+ self.initializeForUpload()
+
+ self.command = '''\
+ if [[ -d WebKitBuild/Coverage/html ]]; then \
+ find WebKitBuild/Coverage/html -type d -print0 | xargs -0 chmod ug+rx; \
+ find WebKitBuild/Coverage/html -type f -print0 | xargs -0 chmod ug+r; \
+ rsync -rlvzP --rsync-path="/home/buildresults/bin/rsync" WebKitBuild/Coverage/html/ %s && rm -rf WebKitBuild/Coverage/html; \
+ fi;''' % (self.getRemotePath(), )
+
+ self.addFactoryArguments(command=self.command)
+
+ def getURLPath(self):
+ return "/results/code-coverage/"
diff --git a/WebKitTools/BuildSlaveSupport/run-performance-tests b/WebKitTools/BuildSlaveSupport/run-performance-tests
new file mode 100755
index 0000000..5d6ea44
--- /dev/null
+++ b/WebKitTools/BuildSlaveSupport/run-performance-tests
@@ -0,0 +1,80 @@
+#!/usr/bin/perl -w
+
+# Copyright (C) 2006 Apple Computer, 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.
+# 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+# its contributors may be used to endorse or promote products derived
+# from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY APPLE 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 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.
+
+# Script used by WebKit build slave to kick off performance tests.
+
+use strict;
+
+use FindBin;
+use lib "$FindBin::Bin/../Scripts";
+use webkitdirs;
+
+use Getopt::Long;
+use IO::Socket;
+my $shouldPrebuild = 1;
+
+my $perfMaster = "webkit-build-1.local";
+my $perfSlave = "webkit-build-2.local";
+my $slaveUser = "buildbot";
+my $reportPort = 54481; # Something that looks sorta like SAFARI
+my $slaveDirectory = "/ToTest";
+
+my $buildDirectory = determineConfigurationProductDir();
+
+my $userAndHost = $slaveUser . "@" . $perfSlave;
+my $resultsUploadDestination;
+
+GetOptions('upload-results=s' => \$resultsUploadDestination);
+
+print "Copying built frameworks to PLT slave...\n";
+my @frameworks = ("$buildDirectory/JavaScriptCore.framework", "$buildDirectory/WebCore.framework", "$buildDirectory/WebKit.framework");
+die "Failed to copy to slave\n" unless (system("rsync", "-avz", @frameworks, "$userAndHost:$slaveDirectory") == 0);
+
+print "Opening reponse port for PLT slave...\n";
+my $sock = new IO::Socket::INET(LocalHost => $perfMaster,
+ LocalPort => $reportPort,
+ Proto => 'tcp',
+ Listen => 1,
+ Reuse => 1);
+die "Could not create socket for port $reportPort: $!\n" unless $sock;
+
+print "Starting performance tests on PLT slave...\n";
+die "Failed to start slave!\n" unless (system("ssh", $userAndHost, "autovicki", $slaveDirectory, "--safari", "$slaveDirectory/Safari.app", "--count", 5, "--clean-exit", "--webkit-revision", currentSVNRevision(), "--show-results", "send-completed-results.command") == 0);
+
+print "Waiting for PLT slave to respond...\n";
+my $new_sock = $sock->accept();
+while(<$new_sock>) {
+ print $_;
+}
+close($sock);
+
+if ($resultsUploadDestination) {
+ print "Uploading results to $resultsUploadDestination\n";
+ die "Failed to upload xml results file." unless (system("scp", "$userAndHost:/Results/PerformanceReportSummary.xml", $resultsUploadDestination) == 0);
+ die "Failed to upload svg results file." unless (system("scp", "$userAndHost:/Results/PerformanceGraph.svg", $resultsUploadDestination) == 0);
+}