Code review comment for lp:~julian-edwards/launchpad/buildd-failure-counting
- buildd-failure-counting
- Merge into db-devel
Revision history for this message
Julian Edwards (julian-edwards) wrote : | # |
1 | === modified file 'lib/lp/buildmaster/interfaces/builder.py' |
2 | --- lib/lp/buildmaster/interfaces/builder.py 2010-08-20 13:47:47 +0000 |
3 | +++ lib/lp/buildmaster/interfaces/builder.py 2010-08-24 09:55:13 +0000 |
4 | @@ -154,6 +154,12 @@ |
5 | title=u"The current behavior of the builder for the current job.", |
6 | required=False) |
7 | |
8 | + def gotFailure(): |
9 | + """Increment failure_count on the builder.""" |
10 | + |
11 | + def resetFailureCount(): |
12 | + """Set the failure_count back to zero.""" |
13 | + |
14 | def checkSlaveAlive(): |
15 | """Check that the buildd slave is alive. |
16 | |
17 | |
18 | === modified file 'lib/lp/buildmaster/interfaces/buildfarmjob.py' |
19 | --- lib/lp/buildmaster/interfaces/buildfarmjob.py 2010-07-23 20:27:27 +0000 |
20 | +++ lib/lp/buildmaster/interfaces/buildfarmjob.py 2010-08-24 10:01:21 +0000 |
21 | @@ -270,6 +270,9 @@ |
22 | returned. |
23 | """ |
24 | |
25 | + def gotFailure(): |
26 | + """Increment the failure_count for this job.""" |
27 | + |
28 | title = exported(TextLine(title=_("Title"), required=False)) |
29 | |
30 | was_built = Attribute("Whether or not modified by the builddfarm.") |
31 | |
32 | === modified file 'lib/lp/buildmaster/manager.py' |
33 | --- lib/lp/buildmaster/manager.py 2010-08-20 13:42:19 +0000 |
34 | +++ lib/lp/buildmaster/manager.py 2010-08-24 10:27:37 +0000 |
35 | @@ -150,6 +150,8 @@ |
36 | |
37 | def assessFailureCounts(builder, fail_notes): |
38 | """View builder/job failure_count and work out which needs to die. """ |
39 | + # builder.currentjob hides a complicated query, don't run it twice. |
40 | + # See bug 623281. |
41 | current_job = builder.currentjob |
42 | build_job = current_job.specific_job.build |
43 | |
44 | @@ -361,7 +363,7 @@ |
45 | if self.builder.currentjob is not None: |
46 | # After a successful dispatch we can reset the |
47 | # failure_count. |
48 | - self.builder.failure_count = 0 |
49 | + self.builder.resetFailureCount() |
50 | transaction.commit() |
51 | return slave |
52 | |
53 | @@ -493,8 +495,8 @@ |
54 | return self.reset_result(slave, error_text) |
55 | |
56 | def _incrementFailureCounts(self, builder): |
57 | - builder.failure_count += 1 |
58 | - builder.getCurrentBuildFarmJob().failure_count += 1 |
59 | + builder.gotFailure() |
60 | + builder.getCurrentBuildFarmJob().gotFailure() |
61 | |
62 | def checkDispatch(self, response, method, slave): |
63 | """Verify the results of a slave xmlrpc call. |
64 | |
65 | === modified file 'lib/lp/buildmaster/model/builder.py' |
66 | --- lib/lp/buildmaster/model/builder.py 2010-08-20 13:47:47 +0000 |
67 | +++ lib/lp/buildmaster/model/builder.py 2010-08-24 10:15:31 +0000 |
68 | @@ -294,6 +294,14 @@ |
69 | current_build_behavior = property( |
70 | _getCurrentBuildBehavior, _setCurrentBuildBehavior) |
71 | |
72 | + def gotFailure(self): |
73 | + """See `IBuilder`.""" |
74 | + self.failure_count += 1 |
75 | + |
76 | + def resetFailureCount(self): |
77 | + """See `IBuilder`.""" |
78 | + self.failure_count = 0 |
79 | + |
80 | def checkSlaveAlive(self): |
81 | """See IBuilder.""" |
82 | if self.slave.echo("Test")[0] != "Test": |
83 | @@ -311,6 +319,8 @@ |
84 | """See IBuilder.""" |
85 | return self.slave.clean() |
86 | |
87 | + # XXX 2010-08-24 Julian bug=623281 |
88 | + # This should not be a property! It's masking a complicated query. |
89 | @property |
90 | def currentjob(self): |
91 | """See IBuilder""" |
92 | |
93 | === modified file 'lib/lp/buildmaster/model/buildfarmjob.py' |
94 | --- lib/lp/buildmaster/model/buildfarmjob.py 2010-08-17 15:04:47 +0000 |
95 | +++ lib/lp/buildmaster/model/buildfarmjob.py 2010-08-24 10:00:34 +0000 |
96 | @@ -344,6 +344,10 @@ |
97 | |
98 | return build_without_outer_proxy |
99 | |
100 | + def gotFailure(self): |
101 | + """See `IBuildFarmJob`.""" |
102 | + self.failure_count += 1 |
103 | + |
104 | |
105 | class BuildFarmJobDerived: |
106 | implements(IBuildFarmJob) |
On Monday 23 August 2010 18:34:43 Jonathan Lange wrote:
> I would argue that most things that manipulate state on object X
> should be methods of object X. I would not say it's a universal rule.
If we boil it down to the basic manipulation required, I completely agree.
> I think you have, in this case, particularly given the concessions
> below to have methods on Job (however it's spelled) and Builder that
> do the failure incrementing. That seems like a clean division of
> responsibility.
Woot! :)
> > I'd prefer to have a gotFailure() on each of Builder and BuildFarmJob and
> > have the build manager call each in turn.
> >
> > Let me know if you think that is acceptable and I'll do that change (it's
> > not in the attached diff).
>
> I think that's a great idea.
Ok it's done.
> Re robustness, I think you lose one kind of robustness and gain another.
I guess there are different ways of looking at it...
> "Was this method called?" tests are robust against behaviour change. martinfowler. com/articles/ mocksArentStubs .html for a good
> If you change what assessFailureCounts is supposed to do, then you
> won't have to change these tests, only the assessFailureCounts ones.
> (Some people call this "Mockist")
>
> Tests that check state are robust against implementation change. If
> you change the details of how you've implemented the code (as you've
> done during this review process), you won't have to change any tests.
> (Some people call this "Classic")
>
> As a rule, I lean heavily toward the latter, since I change
> implementation details much more frequently than behaviour. I use
> mocks in situations where there's a very clearly defined, fairly
> stable interface and when using some other kind of double would be
> prohibitively difficult.
>
> See http://
> discussion on the whole topic.
>
> As far as this diff goes, I think using a mock is less preferable but
> still sound, and I'm happy to see it merged.
I think I'm in total agreement with the sentiment above. In my case here I am
trying to abstract away from the "how failures are counted" as much as
possible since I forsee some changes in how we make it work. I suspect that
this branch will not be the final word on the matter :)
> It seems to me that Builder.currentjob ought to be replaced with a
> method asap, since it's doing a query, and naive readers might well
> miss that fact.
Agreed, I've filed a bug though as after grepping around, it will be a big
diff and I don't want to pollute this branch.
> If it's doing dupe queries and you aren't going to change currentjob
> to a method in this branch, then please add a comment saying something
> like:
>
> # builder.currentjob runs a query. Don't run it twice.
Done!
See partial diff.
Thanks for sticking with me :)