def test_compose_bcd_missing_template(self): method = WindowsPXEBootMethod() self.patch(method, "get_resource_path").return_value = "" local_host = factory.make_ipv4_address() kernel_params = make_kernel_parameters() self.assertRaises( BootMethodError, method.compose_bcd, kernel_params, local_host )
def test__parses_URL_with_IPv4_address_and_port(self): ip = factory.make_ipv4_address().encode("ascii") port = factory.pick_port() path = factory.make_name("path").encode("ascii") uri = get_patched_URI().fromBytes(b"http://%s:%d/%s" % (ip, port, path)) self.expectThat(uri.host, Equals(ip)) self.expectThat(uri.path, Equals(b"/%s" % path)) self.expectThat(uri.port, Equals(port))
def test_get_default_gateway_ip_returns_first_ip(self): gw_address = factory.make_ipv4_address() ipv4_address1 = factory.make_ipv4_address() ipv4_address2 = factory.make_ipv4_address() iface = factory.make_name('eth') self.patch(netifaces, 'gateways').return_value = { 'default': { netifaces.AF_INET: (gw_address, iface), } } self.patch(netifaces, 'ifaddresses').return_value = { netifaces.AF_INET: [{ 'addr': ipv4_address1 }, { 'addr': ipv4_address2 }] } self.assertEqual(ipv4_address1, snappy.get_default_gateway_ip())
def test_login_with_password(self): virsh_outputs = [ "ubuntu@%s's password: " % factory.make_ipv4_address(), ] conn = self.configure_virshssh_pexpect(virsh_outputs) fake_password = factory.make_name('password') mock_sendline = self.patch(conn, 'sendline') conn.login(poweraddr=None, password=fake_password) self.assertThat(mock_sendline, MockCalledOnceWith(fake_password))
def make_context(): """Make and return a power parameters context.""" return { "power_address": factory.make_ipv4_address(), "power_port": "%d" % randint(2000, 4000), "power_user": factory.make_name("power_user"), "power_pass": factory.make_name("power_pass"), "blade_id": "%d" % randint(1, 24), }
def make_context(): """Make and return a power parameters context.""" return { 'power_address': factory.make_ipv4_address(), 'power_port': "%d" % randint(2000, 4000), 'power_user': factory.make_name('power_user'), 'power_pass': factory.make_name('power_pass'), 'blade_id': "%d" % randint(1, 24), }
def test_tftp_service(self): # A TFTP service is configured and added to the top-level service. interfaces = [ factory.make_ipv4_address(), factory.make_ipv6_address(), ] self.patch( tftp_module, "get_all_interface_addresses", lambda: interfaces) example_root = self.make_dir() example_client_service = Mock() example_port = factory.pick_port() tftp_service = TFTPService( resource_root=example_root, client_service=example_client_service, port=example_port) tftp_service.updateServers() # The "tftp" service is a multi-service containing UDP servers for # each interface defined by get_all_interface_addresses(). self.assertIsInstance(tftp_service, MultiService) # There's also a TimerService that updates the servers every 45s. self.assertThat( tftp_service.refresher, MatchesStructure.byEquality( step=45, parent=tftp_service, name="refresher", call=(tftp_service.updateServers, (), {}), )) expected_backend = MatchesAll( IsInstance(TFTPBackend), AfterPreprocessing( lambda backend: backend.base.path, Equals(example_root)), AfterPreprocessing( lambda backend: backend.client_service, Equals(example_client_service))) expected_protocol = MatchesAll( IsInstance(TFTP), AfterPreprocessing( lambda protocol: protocol.backend, expected_backend)) expected_server = MatchesAll( IsInstance(internet.UDPServer), AfterPreprocessing( lambda service: len(service.args), Equals(2)), AfterPreprocessing( lambda service: service.args[0], # port Equals(example_port)), AfterPreprocessing( lambda service: service.args[1], # protocol expected_protocol)) self.assertThat( tftp_service.getServers(), AllMatch(expected_server)) # Only the interface used for each service differs. self.assertItemsEqual( [svc.kwargs for svc in tftp_service.getServers()], [{"interface": interface} for interface in interfaces])
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_get_amt_command_raises_power_error(self): amt_power_driver = AMTPowerDriver() for error, error_info in AMT_ERRORS.items(): self.patch_run_command(stderr=error.encode("utf-8"), decode=True) self.assertRaises( error_info.get("exception"), amt_power_driver._get_amt_command, factory.make_ipv4_address(), factory.make_name("power_pass"), )
def test_power_query_seamicro15k_v2_raises_error_when_api_None(self): ip = factory.make_ipv4_address() username = factory.make_string() password = factory.make_string() mock_get_api = self.patch(seamicro, 'get_seamicro15k_api') mock_get_api.return_value = None self.assertRaises(SeaMicroError, power_query_seamicro15k_v2, ip, username, password, '0')
def test_power_control_seamicro15k_v09_exception_failure(self): self.configure_api_v09_login() ip = factory.make_ipv4_address() username = factory.make_string() password = factory.make_string() mock = self.patch(SeaMicroAPIV09, 'power_server') mock.side_effect = SeaMicroAPIV09Error("mock error") self.assertRaises(SeaMicroAPIV09Error, power_control_seamicro15k_v09, ip, username, password, '25', 'on')
def test_get_default_gateway_ip_returns_ipv4_over_ipv6(self): ipv4_address = factory.make_ipv4_address() ipv6_address = factory.make_ipv6_address() self.patch(netifaces, 'gateways').return_value = { 'default': { netifaces.AF_INET: (ipv4_address, factory.make_name('eth')), netifaces.AF_INET6: (ipv6_address, factory.make_name('eth')), } } self.assertEqual(ipv4_address, snappy.get_default_gateway_ip())
def test__get_amt_command_raises_power_error(self): amt_power_driver = AMTPowerDriver() for error, error_info in AMT_ERRORS.items(): popen_mock = self.patch(amt_module, 'Popen') process = popen_mock.return_value process.communicate.return_value = (b'', error.encode('utf-8')) self.assertRaises(error_info.get('exception'), amt_power_driver._get_amt_command, factory.make_ipv4_address(), factory.make_name('power_pass'))
def make_sources(): hosts = [factory.make_hostname().lower() for _ in range(2)] hosts.append(factory.make_ipv4_address()) hosts.append("[%s]" % factory.make_ipv6_address()) urls = [ "http://%s:%s/images-stream/streams/v1/index.json" % (host, randint(1, 1000)) for host in hosts ] sources = [{"url": url, "selections": []} for url in urls] return sources, hosts
def test_wsman_query_state_runs_query_loop(self): amt_power_driver = AMTPowerDriver() ip_address = factory.make_ipv4_address() power_pass = factory.make_name('power_pass') _issue_wsman_command_mock = self.patch(amt_power_driver, '_issue_wsman_command') _issue_wsman_command_mock.return_value = None self.assertRaises(PowerActionError, amt_power_driver.wsman_query_state, ip_address, power_pass)
def test_power_control_seamicro15k_v09(self): self.configure_api_v09_login() ip = factory.make_ipv4_address() username = factory.make_string() password = factory.make_string() mock = self.patch(SeaMicroAPIV09, "power_server") power_control_seamicro15k_v09(ip, username, password, "25", "on") self.assertThat( mock, MockCalledOnceWith("25/0", POWER_STATUS.ON, do_pxe=True))
def test_compose_rootfs_over_http_ipv4(self): params = make_kernel_parameters(fs_host=factory.make_ipv4_address()) self.assertThat( compose_kernel_command_line(params), ContainsAll([ "ro", "root=squash:http://%s:5248/images/%s/%s/%s/%s/%s/squashfs" % (params.fs_host, params.osystem, params.arch, params.subarch, params.release, params.label) ]))
def test_ignores_network_larger_than_slash_16(self): network = IPNetwork("%s/15" % factory.make_ipv4_address()) self.assertEqual( [], DNSReverseZoneConfig.get_GENERATE_directives( network, factory.make_string(), DomainInfo(network, "do not care"), ), )
def test_dtrt_for_larger_networks(self): # For every other network size that we're not explicitly # testing here, # DNSForwardZoneConfig.get_GENERATE_directives() will return # one GENERATE directive for every 255 addresses in the network. for prefixlen in range(23, 16): network = IPNetwork("%s/%s" % (factory.make_ipv4_address(), prefixlen)) directives = DNSForwardZoneConfig.get_GENERATE_directives(network) self.assertIsEqual(network.size / 256, len(directives))
def test_returns_single_entry_for_slash_24_network(self): network = IPNetwork("%s/24" % factory.make_ipv4_address()) reverse = ".".join(IPAddress(network).reverse_dns.split(".")[1:-1]) domain = factory.make_string() expected_generate_directives = self.get_expected_generate_directives( network, domain) directives = DNSReverseZoneConfig.get_GENERATE_directives( network, domain, DomainInfo(network, reverse)) self.expectThat(directives, HasLength(1)) self.assertItemsEqual(expected_generate_directives, directives)
def test_get_reader_bcd(self): method = WindowsPXEBootMethod() mock_compose_bcd = self.patch(method, 'compose_bcd') local_host = factory.make_ipv4_address() kernel_params = make_kernel_parameters(osystem='windows') method.get_reader( None, kernel_params, path='bcd', local_host=local_host) self.assertThat( mock_compose_bcd, MockCalledOnceWith(kernel_params, local_host))
def test_get_boot_method_reader_returns_rendered_params(self): # Fake configuration parameters, as discovered from the file path. fake_params = {"mac": factory.make_mac_address("-")} # Fake kernel configuration parameters, as returned from the RPC call. fake_kernel_params = make_kernel_parameters() fake_params = fake_kernel_params._asdict() # Stub the output of list_boot_images so the label is set in the # kernel parameters. boot_image = { "osystem": fake_params["osystem"], "release": fake_params["release"], "architecture": fake_params["arch"], "subarchitecture": fake_params["subarch"], "purpose": fake_params["purpose"], "supported_subarches": "", "label": fake_params["label"], } self.patch(tftp_module, "list_boot_images").return_value = [boot_image] del fake_params["label"] # Stub RPC call to return the fake configuration parameters. client = Mock() client.localIdent = factory.make_name("system_id") client.return_value = succeed(fake_params) client_service = Mock() client_service.getClientNow.return_value = succeed(client) # get_boot_method_reader() takes a dict() of parameters and returns an # `IReader` of a PXE configuration, rendered by # `PXEBootMethod.get_reader`. backend = TFTPBackend(self.make_dir(), client_service) # Stub get_reader to return the render parameters. method = PXEBootMethod() fake_render_result = factory.make_name("render").encode("utf-8") render_patch = self.patch(method, "get_reader") render_patch.return_value = BytesReader(fake_render_result) # Get the rendered configuration, which will actually be a JSON dump # of the render-time parameters. params_with_ip = dict(fake_params) params_with_ip['remote_ip'] = factory.make_ipv4_address() reader = yield backend.get_boot_method_reader(method, params_with_ip) self.addCleanup(reader.finish) self.assertIsInstance(reader, BytesReader) output = reader.read(10000) # The result has been rendered by `method.get_reader`. self.assertEqual(fake_render_result, output) self.assertThat( method.get_reader, MockCalledOnceWith(backend, kernel_params=fake_kernel_params, **params_with_ip))
def test_get_ip_address_prefers_v4_addresses_to_v6(self): addresses = [factory.make_ipv6_address() for _ in range(3)] # We add a deliberately low v6 address to show that the v4 # address is always preferred. ipv6_address = "::1" ipv4_address = factory.make_ipv4_address() addresses.append(ipv6_address) addresses.append(ipv4_address) self.patch(address, "get_all_addresses_for_interface").return_value = addresses self.assertEqual(ipv4_address, address.get_ip_address(b"lo"))
def test_wsman_power_off_raises_power_action_error(self): amt_power_driver = AMTPowerDriver() ip_address = factory.make_ipv4_address() power_pass = factory.make_name('power_pass') self.patch(amt_power_driver, '_issue_wsman_command') wsman_query_state_mock = self.patch(amt_power_driver, 'wsman_query_state') wsman_query_state_mock.return_value = 'error' self.assertRaises(PowerActionError, amt_power_driver.wsman_power_off, ip_address, power_pass)
def test_get_default_gateway_ip_returns_ipv4_over_ipv6(self): gw4_address = factory.make_ipv4_address() gw6_address = factory.make_ipv6_address() ipv4_address = factory.make_ipv4_address() ipv6_address = factory.make_ipv6_address() iface = factory.make_name('eth') self.patch(netifaces, 'gateways').return_value = { 'default': { netifaces.AF_INET: (gw4_address, iface), netifaces.AF_INET6: (gw6_address, iface), } } self.patch(netifaces, 'ifaddresses').return_value = { netifaces.AF_INET: [{ 'addr': ipv4_address }], netifaces.AF_INET6: [{ 'addr': ipv6_address }], } self.assertEqual(ipv4_address, snappy.get_default_gateway_ip())
def test_renders_the_given_peers(self): peers = [ factory.make_ipv4_address(), factory.make_ipv6_address(), factory.make_hostname(), ] ntp_maas_conf = config._render_ntp_maas_conf([], peers, 0) self.assertThat(ntp_maas_conf, StartsWith('# MAAS NTP configuration.\n')) observed_peers = extract_peers_full(ntp_maas_conf) self.assertThat(observed_peers, Equals([("peer", peer, "") for peer in peers]))
def test_enlist_compose_kernel_command_line_inc_cc_datasource(self): # The result of compose_kernel_command_line includes the cloud-init # options for the datasource and cloud-config-url params = self.make_kernel_parameters( purpose="enlist", fs_host=factory.make_ipv4_address()) cmdline = compose_kernel_command_line(params) self.assertThat( cmdline, ContainsAll([ "cc:{'datasource_list': ['MAAS']}end_cc", "cloud-config-url=%s" % params.preseed_url ]))
def test_enlist_compose_kernel_command_line_inc_purpose_opts4(self): # The result of compose_kernel_command_line includes the purpose # options for a non "commissioning" node. params = self.make_kernel_parameters( purpose="enlist", fs_host=factory.make_ipv4_address()) cmdline = compose_kernel_command_line(params) self.assertThat( cmdline, ContainsAll([ "root=squash:http://", "overlayroot=tmpfs", "ip6=off", "ip=::::%s:BOOTIF" % params.hostname ]))
def addEventLoop(self, protocol): """Add a new stub event-loop using the given `protocol`. The `protocol` should be an instance of `amp.AMP`. :return: py:class:`twisted.test.iosim.IOPump` """ self.ensureSharedSecret() eventloop = self.getEventLoopName(protocol) address = factory.make_ipv4_address(), factory.pick_port() client = ClusterClient(address, eventloop, self.rpc_service) return self.connect(client, protocol)
def test_get_default_gateway_ip_returns_first_ip(self): gw_address = factory.make_ipv4_address() ipv4_address1 = factory.make_ipv4_address() ipv4_address2 = factory.make_ipv4_address() iface = factory.make_name("eth") self.patch(netifaces, "gateways").return_value = { "default": { netifaces.AF_INET: (gw_address, iface) } } self.patch(netifaces, "ifaddresses").return_value = { netifaces.AF_INET: [ { "addr": ipv4_address1 }, { "addr": ipv4_address2 }, ] } self.assertEqual(ipv4_address1, snappy.get_default_gateway_ip())