def setUp(self): super(TestRegionServiceMaker, self).setUp() self.patch(eventloop.loop, "services", MultiService()) self.patch_autospec(crochet, "no_setup") self.patch_autospec(logger, "configure") # Enable database access in the reactor just for these tests. asynchronous(enable_all_database_connections, timeout=5)() import_websocket_handlers()
def test_probe_and_enlist(self): user = factory.make_name("user") url = factory.make_name("url") username = factory.make_name("username") password = factory.make_name("password") system_id = factory.make_name("system_id") domain = factory.make_name("domain") api = Mock() self.patch(ucsm, "UCSM_XML_API").return_value = api server_element = {"uuid": "uuid"} server = (server_element, ["mac"]) probe_servers_mock = self.patch(ucsm, "probe_servers") probe_servers_mock.return_value = [server] set_lan_boot_default_mock = self.patch(ucsm, "set_lan_boot_default") create_node_mock = self.patch(ucsm, "create_node") create_node_mock.side_effect = asynchronous(lambda *args: system_id) commission_node_mock = self.patch(ucsm, "commission_node") yield deferToThread(probe_and_enlist_ucsm, user, url, username, password, True, domain) self.expectThat(set_lan_boot_default_mock, MockCalledOnceWith(api, server_element)) self.expectThat(probe_servers_mock, MockCalledOnceWith(api)) params = { "power_address": url, "power_user": username, "power_pass": password, "uuid": server[0]["uuid"], } self.expectThat( create_node_mock, MockCalledOnceWith(server[1], "amd64", "ucsm", params, domain), ) self.expectThat(commission_node_mock, MockCalledOnceWith(system_id, user))
def test_probe_and_enlist(self): num_servers = 100 self.configure_vmomi_api(servers=num_servers) mock_create_node = self.patch(vmware, "create_node") system_id = factory.make_name("system_id") mock_create_node.side_effect = asynchronous( lambda *args, **kwargs: system_id ) mock_commission_node = self.patch(vmware, "commission_node") host = factory.make_hostname() username = factory.make_username() password = factory.make_username() yield deferToThread( vmware.probe_vmware_and_enlist, factory.make_username(), host, username, password, accept_all=True, ) self.assertEqual(mock_create_node.call_count, num_servers) self.assertEqual(mock_commission_node.call_count, num_servers)
def test_probe_and_enlist_msftocs_probes_and_enlists(self): context = make_context() user = factory.make_name("user") system_id = factory.make_name("system_id") domain = factory.make_name("domain") macs = [factory.make_mac_address() for _ in range(3)] mock_get_blades = self.patch(MicrosoftOCSPowerDriver, "get_blades") mock_get_blades.return_value = {"%s" % context["blade_id"]: macs} self.patch(MicrosoftOCSPowerDriver, "set_next_boot_device") mock_create_node = self.patch(msftocs_module, "create_node") mock_create_node.side_effect = asynchronous(lambda *args: system_id) mock_commission_node = self.patch(msftocs_module, "commission_node") yield deferToThread( probe_and_enlist_msftocs, user, context["power_address"], int(context["power_port"]), context["power_user"], context["power_pass"], True, domain, ) self.expectThat( mock_create_node, MockCalledOnceWith(macs, "amd64", "msftocs", context, domain), ) self.expectThat(mock_commission_node, MockCalledOnceWith(system_id, user))
def test_probe_and_enlist_recs_probes_and_enlists(self): user = factory.make_name('user') ip, port, username, password, node_id, context = self.make_context() domain = factory.make_name('domain') macs = [factory.make_mac_address() for _ in range(3)] mock_get_nodes = self.patch(RECSAPI, "get_nodes") mock_get_nodes.return_value = { node_id: { 'macs': macs, 'arch': 'amd64' } } self.patch(RECSAPI, "set_boot_source") mock_create_node = self.patch(recs_module, "create_node") mock_create_node.side_effect = asynchronous(lambda *args: node_id) mock_commission_node = self.patch(recs_module, "commission_node") yield deferToThread(probe_and_enlist_recs, user, ip, int(port), username, password, True, domain) self.expectThat( mock_create_node, MockCalledOnceWith(macs, 'amd64', 'recs_box', context, domain)) self.expectThat(mock_commission_node, MockCalledOnceWith(node_id, user))
def test_probe_and_enlist(self): node_id = make_node_id() node_list = NODE_LIST % node_id node_info = NODE_INFO % (node_id, self.product_name) node_macaddr = NODE_MACADDR % (node_id, factory.make_mac_address(), factory.make_mac_address()) macs = re.findall(r':'.join(['[0-9a-f]{2}'] * 6), node_macaddr) user = factory.make_name('user') host = factory.make_hostname('mscm') username = factory.make_name('user') password = factory.make_name('password') domain = factory.make_name('domain') system_id = factory.make_name('system_id') mscm_driver = self.patch(mscm_module, "MSCMPowerDriver").return_value mscm_driver.run_mscm_command.side_effect = (node_list, None, node_info, node_macaddr) create_node = self.patch(mscm_module, 'create_node') create_node.side_effect = asynchronous(lambda *args: system_id) commission_node = self.patch(mscm_module, 'commission_node') params = { 'power_address': host, 'power_user': username, 'power_pass': password, 'node_id': node_id, } yield deferToThread(probe_and_enlist_mscm, user, host, username, password, True, domain) self.expectThat( create_node, MockCalledOnceWith(macs, self.arch, 'mscm', params, domain)) self.expectThat(commission_node, MockCalledOnceWith(system_id, user))
def test_probe_and_enlist_skips_pxe_config_if_create_node_failed(self): num_servers = 1 self.configure_vmomi_api(servers=num_servers) mock_create_node = self.patch(vmware, "create_node") mock_create_node.side_effect = asynchronous( lambda *args, **kwargs: None) mock_reconfigure_vm = self.patch(FakeVmomiVM, "ReconfigVM_Task") # We need to not actually try to commission any nodes... self.patch(vmware, "commission_node") host = factory.make_hostname() username = factory.make_username() password = factory.make_username() yield deferToThread( vmware.probe_vmware_and_enlist, factory.make_username(), host, username, password, accept_all=True, ) self.assertEqual(mock_reconfigure_vm.call_count, 0)
def test_probe_and_enlist_recs_probes_and_enlists_no_commission(self): user = factory.make_name("user") ip, port, username, password, node_id, context = self.make_context() domain = factory.make_name("domain") macs = [factory.make_mac_address() for _ in range(3)] mock_get_nodes = self.patch(RECSAPI, "get_nodes") mock_get_nodes.return_value = {node_id: {"macs": macs, "arch": "arm"}} self.patch(RECSAPI, "set_boot_source") mock_create_node = self.patch(recs_module, "create_node") mock_create_node.side_effect = asynchronous(lambda *args: node_id) mock_commission_node = self.patch(recs_module, "commission_node") yield deferToThread( probe_and_enlist_recs, user, ip, int(port), username, password, False, domain, ) self.expectThat( mock_create_node, MockCalledOnceWith(macs, "armhf", "recs_box", context, domain), ) self.expectThat(mock_commission_node, MockNotCalled())
def test_execute_calls_asynchronous_method_with_params(self): # An asynchronous method -- decorated with @asynchronous -- is called # directly, not in a thread. handler = self.make_nodes_handler() handler.get = asynchronous(lambda params: sentinel.thing) params = {"system_id": factory.make_name("system_id")} result = handler.execute("get", params).wait(30) self.assertThat(result, Is(sentinel.thing))
def test_maybe_make_stats_request_doesnt_make_request(self): mock_call = self.patch(stats, "make_maas_user_agent_request") with transaction.atomic(): Config.objects.set_config("enable_analytics", False) service = stats.StatsService() maybe_make_stats_request = asynchronous( service.maybe_make_stats_request) maybe_make_stats_request().wait(5) self.assertThat(mock_call, MockNotCalled())
def test_maybe_make_stats_request_doesnt_make_request(self): mock_call = self.patch(prometheus, "push_stats_to_prometheus") with transaction.atomic(): Config.objects.set_config('enable_analytics', False) service = prometheus.PrometheusService() maybe_push_prometheus_stats = asynchronous( service.maybe_push_prometheus_stats) maybe_push_prometheus_stats().wait(5) self.assertThat(mock_call, MockNotCalled())
def test_maybe_make_stats_request_makes_request(self): mock_call = self.patch(stats, "push_stats_to_prometheus") self.patch(stats, "PROMETHEUS_SUPPORTED", True) with transaction.atomic(): Config.objects.set_config('prometheus_enabled', True) Config.objects.set_config( 'prometheus_push_gateway', '192.168.1.1:8081') service = stats.PrometheusService() maybe_push_prometheus_stats = asynchronous( service.maybe_push_prometheus_stats) maybe_push_prometheus_stats().wait(5) self.assertThat(mock_call, MockCalledOnce())
def test_probe_and_enlist(self): node_id = make_node_id() node_list = NODE_LIST % node_id node_info = NODE_INFO % (node_id, self.product_name) node_macaddr = NODE_MACADDR % ( node_id, factory.make_mac_address(), factory.make_mac_address(), ) macs = re.findall(r":".join(["[0-9a-f]{2}"] * 6), node_macaddr) user = factory.make_name("user") host = factory.make_hostname("mscm") username = factory.make_name("user") password = factory.make_name("password") domain = factory.make_name("domain") system_id = factory.make_name("system_id") mscm_driver = self.patch(mscm_module, "MSCMPowerDriver").return_value mscm_driver.run_mscm_command.side_effect = ( node_list, None, node_info, node_macaddr, ) create_node = self.patch(mscm_module, "create_node") create_node.side_effect = asynchronous(lambda *args: system_id) commission_node = self.patch(mscm_module, "commission_node") params = { "power_address": host, "power_user": username, "power_pass": password, "node_id": node_id, } yield deferToThread( probe_and_enlist_mscm, user, host, username, password, True, domain ) self.expectThat( create_node, MockCalledOnceWith(macs, self.arch, "mscm", params, domain), ) self.expectThat(commission_node, MockCalledOnceWith(system_id, user))
def test_calls_are_made_to_all_clusters(self): rpc_fixture = self.prepare_live_rpc() rack_controllers = [factory.make_RackController() for _ in range(3)] protocols = [] rack_creds = [] for rack in rack_controllers: tokens = list(get_auth_tokens(rack.owner)) if len(tokens) > 0: # Use the latest token. token = tokens[-1] else: token = create_auth_token(rack.owner) creds = convert_tuple_to_string(get_creds_tuple(token)) rack_creds.append(creds) protocol = rpc_fixture.makeCluster(rack, EvaluateTag) protocol.EvaluateTag.side_effect = always_succeed_with({}) protocols.append(protocol) tag = factory.make_Tag(populate=False) [d] = populate_tags(tag) # `d` is a testing-only convenience. We must wait for it to fire, and # we must do that from the reactor thread. wait_for_populate = asynchronous(lambda: d) wait_for_populate().wait(10) for rack, protocol, creds in zip(rack_controllers, protocols, rack_creds): self.expectThat( protocol.EvaluateTag, MockCalledOnceWith( protocol, tag_name=tag.name, tag_definition=tag.definition, system_id=rack.system_id, tag_nsmap=ANY, credentials=creds, nodes=ANY, ), )
def test_probe_and_enlist_msftocs_probes_and_enlists(self): context = make_context() user = factory.make_name('user') system_id = factory.make_name('system_id') domain = factory.make_name('domain') macs = [factory.make_mac_address() for _ in range(3)] mock_get_blades = self.patch(MicrosoftOCSPowerDriver, "get_blades") mock_get_blades.return_value = {'%s' % context['blade_id']: macs} self.patch(MicrosoftOCSPowerDriver, "set_next_boot_device") mock_create_node = self.patch(msftocs_module, "create_node") mock_create_node.side_effect = asynchronous(lambda *args: system_id) mock_commission_node = self.patch(msftocs_module, "commission_node") yield deferToThread( probe_and_enlist_msftocs, user, context['power_address'], int(context['power_port']), context['power_user'], context['power_pass'], True, domain) self.expectThat( mock_create_node, MockCalledOnceWith( macs, 'amd64', 'msftocs', context, domain)) self.expectThat( mock_commission_node, MockCalledOnceWith(system_id, user))
def test_probe_and_enlist(self): user = factory.make_name('user') url = factory.make_name('url') username = factory.make_name('username') password = factory.make_name('password') system_id = factory.make_name('system_id') domain = factory.make_name('domain') api = Mock() self.patch(ucsm, 'UCSM_XML_API').return_value = api server_element = {'uuid': 'uuid'} server = ( server_element, ['mac'], ) probe_servers_mock = self.patch(ucsm, 'probe_servers') probe_servers_mock.return_value = [server] set_lan_boot_default_mock = self.patch(ucsm, 'set_lan_boot_default') create_node_mock = self.patch(ucsm, 'create_node') create_node_mock.side_effect = asynchronous(lambda *args: system_id) commission_node_mock = self.patch(ucsm, 'commission_node') yield deferToThread(probe_and_enlist_ucsm, user, url, username, password, True, domain) self.expectThat(set_lan_boot_default_mock, MockCalledOnceWith(api, server_element)) self.expectThat(probe_servers_mock, MockCalledOnceWith(api)) params = { 'power_address': url, 'power_user': username, 'power_pass': password, 'uuid': server[0]['uuid'] } self.expectThat( create_node_mock, MockCalledOnceWith(server[1], 'amd64', 'ucsm', params, domain)) self.expectThat(commission_node_mock, MockCalledOnceWith(system_id, user))
def test_probe_and_enlist_reconfigures_boot_order_if_create_node_ok(self): num_servers = 1 self.configure_vmomi_api(servers=num_servers) mock_create_node = self.patch(vmware, 'create_node') system_id = factory.make_name('system_id') mock_create_node.side_effect = asynchronous( lambda *args, **kwargs: system_id) mock_reconfigure_vm = self.patch(FakeVmomiVM, 'ReconfigVM_Task') # We need to not actually try to commission any nodes... self.patch(vmware, 'commission_node') host = factory.make_hostname() username = factory.make_username() password = factory.make_username() yield deferToThread(vmware.probe_vmware_and_enlist, factory.make_username(), host, username, password, accept_all=True) self.assertEqual(mock_reconfigure_vm.call_count, num_servers)
def test_probe_and_enlist(self): # Patch VirshSSH list so that some machines are returned # with some fake architectures. user = factory.make_name('user') system_id = factory.make_name('system_id') machines = [factory.make_name('machine') for _ in range(5)] self.patch(virsh.VirshSSH, 'list').return_value = machines fake_arch = factory.make_name('arch') mock_arch = self.patch(virsh.VirshSSH, 'get_arch') mock_arch.return_value = fake_arch domain = factory.make_name('domain') # Patch get_state so that one of the machines is on, so we # can check that it will be forced off. fake_states = [ virsh.VirshVMState.ON, virsh.VirshVMState.OFF, virsh.VirshVMState.OFF, virsh.VirshVMState.ON, virsh.VirshVMState.ON, ] mock_state = self.patch(virsh.VirshSSH, 'get_state') mock_state.side_effect = fake_states # Setup the power parameters that we should expect to be # the output of the probe_and_enlist fake_password = factory.make_string() poweraddr = factory.make_name('poweraddr') called_params = [] fake_macs = [] for machine in machines: macs = [factory.make_mac_address() for _ in range(4)] fake_macs.append(macs) called_params.append({ 'power_address': poweraddr, 'power_id': machine, 'power_pass': fake_password, }) # Patch the get_mac_addresses so we get a known list of # mac addresses for each machine. mock_macs = self.patch(virsh.VirshSSH, 'get_mac_addresses') mock_macs.side_effect = fake_macs # Patch the poweroff and create as we really don't want these # actions to occur, but want to also check that they are called. mock_poweroff = self.patch(virsh.VirshSSH, 'poweroff') mock_create_node = self.patch(virsh, 'create_node') mock_create_node.side_effect = asynchronous( lambda *args, **kwargs: None if machines[4] in args else system_id) mock_commission_node = self.patch(virsh, 'commission_node') # Patch login and logout so that we don't really contact # a server at the fake poweraddr mock_login = self.patch(virsh.VirshSSH, 'login') mock_login.return_value = True mock_logout = self.patch(virsh.VirshSSH, 'logout') mock_get_machine_xml = self.patch(virsh.VirshSSH, 'get_machine_xml') mock_get_machine_xml.side_effect = [ SAMPLE_DUMPXML, SAMPLE_DUMPXML_2, SAMPLE_DUMPXML_3, SAMPLE_DUMPXML_4, SAMPLE_DUMPXML, ] mock_run = self.patch(virsh.VirshSSH, 'run') mock_run.side_effect = self._probe_and_enlist_mock_run # Perform the probe and enlist yield deferToThread(virsh.probe_virsh_and_enlist, user, poweraddr, fake_password, accept_all=True, domain=domain) # Check that login was called with the provided poweraddr and # password. self.expectThat(mock_login, MockCalledOnceWith(poweraddr, fake_password)) # Check that the create command had the correct parameters for # each machine. self.expectThat( mock_create_node, MockCallsMatch( call(fake_macs[0], fake_arch, 'virsh', called_params[0], domain, machines[0]), call(fake_macs[1], fake_arch, 'virsh', called_params[1], domain, machines[1]), call(fake_macs[2], fake_arch, 'virsh', called_params[2], domain, machines[2]), call(fake_macs[3], fake_arch, 'virsh', called_params[3], domain, machines[3]), call(fake_macs[4], fake_arch, 'virsh', called_params[4], domain, machines[4]), )) # The first and last machine should have poweroff called on it, as it # was initial in the on state. self.expectThat(mock_poweroff, MockCallsMatch( call(machines[0]), call(machines[3]), )) self.assertThat(mock_logout, MockCalledOnceWith()) self.expectThat( mock_commission_node, MockCallsMatch( call(system_id, user), call(system_id, user), call(system_id, user), call(system_id, user), ))
def test_probe_seamicro15k_and_enlist_v09(self): self.configure_api_v09_login() user = factory.make_name('user') ip = factory.make_ipv4_address() username = factory.make_name('username') password = factory.make_name('password') system_id = factory.make_name('system_id') domain = factory.make_name('domain') result = { 0: { 'serverId': '0/0', 'serverNIC': '0', 'serverMacAddr': factory.make_mac_address(), }, 1: { 'serverId': '1/0', 'serverNIC': '0', 'serverMacAddr': factory.make_mac_address(), }, 2: { 'serverId': '2/0', 'serverNIC': '0', 'serverMacAddr': factory.make_mac_address(), }, 3: { 'serverId': '3/1', 'serverNIC': '1', 'serverMacAddr': factory.make_mac_address(), }, } self.patch(SeaMicroAPIV09, 'get', Mock(return_value=result)) mock_create_node = self.patch(seamicro, 'create_node') mock_create_node.side_effect = asynchronous(lambda *_, **__: system_id) mock_commission_node = self.patch(seamicro, 'commission_node') yield deferToThread(probe_seamicro15k_and_enlist, user, ip, username, password, power_control='restapi', accept_all=True, domain=domain) self.assertEqual(3, mock_create_node.call_count) last = result[2] power_params = { 'power_control': 'restapi', 'system_id': last['serverId'].split('/')[0], 'power_address': ip, 'power_pass': password, 'power_user': username } self.expectThat( mock_create_node, MockCalledWith(last['serverMacAddr'], 'amd64', 'sm15k', power_params, domain=domain)) self.expectThat(mock_commission_node, MockCalledWith(system_id, user))
def test_probe_seamicro15k_and_enlist_v2(self): user = factory.make_name('user') ip = factory.make_ipv4_address() username = factory.make_name('username') password = factory.make_name('password') system_id = factory.make_name('system_id') fake_server_0 = FakeServer('0/0') fake_server_0.add_fake_nic('0') fake_server_0.add_fake_nic('1') fake_server_1 = FakeServer('1/0') fake_server_1.add_fake_nic('0') fake_server_1.add_fake_nic('1') fake_client = FakeSeaMicroClient() fake_client.servers = FakeSeaMicroServerManager() fake_client.servers.servers.append(fake_server_0) fake_client.servers.servers.append(fake_server_1) mock_get_api = self.patch(seamicro, 'get_seamicro15k_api') mock_get_api.return_value = fake_client mock_create_node = self.patch(seamicro, 'create_node') mock_create_node.side_effect = asynchronous(lambda *_, **__: system_id) mock_commission_node = self.patch(seamicro, 'commission_node') yield deferToThread(probe_seamicro15k_and_enlist, user, ip, username, password, power_control='restapi2', accept_all=True) self.assertEqual(2, mock_create_node.call_count) self.expectThat( mock_create_node, MockCallsMatch( call( fake_server_0.get_fake_macs(), 'amd64', 'sm15k', { 'power_control': 'restapi2', 'system_id': '0', 'power_address': ip, 'power_pass': password, 'power_user': username }, domain=None, ), call( fake_server_1.get_fake_macs(), 'amd64', 'sm15k', { 'power_control': 'restapi2', 'system_id': '1', 'power_address': ip, 'power_pass': password, 'power_user': username }, domain=None, ), )) self.expectThat(mock_commission_node, MockCalledWith(system_id, user))
def tearDown(self): super(TestServiceMaker, self).tearDown() # Disable database access in the reactor again. asynchronous(disable_all_database_connections, timeout=5)()
def test_probe_seamicro15k_and_enlist_v09(self): self.configure_api_v09_login() user = factory.make_name("user") ip = factory.make_ipv4_address() username = factory.make_name("username") password = factory.make_name("password") system_id = factory.make_name("system_id") domain = factory.make_name("domain") result = { 0: { "serverId": "0/0", "serverNIC": "0", "serverMacAddr": factory.make_mac_address(), }, 1: { "serverId": "1/0", "serverNIC": "0", "serverMacAddr": factory.make_mac_address(), }, 2: { "serverId": "2/0", "serverNIC": "0", "serverMacAddr": factory.make_mac_address(), }, 3: { "serverId": "3/1", "serverNIC": "1", "serverMacAddr": factory.make_mac_address(), }, } self.patch(SeaMicroAPIV09, "get", Mock(return_value=result)) mock_create_node = self.patch(seamicro, "create_node") mock_create_node.side_effect = asynchronous(lambda *_, **__: system_id) mock_commission_node = self.patch(seamicro, "commission_node") yield deferToThread( probe_seamicro15k_and_enlist, user, ip, username, password, power_control="restapi", accept_all=True, domain=domain, ) self.assertEqual(3, mock_create_node.call_count) last = result[2] power_params = { "power_control": "restapi", "system_id": last["serverId"].split("/")[0], "power_address": ip, "power_pass": password, "power_user": username, } self.expectThat( mock_create_node, MockCalledWith( last["serverMacAddr"], "amd64", "sm15k", power_params, domain=domain, ), ) self.expectThat(mock_commission_node, MockCalledWith(system_id, user))
def test_probe_seamicro15k_and_enlist_v2(self): user = factory.make_name("user") ip = factory.make_ipv4_address() username = factory.make_name("username") password = factory.make_name("password") system_id = factory.make_name("system_id") fake_server_0 = FakeServer("0/0") fake_server_0.add_fake_nic("0") fake_server_0.add_fake_nic("1") fake_server_1 = FakeServer("1/0") fake_server_1.add_fake_nic("0") fake_server_1.add_fake_nic("1") fake_client = FakeSeaMicroClient() fake_client.servers = FakeSeaMicroServerManager() fake_client.servers.servers.append(fake_server_0) fake_client.servers.servers.append(fake_server_1) mock_get_api = self.patch(seamicro, "get_seamicro15k_api") mock_get_api.return_value = fake_client mock_create_node = self.patch(seamicro, "create_node") mock_create_node.side_effect = asynchronous(lambda *_, **__: system_id) mock_commission_node = self.patch(seamicro, "commission_node") yield deferToThread( probe_seamicro15k_and_enlist, user, ip, username, password, power_control="restapi2", accept_all=True, ) self.assertEqual(2, mock_create_node.call_count) self.expectThat( mock_create_node, MockCallsMatch( call( fake_server_0.get_fake_macs(), "amd64", "sm15k", { "power_control": "restapi2", "system_id": "0", "power_address": ip, "power_pass": password, "power_user": username, }, domain=None, ), call( fake_server_1.get_fake_macs(), "amd64", "sm15k", { "power_control": "restapi2", "system_id": "1", "power_address": ip, "power_pass": password, "power_user": username, }, domain=None, ), ), ) self.expectThat(mock_commission_node, MockCalledWith(system_id, user))