[Buildbot-commits] buildbot/buildbot/test test_run.py,1.35,1.36 test_status.py,1.28,1.29

Brian Warner warner at users.sourceforge.net
Sun Nov 27 00:46:15 UTC 2005


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

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

fix StatusReceiver unsubscribe bug

	* buildbot/status/builder.py (BuildStepStatus.unsubscribe): make
	sure that unsubscribe works even if we never sent an ETA update.
	Also, don't explode on duplicate unsubscribe.
	(BuildStepStatus.addLog): make the convenience "return self"-added
	watcher automatically unsubscribe when the Step finishes.
	(BuildStatus.unsubscribe): same handle-duplicate-unsubscribe
	(BuildStatus.stepStarted): same auto-unsubscribe
	(BuilderStatus.buildStarted): same auto-unsubscribe

	* buildbot/interfaces.py (IStatusReceiver.buildStarted): document
	auto-unsubscribe
	(IStatusReceiver.stepStarted): same
	(IStatusReceiver.logStarted): same

	* buildbot/test/test_run.py (Status): move the Status test..
	* buildbot/test/test_status.py (Subscription): .. to here


Index: test_run.py
===================================================================
RCS file: /cvsroot/buildbot/buildbot/buildbot/test/test_run.py,v
retrieving revision 1.35
retrieving revision 1.36
diff -u -d -r1.35 -r1.36
--- test_run.py	14 Oct 2005 19:42:39 -0000	1.35
+++ test_run.py	27 Nov 2005 00:46:13 -0000	1.36
@@ -8,10 +8,9 @@
 
 from buildbot import master, interfaces
 from buildbot.sourcestamp import SourceStamp
-from buildbot.util import now
 from buildbot.slave import bot
 from buildbot.changes import changes
-from buildbot.status import base, builder
+from buildbot.status import builder
 from buildbot.process.base import BuildRequest
 from buildbot.twcompat import maybeWait
 
@@ -73,64 +72,6 @@
                       'builddir': 'dummy23', 'factory': f2})
 """
 
-class STarget(base.StatusReceiver):
-    debug = False
-
-    def __init__(self, mode):
-        self.mode = mode
-        self.events = []
-    def announce(self):
-        if self.debug:
-            print self.events[-1]
-
-    def builderAdded(self, name, builder):
-        self.events.append(("builderAdded", name, builder))
-        self.announce()
-        if "builder" in self.mode:
-            return self
-    def builderChangedState(self, name, state):
-        self.events.append(("builderChangedState", name, state))
-        self.announce()
-    def buildStarted(self, name, build):
-        self.events.append(("buildStarted", name, build))
-        self.announce()
-        if "eta" in self.mode:
-            self.eta_build = build.getETA()
-        if "build" in self.mode:
-            return self
-    def buildETAUpdate(self, build, ETA):
-        self.events.append(("buildETAUpdate", build, ETA))
-        self.announce()
-    def stepStarted(self, build, step):
-        self.events.append(("stepStarted", build, step))
-        self.announce()
-        if 0 and "eta" in self.mode:
-            print "TIMES", step.getTimes()
-            print "ETA", step.getETA()
-            print "EXP", step.getExpectations()
-        if "step" in self.mode:
-            return self
-    def stepETAUpdate(self, build, step, ETA, expectations):
-        self.events.append(("stepETAUpdate", build, step, ETA, expectations))
-        self.announce()
-    def logStarted(self, build, step, log):
-        self.events.append(("logStarted", build, step, log))
-        self.announce()
-    def logFinished(self, build, step, log):
-        self.events.append(("logFinished", build, step, log))
-        self.announce()
-    def stepFinished(self, build, step, results):
-        self.events.append(("stepFinished", build, step, results))
-        if 0 and "eta" in self.mode:
-            print "post-EXP", step.getExpectations()
-        self.announce()
-    def buildFinished(self, name, build, results):
-        self.events.append(("buildFinished", name, build, results))
-        self.announce()
-    def builderRemoved(self, name):
-        self.events.append(("builderRemoved", name))
-        self.announce()
-
 class Run(unittest.TestCase):
     def rmtree(self, d):
         try:
@@ -175,162 +116,6 @@
     def _testPing_2(self, res):
         pass
 
-class Status(RunMixin, unittest.TestCase):
-
-    def testSlave(self):
-        m = self.master
-        s = m.getStatus()
-        self.t1 = t1 = STarget(["builder"])
-        #t1.debug = True; print
-        s.subscribe(t1)
-        self.failUnlessEqual(len(t1.events), 0)
-
-        self.t3 = t3 = STarget(["builder", "build", "step"])
-        s.subscribe(t3)
-
-        m.loadConfig(config_2)
-        m.readConfig = True
-        m.startService()
-
-        self.failUnlessEqual(len(t1.events), 4)
-        self.failUnlessEqual(t1.events[0][0:2], ("builderAdded", "dummy"))
-        self.failUnlessEqual(t1.events[1],
-                             ("builderChangedState", "dummy", "offline"))
-        self.failUnlessEqual(t1.events[2][0:2], ("builderAdded", "testdummy"))
-        self.failUnlessEqual(t1.events[3],
-                             ("builderChangedState", "testdummy", "offline"))
-        t1.events = []
-
-        self.failUnlessEqual(s.getBuilderNames(), ["dummy", "testdummy"])
-        self.failUnlessEqual(s.getBuilderNames(categories=['test']),
-                             ["testdummy"])
-        self.s1 = s1 = s.getBuilder("dummy")
-        self.failUnlessEqual(s1.getName(), "dummy")
-        self.failUnlessEqual(s1.getState(), ("offline", []))
-        self.failUnlessEqual(s1.getCurrentBuilds(), [])
-        self.failUnlessEqual(s1.getLastFinishedBuild(), None)
-        self.failUnlessEqual(s1.getBuild(-1), None)
-        #self.failUnlessEqual(s1.getEvent(-1), foo("created"))
-
-        # status targets should, upon being subscribed, immediately get a
-        # list of all current builders matching their category
-        self.t2 = t2 = STarget([])
-        s.subscribe(t2)
-        self.failUnlessEqual(len(t2.events), 2)
-        self.failUnlessEqual(t2.events[0][0:2], ("builderAdded", "dummy"))
-        self.failUnlessEqual(t2.events[1][0:2], ("builderAdded", "testdummy"))
-
-        d = self.connectSlave(builders=["dummy", "testdummy"])
-        d.addCallback(self._testSlave_1, t1)
-        return maybeWait(d)
-
-    def _testSlave_1(self, res, t1):
-        self.failUnlessEqual(len(t1.events), 2)
-        self.failUnlessEqual(t1.events[0],
-                             ("builderChangedState", "dummy", "idle"))
-        self.failUnlessEqual(t1.events[1],
-                             ("builderChangedState", "testdummy", "idle"))
-        t1.events = []
-
-        c = interfaces.IControl(self.master)
-        req = BuildRequest("forced build for testing", SourceStamp())
-        c.getBuilder("dummy").requestBuild(req)
-        d = req.waitUntilFinished()
-        d2 = self.master.botmaster.waitUntilBuilderIdle("dummy")
-        dl = defer.DeferredList([d, d2])
-        dl.addCallback(self._testSlave_2)
-        return dl
-
-    def _testSlave_2(self, res):
-        # t1 subscribes to builds, but not anything lower-level
-        ev = self.t1.events
-        self.failUnlessEqual(len(ev), 4)
-        self.failUnlessEqual(ev[0][0:3],
-                             ("builderChangedState", "dummy", "building"))
-        self.failUnlessEqual(ev[1][0], "buildStarted")
-        self.failUnlessEqual(ev[2][0:2]+ev[2][3:4],
-                             ("buildFinished", "dummy", builder.SUCCESS))
-        self.failUnlessEqual(ev[3][0:3],
-                             ("builderChangedState", "dummy", "idle"))
-
-        self.failUnlessEqual([ev[0] for ev in self.t3.events],
-                             ["builderAdded",
-                              "builderChangedState", # offline
-                              "builderAdded",
-                              "builderChangedState", # idle
-                              "builderChangedState", # offline
-                              "builderChangedState", # idle
-                              "builderChangedState", # building
-                              "buildStarted",
-                              "stepStarted", "stepETAUpdate", "stepFinished",
-                              "stepStarted", "stepETAUpdate",
-                              "logStarted", "logFinished", "stepFinished",
-                              "buildFinished",
-                              "builderChangedState", # idle
-                              ])
-
-        b = self.s1.getLastFinishedBuild()
-        self.failUnless(b)
-        self.failUnlessEqual(b.getBuilder().getName(), "dummy")
-        self.failUnlessEqual(b.getNumber(), 0)
-        self.failUnlessEqual(b.getSourceStamp(), (None, None, None))
-        self.failUnlessEqual(b.getReason(), "forced build for testing")
-        self.failUnlessEqual(b.getChanges(), [])
-        self.failUnlessEqual(b.getResponsibleUsers(), [])
-        self.failUnless(b.isFinished())
-        self.failUnlessEqual(b.getText(), ['build', 'successful'])
-        self.failUnlessEqual(b.getColor(), "green")
-        self.failUnlessEqual(b.getResults(), builder.SUCCESS)
-
-        steps = b.getSteps()
-        self.failUnlessEqual(len(steps), 2)
-
-        eta = 0
-        st1 = steps[0]
-        self.failUnlessEqual(st1.getName(), "dummy")
-        self.failUnless(st1.isFinished())
-        self.failUnlessEqual(st1.getText(), ["delay", "1 secs"])
-        start,finish = st1.getTimes()
-        self.failUnless(0.5 < (finish-start) < 10)
-        self.failUnlessEqual(st1.getExpectations(), [])
-        self.failUnlessEqual(st1.getLogs(), [])
-        eta += finish-start
-
-        st2 = steps[1]
-        self.failUnlessEqual(st2.getName(), "remote dummy")
-        self.failUnless(st2.isFinished())
-        self.failUnlessEqual(st2.getText(),
-                             ["remote", "delay", "2 secs"])
-        start,finish = st2.getTimes()
-        self.failUnless(1.5 < (finish-start) < 10)
-        eta += finish-start
-        self.failUnlessEqual(st2.getExpectations(), [('output', 38, None)])
-        logs = st2.getLogs()
-        self.failUnlessEqual(len(logs), 1)
-        self.failUnlessEqual(logs[0].getName(), "log")
-        self.failUnlessEqual(logs[0].getText(), "data")
-
-        self.eta = eta
-        # now we run it a second time, and we should have an ETA
-
-        self.t4 = t4 = STarget(["builder", "build", "eta"])
-        self.master.getStatus().subscribe(t4)
-        c = interfaces.IControl(self.master)
-        req = BuildRequest("forced build for testing", SourceStamp())
-        c.getBuilder("dummy").requestBuild(req)
-        d = req.waitUntilFinished()
-        d2 = self.master.botmaster.waitUntilBuilderIdle("dummy")
-        dl = defer.DeferredList([d, d2])
-        dl.addCallback(self._testSlave_3)
-        return dl
-
-    def _testSlave_3(self, res):
-        t4 = self.t4
-        eta = self.eta
-        self.failUnless(eta-1 < t4.eta_build < eta+1, # should be 3 seconds
-                        "t4.eta_build was %g, not in (%g,%g)"
-                        % (t4.eta_build, eta-1, eta+1))
-
 class BuilderNames(unittest.TestCase):
 
     def testGetBuilderNames(self):

Index: test_status.py
===================================================================
RCS file: /cvsroot/buildbot/buildbot/buildbot/test/test_status.py,v
retrieving revision 1.28
retrieving revision 1.29
diff -u -d -r1.28 -r1.29
--- test_status.py	5 Nov 2005 21:52:09 -0000	1.28
+++ test_status.py	27 Nov 2005 00:46:13 -0000	1.29
@@ -7,13 +7,15 @@
 
 from buildbot import interfaces
 from buildbot.sourcestamp import SourceStamp
+from buildbot.process.base import BuildRequest
 from buildbot.twcompat import implements, providedBy, maybeWait
-from buildbot.status import builder
+from buildbot.status import builder, base
 try:
     from buildbot.status import mail
 except ImportError:
     mail = None
 from buildbot.status import progress, client # NEEDS COVERAGE
+from buildbot.test.runutils import RunMixin
 
 class MyStep:
     build = None
@@ -668,6 +670,250 @@
         self.failUnless(s.finished)
 
 
+config_base = """
+from buildbot.process import factory, step
+s = factory.s
+
+f1 = factory.QuickBuildFactory('fakerep', 'cvsmodule', configure=None)
+
+f2 = factory.BuildFactory([
+    s(step.Dummy, timeout=1),
+    s(step.RemoteDummy, timeout=2),
+    ])
+
+BuildmasterConfig = c = {}
+c['bots'] = [['bot1', 'sekrit']]
+c['sources'] = []
+c['schedulers'] = []
+c['builders'] = []
+c['builders'].append({'name':'quick', 'slavename':'bot1',
+                      'builddir': 'quickdir', 'factory': f1})
+c['slavePortnum'] = 0
+"""
+
+config_2 = config_base + """
+c['builders'] = [{'name': 'dummy', 'slavename': 'bot1',
+                  'builddir': 'dummy1', 'factory': f2},
+                 {'name': 'testdummy', 'slavename': 'bot1',
+                  'builddir': 'dummy2', 'factory': f2, 'category': 'test'}]
+"""
+
+class STarget(base.StatusReceiver):
+    debug = False
+
+    def __init__(self, mode):
+        self.mode = mode
+        self.events = []
+    def announce(self):
+        if self.debug:
+            print self.events[-1]
+
+    def builderAdded(self, name, builder):
+        self.events.append(("builderAdded", name, builder))
+        self.announce()
+        if "builder" in self.mode:
+            return self
+    def builderChangedState(self, name, state):
+        self.events.append(("builderChangedState", name, state))
+        self.announce()
+    def buildStarted(self, name, build):
+        self.events.append(("buildStarted", name, build))
+        self.announce()
+        if "eta" in self.mode:
+            self.eta_build = build.getETA()
+        if "build" in self.mode:
+            return self
+    def buildETAUpdate(self, build, ETA):
+        self.events.append(("buildETAUpdate", build, ETA))
+        self.announce()
+    def stepStarted(self, build, step):
+        self.events.append(("stepStarted", build, step))
+        self.announce()
+        if 0 and "eta" in self.mode:
+            print "TIMES", step.getTimes()
+            print "ETA", step.getETA()
+            print "EXP", step.getExpectations()
+        if "step" in self.mode:
+            return self
+    def stepETAUpdate(self, build, step, ETA, expectations):
+        self.events.append(("stepETAUpdate", build, step, ETA, expectations))
+        self.announce()
+    def logStarted(self, build, step, log):
+        self.events.append(("logStarted", build, step, log))
+        self.announce()
+    def logFinished(self, build, step, log):
+        self.events.append(("logFinished", build, step, log))
+        self.announce()
+    def stepFinished(self, build, step, results):
+        self.events.append(("stepFinished", build, step, results))
+        if 0 and "eta" in self.mode:
+            print "post-EXP", step.getExpectations()
+        self.announce()
+    def buildFinished(self, name, build, results):
+        self.events.append(("buildFinished", name, build, results))
+        self.announce()
+    def builderRemoved(self, name):
+        self.events.append(("builderRemoved", name))
+        self.announce()
+
+class Subscription(RunMixin, unittest.TestCase):
+    # verify that StatusTargets can subscribe/unsubscribe properly
+
+    def testSlave(self):
+        m = self.master
+        s = m.getStatus()
+        self.t1 = t1 = STarget(["builder"])
+        #t1.debug = True; print
+        s.subscribe(t1)
+        self.failUnlessEqual(len(t1.events), 0)
+
+        self.t3 = t3 = STarget(["builder", "build", "step"])
+        s.subscribe(t3)
+
+        m.loadConfig(config_2)
+        m.readConfig = True
+        m.startService()
+
+        self.failUnlessEqual(len(t1.events), 4)
+        self.failUnlessEqual(t1.events[0][0:2], ("builderAdded", "dummy"))
+        self.failUnlessEqual(t1.events[1],
+                             ("builderChangedState", "dummy", "offline"))
+        self.failUnlessEqual(t1.events[2][0:2], ("builderAdded", "testdummy"))
+        self.failUnlessEqual(t1.events[3],
+                             ("builderChangedState", "testdummy", "offline"))
+        t1.events = []
+
+        self.failUnlessEqual(s.getBuilderNames(), ["dummy", "testdummy"])
+        self.failUnlessEqual(s.getBuilderNames(categories=['test']),
+                             ["testdummy"])
+        self.s1 = s1 = s.getBuilder("dummy")
+        self.failUnlessEqual(s1.getName(), "dummy")
+        self.failUnlessEqual(s1.getState(), ("offline", []))
+        self.failUnlessEqual(s1.getCurrentBuilds(), [])
+        self.failUnlessEqual(s1.getLastFinishedBuild(), None)
+        self.failUnlessEqual(s1.getBuild(-1), None)
+        #self.failUnlessEqual(s1.getEvent(-1), foo("created"))
+
+        # status targets should, upon being subscribed, immediately get a
+        # list of all current builders matching their category
+        self.t2 = t2 = STarget([])
+        s.subscribe(t2)
+        self.failUnlessEqual(len(t2.events), 2)
+        self.failUnlessEqual(t2.events[0][0:2], ("builderAdded", "dummy"))
+        self.failUnlessEqual(t2.events[1][0:2], ("builderAdded", "testdummy"))
+
+        d = self.connectSlave(builders=["dummy", "testdummy"])
+        d.addCallback(self._testSlave_1, t1)
+        return maybeWait(d)
+
+    def _testSlave_1(self, res, t1):
+        self.failUnlessEqual(len(t1.events), 2)
+        self.failUnlessEqual(t1.events[0],
+                             ("builderChangedState", "dummy", "idle"))
+        self.failUnlessEqual(t1.events[1],
+                             ("builderChangedState", "testdummy", "idle"))
+        t1.events = []
+
+        c = interfaces.IControl(self.master)
+        req = BuildRequest("forced build for testing", SourceStamp())
+        c.getBuilder("dummy").requestBuild(req)
+        d = req.waitUntilFinished()
+        d2 = self.master.botmaster.waitUntilBuilderIdle("dummy")
+        dl = defer.DeferredList([d, d2])
+        dl.addCallback(self._testSlave_2)
+        return dl
+
+    def _testSlave_2(self, res):
+        # t1 subscribes to builds, but not anything lower-level
+        ev = self.t1.events
+        self.failUnlessEqual(len(ev), 4)
+        self.failUnlessEqual(ev[0][0:3],
+                             ("builderChangedState", "dummy", "building"))
+        self.failUnlessEqual(ev[1][0], "buildStarted")
+        self.failUnlessEqual(ev[2][0:2]+ev[2][3:4],
+                             ("buildFinished", "dummy", builder.SUCCESS))
+        self.failUnlessEqual(ev[3][0:3],
+                             ("builderChangedState", "dummy", "idle"))
+
+        self.failUnlessEqual([ev[0] for ev in self.t3.events],
+                             ["builderAdded",
+                              "builderChangedState", # offline
+                              "builderAdded",
+                              "builderChangedState", # idle
+                              "builderChangedState", # offline
+                              "builderChangedState", # idle
+                              "builderChangedState", # building
+                              "buildStarted",
+                              "stepStarted", "stepETAUpdate", "stepFinished",
+                              "stepStarted", "stepETAUpdate",
+                              "logStarted", "logFinished", "stepFinished",
+                              "buildFinished",
+                              "builderChangedState", # idle
+                              ])
+
+        b = self.s1.getLastFinishedBuild()
+        self.failUnless(b)
+        self.failUnlessEqual(b.getBuilder().getName(), "dummy")
+        self.failUnlessEqual(b.getNumber(), 0)
+        self.failUnlessEqual(b.getSourceStamp(), (None, None, None))
+        self.failUnlessEqual(b.getReason(), "forced build for testing")
+        self.failUnlessEqual(b.getChanges(), [])
+        self.failUnlessEqual(b.getResponsibleUsers(), [])
+        self.failUnless(b.isFinished())
+        self.failUnlessEqual(b.getText(), ['build', 'successful'])
+        self.failUnlessEqual(b.getColor(), "green")
+        self.failUnlessEqual(b.getResults(), builder.SUCCESS)
+
+        steps = b.getSteps()
+        self.failUnlessEqual(len(steps), 2)
+
+        eta = 0
+        st1 = steps[0]
+        self.failUnlessEqual(st1.getName(), "dummy")
+        self.failUnless(st1.isFinished())
+        self.failUnlessEqual(st1.getText(), ["delay", "1 secs"])
+        start,finish = st1.getTimes()
+        self.failUnless(0.5 < (finish-start) < 10)
+        self.failUnlessEqual(st1.getExpectations(), [])
+        self.failUnlessEqual(st1.getLogs(), [])
+        eta += finish-start
+
+        st2 = steps[1]
+        self.failUnlessEqual(st2.getName(), "remote dummy")
+        self.failUnless(st2.isFinished())
+        self.failUnlessEqual(st2.getText(),
+                             ["remote", "delay", "2 secs"])
+        start,finish = st2.getTimes()
+        self.failUnless(1.5 < (finish-start) < 10)
+        eta += finish-start
+        self.failUnlessEqual(st2.getExpectations(), [('output', 38, None)])
+        logs = st2.getLogs()
+        self.failUnlessEqual(len(logs), 1)
+        self.failUnlessEqual(logs[0].getName(), "log")
+        self.failUnlessEqual(logs[0].getText(), "data")
+
+        self.eta = eta
+        # now we run it a second time, and we should have an ETA
+
+        self.t4 = t4 = STarget(["builder", "build", "eta"])
+        self.master.getStatus().subscribe(t4)
+        c = interfaces.IControl(self.master)
+        req = BuildRequest("forced build for testing", SourceStamp())
+        c.getBuilder("dummy").requestBuild(req)
+        d = req.waitUntilFinished()
+        d2 = self.master.botmaster.waitUntilBuilderIdle("dummy")
+        dl = defer.DeferredList([d, d2])
+        dl.addCallback(self._testSlave_3)
+        return dl
+
+    def _testSlave_3(self, res):
+        t4 = self.t4
+        eta = self.eta
+        self.failUnless(eta-1 < t4.eta_build < eta+1, # should be 3 seconds
+                        "t4.eta_build was %g, not in (%g,%g)"
+                        % (t4.eta_build, eta-1, eta+1))
+    
+
 class Client(unittest.TestCase):
     def testAdaptation(self):
         b = builder.BuilderStatus("bname")





More information about the Commits mailing list