Merge lp://staging/~al-maisan/launchpad/spurious-tests-525329 into lp://staging/launchpad/db-devel

Proposed by Muharem Hrnjadovic
Status: Merged
Approved by: Graham Binns
Approved revision: no longer in the source branch.
Merged at revision: not available
Proposed branch: lp://staging/~al-maisan/launchpad/spurious-tests-525329
Merge into: lp://staging/launchpad/db-devel
Diff against target: 123 lines (+34/-12)
2 files modified
lib/lp/soyuz/model/buildqueue.py (+10/-4)
lib/lp/soyuz/tests/test_buildqueue.py (+24/-8)
To merge this branch: bzr merge lp://staging/~al-maisan/launchpad/spurious-tests-525329
Reviewer Review Type Date Requested Status
Graham Binns (community) code Approve
Review via email: mp+20233@code.staging.launchpad.net
To post a comment you must log in.
Revision history for this message
Muharem Hrnjadovic (al-maisan) wrote :

Hello,

quite a few tests that predict times or durations failed in spurious
fashion in the last few days.

The branch at hand introduces a BuildQueue._now() method that is used by the
BuildQueue code under test while enabling the unit tests to "monkey-patch"
that method and have it return a constant time in order to facilitate the
testing process.

This is based on an idea of Julian's.

Tests to run:

    bin/test -vv -t test_buildqueue

No "make lint" errors or warnings.

Revision history for this message
Graham Binns (gmb) :
review: Approve (code)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'lib/lp/soyuz/model/buildqueue.py'
--- lib/lp/soyuz/model/buildqueue.py 2010-02-22 08:30:06 +0000
+++ lib/lp/soyuz/model/buildqueue.py 2010-03-01 16:30:47 +0000
@@ -223,16 +223,17 @@
223223
224 head_job_processor, head_job_virtualized = head_job_platform224 head_job_processor, head_job_virtualized = head_job_platform
225225
226 now = self._now()
226 delay_query = """227 delay_query = """
227 SELECT MIN(228 SELECT MIN(
228 CASE WHEN229 CASE WHEN
229 EXTRACT(EPOCH FROM230 EXTRACT(EPOCH FROM
230 (BuildQueue.estimated_duration -231 (BuildQueue.estimated_duration -
231 (((now() AT TIME ZONE 'UTC') - Job.date_started)))) >= 0232 (((%s AT TIME ZONE 'UTC') - Job.date_started)))) >= 0
232 THEN233 THEN
233 EXTRACT(EPOCH FROM234 EXTRACT(EPOCH FROM
234 (BuildQueue.estimated_duration -235 (BuildQueue.estimated_duration -
235 (((now() AT TIME ZONE 'UTC') - Job.date_started))))236 (((%s AT TIME ZONE 'UTC') - Job.date_started))))
236 ELSE237 ELSE
237 -- Assume that jobs that have overdrawn their estimated238 -- Assume that jobs that have overdrawn their estimated
238 -- duration time budget will complete within 2 minutes.239 -- duration time budget will complete within 2 minutes.
@@ -253,7 +254,7 @@
253 AND Job.status = %s254 AND Job.status = %s
254 AND Builder.virtualized = %s255 AND Builder.virtualized = %s
255 """ % sqlvalues(256 """ % sqlvalues(
256 JobStatus.RUNNING,257 now, now, JobStatus.RUNNING,
257 normalize_virtualization(head_job_virtualized))258 normalize_virtualization(head_job_virtualized))
258259
259 if head_job_processor is not None:260 if head_job_processor is not None:
@@ -460,10 +461,15 @@
460461
461 # A job will not get dispatched in less than 5 seconds no matter what.462 # A job will not get dispatched in less than 5 seconds no matter what.
462 start_time = max(5, min_wait_time + sum_of_delays)463 start_time = max(5, min_wait_time + sum_of_delays)
463 result = datetime.utcnow() + timedelta(seconds=start_time)464 result = self._now() + timedelta(seconds=start_time)
464465
465 return result466 return result
466467
468 @staticmethod
469 def _now():
470 """Provide utcnow() while allowing test code to monkey-patch this."""
471 return datetime.utcnow()
472
467473
468class BuildQueueSet(object):474class BuildQueueSet(object):
469 """Utility to deal with BuildQueue content class."""475 """Utility to deal with BuildQueue content class."""
470476
=== modified file 'lib/lp/soyuz/tests/test_buildqueue.py'
--- lib/lp/soyuz/tests/test_buildqueue.py 2010-02-25 16:34:13 +0000
+++ lib/lp/soyuz/tests/test_buildqueue.py 2010-03-01 16:30:47 +0000
@@ -96,8 +96,12 @@
96 queue_entry.lastscore)96 queue_entry.lastscore)
9797
9898
99def check_mintime_to_builder(test, bq, min_time):99def check_mintime_to_builder(
100 test, bq, min_time, time_stamp=datetime.utcnow()):
100 """Test the estimated time until a builder becomes available."""101 """Test the estimated time until a builder becomes available."""
102 # Monkey-patch BuildQueueSet._now() so it returns a constant time stamp
103 # that's not too far in the future. This avoids spurious test failures.
104 monkey_patch_the_now_property(bq)
101 delay = bq._estimateTimeToNextBuilder()105 delay = bq._estimateTimeToNextBuilder()
102 test.assertTrue(106 test.assertTrue(
103 delay <= min_time,107 delay <= min_time,
@@ -131,8 +135,24 @@
131 return builder_data[(getattr(job.processor, 'id', None), job.virtualized)]135 return builder_data[(getattr(job.processor, 'id', None), job.virtualized)]
132136
133137
138def monkey_patch_the_now_property(buildqueue):
139 """Patch BuildQueue._now() so it returns a constant time stamp.
140
141 This avoids spurious test failures.
142 """
143 # Use the date/time the job started if available.
144 time_stamp = buildqueue.job.date_started
145 if not time_stamp:
146 time_stamp = datetime.utcnow()
147 buildqueue._now = lambda: time_stamp
148 return time_stamp
149
150
134def check_estimate(test, job, delay_in_seconds):151def check_estimate(test, job, delay_in_seconds):
135 """Does the dispatch time estimate match the expectation?"""152 """Does the dispatch time estimate match the expectation?"""
153 # Monkey-patch BuildQueueSet._now() so it returns a constant time stamp.
154 # This avoids spurious test failures.
155 time_stamp = monkey_patch_the_now_property(job)
136 estimate = job.getEstimatedJobStartTime()156 estimate = job.getEstimatedJobStartTime()
137 if delay_in_seconds is None:157 if delay_in_seconds is None:
138 test.assertEquals(158 test.assertEquals(
@@ -140,7 +160,7 @@
140 "An estimate should not be possible at present but one was "160 "An estimate should not be possible at present but one was "
141 "returned (%s) nevertheless." % estimate)161 "returned (%s) nevertheless." % estimate)
142 else:162 else:
143 estimate -= datetime.utcnow()163 estimate -= time_stamp
144 test.assertTrue(164 test.assertTrue(
145 estimate.seconds <= delay_in_seconds,165 estimate.seconds <= delay_in_seconds,
146 "The estimated delay deviates from the expected one (%s > %s)" %166 "The estimated delay deviates from the expected one (%s > %s)" %
@@ -495,9 +515,7 @@
495class TestMinTimeToNextBuilder(SingleArchBuildsBase):515class TestMinTimeToNextBuilder(SingleArchBuildsBase):
496 """Test estimated time-to-builder with builds targetting a single516 """Test estimated time-to-builder with builds targetting a single
497 processor."""517 processor."""
498 # XXX Michael Nelson 20100223 bug=525329518 def test_min_time_to_next_builder(self):
499 # This is still failing spuriously.
500 def disabled_test_min_time_to_next_builder(self):
501 """When is the next builder capable of running the job at the head of519 """When is the next builder capable of running the job at the head of
502 the queue becoming available?"""520 the queue becoming available?"""
503 # Test the estimation of the minimum time until a builder becomes521 # Test the estimation of the minimum time until a builder becomes
@@ -684,9 +702,7 @@
684702
685class TestMinTimeToNextBuilderMulti(MultiArchBuildsBase):703class TestMinTimeToNextBuilderMulti(MultiArchBuildsBase):
686 """Test estimated time-to-builder with builds and multiple processors."""704 """Test estimated time-to-builder with builds and multiple processors."""
687 # XXX Michael Nelson 20100223 bug=525329705 def test_min_time_to_next_builder(self):
688 # This is still failing spuriously.
689 def disabled_test_min_time_to_next_builder(self):
690 """When is the next builder capable of running the job at the head of706 """When is the next builder capable of running the job at the head of
691 the queue becoming available?"""707 the queue becoming available?"""
692 # One of four builders for the 'apg' build is immediately available.708 # One of four builders for the 'apg' build is immediately available.

Subscribers

People subscribed via source and target branches

to status/vote changes: