[pypy-svn] r50596 - pypy/build/buildbot

exarkun at codespeak.net exarkun at codespeak.net
Mon Jan 14 15:55:52 CET 2008


Author: exarkun
Date: Mon Jan 14 15:55:51 2008
New Revision: 50596

Added:
   pypy/build/buildbot/
   pypy/build/buildbot/master.cfg
   pypy/build/buildbot/pypy_status.py
   pypy/build/buildbot/pypybuilders.py
   pypy/build/buildbot/slaveinfo.py
   pypy/build/buildbot/text-conftest.py
Log:
master configuration for pypy buildbot

Added: pypy/build/buildbot/master.cfg
==============================================================================
--- (empty file)
+++ pypy/build/buildbot/master.cfg	Mon Jan 14 15:55:51 2008
@@ -0,0 +1,69 @@
+
+from buildbot.scheduler import Nightly
+from buildbot.buildslave import BuildSlave
+from buildbot.status.html import WebStatus
+
+from pypybuilders import PyPyBuildFactory
+from slaveinfo import passwords
+
+httpPortNumber = 10408
+
+# I really wanted to pass logPath to Site
+from twisted.web.server import Site
+class LoggingSite(Site):
+    def __init__(self, *a, **kw):
+        Site.__init__(self, logPath='httpd.log', *a, **kw)
+from twisted.web import server
+server.Site = LoggingSite
+# So I did.
+
+BuildmasterConfig = {
+    'slavePortnum': "tcp:10407",
+
+    'change_source': [],
+    'schedulers': [Nightly("nightly", [
+                           "pypy-c-allworkingmodules-32",
+                           "pypy-c-allworkingmodules-faassen-32",
+                           "pypy-c-allworkingmodules-faassen-64",
+                           "pypy-c-allworkingmodules-faassen-winxp32"],
+                       hour=19)],
+    'status': [WebStatus(httpPortNumber, allowForce=True)],
+
+    'slaves': [BuildSlave(name, password)
+               for (name, password)
+               in passwords.iteritems()],
+
+    'builders': [{"name": "pypy-c-allworkingmodules-32",
+                  "slavenames": ["charm"],
+                  "builddir": "pypy-c-allworkingmodules-32",
+                  "factory": PyPyBuildFactory(["--boxed"],
+                                              [],
+                                              ["--allworkingmodules"])},
+
+                 {"name": "pypy-c-allworkingmodules-faassen-32",
+                  "slavenames": ["charm"],
+                  "builddir": "pypy-c-allworkingmodules-faassen-32",
+                  "factory": PyPyBuildFactory(None,
+                                              ["--gc=semispace"],
+                                              ["--allworkingmodules",
+                                               "--faassen"])},
+
+                 {"name": "pypy-c-allworkingmodules-faassen-64",
+                  "slavenames": ["linux-dvs0"],
+                  "builddir": "pypy-c-allworkingmodules-faassen-64",
+                  "factory": PyPyBuildFactory([],
+                                              [],
+                                              ["--allworkingmodules",
+                                               "--faassen"])},
+
+                 {"name": "pypy-c-allworkingmodules-faassen-winxp32",
+                  "slavenames": ["winxp32-py2.5"],
+                  "builddir": "pypy-c-allworkingmodules-faassen-winxp32",
+                  "factory": PyPyBuildFactory([],
+                                              [],
+                                              [])},
+                ],
+
+    'buildbotURL': 'http://office.divmod.com:%d/' % (httpPortNumber,),
+    'projectURL': 'http://codespeak.net/pypy/',
+    'projectName': 'PyPy'}

Added: pypy/build/buildbot/pypy_status.py
==============================================================================
--- (empty file)
+++ pypy/build/buildbot/pypy_status.py	Mon Jan 14 15:55:51 2008
@@ -0,0 +1,61 @@
+
+from sets import Set
+
+from nevow import tags
+from nevow.url import URL
+from nevow.flat import flatten
+
+from buildbot.status.web.base import ICurrentBox, HtmlResource, map_branches, build_get_class
+
+class RecentlyFailingTests(HtmlResource):
+    def body(self, request):
+        status = self.getStatus(req)
+        builderNames = status.getBuilderNames()
+
+        # Keys are the names of tests which failed recently.  Each
+        # value is a list the elements of which is a group of test
+        # results for a particular build.  The group is a dict the
+        # keys of which are a builder name and the values of which are
+        # the result for that test on that builder for that build.
+        # eg
+        #
+        # {'foo.tests.test_foo.FooTests.test_foo': [
+        #     {'win32': 'passed', 'linux': 'failed'},
+        #     {'win32': 'passed', 'linux': 'passed'},
+        #     {'win32': 'failed', 'linux': 'passed'}]}
+	failedTests = {}
+
+        for name in builderNames:
+            recentFailures = Set()
+            builder = status.getBuilder(name)
+            recentBuilds = builder.generateFinishedBuilds(branches=[None], num_builds=10)
+            for build in recentBuilds:
+                recentFailures.update(build.getLog('failed').splitlines())
+
+        for name in builderNames:
+            builder = status.getBuilder(name)
+            recentBuilds = builder.generateFinishedBuilds(branches=[None], num_builds=10)
+            for build in recentBuilds:
+                results = {}
+                for passed in build.getLog('passed').splitlines():
+                    results[passed] = 'passed'
+                for failed in build.getLog('failed').splitlines():
+                    results[failed] = 'failed'
+                for skipped in build.getLog('skipped').splitlines():
+                    results[skipped] = 'skipped'
+                for recentFailed in recentFailures:
+                    
+
+                
+
+        table = tags.table[[
+                tags.tr[[
+                        tags.td[[
+                                testResult[0]
+                                for testResult
+                                in testResultsForBuild],
+                            tags.td[testName]]
+                        for testResultsForBuild
+                        in testResultsOverTime]]
+                    for (testName, testResultsOverTime)
+                    in failedTests.iteritems()]]

Added: pypy/build/buildbot/pypybuilders.py
==============================================================================
--- (empty file)
+++ pypy/build/buildbot/pypybuilders.py	Mon Jan 14 15:55:51 2008
@@ -0,0 +1,132 @@
+
+from buildbot.interfaces import LOG_CHANNEL_STDOUT
+from buildbot.process.factory import BuildFactory
+from buildbot.steps.source import SVN
+from buildbot.steps.shell import ShellCommand
+from buildbot.steps.transfer import FileUpload, FileDownload
+from buildbot.steps.python_twisted import Trial
+
+class Translate(ShellCommand):
+    name = "translate"
+    description = ["Translating"]
+    descriptionDone = ["Translation"]
+
+    command = ["python", "translate.py", "--batch"]
+    translationTarget = "targetpypystandalone"
+    haltOnFailure = True
+
+    def __init__(self, translationArgs, targetArgs,
+                 workdir="build/pypy-src/pypy/translator/goal",
+                 *a, **kw):
+        self.command = self.command + translationArgs + [self.translationTarget] + targetArgs
+        ShellCommand.__init__(self, workdir, *a, **kw)
+
+
+
+class PyTest(ShellCommand):
+    name = "py.test pypy"
+    description = ["PyPy", "Tests"]
+
+    command = ["find", "-name", "test", "-type", "d", "-exec", "python", "py/bin/py.test", "--session=MySession", "{}", ";"]
+    haltOnFailure = False
+
+    def __init__(self, testPackage, testArguments, workdir="build/pypy-src", *a, **kw):
+        ShellCommand.__init__(self, workdir, *a, **kw)
+        self.command = list(self.command)
+        self.command[1:1] = [testPackage]
+        self.command[-2:-2] = testArguments
+
+
+    def createSummary(self, log):
+        """
+        foo.test.test_foo.py.AppTestFoo.().test_foo passed
+        foo.test.test_foo.py.AppTestFoo.().test_bar failed
+        foo.test.test_foo.py.AppTestFoo.().test_baz skipped
+        """
+        stdout = ''.join(
+            log.getChunks(channels=[LOG_CHANNEL_STDOUT],
+                          onlyText=True))
+
+        resultLists = {
+            'passed': [],
+            'failed': [],
+            'skipped': [],
+            }
+        weird = []
+        for result in stdout.splitlines():
+            testName, testResult = result.rsplit(None, 1)
+            if testResult in resultLists:
+                resultLists[testResult].append(testName)
+            else:
+                weird.append(result)
+        resultLists['weird'] = weird
+
+        for testGroup, testNames in resultLists.iteritems():
+            if testNames:
+                self.addCompleteLog(
+                    '%d %s' % (len(testNames), testGroup),
+                    '\n'.join(testNames))
+
+
+
+class PySwitch(ShellCommand):
+    name = "switch"
+    description = ["Switch", "Py", "to", "reporter-merge"]
+
+    command = ["svn", "switch",
+               "http://codespeak.net/svn/py/branch/reporter-merge/py"]
+    haltOnFailure = True
+
+    def __init__(self, workdir="build/pypy-src/py", *a, **kw):
+        ShellCommand.__init__(self, workdir, *a, **kw)
+
+
+
+class PyPyBuildFactory(BuildFactory):
+    def __init__(self, pytestArguments, translationArguments,
+                 targetArguments, *a, **kw):
+        BuildFactory.__init__(self, *a, **kw)
+
+        self.addStep(
+            SVN,
+            workdir="build/pypy-src",
+            svnurl="http://codespeak.net/svn/pypy/dist",
+            mode="copy")
+
+        self.addStep(PySwitch)
+        self.addStep(
+            FileDownload,
+            mastersrc="text-conftest.py",
+            slavedest="conftest.py",
+            workdir="build/pypy-src")
+
+        if pytestArguments is not None:
+            self.addStep(
+                PyTest,
+                testPackage="pypy",
+                testArguments=pytestArguments,
+                timeout=60 * 60)
+
+        self.addStep(
+            Translate,
+            translationArgs=translationArguments,
+            targetArgs=targetArguments)
+
+        # self.addStep(FileUpload,
+        #              slavesrc="pypy-src/pypy/translator/goal/pypy-c",
+        #              masterdest="pypy-c")
+
+        self.addStep(
+            SVN,
+            workdir="build/twisted-src",
+            svnurl="svn://svn.twistedmatrix.com/svn/Twisted/trunk",
+            mode="copy")
+
+        self.addStep(
+            Trial,
+            workdir="build/twisted-src",
+            python=["../pypy-src/pypy/translator/goal/pypy-c",
+                    "--oldstyle"],
+            testpath=None,
+            trial="bin/trial",
+            tests=["twisted"])

Added: pypy/build/buildbot/slaveinfo.py
==============================================================================
--- (empty file)
+++ pypy/build/buildbot/slaveinfo.py	Mon Jan 14 15:55:51 2008
@@ -0,0 +1,3 @@
+
+# Mapping from slave name to slave password
+passwords = {}

Added: pypy/build/buildbot/text-conftest.py
==============================================================================
--- (empty file)
+++ pypy/build/buildbot/text-conftest.py	Mon Jan 14 15:55:51 2008
@@ -0,0 +1,42 @@
+
+import sys
+
+import py
+from py.__.test.session import Session
+from py.__.test.reporter import AbstractReporter
+
+class MyReporter(AbstractReporter):
+    def __init__(self, *args, **kwds):
+        super(MyReporter, self).__init__(*args, **kwds)
+
+        # XXXXXXXXXXXXXXx SUPER HACK mostly broken only works if you run
+        # py.test just how I run py.test, sorry. -exarkun
+        self.name = filter(None, sys.argv[-1].split('/')[:-1])
+    
+    def report_unknown(self, event):
+        pass
+
+    def report_TestStarted(self, event):
+        pass
+
+    def report_TestFinished(self, event):
+        pass
+
+    def report_ReceivedItemOutcome(self, event):
+        if event.outcome.passed:
+            result = 'passed'
+        elif event.outcome.skipped:
+            result = 'skipped'
+        else:
+            result = 'failed'
+        self.out.line('%s %s' % ('.'.join(self.name), result))
+
+    def report_ItemStart(self, event):
+        self.name.append(event.item.name)
+
+    def report_ItemFinish(self, event):
+        self.name.pop()
+
+class MySession(Session):
+    reporterclass = MyReporter
+



More information about the Pypy-commit mailing list