rename c['bots'] to c['slaves'], and use buildbot.slave.BuildSlave instances instead...
[buildbot.git] / buildbot / test / test_dependencies.py
blobda8de5eb4fa0b2fbfa65fe37c1503ae703aac272
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
10 config_1 = """
11 from buildbot import scheduler
12 from buildbot.process import factory
13 from buildbot.steps import dummy
14 from buildbot.slave import BuildSlave
15 s = factory.s
16 from buildbot.test.test_locks import LockStep
18 BuildmasterConfig = c = {}
19 c['slaves'] = [BuildSlave('bot1', 'sekrit'), BuildSlave('bot2', 'sekrit')]
20 c['sources'] = []
21 c['schedulers'] = []
22 c['slavePortnum'] = 0
24 # upstream1 (fastfail, slowpass)
25 # -> downstream2 (b3, b4)
26 # upstream3 (slowfail, slowpass)
27 # -> downstream4 (b3, b4)
28 # -> downstream5 (b5)
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)])
41 def builder(name, f):
42 d = {'name': name, 'slavename': 'bot1', 'builddir': name, 'factory': f}
43 return d
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),
52 """
54 class Logger(base.StatusReceiverMultiService):
55 def __init__(self, master):
56 base.StatusReceiverMultiService.__init__(self)
57 self.builds = []
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):
65 def setUp(self):
66 RunMixin.setUp(self)
67 self.master.loadConfig(config_1)
68 self.master.startService()
69 d = self.connectSlave(["slowpass", "fastfail", "fastpass",
70 "b3", "b4", "b5"])
71 return d
73 def findScheduler(self, name):
74 for s in self.master.allSchedulers():
75 if s.name == name:
76 return s
77 raise KeyError("No Scheduler named '%s'" % name)
79 def testParse(self):
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
89 # trigger downstream3
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
96 d = defer.Deferred()
97 d.addCallback(self._testRun_Fail_1)
98 reactor.callLater(5, d.callback, None)
99 return d
101 def _testRun_Fail_1(self, res):
102 # 'slowpass' and 'fastfail' should have run one build each
103 b = self.status.getBuilder('slowpass').getLastFinishedBuild()
104 self.failUnless(b)
105 self.failUnlessEqual(b.getNumber(), 0)
106 b = self.status.getBuilder('fastfail').getLastFinishedBuild()
107 self.failUnless(b)
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
125 # downstream5
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
138 d = defer.Deferred()
139 d.addCallback(self._testRun_Pass_1)
140 reactor.callLater(5, d.callback, None)
141 return d
143 def _testRun_Pass_1(self, res):
144 # 'fastpass' and 'slowpass' should have run one build each
145 b = self.status.getBuilder('fastpass').getLastFinishedBuild()
146 self.failUnless(b)
147 self.failUnlessEqual(b.getNumber(), 0)
149 b = self.status.getBuilder('slowpass').getLastFinishedBuild()
150 self.failUnless(b)
151 self.failUnlessEqual(b.getNumber(), 0)
153 self.failIf(self.status.getBuilder('fastfail').getLastFinishedBuild())
155 b = self.status.getBuilder('b3').getLastFinishedBuild()
156 self.failUnless(b)
157 self.failUnlessEqual(b.getNumber(), 0)
159 b = self.status.getBuilder('b4').getLastFinishedBuild()
160 self.failUnless(b)
161 self.failUnlessEqual(b.getNumber(), 0)
163 b = self.status.getBuilder('b4').getLastFinishedBuild()
164 self.failUnless(b)
165 self.failUnlessEqual(b.getNumber(), 0)