14557.2.1
by Gavin Panella
Revert r14552, thus unreverting r14499 and r14459, to bring back read-only transactions in buildmaster. |
1 |
# Copyright 2009-2011 Canonical Ltd. This software is licensed under the
|
8687.15.16
by Karl Fogel
Add the copyright header block to files under lib/lp/buildmaster/. |
2 |
# GNU Affero General Public License version 3 (see the file LICENSE).
|
7813.2.1
by Celso Providelo
re-basing slave-scanner-ng changes. |
3 |
|
4 |
"""Tests for the renovated slave scanner aka BuilddManager."""
|
|
5 |
||
14557.2.1
by Gavin Panella
Revert r14552, thus unreverting r14499 and r14459, to bring back read-only transactions in buildmaster. |
6 |
from collections import namedtuple |
7813.2.15
by Celso Providelo
applying review comments, r=bigjools. |
7 |
import os |
10724.2.3
by Julian Edwards
tests all pass \o/ |
8 |
import signal |
11121.2.3
by Henning Eggers
Added test for logging behavior. |
9 |
import time |
11593.3.120
by Julian Edwards
re-add revno 11801 which was backed out in devel due to test failures resulting from a twisted bug |
10 |
import xmlrpclib |
11403.1.4
by Henning Eggers
Reformatted imports using format-imports script r32. |
11 |
|
14557.2.1
by Gavin Panella
Revert r14552, thus unreverting r14499 and r14459, to bring back read-only transactions in buildmaster. |
12 |
from lpbuildd.tests import BuilddSlaveTestSetup |
11705.2.25
by Jonathan Lange
Easier than I thought. |
13 |
from testtools.deferredruntest import ( |
14 |
assert_fails_with, |
|
15 |
AsynchronousDeferredRunTest, |
|
16 |
)
|
|
11403.1.4
by Henning Eggers
Reformatted imports using format-imports script r32. |
17 |
from twisted.internet import ( |
18 |
defer, |
|
19 |
reactor, |
|
20 |
task, |
|
21 |
)
|
|
14557.2.1
by Gavin Panella
Revert r14552, thus unreverting r14499 and r14459, to bring back read-only transactions in buildmaster. |
22 |
from twisted.internet.task import deferLater |
7856.1.1
by Celso Providelo
Fixing remaining issues with BuilddManager, specially the dispatch-error-handler part. |
23 |
from twisted.python.failure import Failure |
7813.2.1
by Celso Providelo
re-basing slave-scanner-ng changes. |
24 |
from zope.component import getUtility |
8533.1.3
by Celso Providelo
Fixing the slip on buildd-manager that blocks the dispatcher on jobs with missing chroots. |
25 |
from zope.security.proxy import removeSecurityProxy |
7813.2.1
by Celso Providelo
re-basing slave-scanner-ng changes. |
26 |
|
11458.1.1
by Jelmer Vernooij
Move enums of buildmaster. |
27 |
from lp.buildmaster.enums import BuildStatus |
7675.509.139
by William Grant
Move (I)BuildQueue(Set) to lp.buildmaster. |
28 |
from lp.buildmaster.interfaces.builder import IBuilderSet |
29 |
from lp.buildmaster.interfaces.buildqueue import IBuildQueueSet |
|
8426.7.3
by Julian Edwards
Migrate buildmaster to the lp tree. |
30 |
from lp.buildmaster.manager import ( |
11593.3.120
by Julian Edwards
re-add revno 11801 which was backed out in devel due to test failures resulting from a twisted bug |
31 |
assessFailureCounts, |
11403.1.4
by Henning Eggers
Reformatted imports using format-imports script r32. |
32 |
BuilddManager, |
33 |
NewBuildersScanner, |
|
34 |
SlaveScanner, |
|
35 |
)
|
|
11593.3.120
by Julian Edwards
re-add revno 11801 which was backed out in devel due to test failures resulting from a twisted bug |
36 |
from lp.buildmaster.model.builder import Builder |
14557.2.1
by Gavin Panella
Revert r14552, thus unreverting r14499 and r14459, to bring back read-only transactions in buildmaster. |
37 |
from lp.buildmaster.model.packagebuild import PackageBuild |
14542.2.27
by Gavin Panella
Use BuilddManagerTestFixture in TestSlaveScannerScan. |
38 |
from lp.buildmaster.testing import BuilddManagerTestFixture |
8426.7.9
by Julian Edwards
Fix bad import in a test change merged from trunk. |
39 |
from lp.buildmaster.tests.harness import BuilddManagerTestSetup |
11593.3.120
by Julian Edwards
re-add revno 11801 which was backed out in devel due to test failures resulting from a twisted bug |
40 |
from lp.buildmaster.tests.mock_slaves import ( |
41 |
BrokenSlave, |
|
42 |
BuildingSlave, |
|
11705.2.26
by Jonathan Lange
Factor out SoyuzTestPublisher construction so as to avoid circular imports. |
43 |
make_publisher, |
11593.3.120
by Julian Edwards
re-add revno 11801 which was backed out in devel due to test failures resulting from a twisted bug |
44 |
OkSlave, |
14557.2.1
by Gavin Panella
Revert r14552, thus unreverting r14499 and r14459, to bring back read-only transactions in buildmaster. |
45 |
WaitingSlave, |
11593.3.120
by Julian Edwards
re-add revno 11801 which was backed out in devel due to test failures resulting from a twisted bug |
46 |
)
|
7675.509.139
by William Grant
Move (I)BuildQueue(Set) to lp.buildmaster. |
47 |
from lp.registry.interfaces.distribution import IDistributionSet |
14612.2.1
by William Grant
format-imports on lib/. So many imports. |
48 |
from lp.services.config import config |
14542.2.33
by Gavin Panella
TestSlaveScannerScan needs TestCaseWithFactory after all, and fix a missing import. |
49 |
from lp.services.database.constants import UTC_NOW |
14557.2.1
by Gavin Panella
Revert r14552, thus unreverting r14499 and r14459, to bring back read-only transactions in buildmaster. |
50 |
from lp.services.log.logger import BufferLogger |
10667.2.2
by Michael Nelson
Mass renaming of imports and references to IBuild/Build/IBuildSet |
51 |
from lp.soyuz.interfaces.binarypackagebuild import IBinaryPackageBuildSet |
11705.2.25
by Jonathan Lange
Easier than I thought. |
52 |
from lp.testing import ( |
14612.2.1
by William Grant
format-imports on lib/. So many imports. |
53 |
ANONYMOUS, |
54 |
login, |
|
11705.2.25
by Jonathan Lange
Easier than I thought. |
55 |
TestCase, |
56 |
TestCaseWithFactory, |
|
57 |
)
|
|
10888.6.14
by Julian Edwards
checkForNewBuilders returns builders if they're new |
58 |
from lp.testing.factory import LaunchpadObjectFactory |
10888.6.19
by Julian Edwards
fix a test isolation issue |
59 |
from lp.testing.fakemethod import FakeMethod |
14612.2.1
by William Grant
format-imports on lib/. So many imports. |
60 |
from lp.testing.layers import ( |
61 |
LaunchpadScriptLayer, |
|
62 |
LaunchpadZopelessLayer, |
|
63 |
ZopelessDatabaseLayer, |
|
64 |
)
|
|
14557.2.1
by Gavin Panella
Revert r14552, thus unreverting r14499 and r14459, to bring back read-only transactions in buildmaster. |
65 |
from lp.testing.sampledata import ( |
66 |
BOB_THE_BUILDER_NAME, |
|
67 |
FROG_THE_BUILDER_NAME, |
|
68 |
)
|
|
69 |
||
70 |
||
14542.2.33
by Gavin Panella
TestSlaveScannerScan needs TestCaseWithFactory after all, and fix a missing import. |
71 |
class TestSlaveScannerScan(TestCaseWithFactory): |
10888.6.6
by Julian Edwards
loads of tests fixed, only 2 left. yay |
72 |
"""Tests `SlaveScanner.scan` method.
|
7813.2.14
by Celso Providelo
applying review comments, r=bigjools. |
73 |
|
74 |
This method uses the old framework for scanning and dispatching builds.
|
|
75 |
"""
|
|
11705.2.25
by Jonathan Lange
Easier than I thought. |
76 |
layer = LaunchpadZopelessLayer |
77 |
run_tests_with = AsynchronousDeferredRunTest.make_factory(timeout=20) |
|
7813.2.14
by Celso Providelo
applying review comments, r=bigjools. |
78 |
|
79 |
def setUp(self): |
|
11705.2.25
by Jonathan Lange
Easier than I thought. |
80 |
"""Set up BuilddSlaveTest.
|
7813.2.14
by Celso Providelo
applying review comments, r=bigjools. |
81 |
|
82 |
Also adjust the sampledata in a way a build can be dispatched to
|
|
83 |
'bob' builder.
|
|
84 |
"""
|
|
11705.2.25
by Jonathan Lange
Easier than I thought. |
85 |
super(TestSlaveScannerScan, self).setUp() |
8137.17.24
by Barry Warsaw
thread merge |
86 |
# Creating the required chroots needed for dispatching.
|
11705.2.26
by Jonathan Lange
Factor out SoyuzTestPublisher construction so as to avoid circular imports. |
87 |
test_publisher = make_publisher() |
8137.17.24
by Barry Warsaw
thread merge |
88 |
ubuntu = getUtility(IDistributionSet).getByName('ubuntu') |
89 |
hoary = ubuntu.getSeries('hoary') |
|
7675.509.141
by William Grant
Fix lint. |
90 |
test_publisher.setUpDefaultDistroSeries(hoary) |
8137.17.24
by Barry Warsaw
thread merge |
91 |
test_publisher.addFakeChroots() |
7813.2.14
by Celso Providelo
applying review comments, r=bigjools. |
92 |
|
14542.2.27
by Gavin Panella
Use BuilddManagerTestFixture in TestSlaveScannerScan. |
93 |
self.useFixture(BuilddManagerTestFixture()) |
14557.2.1
by Gavin Panella
Revert r14552, thus unreverting r14499 and r14459, to bring back read-only transactions in buildmaster. |
94 |
|
8137.17.24
by Barry Warsaw
thread merge |
95 |
def _resetBuilder(self, builder): |
11593.3.120
by Julian Edwards
re-add revno 11801 which was backed out in devel due to test failures resulting from a twisted bug |
96 |
"""Reset the given builder and its job."""
|
7813.2.14
by Celso Providelo
applying review comments, r=bigjools. |
97 |
builder.builderok = True |
98 |
job = builder.currentjob |
|
99 |
if job is not None: |
|
8137.17.24
by Barry Warsaw
thread merge |
100 |
job.reset() |
7813.2.14
by Celso Providelo
applying review comments, r=bigjools. |
101 |
|
14557.2.1
by Gavin Panella
Revert r14552, thus unreverting r14499 and r14459, to bring back read-only transactions in buildmaster. |
102 |
def getFreshBuilder(self, slave=None, name=BOB_THE_BUILDER_NAME, |
103 |
failure_count=0): |
|
104 |
"""Return a builder.
|
|
105 |
||
106 |
The builder is taken from sample data, but reset to a usable state.
|
|
107 |
Be careful: this is not a proper factory method. Identical calls
|
|
108 |
return (and reset) the same builder. Don't rely on that though;
|
|
109 |
maybe someday we'll have a proper factory here.
|
|
110 |
"""
|
|
111 |
if slave is None: |
|
112 |
slave = OkSlave() |
|
113 |
builder = getUtility(IBuilderSet)[name] |
|
114 |
self._resetBuilder(builder) |
|
115 |
builder.setSlaveForTesting(slave) |
|
116 |
builder.failure_count = failure_count |
|
117 |
return builder |
|
118 |
||
8137.17.24
by Barry Warsaw
thread merge |
119 |
def assertBuildingJob(self, job, builder, logtail=None): |
120 |
"""Assert the given job is building on the given builder."""
|
|
7675.461.4
by Muharem Hrnjadovic
testScanUpdatesBuildingJobs passes |
121 |
from lp.services.job.interfaces.job import JobStatus |
8137.17.24
by Barry Warsaw
thread merge |
122 |
if logtail is None: |
123 |
logtail = 'Dummy sampledata entry, not processing' |
|
124 |
||
125 |
self.assertTrue(job is not None) |
|
126 |
self.assertEqual(job.builder, builder) |
|
7675.390.5
by Muharem Hrnjadovic
Review changes, round 1. |
127 |
self.assertTrue(job.date_started is not None) |
7675.461.4
by Muharem Hrnjadovic
testScanUpdatesBuildingJobs passes |
128 |
self.assertEqual(job.job.status, JobStatus.RUNNING) |
10667.2.2
by Michael Nelson
Mass renaming of imports and references to IBuild/Build/IBuildSet |
129 |
build = getUtility(IBinaryPackageBuildSet).getByQueueEntry(job) |
7675.687.129
by Michael Nelson
Fixed test_manager.py |
130 |
self.assertEqual(build.status, BuildStatus.BUILDING) |
8137.17.24
by Barry Warsaw
thread merge |
131 |
self.assertEqual(job.logtail, logtail) |
132 |
||
14557.2.1
by Gavin Panella
Revert r14552, thus unreverting r14499 and r14459, to bring back read-only transactions in buildmaster. |
133 |
def _getScanner(self, builder_name=None, clock=None): |
10888.6.6
by Julian Edwards
loads of tests fixed, only 2 left. yay |
134 |
"""Instantiate a SlaveScanner object.
|
8137.17.24
by Barry Warsaw
thread merge |
135 |
|
136 |
Replace its default logging handler by a testing version.
|
|
7813.2.14
by Celso Providelo
applying review comments, r=bigjools. |
137 |
"""
|
11593.3.120
by Julian Edwards
re-add revno 11801 which was backed out in devel due to test failures resulting from a twisted bug |
138 |
if builder_name is None: |
139 |
builder_name = BOB_THE_BUILDER_NAME |
|
14557.2.1
by Gavin Panella
Revert r14552, thus unreverting r14499 and r14459, to bring back read-only transactions in buildmaster. |
140 |
scanner = SlaveScanner(builder_name, BufferLogger(), clock=clock) |
11593.3.120
by Julian Edwards
re-add revno 11801 which was backed out in devel due to test failures resulting from a twisted bug |
141 |
scanner.logger.name = 'slave-scanner' |
7813.2.14
by Celso Providelo
applying review comments, r=bigjools. |
142 |
|
11593.3.120
by Julian Edwards
re-add revno 11801 which was backed out in devel due to test failures resulting from a twisted bug |
143 |
return scanner |
8137.17.24
by Barry Warsaw
thread merge |
144 |
|
10888.6.6
by Julian Edwards
loads of tests fixed, only 2 left. yay |
145 |
def _checkDispatch(self, slave, builder): |
11593.3.120
by Julian Edwards
re-add revno 11801 which was backed out in devel due to test failures resulting from a twisted bug |
146 |
# SlaveScanner.scan returns a slave when a dispatch was
|
147 |
# successful. We also check that the builder has a job on it.
|
|
148 |
||
149 |
self.assertTrue(slave is not None, "Expected a slave.") |
|
10888.7.22
by Julian Edwards
move the builder failure_count reset to a point in the manager where we can be sure the dispatch was successful. |
150 |
self.assertEqual(0, builder.failure_count) |
11593.3.120
by Julian Edwards
re-add revno 11801 which was backed out in devel due to test failures resulting from a twisted bug |
151 |
self.assertTrue(builder.currentjob is not None) |
8137.17.24
by Barry Warsaw
thread merge |
152 |
|
153 |
def testScanDispatchForResetBuilder(self): |
|
154 |
# A job gets dispatched to the sampledata builder after it's reset.
|
|
155 |
||
14557.2.1
by Gavin Panella
Revert r14552, thus unreverting r14499 and r14459, to bring back read-only transactions in buildmaster. |
156 |
# Obtain a builder. Initialize failure count to 1 so that
|
157 |
# _checkDispatch can make sure that a successful dispatch resets
|
|
158 |
# the count to 0.
|
|
14542.2.27
by Gavin Panella
Use BuilddManagerTestFixture in TestSlaveScannerScan. |
159 |
with BuilddManagerTestFixture.extraSetUp(): |
160 |
builder = self.getFreshBuilder(failure_count=1) |
|
8137.17.24
by Barry Warsaw
thread merge |
161 |
|
162 |
# Run 'scan' and check its result.
|
|
11593.3.120
by Julian Edwards
re-add revno 11801 which was backed out in devel due to test failures resulting from a twisted bug |
163 |
self.layer.switchDbUser(config.builddmaster.dbuser) |
164 |
scanner = self._getScanner() |
|
165 |
d = defer.maybeDeferred(scanner.scan) |
|
8137.17.24
by Barry Warsaw
thread merge |
166 |
d.addCallback(self._checkDispatch, builder) |
167 |
return d |
|
168 |
||
11593.3.120
by Julian Edwards
re-add revno 11801 which was backed out in devel due to test failures resulting from a twisted bug |
169 |
def _checkNoDispatch(self, slave, builder): |
8533.1.3
by Celso Providelo
Fixing the slip on buildd-manager that blocks the dispatcher on jobs with missing chroots. |
170 |
"""Assert that no dispatch has occurred.
|
171 |
||
11593.3.120
by Julian Edwards
re-add revno 11801 which was backed out in devel due to test failures resulting from a twisted bug |
172 |
'slave' is None, so no interations would be passed
|
8533.1.3
by Celso Providelo
Fixing the slip on buildd-manager that blocks the dispatcher on jobs with missing chroots. |
173 |
to the asynchonous dispatcher and the builder remained active
|
174 |
and IDLE.
|
|
175 |
"""
|
|
14557.2.1
by Gavin Panella
Revert r14552, thus unreverting r14499 and r14459, to bring back read-only transactions in buildmaster. |
176 |
self.assertIs(None, slave, "Unexpected slave.") |
8533.1.3
by Celso Providelo
Fixing the slip on buildd-manager that blocks the dispatcher on jobs with missing chroots. |
177 |
|
178 |
builder = getUtility(IBuilderSet).get(builder.id) |
|
179 |
self.assertTrue(builder.builderok) |
|
14557.2.1
by Gavin Panella
Revert r14552, thus unreverting r14499 and r14459, to bring back read-only transactions in buildmaster. |
180 |
self.assertIs(None, builder.currentjob) |
8533.1.3
by Celso Providelo
Fixing the slip on buildd-manager that blocks the dispatcher on jobs with missing chroots. |
181 |
|
182 |
def testNoDispatchForMissingChroots(self): |
|
183 |
# When a required chroot is not present the `scan` method
|
|
184 |
# should not return any `RecordingSlaves` to be processed
|
|
185 |
# and the builder used should remain active and IDLE.
|
|
14542.2.27
by Gavin Panella
Use BuilddManagerTestFixture in TestSlaveScannerScan. |
186 |
with BuilddManagerTestFixture.extraSetUp(): |
187 |
builder = self.getFreshBuilder() |
|
188 |
# Remove hoary/i386 chroot.
|
|
189 |
login('foo.bar@canonical.com') |
|
190 |
ubuntu = getUtility(IDistributionSet).getByName('ubuntu') |
|
191 |
hoary = ubuntu.getSeries('hoary') |
|
192 |
pocket_chroot = hoary.getDistroArchSeries('i386').getPocketChroot() |
|
193 |
removeSecurityProxy(pocket_chroot).chroot = None |
|
194 |
||
8533.1.3
by Celso Providelo
Fixing the slip on buildd-manager that blocks the dispatcher on jobs with missing chroots. |
195 |
login(ANONYMOUS) |
196 |
||
197 |
# Run 'scan' and check its result.
|
|
11593.3.120
by Julian Edwards
re-add revno 11801 which was backed out in devel due to test failures resulting from a twisted bug |
198 |
self.layer.switchDbUser(config.builddmaster.dbuser) |
199 |
scanner = self._getScanner() |
|
200 |
d = defer.maybeDeferred(scanner.singleCycle) |
|
8533.1.3
by Celso Providelo
Fixing the slip on buildd-manager that blocks the dispatcher on jobs with missing chroots. |
201 |
d.addCallback(self._checkNoDispatch, builder) |
202 |
return d |
|
203 |
||
10888.6.6
by Julian Edwards
loads of tests fixed, only 2 left. yay |
204 |
def _checkJobRescued(self, slave, builder, job): |
205 |
"""`SlaveScanner.scan` rescued the job.
|
|
8137.17.24
by Barry Warsaw
thread merge |
206 |
|
207 |
Nothing gets dispatched, the 'broken' builder remained disabled
|
|
208 |
and the 'rescued' job is ready to be dispatched.
|
|
209 |
"""
|
|
10888.6.6
by Julian Edwards
loads of tests fixed, only 2 left. yay |
210 |
self.assertTrue( |
211 |
slave is None, "Unexpected slave.") |
|
8137.17.24
by Barry Warsaw
thread merge |
212 |
|
213 |
builder = getUtility(IBuilderSet).get(builder.id) |
|
214 |
self.assertFalse(builder.builderok) |
|
215 |
||
216 |
job = getUtility(IBuildQueueSet).get(job.id) |
|
217 |
self.assertTrue(job.builder is None) |
|
7675.390.5
by Muharem Hrnjadovic
Review changes, round 1. |
218 |
self.assertTrue(job.date_started is None) |
10667.2.2
by Michael Nelson
Mass renaming of imports and references to IBuild/Build/IBuildSet |
219 |
build = getUtility(IBinaryPackageBuildSet).getByQueueEntry(job) |
7675.687.129
by Michael Nelson
Fixed test_manager.py |
220 |
self.assertEqual(build.status, BuildStatus.NEEDSBUILD) |
8137.17.24
by Barry Warsaw
thread merge |
221 |
|
222 |
def testScanRescuesJobFromBrokenBuilder(self): |
|
223 |
# The job assigned to a broken builder is rescued.
|
|
14047.3.37
by Jeroen Vermeulen
Review change: only set up BuilddSlaveTestSetup fixture where it's needed. |
224 |
self.useFixture(BuilddSlaveTestSetup()) |
8137.17.24
by Barry Warsaw
thread merge |
225 |
|
9353.2.1
by Celso Providelo
Fixing bug #424797 (swalloed test failure in buildd-manager suite). |
226 |
# Sampledata builder is enabled and is assigned to an active job.
|
10888.7.23
by Julian Edwards
jml's review comments |
227 |
builder = getUtility(IBuilderSet)[BOB_THE_BUILDER_NAME] |
9353.2.1
by Celso Providelo
Fixing bug #424797 (swalloed test failure in buildd-manager suite). |
228 |
self.assertTrue(builder.builderok) |
229 |
job = builder.currentjob |
|
230 |
self.assertBuildingJob(job, builder) |
|
231 |
||
232 |
# Disable the sampledata builder
|
|
233 |
login('foo.bar@canonical.com') |
|
14542.2.27
by Gavin Panella
Use BuilddManagerTestFixture in TestSlaveScannerScan. |
234 |
with BuilddManagerTestFixture.extraSetUp(): |
235 |
builder.builderok = False |
|
9353.2.1
by Celso Providelo
Fixing bug #424797 (swalloed test failure in buildd-manager suite). |
236 |
login(ANONYMOUS) |
8137.17.24
by Barry Warsaw
thread merge |
237 |
|
238 |
# Run 'scan' and check its result.
|
|
11593.3.120
by Julian Edwards
re-add revno 11801 which was backed out in devel due to test failures resulting from a twisted bug |
239 |
self.layer.switchDbUser(config.builddmaster.dbuser) |
240 |
scanner = self._getScanner() |
|
241 |
d = defer.maybeDeferred(scanner.scan) |
|
9353.2.1
by Celso Providelo
Fixing bug #424797 (swalloed test failure in buildd-manager suite). |
242 |
d.addCallback(self._checkJobRescued, builder, job) |
8137.17.24
by Barry Warsaw
thread merge |
243 |
return d |
244 |
||
10888.6.6
by Julian Edwards
loads of tests fixed, only 2 left. yay |
245 |
def _checkJobUpdated(self, slave, builder, job): |
246 |
"""`SlaveScanner.scan` updates legitimate jobs.
|
|
8137.17.24
by Barry Warsaw
thread merge |
247 |
|
248 |
Job is kept assigned to the active builder and its 'logtail' is
|
|
249 |
updated.
|
|
250 |
"""
|
|
10888.6.6
by Julian Edwards
loads of tests fixed, only 2 left. yay |
251 |
self.assertTrue(slave is None, "Unexpected slave.") |
8137.17.24
by Barry Warsaw
thread merge |
252 |
|
253 |
builder = getUtility(IBuilderSet).get(builder.id) |
|
254 |
self.assertTrue(builder.builderok) |
|
255 |
||
256 |
job = getUtility(IBuildQueueSet).get(job.id) |
|
10430.8.5
by William Grant
Drop all the rescueIfLost-test-specific mock slaves, use a special build behavior in the rIL test, and fix other tests that used the late mocks. |
257 |
self.assertBuildingJob(job, builder, logtail='This is a build log') |
8137.17.24
by Barry Warsaw
thread merge |
258 |
|
259 |
def testScanUpdatesBuildingJobs(self): |
|
260 |
# Enable sampledata builder attached to an appropriate testing
|
|
261 |
# slave. It will respond as if it was building the sampledata job.
|
|
10888.7.23
by Julian Edwards
jml's review comments |
262 |
builder = getUtility(IBuilderSet)[BOB_THE_BUILDER_NAME] |
8137.17.24
by Barry Warsaw
thread merge |
263 |
|
264 |
login('foo.bar@canonical.com') |
|
14542.2.27
by Gavin Panella
Use BuilddManagerTestFixture in TestSlaveScannerScan. |
265 |
with BuilddManagerTestFixture.extraSetUp(): |
266 |
builder.builderok = True |
|
267 |
builder.setSlaveForTesting(BuildingSlave(build_id='8-1')) |
|
8137.17.24
by Barry Warsaw
thread merge |
268 |
login(ANONYMOUS) |
269 |
||
7675.461.6
by Muharem Hrnjadovic
took back unneeded change |
270 |
job = builder.currentjob |
8137.17.24
by Barry Warsaw
thread merge |
271 |
self.assertBuildingJob(job, builder) |
272 |
||
273 |
# Run 'scan' and check its result.
|
|
11593.3.120
by Julian Edwards
re-add revno 11801 which was backed out in devel due to test failures resulting from a twisted bug |
274 |
self.layer.switchDbUser(config.builddmaster.dbuser) |
275 |
scanner = self._getScanner() |
|
276 |
d = defer.maybeDeferred(scanner.scan) |
|
8137.17.24
by Barry Warsaw
thread merge |
277 |
d.addCallback(self._checkJobUpdated, builder, job) |
8294.3.1
by Celso Providelo
Re-fixing bug #343683 (legitimate building jobs were being erroneously reset). |
278 |
return d |
279 |
||
11593.3.120
by Julian Edwards
re-add revno 11801 which was backed out in devel due to test failures resulting from a twisted bug |
280 |
def test_scan_with_nothing_to_dispatch(self): |
14542.2.27
by Gavin Panella
Use BuilddManagerTestFixture in TestSlaveScannerScan. |
281 |
with BuilddManagerTestFixture.extraSetUp(): |
282 |
builder = self.factory.makeBuilder() |
|
283 |
builder.setSlaveForTesting(OkSlave()) |
|
11593.3.120
by Julian Edwards
re-add revno 11801 which was backed out in devel due to test failures resulting from a twisted bug |
284 |
scanner = self._getScanner(builder_name=builder.name) |
285 |
d = scanner.scan() |
|
286 |
return d.addCallback(self._checkNoDispatch, builder) |
|
287 |
||
288 |
def test_scan_with_manual_builder(self): |
|
289 |
# Reset sampledata builder.
|
|
14542.2.27
by Gavin Panella
Use BuilddManagerTestFixture in TestSlaveScannerScan. |
290 |
with BuilddManagerTestFixture.extraSetUp(): |
291 |
builder = self.getFreshBuilder() |
|
292 |
builder.manual = True |
|
11593.3.120
by Julian Edwards
re-add revno 11801 which was backed out in devel due to test failures resulting from a twisted bug |
293 |
scanner = self._getScanner() |
294 |
d = scanner.scan() |
|
295 |
d.addCallback(self._checkNoDispatch, builder) |
|
296 |
return d |
|
297 |
||
298 |
def test_scan_with_not_ok_builder(self): |
|
299 |
# Reset sampledata builder.
|
|
14542.2.27
by Gavin Panella
Use BuilddManagerTestFixture in TestSlaveScannerScan. |
300 |
with BuilddManagerTestFixture.extraSetUp(): |
301 |
builder = self.getFreshBuilder() |
|
302 |
builder.builderok = False |
|
11593.3.120
by Julian Edwards
re-add revno 11801 which was backed out in devel due to test failures resulting from a twisted bug |
303 |
scanner = self._getScanner() |
304 |
d = scanner.scan() |
|
305 |
# Because the builder is not ok, we can't use _checkNoDispatch.
|
|
306 |
d.addCallback( |
|
11705.2.25
by Jonathan Lange
Easier than I thought. |
307 |
lambda ignored: self.assertIs(None, builder.currentjob)) |
11593.3.120
by Julian Edwards
re-add revno 11801 which was backed out in devel due to test failures resulting from a twisted bug |
308 |
return d |
309 |
||
310 |
def test_scan_of_broken_slave(self): |
|
14542.2.27
by Gavin Panella
Use BuilddManagerTestFixture in TestSlaveScannerScan. |
311 |
with BuilddManagerTestFixture.extraSetUp(): |
312 |
builder = self.getFreshBuilder(slave=BrokenSlave()) |
|
11593.3.120
by Julian Edwards
re-add revno 11801 which was backed out in devel due to test failures resulting from a twisted bug |
313 |
scanner = self._getScanner(builder_name=builder.name) |
314 |
d = scanner.scan() |
|
11705.2.25
by Jonathan Lange
Easier than I thought. |
315 |
return assert_fails_with(d, xmlrpclib.Fault) |
11593.3.120
by Julian Edwards
re-add revno 11801 which was backed out in devel due to test failures resulting from a twisted bug |
316 |
|
317 |
def _assertFailureCounting(self, builder_count, job_count, |
|
318 |
expected_builder_count, expected_job_count): |
|
14557.2.1
by Gavin Panella
Revert r14552, thus unreverting r14499 and r14459, to bring back read-only transactions in buildmaster. |
319 |
# Avoid circular imports.
|
320 |
from lp.buildmaster import manager as manager_module |
|
321 |
||
10888.7.20
by Julian Edwards
Now also deal with exception failures as well as the dispatch failures. |
322 |
# If scan() fails with an exception, failure_counts should be
|
11593.3.120
by Julian Edwards
re-add revno 11801 which was backed out in devel due to test failures resulting from a twisted bug |
323 |
# incremented. What we do with the results of the failure
|
324 |
# counts is tested below separately, this test just makes sure that
|
|
325 |
# scan() is setting the counts.
|
|
10888.7.23
by Julian Edwards
jml's review comments |
326 |
def failing_scan(): |
11593.3.120
by Julian Edwards
re-add revno 11801 which was backed out in devel due to test failures resulting from a twisted bug |
327 |
return defer.fail(Exception("fake exception")) |
14557.2.1
by Gavin Panella
Revert r14552, thus unreverting r14499 and r14459, to bring back read-only transactions in buildmaster. |
328 |
|
14542.2.27
by Gavin Panella
Use BuilddManagerTestFixture in TestSlaveScannerScan. |
329 |
with BuilddManagerTestFixture.extraSetUp(): |
330 |
scanner = self._getScanner() |
|
331 |
scanner.scan = failing_scan |
|
332 |
self.patch(manager_module, 'assessFailureCounts', FakeMethod()) |
|
333 |
builder = getUtility(IBuilderSet)[scanner.builder_name] |
|
11593.3.120
by Julian Edwards
re-add revno 11801 which was backed out in devel due to test failures resulting from a twisted bug |
334 |
|
14542.2.27
by Gavin Panella
Use BuilddManagerTestFixture in TestSlaveScannerScan. |
335 |
builder.failure_count = builder_count |
336 |
builder.currentjob.specific_job.build.failure_count = job_count |
|
337 |
# The _scanFailed() calls abort, so make sure our existing failure
|
|
338 |
# counts are persisted by exiting the extraSetUp() context (which
|
|
339 |
# commits).
|
|
11593.3.120
by Julian Edwards
re-add revno 11801 which was backed out in devel due to test failures resulting from a twisted bug |
340 |
|
341 |
# singleCycle() calls scan() which is our fake one that throws an
|
|
10888.7.20
by Julian Edwards
Now also deal with exception failures as well as the dispatch failures. |
342 |
# exception.
|
11593.3.120
by Julian Edwards
re-add revno 11801 which was backed out in devel due to test failures resulting from a twisted bug |
343 |
d = scanner.singleCycle() |
10888.7.20
by Julian Edwards
Now also deal with exception failures as well as the dispatch failures. |
344 |
|
345 |
# Failure counts should be updated, and the assessment method
|
|
11593.3.120
by Julian Edwards
re-add revno 11801 which was backed out in devel due to test failures resulting from a twisted bug |
346 |
# should have been called. The actual behaviour is tested below
|
347 |
# in TestFailureAssessments.
|
|
348 |
def got_scan(ignored): |
|
349 |
self.assertEqual(expected_builder_count, builder.failure_count) |
|
350 |
self.assertEqual( |
|
351 |
expected_job_count, |
|
352 |
builder.currentjob.specific_job.build.failure_count) |
|
353 |
self.assertEqual( |
|
354 |
1, manager_module.assessFailureCounts.call_count) |
|
355 |
||
356 |
return d.addCallback(got_scan) |
|
357 |
||
358 |
def test_scan_first_fail(self): |
|
359 |
# The first failure of a job should result in the failure_count
|
|
360 |
# on the job and the builder both being incremented.
|
|
361 |
self._assertFailureCounting( |
|
362 |
builder_count=0, job_count=0, expected_builder_count=1, |
|
363 |
expected_job_count=1) |
|
364 |
||
365 |
def test_scan_second_builder_fail(self): |
|
366 |
# The first failure of a job should result in the failure_count
|
|
367 |
# on the job and the builder both being incremented.
|
|
368 |
self._assertFailureCounting( |
|
369 |
builder_count=1, job_count=0, expected_builder_count=2, |
|
370 |
expected_job_count=1) |
|
371 |
||
372 |
def test_scan_second_job_fail(self): |
|
373 |
# The first failure of a job should result in the failure_count
|
|
374 |
# on the job and the builder both being incremented.
|
|
375 |
self._assertFailureCounting( |
|
376 |
builder_count=0, job_count=1, expected_builder_count=1, |
|
377 |
expected_job_count=2) |
|
378 |
||
379 |
def test_scanFailed_handles_lack_of_a_job_on_the_builder(self): |
|
380 |
def failing_scan(): |
|
381 |
return defer.fail(Exception("fake exception")) |
|
382 |
scanner = self._getScanner() |
|
383 |
scanner.scan = failing_scan |
|
384 |
builder = getUtility(IBuilderSet)[scanner.builder_name] |
|
14542.2.27
by Gavin Panella
Use BuilddManagerTestFixture in TestSlaveScannerScan. |
385 |
with BuilddManagerTestFixture.extraSetUp(): |
386 |
builder.failure_count = Builder.FAILURE_THRESHOLD |
|
387 |
builder.currentjob.reset() |
|
11593.3.120
by Julian Edwards
re-add revno 11801 which was backed out in devel due to test failures resulting from a twisted bug |
388 |
|
389 |
d = scanner.singleCycle() |
|
390 |
||
391 |
def scan_finished(ignored): |
|
392 |
self.assertFalse(builder.builderok) |
|
393 |
||
394 |
return d.addCallback(scan_finished) |
|
395 |
||
396 |
def test_fail_to_resume_slave_resets_job(self): |
|
397 |
# If an attempt to resume and dispatch a slave fails, it should
|
|
398 |
# reset the job via job.reset()
|
|
399 |
||
400 |
# Make a slave with a failing resume() method.
|
|
401 |
slave = OkSlave() |
|
402 |
slave.resume = lambda: deferLater( |
|
403 |
reactor, 0, defer.fail, Failure(('out', 'err', 1))) |
|
404 |
||
405 |
# Reset sampledata builder.
|
|
406 |
builder = removeSecurityProxy( |
|
407 |
getUtility(IBuilderSet)[BOB_THE_BUILDER_NAME]) |
|
14542.2.27
by Gavin Panella
Use BuilddManagerTestFixture in TestSlaveScannerScan. |
408 |
with BuilddManagerTestFixture.extraSetUp(): |
409 |
self._resetBuilder(builder) |
|
410 |
self.assertEqual(0, builder.failure_count) |
|
411 |
builder.setSlaveForTesting(slave) |
|
412 |
builder.vm_host = "fake_vm_host" |
|
11593.3.120
by Julian Edwards
re-add revno 11801 which was backed out in devel due to test failures resulting from a twisted bug |
413 |
|
414 |
scanner = self._getScanner() |
|
415 |
||
416 |
# Get the next job that will be dispatched.
|
|
417 |
job = removeSecurityProxy(builder._findBuildCandidate()) |
|
14542.2.27
by Gavin Panella
Use BuilddManagerTestFixture in TestSlaveScannerScan. |
418 |
with BuilddManagerTestFixture.extraSetUp(): |
419 |
job.virtualized = True |
|
420 |
builder.virtualized = True |
|
11593.3.120
by Julian Edwards
re-add revno 11801 which was backed out in devel due to test failures resulting from a twisted bug |
421 |
d = scanner.singleCycle() |
422 |
||
423 |
def check(ignored): |
|
424 |
# The failure_count will have been incremented on the
|
|
425 |
# builder, we can check that to see that a dispatch attempt
|
|
426 |
# did indeed occur.
|
|
427 |
self.assertEqual(1, builder.failure_count) |
|
428 |
# There should also be no builder set on the job.
|
|
429 |
self.assertTrue(job.builder is None) |
|
430 |
build = getUtility(IBinaryPackageBuildSet).getByQueueEntry(job) |
|
431 |
self.assertEqual(build.status, BuildStatus.NEEDSBUILD) |
|
432 |
||
433 |
return d.addCallback(check) |
|
11593.3.48
by Julian Edwards
1. Split startCycle in two so that we have separate methods for a single cycle and one that also schedules the next one. This makes testing easier. |
434 |
|
14206.2.2
by Julian Edwards
merge remainder of backed out branch |
435 |
def test_cancelling_a_build(self): |
436 |
# When scanning an in-progress build, if its state is CANCELLING
|
|
437 |
# then the build should be stopped and moved to the CANCELLED state.
|
|
438 |
||
439 |
# Set up a building slave with a fake resume method so we can see
|
|
440 |
# if it got called later.
|
|
441 |
slave = BuildingSlave(build_id="8-1") |
|
442 |
call_counter = FakeMethod() |
|
14206.2.11
by Julian Edwards
fix lint |
443 |
|
14206.2.2
by Julian Edwards
merge remainder of backed out branch |
444 |
def fake_resume(): |
445 |
call_counter() |
|
446 |
return defer.succeed((None, None, 0)) |
|
447 |
slave.resume = fake_resume |
|
448 |
||
449 |
# Set the sample data builder building with the slave from above.
|
|
450 |
builder = getUtility(IBuilderSet)[BOB_THE_BUILDER_NAME] |
|
451 |
login('foo.bar@canonical.com') |
|
14542.2.27
by Gavin Panella
Use BuilddManagerTestFixture in TestSlaveScannerScan. |
452 |
with BuilddManagerTestFixture.extraSetUp(): |
453 |
builder.builderok = True |
|
454 |
# For now, we can only cancel virtual builds.
|
|
455 |
builder.virtualized = True |
|
456 |
builder.vm_host = "fake_vm_host" |
|
457 |
builder.setSlaveForTesting(slave) |
|
14206.2.2
by Julian Edwards
merge remainder of backed out branch |
458 |
login(ANONYMOUS) |
459 |
buildqueue = builder.currentjob |
|
460 |
self.assertBuildingJob(buildqueue, builder) |
|
461 |
||
462 |
# Now set the build to CANCELLING.
|
|
463 |
build = getUtility(IBinaryPackageBuildSet).getByQueueEntry(buildqueue) |
|
14542.2.27
by Gavin Panella
Use BuilddManagerTestFixture in TestSlaveScannerScan. |
464 |
with BuilddManagerTestFixture.extraSetUp(): |
465 |
build.status = BuildStatus.CANCELLING |
|
14206.2.2
by Julian Edwards
merge remainder of backed out branch |
466 |
|
467 |
# Run 'scan' and check its results.
|
|
468 |
self.layer.switchDbUser(config.builddmaster.dbuser) |
|
469 |
scanner = self._getScanner() |
|
470 |
d = scanner.scan() |
|
471 |
||
14206.2.3
by Julian Edwards
Start of unit tests for new checkCancellation method |
472 |
# The build state should be cancelled and we should have also
|
473 |
# called the resume() method on the slave that resets the virtual
|
|
474 |
# machine.
|
|
14206.2.2
by Julian Edwards
merge remainder of backed out branch |
475 |
def check_cancelled(ignore, builder, buildqueue): |
476 |
self.assertEqual(1, call_counter.call_count) |
|
477 |
self.assertEqual(BuildStatus.CANCELLED, build.status) |
|
478 |
||
479 |
d.addCallback(check_cancelled, builder, buildqueue) |
|
480 |
return d |
|
481 |
||
14557.2.1
by Gavin Panella
Revert r14552, thus unreverting r14499 and r14459, to bring back read-only transactions in buildmaster. |
482 |
def makeFakeFailure(self): |
483 |
"""Produce a fake failure for use with SlaveScanner._scanFailed."""
|
|
484 |
FakeFailure = namedtuple('FakeFailure', ['getErrorMessage', 'check']) |
|
485 |
return FakeFailure( |
|
486 |
FakeMethod(self.factory.getUniqueString()), |
|
487 |
FakeMethod(True)) |
|
488 |
||
489 |
def test_interleaved_success_and_failure_do_not_interfere(self): |
|
490 |
# It's possible for one builder to fail while another continues
|
|
491 |
# to function properly. When that happens, the failed builder
|
|
492 |
# may cause database changes to be rolled back. But that does
|
|
493 |
# not affect the functioning builder.
|
|
494 |
clock = task.Clock() |
|
495 |
||
14542.2.27
by Gavin Panella
Use BuilddManagerTestFixture in TestSlaveScannerScan. |
496 |
with BuilddManagerTestFixture.extraSetUp(): |
497 |
broken_builder = self.getFreshBuilder( |
|
498 |
slave=BrokenSlave(), name=BOB_THE_BUILDER_NAME) |
|
499 |
broken_scanner = self._getScanner( |
|
500 |
builder_name=broken_builder.name) |
|
501 |
good_builder = self.getFreshBuilder( |
|
502 |
slave=WaitingSlave(), name=FROG_THE_BUILDER_NAME) |
|
503 |
good_build = self.factory.makeBinaryPackageBuild( |
|
504 |
distroarchseries=self.factory.makeDistroArchSeries()) |
|
505 |
||
506 |
# The good build is being handled by the good builder.
|
|
507 |
buildqueue = good_build.queueBuild() |
|
508 |
buildqueue.builder = good_builder |
|
509 |
||
510 |
removeSecurityProxy( |
|
511 |
good_build.build_farm_job).date_started = UTC_NOW |
|
14557.2.1
by Gavin Panella
Revert r14552, thus unreverting r14499 and r14459, to bring back read-only transactions in buildmaster. |
512 |
|
513 |
# The good builder requests information from a successful build,
|
|
514 |
# and up receiving it, updates the build's metadata.
|
|
515 |
# Our dependencies string goes into the build, and its
|
|
516 |
# date_finished will be set.
|
|
517 |
dependencies = self.factory.getUniqueString() |
|
518 |
PackageBuild.storeBuildInfo( |
|
519 |
good_build, None, {'dependencies': dependencies}) |
|
520 |
clock.advance(1) |
|
521 |
||
522 |
# The broken scanner experiences a failure before the good
|
|
523 |
# scanner is receiving its data. This aborts the ongoing
|
|
524 |
# transaction.
|
|
525 |
# As a somewhat weird example, if the builder changed its own
|
|
526 |
# title, that change will be rolled back.
|
|
527 |
original_broken_builder_title = broken_builder.title |
|
528 |
broken_builder.title = self.factory.getUniqueString() |
|
529 |
broken_scanner._scanFailed(self.makeFakeFailure()) |
|
530 |
||
531 |
# The work done by the good scanner is retained. The
|
|
532 |
# storeBuildInfo code committed it.
|
|
533 |
self.assertEqual(dependencies, good_build.dependencies) |
|
534 |
self.assertIsNot(None, good_build.date_finished) |
|
535 |
||
536 |
# The work done by the broken scanner is rolled back.
|
|
537 |
self.assertEqual(original_broken_builder_title, broken_builder.title) |
|
538 |
||
10888.7.23
by Julian Edwards
jml's review comments |
539 |
|
14206.2.5
by Julian Edwards
Check that non-cancelling build is ignored |
540 |
class TestCancellationChecking(TestCaseWithFactory): |
14206.2.3
by Julian Edwards
Start of unit tests for new checkCancellation method |
541 |
"""Unit tests for the checkCancellation method."""
|
542 |
||
14206.2.4
by Julian Edwards
Check that inactive builder is ignored |
543 |
layer = ZopelessDatabaseLayer |
14206.2.3
by Julian Edwards
Start of unit tests for new checkCancellation method |
544 |
run_tests_with = AsynchronousDeferredRunTest.make_factory(timeout=20) |
545 |
||
546 |
def setUp(self): |
|
547 |
super(TestCancellationChecking, self).setUp() |
|
548 |
builder_name = BOB_THE_BUILDER_NAME |
|
14206.2.4
by Julian Edwards
Check that inactive builder is ignored |
549 |
self.builder = getUtility(IBuilderSet)[builder_name] |
14206.2.5
by Julian Edwards
Check that non-cancelling build is ignored |
550 |
self.builder.virtualized = True |
14206.2.3
by Julian Edwards
Start of unit tests for new checkCancellation method |
551 |
self.scanner = SlaveScanner(builder_name, BufferLogger()) |
14206.2.4
by Julian Edwards
Check that inactive builder is ignored |
552 |
self.scanner.builder = self.builder |
14206.2.3
by Julian Edwards
Start of unit tests for new checkCancellation method |
553 |
self.scanner.logger.name = 'slave-scanner' |
554 |
||
14542.2.28
by Gavin Panella
Use BuilddManagerTestFixture in TestCancellationChecking. |
555 |
self.useFixture(BuilddManagerTestFixture()) |
14542.2.27
by Gavin Panella
Use BuilddManagerTestFixture in TestSlaveScannerScan. |
556 |
|
14206.2.3
by Julian Edwards
Start of unit tests for new checkCancellation method |
557 |
def test_ignores_nonvirtual(self): |
14206.2.4
by Julian Edwards
Check that inactive builder is ignored |
558 |
# If the builder is nonvirtual make sure we return False.
|
14542.2.28
by Gavin Panella
Use BuilddManagerTestFixture in TestCancellationChecking. |
559 |
with BuilddManagerTestFixture.extraSetUp(): |
560 |
self.builder.virtualized = False |
|
14206.2.4
by Julian Edwards
Check that inactive builder is ignored |
561 |
d = self.scanner.checkCancellation(self.builder) |
14206.2.13
by Julian Edwards
simplify assertions |
562 |
return d.addCallback(self.assertFalse) |
14206.2.4
by Julian Edwards
Check that inactive builder is ignored |
563 |
|
564 |
def test_ignores_no_buildqueue(self): |
|
565 |
# If the builder has no buildqueue associated,
|
|
566 |
# make sure we return False.
|
|
14206.2.5
by Julian Edwards
Check that non-cancelling build is ignored |
567 |
buildqueue = self.builder.currentjob |
14542.2.28
by Gavin Panella
Use BuilddManagerTestFixture in TestCancellationChecking. |
568 |
with BuilddManagerTestFixture.extraSetUp(): |
569 |
buildqueue.reset() |
|
14206.2.4
by Julian Edwards
Check that inactive builder is ignored |
570 |
d = self.scanner.checkCancellation(self.builder) |
14206.2.13
by Julian Edwards
simplify assertions |
571 |
return d.addCallback(self.assertFalse) |
14206.2.4
by Julian Edwards
Check that inactive builder is ignored |
572 |
|
14206.2.5
by Julian Edwards
Check that non-cancelling build is ignored |
573 |
def test_ignores_build_not_cancelling(self): |
574 |
# If the active build is not in a CANCELLING state, ignore it.
|
|
575 |
buildqueue = self.builder.currentjob |
|
576 |
build = getUtility(IBinaryPackageBuildSet).getByQueueEntry(buildqueue) |
|
14542.2.28
by Gavin Panella
Use BuilddManagerTestFixture in TestCancellationChecking. |
577 |
with BuilddManagerTestFixture.extraSetUp(): |
578 |
build.status = BuildStatus.BUILDING |
|
14206.2.5
by Julian Edwards
Check that non-cancelling build is ignored |
579 |
d = self.scanner.checkCancellation(self.builder) |
14206.2.13
by Julian Edwards
simplify assertions |
580 |
return d.addCallback(self.assertFalse) |
14206.2.3
by Julian Edwards
Start of unit tests for new checkCancellation method |
581 |
|
14206.2.6
by Julian Edwards
Check that a cancelling build is actually cancelled. |
582 |
def test_cancelling_build_is_cancelled(self): |
14206.2.7
by Julian Edwards
build cancellation check |
583 |
# If a build is CANCELLING, make sure True is returned and the
|
584 |
# slave was resumed.
|
|
585 |
call_counter = FakeMethod() |
|
14206.2.11
by Julian Edwards
fix lint |
586 |
|
14206.2.7
by Julian Edwards
build cancellation check |
587 |
def fake_resume(): |
588 |
call_counter() |
|
589 |
return defer.succeed((None, None, 0)) |
|
590 |
slave = OkSlave() |
|
591 |
slave.resume = fake_resume |
|
14542.2.28
by Gavin Panella
Use BuilddManagerTestFixture in TestCancellationChecking. |
592 |
|
593 |
with BuilddManagerTestFixture.extraSetUp(): |
|
594 |
self.builder.vm_host = "fake_vm_host" |
|
595 |
self.builder.setSlaveForTesting(slave) |
|
596 |
buildqueue = self.builder.currentjob |
|
597 |
build = getUtility(IBinaryPackageBuildSet).getByQueueEntry(buildqueue) |
|
598 |
build.status = BuildStatus.CANCELLING |
|
14206.2.7
by Julian Edwards
build cancellation check |
599 |
|
600 |
def check(result): |
|
601 |
self.assertEqual(1, call_counter.call_count) |
|
602 |
self.assertTrue(result) |
|
603 |
self.assertEqual(BuildStatus.CANCELLED, build.status) |
|
604 |
||
14206.2.6
by Julian Edwards
Check that a cancelling build is actually cancelled. |
605 |
d = self.scanner.checkCancellation(self.builder) |
14206.2.10
by Julian Edwards
Make tests return the deferred |
606 |
return d.addCallback(check) |
14206.2.3
by Julian Edwards
Start of unit tests for new checkCancellation method |
607 |
|
608 |
||
11705.2.25
by Jonathan Lange
Easier than I thought. |
609 |
class TestBuilddManager(TestCase): |
10888.6.15
by Julian Edwards
refactor code to add scanners and add a test for it |
610 |
|
11705.2.25
by Jonathan Lange
Easier than I thought. |
611 |
layer = LaunchpadZopelessLayer |
10888.6.15
by Julian Edwards
refactor code to add scanners and add a test for it |
612 |
|
10888.6.20
by Julian Edwards
add code that starts up the scan for new builders and tests for it |
613 |
def _stub_out_scheduleNextScanCycle(self): |
10888.6.19
by Julian Edwards
fix a test isolation issue |
614 |
# stub out the code that adds a callLater, so that later tests
|
615 |
# don't get surprises.
|
|
11593.3.120
by Julian Edwards
re-add revno 11801 which was backed out in devel due to test failures resulting from a twisted bug |
616 |
self.patch(SlaveScanner, 'startCycle', FakeMethod()) |
10888.6.19
by Julian Edwards
fix a test isolation issue |
617 |
|
10888.6.20
by Julian Edwards
add code that starts up the scan for new builders and tests for it |
618 |
def test_addScanForBuilders(self): |
619 |
# Test that addScanForBuilders generates NewBuildersScanner objects.
|
|
620 |
self._stub_out_scheduleNextScanCycle() |
|
621 |
||
10888.6.15
by Julian Edwards
refactor code to add scanners and add a test for it |
622 |
manager = BuilddManager() |
10888.6.26
by Julian Edwards
more cleanups |
623 |
builder_names = set( |
624 |
builder.name for builder in getUtility(IBuilderSet)) |
|
10888.6.15
by Julian Edwards
refactor code to add scanners and add a test for it |
625 |
scanners = manager.addScanForBuilders(builder_names) |
10888.6.26
by Julian Edwards
more cleanups |
626 |
scanner_names = set(scanner.builder_name for scanner in scanners) |
627 |
self.assertEqual(builder_names, scanner_names) |
|
10888.6.15
by Julian Edwards
refactor code to add scanners and add a test for it |
628 |
|
10888.6.20
by Julian Edwards
add code that starts up the scan for new builders and tests for it |
629 |
def test_startService_adds_NewBuildersScanner(self): |
630 |
# When startService is called, the manager will start up a
|
|
631 |
# NewBuildersScanner object.
|
|
632 |
self._stub_out_scheduleNextScanCycle() |
|
10888.6.26
by Julian Edwards
more cleanups |
633 |
clock = task.Clock() |
634 |
manager = BuilddManager(clock=clock) |
|
10888.6.20
by Julian Edwards
add code that starts up the scan for new builders and tests for it |
635 |
|
10888.6.21
by Julian Edwards
use FakeMethod instead of my own stubs |
636 |
# Replace scan() with FakeMethod so we can see if it was called.
|
10888.6.26
by Julian Edwards
more cleanups |
637 |
manager.new_builders_scanner.scan = FakeMethod() |
10888.6.20
by Julian Edwards
add code that starts up the scan for new builders and tests for it |
638 |
|
639 |
manager.startService() |
|
10888.6.26
by Julian Edwards
more cleanups |
640 |
advance = NewBuildersScanner.SCAN_INTERVAL + 1 |
641 |
clock.advance(advance) |
|
642 |
self.assertNotEqual(0, manager.new_builders_scanner.scan.call_count) |
|
10888.6.20
by Julian Edwards
add code that starts up the scan for new builders and tests for it |
643 |
|
10888.6.15
by Julian Edwards
refactor code to add scanners and add a test for it |
644 |
|
11593.3.120
by Julian Edwards
re-add revno 11801 which was backed out in devel due to test failures resulting from a twisted bug |
645 |
class TestFailureAssessments(TestCaseWithFactory): |
646 |
||
647 |
layer = ZopelessDatabaseLayer |
|
648 |
||
649 |
def setUp(self): |
|
650 |
TestCaseWithFactory.setUp(self) |
|
651 |
self.builder = self.factory.makeBuilder() |
|
652 |
self.build = self.factory.makeSourcePackageRecipeBuild() |
|
653 |
self.buildqueue = self.build.queueBuild() |
|
654 |
self.buildqueue.markAsBuilding(self.builder) |
|
655 |
||
656 |
def test_equal_failures_reset_job(self): |
|
657 |
self.builder.gotFailure() |
|
658 |
self.builder.getCurrentBuildFarmJob().gotFailure() |
|
659 |
||
660 |
assessFailureCounts(self.builder, "failnotes") |
|
661 |
self.assertIs(None, self.builder.currentjob) |
|
662 |
self.assertEqual(self.build.status, BuildStatus.NEEDSBUILD) |
|
663 |
||
664 |
def test_job_failing_more_than_builder_fails_job(self): |
|
665 |
self.builder.getCurrentBuildFarmJob().gotFailure() |
|
11983.2.1
by Julian Edwards
Ensure that builder failure_count is reset when deciding to fail a job |
666 |
self.builder.getCurrentBuildFarmJob().gotFailure() |
667 |
self.builder.gotFailure() |
|
11593.3.120
by Julian Edwards
re-add revno 11801 which was backed out in devel due to test failures resulting from a twisted bug |
668 |
|
669 |
assessFailureCounts(self.builder, "failnotes") |
|
670 |
self.assertIs(None, self.builder.currentjob) |
|
671 |
self.assertEqual(self.build.status, BuildStatus.FAILEDTOBUILD) |
|
11983.2.1
by Julian Edwards
Ensure that builder failure_count is reset when deciding to fail a job |
672 |
self.assertEqual(0, self.builder.failure_count) |
11593.3.120
by Julian Edwards
re-add revno 11801 which was backed out in devel due to test failures resulting from a twisted bug |
673 |
|
674 |
def test_builder_failing_more_than_job_but_under_fail_threshold(self): |
|
675 |
self.builder.failure_count = Builder.FAILURE_THRESHOLD - 1 |
|
676 |
||
677 |
assessFailureCounts(self.builder, "failnotes") |
|
678 |
self.assertIs(None, self.builder.currentjob) |
|
679 |
self.assertEqual(self.build.status, BuildStatus.NEEDSBUILD) |
|
680 |
self.assertTrue(self.builder.builderok) |
|
681 |
||
682 |
def test_builder_failing_more_than_job_but_over_fail_threshold(self): |
|
683 |
self.builder.failure_count = Builder.FAILURE_THRESHOLD |
|
684 |
||
685 |
assessFailureCounts(self.builder, "failnotes") |
|
686 |
self.assertIs(None, self.builder.currentjob) |
|
687 |
self.assertEqual(self.build.status, BuildStatus.NEEDSBUILD) |
|
688 |
self.assertFalse(self.builder.builderok) |
|
689 |
self.assertEqual("failnotes", self.builder.failnotes) |
|
690 |
||
691 |
def test_builder_failing_with_no_attached_job(self): |
|
692 |
self.buildqueue.reset() |
|
693 |
self.builder.failure_count = Builder.FAILURE_THRESHOLD |
|
694 |
||
695 |
assessFailureCounts(self.builder, "failnotes") |
|
696 |
self.assertFalse(self.builder.builderok) |
|
697 |
self.assertEqual("failnotes", self.builder.failnotes) |
|
698 |
||
699 |
||
11705.2.25
by Jonathan Lange
Easier than I thought. |
700 |
class TestNewBuilders(TestCase): |
10888.6.11
by Julian Edwards
First part of detecting new builders |
701 |
"""Test detecting of new builders."""
|
702 |
||
11705.2.25
by Jonathan Lange
Easier than I thought. |
703 |
layer = LaunchpadZopelessLayer |
10888.6.11
by Julian Edwards
First part of detecting new builders |
704 |
|
10888.6.26
by Julian Edwards
more cleanups |
705 |
def _getScanner(self, manager=None, clock=None): |
706 |
return NewBuildersScanner(manager=manager, clock=clock) |
|
10888.6.15
by Julian Edwards
refactor code to add scanners and add a test for it |
707 |
|
10888.6.11
by Julian Edwards
First part of detecting new builders |
708 |
def test_init_stores_existing_builders(self): |
13194.2.1
by Gavin Panella
Change all uses of 'initialise' to 'initialize'. |
709 |
# Make sure that NewBuildersScanner initializes itself properly
|
10888.6.12
by Julian Edwards
Add scheduleScan and a test |
710 |
# by storing a list of existing builders.
|
10888.6.11
by Julian Edwards
First part of detecting new builders |
711 |
all_builders = [builder.name for builder in getUtility(IBuilderSet)] |
10888.6.15
by Julian Edwards
refactor code to add scanners and add a test for it |
712 |
builder_scanner = self._getScanner() |
10888.6.11
by Julian Edwards
First part of detecting new builders |
713 |
self.assertEqual(all_builders, builder_scanner.current_builders) |
714 |
||
10888.6.12
by Julian Edwards
Add scheduleScan and a test |
715 |
def test_scheduleScan(self): |
716 |
# Test that scheduleScan calls the "scan" method.
|
|
10888.6.26
by Julian Edwards
more cleanups |
717 |
clock = task.Clock() |
718 |
builder_scanner = self._getScanner(clock=clock) |
|
10888.6.30
by Julian Edwards
woops, return instantiated FakeMethod when stubbing out methods in tests |
719 |
builder_scanner.scan = FakeMethod() |
10888.6.12
by Julian Edwards
Add scheduleScan and a test |
720 |
builder_scanner.scheduleScan() |
721 |
||
10888.6.26
by Julian Edwards
more cleanups |
722 |
advance = NewBuildersScanner.SCAN_INTERVAL + 1 |
723 |
clock.advance(advance) |
|
724 |
self.assertNotEqual( |
|
725 |
0, builder_scanner.scan.call_count, |
|
726 |
"scheduleScan did not schedule anything") |
|
10888.6.11
by Julian Edwards
First part of detecting new builders |
727 |
|
10888.6.13
by Julian Edwards
basic case for checkForNewBuilders not returning anything |
728 |
def test_checkForNewBuilders(self): |
729 |
# Test that checkForNewBuilders() detects a new builder
|
|
10888.6.14
by Julian Edwards
checkForNewBuilders returns builders if they're new |
730 |
|
731 |
# The basic case, where no builders are added.
|
|
10888.6.15
by Julian Edwards
refactor code to add scanners and add a test for it |
732 |
builder_scanner = self._getScanner() |
10888.6.26
by Julian Edwards
more cleanups |
733 |
self.assertEqual([], builder_scanner.checkForNewBuilders()) |
10888.6.13
by Julian Edwards
basic case for checkForNewBuilders not returning anything |
734 |
|
10888.6.14
by Julian Edwards
checkForNewBuilders returns builders if they're new |
735 |
# Add two builders and ensure they're returned.
|
736 |
new_builders = ["scooby", "lassie"] |
|
737 |
factory = LaunchpadObjectFactory() |
|
738 |
for builder_name in new_builders: |
|
739 |
factory.makeBuilder(name=builder_name) |
|
10888.6.26
by Julian Edwards
more cleanups |
740 |
self.assertEqual( |
10888.6.14
by Julian Edwards
checkForNewBuilders returns builders if they're new |
741 |
new_builders, builder_scanner.checkForNewBuilders()) |
742 |
||
12374.2.1
by Gavin Panella
Ensure that checkForNewBuilders() only detects a new builder once. |
743 |
def test_checkForNewBuilders_detects_builder_only_once(self): |
744 |
# checkForNewBuilders() only detects a new builder once.
|
|
745 |
builder_scanner = self._getScanner() |
|
746 |
LaunchpadObjectFactory().makeBuilder(name="sammy") |
|
747 |
self.assertEqual(["sammy"], builder_scanner.checkForNewBuilders()) |
|
748 |
self.assertEqual([], builder_scanner.checkForNewBuilders()) |
|
749 |
||
10888.6.16
by Julian Edwards
add scan() and a test |
750 |
def test_scan(self): |
11593.3.120
by Julian Edwards
re-add revno 11801 which was backed out in devel due to test failures resulting from a twisted bug |
751 |
# See if scan detects new builders.
|
10888.6.16
by Julian Edwards
add scan() and a test |
752 |
|
753 |
def fake_checkForNewBuilders(): |
|
754 |
return "new_builders" |
|
755 |
||
756 |
def fake_addScanForBuilders(new_builders): |
|
10888.6.27
by Julian Edwards
one more test cleanup |
757 |
self.assertEqual("new_builders", new_builders) |
10888.6.16
by Julian Edwards
add scan() and a test |
758 |
|
10888.6.26
by Julian Edwards
more cleanups |
759 |
clock = task.Clock() |
760 |
builder_scanner = self._getScanner(BuilddManager(), clock=clock) |
|
10888.6.16
by Julian Edwards
add scan() and a test |
761 |
builder_scanner.checkForNewBuilders = fake_checkForNewBuilders |
762 |
builder_scanner.manager.addScanForBuilders = fake_addScanForBuilders |
|
10888.6.30
by Julian Edwards
woops, return instantiated FakeMethod when stubbing out methods in tests |
763 |
builder_scanner.scheduleScan = FakeMethod() |
10888.6.16
by Julian Edwards
add scan() and a test |
764 |
|
10888.6.26
by Julian Edwards
more cleanups |
765 |
builder_scanner.scan() |
766 |
advance = NewBuildersScanner.SCAN_INTERVAL + 1 |
|
767 |
clock.advance(advance) |
|
10888.6.16
by Julian Edwards
add scan() and a test |
768 |
|
10888.6.13
by Julian Edwards
basic case for checkForNewBuilders not returning anything |
769 |
|
11121.2.7
by Henning Eggers
Reviewer suggestions. |
770 |
def is_file_growing(filepath, poll_interval=1, poll_repeat=10): |
771 |
"""Poll the file size to see if it grows.
|
|
772 |
||
773 |
Checks the size of the file in given intervals and returns True as soon as
|
|
774 |
it sees the size increase between two polls. If the size does not
|
|
775 |
increase after a given number of polls, the function returns False.
|
|
776 |
If the file does not exist, the function silently ignores that and waits
|
|
777 |
for it to appear on the next pall. If it has not appeared by the last
|
|
778 |
poll, the exception is propagated.
|
|
779 |
Program execution is blocked during polling.
|
|
780 |
||
781 |
:param filepath: The path to the file to be palled.
|
|
782 |
:param poll_interval: The number of seconds in between two polls.
|
|
783 |
:param poll_repeat: The number times to repeat the polling, so the size is
|
|
784 |
polled a total of poll_repeat+1 times. The default values create a
|
|
785 |
total poll time of 11 seconds. The BuilddManager logs
|
|
786 |
"scanning cycles" every 5 seconds so these settings should see an
|
|
7675.767.10
by William Grant
Fix lint. |
787 |
increase if the process is logging to this file.
|
11121.2.7
by Henning Eggers
Reviewer suggestions. |
788 |
"""
|
11121.2.3
by Henning Eggers
Added test for logging behavior. |
789 |
last_size = None |
14206.2.11
by Julian Edwards
fix lint |
790 |
for poll in range(poll_repeat + 1): |
11121.2.3
by Henning Eggers
Added test for logging behavior. |
791 |
try: |
11121.2.7
by Henning Eggers
Reviewer suggestions. |
792 |
statinfo = os.stat(filepath) |
11121.2.3
by Henning Eggers
Added test for logging behavior. |
793 |
if last_size is None: |
794 |
last_size = statinfo.st_size |
|
795 |
elif statinfo.st_size > last_size: |
|
796 |
return True |
|
797 |
else: |
|
798 |
# The file should not be shrinking.
|
|
799 |
assert statinfo.st_size == last_size |
|
800 |
except OSError: |
|
11121.2.5
by Henning Eggers
Removed some lint. |
801 |
if poll == poll_repeat: |
11121.2.3
by Henning Eggers
Added test for logging behavior. |
802 |
# Propagate only on the last loop, i.e. give up.
|
803 |
raise
|
|
11121.2.5
by Henning Eggers
Removed some lint. |
804 |
time.sleep(poll_interval) |
11121.2.3
by Henning Eggers
Added test for logging behavior. |
805 |
return False |
806 |
||
807 |
||
11593.3.120
by Julian Edwards
re-add revno 11801 which was backed out in devel due to test failures resulting from a twisted bug |
808 |
class TestBuilddManagerScript(TestCaseWithFactory): |
8486.7.1
by Celso Providelo
Fixing bug #380848 (buildd-manager circular imports, also testing if the TAC file starts and stops correctly). |
809 |
|
8486.7.3
by Celso Providelo
Fixing test failure. |
810 |
layer = LaunchpadScriptLayer |
8486.7.1
by Celso Providelo
Fixing bug #380848 (buildd-manager circular imports, also testing if the TAC file starts and stops correctly). |
811 |
|
812 |
def testBuilddManagerRuns(self): |
|
11121.2.3
by Henning Eggers
Added test for logging behavior. |
813 |
# The `buildd-manager.tac` starts and stops correctly.
|
11634.2.8
by Robert Collins
Fix test failures. |
814 |
fixture = BuilddManagerTestSetup() |
815 |
fixture.setUp() |
|
816 |
fixture.tearDown() |
|
11593.3.120
by Julian Edwards
re-add revno 11801 which was backed out in devel due to test failures resulting from a twisted bug |
817 |
self.layer.force_dirty_database() |
8486.7.1
by Celso Providelo
Fixing bug #380848 (buildd-manager circular imports, also testing if the TAC file starts and stops correctly). |
818 |
|
10888.6.35
by Julian Edwards
disable the two logging tests which should be in lp.services.twistedsupport, not here. they are preventing me from landing this branch. see bug 614275 |
819 |
# XXX Julian 2010-08-06 bug=614275
|
820 |
# These next 2 tests are in the wrong place, they should be near the
|
|
821 |
# implementation of RotatableFileLogObserver and not depend on the
|
|
822 |
# behaviour of the buildd-manager. I've disabled them here because
|
|
823 |
# they prevented me from landing this branch which reduces the
|
|
824 |
# logging output.
|
|
825 |
||
826 |
def disabled_testBuilddManagerLogging(self): |
|
11121.2.7
by Henning Eggers
Reviewer suggestions. |
827 |
# The twistd process logs as execpected.
|
11634.2.8
by Robert Collins
Fix test failures. |
828 |
test_setup = self.useFixture(BuilddManagerTestSetup()) |
11121.2.3
by Henning Eggers
Added test for logging behavior. |
829 |
logfilepath = test_setup.logfile |
11121.2.7
by Henning Eggers
Reviewer suggestions. |
830 |
# The process logs to its logfile.
|
11121.2.3
by Henning Eggers
Added test for logging behavior. |
831 |
self.assertTrue(is_file_growing(logfilepath)) |
832 |
# After rotating the log, the process keeps using the old file, no
|
|
833 |
# new file is created.
|
|
14206.2.11
by Julian Edwards
fix lint |
834 |
rotated_logfilepath = logfilepath + '.1' |
11121.2.3
by Henning Eggers
Added test for logging behavior. |
835 |
os.rename(logfilepath, rotated_logfilepath) |
836 |
self.assertTrue(is_file_growing(rotated_logfilepath)) |
|
837 |
self.assertFalse(os.access(logfilepath, os.F_OK)) |
|
838 |
# Upon receiving the USR1 signal, the process will re-open its log
|
|
839 |
# file at the old location.
|
|
840 |
test_setup.sendSignal(signal.SIGUSR1) |
|
841 |
self.assertTrue(is_file_growing(logfilepath)) |
|
842 |
self.assertTrue(os.access(rotated_logfilepath, os.F_OK)) |
|
843 |
||
10888.6.35
by Julian Edwards
disable the two logging tests which should be in lp.services.twistedsupport, not here. they are preventing me from landing this branch. see bug 614275 |
844 |
def disabled_testBuilddManagerLoggingNoRotation(self): |
11121.2.4
by Henning Eggers
Added test for log file rotation not happening. |
845 |
# The twistd process does not perform its own rotation.
|
846 |
# By default twistd will rotate log files that grow beyond
|
|
847 |
# 1000000 bytes but this is deactivated for the buildd manager.
|
|
848 |
test_setup = BuilddManagerTestSetup() |
|
849 |
logfilepath = test_setup.logfile |
|
14206.2.11
by Julian Edwards
fix lint |
850 |
rotated_logfilepath = logfilepath + '.1' |
11121.2.4
by Henning Eggers
Added test for log file rotation not happening. |
851 |
# Prefill the log file to just under 1000000 bytes.
|
852 |
test_setup.precreateLogfile( |
|
853 |
"2010-07-27 12:36:54+0200 [-] Starting scanning cycle.\n", 18518) |
|
11634.2.8
by Robert Collins
Fix test failures. |
854 |
self.useFixture(test_setup) |
11121.2.7
by Henning Eggers
Reviewer suggestions. |
855 |
# The process logs to the logfile.
|
11121.2.4
by Henning Eggers
Added test for log file rotation not happening. |
856 |
self.assertTrue(is_file_growing(logfilepath)) |
857 |
# No rotation occured.
|
|
858 |
self.assertFalse( |
|
859 |
os.access(rotated_logfilepath, os.F_OK), |
|
860 |
"Twistd's log file was rotated by twistd.") |