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 |