Merge lp:~benji/launchpad/bug-963463 into lp:launchpad

Proposed by Benji York
Status: Merged
Approved by: Brad Crittenden
Approved revision: no longer in the source branch.
Merged at revision: 15053
Proposed branch: lp:~benji/launchpad/bug-963463
Merge into: lp:launchpad
Diff against target: 210 lines (+48/-6)
1 file modified
lib/lp/registry/tests/test_distributionmirror_prober.py (+48/-6)
To merge this branch: bzr merge lp:~benji/launchpad/bug-963463
Reviewer Review Type Date Requested Status
Brad Crittenden (community) code Approve
Review via email: mp+100514@code.launchpad.net

Commit message

Fix tests that use twisted and leave DelayedCalls, uncalled in the reactor.

Description of the change

Bug 963463 is about tests failing intermittently when run in groups (in
parallel, but that doesn't matter).

The problem is that there are tests that use twisted and leave
DelayedCalls, uncalled in the reactor. Tests using testtools later
detect the dirty reactor and generates an error.

This branch fixes several (all?) instances of those tests by giving them
a tearDown that clears out the reactor.

Lint: "make lint" reported several "E301 expected 1 blank line, found 0"
in ./lib/lp/registry/tests/test_distributionmirror_prober.py which I
fixed.

QA: since this is a testing bug, there is no QA to do.

To post a comment you must log in.
Revision history for this message
Brad Crittenden (bac) wrote :

Hey Benji this looks great. On IRC I twisted (ha!) into agreeing to add a helper function so those common bits aren't repeated.

Thanks.

review: Approve (code)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'lib/lp/registry/tests/test_distributionmirror_prober.py'
2--- lib/lp/registry/tests/test_distributionmirror_prober.py 2012-02-28 05:36:01 +0000
3+++ lib/lp/registry/tests/test_distributionmirror_prober.py 2012-04-02 20:59:22 +0000
4@@ -69,6 +69,14 @@
5 )
6
7
8+def clean_up_reactor():
9+ # XXX: JonathanLange 2010-11-22: These tests leave stacks of delayed
10+ # calls around. They need to be updated to use Twisted correctly.
11+ # For the meantime, just blat the reactor.
12+ for delayed_call in reactor.getDelayedCalls():
13+ delayed_call.cancel()
14+
15+
16 class HTTPServerTestSetup(TacTestSetup):
17
18 def setUpRoot(self):
19@@ -142,16 +150,20 @@
20 connect to the given host.
21 """
22 prober = ProberFactory(url)
23+
24 def fakeConnect(host, port, factory):
25 factory.connecting_to = host
26 factory.succeeded('200')
27+
28 prober.connecting_to = None
29 orig_connect = reactor.connectTCP
30 reactor.connectTCP = fakeConnect
31+
32 def restore_connect(result, orig_connect):
33 self.failUnlessEqual(prober.connecting_to, host)
34 reactor.connectTCP = orig_connect
35 return None
36+
37 deferred = prober.probe()
38 return deferred.addCallback(restore_connect, orig_connect)
39
40@@ -179,11 +191,13 @@
41 self.failUnless(prober.redirection_count == 0)
42 self.failUnless(prober.url == url)
43 deferred = prober.probe()
44+
45 def got_result(result):
46 self.failUnless(prober.redirection_count == 1)
47 new_url = 'http://localhost:%s/valid-mirror/file' % self.port
48 self.failUnless(prober.url == new_url)
49 self.failUnless(result == str(httplib.OK))
50+
51 return deferred.addCallback(got_result)
52
53 def test_redirectawareprober_detects_infinite_loop(self):
54@@ -200,26 +214,32 @@
55
56 def test_200(self):
57 d = self._createProberAndProbe(self.urls['200'])
58+
59 def got_result(result):
60 self.failUnless(
61 result == str(httplib.OK),
62 "Expected a '200' status but got '%s'" % result)
63+
64 return d.addCallback(got_result)
65
66 def test_success_cancel_timeout_call(self):
67 prober = ProberFactory(self.urls['200'])
68 deferred = prober.probe()
69 self.failUnless(prober.timeoutCall.active())
70+
71 def check_timeout_call(result):
72 self.failIf(prober.timeoutCall.active())
73+
74 return deferred.addCallback(check_timeout_call)
75
76 def test_failure_cancel_timeout_call(self):
77 prober = ProberFactory(self.urls['500'])
78 deferred = prober.probe()
79 self.failUnless(prober.timeoutCall.active())
80+
81 def check_timeout_call(result):
82 self.failIf(prober.timeoutCall.active())
83+
84 return deferred.addErrback(check_timeout_call)
85
86 def test_notfound(self):
87@@ -299,6 +319,8 @@
88 # Restore the globals that our tests fiddle with.
89 distributionmirror_prober.host_requests = self.orig_host_requests
90 distributionmirror_prober.host_timeouts = self.orig_host_timeouts
91+ # We need to remove any DelayedCalls that didn't actually get called.
92+ clean_up_reactor()
93 super(
94 TestProberFactoryRequestTimeoutRatioWithoutTwisted,
95 self).tearDown()
96@@ -402,22 +424,26 @@
97 host = 'localhost'
98 d = self._createProberAndProbe(
99 u'http://%s:%s/timeout' % (host, self.port))
100+
101 def got_error(error):
102 self.failUnlessEqual(
103 {host: 1}, distributionmirror_prober.host_requests)
104 self.failUnlessEqual(
105 {host: 1}, distributionmirror_prober.host_timeouts)
106+
107 return d.addErrback(got_error)
108
109 def test_non_timeout_is_recorded(self):
110 host = 'localhost'
111 d = self._createProberAndProbe(
112 u'http://%s:%s/valid-mirror' % (host, self.port))
113+
114 def got_result(result):
115 self.failUnlessEqual(
116 {host: 1}, distributionmirror_prober.host_requests)
117 self.failUnlessEqual(
118 {host: 0}, distributionmirror_prober.host_timeouts)
119+
120 return d.addCallback(got_result)
121
122 def test_failure_after_too_many_timeouts(self):
123@@ -518,6 +544,11 @@
124
125 class TestRedirectAwareProberFactoryAndProtocol(TestCase):
126
127+ def tearDown(self):
128+ # We need to remove any DelayedCalls that didn't actually get called.
129+ clean_up_reactor()
130+ super(TestRedirectAwareProberFactoryAndProtocol, self).tearDown()
131+
132 def test_redirect_resets_timeout(self):
133 prober = RedirectAwareProberFactory('http://foo.bar')
134 prober.timeoutCall = FakeTimeOutCall()
135@@ -532,16 +563,20 @@
136 prober = RedirectAwareProberFactory(url)
137 prober.timeoutCall = FakeTimeOutCall()
138 prober.connectCalled = False
139+
140 def connect():
141 prober.connectCalled = True
142+
143 prober.connect = connect
144 return prober
145
146 def test_raises_error_if_redirected_to_different_file(self):
147 prober = self._createFactoryAndStubConnectAndTimeoutCall(
148 'http://foo.bar/baz/boo/package.deb')
149+
150 def failed(error):
151 prober.has_failed = True
152+
153 prober.failed = failed
154 prober.redirect('http://foo.bar/baz/boo/notfound?file=package.deb')
155 self.failUnless(prober.has_failed)
156@@ -622,8 +657,10 @@
157 def getLogger(self):
158 logger = logging.getLogger('distributionmirror-prober')
159 logger.errorCalled = False
160+
161 def error(msg):
162 logger.errorCalled = True
163+
164 logger.error = error
165 return logger
166
167@@ -739,13 +776,16 @@
168 # not a ProberTimeout, a BadResponseCode or a ConnectionSkipped.
169 d = defer.Deferred()
170 d.addErrback(callbacks.deleteMirrorSeries)
171+ ok = []
172+
173 def got_result(result):
174 self.fail(
175 "Any failure that's not a timeout/bad-response/skipped "
176 "should be propagated.")
177- ok = []
178+
179 def got_failure(failure):
180 ok.append(1)
181+
182 d.addCallbacks(got_result, got_failure)
183 d.errback(Failure(ZeroDivisionError()))
184 self.assertEqual([1], ok)
185@@ -786,11 +826,8 @@
186 RequestManager.host_locks.clear()
187
188 def tearDown(self):
189- # XXX: JonathanLange 2010-11-22: These tests leave stacks of delayed
190- # calls around. They need to be updated to use Twisted correctly.
191- # For the meantime, just blat the reactor.
192- for delayed_call in reactor.getDelayedCalls():
193- delayed_call.cancel()
194+ # We need to remove any DelayedCalls that didn't actually get called.
195+ clean_up_reactor()
196 super(TestProbeFunctionSemaphores, self).tearDown()
197
198 def test_MirrorCDImageSeries_records_are_deleted_before_probing(self):
199@@ -879,6 +916,11 @@
200
201 class TestLoggingMixin(TestCase):
202
203+ def tearDown(self):
204+ # We need to remove any DelayedCalls that didn't actually get called.
205+ clean_up_reactor()
206+ super(TestLoggingMixin, self).tearDown()
207+
208 def _fake_gettime(self):
209 # Fake the current time.
210 fake_time = datetime(2004, 10, 20, 12, 00, 00, 000000)