[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