def test_report_power_state_changes_power_state_if_unknown(self): system_id = factory.make_name('system_id') hostname = factory.make_name('hostname') power_state = "unknown" _, _, io = self.patch_rpc_methods() self.patch_autospec(power, 'power_state_update') # Simulate a success when querying state. query = succeed(power_state) report = power.report_power_state(query, system_id, hostname) # This blocks until the deferred is complete. io.flush() self.assertEqual(power_state, extract_result(report)) self.assertThat(power.power_state_update, MockCalledOnceWith(system_id, power_state))
def test_report_power_state_changes_power_state_if_success(self): system_id = factory.make_name("system_id") hostname = factory.make_name("hostname") power_state = random.choice(["on", "off"]) _, _, io = self.patch_rpc_methods() self.patch_autospec(power, "power_state_update") # Simulate a success when querying state. query = succeed(power_state) report = power.report_power_state(query, system_id, hostname) # This blocks until the deferred is complete. io.flush() self.assertEqual(power_state, extract_result(report)) self.assertThat( power.power_state_update, MockCalledOnceWith(system_id, power_state), )
def test_report_power_state_changes_power_state_if_failure(self): system_id = factory.make_name("system_id") hostname = factory.make_name("hostname") err_msg = factory.make_name("error") _, _, io = self.patch_rpc_methods() self.patch_autospec(power, "power_state_update") # Simulate a failure when querying state. query = fail(exceptions.PowerActionFail(err_msg)) report = power.report_power_state(query, system_id, hostname) # This blocks until the deferred is complete. io.flush() error = self.assertRaises(exceptions.PowerActionFail, extract_result, report) self.assertEqual(err_msg, str(error)) self.assertThat(power.power_state_update, MockCalledOnceWith(system_id, "error"))
def test_report_power_state_reports_all_exceptions(self): logger_twisted = self.useFixture(TwistedLoggerFixture()) logger_maaslog = self.useFixture(FakeLogger("maas")) # Avoid threads here. self.patch(power, "deferToThread", maybeDeferred) exception_type = factory.make_exception_type() exception_message = factory.make_string() exception = exception_type(exception_message) # Pretend the query always fails with `exception`. query = self.patch_autospec(power, self.func) query.side_effect = always_fail_with(exception) # Intercept calls to power_state_update() and send_node_event(). power_state_update = self.patch_autospec(power, "power_state_update") power_state_update.return_value = succeed(None) send_node_event = self.patch_autospec(power, "send_node_event") send_node_event.return_value = succeed(None) self.patch( self.power_driver, "detect_missing_packages" ).return_value = [] system_id = factory.make_name("system_id") hostname = factory.make_name("hostname") context = sentinel.context clock = Clock() d = power.get_power_state( system_id, hostname, self.power_type, context, clock ) d = power.report_power_state(d, system_id, hostname) # Crank through some number of retries. for wait in self.waits: self.assertFalse(d.called) clock.advance(wait) self.assertTrue(d.called) # Finally the exception from the query is raised. self.assertRaises(exception_type, extract_result, d) # The broken power query function patched earlier was called the same # number of times as there are steps in the default waiting policy. expected_call = call(system_id, hostname, self.power_type, context) expected_calls = [expected_call] * self.calls self.assertThat(query, MockCallsMatch(*expected_calls)) expected_message = "%s: Power state could not be queried: %s" % ( hostname, exception_message, ) # An attempt was made to report the failure to the region. self.assertThat( power_state_update, MockCalledOnceWith(system_id, "error") ) # An attempt was made to log a node event with details. self.assertThat( send_node_event, MockCalledOnceWith( EVENT_TYPES.NODE_POWER_QUERY_FAILED, system_id, hostname, exception_message, ), ) # Nothing was logged to the Twisted log. self.assertEqual("", logger_twisted.output) # A brief message is written to maaslog. self.assertEqual(expected_message + "\n", logger_maaslog.output)