[Buildbot-commits] buildbot/buildbot/test test_run.py, 1.40, 1.41 test_slaves.py, 1.4, 1.5
Brian Warner
warner at users.sourceforge.net
Fri Nov 24 07:16:38 UTC 2006
Update of /cvsroot/buildbot/buildbot/buildbot/test
In directory sc8-pr-cvs3.sourceforge.net:/tmp/cvs-serv32609/buildbot/test
Modified Files:
test_run.py test_slaves.py
Log Message:
[project @ reconfig no longer interrupts builds, nor does it disconnect/reconnect slaves]
Original author: warner at lothar.com
Date: 2006-11-23 21:32:36
Index: test_run.py
===================================================================
RCS file: /cvsroot/buildbot/buildbot/buildbot/test/test_run.py,v
retrieving revision 1.40
retrieving revision 1.41
diff -u -d -r1.40 -r1.41
--- test_run.py 15 Sep 2006 14:47:41 -0000 1.40
+++ test_run.py 24 Nov 2006 07:16:35 -0000 1.41
@@ -497,10 +497,10 @@
def _testChangeBuilddir_2(self, res):
bot = self.bot
- # this causes the builder to be replaced
- self.failIfIdentical(self.builder, bot.builders.get("dummy"))
+ # this does NOT cause the builder to be replaced
builder = bot.builders.get("dummy")
self.failUnless(builder)
+ self.failUnlessIdentical(self.builder, builder)
# the basedir should be updated
self.failUnlessEqual(builder.builddir, "dummy2")
self.failUnlessEqual(builder.basedir,
Index: test_slaves.py
===================================================================
RCS file: /cvsroot/buildbot/buildbot/buildbot/test/test_slaves.py,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -d -r1.4 -r1.5
--- test_slaves.py 15 Sep 2006 14:47:41 -0000 1.4
+++ test_slaves.py 24 Nov 2006 07:16:35 -0000 1.5
@@ -3,11 +3,13 @@
from twisted.trial import unittest
from buildbot.twcompat import maybeWait
from twisted.internet import defer, reactor
+from twisted.python import log
from buildbot.test.runutils import RunMixin
from buildbot.sourcestamp import SourceStamp
from buildbot.process.base import BuildRequest
from buildbot.status.builder import SUCCESS
+from buildbot.slave import bot
config_1 = """
from buildbot.process import factory
@@ -21,12 +23,22 @@
c['slavePortnum'] = 0
c['schedulers'] = []
-f = factory.BuildFactory([s(dummy.RemoteDummy, timeout=1)])
+f1 = factory.BuildFactory([s(dummy.RemoteDummy, timeout=1)])
+f2 = factory.BuildFactory([s(dummy.RemoteDummy, timeout=2)])
c['builders'] = [
{'name': 'b1', 'slavenames': ['bot1','bot2','bot3'],
- 'builddir': 'b1', 'factory': f},
+ 'builddir': 'b1', 'factory': f1},
+ ]
+"""
+
+config_2 = config_1 + """
+
+c['builders'] = [
+ {'name': 'b1', 'slavenames': ['bot1','bot2','bot3'],
+ 'builddir': 'b1', 'factory': f2},
]
+
"""
class Slave(RunMixin, unittest.TestCase):
@@ -167,6 +179,198 @@
def _testDontClaimPingingSlave_3(self, res):
self.failUnlessEqual(res.getSlavename(), "bot1")
+config_3 = """
+from buildbot.process import factory
+from buildbot.steps import dummy
+s = factory.s
+
+BuildmasterConfig = c = {}
+c['bots'] = [('bot1', 'sekrit')]
+c['sources'] = []
+c['schedulers'] = []
+c['slavePortnum'] = 0
+c['schedulers'] = []
+
+f1 = factory.BuildFactory([s(dummy.Wait, handle='one')])
+f2 = factory.BuildFactory([s(dummy.Wait, handle='two')])
+f3 = factory.BuildFactory([s(dummy.Wait, handle='three')])
+
+c['builders'] = [
+ {'name': 'b1', 'slavenames': ['bot1'],
+ 'builddir': 'b1', 'factory': f1},
+ ]
+"""
+
+config_4 = config_3 + """
+c['builders'] = [
+ {'name': 'b1', 'slavenames': ['bot1'],
+ 'builddir': 'b1', 'factory': f2},
+ ]
+"""
+
+config_5 = config_3 + """
+c['builders'] = [
+ {'name': 'b1', 'slavenames': ['bot1'],
+ 'builddir': 'b1', 'factory': f3},
+ ]
+"""
+
+from buildbot.slave.commands import waitCommandRegistry
+
+class Reconfig(RunMixin, unittest.TestCase):
+
+ def setUp(self):
+ RunMixin.setUp(self)
+ self.master.loadConfig(config_3)
+ self.master.startService()
+ d = self.connectSlave(["b1"])
+ return maybeWait(d)
+
+ def _one_started(self):
+ log.msg("testReconfig._one_started")
+ self.build1_started = True
+ self.d1.callback(None)
+ return self.d2
+
+ def _two_started(self):
+ log.msg("testReconfig._two_started")
+ self.build2_started = True
+ self.d3.callback(None)
+ return self.d4
+
+ def _three_started(self):
+ log.msg("testReconfig._three_started")
+ self.build3_started = True
+ self.d5.callback(None)
+ return self.d6
+
+ def testReconfig(self):
+ # reconfiguring a Builder should not interrupt any running Builds. No
+ # queued BuildRequests should be lost. The next Build started should
+ # use the new process.
+ slave1 = self.slaves['bot1']
+ bot1 = slave1.getServiceNamed('bot')
+ sb1 = bot1.builders['b1']
+ self.failUnless(isinstance(sb1, bot.SlaveBuilder))
+ self.failUnless(sb1.running)
+ b1 = self.master.botmaster.builders['b1']
+ self.orig_b1 = b1
+
+ self.d1 = d1 = defer.Deferred()
+ self.d2 = d2 = defer.Deferred()
+ self.d3, self.d4 = defer.Deferred(), defer.Deferred()
+ self.d5, self.d6 = defer.Deferred(), defer.Deferred()
+ self.build1_started = False
+ self.build2_started = False
+ self.build3_started = False
+ waitCommandRegistry[("one","build1")] = self._one_started
+ waitCommandRegistry[("two","build2")] = self._two_started
+ waitCommandRegistry[("three","build3")] = self._three_started
+
+ # use different branches to make sure these cannot be merged
+ br1 = BuildRequest("build1", SourceStamp(branch="1"))
+ b1.submitBuildRequest(br1)
+ br2 = BuildRequest("build2", SourceStamp(branch="2"))
+ b1.submitBuildRequest(br2)
+ br3 = BuildRequest("build3", SourceStamp(branch="3"))
+ b1.submitBuildRequest(br3)
+ self.requests = (br1, br2, br3)
+ # all three are now in the queue
+
+ # wait until the first one has started
+ d1.addCallback(self._testReconfig_2)
+ return d1
+
+ def _testReconfig_2(self, res):
+ log.msg("_testReconfig_2")
+ # confirm that it is building
+ brs = self.requests[0].status.getBuilds()
+ self.failUnlessEqual(len(brs), 1)
+ self.build1 = brs[0]
+ self.failUnlessEqual(self.build1.getCurrentStep().getName(), "wait")
+ # br1 is building, br2 and br3 are in the queue (in that order). Now
+ # we reconfigure the Builder.
+ self.failUnless(self.build1_started)
+ d = self.master.loadConfig(config_4)
+ d.addCallback(self._testReconfig_3)
+ return d
+
+ def _testReconfig_3(self, res):
+ log.msg("_testReconfig_3")
+ # now check to see that br1 is still building, and that br2 and br3
+ # are in the queue of the new builder
+ b1 = self.master.botmaster.builders['b1']
+ self.failIfIdentical(b1, self.orig_b1)
+ self.failIf(self.build1.isFinished())
+ self.failUnlessEqual(self.build1.getCurrentStep().getName(), "wait")
+ self.failUnlessEqual(len(b1.buildable), 2)
+ self.failUnless(self.requests[1] in b1.buildable)
+ self.failUnless(self.requests[2] in b1.buildable)
+
+ # allow br1 to finish, and make sure its status is delivered normally
+ d = self.requests[0].waitUntilFinished()
+ d.addCallback(self._testReconfig_4)
+ self.d2.callback(None)
+ return d
+
+ def _testReconfig_4(self, bs):
+ log.msg("_testReconfig_4")
+ self.failUnlessEqual(bs.getReason(), "build1")
+ self.failUnless(bs.isFinished())
+ self.failUnlessEqual(bs.getResults(), SUCCESS)
+
+ # at this point, the first build has finished, and there is a pending
+ # call to start the second build. Once that pending call fires, there
+ # is a network roundtrip before the 'wait' RemoteCommand is delivered
+ # to the slave. We need to wait for both events to happen before we
+ # can check to make sure it is using the correct process. Just wait a
+ # full second.
+ d = defer.Deferred()
+ d.addCallback(self._testReconfig_5)
+ reactor.callLater(1, d.callback, None)
+ return d
+
+ def _testReconfig_5(self, res):
+ log.msg("_testReconfig_5")
+ # at this point the next build ought to be running
+ b1 = self.master.botmaster.builders['b1']
+ self.failUnlessEqual(len(b1.buildable), 1)
+ self.failUnless(self.requests[2] in b1.buildable)
+ self.failUnlessEqual(len(b1.building), 1)
+ # and it ought to be using the new process
+ self.failUnless(self.build2_started)
+
+ # now, while the second build is running, change the config multiple
+ # times.
+
+ d = self.master.loadConfig(config_3)
+ d.addCallback(lambda res: self.master.loadConfig(config_4))
+ d.addCallback(lambda res: self.master.loadConfig(config_5))
+ def _done(res):
+ # then once that's done, allow the second build to finish and
+ # wait for it to complete
+ da = self.requests[1].waitUntilFinished()
+ self.d4.callback(None)
+ return da
+ d.addCallback(_done)
+ def _done2(res):
+ # and once *that*'s done, wait another second to let the third
+ # build start
+ db = defer.Deferred()
+ reactor.callLater(1, db.callback, None)
+ return db
+ d.addCallback(_done2)
+ d.addCallback(self._testReconfig_6)
+ return d
+
+ def _testReconfig_6(self, res):
+ log.msg("_testReconfig_6")
+ # now check to see that the third build is running
+ self.failUnless(self.build3_started)
+
+ # we're done
+
+
class Slave2(RunMixin, unittest.TestCase):
More information about the Commits
mailing list