Merge lp:~wgrant/launchpad/rescueiflost-and-updatestatus-to-model into lp:launchpad
- rescueiflost-and-updatestatus-to-model
- Merge into devel
Proposed by
William Grant
Status: | Merged |
---|---|
Approved by: | Michael Nelson |
Approved revision: | no longer in the source branch. |
Merged at revision: | not available |
Proposed branch: | lp:~wgrant/launchpad/rescueiflost-and-updatestatus-to-model |
Merge into: | lp:launchpad |
Prerequisite: | lp:~wgrant/launchpad/refactor-slave-architecture-check |
Diff against target: |
326 lines (+105/-87) 5 files modified
lib/lp/buildmaster/buildergroup.py (+1/-76) lib/lp/buildmaster/interfaces/builder.py (+12/-0) lib/lp/buildmaster/model/builder.py (+76/-1) lib/lp/soyuz/doc/buildd-slavescanner.txt (+8/-10) lib/lp/soyuz/tests/soyuzbuilddhelpers.py (+8/-0) |
To merge this branch: | bzr merge lp:~wgrant/launchpad/rescueiflost-and-updatestatus-to-model |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Michael Nelson (community) | code | Approve | |
Review via email: mp+22016@code.launchpad.net |
Commit message
Move BuilderGroup.
Description of the change
BuilderGroup.
To post a comment you must log in.
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'lib/lp/buildmaster/buildergroup.py' | |||
2 | --- lib/lp/buildmaster/buildergroup.py 2010-03-24 12:02:21 +0000 | |||
3 | +++ lib/lp/buildmaster/buildergroup.py 2010-03-24 12:02:22 +0000 | |||
4 | @@ -15,7 +15,6 @@ | |||
5 | 15 | 15 | ||
6 | 16 | from lp.buildmaster.interfaces.builder import ( | 16 | from lp.buildmaster.interfaces.builder import ( |
7 | 17 | BuildDaemonError, IBuilderSet) | 17 | BuildDaemonError, IBuilderSet) |
8 | 18 | from lp.buildmaster.interfaces.builder import CorruptBuildID | ||
9 | 19 | 18 | ||
10 | 20 | 19 | ||
11 | 21 | class BuilderGroup: | 20 | class BuilderGroup: |
12 | @@ -46,81 +45,7 @@ | |||
13 | 46 | # 'ok' are not worth rechecking here for some currently | 45 | # 'ok' are not worth rechecking here for some currently |
14 | 47 | # undocumented reason. This also relates to bug #30633. | 46 | # undocumented reason. This also relates to bug #30633. |
15 | 48 | if builder.builderok: | 47 | if builder.builderok: |
17 | 49 | self.updateBuilderStatus(builder, arch) | 48 | builder.updateStatus(self.logger) |
18 | 50 | 49 | ||
19 | 51 | # Commit the updates made to the builders. | 50 | # Commit the updates made to the builders. |
20 | 52 | self.commit() | 51 | self.commit() |
21 | 53 | |||
22 | 54 | def updateBuilderStatus(self, builder, arch): | ||
23 | 55 | """Update the status for a builder by probing it. | ||
24 | 56 | |||
25 | 57 | :param builder: A builder object. | ||
26 | 58 | :param arch: The expected architecture family of the builder. | ||
27 | 59 | """ | ||
28 | 60 | self.logger.debug('Checking %s' % builder.name) | ||
29 | 61 | try: | ||
30 | 62 | builder.checkSlaveAlive() | ||
31 | 63 | builder.checkSlaveArchitecture() | ||
32 | 64 | self.rescueBuilderIfLost(builder) | ||
33 | 65 | # Catch only known exceptions. | ||
34 | 66 | # XXX cprov 2007-06-15 bug=120571: ValueError & TypeError catching is | ||
35 | 67 | # disturbing in this context. We should spend sometime sanitizing the | ||
36 | 68 | # exceptions raised in the Builder API since we already started the | ||
37 | 69 | # main refactoring of this area. | ||
38 | 70 | except (ValueError, TypeError, xmlrpclib.Fault, | ||
39 | 71 | BuildDaemonError), reason: | ||
40 | 72 | builder.failBuilder(str(reason)) | ||
41 | 73 | self.logger.warn( | ||
42 | 74 | "%s (%s) marked as failed due to: %s", | ||
43 | 75 | builder.name, builder.url, builder.failnotes, exc_info=True) | ||
44 | 76 | except socket.error, reason: | ||
45 | 77 | error_message = str(reason) | ||
46 | 78 | builder.handleTimeout(self.logger, error_message) | ||
47 | 79 | |||
48 | 80 | def rescueBuilderIfLost(self, builder): | ||
49 | 81 | """Reset Builder slave if job information doesn't match with DB. | ||
50 | 82 | |||
51 | 83 | If builder is BUILDING or WAITING but has an information record | ||
52 | 84 | that doesn't match what is stored in the DB, we have to dismiss | ||
53 | 85 | its current actions and let the slave free for another job, | ||
54 | 86 | assuming the XMLRPC is working properly at this point. | ||
55 | 87 | """ | ||
56 | 88 | status_sentence = builder.slaveStatusSentence() | ||
57 | 89 | |||
58 | 90 | # 'ident_position' dict relates the position of the job identifier | ||
59 | 91 | # token in the sentence received from status(), according the | ||
60 | 92 | # two status we care about. See see lib/canonical/buildd/slave.py | ||
61 | 93 | # for further information about sentence format. | ||
62 | 94 | ident_position = { | ||
63 | 95 | 'BuilderStatus.BUILDING': 1, | ||
64 | 96 | 'BuilderStatus.WAITING': 2 | ||
65 | 97 | } | ||
66 | 98 | |||
67 | 99 | # Isolate the BuilderStatus string, always the first token in | ||
68 | 100 | # see lib/canonical/buildd/slave.py and | ||
69 | 101 | # IBuilder.slaveStatusSentence(). | ||
70 | 102 | status = status_sentence[0] | ||
71 | 103 | |||
72 | 104 | # If slave is not building nor waiting, it's not in need of rescuing. | ||
73 | 105 | if status not in ident_position.keys(): | ||
74 | 106 | return | ||
75 | 107 | |||
76 | 108 | slave_build_id = status_sentence[ident_position[status]] | ||
77 | 109 | |||
78 | 110 | try: | ||
79 | 111 | builder.verifySlaveBuildID(slave_build_id) | ||
80 | 112 | except CorruptBuildID, reason: | ||
81 | 113 | if status == 'BuilderStatus.WAITING': | ||
82 | 114 | builder.cleanSlave() | ||
83 | 115 | else: | ||
84 | 116 | builder.requestAbort() | ||
85 | 117 | self.logger.warn("Builder '%s' rescued from '%s': '%s'" % ( | ||
86 | 118 | builder.name, slave_build_id, reason)) | ||
87 | 119 | |||
88 | 120 | def updateBuild(self, queueItem): | ||
89 | 121 | """Verify the current build job status. | ||
90 | 122 | |||
91 | 123 | Perform the required actions for each state. | ||
92 | 124 | """ | ||
93 | 125 | queueItem.builder.updateBuild(queueItem) | ||
94 | 126 | self.commit() | ||
95 | 127 | 52 | ||
96 | === modified file 'lib/lp/buildmaster/interfaces/builder.py' | |||
97 | --- lib/lp/buildmaster/interfaces/builder.py 2010-03-24 12:02:21 +0000 | |||
98 | +++ lib/lp/buildmaster/interfaces/builder.py 2010-03-24 12:02:22 +0000 | |||
99 | @@ -173,6 +173,18 @@ | |||
100 | 173 | :raises BuildDaemonError: When the slave is down. | 173 | :raises BuildDaemonError: When the slave is down. |
101 | 174 | """ | 174 | """ |
102 | 175 | 175 | ||
103 | 176 | def rescueIfLost(logger=None): | ||
104 | 177 | """Reset the slave if its job information doesn't match the DB. | ||
105 | 178 | |||
106 | 179 | If the builder is BUILDING or WAITING but has a build ID string | ||
107 | 180 | that doesn't match what is stored in the DB, we have to dismiss | ||
108 | 181 | its current actions and clean the slave for another job, assuming | ||
109 | 182 | the XMLRPC is working properly at this point. | ||
110 | 183 | """ | ||
111 | 184 | |||
112 | 185 | def updateStatus(logger=None): | ||
113 | 186 | """Update the builder's status by probing it.""" | ||
114 | 187 | |||
115 | 176 | def cleanSlave(): | 188 | def cleanSlave(): |
116 | 177 | """Clean any temporary files from the slave.""" | 189 | """Clean any temporary files from the slave.""" |
117 | 178 | 190 | ||
118 | 179 | 191 | ||
119 | === modified file 'lib/lp/buildmaster/model/builder.py' | |||
120 | --- lib/lp/buildmaster/model/builder.py 2010-03-24 12:02:21 +0000 | |||
121 | +++ lib/lp/buildmaster/model/builder.py 2010-03-24 12:02:22 +0000 | |||
122 | @@ -8,6 +8,8 @@ | |||
123 | 8 | __all__ = [ | 8 | __all__ = [ |
124 | 9 | 'Builder', | 9 | 'Builder', |
125 | 10 | 'BuilderSet', | 10 | 'BuilderSet', |
126 | 11 | 'rescueBuilderIfLost', | ||
127 | 12 | 'updateBuilderStatus', | ||
128 | 11 | ] | 13 | ] |
129 | 12 | 14 | ||
130 | 13 | import httplib | 15 | import httplib |
131 | @@ -40,7 +42,8 @@ | |||
132 | 40 | from lp.buildmaster.interfaces.buildbase import BuildStatus | 42 | from lp.buildmaster.interfaces.buildbase import BuildStatus |
133 | 41 | from lp.buildmaster.interfaces.builder import ( | 43 | from lp.buildmaster.interfaces.builder import ( |
134 | 42 | BuildDaemonError, BuildSlaveFailure, CannotBuild, CannotFetchFile, | 44 | BuildDaemonError, BuildSlaveFailure, CannotBuild, CannotFetchFile, |
136 | 43 | CannotResumeHost, IBuilder, IBuilderSet, ProtocolVersionMismatch) | 45 | CannotResumeHost, CorruptBuildID, IBuilder, IBuilderSet, |
137 | 46 | ProtocolVersionMismatch) | ||
138 | 44 | from lp.buildmaster.interfaces.buildfarmjobbehavior import ( | 47 | from lp.buildmaster.interfaces.buildfarmjobbehavior import ( |
139 | 45 | BuildBehaviorMismatch) | 48 | BuildBehaviorMismatch) |
140 | 46 | from lp.buildmaster.interfaces.buildqueue import IBuildQueueSet | 49 | from lp.buildmaster.interfaces.buildqueue import IBuildQueueSet |
141 | @@ -154,6 +157,71 @@ | |||
142 | 154 | raise BuildSlaveFailure(info) | 157 | raise BuildSlaveFailure(info) |
143 | 155 | 158 | ||
144 | 156 | 159 | ||
145 | 160 | # This is a separate function since MockBuilder needs to use it too. | ||
146 | 161 | # Do not use it -- (Mock)Builder.rescueIfLost should be used instead. | ||
147 | 162 | def rescueBuilderIfLost(builder, logger=None): | ||
148 | 163 | """See `IBuilder`.""" | ||
149 | 164 | status_sentence = builder.slaveStatusSentence() | ||
150 | 165 | |||
151 | 166 | # 'ident_position' dict relates the position of the job identifier | ||
152 | 167 | # token in the sentence received from status(), according the | ||
153 | 168 | # two status we care about. See see lib/canonical/buildd/slave.py | ||
154 | 169 | # for further information about sentence format. | ||
155 | 170 | ident_position = { | ||
156 | 171 | 'BuilderStatus.BUILDING': 1, | ||
157 | 172 | 'BuilderStatus.WAITING': 2 | ||
158 | 173 | } | ||
159 | 174 | |||
160 | 175 | # Isolate the BuilderStatus string, always the first token in | ||
161 | 176 | # see lib/canonical/buildd/slave.py and | ||
162 | 177 | # IBuilder.slaveStatusSentence(). | ||
163 | 178 | status = status_sentence[0] | ||
164 | 179 | |||
165 | 180 | # If slave is not building nor waiting, it's not in need of rescuing. | ||
166 | 181 | if status not in ident_position.keys(): | ||
167 | 182 | return | ||
168 | 183 | |||
169 | 184 | slave_build_id = status_sentence[ident_position[status]] | ||
170 | 185 | |||
171 | 186 | try: | ||
172 | 187 | builder.verifySlaveBuildID(slave_build_id) | ||
173 | 188 | except CorruptBuildID, reason: | ||
174 | 189 | if status == 'BuilderStatus.WAITING': | ||
175 | 190 | builder.cleanSlave() | ||
176 | 191 | else: | ||
177 | 192 | builder.requestAbort() | ||
178 | 193 | if logger: | ||
179 | 194 | logger.warn( | ||
180 | 195 | "Builder '%s' rescued from '%s': '%s'" % | ||
181 | 196 | (builder.name, slave_build_id, reason)) | ||
182 | 197 | |||
183 | 198 | |||
184 | 199 | def updateBuilderStatus(builder, logger=None): | ||
185 | 200 | """See `IBuilder`.""" | ||
186 | 201 | if logger: | ||
187 | 202 | logger.debug('Checking %s' % builder.name) | ||
188 | 203 | |||
189 | 204 | try: | ||
190 | 205 | builder.checkSlaveAlive() | ||
191 | 206 | builder.checkSlaveArchitecture() | ||
192 | 207 | builder.rescueIfLost(logger) | ||
193 | 208 | # Catch only known exceptions. | ||
194 | 209 | # XXX cprov 2007-06-15 bug=120571: ValueError & TypeError catching is | ||
195 | 210 | # disturbing in this context. We should spend sometime sanitizing the | ||
196 | 211 | # exceptions raised in the Builder API since we already started the | ||
197 | 212 | # main refactoring of this area. | ||
198 | 213 | except (ValueError, TypeError, xmlrpclib.Fault, | ||
199 | 214 | BuildDaemonError), reason: | ||
200 | 215 | builder.failBuilder(str(reason)) | ||
201 | 216 | if logger: | ||
202 | 217 | logger.warn( | ||
203 | 218 | "%s (%s) marked as failed due to: %s", | ||
204 | 219 | builder.name, builder.url, builder.failnotes, exc_info=True) | ||
205 | 220 | except socket.error, reason: | ||
206 | 221 | error_message = str(reason) | ||
207 | 222 | builder.handleTimeout(logger, error_message) | ||
208 | 223 | |||
209 | 224 | |||
210 | 157 | class Builder(SQLBase): | 225 | class Builder(SQLBase): |
211 | 158 | 226 | ||
212 | 159 | implements(IBuilder, IHasBuildRecords) | 227 | implements(IBuilder, IHasBuildRecords) |
213 | @@ -256,6 +324,13 @@ | |||
214 | 256 | if self.slave.echo("Test")[0] != "Test": | 324 | if self.slave.echo("Test")[0] != "Test": |
215 | 257 | raise BuildDaemonError("Failed to echo OK") | 325 | raise BuildDaemonError("Failed to echo OK") |
216 | 258 | 326 | ||
217 | 327 | def rescueIfLost(self, logger=None): | ||
218 | 328 | """See `IBuilder`.""" | ||
219 | 329 | rescueBuilderIfLost(self, logger) | ||
220 | 330 | |||
221 | 331 | def updateStatus(self, logger=None): | ||
222 | 332 | updateBuilderStatus(self, logger) | ||
223 | 333 | |||
224 | 259 | def cleanSlave(self): | 334 | def cleanSlave(self): |
225 | 260 | """See IBuilder.""" | 335 | """See IBuilder.""" |
226 | 261 | return self.slave.clean() | 336 | return self.slave.clean() |
227 | 262 | 337 | ||
228 | === modified file 'lib/lp/soyuz/doc/buildd-slavescanner.txt' | |||
229 | --- lib/lp/soyuz/doc/buildd-slavescanner.txt 2010-03-13 02:18:57 +0000 | |||
230 | +++ lib/lp/soyuz/doc/buildd-slavescanner.txt 2010-03-24 12:02:22 +0000 | |||
231 | @@ -69,21 +69,21 @@ | |||
232 | 69 | 69 | ||
233 | 70 | >>> sanebuilding_builder = MockBuilder( | 70 | >>> sanebuilding_builder = MockBuilder( |
234 | 71 | ... 'Sane Building Slave', SaneBuildingSlave()) | 71 | ... 'Sane Building Slave', SaneBuildingSlave()) |
236 | 72 | >>> buildergroup.rescueBuilderIfLost(sanebuilding_builder) is None | 72 | >>> sanebuilding_builder.rescueIfLost(buildergroup.logger) is None |
237 | 73 | True | 73 | True |
238 | 74 | 74 | ||
239 | 75 | A sane WAITING slave: | 75 | A sane WAITING slave: |
240 | 76 | 76 | ||
241 | 77 | >>> sanewaiting_builder = MockBuilder( | 77 | >>> sanewaiting_builder = MockBuilder( |
242 | 78 | ... 'Sane Waiting Slave', SaneWaitingSlave()) | 78 | ... 'Sane Waiting Slave', SaneWaitingSlave()) |
244 | 79 | >>> buildergroup.rescueBuilderIfLost(sanewaiting_builder) is None | 79 | >>> sanewaiting_builder.rescueIfLost(buildergroup.logger) is None |
245 | 80 | True | 80 | True |
246 | 81 | 81 | ||
247 | 82 | A insane WAITING slave, with wrong BuildQueue/Build relation: | 82 | A insane WAITING slave, with wrong BuildQueue/Build relation: |
248 | 83 | 83 | ||
249 | 84 | >>> insanewaiting_builder = MockBuilder( | 84 | >>> insanewaiting_builder = MockBuilder( |
250 | 85 | ... 'Insane Waiting Slave', InsaneWaitingSlave()) | 85 | ... 'Insane Waiting Slave', InsaneWaitingSlave()) |
252 | 86 | >>> buildergroup.rescueBuilderIfLost(insanewaiting_builder) | 86 | >>> insanewaiting_builder.rescueIfLost(buildergroup.logger) |
253 | 87 | WARNING:root:Builder 'Insane Waiting Slave' rescued from '7-1': 'Job build entry mismatch' | 87 | WARNING:root:Builder 'Insane Waiting Slave' rescued from '7-1': 'Job build entry mismatch' |
254 | 88 | 88 | ||
255 | 89 | It was rescued because the BuildQueue.id == 1 isn't related to | 89 | It was rescued because the BuildQueue.id == 1 isn't related to |
256 | @@ -94,7 +94,7 @@ | |||
257 | 94 | 94 | ||
258 | 95 | >>> lostbuilding_builder = MockBuilder( | 95 | >>> lostbuilding_builder = MockBuilder( |
259 | 96 | ... 'Lost Building Slave', LostBuildingSlave()) | 96 | ... 'Lost Building Slave', LostBuildingSlave()) |
261 | 97 | >>> buildergroup.rescueBuilderIfLost(lostbuilding_builder) | 97 | >>> lostbuilding_builder.rescueIfLost(buildergroup.logger) |
262 | 98 | WARNING:root:Builder 'Lost Building Slave' rescued from '1000-10000': | 98 | WARNING:root:Builder 'Lost Building Slave' rescued from '1000-10000': |
263 | 99 | 'Build 1000 is not available: 'Object not found'' | 99 | 'Build 1000 is not available: 'Object not found'' |
264 | 100 | 100 | ||
265 | @@ -102,7 +102,7 @@ | |||
266 | 102 | 102 | ||
267 | 103 | >>> lostwaiting_builder = MockBuilder( | 103 | >>> lostwaiting_builder = MockBuilder( |
268 | 104 | ... 'Lost Waiting Slave', LostWaitingSlave()) | 104 | ... 'Lost Waiting Slave', LostWaitingSlave()) |
270 | 105 | >>> buildergroup.rescueBuilderIfLost(lostwaiting_builder) | 105 | >>> lostwaiting_builder.rescueIfLost(buildergroup.logger) |
271 | 106 | WARNING:root:Builder 'Lost Waiting Slave' rescued from '1000-10000': | 106 | WARNING:root:Builder 'Lost Waiting Slave' rescued from '1000-10000': |
272 | 107 | 'Build 1000 is not available: 'Object not found'' | 107 | 'Build 1000 is not available: 'Object not found'' |
273 | 108 | 108 | ||
274 | @@ -115,13 +115,13 @@ | |||
275 | 115 | >>> lostbuilding_builder = MockBuilder( | 115 | >>> lostbuilding_builder = MockBuilder( |
276 | 116 | ... 'Lost Building Slave', LostBuildingSlave()) | 116 | ... 'Lost Building Slave', LostBuildingSlave()) |
277 | 117 | >>> lostbuilding_builder.current_build_behavior = IdleBuildBehavior() | 117 | >>> lostbuilding_builder.current_build_behavior = IdleBuildBehavior() |
279 | 118 | >>> buildergroup.rescueBuilderIfLost(lostbuilding_builder) | 118 | >>> lostbuilding_builder.rescueIfLost(buildergroup.logger) |
280 | 119 | WARNING:root:Builder 'Lost Building Slave' rescued from '1000-10000': 'No job assigned to builder' | 119 | WARNING:root:Builder 'Lost Building Slave' rescued from '1000-10000': 'No job assigned to builder' |
281 | 120 | 120 | ||
282 | 121 | >>> lostwaiting_builder = MockBuilder( | 121 | >>> lostwaiting_builder = MockBuilder( |
283 | 122 | ... 'Lost Waiting Slave', LostWaitingSlave()) | 122 | ... 'Lost Waiting Slave', LostWaitingSlave()) |
284 | 123 | >>> lostwaiting_builder.current_build_behavior = IdleBuildBehavior() | 123 | >>> lostwaiting_builder.current_build_behavior = IdleBuildBehavior() |
286 | 124 | >>> buildergroup.rescueBuilderIfLost(lostwaiting_builder) | 124 | >>> lostwaiting_builder.rescueIfLost(buildergroup.logger) |
287 | 125 | WARNING:root:Builder 'Lost Waiting Slave' rescued from '1000-10000': 'No job assigned to builder' | 125 | WARNING:root:Builder 'Lost Waiting Slave' rescued from '1000-10000': 'No job assigned to builder' |
288 | 126 | 126 | ||
289 | 127 | Slave-scanner will deactivate a 'lost-building' builder that could not | 127 | Slave-scanner will deactivate a 'lost-building' builder that could not |
290 | @@ -130,9 +130,7 @@ | |||
291 | 130 | >>> lostbuilding_builder = MockBuilder( | 130 | >>> lostbuilding_builder = MockBuilder( |
292 | 131 | ... 'Lost Building Broken Slave', LostBuildingBrokenSlave()) | 131 | ... 'Lost Building Broken Slave', LostBuildingBrokenSlave()) |
293 | 132 | 132 | ||
297 | 133 | >>> from canonical.launchpad.interfaces import IDistributionSet | 133 | >>> lostbuilding_builder.updateStatus(buildergroup.logger) |
295 | 134 | >>> hoary_i386 = getUtility(IDistributionSet)['ubuntu']['hoary']['i386'] | ||
296 | 135 | >>> buildergroup.updateBuilderStatus(lostbuilding_builder, hoary_i386) | ||
298 | 136 | WARNING:root:Lost Building Broken Slave (http://fake:0000) marked as failed due to: <Fault 8002: 'Could not abort'> | 134 | WARNING:root:Lost Building Broken Slave (http://fake:0000) marked as failed due to: <Fault 8002: 'Could not abort'> |
299 | 137 | Traceback (most recent call last): | 135 | Traceback (most recent call last): |
300 | 138 | ... | 136 | ... |
301 | 139 | 137 | ||
302 | === modified file 'lib/lp/soyuz/tests/soyuzbuilddhelpers.py' | |||
303 | --- lib/lp/soyuz/tests/soyuzbuilddhelpers.py 2010-03-24 12:02:21 +0000 | |||
304 | +++ lib/lp/soyuz/tests/soyuzbuilddhelpers.py 2010-03-24 12:02:22 +0000 | |||
305 | @@ -27,6 +27,8 @@ | |||
306 | 27 | 27 | ||
307 | 28 | from canonical.config import config | 28 | from canonical.config import config |
308 | 29 | from lp.buildmaster.interfaces.builder import CannotFetchFile | 29 | from lp.buildmaster.interfaces.builder import CannotFetchFile |
309 | 30 | from lp.buildmaster.model.builder import (rescueBuilderIfLost, | ||
310 | 31 | updateBuilderStatus) | ||
311 | 30 | from lp.soyuz.model.binarypackagebuildbehavior import ( | 32 | from lp.soyuz.model.binarypackagebuildbehavior import ( |
312 | 31 | BinaryPackageBuildBehavior) | 33 | BinaryPackageBuildBehavior) |
313 | 32 | 34 | ||
314 | @@ -70,6 +72,12 @@ | |||
315 | 70 | def checkSlaveArchitecture(self): | 72 | def checkSlaveArchitecture(self): |
316 | 71 | pass | 73 | pass |
317 | 72 | 74 | ||
318 | 75 | def rescueIfLost(self, logger=None): | ||
319 | 76 | rescueBuilderIfLost(self, logger) | ||
320 | 77 | |||
321 | 78 | def updateStatus(self, logger=None): | ||
322 | 79 | updateBuilderStatus(self, logger) | ||
323 | 80 | |||
324 | 73 | 81 | ||
325 | 74 | class SaneBuildingSlave: | 82 | class SaneBuildingSlave: |
326 | 75 | """A mock slave that is currently building build 8 and buildqueue 1.""" | 83 | """A mock slave that is currently building build 8 and buildqueue 1.""" |
Thanks for more cleanups and simplifications William!
It'd be nice if we didn't need to define the functions externally to be able to re-use them, but you clarified why that's necessary. Although I wonder if MockBuilder could just inherit from Builder and stub out the relevant methods as required? (leaving rescuiIfLost/ updateStatus) ? I'll leave it up to you.
Just a small suggested update for a comment below.
> === modified file 'lib/lp/ buildmaster/ model/builder. py' buildmaster/ model/builder. py 2010-03-24 12:02:21 +0000 buildmaster/ model/builder. py 2010-03-24 12:02:22 +0000 fLost', tatus', interfaces. buildbase import BuildStatus interfaces. builder import ( Mismatch) Mismatch) interfaces. buildfarmjobbeh avior import ( smatch) interfaces. buildqueue import IBuildQueueSet re(info) rescueIfLost should be used instead.
> --- lib/lp/
> +++ lib/lp/
> @@ -8,6 +8,8 @@
> __all__ = [
> 'Builder',
> 'BuilderSet',
> + 'rescueBuilderI
> + 'updateBuilderS
> ]
>
> import httplib
> @@ -40,7 +42,8 @@
> from lp.buildmaster.
> from lp.buildmaster.
> BuildDaemonError, BuildSlaveFailure, CannotBuild, CannotFetchFile,
> - CannotResumeHost, IBuilder, IBuilderSet, ProtocolVersion
> + CannotResumeHost, CorruptBuildID, IBuilder, IBuilderSet,
> + ProtocolVersion
> from lp.buildmaster.
> BuildBehaviorMi
> from lp.buildmaster.
> @@ -154,6 +157,71 @@
> raise BuildSlaveFailu
>
>
> +# This is a separate function since MockBuilder needs to use it too.
> +# Do not use it -- (Mock)Builder.
Perhaps:
These functions are defined here so that both Builder and MockBuilder updateStatus methods.
can share the implementation for the rescueIfLost/
> +def rescueBuilderIf Lost(builder, logger=None): slaveStatusSent ence()
> + """See `IBuilder`."""
> + status_sentence = builder.
{{{ updatestatus branch, couldn't we do something like rescueIfLost = Builder. rescueIfLost on the MockBuilder
if the code is the same? (and not have to define the functions?)
10:10 < noodles775> wgrant: with your rescueiflost/
10:10 < wgrant> noodles775: Bound methods check the type of the first argument.
10:10 < wgrant> So no, it's not quite that easy :(
10:10 < wgrant> Er, unbound methods.
10:10 < noodles775> Ok.
10:22 < noodles775> wgrant: in which case, is there an obvious reason that I'm missing for why MockBuilder couldn't inherit from Builder and just overload all its methods as needed?
10:27 < wgrant> noodles775: It looks like a few other mocks do that. So maybe I could.
10:27 < noodles775> wgrant: OK, I'll leave it up to you - I personally think it would improve the code.
10:27 < noodles775> r=me
}}}