Merge lp:~allenap/maas/region-leaky-tests into lp:~maas-committers/maas/trunk

Proposed by Gavin Panella
Status: Merged
Merged at revision: 5028
Proposed branch: lp:~allenap/maas/region-leaky-tests
Merge into: lp:~maas-committers/maas/trunk
Diff against target: 666 lines (+154/-50)
16 files modified
src/maasserver/api/tests/test_boot_resources.py (+11/-0)
src/maasserver/api/tests/test_machine.py (+4/-2)
src/maasserver/api/tests/test_tag.py (+4/-0)
src/maasserver/models/signals/testing.py (+48/-0)
src/maasserver/models/signals/tests/test_power.py (+9/-6)
src/maasserver/rack_controller.py (+4/-1)
src/maasserver/rpc/tests/test_regionservice.py (+4/-19)
src/maasserver/tests/test_bootresources.py (+7/-0)
src/maasserver/tests/test_node_action.py (+2/-0)
src/maasserver/tests/test_rack_controller.py (+1/-1)
src/maasserver/tests/test_region_controller.py (+9/-0)
src/maasserver/tests/test_status_monitor.py (+5/-5)
src/maasserver/utils/tests/test_osystems.py (+4/-11)
src/maastesting/testcase.py (+14/-3)
src/metadataserver/tests/test_api.py (+23/-2)
src/metadataserver/tests/test_api_status.py (+5/-0)
To merge this branch: bzr merge lp:~allenap/maas/region-leaky-tests
Reviewer Review Type Date Requested Status
Jeffrey C Jones (community) Approve
LaMont Jones (community) Approve
MAAS Maintainers Pending
Review via email: mp+294666@code.launchpad.net

Commit message

Fix many leaky tests, re-enable regionservice tests, and make MAASCrochetRunTest the default when appropriate.

To post a comment you must log in.
Revision history for this message
Gavin Panella (allenap) wrote :

With the exception of the following, this changes only tests:

--- src/maasserver/rack_controller.py   2016-05-11 19:01:48 +0000
+++ src/maasserver/rack_controller.py   2016-05-13 16:12:12 +0000
@@ -205,7 +205,10 @@

     def process(self):
         """Process the next rack controller that needs an update."""
-        if len(self.needsDHCPUpdate) == 0:
+        if not self.running:
+            # We're shutting down.
+            self.processing.stop()
+        elif len(self.needsDHCPUpdate) == 0:
             # Nothing more to do.
             self.processing.stop()
         else:

Revision history for this message
LaMont Jones (lamont) wrote :

Looks reasonable.

review: Approve
Revision history for this message
Jeffrey C Jones (trapnine) wrote :

Lgtm. Glad we're fixing these.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'src/maasserver/api/tests/test_boot_resources.py'
2--- src/maasserver/api/tests/test_boot_resources.py 2016-02-26 18:48:26 +0000
3+++ src/maasserver/api/tests/test_boot_resources.py 2016-05-16 09:22:35 +0000
4@@ -14,6 +14,7 @@
5 boot_resource_set_to_dict,
6 boot_resource_to_dict,
7 )
8+from maasserver.clusterrpc.boot_images import RackControllersImporter
9 from maasserver.enum import (
10 BOOT_RESOURCE_FILE_TYPE,
11 BOOT_RESOURCE_TYPE,
12@@ -113,6 +114,11 @@
13 dict_representation['sets'][resource_set.version])
14
15
16+def prevent_scheduling_of_image_imports(test):
17+ """Make `RackControllersImporter.schedule` a no-op."""
18+ test.patch_autospec(RackControllersImporter, "schedule")
19+
20+
21 class TestBootResourcesAPI(APITestCase):
22 """Test the the boot resource API."""
23
24@@ -211,6 +217,7 @@
25 return upload_type, filetype
26
27 def test_POST_creates_boot_resource(self):
28+ prevent_scheduling_of_image_imports(self)
29 self.become_admin()
30
31 name = factory.make_name('name')
32@@ -241,6 +248,7 @@
33 self.assertEqual(sample_binary_data, written_data)
34
35 def test_POST_creates_boot_resource_with_default_filetype(self):
36+ prevent_scheduling_of_image_imports(self)
37 self.become_admin()
38
39 name = factory.make_name('name')
40@@ -330,6 +338,7 @@
41 self.assertEqual(http.client.BAD_REQUEST, response.status_code)
42
43 def test_POST_returns_full_definition_of_boot_resource(self):
44+ prevent_scheduling_of_image_imports(self)
45 self.become_admin()
46
47 name = factory.make_name('name')
48@@ -464,6 +473,7 @@
49 reverse('boot_resource_file_upload_handler', args=['3', '5']))
50
51 def test_PUT_resource_file_writes_content(self):
52+ prevent_scheduling_of_image_imports(self)
53 self.become_admin()
54 rfile, content = self.make_empty_resource_file()
55 response = self.client.put(
56@@ -541,6 +551,7 @@
57 MockCalledOnceWith())
58
59 def test_PUT_with_multiple_requests_and_large_content(self):
60+ prevent_scheduling_of_image_imports(self)
61 self.become_admin()
62
63 # Get large amount of data to test with
64
65=== modified file 'src/maasserver/api/tests/test_machine.py'
66--- src/maasserver/api/tests/test_machine.py 2016-05-12 19:07:37 +0000
67+++ src/maasserver/api/tests/test_machine.py 2016-05-16 09:22:35 +0000
68@@ -36,6 +36,7 @@
69 StaticIPAddress,
70 )
71 from maasserver.models.node import RELEASABLE_STATUSES
72+from maasserver.models.signals.testing import SignalsDisabled
73 from maasserver.storage_layouts import (
74 MIN_BOOT_PARTITION_SIZE,
75 StorageLayoutError,
76@@ -1382,8 +1383,9 @@
77 machine_stop = self.patch(node_module.Machine, "_stop")
78 machine_stop.side_effect = lambda user: post_commit()
79
80- response = self.client.post(
81- self.get_machine_uri(machine), {'op': 'abort'})
82+ with SignalsDisabled("power"):
83+ response = self.client.post(
84+ self.get_machine_uri(machine), {'op': 'abort'})
85
86 self.assertEqual(http.client.OK, response.status_code)
87 self.assertEqual(
88
89=== modified file 'src/maasserver/api/tests/test_tag.py'
90--- src/maasserver/api/tests/test_tag.py 2016-05-12 19:07:37 +0000
91+++ src/maasserver/api/tests/test_tag.py 2016-05-16 09:22:35 +0000
92@@ -503,6 +503,7 @@
93 self.assertFalse(Tag.objects.filter(name=name).exists())
94
95 def test_POST_new_creates_tag(self):
96+ self.patch_autospec(Tag, "populate_nodes")
97 self.become_admin()
98 name = factory.make_string()
99 definition = '//node'
100@@ -521,6 +522,7 @@
101 self.assertEqual(comment, parsed_result['comment'])
102 self.assertEqual(definition, parsed_result['definition'])
103 self.assertTrue(Tag.objects.filter(name=name).exists())
104+ self.assertThat(Tag.populate_nodes, MockCalledOnceWith(ANY))
105
106 def test_POST_new_without_definition_creates_tag(self):
107 self.become_admin()
108@@ -562,6 +564,7 @@
109 self.assertFalse(Tag.objects.filter(name=invalid).exists())
110
111 def test_POST_new_kernel_opts(self):
112+ self.patch_autospec(Tag, "populate_nodes")
113 self.become_admin()
114 name = factory.make_string()
115 definition = '//node'
116@@ -584,6 +587,7 @@
117 self.assertEqual(extra_kernel_opts, parsed_result['kernel_opts'])
118 self.assertEqual(
119 extra_kernel_opts, Tag.objects.filter(name=name)[0].kernel_opts)
120+ self.assertThat(Tag.populate_nodes, MockCalledOnceWith(ANY))
121
122 def test_POST_new_populates_nodes(self):
123 populate_nodes = self.patch_autospec(Tag, "populate_nodes")
124
125=== added file 'src/maasserver/models/signals/testing.py'
126--- src/maasserver/models/signals/testing.py 1970-01-01 00:00:00 +0000
127+++ src/maasserver/models/signals/testing.py 2016-05-16 09:22:35 +0000
128@@ -0,0 +1,48 @@
129+# Copyright 2016 Canonical Ltd. This software is licensed under the
130+# GNU Affero General Public License version 3 (see the file LICENSE).
131+
132+"""Testing helpers for dealing with signals."""
133+
134+__all__ = [
135+ "SignalsDisabled",
136+]
137+
138+from fixtures import Fixture
139+from maasserver.models import signals
140+
141+
142+class SignalsDisabled(Fixture):
143+ """Disable all signals managed by `SignalsManager`.
144+
145+ By convention, modules imported into `maasserver.models.signals` ought to
146+ have a ``signals`` attribute which is an instance of `SignalsManager`.
147+ """
148+
149+ managers = {
150+ name: getattr(signals, name).signals
151+ for name in signals.__all__
152+ }
153+
154+ def __init__(self, *disable):
155+ """Initialise a new `SignalsDisabled` fixture.
156+
157+ :param disable: The signal managers to disable. Can be specified as
158+ names of managers or as `SignalsManager` instances. If no managers
159+ are specified, ALL managers will be disabled. If the manager is
160+ already disabled it will not be enabled at clean-up.
161+ """
162+ super(SignalsDisabled, self).__init__()
163+ if len(disable) == 0:
164+ self.disable = self.managers.values()
165+ else:
166+ self.disable = {
167+ self.managers[d] if isinstance(d, str) else d
168+ for d in disable
169+ }
170+
171+ def setUp(self):
172+ super(SignalsDisabled, self).setUp()
173+ for manager in self.disable:
174+ if manager.enabled:
175+ self.addCleanup(manager.enable)
176+ manager.disable()
177
178=== modified file 'src/maasserver/models/signals/tests/test_power.py'
179--- src/maasserver/models/signals/tests/test_power.py 2016-05-12 19:07:37 +0000
180+++ src/maasserver/models/signals/tests/test_power.py 2016-05-16 09:22:35 +0000
181@@ -45,12 +45,15 @@
182 old_status = NODE_STATUS.COMMISSIONING
183 node = factory.make_Node(status=old_status, power_type='virsh')
184 node.status = get_failed_status(old_status)
185- node.save()
186- # update_power_state_of_node_soon is registered as a post-commit task,
187- # so it's not called immediately.
188- self.expectThat(
189- power.update_power_state_of_node_soon,
190- MockNotCalled())
191+
192+ with post_commit_hooks:
193+ node.save()
194+ # update_power_state_of_node_soon is registered as a post-commit
195+ # task, so it's not called immediately.
196+ self.expectThat(
197+ power.update_power_state_of_node_soon,
198+ MockNotCalled())
199+
200 # One post-commit hooks have been fired, then it's called.
201 post_commit_hooks.fire()
202 self.assertThat(
203
204=== modified file 'src/maasserver/rack_controller.py'
205--- src/maasserver/rack_controller.py 2016-05-11 19:01:48 +0000
206+++ src/maasserver/rack_controller.py 2016-05-16 09:22:35 +0000
207@@ -205,7 +205,10 @@
208
209 def process(self):
210 """Process the next rack controller that needs an update."""
211- if len(self.needsDHCPUpdate) == 0:
212+ if not self.running:
213+ # We're shutting down.
214+ self.processing.stop()
215+ elif len(self.needsDHCPUpdate) == 0:
216 # Nothing more to do.
217 self.processing.stop()
218 else:
219
220=== modified file 'src/maasserver/rpc/tests/test_regionservice.py'
221--- src/maasserver/rpc/tests/test_regionservice.py 2016-05-13 21:51:16 +0000
222+++ src/maasserver/rpc/tests/test_regionservice.py 2016-05-16 09:22:35 +0000
223@@ -58,6 +58,7 @@
224 timestampedmodel,
225 )
226 from maasserver.models.interface import PhysicalInterface
227+from maasserver.models.signals.testing import SignalsDisabled
228 from maasserver.models.timestampedmodel import now
229 from maasserver.rpc import (
230 events as events_module,
231@@ -198,24 +199,6 @@
232 wait_for_reactor = wait_for(30) # 30 seconds.
233
234
235-class SkipAll:
236-
237- skipReason = "XXX: GavinPanella 2016-04-12 bug=1572646: Fails spuriously."
238-
239- def setUp(self):
240- super(SkipAll, self).setUp()
241- self.skipTest(self.skipReason)
242-
243- @classmethod
244- def make(cls, base):
245- return type(base.__name__, (cls, base), {})
246-
247-
248-MAASTestCase = SkipAll.make(MAASTestCase)
249-MAASServerTestCase = SkipAll.make(MAASServerTestCase)
250-MAASTransactionServerTestCase = SkipAll.make(MAASTransactionServerTestCase)
251-
252-
253 @transactional
254 def transactional_reload_object(obj):
255 return reload_object(obj)
256@@ -517,6 +500,7 @@
257 "ports": urlparse("http://ports.ubuntu.com/ubuntu-ports")},
258 response)
259
260+ @wait_for_reactor
261 @inlineCallbacks
262 def test_get_archive_mirrors_with_ports_archive_set(self):
263 url = factory.make_parsed_url()
264@@ -525,7 +509,7 @@
265 response = yield call_responder(Region(), GetArchiveMirrors, {})
266
267 self.assertEqual(
268- {"main": urlparse("http://arhive.ubuntu.com/ubuntu"),
269+ {"main": urlparse("http://archive.ubuntu.com/ubuntu"),
270 "ports": url},
271 response)
272
273@@ -590,6 +574,7 @@
274 @wait_for_reactor
275 @inlineCallbacks
276 def test_mark_node_failed_changes_status_and_updates_error_msg(self):
277+ self.useFixture(SignalsDisabled("power"))
278 system_id = yield deferToDatabase(self.create_deploying_node)
279
280 error_description = factory.make_name('error-description')
281
282=== modified file 'src/maasserver/tests/test_bootresources.py'
283--- src/maasserver/tests/test_bootresources.py 2016-05-12 19:07:37 +0000
284+++ src/maasserver/tests/test_bootresources.py 2016-05-16 09:22:35 +0000
285@@ -59,6 +59,7 @@
286 Config,
287 LargeFile,
288 )
289+from maasserver.models.signals.testing import SignalsDisabled
290 from maasserver.rpc.testing.fixtures import MockLiveRegionToClusterRPCFixture
291 from maasserver.testing.config import RegionConfigurationFixture
292 from maasserver.testing.dblocks import lock_held_in_other_thread
293@@ -723,6 +724,7 @@
294 mock_prevent, MockNotCalled())
295
296 def test_get_or_create_boot_resource_set_creates_resource_set(self):
297+ self.useFixture(SignalsDisabled("largefiles"))
298 name, architecture, product = make_product()
299 product, resource = make_boot_resource_group_from_product(product)
300 with post_commit_hooks:
301@@ -742,6 +744,7 @@
302 self.assertEqual(product['label'], resource_set.label)
303
304 def test_get_or_create_boot_resource_file_creates_resource_file(self):
305+ self.useFixture(SignalsDisabled("largefiles"))
306 name, architecture, product = make_product()
307 product, resource = make_boot_resource_group_from_product(product)
308 resource_set = resource.sets.first()
309@@ -888,6 +891,7 @@
310 self.assertThat(mock_save_later, MockNotCalled())
311
312 def test_insert_deletes_mismatch_largefile(self):
313+ self.useFixture(SignalsDisabled("largefiles"))
314 name, architecture, product = make_product()
315 with transaction.atomic():
316 product, resource = make_boot_resource_group_from_product(product)
317@@ -905,6 +909,7 @@
318 self.assertThat(mock_save_later, MockNotCalled())
319
320 def test_insert_prints_warning_if_mismatch_largefile(self):
321+ self.useFixture(SignalsDisabled("largefiles"))
322 name, architecture, product = make_product()
323 with transaction.atomic():
324 product, resource = make_boot_resource_group_from_product(product)
325@@ -986,6 +991,7 @@
326 # Test case for bug 1419041: if the call to insert() makes
327 # an existing complete resource incomplete: print an error in the
328 # log.
329+ self.useFixture(SignalsDisabled("largefiles"))
330 name, architecture, product = make_product()
331 with transaction.atomic():
332 resource = factory.make_BootResource(
333@@ -1057,6 +1063,7 @@
334 BootResourceSet.objects.filter(id=incomplete_set.id).exists())
335
336 def test_resource_set_cleaner_keeps_only_newest_completed_set(self):
337+ self.useFixture(SignalsDisabled("largefiles"))
338 with transaction.atomic():
339 resource = factory.make_BootResource(
340 rtype=BOOT_RESOURCE_TYPE.SYNCED)
341
342=== modified file 'src/maasserver/tests/test_node_action.py'
343--- src/maasserver/tests/test_node_action.py 2016-05-12 19:07:37 +0000
344+++ src/maasserver/tests/test_node_action.py 2016-05-16 09:22:35 +0000
345@@ -25,6 +25,7 @@
346 signals,
347 StaticIPAddress,
348 )
349+from maasserver.models.signals.testing import SignalsDisabled
350 from maasserver.node_action import (
351 Abort,
352 Acquire,
353@@ -297,6 +298,7 @@
354 class TestAbortAction(MAASTransactionServerTestCase):
355
356 def test_Abort_aborts_disk_erasing(self):
357+ self.useFixture(SignalsDisabled("power"))
358 with transaction.atomic():
359 owner = factory.make_User()
360 node = factory.make_Node(
361
362=== modified file 'src/maasserver/tests/test_rack_controller.py'
363--- src/maasserver/tests/test_rack_controller.py 2016-05-12 19:07:37 +0000
364+++ src/maasserver/tests/test_rack_controller.py 2016-05-16 09:22:35 +0000
365@@ -312,7 +312,7 @@
366 service.running = False
367 mock_processDHCP = self.patch(service, "processDHCP")
368 service.startProcessing()
369- yield service.processing
370+ yield service.processingDone
371 self.assertThat(mock_processDHCP, MockNotCalled())
372
373 @wait_for_reactor
374
375=== modified file 'src/maasserver/tests/test_region_controller.py'
376--- src/maasserver/tests/test_region_controller.py 2016-05-12 19:07:37 +0000
377+++ src/maasserver/tests/test_region_controller.py 2016-05-16 09:22:35 +0000
378@@ -46,28 +46,37 @@
379 needsDNSUpdate=False,
380 postgresListener=sentinel.listener))
381
382+ @wait_for_reactor
383+ @inlineCallbacks
384 def test_startService_registers_with_postgres_listener(self):
385 listener = MagicMock()
386 service = RegionControllerService(listener)
387 service.startService()
388+ yield service.processingDefer
389 self.assertThat(
390 listener.register,
391 MockCallsMatch(
392 call("sys_dns", service.markDNSForUpdate),
393 call("sys_proxy", service.markProxyForUpdate)))
394
395+ @wait_for_reactor
396+ @inlineCallbacks
397 def test_startService_calls_markDNSForUpdate(self):
398 listener = MagicMock()
399 service = RegionControllerService(listener)
400 mock_markDNSForUpdate = self.patch(service, "markDNSForUpdate")
401 service.startService()
402+ yield service.processingDefer
403 self.assertThat(mock_markDNSForUpdate, MockCalledOnceWith(None, None))
404
405+ @wait_for_reactor
406+ @inlineCallbacks
407 def test_startService_calls_markProxyForUpdate(self):
408 listener = MagicMock()
409 service = RegionControllerService(listener)
410 mock_markProxyForUpdate = self.patch(service, "markProxyForUpdate")
411 service.startService()
412+ yield service.processingDefer
413 self.assertThat(
414 mock_markProxyForUpdate, MockCalledOnceWith(None, None))
415
416
417=== modified file 'src/maasserver/tests/test_status_monitor.py'
418--- src/maasserver/tests/test_status_monitor.py 2016-05-12 19:07:37 +0000
419+++ src/maasserver/tests/test_status_monitor.py 2016-05-16 09:22:35 +0000
420@@ -13,13 +13,13 @@
421 from unittest.mock import call
422
423 from maasserver import status_monitor
424+from maasserver.models.signals.testing import SignalsDisabled
425 from maasserver.node_status import NODE_FAILURE_STATUS_TRANSITIONS
426 from maasserver.status_monitor import (
427 mark_nodes_failed_after_expiring,
428 StatusMonitorService,
429 )
430 from maasserver.testing.factory import factory
431-from maasserver.testing.orm import post_commit_hooks
432 from maasserver.testing.testcase import MAASServerTestCase
433 from maasserver.utils.orm import reload_object
434 from maastesting.matchers import (
435@@ -34,6 +34,7 @@
436 class TestMarkNodesFailedAfterExpiring(MAASServerTestCase):
437
438 def test__marks_all_possible_failed_status_as_failed(self):
439+ self.useFixture(SignalsDisabled("power"))
440 current_time = datetime.now()
441 self.patch(status_monitor, "now").return_value = current_time
442 expired_time = current_time - timedelta(minutes=1)
443@@ -41,8 +42,7 @@
444 factory.make_Node(status=status, status_expires=expired_time)
445 for status in NODE_FAILURE_STATUS_TRANSITIONS.keys()
446 ]
447- with post_commit_hooks:
448- mark_nodes_failed_after_expiring()
449+ mark_nodes_failed_after_expiring()
450 failed_statuses = [
451 reload_object(node).status
452 for node in nodes
453@@ -51,6 +51,7 @@
454 NODE_FAILURE_STATUS_TRANSITIONS.values(), failed_statuses)
455
456 def test__skips_those_that_have_not_expired(self):
457+ self.useFixture(SignalsDisabled("power"))
458 current_time = datetime.now()
459 self.patch(status_monitor, "now").return_value = current_time
460 expired_time = current_time + timedelta(minutes=1)
461@@ -58,8 +59,7 @@
462 factory.make_Node(status=status, status_expires=expired_time)
463 for status in NODE_FAILURE_STATUS_TRANSITIONS.keys()
464 ]
465- with post_commit_hooks:
466- mark_nodes_failed_after_expiring()
467+ mark_nodes_failed_after_expiring()
468 failed_statuses = [
469 reload_object(node).status
470 for node in nodes
471
472=== modified file 'src/maasserver/utils/tests/test_osystems.py'
473--- src/maasserver/utils/tests/test_osystems.py 2015-12-01 18:12:59 +0000
474+++ src/maasserver/utils/tests/test_osystems.py 2016-05-16 09:22:35 +0000
475@@ -16,14 +16,13 @@
476 )
477 from maasserver.models import (
478 BootResource,
479- BootSourceCache,
480 Config,
481 )
482+from maasserver.models.signals.testing import SignalsDisabled
483 from maasserver.testing.factory import factory
484 from maasserver.testing.osystems import make_usable_osystem
485 from maasserver.testing.testcase import MAASServerTestCase
486 from maasserver.utils import osystems as osystems_module
487-from maasserver.utils.orm import post_commit_hooks
488 from maasserver.utils.osystems import (
489 get_distro_series_initial,
490 get_release_requires_key,
491@@ -260,17 +259,11 @@
492 self.assertEqual(choices, list_commissioning_choices([osystem]))
493
494 def test_make_hwe_kernel_ui_text_finds_release_from_bootsourcecache(self):
495+ self.useFixture(SignalsDisabled("bootsources"))
496 release = factory.pick_ubuntu_release()
497 kernel = 'hwe-' + release[0]
498- # Stub out the post commit tasks otherwise the test fails due to
499- # unrun post-commit tasks at the end of the test.
500- self.patch(BootSourceCache, "post_commit_do")
501- # Force run the post commit tasks as we make new boot sources
502- with post_commit_hooks:
503- factory.make_BootSourceCache(
504- os="ubuntu/%s" % release,
505- subarch=kernel,
506- release=release)
507+ factory.make_BootSourceCache(
508+ os="ubuntu/%s" % release, subarch=kernel, release=release)
509 self.assertEqual(
510 '%s (%s)' % (release, kernel),
511 make_hwe_kernel_ui_text(kernel))
512
513=== modified file 'src/maastesting/testcase.py'
514--- src/maastesting/testcase.py 2016-05-12 19:07:37 +0000
515+++ src/maastesting/testcase.py 2016-05-16 09:22:35 +0000
516@@ -16,11 +16,13 @@
517 import os
518 from unittest import mock
519
520+import crochet
521 from maastesting.crochet import EventualResultCatchingMixin
522 from maastesting.factory import factory
523 from maastesting.fixtures import TempDirectory
524 from maastesting.matchers import DocTestMatches
525 from maastesting.runtest import (
526+ MAASCrochetRunTest,
527 MAASRunTest,
528 MAASTwistedRunTest,
529 )
530@@ -100,9 +102,6 @@
531
532 """
533
534- # Use a customised executor.
535- run_tests_with = MAASRunTest
536-
537 # Allow testtools to generate longer diffs when tests fail.
538 maxDiff = testtools.TestCase.maxDiff * 3
539
540@@ -126,6 +125,18 @@
541 database_use_possible = "DJANGO_SETTINGS_MODULE" in os.environ
542 database_use_permitted = False
543
544+ @property
545+ def run_tests_with(self):
546+ """Use a customised executor.
547+
548+ If crochet is managing the Twisted reactor, use `MAASCrochetRunTest`,
549+ otherwise default to `MAASRunTest`.
550+ """
551+ if crochet._watchdog.is_alive():
552+ return MAASCrochetRunTest
553+ else:
554+ return MAASRunTest
555+
556 def setUp(self):
557 self.maybeCloseDatabaseConnections()
558 super(MAASTestCase, self).setUp()
559
560=== modified file 'src/metadataserver/tests/test_api.py'
561--- src/metadataserver/tests/test_api.py 2016-05-12 19:07:37 +0000
562+++ src/metadataserver/tests/test_api.py 2016-05-16 09:22:35 +0000
563@@ -39,6 +39,7 @@
564 Tag,
565 )
566 from maasserver.models.node import Node
567+from maasserver.models.signals.testing import SignalsDisabled
568 from maasserver.rpc.testing.mixins import PreseedRPCMixin
569 from maasserver.testing.config import RegionConfigurationFixture
570 from maasserver.testing.factory import factory
571@@ -500,6 +501,10 @@
572 class TestMetadataUserDataStateChanges(MAASServerTestCase):
573 """Tests for the metadata user-data API endpoint."""
574
575+ def setUp(self):
576+ super(TestMetadataUserDataStateChanges, self).setUp()
577+ self.useFixture(SignalsDisabled("power"))
578+
579 def test_request_does_not_cause_status_change_if_not_deploying(self):
580 status = factory.pick_enum(
581 NODE_STATUS, but_not=[NODE_STATUS.DEPLOYING])
582@@ -545,6 +550,10 @@
583
584 class TestInstallingAPI(MAASServerTestCase):
585
586+ def setUp(self):
587+ super(TestInstallingAPI, self).setUp()
588+ self.useFixture(SignalsDisabled("power"))
589+
590 def test_other_user_than_node_cannot_signal_installation_result(self):
591 node = factory.make_Node(status=NODE_STATUS.DEPLOYING)
592 client = OAuthAuthenticatedClient(factory.make_User())
593@@ -617,6 +626,10 @@
594
595 class TestCommissioningAPI(MAASServerTestCase):
596
597+ def setUp(self):
598+ super(TestCommissioningAPI, self).setUp()
599+ self.useFixture(SignalsDisabled("power"))
600+
601 def test_commissioning_scripts(self):
602 script = factory.make_CommissioningScript()
603 response = make_node_client().get(
604@@ -841,6 +854,7 @@
605 self.assertEqual('', reload_object(node).error)
606
607 def test_signalling_stores_files_for_any_status(self):
608+ self.useFixture(SignalsDisabled("power"))
609 statuses = ['WORKING', 'OK', 'FAILED']
610 filename = factory.make_string()
611 nodes = {
612@@ -962,8 +976,10 @@
613 power_address=factory.make_ipv4_address(),
614 power_user=factory.make_string(),
615 power_pass=factory.make_string())
616- response = call_signal(
617- client, power_type="moonshot", power_parameters=json.dumps(params))
618+ with SignalsDisabled("power"):
619+ response = call_signal(
620+ client, power_type="moonshot",
621+ power_parameters=json.dumps(params))
622 self.assertEqual(
623 http.client.OK, response.status_code, response.content)
624 node = reload_object(node)
625@@ -1065,6 +1081,7 @@
626 MockNotCalled())
627
628 def test_signal_calls_sets_initial_network_config_if_OK(self):
629+ self.useFixture(SignalsDisabled("power"))
630 mock_set_initial_networking_configuration = self.patch_autospec(
631 Node, "set_initial_networking_configuration")
632 node = factory.make_Node(status=NODE_STATUS.COMMISSIONING)
633@@ -1112,6 +1129,10 @@
634
635 class TestDiskErasingAPI(MAASServerTestCase):
636
637+ def setUp(self):
638+ super(TestDiskErasingAPI, self).setUp()
639+ self.useFixture(SignalsDisabled("power"))
640+
641 def test_signaling_erasing_failure_makes_node_failed_erasing(self):
642 node = factory.make_Node(
643 status=NODE_STATUS.DISK_ERASING, owner=factory.make_User())
644
645=== modified file 'src/metadataserver/tests/test_api_status.py'
646--- src/metadataserver/tests/test_api_status.py 2016-05-12 19:07:37 +0000
647+++ src/metadataserver/tests/test_api_status.py 2016-05-16 09:22:35 +0000
648@@ -20,6 +20,7 @@
649 Event,
650 Tag,
651 )
652+from maasserver.models.signals.testing import SignalsDisabled
653 from maasserver.testing.factory import factory
654 from maasserver.testing.oauthclient import OAuthAuthenticatedClient
655 from maasserver.testing.testcase import MAASServerTestCase
656@@ -66,6 +67,10 @@
657
658 class TestStatusAPI(MAASServerTestCase):
659
660+ def setUp(self):
661+ super(TestStatusAPI, self).setUp()
662+ self.useFixture(SignalsDisabled("power"))
663+
664 def test_other_user_than_node_cannot_signal_installation_result(self):
665 node = factory.make_Node(status=NODE_STATUS.DEPLOYING)
666 client = OAuthAuthenticatedClient(factory.make_User())