[Buildbot-commits] buildbot/buildbot interfaces.py,1.28,1.29 buildset.py,1.1,1.2 master.py,1.79,1.80

Brian Warner warner at users.sourceforge.net
Wed Aug 17 02:15:39 UTC 2005


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

Modified Files:
	interfaces.py buildset.py master.py 
Log Message:
Revision: arch at buildbot.sf.net--2004/buildbot--dev--0--patch-295
Creator:  Brian Warner <warner at monolith.lothar.com>

implement IBuildSetStatus/IBuildRequestStatus, wire them into place

	* buildbot/status/builder.py: implement IBuildSetStatus and
	IBuildRequestStatus, wire them into place.
	* buildbot/buildset.py: same. Add ID, move wait-until-finished
	methods into the BuildSetStatus object.
	* buildbot/interfaces.py: same
	(IStatus.getBuildSets): new method to get pending BuildSets
	(IStatusReceiver.buildsetSubmitted): new method which hears about
	new BuildSets
	* buildbot/master.py (BuildMaster.submitBuildSet): same
	* buildbot/process/base.py (BuildRequest): same, replace
	waitUntilStarted with subscribe/unsubscribe
	* buildbot/process/builder.py (BuilderControl.forceBuild): use
	subscribe instead of waitUntilStarted
	* buildbot/status/base.py (StatusReceiver.buildsetSubmitted): stub
	for new method
	* buildbot/status/client.py (StatusClientPerspective.builderRemoved): 
	same
	* buildbot/test/test_buildreq.py: update for new code
	* buildbot/test/test_control.py (Force.testRequest): same


Index: buildset.py
===================================================================
RCS file: /cvsroot/buildbot/buildbot/buildbot/buildset.py,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- buildset.py	19 Jul 2005 23:11:59 -0000	1.1
+++ buildset.py	17 Aug 2005 02:15:36 -0000	1.2
@@ -12,35 +12,21 @@
     source.revision), or a build of a certain set of Changes
     (source.changes=list)."""
 
-    def __init__(self, builderNames, source, reason=None):
+    def __init__(self, builderNames, source, reason=None, bsid=None):
         """
         @param source: a L{SourceStamp}
         """
         self.builderNames = builderNames
         self.source = source
         self.reason = reason
-        self.set_status = bss = builder.BuildSetStatus()
-        bss.setSourceStamp(source)
-        bss.setReason(reason)
-        self.successWatchers = []
-        self.finishedWatchers = []
         self.failed = False
+        self.status = bss = builder.BuildSetStatus(source, reason,
+                                                   builderNames, bsid)
 
     def waitUntilSuccess(self):
-        """Return a Deferred that will fire (with an IBuildSetStatus) when we
-        know whether or not this BuildSet will be a complete success (all
-        builds succeeding). This means it will fire upon the first failing
-        build, or upon the last successful one."""
-        # TODO: make it safe to call this after the buildset has completed
-        d = defer.Deferred()
-        self.successWatchers.append(d)
-        return d
-
+        return self.status.waitUntilSuccess()
     def waitUntilFinished(self):
-        """Return a Deferred that will fire when all builds have finished."""
-        d = defer.Deferred()
-        self.finishedWatchers.append(d)
-        return d
+        return self.status.waitUntilFinished()
 
     def start(self, builders):
         """This is called by the BuildMaster to actually create and submit
@@ -50,38 +36,28 @@
 
         # create the requests
         for b in builders:
-            req = base.BuildRequest(self.reason, self.source)
+            req = base.BuildRequest(self.reason, self.source, b.name)
             reqs.append((b, req))
             self.requests.append(req)
             d = req.waitUntilFinished()
             d.addCallback(self.requestFinished, req)
-                
+
+        # tell our status about them
+        req_statuses = [req.status for req in self.requests]
+        self.status.setBuildRequestStatuses(req_statuses)
+
         # now submit them
-        self.status = {} # maps requests to BuildStatus
         for b,req in reqs:
             b.submitBuildRequest(req)
 
     def requestFinished(self, buildstatus, req):
         self.requests.remove(req)
-        self.status[req] = buildstatus
         if buildstatus.getResults() == builder.FAILURE:
             if not self.failed:
-                self.failed = True
-                self.set_status.setResults(builder.FAILURE)
-                self.notifySuccessWatchers()
+                self.failed = self.status.failed = True
+                self.status.setResults(builder.FAILURE)
+                self.status.notifySuccessWatchers()
         if not self.requests:
-            self.set_status.setResults(builder.SUCCESS)
-            self.notifyFinishedWatchers()
-
-    def notifySuccessWatchers(self):
-        for d in self.successWatchers:
-            d.callback(self.set_status)
-        self.successWatchers = []
-
-    def notifyFinishedWatchers(self):
-        if not self.failed:
-            self.notifySuccessWatchers()
-        for d in self.finishedWatchers:
-            d.callback(self.set_status)
-        self.finishedWatchers = []
+            self.status.setResults(builder.SUCCESS)
+            self.status.notifyFinishedWatchers()
 

Index: interfaces.py
===================================================================
RCS file: /cvsroot/buildbot/buildbot/buildbot/interfaces.py,v
retrieving revision 1.28
retrieving revision 1.29
diff -u -d -r1.28 -r1.29
--- interfaces.py	20 Jul 2005 04:21:57 -0000	1.28
+++ interfaces.py	17 Aug 2005 02:15:36 -0000	1.29
@@ -95,12 +95,17 @@
     def getSlave(name):
         """Return the ISlaveStatus object for a given named buildslave."""
 
+    def getBuildSets():
+        """Return a list of active (non-finished) IBuildSetStatus objects."""
+
     def subscribe(receiver):
         """Register an IStatusReceiver to receive new status events. The
         receiver will immediately be sent a set of 'builderAdded' messages
         for all current builders. It will receive further 'builderAdded' and
         'builderRemoved' messages as the config file is reloaded and builders
-        come and go. No additional messages will be sent unless the receiver
+        come and go. It will also receive 'buildsetSubmitted' messages for
+        all outstanding BuildSets (and each new BuildSet that gets
+        submitted). No additional messages will be sent unless the receiver
         asks for them by calling .subscribe on the IBuilderStatus objects
         which accompany the addedBuilder message."""
 
@@ -118,22 +123,54 @@
         pass
     def getChanges():
         pass
+    def getID():
+        """Return the BuildSet's ID string, if any. The 'try' feature uses a
+        random string as a BuildSetID to relate submitted jobs with the
+        resulting BuildSet."""
     def getResponsibleUsers():
-        pass
+        pass # not implemented
     def getInterestedUsers():
-        pass
-    def getBuilds():
-        """Return a list of IBuildStatus objects that represent my
-        component Builds."""
+        pass # not implemented
+    def getBuilderNames():
+        """Return a list of the names of all Builders on which this set will
+        do builds."""
+    def getBuildRequests():
+        """Return a list of IBuildRequestStatus objects that represent my
+        component Builds. This list might correspond to the Builders named by
+        getBuilderNames(), but if builder categories are used, or 'Builder
+        Aliases' are implemented, then they may not."""
     def isFinished():
         pass
-    def waitUntilFirstFailure():
-        pass
+    def waitUntilSuccess():
+        """Return a Deferred that fires (with this IBuildSetStatus object)
+        when the outcome of the BuildSet is known, i.e., upon the first
+        failure, or after all builds complete successfully."""
     def waitUntilFinished():
-        pass
+        """Return a Deferred that fires (with this IBuildSetStatus object)
+        when all builds have finished."""
     def getResults():
         pass
 
+class IBuildRequestStatus(Interface):
+    """I represent a request to build a particular set of source code on a
+    particular Builder. These requests may be merged by the time they are
+    finally turned into a Build."""
+
+    def getSourceStamp():
+        pass
+    def getBuilderName():
+        pass
+    def subscribe(observer):
+        """Register a callable that will be invoked (with a single
+        IBuildStatus object) for each Build that is created to satisfy this
+        request. There may be multiple Builds created in an attempt to handle
+        the request: they may be interrupted by the user or abandoned due to
+        a lost slave. The last Build (the one which actually gets to run to
+        completion) is said to 'satisfy' the BuildRequest. The observer will
+        be called once for each of these Builds, both old and new."""
+    def unsubscribe(observer):
+        """Unregister the callable that was registered with subscribe()."""
+
 
 class ISlaveStatus(Interface):
     def getName():
@@ -639,6 +676,12 @@
     """I am an object which can receive build status updates. I may be
     subscribed to an IStatus, an IBuilderStatus, or an IBuildStatus."""
 
+    def buildsetSubmitted(buildset):
+        """A new BuildSet has been submitted to the buildmaster.
+
+        @type buildset: implementor of L{IBuildSetStatus}
+        """
+
     def builderAdded(builderName, builder):
         """
         A new Builder has just been added. This method may return an
@@ -734,7 +777,6 @@
     def submitBuildSet(buildset):
         """Submit a BuildSet object, which will eventually be run on all of
         the builders listed therein."""
-        # TODO: return a status object
 
     def getBuilder(name):
         """Retrieve the IBuilderControl object for the given Builder."""
@@ -787,6 +829,16 @@
         # the Builder column, so it kinda fits here too.
 
 class IBuildRequestControl(Interface):
+    def subscribe(observer):
+        """Register a callable that will be invoked (with a single
+        IBuildControl object) for each Build that is created to satisfy this
+        request. There may be multiple Builds created in an attempt to handle
+        the request: they may be interrupted by the user or abandoned due to
+        a lost slave. The last Build (the one which actually gets to run to
+        completion) is said to 'satisfy' the BuildRequest. The observer will
+        be called once for each of these Builds, both old and new."""
+    def unsubscribe(observer):
+        """Unregister the callable that was registered with subscribe()."""
     def cancel():
         """Remove the build from the pending queue. Has no effect if the
         build has already been started."""

Index: master.py
===================================================================
RCS file: /cvsroot/buildbot/buildbot/buildbot/master.py,v
retrieving revision 1.79
retrieving revision 1.80
diff -u -d -r1.79 -r1.80
--- master.py	11 Aug 2005 21:58:41 -0000	1.79
+++ master.py	17 Aug 2005 02:15:36 -0000	1.80
@@ -974,6 +974,7 @@
         # now tell the BuildSet to create BuildRequests for all those
         # Builders and submit them
         bs.start(builders)
+        self.status.buildsetSubmitted(bs.status)
 
 
 class Control:
@@ -990,7 +991,6 @@
 
     def submitBuildSet(self, bs):
         self.master.submitBuildSet(bs)
-        # TODO: return a BuildSetStatus
 
     def getBuilder(self, name):
         b = self.master.botmaster.builders[name]





More information about the Commits mailing list