def test_monitorServices_handles_failure(self): # Pretend we're in a production environment. self.patch(sms, "is_dev_environment").return_value = False monitor_service = sms.ServiceMonitorService(sentinel.client_service, Clock()) mock_ensureServices = self.patch(monitor_service, "_getConnection") mock_ensureServices.return_value = fail(factory.make_exception()) with TwistedLoggerFixture() as logger: monitor_service.monitorServices() self.assertDocTestMatches( """\ Failed to monitor services and update region. Traceback (most recent call last): ...""", logger.output)
def test__logs_when_sending_event_errors(self): send_event = self.patch(tftp_module, "send_node_event_mac_address") send_event.side_effect = factory.make_exception() clock = Clock() log_request(sentinel.macaddr, sentinel.filename, clock) self.assertThat(send_event, MockNotCalled()) with TwistedLoggerFixture() as logger: clock.advance(0.0) self.assertDocTestMatches( """\ Logging TFTP request failed. Traceback (most recent call last): ... maastesting.factory.TestException#... """, logger.output)
def test_secure_erase_fails_when_still_enabled_hdparm(self): tmp_dir = self.make_dir() dev_path = (tmp_dir + "/%s").encode("ascii") self.patch(maas_wipe, "DEV_PATH", dev_path) dev_name = factory.make_name("disk").encode("ascii") file_path = dev_path % dev_name self.make_empty_file(file_path) mock_check_output = self.patch(subprocess, "check_output") self.patch(maas_wipe, "get_hdparm_security_info").return_value = { b"enabled": True } exception = factory.make_exception() mock_check_call = self.patch(subprocess, "check_call") mock_check_call.side_effect = exception error = self.assertRaises(WipeError, secure_erase_hdparm, dev_name) self.assertThat( mock_check_call, MockCalledOnceWith( [ b"hdparm", b"--user-master", b"u", b"--security-erase", b"maas", file_path, ] ), ) self.assertThat( mock_check_output, MockCallsMatch( call( [ b"hdparm", b"--user-master", b"u", b"--security-set-pass", b"maas", file_path, ] ), call([b"hdparm", b"--security-disable", b"maas", file_path]), ), ) self.assertEqual("Failed to securely erase.", str(error)) self.assertEqual(exception, error.__cause__)
def test_try_secure_erase_failed_erase(self): disk_name = factory.make_name("disk").encode("ascii") disk_info = { b"supported": True, b"enabled": False, b"locked": False, b"frozen": False, } exception = factory.make_exception() self.patch(maas_wipe, "secure_erase").side_effect = exception self.assertFalse(try_secure_erase(disk_name, disk_info)) self.assertThat( self.print_flush, MockCalledOnceWith("%s: failed to be securely erased: %s" % (disk_name.decode("ascii"), exception)), )
def test__does_log_other_exceptions_when_restarting(self): self.patch_sudo_write_file() self.patch_restartService().side_effect = ( factory.make_exception("DHCP is on strike today")) failover_peers = [make_failover_peer_config()] shared_networks = fix_shared_networks_failover([make_shared_network()], failover_peers) with FakeLogger("maas") as logger: with ExpectedException(exceptions.CannotConfigureDHCP): yield self.configure(factory.make_name('key'), failover_peers, shared_networks, [make_host()], [make_interface()], make_global_dhcp_snippets()) self.assertDocTestMatches( "DHCPv... server failed to restart: " "DHCP is on strike today", logger.output)
def test_secure_erase_writes_known_data(self): tmp_dir = self.make_dir() dev_path = (tmp_dir + "/%s").encode("ascii") self.patch(maas_wipe, "DEV_PATH", dev_path) dev_name = factory.make_name("disk").encode("ascii") file_path = dev_path % dev_name self.make_empty_file(file_path) # Fail at the set-pass to stop the function. mock_check_output = self.patch(subprocess, "check_output") mock_check_output.side_effect = factory.make_exception() self.assertRaises(WipeError, secure_erase, dev_name) expected_buf = b"M" * 1024 * 1024 with open(file_path, "rb") as fp: read_buf = fp.read(len(expected_buf)) self.assertEqual(expected_buf, read_buf, "First 1 MiB of file was not written.")
def test__error_when_starting_is_logged(self): service = self.make_webapp() self.addCleanup(service.stopService) mock_prepare = self.patch_autospec(service, "prepareApplication") mock_prepare.side_effect = factory.make_exception() # The failure is logged. with TwistedLoggerFixture() as logger: service.startService() self.assertDocTestMatches( dedent("""\ MAAS web application failed to start Traceback (most recent call last): ... maastesting.factory.TestException#... """), logger.output)
def test__logs_failures_from_cancelled_hooks(self): logger = self.useFixture(TwistedLoggerFixture()) error = factory.make_exception() dhooks = DeferredHooks() d = Deferred() d.addBoth(lambda _: Failure(error)) dhooks.add(d) dhooks.reset() self.assertThat(dhooks.hooks, HasLength(0)) self.assertThat(d, IsFiredDeferred()) self.assertDocTestMatches( dedent("""\ Failure when cancelling hook. Traceback (most recent call last): ... maastesting.factory.TestException#... """), logger.output)
def test_failures_are_logged(self): deferToDatabase = self.patch(publication, "deferToDatabase") deferToDatabase.return_value = fail(factory.make_exception()) dnsgc = publication.DNSPublicationGarbageService() dnsgc.clock = clock = Clock() with TwistedLoggerFixture() as logger: dnsgc.startService() clock.advance(dnsgc._loop.interval) dnsgc.stopService() self.assertThat( logger.output, DocTestMatches("""\ Failure when removing old DNS publications. Traceback (most recent call last):... Failure: maastesting.factory.TestException#... """)) self.assertFalse(dnsgc.running)
def test_render_GET_500_server_error(self): path = factory.make_name('path') ip = factory.make_ip_address() request = DummyRequest([path.encode('utf-8')]) request.requestHeaders = Headers({ 'X-Server-Addr': ['192.168.1.1'], 'X-Server-Port': ['5248'], 'X-Forwarded-For': [ip], 'X-Forwarded-Port': ['%s' % factory.pick_port()], }) self.patch(http.log, 'info') mock_deferLater = self.patch(http, 'deferLater') mock_deferLater.side_effect = always_succeed_with(None) exc = factory.make_exception("internal error") self.tftp.backend.get_reader.return_value = fail(exc) resource = http.HTTPBootResource() yield self.render_GET(resource, request) self.assertEquals(500, request.responseCode) self.assertEquals(str(exc).encode('utf-8'), b''.join(request.written))
def test__logs_failures_from_cancellers(self): logger = self.useFixture(TwistedLoggerFixture()) canceller = Mock() canceller.side_effect = factory.make_exception() dhooks = DeferredHooks() d = Deferred(canceller) dhooks.add(d) dhooks.reset() self.assertThat(dhooks.hooks, HasLength(0)) # The hook has not been fired, but because the user-supplied canceller # has failed we're not in a position to know what to do. This reflects # a programming error and not a run-time error that we ought to be # prepared for, so it is left as-is. self.assertThat(d, IsUnfiredDeferred()) self.assertDocTestMatches( dedent("""\ Failure when cancelling hook. Traceback (most recent call last): ... maastesting.factory.TestException#... """), logger.output)
def test__tryUpdate_logs_errors_from_broken_method(self): rpc_service, _ = yield prepareRegion(self) self.patch_autospec(ntp, "configure_rack") # No-op configuration. service = ntp.RackNetworkTimeProtocolService(rpc_service, reactor) broken_method = self.patch_autospec(service, self.method) broken_method.side_effect = factory.make_exception() # Ensure that we never actually execute against systemd. self.patch_autospec(service_monitor, "restartService") self.useFixture(MAASRootFixture()) with TwistedLoggerFixture() as logger: yield service._tryUpdate() self.assertThat( logger.output, DocTestMatches(""" Failed to update NTP configuration. Traceback (most recent call last): ... maastesting.factory.TestException#... """))
def test_render_GET_500_server_error(self): path = factory.make_name("path") ip = factory.make_ip_address() request = DummyRequest([path.encode("utf-8")]) request.requestHeaders = Headers({ "X-Server-Addr": ["192.168.1.1"], "X-Server-Port": ["5248"], "X-Forwarded-For": [ip], "X-Forwarded-Port": ["%s" % factory.pick_port()], }) self.patch(http.log, "info") mock_deferLater = self.patch(http, "deferLater") mock_deferLater.side_effect = always_succeed_with(None) exc = factory.make_exception("internal error") self.tftp.backend.get_reader.return_value = fail(exc) resource = http.HTTPBootResource() yield self.render_GET(resource, request) self.assertEqual(500, request.responseCode) self.assertEqual(str(exc).encode("utf-8"), b"".join(request.written))
def test_tryUpdate_logs_errors_from_broken_method(self): # Patch the logger in the clusterservice so no log messages are printed # because the tests run in debug mode. self.patch(common.log, "debug") rpc_service, _ = yield prepareRegion(self) self.patch_autospec(external, "configure_rack") # No-op configuration. ntp = external.RackNTP() service = make_startable_RackExternalService( self, rpc_service, reactor, [("NTP", ntp)] ) broken_method = self.patch_autospec(ntp, self.method) broken_method.side_effect = factory.make_exception() # Ensure that we never actually execute against systemd. self.patch_autospec(service_monitor, "restartService") yield service.startService() self.addCleanup((yield service.stopService)) self.useFixture(MAASRootFixture()) with TwistedLoggerFixture() as logger: yield service._orig_tryUpdate() self.assertThat( logger.output, DocTestMatches( """ Failed to update NTP configuration. Traceback (most recent call last): ... maastesting.factory.TestException#... """ ), )
def raise_exception(service_name): raise factory.make_exception(service_name + " broke")
def test_upgrade_returns_None(self): self.expectThat( ExternalProcessError.upgrade(factory.make_exception()), Is(None) )
def test__writes_config_and_restarts_when_omapi_fails(self): write_file = self.patch_sudo_write_file() get_service_state = self.patch_getServiceState() get_service_state.return_value = ServiceState(SERVICE_STATE.ON, "running") restart_service = self.patch_restartService() ensure_service = self.patch_ensureService() update_hosts = self.patch_update_hosts() update_hosts.side_effect = factory.make_exception() failover_peers = make_failover_peer_config() shared_network = make_shared_network() [shared_network] = fix_shared_networks_failover([shared_network], [failover_peers]) old_hosts = [make_host(dhcp_snippets=[]) for _ in range(3)] interface = make_interface() global_dhcp_snippets = make_global_dhcp_snippets() expected_config = factory.make_name("config") self.patch_get_config().return_value = expected_config dhcp_service = dhcp.service_monitor.getServiceByName( self.server.dhcp_service) on = self.patch_autospec(dhcp_service, "on") omapi_key = factory.make_name("omapi_key") old_state = dhcp.DHCPState( omapi_key, [failover_peers], [shared_network], old_hosts, [interface], global_dhcp_snippets, ) dhcp._current_server_state[self.server.dhcp_service] = old_state new_hosts = copy.deepcopy(old_hosts) removed_host = new_hosts.pop() modified_host = new_hosts[0] modified_host["ip"] = factory.make_ip_address() added_host = make_host(dhcp_snippets=[]) new_hosts.append(added_host) with FakeLogger("maas") as logger: yield self.configure( omapi_key, [failover_peers], [shared_network], new_hosts, [interface], global_dhcp_snippets, ) self.assertThat( write_file, MockCallsMatch( call( self.server.config_filename, expected_config.encode("utf-8"), mode=0o640, ), call( self.server.interfaces_filename, interface["name"].encode("utf-8"), mode=0o640, ), ), ) self.assertThat(on, MockCalledOnceWith()) self.assertThat( get_service_state, MockCalledOnceWith(self.server.dhcp_service, now=True), ) self.assertThat(restart_service, MockCalledOnceWith(self.server.dhcp_service)) self.assertThat(ensure_service, MockCalledOnceWith(self.server.dhcp_service)) self.assertThat( update_hosts, MockCalledOnceWith(ANY, [removed_host], [added_host], [modified_host]), ) self.assertEquals( dhcp._current_server_state[self.server.dhcp_service], dhcp.DHCPState( omapi_key, [failover_peers], [shared_network], new_hosts, [interface], global_dhcp_snippets, ), ) self.assertDocTestMatches( "Failed to update all host maps. Restarting DHCPv... " "service to ensure host maps are in-sync.", logger.output, )
def canceller(d): d.callback(None) raise factory.make_exception()