def test_removes_master_mac_property_v2(self): nic_master, mac_master = "ens3", self.random_string() nic_other, mac_other = "ens7", self.random_string() nic_extra, mac_extra = "enp0s1f2", self.random_string() self.m_get_interfaces_by_mac.return_value = { mac_master: nic_master, mac_other: nic_other, mac_extra: nic_extra, } netcfg = { "version": 2, "ethernets": { nic_extra: { "dhcp4": True, "set-name": nic_extra, "match": {"macaddress": mac_extra}, }, nic_other: { "dhcp4": True, "set-name": nic_other, "match": {"macaddress": mac_other}, }, nic_master: { "dhcp4": True, "set-name": nic_master, "match": {"macaddress": mac_master}, }, }, } def _is_netfail_master(iface): if iface == "ens3": return True return False self.m_netfail_master.side_effect = _is_netfail_master expected_cfg = { "version": 2, "ethernets": { nic_master: {"dhcp4": True, "match": {"name": nic_master}}, nic_extra: { "dhcp4": True, "set-name": nic_extra, "match": {"macaddress": mac_extra}, }, nic_other: { "dhcp4": True, "set-name": nic_other, "match": {"macaddress": mac_other}, }, }, } oracle._ensure_netfailover_safe(netcfg) import pprint pprint.pprint(netcfg) print("---- ^^ modified ^^ ---- vv original vv ----") pprint.pprint(expected_cfg) self.assertEqual(expected_cfg, netcfg)
def test_removes_master_mac_property_v1(self): nic_master, mac_master = 'ens3', self.random_string() nic_other, mac_other = 'ens7', self.random_string() nic_extra, mac_extra = 'enp0s1f2', self.random_string() self.m_get_interfaces_by_mac.return_value = { mac_master: nic_master, mac_other: nic_other, mac_extra: nic_extra, } netcfg = {'version': 1, 'config': [ {'type': 'physical', 'name': nic_master, 'mac_address': mac_master}, {'type': 'physical', 'name': nic_other, 'mac_address': mac_other}, {'type': 'physical', 'name': nic_extra, 'mac_address': mac_extra}, ]} def _is_netfail_master(iface): if iface == 'ens3': return True return False self.m_netfail_master.side_effect = _is_netfail_master expected_cfg = {'version': 1, 'config': [ {'type': 'physical', 'name': nic_master}, {'type': 'physical', 'name': nic_other, 'mac_address': mac_other}, {'type': 'physical', 'name': nic_extra, 'mac_address': mac_extra}, ]} oracle._ensure_netfailover_safe(netcfg) self.assertEqual(expected_cfg, netcfg)
def test_secondary_nic(self): self.m_readurl.return_value = OPC_VM_SECONDARY_VNIC_RESPONSE mac_addr, nic_name = '00:00:17:02:2b:b1', 'ens3' self.m_get_interfaces_by_mac.return_value = { mac_addr: nic_name, } network_config = {'version': 1, 'config': [{'primary': 'nic'}]} oracle._add_network_config_from_opc_imds(network_config) # The input is mutated self.assertEqual(2, len(network_config['config'])) secondary_nic_cfg = network_config['config'][1] self.assertEqual(nic_name, secondary_nic_cfg['name']) self.assertEqual('physical', secondary_nic_cfg['type']) self.assertEqual(mac_addr, secondary_nic_cfg['mac_address']) self.assertEqual(9000, secondary_nic_cfg['mtu']) self.assertEqual(1, len(secondary_nic_cfg['subnets'])) subnet_cfg = secondary_nic_cfg['subnets'][0] # These values are hard-coded in OPC_VM_SECONDARY_VNIC_RESPONSE self.assertEqual('10.0.0.231', subnet_cfg['address']) self.assertEqual('24', subnet_cfg['netmask']) self.assertEqual('10.0.0.1', subnet_cfg['gateway']) self.assertEqual('manual', subnet_cfg['control'])
def test_removes_master_mac_property_v1(self): nic_master, mac_master = "ens3", self.random_string() nic_other, mac_other = "ens7", self.random_string() nic_extra, mac_extra = "enp0s1f2", self.random_string() self.m_get_interfaces_by_mac.return_value = { mac_master: nic_master, mac_other: nic_other, mac_extra: nic_extra, } netcfg = { "version": 1, "config": [ { "type": "physical", "name": nic_master, "mac_address": mac_master, }, { "type": "physical", "name": nic_other, "mac_address": mac_other, }, { "type": "physical", "name": nic_extra, "mac_address": mac_extra, }, ], } def _is_netfail_master(iface): if iface == "ens3": return True return False self.m_netfail_master.side_effect = _is_netfail_master expected_cfg = { "version": 1, "config": [ { "type": "physical", "name": nic_master }, { "type": "physical", "name": nic_other, "mac_address": mac_other, }, { "type": "physical", "name": nic_extra, "mac_address": mac_extra, }, ], } oracle._ensure_netfailover_safe(netcfg) self.assertEqual(expected_cfg, netcfg)
def test_parse_html(self): """Test parsing of lower case html.""" self.assertEqual( ['2013-10-17/', 'latest/'], oracle._load_index(self._known_html_api_versions)) self.assertEqual( ['meta_data.json', 'user_data'], oracle._load_index(self._known_html_contents))
def test_parse_newline_list_with_endl(self): """Test parsing of newline separated list with ending newline.""" self.assertEqual( ['2013-10-17/', 'latest/'], oracle._load_index("\n".join(["2013-10-17/", "latest/", ""]))) self.assertEqual( ['meta_data.json', 'user_data'], oracle._load_index("\n".join(["meta_data.json", "user_data", ""])))
def test_broken_no_metadata_json(self, m_read_system_uuid): """Datasource requires meta_data.json.""" httpretty.register_uri(httpretty.GET, self.mdurl + MD_VER + "/", '\n'.join(['user_data']).encode('utf-8')) with self.assertRaises(BrokenMetadata) as cm: oracle.read_metadata() self.assertIn("Required field 'meta_data.json' missing", str(cm.exception))
def test_parse_newline_list_with_endl(self): """Test parsing of newline separated list with ending newline.""" self.assertEqual(['2013-10-17/', 'latest/'], oracle._load_index("\n".join( ["2013-10-17/", "latest/", ""]))) self.assertEqual(['meta_data.json', 'user_data'], oracle._load_index("\n".join( ["meta_data.json", "user_data", ""])))
def test_broken_no_metadata_json(self, m_read_system_uuid): """Datasource requires meta_data.json.""" httpretty.register_uri( httpretty.GET, self.mdurl + MD_VER + "/", '\n'.join(['user_data']).encode('utf-8')) with self.assertRaises(BrokenMetadata) as cm: oracle.read_metadata() self.assertIn("Required field 'meta_data.json' missing", str(cm.exception))
def test_parse_newline_list_without_endl(self): """Test parsing of newline separated list with no ending newline. Actual openstack implementation does not include trailing newline.""" self.assertEqual(['2013-10-17/', 'latest/'], oracle._load_index("\n".join( ["2013-10-17/", "latest/"]))) self.assertEqual(['meta_data.json', 'user_data'], oracle._load_index("\n".join( ["meta_data.json", "user_data"])))
def test_parse_newline_list_without_endl(self): """Test parsing of newline separated list with no ending newline. Actual openstack implementation does not include trailing newline.""" self.assertEqual( ['2013-10-17/', 'latest/'], oracle._load_index("\n".join(["2013-10-17/", "latest/"]))) self.assertEqual( ['meta_data.json', 'user_data'], oracle._load_index("\n".join(["meta_data.json", "user_data"])))
def test_parse_html_upper(self): """Test parsing of upper case html, although known content is lower.""" def _toupper(data): return data.replace("<a", "<A").replace("html>", "HTML>") self.assertEqual( ['2013-10-17/', 'latest/'], oracle._load_index(_toupper(self._known_html_api_versions))) self.assertEqual( ['meta_data.json', 'user_data'], oracle._load_index(_toupper(self._known_html_contents)))
def test_missing_mac_skipped_v2(self): self.m_readurl.return_value = OPC_VM_SECONDARY_VNIC_RESPONSE self.m_get_interfaces_by_mac.return_value = {} network_config = {'version': 2, 'ethernets': {'primary': {'nic': {}}}} oracle._add_network_config_from_opc_imds(network_config) self.assertEqual(1, len(network_config['ethernets'])) self.assertIn( 'Interface with MAC 00:00:17:02:2b:b1 not found; skipping', self.logs.getvalue())
def test_parse_html_upper(self): """Test parsing of upper case html, although known content is lower.""" def _toupper(data): return data.replace("<a", "<A").replace("html>", "HTML>") self.assertEqual(['2013-10-17/', 'latest/'], oracle._load_index( _toupper(self._known_html_api_versions))) self.assertEqual(['meta_data.json', 'user_data'], oracle._load_index(_toupper( self._known_html_contents)))
def test_checks_v1_skips_non_phys_interfaces(self): mac_addr, nic_name = '00:00:17:02:2b:b1', 'bond0' self.m_get_interfaces_by_mac.return_value = { mac_addr: nic_name, } netcfg = {'version': 1, 'config': [ {'type': 'bond', 'name': nic_name, 'mac_address': mac_addr, 'subnets': [{'type': 'dhcp4'}]}]} passed_netcfg = copy.copy(netcfg) oracle._ensure_netfailover_safe(passed_netcfg) self.assertEqual(netcfg, passed_netcfg) self.assertEqual(0, self.m_netfail_master.call_count)
def test_skips_v2_non_ethernet_interfaces(self): mac_addr, nic_name = '00:00:17:02:2b:b1', 'wlps0' self.m_get_interfaces_by_mac.return_value = { mac_addr: nic_name, } netcfg = {'version': 2, 'wifis': { nic_name: {'dhcp4': True, 'critical': True, 'set-name': nic_name, 'match': {'macaddress': mac_addr}}}} passed_netcfg = copy.copy(netcfg) oracle._ensure_netfailover_safe(passed_netcfg) self.assertEqual(netcfg, passed_netcfg) self.assertEqual(0, self.m_netfail_master.call_count)
def test_checks_v2_type_ethernet_interfaces(self): mac_addr, nic_name = '00:00:17:02:2b:b1', 'ens3' self.m_get_interfaces_by_mac.return_value = { mac_addr: nic_name, } netcfg = {'version': 2, 'ethernets': { nic_name: {'dhcp4': True, 'critical': True, 'set-name': nic_name, 'match': {'macaddress': mac_addr}}}} passed_netcfg = copy.copy(netcfg) self.m_netfail_master.return_value = False oracle._ensure_netfailover_safe(passed_netcfg) self.assertEqual(netcfg, passed_netcfg) self.assertEqual([mock.call(nic_name)], self.m_netfail_master.call_args_list)
def test_checks_v1_type_physical_interfaces(self): mac_addr, nic_name = '00:00:17:02:2b:b1', 'ens3' self.m_get_interfaces_by_mac.return_value = { mac_addr: nic_name, } netcfg = {'version': 1, 'config': [ {'type': 'physical', 'name': nic_name, 'mac_address': mac_addr, 'subnets': [{'type': 'dhcp4'}]}]} passed_netcfg = copy.copy(netcfg) self.m_netfail_master.return_value = False oracle._ensure_netfailover_safe(passed_netcfg) self.assertEqual(netcfg, passed_netcfg) self.assertEqual([mock.call(nic_name)], self.m_netfail_master.call_args_list)
def oracle_ds(request, fixture_utils, paths, metadata_version): """ Return an instantiated DataSourceOracle. This also performs the mocking required for the default test case: * ``_read_system_uuid`` returns something, * ``_is_platform_viable`` returns True, * ``_is_iscsi_root`` returns True (the simpler code path), * ``read_opc_metadata`` returns ``OPC_V1_METADATA`` (This uses the paths fixture for the required helpers.Paths object, and the fixture_utils fixture for fetching markers.) """ sys_cfg = fixture_utils.closest_marker_first_arg_or( request, "ds_sys_cfg", mock.MagicMock() ) metadata = OpcMetadata(metadata_version, json.loads(OPC_V2_METADATA), None) with mock.patch(DS_PATH + "._read_system_uuid", return_value="someuuid"): with mock.patch(DS_PATH + "._is_platform_viable", return_value=True): with mock.patch(DS_PATH + "._is_iscsi_root", return_value=True): with mock.patch( DS_PATH + ".read_opc_metadata", return_value=metadata, ): yield oracle.DataSourceOracle( sys_cfg=sys_cfg, distro=mock.Mock(), paths=paths, )
def test_bare_metal_machine_skipped(self): # nicIndex in the first entry indicates a bare metal machine self.m_readurl.return_value = OPC_BM_SECONDARY_VNIC_RESPONSE # We test this by passing in a non-dict to ensure that no dict # operations are used self.assertFalse(oracle._add_network_config_from_opc_imds(object())) self.assertIn('bare metal machine', self.logs.getvalue())
def test_retries( self, v2_failure_count, v1_failure_count, expected_body, expectation, httpretty, ): v2_responses = [httpretty.Response("", status=404)] * v2_failure_count v2_responses.append(httpretty.Response(OPC_V2_METADATA)) v1_responses = [httpretty.Response("", status=404)] * v1_failure_count v1_responses.append(httpretty.Response(OPC_V1_METADATA)) httpretty.register_uri( httpretty.GET, "http://169.254.169.254/opc/v1/instance/", responses=v1_responses, ) httpretty.register_uri( httpretty.GET, "http://169.254.169.254/opc/v2/instance/", responses=v2_responses, ) with expectation: assert expected_body == oracle.read_opc_metadata().instance_data
def test_with_userdata(self, m_read_system_uuid): data = {'user_data': b'#!/bin/sh\necho hi world\n', 'meta_data.json': json.dumps(self.my_md)} self.populate_md(data) result = oracle.read_metadata()[MD_VER] self.assertEqual(data['user_data'], result['user_data']) self.assertEqual(self.my_md, result['meta_data'])
def test_metadata_returned(self, version, setup_urls, instance_data, fetch_vnics, vnics_data, httpretty): setup_urls(httpretty) metadata = oracle.read_opc_metadata(fetch_vnics_data=fetch_vnics) assert version == metadata.version assert instance_data == metadata.instance_data assert vnics_data == metadata.vnics_data
def test__ensure_netfailover_safe( self, m_netfail_master, m_get_interfaces_by_mac, nic_name, netcfg, netfail_master_return, call_args_list, ): m_get_interfaces_by_mac.return_value = { MAC_ADDR: nic_name, } passed_netcfg = copy.copy(netcfg) if netfail_master_return is not None: m_netfail_master.return_value = netfail_master_return oracle._ensure_netfailover_safe(passed_netcfg) assert netcfg == passed_netcfg assert call_args_list == m_netfail_master.call_args_list
def test_retries(self, expectation, failure_count, httpretty): responses = [httpretty.Response("", status=404)] * failure_count responses.append(httpretty.Response(OPC_V1_METADATA)) httpretty.register_uri( httpretty.GET, "http://169.254.169.254/opc/v1/instance/", responses=responses, ) expected = json.loads(OPC_V1_METADATA) with expectation: assert expected == oracle.read_opc_metadata()
def test_checks_v1_skips_non_phys_interfaces(self): mac_addr, nic_name = "00:00:17:02:2b:b1", "bond0" self.m_get_interfaces_by_mac.return_value = { mac_addr: nic_name, } netcfg = { "version": 1, "config": [ { "type": "bond", "name": nic_name, "mac_address": mac_addr, "subnets": [{"type": "dhcp4"}], } ], } passed_netcfg = copy.copy(netcfg) oracle._ensure_netfailover_safe(passed_netcfg) self.assertEqual(netcfg, passed_netcfg) self.assertEqual(0, self.m_netfail_master.call_count)
def test_skips_v2_non_ethernet_interfaces(self): mac_addr, nic_name = "00:00:17:02:2b:b1", "wlps0" self.m_get_interfaces_by_mac.return_value = { mac_addr: nic_name, } netcfg = { "version": 2, "wifis": { nic_name: { "dhcp4": True, "critical": True, "set-name": nic_name, "match": {"macaddress": mac_addr}, } }, } passed_netcfg = copy.copy(netcfg) oracle._ensure_netfailover_safe(passed_netcfg) self.assertEqual(netcfg, passed_netcfg) self.assertEqual(0, self.m_netfail_master.call_count)
def test_fetch_vnics_error(self, caplog): def mocked_fetch(*args, path="instance", **kwargs): if path == "vnics": raise UrlError("cause") with mock.patch(DS_PATH + "._fetch", side_effect=mocked_fetch): opc_metadata = oracle.read_opc_metadata(fetch_vnics_data=True) assert None is opc_metadata.vnics_data assert ( logging.WARNING, "Failed to fetch IMDS network configuration!", ) == caplog.record_tuples[-2][1:]
def test_secondary_nic_v2(self): self.m_readurl.return_value = OPC_VM_SECONDARY_VNIC_RESPONSE mac_addr, nic_name = '00:00:17:02:2b:b1', 'ens3' self.m_get_interfaces_by_mac.return_value = { mac_addr: nic_name, } network_config = {'version': 2, 'ethernets': {'primary': {'nic': {}}}} oracle._add_network_config_from_opc_imds(network_config) # The input is mutated self.assertEqual(2, len(network_config['ethernets'])) secondary_nic_cfg = network_config['ethernets']['ens3'] self.assertFalse(secondary_nic_cfg['dhcp4']) self.assertFalse(secondary_nic_cfg['dhcp6']) self.assertEqual(mac_addr, secondary_nic_cfg['match']['macaddress']) self.assertEqual(9000, secondary_nic_cfg['mtu']) self.assertEqual(1, len(secondary_nic_cfg['addresses'])) # These values are hard-coded in OPC_VM_SECONDARY_VNIC_RESPONSE self.assertEqual('10.0.0.231', secondary_nic_cfg['addresses'][0])
def detect_openstack(accept_oracle=False): """Return True when a potential OpenStack platform is detected.""" if not util.is_x86(): return True # Non-Intel cpus don't properly report dmi product names product_name = util.read_dmi_data('system-product-name') if product_name in VALID_DMI_PRODUCT_NAMES: return True elif util.read_dmi_data('chassis-asset-tag') in VALID_DMI_ASSET_TAGS: return True elif accept_oracle and oracle._is_platform_viable(): return True elif util.get_proc_env(1).get('product_name') == DMI_PRODUCT_NOVA: return True return False
def test_checks_v2_type_ethernet_interfaces(self): mac_addr, nic_name = "00:00:17:02:2b:b1", "ens3" self.m_get_interfaces_by_mac.return_value = { mac_addr: nic_name, } netcfg = { "version": 2, "ethernets": { nic_name: { "dhcp4": True, "critical": True, "set-name": nic_name, "match": {"macaddress": mac_addr}, } }, } passed_netcfg = copy.copy(netcfg) self.m_netfail_master.return_value = False oracle._ensure_netfailover_safe(passed_netcfg) self.assertEqual(netcfg, passed_netcfg) self.assertEqual( [mock.call(nic_name)], self.m_netfail_master.call_args_list )
def test_checks_v1_type_physical_interfaces(self): mac_addr, nic_name = "00:00:17:02:2b:b1", "ens3" self.m_get_interfaces_by_mac.return_value = { mac_addr: nic_name, } netcfg = { "version": 1, "config": [ { "type": "physical", "name": nic_name, "mac_address": mac_addr, "subnets": [{"type": "dhcp4"}], } ], } passed_netcfg = copy.copy(netcfg) self.m_netfail_master.return_value = False oracle._ensure_netfailover_safe(passed_netcfg) self.assertEqual(netcfg, passed_netcfg) self.assertEqual( [mock.call(nic_name)], self.m_netfail_master.call_args_list )
def test_removes_master_mac_property_v2(self): nic_master, mac_master = 'ens3', self.random_string() nic_other, mac_other = 'ens7', self.random_string() nic_extra, mac_extra = 'enp0s1f2', self.random_string() self.m_get_interfaces_by_mac.return_value = { mac_master: nic_master, mac_other: nic_other, mac_extra: nic_extra, } netcfg = {'version': 2, 'ethernets': { nic_extra: {'dhcp4': True, 'set-name': nic_extra, 'match': {'macaddress': mac_extra}}, nic_other: {'dhcp4': True, 'set-name': nic_other, 'match': {'macaddress': mac_other}}, nic_master: {'dhcp4': True, 'set-name': nic_master, 'match': {'macaddress': mac_master}}, }} def _is_netfail_master(iface): if iface == 'ens3': return True return False self.m_netfail_master.side_effect = _is_netfail_master expected_cfg = {'version': 2, 'ethernets': { nic_master: {'dhcp4': True, 'match': {'name': nic_master}}, nic_extra: {'dhcp4': True, 'set-name': nic_extra, 'match': {'macaddress': mac_extra}}, nic_other: {'dhcp4': True, 'set-name': nic_other, 'match': {'macaddress': mac_other}}, }} oracle._ensure_netfailover_safe(netcfg) import pprint pprint.pprint(netcfg) print('---- ^^ modified ^^ ---- vv original vv ----') pprint.pprint(expected_cfg) self.assertEqual(expected_cfg, netcfg)
def test_unknown_fields_included(self, m_read_system_uuid): """Unknown fields listed in index should be included. And those ending in .json should be decoded.""" some_data = {'key1': 'data1', 'subk1': {'subd1': 'subv'}} some_vendor_data = {'cloud-init': 'foo'} data = {'meta_data.json': json.dumps(self.my_md), 'some_data.json': json.dumps(some_data), 'vendor_data.json': json.dumps(some_vendor_data), 'other_blob': b'this is blob'} self.populate_md(data) result = oracle.read_metadata()[MD_VER] self.assertNotIn('user_data', result) self.assertEqual(self.my_md, result['meta_data']) self.assertEqual(some_data, result['some_data']) self.assertEqual(some_vendor_data, result['vendor_data']) self.assertEqual(data['other_blob'], result['other_blob'])
def test_expected_not_viable_other(self, m_read_dmi_data): """System with unnown chassis tag is not viable.""" self.assertFalse(oracle._is_platform_viable()) m_read_dmi_data.assert_has_calls([mock.call('chassis-asset-tag')])
def test_expected_viable(self, m_read_dmi_data): """System with known chassis tag is viable.""" self.assertTrue(oracle._is_platform_viable()) m_read_dmi_data.assert_has_calls([mock.call('chassis-asset-tag')])
def test_without_userdata(self, m_read_system_uuid): data = {'meta_data.json': json.dumps(self.my_md)} self.populate_md(data) result = oracle.read_metadata()[MD_VER] self.assertNotIn('user_data', result) self.assertEqual(self.my_md, result['meta_data'])