def test__power_on(self): driver = RedfishPowerDriver() system_id = factory.make_name('system_id') context = make_context() url = driver.get_url(context) headers = driver.make_auth_headers(**context) node_id = context.get('node_id').encode('utf-8') mock_set_pxe_boot = self.patch(driver, 'set_pxe_boot') mock_power_query = self.patch(driver, 'power_query') mock_power_query.return_value = "on" mock_power = self.patch(driver, 'power') yield driver.power_on(system_id, context) self.assertThat(mock_set_pxe_boot, MockCalledOnceWith( url, node_id, headers)) self.assertThat(mock_power_query, MockCalledOnceWith( system_id, context)) self.assertThat(mock_power, MockCallsMatch( call("ForceOff", url, node_id, headers), call("On", url, node_id, headers)))
def test_power_on_calls_run_mscm_command(self): driver = MSCMPowerDriver() system_id = factory.make_name("system_id") context = make_context() power_query = self.patch(driver, "power_query") power_query.return_value = "on" self.patch(driver, "power_off") self.patch(driver, "configure_node_bootonce_pxe") run_mscm_command = self.patch(driver, "run_mscm_command") driver.power_on(system_id, context) self.assertThat( run_mscm_command, MockCallsMatch( call( "set node bootonce pxe %s" % context["node_id"], **context ), call("set node power on %s" % context["node_id"], **context), ), )
def test_run_script_only_sends_result_when_avail(self): scripts_dir = self.useFixture(TempDirectory()).path script = make_script(scripts_dir=scripts_dir) os.remove(script['result_path']) run_script(script, scripts_dir) self.assertThat(self.mock_output_and_send, MockCallsMatch( call('Starting %s' % script['msg_name'], **self.args), call( 'Finished %s: None' % script['msg_name'], exit_status=None, files={ script['combined_name']: script['combined'].encode(), script['stdout_name']: script['stdout'].encode(), script['stderr_name']: script['stderr'].encode(), }, **self.args), )) self.assertThat(self.mock_capture_script_output, MockCalledOnceWith( ANY, script['combined_path'], script['stdout_path'], script['stderr_path'], script['timeout_seconds']))
def test_compose_uses_non_commit_forms_first(self): request = MagicMock() pods = self.make_pods() # Make it skip the first over commitable pod pods[1].capabilities = [Capabilities.OVER_COMMIT] pods[1].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(), 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)))
def test_power_on_calls_power_control_recs(self): ip, port, username, password, node_id, context = self.make_context() recs_power_driver = RECSPowerDriver() power_control_recs_mock = self.patch(recs_power_driver, "power_control_recs") set_boot_source_recs_mock = self.patch(recs_power_driver, "set_boot_source_recs") recs_power_driver.power_on(context["node_id"], context) self.assertThat( power_control_recs_mock, MockCalledOnceWith(ip, port, username, password, node_id, "on"), ) self.assertThat( set_boot_source_recs_mock, MockCallsMatch( call(ip, port, username, password, node_id, "HDD", True), call(ip, port, username, password, node_id, "PXE", False), ), )
def test__deferredDHCPRequestErrback_cancels_all_on_FirstError(self): mock_cancelAll = self.patch(DHCPRequestMonitor, "cancelAll") def raise_ioerror(): raise IOError() a = deferLater(reactor, 0.0, raise_ioerror) b = deferLater(reactor, 6, lambda: "b") monitor = DHCPRequestMonitor("lo") monitor.deferredDHCPRequests = [a, b] deferredList = DeferredList( monitor.deferredDHCPRequests, consumeErrors=True, fireOnOneErrback=True, ) deferredList.addErrback(monitor.deferredDHCPRequestErrback) yield deferredList # Still have one call left in the reactor, since we mocked cancelAll(). b.cancel() self.assertThat(mock_cancelAll, MockCallsMatch(call([a, b])))
def test__run_logs_result_and_makes_properties_available(self): logger = self.useFixture(TwistedLoggerFixture()) monitor = DHCPRequestMonitor('lo') mock_send_and_await = self.patch(monitor, 'send_requests_and_await_replies') mock_send_and_await.return_value = { DHCPServer('127.0.0.1', '127.0.0.1'), DHCPServer('127.1.1.1', '127.2.2.2'), } yield monitor.run() self.assertThat(mock_send_and_await, MockCallsMatch(call())) self.assertThat( logger.output, DocTestMatches( "External DHCP server(s) discovered on interface 'lo': 127.0.0.1, " "127.1.1.1 (via 127.2.2.2)")) self.assertThat(monitor.dhcp_servers, Equals({"127.0.0.1", "127.1.1.1"})) self.assertThat(monitor.dhcp_addresses, Equals({"127.0.0.1", "127.2.2.2"}))
def test__waits(self): blockdevice = factory.make_name('blockdevice') test = factory.make_name('test') device = factory.make_name('device') mock_sleep = self.patch(smartctl, 'sleep') mock_run_smartctl = self.patch(smartctl, 'run_smartctl') mock_run_smartctl.side_effect = ( 'Self-test execution status: (42) Self-test routine in progress', '', '', ) smartctl.wait_smartctl_selftest(blockdevice, test, device) self.assertThat( mock_run_smartctl, MockCallsMatch(call(blockdevice, ['-c'], device), call(blockdevice, ['-c'], device), call(blockdevice, ['--all'], device))) self.assertThat(mock_sleep, MockCalledOnceWith(30))
def test_writes_keyring_data(self): fake_write_keyring = self.patch(keyrings, "write_keyring") sources = [{ "url": "http://%s" % self.getUniqueString(), "keyring_data": factory.make_bytes(), } for _ in range(5)] keyring_path = self.make_dir() keyrings.write_all_keyrings(keyring_path, sources) expected_calls = (mock.call( os.path.join( keyring_path, keyrings.calculate_keyring_name(source["url"]), ), source["keyring_data"], ) for source in sources) self.assertThat(fake_write_keyring, MockCallsMatch(*expected_calls))
def test_gets_adaptors(self): adaptor = 'adaptor' server = make_server() mac = 'xx' api = make_api() mock = self.patch(ucsm, 'get_children') def fake_get_children(api, element, class_id): if class_id == 'adaptorUnit': return [adaptor] elif class_id == 'adaptorHostEthIf': return [Element('ethif', {'mac': mac})] mock.side_effect = fake_get_children macs = get_macs(api, server) self.assertThat( mock, MockCallsMatch(call(api, server, 'adaptorUnit'), call(api, adaptor, 'adaptorHostEthIf'))) self.assertEqual([mac], macs)
def test__waits_alt(self): blockdevice = factory.make_name('blockdevice') test = factory.make_name('test') device = factory.make_name('device') mock_sleep = self.patch(smartctl, 'sleep') mock_run_smartctl = self.patch(smartctl, 'run_smartctl') mock_run_smartctl.side_effect = ( 'Background %s Self test in progress' % test, 'Background %s Self test in progress' % test, '', ) smartctl.wait_smartctl_selftest(blockdevice, test, device) self.assertThat( mock_run_smartctl, MockCallsMatch(call(blockdevice, ['-c'], device), call(blockdevice, ['--all'], device), call(blockdevice, ['--all'], device))) self.assertThat(mock_sleep, MockCalledOnceWith(30))
def test_DELETE_delete_with_force(self): self.become_admin() vlan = factory.make_VLAN() subnet = factory.make_Subnet(vlan=vlan) region = factory.make_Node_with_Interface_on_Subnet( node_type=NODE_TYPE.REGION_CONTROLLER, subnet=subnet, vlan=vlan) ip = factory.make_StaticIPAddress( interface=region.interface_set.first()) factory.make_Pod(ip_address=ip) mock_async_delete = self.patch(Pod, "async_delete") response = self.client.delete( self.get_region_uri(region), QUERY_STRING=urlencode({"force": "true"}, doseq=True), ) self.assertEqual( http.client.NO_CONTENT, response.status_code, explain_unexpected_response(http.client.NO_CONTENT, response), ) self.assertThat(mock_async_delete, MockCallsMatch(call()))
def test__issue_ipmi_command_issues_power_off_soft_mode(self): context = make_context() context["power_off_mode"] = "soft" ipmipower_command = make_ipmipower_command(**context) ipmipower_command += ("--soft", ) ipmi_power_driver = IPMIPowerDriver() env = get_env_with_locale() popen_mock = self.patch(ipmi_module, "Popen") process = popen_mock.return_value process.communicate.side_effect = [(b"off", b"")] process.returncode = 0 result = ipmi_power_driver._issue_ipmi_command("off", **context) self.expectThat( popen_mock, MockCallsMatch( call(ipmipower_command, stdout=PIPE, stderr=PIPE, env=env)), ) self.expectThat(result, Equals("off"))
def test_query_all_nodes_only_queries_queryable_power_types(self): nodes = self.make_nodes() # nodes are all queryable, so add one that isn't: nodes.append(self.make_node(power_type='manual')) # Report back that all nodes' power states are as recorded. power_states = [node['power_state'] for node in nodes] get_power_state = self.patch(power, 'get_power_state') get_power_state.side_effect = map(succeed, power_states) suppress_reporting(self) yield power.query_all_nodes(nodes) self.assertThat( get_power_state, MockCallsMatch(*(call(node['system_id'], node['hostname'], node['power_type'], node['context'], clock=reactor) for node in nodes if node['power_type'] in PowerDriverRegistry)))
def test__set_pxe_boot_sets_pxe(self): amt_power_driver = AMTPowerDriver() ip_address = factory.make_ipv4_address() power_pass = factory.make_name('power_pass') wsman_pxe_options = { 'ChangeBootOrder': (join(dirname(dirname(__file__)), "amt.wsman-pxe.xml"), ('http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/' 'CIM_BootConfigSetting?InstanceID="Intel(r) ' 'AMT: Boot Configuration 0"')), 'SetBootConfigRole': (join(dirname(dirname(__file__)), "amt.wsman-boot-config.xml"), ('http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/' 'CIM_BootService?SystemCreationClassName=' '"CIM_ComputerSystem"&SystemName="Intel(r) AMT"' '&CreationClassName="CIM_BootService"&Name="Intel(r)' ' AMT Boot Service"')), } wsman_opts = ('--port', '16992', '--hostname', ip_address, '--username', 'admin', '--password', power_pass, '--noverifypeer', '--noverifyhost') _run_mock = self.patch(amt_power_driver, '_run') amt_power_driver._set_pxe_boot(ip_address, power_pass) commands = [] stdins = [] for method, (schema_file, schema_uri) in wsman_pxe_options.items(): with open(schema_file, "rb") as fd: wsman_opts += ( '--input', '-', ) action = ('invoke', '--method', method, schema_uri) command = ('wsman', ) + wsman_opts + action commands.append(command) stdins.append(fd.read()) self.assertThat( _run_mock, MockCallsMatch(call(commands[0], power_pass, stdin=stdins[0]), call(commands[1], power_pass, stdin=stdins[1])))
def test_DELETE_delete_with_force(self): self.become_admin() vlan = factory.make_VLAN() factory.make_Subnet(vlan=vlan) rack = factory.make_RackController(vlan=vlan) ip = factory.make_StaticIPAddress(interface=rack.interface_set.first()) factory.make_Pod(ip_address=ip) vlan.dhcp_on = True vlan.primary_rack = rack vlan.save() mock_async_delete = self.patch(Pod, "async_delete") response = self.client.delete( self.get_rack_uri(rack), QUERY_STRING=urlencode({"force": "true"}, doseq=True), ) self.assertEqual( http.client.NO_CONTENT, response.status_code, explain_unexpected_response(http.client.NO_CONTENT, response), ) self.assertThat(mock_async_delete, MockCallsMatch(call()))
def test_SMART_support_no_match_found(self): storage = factory.make_name('storage') mock_check_output = self.patch(smartctl, "check_output") mock_check_output.return_value = b"SMART support is not available." mock_print = self.patch(smartctl, "print") self.assertRaises(SystemExit, smartctl.check_SMART_support, storage) self.assertThat( mock_check_output, MockCalledOnceWith(['sudo', '-n', 'smartctl', '--all', storage], stderr=STDOUT, timeout=smartctl.TIMEOUT)) self.assertThat( mock_print, MockCallsMatch( call('INFO: Veriying SMART support for the following ' 'drive: %s' % storage), call('INFO: Running command: ' 'sudo -n smartctl --all %s\n' % storage), call('INFO: Unable to run test. The following drive does ' 'not support SMART: %s\n' % storage)))
def test_SMART_support_is_not_available(self): storage = factory.make_name('storage') mock_check_output = self.patch(smartctl, "check_output") mock_check_output.side_effect = CalledProcessError(1, 'smartctl') mock_print = self.patch(smartctl, "print") self.assertRaises(SystemExit, smartctl.check_SMART_support, storage) self.assertThat( mock_check_output, MockCalledOnceWith(['sudo', '-n', 'smartctl', '--all', storage], stderr=STDOUT, timeout=smartctl.TIMEOUT)) self.assertThat( mock_print, MockCallsMatch( call('INFO: Veriying SMART support for the following drive: ' '%s' % storage), call('INFO: Running command: sudo -n smartctl --all ' '%s\n' % storage), call('INFO: Unable to determine if the drive supports SMART. ' 'Command failed to run and did not return any output. ')))
def test_list_supported_drives_ignores_iscsiadm_timeout(self): mock_check_output = self.patch(badblocks, 'check_output') drive = self.make_drive() mock_check_output.side_effect = [ TimeoutExpired('iscsiadm', 60), self.make_lsblk_line(drive) ] self.assertDictEqual( {'PATH': '/dev/%s' % drive['NAME'], **drive}, badblocks.list_drives()[0]) self.assertThat( mock_check_output, MockCallsMatch( call( ['sudo', '-n', 'iscsiadm', '-m', 'session', '-P', '3'], timeout=badblocks.TIMEOUT, stderr=DEVNULL), call( [ 'lsblk', '--exclude', '1,2,7', '-d', '-P', '-o', 'NAME,RO,MODEL,SERIAL', ], timeout=badblocks.TIMEOUT)))
def test_power_on_powers_on_blade(self): driver = MicrosoftOCSPowerDriver() context = make_context() system_id = factory.make_name('system_id') mock_power_query = self.patch(driver, "power_query") mock_power_query.return_value = 'on' mock_power_off = self.patch(driver, "power_off") mock_set_next_boot_device = self.patch( driver, "set_next_boot_device") mock_get = self.patch(driver, "get") driver.power_on(system_id, context) self.expectThat( mock_power_query, MockCalledOnceWith(system_id, context)) self.expectThat(mock_power_off, MockCalledOnceWith(system_id, context)) self.expectThat( mock_set_next_boot_device, MockCallsMatch( call(context, persistent=True), call(context, pxe=True))) self.expectThat( mock_get, MockCalledOnceWith( 'SetBladeOn', context, ["bladeid=%s" % context['blade_id']]))
def test_query_all_nodes_skips_nodes_in_action_registry(self): nodes = self.make_nodes() # First node is in the registry. power.power_action_registry[nodes[0]["system_id"]] = sentinel.action # Report back power state of nodes' not in registry. power_states = [node["power_state"] for node in nodes[1:]] get_power_state = self.patch(power, "get_power_state") get_power_state.side_effect = map(succeed, power_states) suppress_reporting(self) yield power.query_all_nodes(nodes) self.assertThat( get_power_state, MockCallsMatch( *( call( node["system_id"], node["hostname"], node["power_type"], node["context"], clock=reactor, ) for node in nodes[1:] ) ), ) self.assertThat( get_power_state, Not( MockCalledWith( nodes[0]["system_id"], nodes[0]["hostname"], nodes[0]["power_type"], nodes[0]["context"], clock=reactor, ) ), )
def test_run_scripts(self): mock_install_deps = self.patch( maas_run_remote_scripts, 'install_dependencies') mock_run_script = self.patch(maas_run_remote_scripts, 'run_script') single_thread = make_scripts(instance=False, parallel=0) instance_thread = [ make_scripts(parallel=1) for _ in range(3) ] any_thread = make_scripts(instance=False, parallel=2) scripts = copy.deepcopy(single_thread) for instance_thread_group in instance_thread: scripts += copy.deepcopy(instance_thread_group) scripts += copy.deepcopy(any_thread) url = factory.make_url() creds = factory.make_name('creds') scripts_dir = factory.make_name('scripts_dir') out_dir = os.path.join(scripts_dir, 'out') run_scripts(url, creds, scripts_dir, out_dir, scripts) self.assertEquals( len(single_thread) + len(instance_thread) + len(any_thread), mock_install_deps.call_count) expected_calls = [ call(script=script, scripts_dir=scripts_dir, send_result=True) for script in sorted(scripts, key=lambda i: ( 99 if i['hardware_type'] == 0 else i['hardware_type'], i['name'])) if script['parallel'] != 2 ] expected_calls += [ call(script=script, scripts_dir=scripts_dir, send_result=True) for script in sorted(scripts, key=lambda i: ( len(i.get('packages', {}).keys()), i['name'])) if script['parallel'] == 2 ] self.assertThat(mock_run_script, MockCallsMatch(*expected_calls))
def test_run_smartctl_failure(self): self.patch(smartctl, 'list_supported_drives').return_value = [ ['/dev/sda', '-d', 'sat'], ] output = factory.make_string() mock_popen = self.patch(smartctl, 'Popen') mock_popen.return_value = Popen('echo -n %s; exit 1' % output, stdout=PIPE, shell=True) mock_print = self.patch(smartctl, 'print') self.assertEquals(1, smartctl.run_smartctl()) dashes = '-' * int((80.0 - (2 + len('/dev/sda'))) / 2) header = '%s /dev/sda %s' % (dashes, dashes) self.assertThat( mock_print, MockCallsMatch( call(header), call(), call('Error, `smartctl --xall /dev/sda -d sat` returned 1!'), call('See the smartctl man page for return code meaning'), call(), call(output)))
def test__writes_config_and_calls_restart_when_no_current_state(self): write_file = self.patch_sudo_write_file() restart_service = self.patch_restartService() failover_peers = make_failover_peer_config() shared_network = make_shared_network() [shared_network] = fix_shared_networks_failover([shared_network], [failover_peers]) host = make_host() 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') yield self.configure(omapi_key, [failover_peers], [shared_network], [host], [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(restart_service, MockCalledOnceWith(self.server.dhcp_service)) self.assertEquals( dhcp._current_server_state[self.server.dhcp_service], dhcp.DHCPState(omapi_key, [failover_peers], [shared_network], [host], [interface], global_dhcp_snippets))
def test_requests_beaconing_when_timer_fires(self): fixture = self.useFixture(MockLiveClusterToRegionRPCFixture()) protocol, connecting = fixture.makeEventLoop(region.GetDiscoveryState) self.addCleanup((yield connecting)) rpc_service = services.getServiceNamed("rpc") reactor = Clock() service = RackNetworksMonitoringService( rpc_service, reactor, enable_monitoring=False, enable_beaconing=True, ) service.beaconing_protocol = Mock() service.beaconing_protocol.queueMulticastBeaconing = Mock() service.getInterfaces = lambda: succeed({}) service._recorded = {} service.startService() yield service.stopService() self.assertThat( service.beaconing_protocol.queueMulticastBeaconing, MockCallsMatch(call(solicitation=True)), )
def test__power_on(self): driver = RedfishPowerDriver() context = make_context() url = driver.get_url(context) headers = driver.make_auth_headers(**context) node_id = b'1' mock_redfish_request = self.patch(driver, 'redfish_request') mock_redfish_request.return_value = ( SAMPLE_JSON_SYSTEMS, None) mock_set_pxe_boot = self.patch(driver, 'set_pxe_boot') mock_power_query = self.patch(driver, 'power_query') mock_power_query.return_value = "on" mock_power = self.patch(driver, 'power') yield driver.power_on(node_id, context) self.assertThat(mock_set_pxe_boot, MockCalledOnceWith( url, node_id, headers)) self.assertThat(mock_power_query, MockCalledOnceWith( node_id, context)) self.assertThat(mock_power, MockCallsMatch( call("ForceOff", url, node_id, headers), call("On", url, node_id, headers)))
def test_returns_true_with_device(self): device = factory.make_name("device") self.mock_check_smart_support.return_value = (device, [42]) device = "%s,42" % device self.assertTrue(smartctl.execute_smartctl(self.blockdevice, self.test)) self.assertThat( self.mock_check_smart_support, MockCallsMatch(call(self.blockdevice), call(self.blockdevice, device)), ) self.assertThat( self.mock_run_smartctl_selftest, MockCalledOnceWith(self.blockdevice, self.test, device), ) self.assertThat( self.mock_wait_smartctl_selftest, MockCalledOnceWith(self.blockdevice, self.test, device), ) self.assertThat( self.mock_check_smartctl, MockCalledOnceWith(self.blockdevice, device), )
def test_run_smartctl_with_smartctl_failure(self): self.patch(smartctl, 'list_supported_drives').return_value = [ ['/dev/sda', '-d', 'sat'], ] output = factory.make_string() self.patch(smartctl, 'check_call').side_effect = CalledProcessError( 1, 'smartctl'), mock_popen = self.patch(smartctl, 'Popen') mock_popen.return_value = Popen(['echo', '-n', output], stdout=PIPE) mock_print = self.patch(smartctl, 'print') test = factory.make_name('test') self.assertEquals(1, smartctl.run_smartctl(test)) dashes = '-' * int((80.0 - (2 + len('/dev/sda'))) / 2) header = '%s /dev/sda %s' % (dashes, dashes) self.assertThat( mock_print, MockCallsMatch( call(header), call(), call('Failed to start and wait for smartctl self-test: %s' % test), call(), call(output)))
def test__show_service_start_error(self): url = factory.make_simple_http_url() secret = factory.make_bytes() register_command.run(self.make_args(url=url, secret=to_hex(secret))) mock_call_and_check = self.patch(register_command, 'call_and_check') mock_call_and_check.side_effect = [ call(), call(), ExternalProcessError(1, 'systemctl start', 'mock error'), ] mock_stderr = self.patch(register_command.stderr, 'write') with ExpectedException(SystemExit): register_command.run(self.make_args(url=url, secret=to_hex(secret))) self.assertThat( mock_stderr, MockCallsMatch( call('Unable to enable and start the maas-rackd service.'), call('\n'), call('Failed with error: mock error.'), call('\n'), ))
def test__issue_ipmi_command_issues_power_off(self): context = make_context() ipmi_chassis_config_command = make_ipmi_chassis_config_command( **context, tmp_config_name=ANY) ipmipower_command = make_ipmipower_command(**context) ipmipower_command += ('--off', ) ipmi_power_driver = IPMIPowerDriver() env = select_c_utf8_locale() popen_mock = self.patch(ipmi_module, 'Popen') process = popen_mock.return_value process.communicate.side_effect = [(b'', b''), (b'off', b'')] process.returncode = 0 result = ipmi_power_driver._issue_ipmi_command('off', **context) self.expectThat( popen_mock, MockCallsMatch( call(ipmi_chassis_config_command, stdout=PIPE, stderr=PIPE, env=env), call(ipmipower_command, stdout=PIPE, stderr=PIPE, env=env))) self.expectThat(result, Equals('off'))