def test_compose_uses_commit_forms_second(self): request = MagicMock() pods = self.make_pods() # Make it skip all pods. for pod in pods: pod.capabilities = [Capabilities.OVER_COMMIT] pod.save() data = self.make_data(pods) form = ComposeMachineForPodsForm(request=request, data=data, pods=pods) mock_form_compose = self.patch(ComposeMachineForm, 'compose') mock_form_compose.side_effect = [ factory.make_exception(), factory.make_exception(), factory.make_exception(), None] self.assertTrue(form.is_valid()) form.compose() self.assertThat(mock_form_compose, MockCallsMatch( call( skip_commissioning=True, creation_type=NODE_CREATION_TYPE.DYNAMIC), call( skip_commissioning=True, creation_type=NODE_CREATION_TYPE.DYNAMIC), call( skip_commissioning=True, creation_type=NODE_CREATION_TYPE.DYNAMIC)))
def test_inner_start_up_runs_in_exclusion(self): # Disable boot source cache signals. self.addCleanup(bootsources.signals.enable) bootsources.signals.disable() locked = factory.make_exception("locked") unlocked = factory.make_exception("unlocked") def check_lock(_): raise locked if locks.startup.is_locked() else unlocked self.patch(start_up, "register_mac_type").side_effect = check_lock self.assertRaises(type(locked), start_up.inner_start_up, master=False)
def test_tryUpdate_logs_errors_from_broken_method(self): service = ntp.RegionNetworkTimeProtocolService(reactor) broken_method = self.patch_autospec(service, self.method) broken_method.side_effect = factory.make_exception() # Ensure that we never actually execute against systemd or write an # actual configuration file. self.patch_autospec( ntp, "deferToThread" ).side_effect = always_succeed_with(None) self.patch_autospec(service_monitor, "restartService") 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 fake_pod_discovery(self): discovered_pod = DiscoveredPod( architectures=["amd64/generic"], cores=random.randint(2, 4), memory=random.randint(1024, 4096), local_storage=random.randint(1024, 1024 * 1024), cpu_speed=random.randint(2048, 4048), hints=DiscoveredPodHints( cores=random.randint(2, 4), memory=random.randint(1024, 4096), local_storage=random.randint(1024, 1024 * 1024), cpu_speed=random.randint(2048, 4048), ), ) discovered_rack_1 = factory.make_RackController() discovered_rack_2 = factory.make_RackController() failed_rack = factory.make_RackController() self.patch(pods, "discover_pod").return_value = succeed(( { discovered_rack_1.system_id: discovered_pod, discovered_rack_2.system_id: discovered_pod, }, { failed_rack.system_id: factory.make_exception() }, ))
def fake_pod_discovery(self): discovered_pod = DiscoveredPod( architectures=['amd64/generic'], cores=random.randint(2, 4), memory=random.randint(1024, 4096), local_storage=random.randint(1024, 1024 * 1024), cpu_speed=random.randint(2048, 4048), hints=DiscoveredPodHints( cores=random.randint(2, 4), memory=random.randint(1024, 4096), local_storage=random.randint(1024, 1024 * 1024), cpu_speed=random.randint(2048, 4048)), storage_pools=[ DiscoveredPodStoragePool( id=factory.make_name('pool_id'), name=factory.make_name('name'), type=factory.make_name('type'), path='/var/lib/path/%s' % factory.make_name('path'), storage=random.randint(1024, 1024 * 1024), ) for _ in range(3) ]) discovered_rack_1 = factory.make_RackController() discovered_rack_2 = factory.make_RackController() failed_rack = factory.make_RackController() self.patch(pods_module, "discover_pod").return_value = ({ discovered_rack_1.system_id: discovered_pod, discovered_rack_2.system_id: discovered_pod, }, { failed_rack.system_id: factory.make_exception(), }) return ( discovered_pod, [discovered_rack_1, discovered_rack_2], [failed_rack])
def test__tryUpdate_logs_errors_from_broken_method(self): service = syslog.RegionSyslogService(reactor) broken_method = self.patch_autospec(service, self.method) broken_method.side_effect = factory.make_exception() # Don't actually write the file. self.patch_autospec(syslog, "write_config") # Ensure that we never actually execute against systemd. self.patch_autospec(service_monitor, "restartService") with TwistedLoggerFixture() as logger: yield service._tryUpdate() self.assertThat( logger.output, DocTestMatches( """ Failed to update syslog configuration. Traceback (most recent call last): ... maastesting.factory.TestException#... """ ), )
def test_handleRequest_sends_error(self): node = yield deferToDatabase(self.make_node) # Need to delete the node as the transaction is committed self.addCleanup(self.clean_node, node) protocol, factory = self.make_protocol() protocol.user = MagicMock() self.patch(Handler, "execute").return_value = fail( maas_factory.make_exception("error")) message = { "type": MSG_TYPE.REQUEST, "request_id": 1, "method": "machine.get", "params": { "system_id": node.system_id, } } yield protocol.handleRequest(message) sent_obj = self.get_written_transport_message(protocol) self.expectThat(sent_obj["type"], Equals(MSG_TYPE.RESPONSE)) self.expectThat(sent_obj["request_id"], Equals(1)) self.expectThat(sent_obj["rtype"], Equals(RESPONSE_TYPE.ERROR)) self.expectThat(sent_obj["error"], Equals("error"))
def test_create_proper_return_on_exception(self): self.become_admin() failed_rack = factory.make_RackController() self.patch(pods, "discover_pod").return_value = ({}, { failed_rack.system_id: factory.make_exception(), }) response = self.client.post( reverse('pods_handler'), self.make_pod_info()) self.assertEqual(http.client.SERVICE_UNAVAILABLE, response.status_code)
def test_process_updates_rbac_logs_failure(self): service = self.make_service(sentinel.listener) service.needsRBACUpdate = True mock_rbacSync = self.patch(service, "_rbacSync") mock_rbacSync.side_effect = factory.make_exception() mock_err = self.patch(region_controller.log, "err") service.startProcessing() yield service.processingDefer self.assertThat( mock_err, MockCalledOnceWith(ANY, "Failed syncing resources to RBAC."))
def test__logs_other_errors(self): node = yield deferToDatabase(transactional(factory.make_Node)) mock_power_query = self.patch(Node, "power_query") mock_power_query.side_effect = factory.make_exception('Error') mock_log_err = self.patch(power.log, "err") yield power.update_power_state_of_node(node.system_id) self.assertThat( mock_log_err, MockCalledOnceWith( ANY, "Failed to update power state of machine after state " "transition."))
def test_raises_exception_from_rack_controller(self): failed_rack = factory.make_RackController() exc = factory.make_exception() self.patch(pods_module, "discover_pod").return_value = ({}, { failed_rack.system_id: exc, }) pod_info = self.make_pod_info() form = PodForm(data=pod_info) self.assertTrue(form.is_valid(), form._errors) error = self.assertRaises(PodProblem, form.save) self.assertEquals(str(exc), str(error))
def test_start_up_binds_first_successful_of_endpoint_options(self): service = RegionService(sentinel.ipcWorker) endpoint_broken = Mock() endpoint_broken.listen.return_value = fail(factory.make_exception()) endpoint_okay = Mock() endpoint_okay.listen.return_value = succeed(sentinel.port) service.endpoints = [[endpoint_broken, endpoint_okay]] yield service.startService() self.assertThat(service.ports, Equals([sentinel.port]))
def test_process_updates_zones_logs_failure(self): service = RegionControllerService(sentinel.listener) service.needsDNSUpdate = True mock_dns_update_all_zones = self.patch(region_controller, "dns_update_all_zones") mock_dns_update_all_zones.side_effect = factory.make_exception() mock_err = self.patch(region_controller.log, "err") service.startProcessing() yield service.processingDefer self.assertThat(mock_dns_update_all_zones, MockCalledOnceWith()) self.assertThat(mock_err, MockCalledOnceWith(ANY, "Failed configuring DNS."))
def test_bmc_get_returns_none_on_error(self): key = factory.make_name("key") self.mock_check_output.side_effect = factory.make_exception() self.assertIsNone(self.ipmi._bmc_get(key)) self.assertThat( self.mock_check_output, MockCalledOnceWith( ["bmc-config", "--checkout", f"--key-pair={key}"], stderr=DEVNULL, timeout=60, ), )
def test_add_bmc_user_fails(self): user_number = "User%s" % random.randint(2, 12) password = factory.make_name("password") password_w_spec_chars = factory.make_name("password_w_spec_chars") self.patch(self.ipmi, "_pick_user_number").return_value = user_number self.patch(self.ipmi, "_generate_random_password").side_effect = ( password, password_w_spec_chars, ) mock_bmc_set = self.patch(self.ipmi, "_bmc_set") mock_bmc_set.side_effect = factory.make_exception() self.assertRaises(SystemExit, self.ipmi.add_bmc_user)
def test_process_updates_proxy_logs_failure(self): service = RegionControllerService(sentinel.listener) service.needsProxyUpdate = True mock_proxy_update_config = self.patch(region_controller, "proxy_update_config") mock_proxy_update_config.return_value = fail(factory.make_exception()) mock_err = self.patch(region_controller.log, "err") service.startProcessing() yield service.processingDefer self.assertThat(mock_proxy_update_config, MockCalledOnceWith(reload_proxy=True)) self.assertThat(mock_err, MockCalledOnceWith(ANY, "Failed configuring proxy."))
def test_tryConnection_will_retry_in_3_seconds_if_autoReconnect_set(self): listener = PostgresListenerService() listener.autoReconnect = True startConnection = self.patch(listener, "startConnection") startConnection.side_effect = factory.make_exception() deferLater = self.patch(listener_module, "deferLater") deferLater.return_value = sentinel.retry result = yield listener.tryConnection() self.assertThat(result, Is(sentinel.retry)) self.assertThat(deferLater, MockCalledWith(reactor, 3, ANY))
def test_rpc_info_when_rpc_advertise_startup_failed(self): self.useFixture(RegionEventLoopFixture("rpc", "rpc-advertise")) # Simulate a crash when the rpc-advertise service starts. self.simulateExceptionInAdvertiseService(factory.make_exception()) eventloop.start().wait(2.0) self.addCleanup(lambda: eventloop.reset().wait(5)) response = self.client.get(reverse('rpc-info')) self.assertEqual("application/json", response["Content-Type"]) info = json.loads(response.content.decode("unicode_escape")) self.assertEqual({"eventloops": None}, info)
def test_monitorServices_handles_failure(self): # Pretend we're in a production environment. self.patch( service_monitor_service, "is_dev_environment").return_value = False monitor_service = ServiceMonitorService(Clock()) mock_ensureServices = self.patch(service_monitor, "ensureServices") mock_ensureServices.return_value = fail(factory.make_exception()) with TwistedLoggerFixture() as logger: monitor_service.monitorServices() self.assertDocTestMatches("""\ Failed to monitor services and update database. Traceback (most recent call last): ...""", logger.output)
def test__connectionLost_logs_reason(self): listener = PostgresListenerService() failure = Failure(factory.make_exception("Treason!")) with TwistedLoggerFixture() as logger: listener.connectionLost(failure) self.assertThat( logger.output, DocTestMatches("""\ Connection lost. Traceback (most recent call last):... Failure: maastesting.factory.TestException#...: Treason! """))
def test_start_up_retries_with_wait_on_exception(self): inner_start_up = self.patch(start_up, 'inner_start_up') inner_start_up.side_effect = [ factory.make_exception("Boom!"), None, # Success. ] # We don't want to really sleep. self.patch(start_up, "pause") # start_up() returns without error. start_up.start_up() # However, it did call inner_start_up() twice; the first call resulted # in the "Boom!" exception so it tried again. self.expectThat(inner_start_up, MockCallsMatch(call(), call())) # It also slept once, for 3 seconds, between those attempts. self.expectThat(start_up.pause, MockCalledOnceWith(3.0))
def test_doesnt_create_pod_when_discovery_fails_in_twisted(self): discovered_pod, discovered_racks, failed_racks = yield deferToDatabase( self.fake_pod_discovery) pods_module.discover_pod.return_value = fail(factory.make_exception()) pod_info = yield deferToDatabase(self.make_pod_info) form = yield deferToDatabase( PodForm, data=pod_info, request=self.request) is_valid = yield deferToDatabase(form.is_valid) self.assertTrue(is_valid, form._errors) with ExpectedException(PodProblem): yield form.save() def validate_no_pods(): self.assertItemsEqual([], Pod.objects.all()) yield deferToDatabase(validate_no_pods)
def test_process_calls_processDHCP_multiple_times_on_failure(self): rack_id = random.randint(0, 100) service = RackControllerService(sentinel.ipcWorker, sentinel.listener) service.watching = set([rack_id]) service.needsDHCPUpdate = set([rack_id]) service.running = True mock_processDHCP = self.patch(service, "processDHCP") mock_processDHCP.side_effect = [ fail(factory.make_exception()), succeed(None), ] service.startProcessing() for _ in range(2): yield service.processingDone self.assertThat(mock_processDHCP, MockCallsMatch(call(rack_id), call(rack_id)))
def test_raises_exception_from_rack_controller_in_twisted(self): failed_rack = yield deferToDatabase(factory.make_RackController) exc = factory.make_exception() self.patch(pods_module, "discover_pod").return_value = succeed(({}, { failed_rack.system_id: exc, })) pod_info = yield deferToDatabase(self.make_pod_info) form = yield deferToDatabase(PodForm, data=pod_info) is_valid = yield deferToDatabase(form.is_valid) self.assertTrue(is_valid, form._errors) def validate_error(failure): self.assertIsInstance(failure.value, PodProblem) self.assertEquals(str(exc), str(failure.value)) d = form.save() d.addErrback(validate_error) yield d
def test_process_updates_rbac_retries_with_delay(self): service = self.make_service(sentinel.listener) service.needsRBACUpdate = True service.retryOnFailure = True service.rbacRetryOnFailureDelay = random.randint(1, 10) mock_rbacSync = self.patch(service, "_rbacSync") mock_rbacSync.side_effect = [factory.make_exception(), None] mock_err = self.patch(region_controller.log, "err") mock_pause = self.patch(region_controller, "pause") mock_pause.return_value = succeed(None) service.startProcessing() yield service.processingDefer self.assertThat( mock_err, MockCalledOnceWith(ANY, "Failed syncing resources to RBAC."), ) self.assertThat(mock_pause, MockCalledOnceWith(service.rbacRetryOnFailureDelay))
def test_authenticate_calls_loseConnection_if_error_getting_user(self): csrftoken = maas_factory.make_name("csrftoken") uri = self.make_ws_uri(csrftoken) protocol, factory = self.make_protocol(patch_authenticate=False, transport_uri=uri) mock_loseConnection = self.patch_autospec(protocol, "loseConnection") mock_getUserFromSessionId = self.patch_autospec( protocol, "getUserFromSessionId") mock_getUserFromSessionId.side_effect = maas_factory.make_exception( "unknown reason") yield protocol.authenticate( maas_factory.make_name("sessionid"), csrftoken, ) self.expectThat( mock_loseConnection, MockCalledOnceWith(STATUSES.PROTOCOL_ERROR, "Error authenticating user: unknown reason"))
def test__doesnt_raises_other_errors(self): uuid = factory.make_name("uuid") # Cause a random exception self.patch(leases_module, "update_lease").side_effect = (factory.make_exception()) yield eventloop.start() try: yield call_responder( Region(), UpdateLease, { "cluster_uuid": uuid, "action": "expiry", "mac": factory.make_mac_address(), "ip_family": "ipv4", "ip": factory.make_ipv4_address(), "timestamp": int(time.time()), }) finally: yield eventloop.reset()
def test__calls_PowerQuery_on_all_clients(self): node, power_info = yield deferToDatabase( self.make_node_with_power_info) successful_rack_ids = [ factory.make_name("system_id") for _ in range(3) ] error_rack_ids = [factory.make_name("system_id") for _ in range(3)] failed_rack_ids = [factory.make_name("system_id") for _ in range(3)] clients = [] power_states = [] for rack_id in successful_rack_ids: power_state = random.choice([POWER_STATE.ON, POWER_STATE.OFF]) power_states.append(power_state) client = Mock() client.ident = rack_id client.return_value = succeed({ "state": power_state, }) clients.append(client) for rack_id in error_rack_ids: client = Mock() client.ident = rack_id client.return_value = succeed({ "state": POWER_STATE.ERROR, }) clients.append(client) for rack_id in failed_rack_ids: client = Mock() client.ident = rack_id client.return_value = fail(factory.make_exception()) clients.append(client) self.patch(power_module, "getAllClients").return_value = clients power_state, success_racks, failed_racks = yield power_query_all( node.system_id, node.hostname, power_info) self.assertEqual(pick_best_power_state(power_states), power_state) self.assertItemsEqual(successful_rack_ids, success_racks) self.assertItemsEqual(error_rack_ids + failed_rack_ids, failed_racks)
def test_add_bmc_user_rand_password_with_special_chars(self): self.ipmi.username = None self.ipmi.password = None user_number = "User%s" % random.randint(2, 12) password = factory.make_name("password") password_w_spec_chars = factory.make_name("password_w_spec_chars") self.patch(self.ipmi, "_pick_user_number").return_value = user_number self.patch(self.ipmi, "_generate_random_password").side_effect = ( password, password_w_spec_chars, ) mock_bmc_set = self.patch(self.ipmi, "_bmc_set") mock_bmc_set.side_effect = ( None, factory.make_exception(), None, None, None, None, None, ) self.ipmi.add_bmc_user() self.assertEqual("maas", self.ipmi.username) self.assertEqual(password_w_spec_chars, self.ipmi.password) self.assertThat( mock_bmc_set, MockCallsMatch( call(f"{user_number}:Username", "maas"), call(f"{user_number}:Password", password), call(f"{user_number}:Username", "maas"), call(f"{user_number}:Password", password_w_spec_chars), call(f"{user_number}:Enable_User", "Yes"), call(f"{user_number}:Lan_Privilege_Limit", "Administrator"), call(f"{user_number}:Lan_Enable_IPMI_Msgs", "Yes"), ), )
def test_invalid_check_object(self): backend = MAASAuthorizationBackend() exc = factory.make_exception() self.assertRaises(NotImplementedError, backend.has_perm, factory.make_admin(), NodePermission.view, exc)