Home | History | Annotate | Download | only in build.webkit.org-config
      1 # -*- python -*-
      2 # ex: set syntax=python:
      3 
      4 c = BuildmasterConfig = {}
      5 
      6 from buildbot.buildslave import BuildSlave
      7 from buildbot.changes.pb import PBChangeSource
      8 from buildbot.scheduler import AnyBranchScheduler, Triggerable
      9 from buildbot.schedulers.filter import ChangeFilter
     10 from buildbot.status import html
     11 from buildbot.status.web.authz import Authz
     12 from buildbot.process import buildstep, factory, properties
     13 from buildbot.steps import master, shell, source, transfer, trigger
     14 from buildbot.status.builder import SUCCESS, FAILURE, WARNINGS, SKIPPED
     15 
     16 from twisted.internet import defer
     17 
     18 import os
     19 import re
     20 import simplejson
     21 import urllib
     22 
     23 from webkitpy.common.config import build as wkbuild
     24 from webkitpy.common.net.buildbot import BuildBot as wkbuildbot
     25 
     26 WithProperties = properties.WithProperties
     27 
     28 class ConfigureBuild(buildstep.BuildStep):
     29     name = "configure build"
     30     description = ["configuring build"]
     31     descriptionDone = ["configured build"]
     32     def __init__(self, platform, configuration, architecture, buildOnly, *args, **kwargs):
     33         buildstep.BuildStep.__init__(self, *args, **kwargs)
     34         self.platform = platform.split('-', 1)[0]
     35         self.fullPlatform = platform
     36         self.configuration = configuration
     37         self.architecture = architecture
     38         self.buildOnly = buildOnly
     39         self.addFactoryArguments(platform=platform, configuration=configuration, architecture=architecture, buildOnly=buildOnly)
     40 
     41     def start(self):
     42         self.setProperty("platform", self.platform)
     43         self.setProperty("fullPlatform", self.fullPlatform)
     44         self.setProperty("configuration", self.configuration)
     45         self.setProperty("architecture", self.architecture)
     46         self.setProperty("buildOnly", self.buildOnly)
     47         self.finished(SUCCESS)
     48         return defer.succeed(None)
     49 
     50 
     51 class CheckOutSource(source.SVN):
     52     baseURL = "http://svn.webkit.org/repository/webkit/"
     53     mode = "update"
     54     def __init__(self, *args, **kwargs):
     55         source.SVN.__init__(self, baseURL=self.baseURL, defaultBranch="trunk", mode=self.mode, *args, **kwargs)
     56 
     57 
     58 class InstallWin32Dependencies(shell.Compile):
     59     description = ["installing dependencies"]
     60     descriptionDone = ["installed dependencies"]
     61     command = ["perl", "./Tools/Scripts/update-webkit-auxiliary-libs"]
     62 
     63 class KillOldProcesses(shell.Compile):
     64     name = "kill old processes"
     65     description = ["killing old processes"]
     66     descriptionDone = ["killed old processes"]
     67     command = ["python", "./Tools/BuildSlaveSupport/win/kill-old-processes"]
     68 
     69 class InstallChromiumDependencies(shell.ShellCommand):
     70     name = "gclient"
     71     description = ["updating chromium dependencies"]
     72     descriptionDone = ["updated chromium dependencies"]
     73     command = ["perl", "./Tools/Scripts/update-webkit-chromium", "--force"]
     74     haltOnFailure = True
     75 
     76 class CleanupChromiumCrashLogs(shell.ShellCommand):
     77     name = "cleanup crash logs"
     78     description = ["removing crash logs"]
     79     descriptionDone = ["removed crash logs"]
     80     command = ["python", "./Tools/BuildSlaveSupport/chromium/remove-crash-logs"]
     81     haltOnFailure = False
     82 
     83 
     84 def appendCustomBuildFlags(step, platform):
     85     if platform in ('chromium', 'efl', 'gtk', 'qt', 'wincairo', 'wince', 'wx'):
     86         step.setCommand(step.command + ['--' + platform])
     87 
     88 
     89 class CompileWebKit(shell.Compile):
     90     command = ["perl", "./Tools/Scripts/build-webkit", WithProperties("--%(configuration)s")]
     91     env = {'MFLAGS':''}
     92     name = "compile-webkit"
     93     description = ["compiling"]
     94     descriptionDone = ["compiled"]
     95     warningPattern = ".*arning: .*"
     96 
     97     def start(self):
     98         platform = self.getProperty('platform')
     99         buildOnly = self.getProperty('buildOnly')
    100         if platform == 'mac' and buildOnly:
    101             self.setCommand(self.command + ['DEBUG_INFORMATION_FORMAT=dwarf-with-dsym'])
    102 
    103         appendCustomBuildFlags(self, platform)
    104         return shell.Compile.start(self)
    105 
    106 
    107 class ArchiveBuiltProduct(shell.ShellCommand):
    108     command = ["python", "./Tools/BuildSlaveSupport/built-product-archive",
    109                WithProperties("--platform=%(platform)s"), WithProperties("--%(configuration)s"), "archive"]
    110     name = "archive-built-product"
    111     description = ["archiving built product"]
    112     descriptionDone = ["archived built product"]
    113     haltOnFailure = True
    114 
    115 
    116 class ExtractBuiltProduct(shell.ShellCommand):
    117     command = ["python", "./Tools/BuildSlaveSupport/built-product-archive",
    118                WithProperties("--platform=%(platform)s"), WithProperties("--%(configuration)s"), "extract"]
    119     name = "extract-built-product"
    120     description = ["extracting built product"]
    121     descriptionDone = ["extracted built product"]
    122     haltOnFailure = True
    123 
    124 
    125 class UploadBuiltProduct(transfer.FileUpload):
    126     slavesrc = WithProperties("WebKitBuild/%(configuration)s.zip")
    127     masterdest = WithProperties("archives/%(fullPlatform)s-%(architecture)s-%(configuration)s/%(got_revision)s.zip")
    128     haltOnFailure = True
    129 
    130     def __init__(self):
    131         transfer.FileUpload.__init__(self, self.slavesrc, self.masterdest, mode=0644)
    132 
    133 
    134 class DownloadBuiltProduct(transfer.FileDownload):
    135     slavedest = WithProperties("WebKitBuild/%(configuration)s.zip")
    136     mastersrc = WithProperties("archives/%(fullPlatform)s-%(architecture)s-%(configuration)s/%(got_revision)s.zip")
    137     haltOnFailure = True
    138     flunkOnFailure = True
    139 
    140     def __init__(self):
    141         transfer.FileDownload.__init__(self, self.mastersrc, self.slavedest)
    142 
    143 
    144 class RunJavaScriptCoreTests(shell.Test):
    145     name = "jscore-test"
    146     description = ["jscore-tests running"]
    147     descriptionDone = ["jscore-tests"]
    148     command = ["perl", "./Tools/Scripts/run-javascriptcore-tests", WithProperties("--%(configuration)s")]
    149     logfiles = {'actual.html (source)': 'Source/JavaScriptCore/tests/mozilla/actual.html'}
    150 
    151     def __init__(self, skipBuild=False, *args, **kwargs):
    152         self.skipBuild = skipBuild
    153         shell.Test.__init__(self, *args, **kwargs)
    154         self.addFactoryArguments(skipBuild=skipBuild)
    155 
    156     def start(self):
    157         appendCustomBuildFlags(self, self.getProperty('platform'))
    158         if self.skipBuild:
    159             self.setCommand(self.command + ['--skip-build'])
    160         return shell.Test.start(self)
    161 
    162     def commandComplete(self, cmd):
    163         shell.Test.commandComplete(self, cmd)
    164 
    165         logText = cmd.logs['stdio'].getText()
    166         statusLines = [line for line in logText.splitlines() if line.find('regression') >= 0 and line.find(' found.') >= 0]
    167         if statusLines and statusLines[0].split()[0] != '0':
    168             self.regressionLine = statusLines[0]
    169         else:
    170             self.regressionLine = None
    171 
    172         if 'actual.html (source)' in cmd.logs:
    173             self.addHTMLLog('actual.html', cmd.logs['actual.html (source)'].getText())
    174 
    175     def evaluateCommand(self, cmd):
    176         if self.regressionLine:
    177             return FAILURE
    178 
    179         if cmd.rc != 0:
    180             return FAILURE
    181 
    182         return SUCCESS
    183 
    184     def getText(self, cmd, results):
    185         return self.getText2(cmd, results)
    186 
    187     def getText2(self, cmd, results):
    188         if results != SUCCESS and self.regressionLine:
    189             return [self.name, self.regressionLine]
    190 
    191         return [self.name]
    192 
    193 
    194 class RunWebKitTests(shell.Test):
    195     name = "layout-test"
    196     description = ["layout-tests running"]
    197     descriptionDone = ["layout-tests"]
    198     command = ["perl", "./Tools/Scripts/run-webkit-tests", "--no-launch-safari", "--no-new-test-results",
    199                "--no-sample-on-timeout", "--results-directory", "layout-test-results", "--use-remote-links-to-tests",
    200                WithProperties("--%(configuration)s"), "--exit-after-n-crashes-or-timeouts", "20",  "--exit-after-n-failures", "500"]
    201 
    202     def __init__(self, skipBuild=False, *args, **kwargs):
    203         self.skipBuild = skipBuild
    204         shell.Test.__init__(self, *args, **kwargs)
    205         self.addFactoryArguments(skipBuild=skipBuild)
    206 
    207     def start(self):
    208         platform = self.getProperty('platform')
    209         appendCustomBuildFlags(self, platform)
    210         if platform == "win":
    211             rootArgument = ['--root=' + os.path.join("WebKitBuild", self.getProperty('configuration'), "bin")]
    212         else:
    213             rootArgument = ['--root=WebKitBuild/bin']
    214         if self.skipBuild:
    215             self.setCommand(self.command + rootArgument)
    216         return shell.Test.start(self)
    217 
    218     def commandComplete(self, cmd):
    219         shell.Test.commandComplete(self, cmd)
    220 
    221         logText = cmd.logs['stdio'].getText()
    222         incorrectLayoutLines = []
    223         for line in logText.splitlines():
    224             if line.find('had incorrect layout') >= 0 or line.find('were new') >= 0 or line.find('was new') >= 0:
    225                 incorrectLayoutLines.append(line)
    226             elif line.find('test case') >= 0 and (line.find(' crashed') >= 0 or line.find(' timed out') >= 0):
    227                 incorrectLayoutLines.append(line)
    228             elif line.startswith("WARNING:") and line.find(' leak') >= 0:
    229                 incorrectLayoutLines.append(line.replace('WARNING: ', ''))
    230             elif line.find('Exiting early') >= 0:
    231                 incorrectLayoutLines.append(line)
    232 
    233             # FIXME: Detect and summarize leaks of RefCounted objects
    234 
    235         self.incorrectLayoutLines = incorrectLayoutLines
    236 
    237     def evaluateCommand(self, cmd):
    238         if self.incorrectLayoutLines:
    239             if len(self.incorrectLayoutLines) == 1:
    240                 line = self.incorrectLayoutLines[0]
    241                 if line.find('were new') >= 0 or line.find('was new') >= 0 or line.find(' leak') >= 0:
    242                     return WARNINGS
    243 
    244             return FAILURE
    245 
    246         if cmd.rc != 0:
    247             return FAILURE
    248 
    249         return SUCCESS
    250 
    251     def getText(self, cmd, results):
    252         return self.getText2(cmd, results)
    253 
    254     def getText2(self, cmd, results):
    255         if results != SUCCESS and self.incorrectLayoutLines:
    256             return self.incorrectLayoutLines
    257 
    258         return [self.name]
    259 
    260 
    261 class NewRunWebKitTests(RunWebKitTests):
    262     command = ["python", "./Tools/Scripts/new-run-webkit-tests", "--noshow-results",
    263                "--verbose", "--results-directory", "layout-test-results",
    264                "--builder-name", WithProperties("%(buildername)s"),
    265                "--build-number", WithProperties("%(buildnumber)s"),
    266                "--master-name", "webkit.org",
    267                "--test-results-server", "test-results.appspot.com",
    268                WithProperties("--%(configuration)s")]
    269 
    270 
    271 class RunPythonTests(shell.Test):
    272     name = "webkitpy-test"
    273     description = ["python-tests running"]
    274     descriptionDone = ["python-tests"]
    275     command = ["python", "./Tools/Scripts/test-webkitpy"]
    276 
    277 
    278 class RunPerlTests(shell.Test):
    279     name = "webkitperl-test"
    280     description = ["perl-tests running"]
    281     descriptionDone = ["perl-tests"]
    282     command = ["perl", "./Tools/Scripts/test-webkitperl"]
    283 
    284 
    285 class RunGtkAPITests(shell.Test):
    286     name = "API tests"
    287     description = ["API tests running"]
    288     descriptionDone = ["API tests"]
    289     command = ["perl", "./Tools/Scripts/run-gtk-tests", WithProperties("--%(configuration)s")]
    290 
    291     def commandComplete(self, cmd):
    292         shell.Test.commandComplete(self, cmd)
    293 
    294         logText = cmd.logs['stdio'].getText()
    295         incorrectLines = []
    296         for line in logText.splitlines():
    297             if line.startswith('ERROR'):
    298                 incorrectLines.append(line)
    299 
    300         self.incorrectLines = incorrectLines
    301 
    302     def evaluateCommand(self, cmd):
    303         if self.incorrectLines:
    304             return FAILURE
    305 
    306         if cmd.rc != 0:
    307             return FAILURE
    308 
    309         return SUCCESS
    310 
    311     def getText(self, cmd, results):
    312         return self.getText2(cmd, results)
    313 
    314     def getText2(self, cmd, results):
    315         if results != SUCCESS and self.incorrectLines:
    316             return ["%d API tests failed" % len(self.incorrectLines)]
    317 
    318         return [self.name]
    319 
    320 class RunQtAPITests(shell.Test):
    321     name = "API tests"
    322     description = ["API tests running"]
    323     descriptionDone = ["API tests"]
    324     command = ["python", "./Tools/Scripts/run-qtwebkit-tests",
    325                "--output-file=qt-unit-tests.html", "--do-not-open-results", "--timeout=120",
    326                WithProperties("WebKitBuild/%(configuration_pretty)s/WebKit/qt/tests/")]
    327 
    328     def start(self):
    329         self.setProperty("configuration_pretty", self.getProperty("configuration").title())
    330         return shell.Test.start(self)
    331 
    332     def commandComplete(self, cmd):
    333         shell.Test.commandComplete(self, cmd)
    334 
    335         logText = cmd.logs['stdio'].getText()
    336         foundItems = re.findall("TOTALS: (?P<passed>\d+) passed, (?P<failed>\d+) failed, (?P<skipped>\d+) skipped", logText)
    337 
    338         self.incorrectTests = 0
    339         self.statusLine = []
    340 
    341         if foundItems:
    342             self.incorrectTests = int(foundItems[0][1])
    343             if self.incorrectTests > 0:
    344                 self.statusLine = [
    345                     "%s passed, %s failed, %s skipped" % (foundItems[0][0], foundItems[0][1], foundItems[0][2])
    346                 ]
    347 
    348     def evaluateCommand(self, cmd):
    349         if self.incorrectTests:
    350             return WARNINGS
    351 
    352         if cmd.rc != 0:
    353             return FAILURE
    354 
    355         return SUCCESS
    356 
    357     def getText(self, cmd, results):
    358         return self.getText2(cmd, results)
    359 
    360     def getText2(self, cmd, results):
    361         if results != SUCCESS and self.incorrectTests:
    362             return self.statusLine
    363 
    364         return [self.name]
    365 
    366 class RunWebKitLeakTests(RunWebKitTests):
    367     warnOnWarnings = True
    368     def start(self):
    369         self.setCommand(self.command + ["--leaks"])
    370         return RunWebKitTests.start(self)
    371 
    372 
    373 class RunWebKit2Tests(RunWebKitTests):
    374     def start(self):
    375         self.setCommand(self.command + ["--webkit-test-runner"])
    376         return RunWebKitTests.start(self)
    377 
    378 
    379 class RunChromiumWebKitUnitTests(shell.Test):
    380     name = "webkit-unit-tests"
    381     description = ["webkit-unit-tests running"]
    382     descriptionDone = ["webkit-unit-tests"]
    383     command = ["perl", "./Tools/Scripts/run-chromium-webkit-unit-tests",
    384                WithProperties("--%(configuration)s")]
    385 
    386 
    387 class ArchiveTestResults(shell.ShellCommand):
    388     command = ["python", "./Tools/BuildSlaveSupport/test-result-archive",
    389                WithProperties("--platform=%(platform)s"), WithProperties("--%(configuration)s"), "archive"]
    390     name = "archive-test-results"
    391     description = ["archiving test results"]
    392     descriptionDone = ["archived test results"]
    393     haltOnFailure = True
    394 
    395 
    396 class UploadTestResults(transfer.FileUpload):
    397     slavesrc = "layout-test-results.zip"
    398     masterdest = WithProperties("public_html/results/%(buildername)s/r%(got_revision)s (%(buildnumber)s).zip")
    399 
    400     def __init__(self):
    401         transfer.FileUpload.__init__(self, self.slavesrc, self.masterdest, mode=0644)
    402 
    403 
    404 class ExtractTestResults(master.MasterShellCommand):
    405     zipFile = WithProperties("public_html/results/%(buildername)s/r%(got_revision)s (%(buildnumber)s).zip")
    406     resultDirectory = WithProperties("public_html/results/%(buildername)s/r%(got_revision)s (%(buildnumber)s)")
    407     descriptionDone = ["uploaded results"]
    408 
    409     def __init__(self):
    410         master.MasterShellCommand.__init__(self, "")
    411 
    412     def resultDirectoryURL(self):
    413         return self.build.getProperties().render(self.resultDirectory).replace("public_html/", "/") + "/"
    414 
    415     def start(self):
    416         self.command = ["ditto", "-k", "-x", "-V", self.build.getProperties().render(self.zipFile), self.build.getProperties().render(self.resultDirectory)]
    417         return master.MasterShellCommand.start(self)
    418 
    419     def addCustomURLs(self):
    420         url = self.resultDirectoryURL() + "results.html"
    421         self.addURL("view results", url)
    422 
    423     def finished(self, result):
    424         self.addCustomURLs()
    425         return master.MasterShellCommand.finished(self, result)
    426 
    427 
    428 class ExtractTestResultsAndLeaks(ExtractTestResults):
    429     def addCustomURLs(self):
    430         ExtractTestResults.addCustomURLs(self)
    431         url = "/LeaksViewer/?url=" + urllib.quote(self.resultDirectoryURL(), safe="")
    432         self.addURL("view leaks", url)
    433 
    434 
    435 class Factory(factory.BuildFactory):
    436     def __init__(self, platform, configuration, architectures, buildOnly):
    437         factory.BuildFactory.__init__(self)
    438         self.addStep(ConfigureBuild, platform=platform, configuration=configuration, architecture=" ".join(architectures), buildOnly=buildOnly)
    439         self.addStep(CheckOutSource)
    440         if platform in ("win", "chromium-win"):
    441             self.addStep(KillOldProcesses)
    442         if platform == "win":
    443             self.addStep(InstallWin32Dependencies)
    444         if platform.startswith("chromium"):
    445             self.addStep(InstallChromiumDependencies)
    446 
    447 class BuildFactory(Factory):
    448     def __init__(self, platform, configuration, architectures, triggers=None):
    449         Factory.__init__(self, platform, configuration, architectures, True)
    450         self.addStep(CompileWebKit)
    451         if triggers:
    452             self.addStep(ArchiveBuiltProduct)
    453             self.addStep(UploadBuiltProduct)
    454             self.addStep(trigger.Trigger, schedulerNames=triggers)
    455 
    456 class TestFactory(Factory):
    457     TestClass = RunWebKitTests
    458     ExtractTestResultsClass = ExtractTestResults
    459     def __init__(self, platform, configuration, architectures):
    460         Factory.__init__(self, platform, configuration, architectures, False)
    461         self.addStep(DownloadBuiltProduct)
    462         self.addStep(ExtractBuiltProduct)
    463         self.addStep(RunJavaScriptCoreTests, skipBuild=True)
    464         self.addStep(self.TestClass, skipBuild=(platform == 'win'))
    465         # Tiger's Python 2.3 is too old.  WebKit Python requires 2.5+.
    466         # Sadly we have no way to detect the version on the slave from here.
    467         if platform != "mac-tiger":
    468             self.addStep(RunPythonTests)
    469         self.addStep(RunPerlTests)
    470         self.addStep(ArchiveTestResults)
    471         self.addStep(UploadTestResults)
    472         self.addStep(self.ExtractTestResultsClass)
    473 
    474 class BuildAndTestFactory(Factory):
    475     TestClass = RunWebKitTests
    476     ExtractTestResultsClass = ExtractTestResults
    477     def __init__(self, platform, configuration, architectures):
    478         Factory.__init__(self, platform, configuration, architectures, False)
    479         if platform.startswith("chromium"):
    480             self.addStep(CleanupChromiumCrashLogs)
    481         self.addStep(CompileWebKit)
    482         if not platform.startswith("chromium"):
    483             self.addStep(RunJavaScriptCoreTests)
    484         if platform.startswith("chromium"):
    485             self.addStep(RunChromiumWebKitUnitTests)
    486         self.addStep(self.TestClass)
    487         # Tiger's Python 2.3 is too old.  WebKit Python requires 2.5+.
    488         # Sadly we have no way to detect the version on the slave from here.
    489         # Chromium Win runs in non-Cygwin environment, which is not yet fit
    490         # for running tests. This can be removed once bug 48166 is fixed.
    491         if platform != "mac-tiger":
    492             self.addStep(RunPythonTests)
    493         # Chromium Win runs in non-Cygwin environment, which is not yet fit
    494         # for running tests. This can be removed once bug 48166 is fixed.
    495         if platform != "chromium-win":
    496             self.addStep(RunPerlTests)
    497         self.addStep(ArchiveTestResults)
    498         self.addStep(UploadTestResults)
    499         self.addStep(self.ExtractTestResultsClass)
    500         if platform == "gtk":
    501             self.addStep(RunGtkAPITests)
    502         if platform == "qt":
    503             self.addStep(RunQtAPITests)
    504 
    505 class BuildAndTestLeaksFactory(BuildAndTestFactory):
    506     TestClass = RunWebKitLeakTests
    507     ExtractTestResultsClass = ExtractTestResultsAndLeaks
    508 
    509 class NewBuildAndTestFactory(BuildAndTestFactory):
    510     TestClass = NewRunWebKitTests
    511 
    512 class TestWebKit2Factory(TestFactory):
    513     TestClass = RunWebKit2Tests
    514 
    515 class PlatformSpecificScheduler(AnyBranchScheduler):
    516     def __init__(self, platform, branch, **kwargs):
    517         self.platform = platform
    518         filter = ChangeFilter(branch=[branch, None], filter_fn=self.filter)
    519         AnyBranchScheduler.__init__(self, name=platform, change_filter=filter, **kwargs)
    520 
    521     def filter(self, change):
    522         return wkbuild.should_build(self.platform, change.files)
    523 
    524 trunk_filter = ChangeFilter(branch=["trunk", None])
    525 
    526 def loadBuilderConfig(c):
    527     # FIXME: These file handles are leaked.
    528     passwords = simplejson.load(open('passwords.json'))
    529     config = simplejson.load(open('config.json'))
    530 
    531     # use webkitpy's buildbot module to test for core builders
    532     wkbb = wkbuildbot()
    533 
    534     c['slaves'] = [BuildSlave(slave['name'], passwords[slave['name']], max_builds=1) for slave in config['slaves']]
    535 
    536     c['schedulers'] = []
    537     for scheduler in config['schedulers']:
    538         if "change_filter" in scheduler:
    539             scheduler["change_filter"] = globals()[scheduler["change_filter"]]
    540         kls = globals()[scheduler.pop('type')]
    541         c['schedulers'].append(kls(**scheduler))
    542 
    543     c['builders'] = []
    544     for builder in config['builders']:
    545         for slaveName in builder['slavenames']:
    546             for slave in config['slaves']:
    547                 if slave['name'] != slaveName or slave['platform'] == '*':
    548                     continue
    549 
    550                 if slave['platform'] != builder['platform']:
    551                     raise Exception, "Builder %r is for platform %r but has slave %r for platform %r!" % (builder['name'], builder['platform'], slave['name'], slave['platform'])
    552 
    553                 break
    554 
    555         factory = globals()["%sFactory" % builder.pop('type')]
    556         factoryArgs = []
    557         for key in "platform", "configuration", "architectures", "triggers":
    558             value = builder.pop(key, None)
    559             if value:
    560                 factoryArgs.append(value)
    561 
    562         builder["factory"] = factory(*factoryArgs)
    563 
    564         builder["category"] = "noncore"
    565         if wkbb._is_core_builder(builder['name']):
    566             builder["category"] = "core"
    567 
    568         c['builders'].append(builder)
    569 
    570 loadBuilderConfig(c)
    571 
    572 c['change_source'] = PBChangeSource()
    573 
    574 # permissions for WebStatus
    575 authz = Authz(
    576     forceBuild=True,
    577     forceAllBuilds=True,
    578     pingBuilder=True,
    579     gracefulShutdown=False,
    580     stopBuild=True,
    581     stopAllBuilds=True,
    582     cancelPendingBuild=True,
    583     stopChange=True,
    584     cleanShutdown=False)
    585 
    586 c['status'] = []
    587 c['status'].append(html.WebStatus(http_port=8710, 
    588                                   revlink="http://trac.webkit.org/changeset/%s", 
    589                                   authz=authz))
    590 
    591 c['slavePortnum'] = 17000
    592 c['projectName'] = "WebKit"
    593 c['projectURL'] = "http://webkit.org"
    594 c['buildbotURL'] = "http://build.webkit.org/"
    595 
    596 c['buildHorizon'] = 1000
    597 c['logHorizon'] = 500
    598 c['eventHorizon'] = 200
    599 c['buildCacheSize'] = 60
    600