[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