def test_debugging_logger_logs_binary_response(self): logger = self.useFixture(FakeLogger('maasserver', logging.DEBUG)) request = fake_request("foo") response = HttpResponse( content=sample_binary_data, status=httplib.OK, mimetype=b"application/octet-stream") DebuggingLoggerMiddleware().process_response(request, response) self.assertThat( logger.output, Contains("non-utf-8 (binary?) content"))
def test_delete_sprint_owner(self): # A sprint can be deleted by its owner, even if it has attendees and # specifications. self.useFixture(FakeLogger()) sprint = self.makePopulatedSprint() sprint_url = canonical_url(sprint) owner_url = canonical_url(sprint.owner) browser = self.getViewBrowser(sprint, user=sprint.owner) browser.getLink("Delete sprint").click() browser.getControl("Delete sprint").click() self.assertEqual(owner_url, browser.url) self.assertRaises(NotFound, browser.open, sprint_url)
def test__logs_warning_for_external_dhcp_on_interface_no_vlan(self): rack_controller = factory.make_RackController(interface=False) interface = factory.make_Interface( INTERFACE_TYPE.PHYSICAL, node=rack_controller) dhcp_ip = factory.make_ip_address() interface.vlan = None interface.save() logger = self.useFixture(FakeLogger()) update_foreign_dhcp( rack_controller.system_id, interface.name, dhcp_ip) self.assertThat(logger.output, DocTestMatches( "...DHCP server on an interface with no VLAN defined..."))
def test_unauthorized(self): # A user without edit access cannot delete a sprint. self.useFixture(FakeLogger()) sprint = self.makePopulatedSprint() sprint_url = canonical_url(sprint) other_person = self.factory.makePerson() browser = self.getViewBrowser(sprint, user=other_person) self.assertRaises(LinkNotFoundError, browser.getLink, "Delete sprint") self.assertRaises(Unauthorized, self.getUserBrowser, sprint_url + "/+delete", user=other_person)
def test__does_log_other_exceptions(self): self.patch_sudo_write_file() self.patch_sudo_delete_file() self.patch_ensureService().side_effect = ( factory.make_exception("DHCP is on strike today")) with FakeLogger("maas") as logger: with ExpectedException(exceptions.CannotConfigureDHCP): yield self.configure( factory.make_name('key'), [], [], [], [], []) self.assertDocTestMatches( "DHCPv... server failed to stop: DHCP is on strike today", logger.output)
def test_replace_and_restore_handlers(self): stream = StringIO() logger = logging.getLogger() logger.addHandler(logging.StreamHandler(stream)) logger.setLevel(logging.INFO) logging.info("one") fixture = FakeLogger() with fixture: logging.info("two") logging.info("three") self.assertEqual("two\n", fixture.output) self.assertEqual("one\nthree\n", stream.getvalue())
def setUp(self): super(PhantomJSIntegrationTest, self).setUp() self.logger = self.useFixture(FakeLogger()) reactor = self.useFixture(Reactor()) # Setup a local web server to test the WebDriver server = Service(reactor, "twist", args=["web"], timeout=5) server.expectOutput("Starting reactor...") server.expectPort(8080) self.useFixture(server) self.fixture = PhantomJS(reactor, timeout=10)
def test__logs_resolution_failures(self): # Some ISPs configure their DNS to resolve to an ads page when a domain # doesn't exist. This ensures resolving fails so the test passes. exception = socket.gaierror() exception.errno = random.choice( list(config._gen_addresses_where_possible_suppress)) exception.strerror = '[Errno ...] ...' self.patch(config, '_gen_addresses').side_effect = exception with FakeLogger(config.__name__) as logger: config._get_addresses("no-way-this-exists.maas.io") self.assertThat(logger.output.strip(), DocTestMatches( "Could not resolve no-way-this-exists.maas.io: [Errno ...] ..."))
def test_update_services_logs_when_service_not_recognised(self): service_name = factory.make_name("service") service = self.make_service(service_name) rack_controller = factory.make_RackController() with FakeLogger(services.__name__) as logger: update_services(rack_controller.system_id, [service]) self.assertThat( logger.output, DocTestMatches( "Rack ... reported status for '...' but this is not a " "recognised service (status='...', info='...')."), )
def test_delete_livefs_without_builds(self): # A live filesystem without builds can be deleted. self.useFixture(FakeLogger()) livefs = self.factory.makeLiveFS(registrant=self.person, owner=self.person) livefs_url = canonical_url(livefs) owner_url = canonical_url(self.person) browser = self.getViewBrowser(livefs, user=self.person) browser.getLink("Delete live filesystem").click() browser.getControl("Delete live filesystem").click() self.assertEqual(owner_url, browser.url) self.assertRaises(NotFound, browser.open, livefs_url)
def test_default_profile(self): logger = self.useFixture(FakeLogger()) self.useFixture(MonkeyPatch('sys.argv', ['bindep'])) depends = mock.MagicMock() depends.platform_profiles.return_value = ["platform:ubuntu"] depends.active_rules.return_value = ["A"] depends.check_rules.return_value = [] self.assertEqual(0, main(depends=depends)) self.assertEqual("", logger.output) depends.platform_profiles.assert_called_once_with() depends.active_rules.assert_called_once_with( ["default", "platform:ubuntu"]) depends.check_rules.assert_called_once_with(["A"])
def test__does_not_log_ServiceActionError_when_restarting(self): self.patch_sudo_write_file() self.patch_restartService().side_effect = ServiceActionError() 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("", logger.output)
def test_default_profile(self): logger = self.useFixture(FakeLogger()) self.useFixture(MonkeyPatch('sys.argv', ['bindep'])) mocker = mox.Mox() depends = mocker.CreateMock(Depends) depends.platform_profiles().AndReturn(["platform:ubuntu"]) depends.active_rules(["default", "platform:ubuntu"]).AndReturn(["A"]) depends.check_rules(["A"]).AndReturn([]) mocker.ReplayAll() self.assertEqual(0, main(depends=depends)) self.assertEqual("", logger.output) self.addCleanup(mocker.VerifyAll) self.addCleanup(mocker.UnsetStubs)
def test_query_nodes_copes_with_losing_connection_to_region(self): service = self.make_monitor_service() client = Mock(return_value=fail( ConnectionDone("Connection was closed cleanly."))) with FakeLogger("maas") as maaslog: d = service.query_nodes(client) d.addErrback(service.query_nodes_failed, sentinel.ident) self.assertEqual(None, extract_result(d)) self.assertDocTestMatches("Lost connection to region controller.", maaslog.output)
def test_unauthorized(self): # A user without edit access cannot delete a live filesystem. self.useFixture(FakeLogger()) livefs = self.factory.makeLiveFS(registrant=self.person, owner=self.person) livefs_url = canonical_url(livefs) other_person = self.factory.makePerson() browser = self.getViewBrowser(livefs, user=other_person) self.assertRaises(LinkNotFoundError, browser.getLink, "Delete live filesystem") self.assertRaises(Unauthorized, self.getUserBrowser, livefs_url + "/+delete", user=other_person)
def test_sync_does_propagate_ioerror(self): io_error = factory.make_exception_type(bases=(IOError, )) mock_sync = self.patch(download_descriptions.BasicMirrorWriter, "sync") mock_sync.side_effect = io_error() boot_images_dict = BootImageMapping() dumper = RepoDumper(boot_images_dict) with FakeLogger("maas.import-images", level=logging.INFO) as maaslog: self.assertRaises(io_error, dumper.sync, sentinel.reader, sentinel.path) self.assertDocTestMatches("...error...syncing boot images...", maaslog.output)
def test_private_specification_without_authorization(self): # Users without access get a 404 when trying to view private # specifications. self.useFixture(FakeLogger()) owner = self.factory.makePerson() policy = SpecificationSharingPolicy.PROPRIETARY product = self.factory.makeProduct(owner=owner, specification_sharing_policy=policy) with person_logged_in(owner): spec = self.factory.makeSpecification( product=product, owner=owner, information_type=InformationType.PROPRIETARY) url = canonical_url(spec) self.assertRaises(NotFound, self.getUserBrowser, url=url, user=None)
def test_logs_to_specified_logger(self): xpath = etree.XPath("/foo:bar") doc = etree.XML("<foo/>") root_logger = self.useFixture(FakeLogger()) callers_logger = Mock() try_match_xpath(xpath, doc, callers_logger) self.assertEqual("", root_logger.output) self.assertThat( callers_logger.warning, MockCalledOnceWith( "Invalid expression '%s': %s", "/foo:bar", "Undefined namespace prefix", ), )
def test_logging_output_included_in_details(self): fixture = FakeLogger() detail_name = "pythonlogging:''" with fixture: content = fixture.getDetails()[detail_name] # Output after getDetails is called is included. logging.info('some message') self.assertEqual("some message\n", content.as_text()) # The old content object returns the old usage after cleanUp (not # strictly needed but convenient). Note that no guarantee is made that # it will work after setUp is called again. [It does on Python 2.x, not # on 3.x] self.assertEqual("some message\n", content.as_text()) with fixture: # A new one returns new output: self.assertEqual("", fixture.getDetails()[detail_name].as_text()) # The original content object may either fail, or return the old # content (it must not have been reset..). try: self.assertEqual("some message\n", content.as_text()) except AssertionError: raise except: pass
def test_logging_output_included_in_details(self): fixture = FakeLogger() detail_name = "pythonlogging:''" with fixture: content = fixture.getDetails()[detail_name] # Output after getDetails is called is included. logging.info("some message") self.assertEqual("some message\n", content.as_text()) # The old content object returns the old usage after cleanUp (not # strictly needed but convenient). Note that no guarantee is made that # it will work after setUp is called again. [It does on Python 2.x, not # on 3.x] self.assertEqual("some message\n", content.as_text()) with fixture: # A new one returns new output: self.assertEqual("", fixture.getDetails()[detail_name].as_text()) # The original content object may either fail, or return the old # content (it must not have been reset..). try: self.assertEqual("some message\n", content.as_text()) except AssertionError: raise except: pass
def test___ensureService_allows_dead_for_off_service(self): service = make_fake_service(SERVICE_STATE.OFF) service_monitor = self.make_service_monitor([service]) mock_getServiceState = self.patch(service_monitor, "getServiceState") mock_getServiceState.return_value = succeed( ServiceState(SERVICE_STATE.DEAD, "Result: exit-code")) with FakeLogger("maas.service_monitor", level=logging.DEBUG) as maaslog: yield service_monitor._ensureService(service) self.assertDocTestMatches( "Service '%s' is %s and '%s'." % (service.service_name, SERVICE_STATE.DEAD, "Result: exit-code"), maaslog.output)
def test_operationalerror_view_integration(self): # Test setup. self.useFixture(FakeLogger('SiteError', level=logging.CRITICAL)) self.useFixture(Urllib2Fixture()) class BrokenView(object): """A view that raises an OperationalError""" def __call__(self, *args, **kw): raise OperationalError() ztapi.browserView(None, "error-test", BrokenView()) url = 'http://launchpad.dev/error-test' error = self.getHTTPError(url) self.assertEqual(httplib.SERVICE_UNAVAILABLE, error.code) self.assertThat(error.read(), Contains(OperationalErrorView.reason))
def test_cancel_build_not_owner(self): """A normal user can't cancel a build.""" self.useFixture(FakeLogger()) queue = self.factory.makeSourcePackageRecipeBuild().queueBuild() build = queue.specific_build transaction.commit() build_url = canonical_url(build) logout() browser = self.getUserBrowser(build_url, user=self.chef) self.assertRaises(LinkNotFoundError, browser.getLink, 'Cancel build') self.assertRaises(Unauthorized, self.getUserBrowser, build_url + '/+cancel', user=self.chef)
def test___performServiceAction_logs_error_if_action_fails(self): service = make_fake_service(SERVICE_STATE.ON) service_monitor = self.make_service_monitor() mock_execSystemDServiceAction = self.patch( service_monitor, "_execSystemDServiceAction") error_output = factory.make_name("error") mock_execSystemDServiceAction.return_value = (1, "", error_output) action = factory.make_name("action") with FakeLogger("maas.service_monitor", level=logging.ERROR) as maaslog: with ExpectedException(ServiceActionError): yield service_monitor._performServiceAction(service, action) self.assertDocTestMatches( "Service '%s' failed to %s: %s" % (service.name, action, error_output), maaslog.output)
def test_rescore_build_not_admin(self): """No one but admin can rescore a build.""" self.useFixture(FakeLogger()) queue = self.factory.makeSourcePackageRecipeBuild().queueBuild() build = queue.specific_build transaction.commit() build_url = canonical_url(build) logout() browser = self.getUserBrowser(build_url, user=self.chef) self.assertRaises(LinkNotFoundError, browser.getLink, 'Rescore build') self.assertRaises(Unauthorized, self.getUserBrowser, build_url + '/+rescore', user=self.chef)
def test___ensureService_logs_debug_in_expected_states(self): state = SERVICE_STATE.ON service = make_fake_service(state) service_monitor = self.make_service_monitor([service]) expected_process_state = service_monitor.PROCESS_STATE[state] mock_getServiceState = self.patch(service_monitor, "getServiceState") mock_getServiceState.return_value = succeed( ServiceState(SERVICE_STATE.ON, expected_process_state)) with FakeLogger("maas.service_monitor", level=logging.DEBUG) as maaslog: yield service_monitor._ensureService(service) self.assertDocTestMatches( "Service '%s' is %s and '%s'." % (service.service_name, state, expected_process_state), maaslog.output)
def test_query_all_nodes_swallows_NoSuchNode(self): node1, node2 = self.make_nodes(2) new_state_2 = self.pick_alternate_state(node2['power_state']) get_power_state = self.patch(power, 'get_power_state') get_power_state.side_effect = [ fail(exceptions.NoSuchNode()), succeed(new_state_2), ] suppress_reporting(self) with FakeLogger("maas.power", level=logging.DEBUG) as maaslog: yield power.query_all_nodes([node1, node2]) self.assertDocTestMatches( """\ hostname-...: Power state has changed from ... to ... """, maaslog.output)
def test__scan_as_admin_logs_the_fact_that_a_scan_happened(self): user = factory.make_admin() handler = SubnetHandler(user, {}, None) subnet = factory.make_Subnet(version=4) rack = factory.make_RackController() factory.make_Interface(node=rack, subnet=subnet) logger = self.useFixture(FakeLogger()) cidr = subnet.get_ipnetwork() handler.scan({"id": subnet.id}) # Use MatchesRegex here rather than DocTestMatches because usernames # can contain characters that confuse DocTestMatches (e.g. periods). self.assertThat( logger.output, MatchesRegex( "User '%s' initiated a neighbour discovery scan against subnet: %s" % (re.escape(user.username), re.escape(str(cidr)))), )
def test_try_query_nodes_logs_other_errors(self): service = self.make_monitor_service() self.patch(npms, "getRegionClient").return_value = sentinel.client sentinel.client.localIdent = factory.make_UUID() query_nodes = self.patch(service, "query_nodes") query_nodes.return_value = fail( ZeroDivisionError("Such a shame I can't divide by zero")) with FakeLogger("maas") as maaslog, TwistedLoggerFixture(): d = service.try_query_nodes() self.assertEqual(None, extract_result(d)) self.assertDocTestMatches( "Failed to query nodes' power status: " "Such a shame I can't divide by zero", maaslog.output)
def test_updates_interfaces_in_database(self): region = yield deferToDatabase(factory.make_RegionController) region.owner = yield deferToDatabase(factory.make_admin) yield deferToDatabase(region.save) # Declare this region controller as the one running here. self.useFixture(MAASIDFixture(region.system_id)) interfaces = { factory.make_name("eth"): { "type": "physical", "mac_address": factory.make_mac_address(), "parents": [], "links": [], "enabled": True, } } service = RegionNetworksMonitoringService(reactor, enable_beaconing=False) service.getInterfaces = lambda: succeed(interfaces) with FakeLogger("maas") as logger: service.startService() yield service.stopService() # Nothing was logged. self.assertThat( logger.output, DocTestMatches("Networks monitoring service: " "Process ID ... assumed responsibility."), ) def get_interfaces(): return list(region.interface_set.all()) interfaces_observed = yield deferToDatabase(get_interfaces) self.assertThat(interfaces_observed, HasLength(1)) interface_observed = interfaces_observed[0] self.assertThat(interface_observed, IsInstance(PhysicalInterface)) self.assertThat(interfaces, Contains(interface_observed.name)) interface_expected = interfaces[interface_observed.name] self.assertThat( interface_observed.mac_address.raw, Equals(interface_expected["mac_address"]), )
def test___ensureService_logs_mismatch_for_dead_process_state(self): service = make_fake_service(SERVICE_STATE.OFF) service_monitor = self.make_service_monitor([service]) invalid_process_state = factory.make_name("invalid") mock_getServiceState = self.patch(service_monitor, "getServiceState") mock_getServiceState.return_value = succeed( ServiceState(SERVICE_STATE.DEAD, invalid_process_state)) with FakeLogger("maas.service_monitor", level=logging.WARNING) as maaslog: yield service_monitor._ensureService(service) self.assertDocTestMatches( "Service '%s' is %s but not in the expected state of " "'%s', its current state is '%s'." % (service.service_name, SERVICE_STATE.DEAD.value, service_monitor.PROCESS_STATE[SERVICE_STATE.DEAD], invalid_process_state), maaslog.output)