1 # -*- test-case-name: buildbot.test.test_dependencies -*-
3 from twisted
.trial
import unittest
5 from twisted
.internet
import reactor
, defer
7 from buildbot
.test
.runutils
import RunMixin
8 from buildbot
.status
import base
11 from buildbot import scheduler
12 from buildbot.process import factory
13 from buildbot.steps import dummy
14 from buildbot.slave import BuildSlave
16 from buildbot.test.test_locks import LockStep
18 BuildmasterConfig = c = {}
19 c['slaves'] = [BuildSlave('bot1', 'sekrit'), BuildSlave('bot2', 'sekrit')]
24 # upstream1 (fastfail, slowpass)
25 # -> downstream2 (b3, b4)
26 # upstream3 (slowfail, slowpass)
27 # -> downstream4 (b3, b4)
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]
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)])
42 d = {'name': name, 'slavename': 'bot1', 'builddir': name, 'factory': f}
45 c['builders'] = [builder('slowpass', f_slowpass),
46 builder('fastfail', f_fastfail),
47 builder('fastpass', f_fastpass),
48 builder('b3', f_fastpass),
49 builder('b4', f_fastpass),
50 builder('b5', f_fastpass),
54 class Logger(base
.StatusReceiverMultiService
):
55 def __init__(self
, master
):
56 base
.StatusReceiverMultiService
.__init
__(self
)
58 for bn
in master
.status
.getBuilderNames():
59 master
.status
.getBuilder(bn
).subscribe(self
)
61 def buildStarted(self
, builderName
, build
):
62 self
.builds
.append(builderName
)
64 class Dependencies(RunMixin
, unittest
.TestCase
):
67 self
.master
.loadConfig(config_1
)
68 self
.master
.startService()
69 d
= self
.connectSlave(["slowpass", "fastfail", "fastpass",
73 def findScheduler(self
, name
):
74 for s
in self
.master
.allSchedulers():
77 raise KeyError("No Scheduler named '%s'" % name
)
80 self
.master
.loadConfig(config_1
)
81 # that's it, just make sure this config file is loaded successfully
83 def testRun_Fail(self
):
84 # add an extra status target to make pay attention to which builds
85 # start and which don't.
86 self
.logger
= Logger(self
.master
)
88 # kick off upstream1, which has a failing Builder and thus will not
90 s
= self
.findScheduler("upstream1")
91 # this is an internal function of the Scheduler class
92 s
.fireTimer() # fires a build
93 # t=0: two builders start: 'slowpass' and 'fastfail'
94 # t=1: builder 'fastfail' finishes
95 # t=2: builder 'slowpass' finishes
97 d
.addCallback(self
._testRun
_Fail
_1)
98 reactor
.callLater(5, d
.callback
, None)
101 def _testRun_Fail_1(self
, res
):
102 # 'slowpass' and 'fastfail' should have run one build each
103 b
= self
.status
.getBuilder('slowpass').getLastFinishedBuild()
105 self
.failUnlessEqual(b
.getNumber(), 0)
106 b
= self
.status
.getBuilder('fastfail').getLastFinishedBuild()
108 self
.failUnlessEqual(b
.getNumber(), 0)
110 # none of the other builders should have run
111 self
.failIf(self
.status
.getBuilder('b3').getLastFinishedBuild())
112 self
.failIf(self
.status
.getBuilder('b4').getLastFinishedBuild())
113 self
.failIf(self
.status
.getBuilder('b5').getLastFinishedBuild())
115 # in fact, none of them should have even started
116 self
.failUnlessEqual(len(self
.logger
.builds
), 2)
117 self
.failUnless("slowpass" in self
.logger
.builds
)
118 self
.failUnless("fastfail" in self
.logger
.builds
)
119 self
.failIf("b3" in self
.logger
.builds
)
120 self
.failIf("b4" in self
.logger
.builds
)
121 self
.failIf("b5" in self
.logger
.builds
)
123 def testRun_Pass(self
):
124 # kick off upstream3, which will fire downstream4 and then
126 s
= self
.findScheduler("upstream3")
127 # this is an internal function of the Scheduler class
128 s
.fireTimer() # fires a build
129 # t=0: slowpass and fastpass start
130 # t=1: builder 'fastpass' finishes
131 # t=2: builder 'slowpass' finishes
132 # scheduler 'downstream4' fires
133 # builds b3 and b4 are started
134 # t=3: builds b3 and b4 finish
135 # scheduler 'downstream5' fires
136 # build b5 is started
137 # t=4: build b5 is finished
139 d
.addCallback(self
._testRun
_Pass
_1)
140 reactor
.callLater(5, d
.callback
, None)
143 def _testRun_Pass_1(self
, res
):
144 # 'fastpass' and 'slowpass' should have run one build each
145 b
= self
.status
.getBuilder('fastpass').getLastFinishedBuild()
147 self
.failUnlessEqual(b
.getNumber(), 0)
149 b
= self
.status
.getBuilder('slowpass').getLastFinishedBuild()
151 self
.failUnlessEqual(b
.getNumber(), 0)
153 self
.failIf(self
.status
.getBuilder('fastfail').getLastFinishedBuild())
155 b
= self
.status
.getBuilder('b3').getLastFinishedBuild()
157 self
.failUnlessEqual(b
.getNumber(), 0)
159 b
= self
.status
.getBuilder('b4').getLastFinishedBuild()
161 self
.failUnlessEqual(b
.getNumber(), 0)
163 b
= self
.status
.getBuilder('b4').getLastFinishedBuild()
165 self
.failUnlessEqual(b
.getNumber(), 0)