diff options
Diffstat (limited to 'buildbot/buildbot/test/test_dependencies.py')
-rw-r--r-- | buildbot/buildbot/test/test_dependencies.py | 166 |
1 files changed, 166 insertions, 0 deletions
diff --git a/buildbot/buildbot/test/test_dependencies.py b/buildbot/buildbot/test/test_dependencies.py new file mode 100644 index 0000000..624efc4 --- /dev/null +++ b/buildbot/buildbot/test/test_dependencies.py @@ -0,0 +1,166 @@ +# -*- test-case-name: buildbot.test.test_dependencies -*- + +from twisted.trial import unittest + +from twisted.internet import reactor, defer + +from buildbot.test.runutils import RunMixin +from buildbot.status import base + +config_1 = """ +from buildbot import scheduler +from buildbot.process import factory +from buildbot.steps import dummy +from buildbot.buildslave import BuildSlave +s = factory.s +from buildbot.test.test_locks import LockStep + +BuildmasterConfig = c = {} +c['slaves'] = [BuildSlave('bot1', 'sekrit'), BuildSlave('bot2', 'sekrit')] +c['schedulers'] = [] +c['slavePortnum'] = 0 + +# upstream1 (fastfail, slowpass) +# -> downstream2 (b3, b4) +# upstream3 (slowfail, slowpass) +# -> downstream4 (b3, b4) +# -> downstream5 (b5) + +s1 = scheduler.Scheduler('upstream1', None, 10, ['slowpass', 'fastfail']) +s2 = scheduler.Dependent('downstream2', s1, ['b3', 'b4']) +s3 = scheduler.Scheduler('upstream3', None, 10, ['fastpass', 'slowpass']) +s4 = scheduler.Dependent('downstream4', s3, ['b3', 'b4']) +s5 = scheduler.Dependent('downstream5', s4, ['b5']) +c['schedulers'] = [s1, s2, s3, s4, s5] + +f_fastpass = factory.BuildFactory([s(dummy.Dummy, timeout=1)]) +f_slowpass = factory.BuildFactory([s(dummy.Dummy, timeout=2)]) +f_fastfail = factory.BuildFactory([s(dummy.FailingDummy, timeout=1)]) + +def builder(name, f): + d = {'name': name, 'slavename': 'bot1', 'builddir': name, 'factory': f} + return d + +c['builders'] = [builder('slowpass', f_slowpass), + builder('fastfail', f_fastfail), + builder('fastpass', f_fastpass), + builder('b3', f_fastpass), + builder('b4', f_fastpass), + builder('b5', f_fastpass), + ] +""" + +class Logger(base.StatusReceiverMultiService): + def __init__(self, master): + base.StatusReceiverMultiService.__init__(self) + self.builds = [] + for bn in master.status.getBuilderNames(): + master.status.getBuilder(bn).subscribe(self) + + def buildStarted(self, builderName, build): + self.builds.append(builderName) + +class Dependencies(RunMixin, unittest.TestCase): + def setUp(self): + RunMixin.setUp(self) + self.master.loadConfig(config_1) + self.master.startService() + d = self.connectSlave(["slowpass", "fastfail", "fastpass", + "b3", "b4", "b5"]) + return d + + def findScheduler(self, name): + for s in self.master.allSchedulers(): + if s.name == name: + return s + raise KeyError("No Scheduler named '%s'" % name) + + def testParse(self): + self.master.loadConfig(config_1) + # that's it, just make sure this config file is loaded successfully + + def testRun_Fail(self): + # add an extra status target to make pay attention to which builds + # start and which don't. + self.logger = Logger(self.master) + + # kick off upstream1, which has a failing Builder and thus will not + # trigger downstream3 + s = self.findScheduler("upstream1") + # this is an internal function of the Scheduler class + s.fireTimer() # fires a build + # t=0: two builders start: 'slowpass' and 'fastfail' + # t=1: builder 'fastfail' finishes + # t=2: builder 'slowpass' finishes + d = defer.Deferred() + d.addCallback(self._testRun_Fail_1) + reactor.callLater(5, d.callback, None) + return d + + def _testRun_Fail_1(self, res): + # 'slowpass' and 'fastfail' should have run one build each + b = self.status.getBuilder('slowpass').getLastFinishedBuild() + self.failUnless(b) + self.failUnlessEqual(b.getNumber(), 0) + b = self.status.getBuilder('fastfail').getLastFinishedBuild() + self.failUnless(b) + self.failUnlessEqual(b.getNumber(), 0) + + # none of the other builders should have run + self.failIf(self.status.getBuilder('b3').getLastFinishedBuild()) + self.failIf(self.status.getBuilder('b4').getLastFinishedBuild()) + self.failIf(self.status.getBuilder('b5').getLastFinishedBuild()) + + # in fact, none of them should have even started + self.failUnlessEqual(len(self.logger.builds), 2) + self.failUnless("slowpass" in self.logger.builds) + self.failUnless("fastfail" in self.logger.builds) + self.failIf("b3" in self.logger.builds) + self.failIf("b4" in self.logger.builds) + self.failIf("b5" in self.logger.builds) + + def testRun_Pass(self): + # kick off upstream3, which will fire downstream4 and then + # downstream5 + s = self.findScheduler("upstream3") + # this is an internal function of the Scheduler class + s.fireTimer() # fires a build + # t=0: slowpass and fastpass start + # t=1: builder 'fastpass' finishes + # t=2: builder 'slowpass' finishes + # scheduler 'downstream4' fires + # builds b3 and b4 are started + # t=3: builds b3 and b4 finish + # scheduler 'downstream5' fires + # build b5 is started + # t=4: build b5 is finished + d = defer.Deferred() + d.addCallback(self._testRun_Pass_1) + reactor.callLater(5, d.callback, None) + return d + + def _testRun_Pass_1(self, res): + # 'fastpass' and 'slowpass' should have run one build each + b = self.status.getBuilder('fastpass').getLastFinishedBuild() + self.failUnless(b) + self.failUnlessEqual(b.getNumber(), 0) + + b = self.status.getBuilder('slowpass').getLastFinishedBuild() + self.failUnless(b) + self.failUnlessEqual(b.getNumber(), 0) + + self.failIf(self.status.getBuilder('fastfail').getLastFinishedBuild()) + + b = self.status.getBuilder('b3').getLastFinishedBuild() + self.failUnless(b) + self.failUnlessEqual(b.getNumber(), 0) + + b = self.status.getBuilder('b4').getLastFinishedBuild() + self.failUnless(b) + self.failUnlessEqual(b.getNumber(), 0) + + b = self.status.getBuilder('b4').getLastFinishedBuild() + self.failUnless(b) + self.failUnlessEqual(b.getNumber(), 0) + + |