def test_clears_lock_if_change_power_state_fails(self): class TestException(Exception): pass pcs = self.patch_autospec(power, "power_change_starting") pcs.return_value = fail(TestException("boom")) system_id = factory.make_name("system_id") hostname = factory.make_hostname() power_driver = random.choice( [driver for _, driver in PowerDriverRegistry if driver.queryable] ) power_change = random.choice(["on", "off", "cycle"]) context = sentinel.context logger = self.useFixture(TwistedLoggerFixture()) yield power.maybe_change_power_state( system_id, hostname, power_driver.name, power_change, context ) self.assertNotIn(system_id, power.power_action_registry) self.assertDocTestMatches( """\ %s: Power %s failed. Traceback (most recent call last): ... %s.TestException: boom """ % (hostname, power_change, __name__), logger.dump(), )
def test_calls_change_power_state_later(self): self.patch_methods_using_rpc() system_id = factory.make_name("system_id") hostname = factory.make_name("hostname") power_driver = random.choice( [driver for _, driver in PowerDriverRegistry if driver.queryable] ) power_change = random.choice(["on", "off", "cycle"]) context = { factory.make_name("context-key"): factory.make_name("context-val") } yield power.maybe_change_power_state( system_id, hostname, power_driver.name, power_change, context ) self.assertThat( power.change_power_state, MockCalledOnceWith( system_id, hostname, power_driver.name, power_change, context, power.reactor, ), )
def test_clears_lock_if_change_power_state_is_cancelled(self): # Patch in an unfired Deferred here. This will pause the call so that # we can grab the delayed call from the registry in time to cancel it. self.patch_autospec(power, 'change_power_state') power.change_power_state.return_value = Deferred() self.patch_autospec(power, 'power_change_failure') system_id = factory.make_name('system_id') hostname = factory.make_hostname() power_driver = random.choice( [driver for _, driver in PowerDriverRegistry if driver.queryable]) power_change = random.choice(['on', 'off', 'cycle']) context = sentinel.context logger = self.useFixture(TwistedLoggerFixture()) yield power.maybe_change_power_state(system_id, hostname, power_driver.name, power_change, context) # Get the Deferred from the registry and cancel it. _, d = power.power_action_registry[system_id] d.cancel() yield d self.assertNotIn(system_id, power.power_action_registry) self.assertDocTestMatches( """\ %s: Power could not be set to %s; timed out. """ % (hostname, power_change), logger.dump()) self.assertThat( power.power_change_failure, MockCalledOnceWith(system_id, hostname, power_change, "Timed out"))
def test_clears_lock_if_change_power_state_fails(self): class TestException(Exception): pass pcs = self.patch_autospec(power, 'power_change_starting') pcs.return_value = fail(TestException('boom')) system_id = factory.make_name('system_id') hostname = factory.make_hostname() power_driver = random.choice( [driver for _, driver in PowerDriverRegistry if driver.queryable]) power_change = random.choice(['on', 'off', 'cycle']) context = sentinel.context logger = self.useFixture(TwistedLoggerFixture()) yield power.maybe_change_power_state(system_id, hostname, power_driver.name, power_change, context) reactor.runUntilCurrent() # Run all delayed calls. self.assertNotIn(system_id, power.power_action_registry) self.assertDocTestMatches( """\ %s: Power %s failed. Traceback (most recent call last): ... %s.TestException: boom """ % (hostname, power_change, __name__), logger.dump())
def test_calls_change_power_state_with_timeout(self): self.patch_methods_using_rpc() defer_with_timeout = self.patch(power, "deferWithTimeout") system_id = factory.make_name("system_id") hostname = factory.make_name("hostname") power_driver = random.choice( [driver for _, driver in PowerDriverRegistry if driver.queryable] ) power_change = random.choice(["on", "off", "cycle"]) context = { factory.make_name("context-key"): factory.make_name("context-val") } yield power.maybe_change_power_state( system_id, hostname, power_driver.name, power_change, context ) self.assertThat( defer_with_timeout, MockCalledOnceWith( power.CHANGE_POWER_STATE_TIMEOUT, power.change_power_state, system_id, hostname, power_driver.name, power_change, context, power.reactor, ), )
def test_always_returns_deferred(self): clock = Clock() power_driver = random.choice( [driver for _, driver in PowerDriverRegistry if driver.queryable]) d = power.maybe_change_power_state(sentinel.system_id, sentinel.hostname, power_driver.name, random.choice(("on", "off")), sentinel.context, clock=clock) self.assertThat(d, IsInstance(Deferred))
def test_clears_lock_if_change_power_state_success(self): self.patch_methods_using_rpc() system_id = factory.make_name('system_id') hostname = factory.make_name('hostname') power_driver = random.choice( [driver for _, driver in PowerDriverRegistry if driver.queryable]) power_change = random.choice(['on', 'off', 'cycle']) context = { factory.make_name('context-key'): factory.make_name('context-val') } yield power.maybe_change_power_state(system_id, hostname, power_driver.name, power_change, context) self.assertNotIn(system_id, power.power_action_registry)
def test_checks_missing_packages(self): self.patch_methods_using_rpc() system_id = factory.make_name('system_id') hostname = factory.make_name('hostname') power_driver = random.choice( [driver for _, driver in PowerDriverRegistry if driver.queryable]) power_change = random.choice(['on', 'off', 'cycle']) context = { factory.make_name('context-key'): factory.make_name('context-val') } yield power.maybe_change_power_state(system_id, hostname, power_driver.name, power_change, context) self.assertThat(power_driver.detect_missing_packages, MockCalledOnceWith())
def test_clears_lock_if_change_power_state_success(self): self.patch_methods_using_rpc() system_id = factory.make_name("system_id") hostname = factory.make_name("hostname") power_driver = random.choice( [driver for _, driver in PowerDriverRegistry if driver.queryable]) power_change = random.choice(["on", "off", "cycle"]) context = { factory.make_name("context-key"): factory.make_name("context-val") } yield power.maybe_change_power_state(system_id, hostname, power_driver.name, power_change, context) self.assertNotIn(system_id, power.power_action_registry)
def test_does_nothing_when_change_matches_in_progress_change(self): system_id = factory.make_name('system_id') hostname = factory.make_name('hostname') power_driver = random.choice( [driver for _, driver in PowerDriverRegistry if driver.queryable]) current_power_change = power_change = (random.choice( ['on', 'off', 'cycle'])) context = { factory.make_name('context-key'): factory.make_name('context-val') } power.power_action_registry[system_id] = (current_power_change, sentinel.d) yield power.maybe_change_power_state(system_id, hostname, power_driver.name, power_change, context) self.assertThat(power.power_action_registry, Equals({system_id: (power_change, sentinel.d)}))
def test_errors_when_change_conflicts_with_in_progress_change(self): system_id = factory.make_name('system_id') hostname = factory.make_name('hostname') power_driver = random.choice( [driver for _, driver in PowerDriverRegistry if driver.queryable]) power_changes = ['on', 'off'] random.shuffle(power_changes) current_power_change, power_change = power_changes context = { factory.make_name('context-key'): factory.make_name('context-val') } power.power_action_registry[system_id] = (current_power_change, sentinel.d) with ExpectedException(exceptions.PowerActionAlreadyInProgress): yield power.maybe_change_power_state(system_id, hostname, power_driver.name, power_change, context)
def test_errors_when_missing_packages(self): self.patch_methods_using_rpc() system_id = factory.make_name("system_id") hostname = factory.make_name("hostname") power_driver = random.choice( [driver for _, driver in PowerDriverRegistry if driver.queryable]) power_change = random.choice(["on", "off", "cycle"]) context = { factory.make_name("context-key"): factory.make_name("context-val") } power_driver.detect_missing_packages.return_value = ["gone"] with ExpectedException(exceptions.PowerActionFail): yield power.maybe_change_power_state(system_id, hostname, power_driver.name, power_change, context) self.assertThat(power_driver.detect_missing_packages, MockCalledOnceWith())
def test_adds_action_to_registry(self): self.patch_methods_using_rpc() system_id = factory.make_name('system_id') hostname = factory.make_name('hostname') power_driver = random.choice( [driver for _, driver in PowerDriverRegistry if driver.queryable]) power_change = random.choice(['on', 'off', 'cycle']) context = { factory.make_name('context-key'): factory.make_name('context-val') } yield power.maybe_change_power_state(system_id, hostname, power_driver.name, power_change, context) self.assertEqual({system_id: (power_change, ANY)}, power.power_action_registry) reactor.runUntilCurrent() # Run all delayed calls. self.assertEqual({}, power.power_action_registry)
def test_clears_lock_if_change_power_state_is_cancelled(self): # Patch in an unfired Deferred here. This will pause the call so that # we can grab the delayed call from the registry in time to cancel it. self.patch_autospec(power, "change_power_state") power.change_power_state.return_value = Deferred() self.patch_autospec(power, "power_change_failure") system_id = factory.make_name("system_id") hostname = factory.make_hostname() power_driver = random.choice( [driver for _, driver in PowerDriverRegistry if driver.queryable] ) power_change = random.choice(["on", "off", "cycle"]) context = sentinel.context logger = self.useFixture(TwistedLoggerFixture()) ret = yield power.maybe_change_power_state( system_id, hostname, power_driver.name, power_change, context ) # Get the Deferred from the registry and cancel it. _, d = power.power_action_registry[system_id] d.cancel() yield d # LP: #1761600 - If the deferLater value is returned the RPC call waits # for the power change to complete. This holds up the UI. Make sure # nothing is returned. self.assertIsNone(ret) self.assertNotIn(system_id, power.power_action_registry) self.assertDocTestMatches( """\ %s: Power could not be set to %s; timed out. """ % (hostname, power_change), logger.dump(), ) self.assertThat( power.power_change_failure, MockCalledOnceWith(system_id, hostname, power_change, "Timed out"), )
def test_calls_change_power_state_later(self): self.patch_methods_using_rpc() system_id = factory.make_name('system_id') hostname = factory.make_name('hostname') power_driver = random.choice( [driver for _, driver in PowerDriverRegistry if driver.queryable]) power_change = random.choice(['on', 'off', 'cycle']) context = { factory.make_name('context-key'): factory.make_name('context-val') } yield power.maybe_change_power_state(system_id, hostname, power_driver.name, power_change, context) reactor.runUntilCurrent() # Run all delayed calls. self.assertThat( power.change_power_state, MockCalledOnceWith(system_id, hostname, power_driver.name, power_change, context, power.reactor))
def test_does_nothing_when_change_matches_in_progress_change(self): system_id = factory.make_name("system_id") hostname = factory.make_name("hostname") power_driver = random.choice( [driver for _, driver in PowerDriverRegistry if driver.queryable]) current_power_change = power_change = random.choice( ["on", "off", "cycle"]) context = { factory.make_name("context-key"): factory.make_name("context-val") } power.power_action_registry[system_id] = ( current_power_change, sentinel.d, ) yield power.maybe_change_power_state(system_id, hostname, power_driver.name, power_change, context) self.assertThat( power.power_action_registry, Equals({system_id: (power_change, sentinel.d)}), )
def test__calls_change_power_state_with_timeout(self): self.patch_methods_using_rpc() defer_with_timeout = self.patch(power, 'deferWithTimeout') system_id = factory.make_name('system_id') hostname = factory.make_name('hostname') power_driver = random.choice( [driver for _, driver in PowerDriverRegistry if driver.queryable]) power_change = random.choice(['on', 'off', 'cycle']) context = { factory.make_name('context-key'): factory.make_name('context-val') } yield power.maybe_change_power_state(system_id, hostname, power_driver.name, power_change, context) self.assertThat( defer_with_timeout, MockCalledOnceWith(power.CHANGE_POWER_STATE_TIMEOUT, power.change_power_state, system_id, hostname, power_driver.name, power_change, context, power.reactor))
def test_adds_action_to_registry(self): self.patch_methods_using_rpc() system_id = factory.make_name("system_id") hostname = factory.make_name("hostname") power_driver = random.choice( [driver for _, driver in PowerDriverRegistry if driver.queryable]) power_change = random.choice(["on", "off", "cycle"]) context = { factory.make_name("context-key"): factory.make_name("context-val") } d = power.maybe_change_power_state(system_id, hostname, power_driver.name, power_change, context) # XXX - maybe_change_power_state is resolving before the yield. This # causes power.power_action_registry to be reset before it can be # checked. # self.assertEqual( # {system_id: (power_change, ANY)}, # power.power_action_registry) yield d self.assertEqual({}, power.power_action_registry)