[Buildbot-commits] buildbot/buildbot scheduler.py,1.3,1.4

Brian Warner warner at users.sourceforge.net
Wed Aug 10 07:06:14 UTC 2005


Update of /cvsroot/buildbot/buildbot/buildbot
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv26773/buildbot

Modified Files:
	scheduler.py 
Log Message:
Revision: arch at buildbot.sf.net--2004/buildbot--dev--0--patch-273
Creator:  Brian Warner <warner at lothar.com>

implement Try_Jobdir, with a unit test

	* buildbot/scheduler.py (Try_Jobdir): implement the jobdir style
	of the TryScheduler, no buildsetID or status-tracking support yet
	* buildbot/test/test_scheduler.py (Scheduling.testTryJobdir): test it

	* buildbot/changes/maildir.py (Maildir.setBasedir): make it
	possible to set the basedir after __init__ time, so it is easier
	to use as a Service-child of the BuildMaster instance

	* buildbot/changes/maildirtwisted.py (MaildirService): make a form
	that delivers messages to its Service parent instead of requiring
	a subclass to be useful. This turns out to be much easier to build
	unit tests around.

	* buildbot/scripts/tryclient.py (createJob): utility code to
	create jobfiles, will eventually be used by 'buildbot try'


Index: scheduler.py
===================================================================
RCS file: /cvsroot/buildbot/buildbot/buildbot/scheduler.py,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -d -r1.3 -r1.4
--- scheduler.py	20 Jul 2005 04:49:06 -0000	1.3
+++ scheduler.py	10 Aug 2005 07:06:11 -0000	1.4
@@ -1,16 +1,18 @@
 # -*- test-case-name: buildbot.test.test_dependencies -*-
 
-import time
+import time, os.path
 
 from twisted.internet import reactor
 from twisted.application import service, internet
 from twisted.python import log
+from twisted.protocols import basic
 
 from buildbot import interfaces, buildset, util
 from buildbot.util import now
 from buildbot.status import builder
 from buildbot.twcompat import implements, providedBy
 from buildbot.sourcestamp import SourceStamp
+from buildbot.changes import maildirtwisted
 
 
 class BaseScheduler(service.MultiService, util.ComparableMixin):
@@ -302,3 +304,97 @@
         bs = buildset.BuildSet(self.builderNames,
                                SourceStamp(branch=self.branch))
         self.submit(bs)
+
+class TryBase(service.MultiService, util.ComparableMixin):
+    if implements:
+        implements(interfaces.IScheduler)
+    else:
+        __implements__ = interfaces.IScheduler,
+
+    def __init__(self, name, builderNames):
+        service.MultiService.__init__(self)
+        self.name = name
+        self.builderNames = builderNames
+
+
+class BadJobfile(Exception):
+    pass
+
+class JobFileScanner(basic.NetstringReceiver):
+    def __init__(self):
+        self.strings = []
+        self.transport = self # so transport.loseConnection works
+        self.error = False
+
+    def stringReceived(self, s):
+        self.strings.append(s)
+
+    def loseConnection(self):
+        self.error = True
+
+class Try_Jobdir(TryBase):
+    compare_attrs = ["name", "builderNames", "jobdir"]
+
+    def __init__(self, name, builderNames, jobdir):
+        TryBase.__init__(self, name, builderNames)
+        self.jobdir = jobdir
+        self.watcher = maildirtwisted.MaildirService()
+        self.watcher.setServiceParent(self)
+
+    def setServiceParent(self, parent):
+        self.watcher.setBasedir(os.path.join(parent.basedir, self.jobdir))
+        TryBase.setServiceParent(self, parent)
+
+    def parseJob(self, f):
+        # jobfiles are serialized build requests. Each is a list of
+        # serialized netstrings, in the following order:
+        #  "1", the version number of this format
+        #  buildsetID, arbitrary string, used to find the buildSet later
+        #  branch name, "" for default-branch
+        #  base revision
+        #  patchlevel, usually "1"
+        #  patch
+        #  builderNames...
+        p = JobFileScanner()
+        p.dataReceived(f.read())
+        if p.error:
+            raise BadJobfile("unable to parse netstrings")
+        s = p.strings
+        ver = s.pop(0)
+        if ver != "1":
+            raise BadJobfile("unknown version '%s'" % ver)
+        buildsetID, branch, baserev, patchlevel, diff = s[:5]
+        builderNames = s[5:]
+        if branch == "":
+            branch = None
+        patchlevel = int(patchlevel)
+        patch = (patchlevel, diff)
+        ss = SourceStamp(branch, baserev, patch)
+        return builderNames, ss
+
+    def messageReceived(self, filename):
+        md = os.path.join(self.parent.basedir, self.jobdir)
+        path = os.path.join(md, "new", filename)
+        f = open(path, "r")
+        os.rename(os.path.join(md, "new", filename),
+                  os.path.join(md, "cur", filename))
+        try:
+            builderNames, ss = self.parseJob(f)
+        except BadJobfile:
+            log.msg("%s reports a bad jobfile in %s" % (self, filename))
+            log.err()
+            return
+        # compare builderNames against self.builderNames
+        # TODO: think about this some more.. why bother restricting it?
+        # perhaps self.builderNames should be used as the default list
+        # instead of being used as a restriction?
+        for b in builderNames:
+            if not b in self.builderNames:
+                log.msg("%s got jobfile %s with builder %s" % (self,
+                                                               filename, b))
+                log.msg(" but that wasn't in our list: %s"
+                        % (self.builderNames,))
+                return
+
+        bs = buildset.BuildSet(builderNames, ss)
+        self.parent.submitBuildSet(bs)





More information about the Commits mailing list