| OLD | NEW |
| (Empty) |
| 1 # -*- test-case-name: buildbot.test.test_dependencies -*- | |
| 2 | |
| 3 from twisted.trial import unittest | |
| 4 | |
| 5 from twisted.internet import reactor, defer | |
| 6 | |
| 7 from buildbot.test.runutils import RunMixin | |
| 8 from buildbot.status import base | |
| 9 | |
| 10 config_1 = """ | |
| 11 from buildbot import scheduler | |
| 12 from buildbot.process import factory | |
| 13 from buildbot.steps import dummy | |
| 14 from buildbot.buildslave import BuildSlave | |
| 15 s = factory.s | |
| 16 from buildbot.test.test_locks import LockStep | |
| 17 from buildbot.config import BuilderConfig | |
| 18 | |
| 19 BuildmasterConfig = c = {} | |
| 20 c['slaves'] = [BuildSlave('bot1', 'sekrit'), BuildSlave('bot2', 'sekrit')] | |
| 21 c['schedulers'] = [] | |
| 22 c['slavePortnum'] = 0 | |
| 23 | |
| 24 # upstream1 (fastfail, slowpass) | |
| 25 # -> downstream2 (b3, b4) | |
| 26 # upstream3 (slowfail, slowpass) | |
| 27 # -> downstream4 (b3, b4) | |
| 28 # -> downstream5 (b5) | |
| 29 | |
| 30 s1 = scheduler.Scheduler('upstream1', None, 10, ['slowpass', 'fastfail']) | |
| 31 s2 = scheduler.Dependent('downstream2', s1, ['b3', 'b4']) | |
| 32 s3 = scheduler.Scheduler('upstream3', None, 10, ['fastpass', 'slowpass']) | |
| 33 s4 = scheduler.Dependent('downstream4', s3, ['b3', 'b4']) | |
| 34 s5 = scheduler.Dependent('downstream5', s4, ['b5']) | |
| 35 c['schedulers'] = [s1, s2, s3, s4, s5] | |
| 36 | |
| 37 f_fastpass = factory.BuildFactory([s(dummy.Dummy, timeout=1)]) | |
| 38 f_slowpass = factory.BuildFactory([s(dummy.Dummy, timeout=2)]) | |
| 39 f_fastfail = factory.BuildFactory([s(dummy.FailingDummy, timeout=1)]) | |
| 40 | |
| 41 def builder(name, f): | |
| 42 return BuilderConfig( | |
| 43 name=name, | |
| 44 slavename='bot1', | |
| 45 factory=f) | |
| 46 | |
| 47 c['builders'] = [builder('slowpass', f_slowpass), | |
| 48 builder('fastfail', f_fastfail), | |
| 49 builder('fastpass', f_fastpass), | |
| 50 builder('b3', f_fastpass), | |
| 51 builder('b4', f_fastpass), | |
| 52 builder('b5', f_fastpass), | |
| 53 ] | |
| 54 """ | |
| 55 | |
| 56 class Logger(base.StatusReceiverMultiService): | |
| 57 def __init__(self, master): | |
| 58 base.StatusReceiverMultiService.__init__(self) | |
| 59 self.builds = [] | |
| 60 for bn in master.status.getBuilderNames(): | |
| 61 master.status.getBuilder(bn).subscribe(self) | |
| 62 | |
| 63 def buildStarted(self, builderName, build): | |
| 64 self.builds.append(builderName) | |
| 65 | |
| 66 class Dependencies(RunMixin, unittest.TestCase): | |
| 67 def setUp(self): | |
| 68 RunMixin.setUp(self) | |
| 69 self.master.loadConfig(config_1) | |
| 70 self.master.startService() | |
| 71 d = self.connectSlave(["slowpass", "fastfail", "fastpass", | |
| 72 "b3", "b4", "b5"]) | |
| 73 return d | |
| 74 | |
| 75 def findScheduler(self, name): | |
| 76 for s in self.master.allSchedulers(): | |
| 77 if s.name == name: | |
| 78 return s | |
| 79 raise KeyError("No Scheduler named '%s'" % name) | |
| 80 | |
| 81 def testParse(self): | |
| 82 self.master.loadConfig(config_1) | |
| 83 # that's it, just make sure this config file is loaded successfully | |
| 84 | |
| 85 def testRun_Fail(self): | |
| 86 # add an extra status target to make pay attention to which builds | |
| 87 # start and which don't. | |
| 88 self.logger = Logger(self.master) | |
| 89 | |
| 90 # kick off upstream1, which has a failing Builder and thus will not | |
| 91 # trigger downstream3 | |
| 92 s = self.findScheduler("upstream1") | |
| 93 # this is an internal function of the Scheduler class | |
| 94 s.fireTimer() # fires a build | |
| 95 # t=0: two builders start: 'slowpass' and 'fastfail' | |
| 96 # t=1: builder 'fastfail' finishes | |
| 97 # t=2: builder 'slowpass' finishes | |
| 98 d = defer.Deferred() | |
| 99 d.addCallback(self._testRun_Fail_1) | |
| 100 reactor.callLater(5, d.callback, None) | |
| 101 return d | |
| 102 | |
| 103 def _testRun_Fail_1(self, res): | |
| 104 # 'slowpass' and 'fastfail' should have run one build each | |
| 105 b = self.status.getBuilder('slowpass').getLastFinishedBuild() | |
| 106 self.failUnless(b) | |
| 107 self.failUnlessEqual(b.getNumber(), 0) | |
| 108 b = self.status.getBuilder('fastfail').getLastFinishedBuild() | |
| 109 self.failUnless(b) | |
| 110 self.failUnlessEqual(b.getNumber(), 0) | |
| 111 | |
| 112 # none of the other builders should have run | |
| 113 self.failIf(self.status.getBuilder('b3').getLastFinishedBuild()) | |
| 114 self.failIf(self.status.getBuilder('b4').getLastFinishedBuild()) | |
| 115 self.failIf(self.status.getBuilder('b5').getLastFinishedBuild()) | |
| 116 | |
| 117 # in fact, none of them should have even started | |
| 118 self.failUnlessEqual(len(self.logger.builds), 2) | |
| 119 self.failUnless("slowpass" in self.logger.builds) | |
| 120 self.failUnless("fastfail" in self.logger.builds) | |
| 121 self.failIf("b3" in self.logger.builds) | |
| 122 self.failIf("b4" in self.logger.builds) | |
| 123 self.failIf("b5" in self.logger.builds) | |
| 124 | |
| 125 def testRun_Pass(self): | |
| 126 # kick off upstream3, which will fire downstream4 and then | |
| 127 # downstream5 | |
| 128 s = self.findScheduler("upstream3") | |
| 129 # this is an internal function of the Scheduler class | |
| 130 s.fireTimer() # fires a build | |
| 131 # t=0: slowpass and fastpass start | |
| 132 # t=1: builder 'fastpass' finishes | |
| 133 # t=2: builder 'slowpass' finishes | |
| 134 # scheduler 'downstream4' fires | |
| 135 # builds b3 and b4 are started | |
| 136 # t=3: builds b3 and b4 finish | |
| 137 # scheduler 'downstream5' fires | |
| 138 # build b5 is started | |
| 139 # t=4: build b5 is finished | |
| 140 d = defer.Deferred() | |
| 141 d.addCallback(self._testRun_Pass_1) | |
| 142 reactor.callLater(5, d.callback, None) | |
| 143 return d | |
| 144 | |
| 145 def _testRun_Pass_1(self, res): | |
| 146 # 'fastpass' and 'slowpass' should have run one build each | |
| 147 b = self.status.getBuilder('fastpass').getLastFinishedBuild() | |
| 148 self.failUnless(b) | |
| 149 self.failUnlessEqual(b.getNumber(), 0) | |
| 150 | |
| 151 b = self.status.getBuilder('slowpass').getLastFinishedBuild() | |
| 152 self.failUnless(b) | |
| 153 self.failUnlessEqual(b.getNumber(), 0) | |
| 154 | |
| 155 self.failIf(self.status.getBuilder('fastfail').getLastFinishedBuild()) | |
| 156 | |
| 157 b = self.status.getBuilder('b3').getLastFinishedBuild() | |
| 158 self.failUnless(b) | |
| 159 self.failUnlessEqual(b.getNumber(), 0) | |
| 160 | |
| 161 b = self.status.getBuilder('b4').getLastFinishedBuild() | |
| 162 self.failUnless(b) | |
| 163 self.failUnlessEqual(b.getNumber(), 0) | |
| 164 | |
| 165 b = self.status.getBuilder('b4').getLastFinishedBuild() | |
| 166 self.failUnless(b) | |
| 167 self.failUnlessEqual(b.getNumber(), 0) | |
| 168 | |
| 169 | |
| OLD | NEW |