def test_multiproc_pub_sub(self): if not self.do_test: self.skipTest('pub/sub is not enabled') return self.event_received = False cfg.CONF.set_override('publisher_multiproc_socket', '/tmp/ipc_test_socket', group='df') pub_sub_driver = df_utils.load_driver( cfg.CONF.df.pub_sub_multiproc_driver, df_utils.DF_PUBSUB_DRIVER_NAMESPACE) publisher = pub_sub_driver.get_publisher() publisher.initialize() self.subscriber = pub_sub_driver.get_subscriber() self.subscriber.initialize(self._handle_received_event) self.subscriber.daemonize() publisher.send_event(self.event) test_utils.wait_until_true(lambda: self.event_received) self.subscriber.close() self.subscriber = None # Check that we received the same event self.assertEqual(self.event.table, self.event_received_info.table) self.assertEqual(self.event.key, self.event_received_info.key) self.assertEqual(self.event.action, self.event_received_info.action) # Value is not tested, since it's currently set to None # self.assertEqual(self.event.value, self.event_received_info.value) self.assertEqual(self.event.topic, self.event_received_info.topic)
def test_router_add_extra_route(self): lport = self.port1.port.get_logical_port() ip1 = lport.ip dest = "20.{}.{}.0/24".format(random.randint(0, 254), random.randint(0, 254)) body = {"routes": [{"nexthop": str(ip1), "destination": dest}]} self.neutron.update_router(self.router.router.router_id, body={'router': body}) # table = L3_LOOKUP_TABLE, priority = PRIORITY_VERY_HIGH, ip, # reg5 = router_unique_key, nw_dst = destination, # dl_dst = router_interface_mac # actions = dec_ttl, load: router_interface_mac->eth_src, # load: lport_mac->eth_dst, load:lport_unique_key->NXM_NX_REG7[], # resubmit(, 64) utils.wait_until_true( lambda: any(self._get_extra_route_flows(dest)), timeout=test_const.DEFAULT_RESOURCE_READY_TIMEOUT, exception=Exception('route flow entry is not installed')) body['routes'] = [] self.neutron.update_router(self.router.router.router_id, body={'router': body}) utils.wait_until_true( lambda: not any(self._get_extra_route_flows(dest)), timeout=test_const.DEFAULT_RESOURCE_READY_TIMEOUT, exception=Exception('route flow entry is not deleted'))
def test_create_update_subnet_with_dhcp(self): ovs = utils.OvsFlowsParser() flows_before_change = ovs.dump(self.integration_bridge) network = self.store(objects.NetworkTestObj(self.neutron, self.nb_api)) network_id = network.create() subnet = { 'network_id': network_id, 'cidr': '10.10.254.0/24', 'gateway_ip': '10.10.254.1', 'ip_version': 4, 'name': 'subnet-test', 'enable_dhcp': True } subnet = self.neutron.create_subnet({'subnet': subnet}) subnet_id = subnet['subnet']['id'] dhcp_ip = utils.wait_until_is_and_return( lambda: self.get_dhcp_ip(network_id, subnet_id), exception=Exception('DHCP IP was not generated')) self.assertFalse(utils.check_dhcp_ip_rule(flows_before_change, dhcp_ip)) utils.wait_until_true( lambda: utils.check_dhcp_ip_rule(ovs.dump(self.integration_bridge), dhcp_ip), exception=Exception('DHCP ip was not found in OpenFlow rules'), timeout=5) # change dhcp updated_subnet = {'enable_dhcp': False} self.neutron.update_subnet(subnet_id, {'subnet': updated_subnet}) time.sleep(const.DEFAULT_RESOURCE_READY_TIMEOUT) flows_after_update = ovs.dump(self.integration_bridge) self.assertFalse(utils.check_dhcp_ip_rule(flows_after_update, dhcp_ip)) network.close()
def test_dhcp_app_dos_block(self): def internal_predicate(): ovs = test_utils.OvsFlowsParser() return (self._check_dhcp_block_rule( ovs.dump(self.integration_bridge))) self._create_topology() dhcp_packet = self._create_dhcp_discover() send_dhcp_offer = app_testing_objects.SendAction( self.subnet1.subnet_id, self.port1.port_id, dhcp_packet, ) port_policies = self._create_port_policies(disable_rule=False) policy = app_testing_objects.Policy( initial_actions=[ send_dhcp_offer, send_dhcp_offer, send_dhcp_offer, send_dhcp_offer ], port_policies=port_policies, unknown_port_action=app_testing_objects.IgnoreAction()) self.addCleanup(policy.close) policy.start(self.topology) test_utils.wait_until_true(internal_predicate, const.DEFAULT_RESOURCE_READY_TIMEOUT, 1, None)
def wait_until_fip_active(self, timeout=const.DEFAULT_CMD_TIMEOUT, sleep=1, exception=None): def internal_predicate(): fip = self.get_floatingip() if fip and fip.get_status() == 'ACTIVE': return True return False utils.wait_until_true(internal_predicate, timeout, sleep, exception)
def start_subscribing(self): self._topology = self.store( test_objects.Topology(self.neutron, self.nb_api)) subnet = self._topology.create_subnet(cidr="192.168.200.0/24") port = subnet.create_port() utils.wait_until_true(lambda: port.name is not None, timeout=const.DEFAULT_RESOURCE_READY_TIMEOUT, exception=Exception('Port was not created'))
def test_remote_port(self): if cfg.CONF.core_plugin == DF_PLUGIN: return network = self.store(objects.NetworkTestObj(self.neutron, self.nb_api)) network_id = network.create(network={'name': 'network1'}) self.assertTrue(network.exists()) subnet_info = { 'network_id': network_id, 'cidr': '192.168.150.0/24', 'gateway_ip': '192.168.150.1', 'ip_version': 4, 'name': 'subnet1', 'enable_dhcp': True } subnet = self.store( objects.SubnetTestObj(self.neutron, self.nb_api, network_id=network_id)) subnet.create(subnet_info) self.assertTrue(subnet.exists()) port = self.store( objects.PortTestObj(self.neutron, self.nb_api, network_id)) port_body = { 'admin_state_up': True, 'name': 'port1', 'network_id': network_id, 'binding:profile': { 'port_key': 'remote_port', 'host_ip': '10.10.10.10' } } port.create(port=port_body) self.assertTrue(port.exists()) ovsdb = utils.OvsDBParser() utils.wait_until_true( lambda: self._get_wanted_tunnel_port(ovsdb, '10.10.10.10'), timeout=const.DEFAULT_RESOURCE_READY_TIMEOUT, sleep=2, exception=Exception('Could not get wanted tunnel port')) port.close() self.assertFalse(port.exists()) utils.wait_until_none( lambda: ovsdb.get_tunnel_ofport('10.10.10.10'), timeout=const.DEFAULT_RESOURCE_READY_TIMEOUT, sleep=2, exception=Exception('Could not delete wanted tunnel port')) subnet.close() network.close()
def test_arp_responder(self): """ Add a VM. Verify it's ARP flow is there. """ network = objects.NetworkTestObj(self.neutron, self.nb_api) self.addCleanup(network.close) network_id = network.create(network={'name': 'arp_responder_test'}) subnet_obj = objects.SubnetTestObj(self.neutron, self.nb_api, network_id) self.addCleanup(subnet_obj.close) subnet = { 'network_id': network_id, 'cidr': '10.10.10.0/24', 'gateway_ip': '10.10.10.1', 'ip_version': 4, 'name': 'arp_responder_test', 'enable_dhcp': True } subnet = subnet_obj.create(subnet) flows_before = self._get_arp_table_flows() vm = objects.VMTestObj(self, self.neutron) self.addCleanup(vm.close) vm.create(network=network) ip = vm.get_first_ipv4() self.assertIsNotNone(ip) flows_middle = self._get_arp_table_flows() vm.close() time.sleep(test_const.DEFAULT_RESOURCE_READY_TIMEOUT) flows_delta = [ flow for flow in flows_middle if flow not in flows_before ] self.assertIsNotNone( self._find_arp_responder_flow_by_ip(flows_delta, ip)) condition = lambda: self._check_arp_flow_removal(ip) try: test_utils.wait_until_true( condition, timeout=test_const.DEFAULT_RESOURCE_READY_TIMEOUT, sleep=1, exception=RuntimeError( "Timed out waiting for arp responder flow from %(ip)s" " to be removed" % {'ip': ip})) except Exception as e: self.assertIsNone(e) finally: network.close()
def test_reply_message(self): network = objects.NetworkTestObj(self.neutron, self.nb_api) self.addCleanup(network.close) network_id = network.create() subnet = objects.SubnetTestObj(self.neutron, self.nb_api, network_id) self.addCleanup(subnet.close) subnet_body = { 'network_id': network_id, 'cidr': '10.20.0.0/24', 'gateway_ip': '10.20.0.1', 'ip_version': 4, 'name': 'private', 'enable_dhcp': True } subnet.create(subnet=subnet_body) self.assertTrue(network.exists()) self.assertTrue(subnet.exists()) vm1 = objects.VMTestObj(self, self.neutron) self.addCleanup(vm1.close) vm1.create(network=network) self.assertIsNotNone(vm1.server.addresses['mynetwork']) mac1 = vm1.server.addresses['mynetwork'][0]['OS-EXT-IPS-MAC:mac_addr'] self.assertIsNotNone(mac1) vm2 = objects.VMTestObj(self, self.neutron) self.addCleanup(vm2.close) vm2.create(network=network) self.assertIsNotNone(vm2.server.addresses['mynetwork']) mac2 = vm2.server.addresses['mynetwork'][0]['OS-EXT-IPS-MAC:mac_addr'] self.assertIsNotNone(mac2) # wait util get the message we want self.set_wanted_vms.clear() utils.wait_until_true( lambda: self._get_all_wanted_vms_online(mac1, mac2), timeout=const.DEFAULT_RESOURCE_READY_TIMEOUT, sleep=1, exception=Exception('Could not get wanted online vm')) vm1.close() vm2.close() utils.wait_until_none( lambda: utils.find_logical_port(self.nb_api, ip=None, mac=mac1), timeout=const.DEFAULT_RESOURCE_READY_TIMEOUT, sleep=1, exception=Exception('Port was not deleted')) utils.wait_until_none( lambda: utils.find_logical_port(self.nb_api, ip=None, mac=mac2), timeout=const.DEFAULT_RESOURCE_READY_TIMEOUT, sleep=1, exception=Exception('Port was not deleted'))
def _create_vm(self, network): vm = self.store(objects.VMTestObj(self, self.neutron)) vm.create(network=network) vm_mac = vm.get_first_mac() self.assertTrue(vm_mac is not None) vm_flows = self._get_vm_flows(vm_mac) self.assertTrue(any(vm_flows)) if cfg.CONF.df.enable_neutron_notifier: # test port status update utils.wait_until_true( lambda: self._is_VM_port_status(vm, 'ACTIVE'), timeout=60, exception=Exception('Port status not change to ACTIVE') ) return vm
def _remove_vm(self, vm): vm_mac = vm.get_first_mac() if cfg.CONF.df.enable_neutron_notifier: # test port status update vm.server.stop() utils.wait_until_true( lambda: self._is_VM_port_status(vm, 'DOWN'), timeout=60, exception=Exception('Port status not change to DOWN')) # delete vm vm.close() utils.wait_until_none(lambda: 1 if any(self._get_vm_flows(vm_mac)) else None, timeout=60, exception=Exception('VM flow was not deleted'))
def test_multiproc_pub_sub(self): if not self.do_test: return self.event_received = False cfg.CONF.set_override('publisher_multiproc_socket', '/tmp/ipc_test_socket', group='df') pub_sub_driver = df_utils.load_driver( cfg.CONF.df.pub_sub_multiproc_driver, df_utils.DF_PUBSUB_DRIVER_NAMESPACE) publisher = pub_sub_driver.get_publisher() publisher.initialize() self.subscriber = pub_sub_driver.get_subscriber() self.subscriber.initialize(self._verify_event) self.subscriber.daemonize() publisher.send_event(self.event) test_utils.wait_until_true(lambda: self.event_received)
def test_notify_message(self): network = self.store(objects.NetworkTestObj(self.neutron, self.nb_api)) network_id = network.create() subnet = self.store( objects.SubnetTestObj(self.neutron, self.nb_api, network_id)) subnet_body = { 'network_id': network_id, 'cidr': '10.10.0.0/24', 'gateway_ip': '10.10.0.1', 'ip_version': 4, 'name': 'private', 'enable_dhcp': True } subnet.create(subnet=subnet_body) self.assertTrue(network.exists()) self.assertTrue(subnet.exists()) vm = self.store(objects.VMTestObj(self, self.neutron)) vm.create(network=network) self.assertIsNotNone(vm.server.addresses['mynetwork']) mac = vm.server.addresses['mynetwork'][0]['OS-EXT-IPS-MAC:mac_addr'] self.assertIsNotNone(mac) # wait util get the message we want utils.wait_until_true( lambda: self._get_wanted_vm_online(mac), timeout=const.DEFAULT_RESOURCE_READY_TIMEOUT, sleep=1, exception=Exception('Could not get wanted online vm')) # wait util get the message we want vm.close() utils.wait_until_true( lambda: self._get_wanted_vm_offline(mac), timeout=const.DEFAULT_RESOURCE_READY_TIMEOUT, sleep=1, exception=Exception('Could not get wanted offline vm')) utils.wait_until_none( lambda: utils.get_vm_port(self.nb_api, ip=None, mac=mac), timeout=const.DEFAULT_RESOURCE_READY_TIMEOUT, sleep=1, exception=Exception('Port was not deleted'))
def test_create_update_subnet_without_dhcp(self): ovs = utils.OvsFlowsParser() flows_before_change = ovs.dump(self.integration_bridge) network, network_id, network_key = self._create_network() subnet = {'network_id': network_id, 'cidr': '10.20.0.0/24', 'gateway_ip': '10.20.0.1', 'ip_version': 4, 'name': 'subnet-test', 'enable_dhcp': False} subnet = self.neutron.create_subnet({'subnet': subnet}) subnet_id = subnet['subnet']['id'] time.sleep(const.DEFAULT_CMD_TIMEOUT) flows_after_change = ovs.dump(self.integration_bridge) # change dhcp updated_subnet = {'enable_dhcp': True} self.neutron.update_subnet(subnet_id, {'subnet': updated_subnet}) dhcp_ip = utils.wait_until_is_and_return( lambda: self.get_dhcp_ip(network_id, subnet_id), exception=Exception('DHCP IP was not generated') ) self.assertIsNotNone(dhcp_ip) self.assertFalse(utils.check_dhcp_network_rule( flows_before_change, network_key)) self.assertFalse(utils.check_dhcp_network_rule( flows_after_change, network_key)) utils.wait_until_true( lambda: utils.check_dhcp_network_rule( ovs.dump(self.integration_bridge), network_key), exception=Exception('DHCP ip was not found in OpenFlow rules'), timeout=5 ) network.close() utils.wait_until_none( lambda: utils.check_dhcp_network_rule( ovs.dump(self.integration_bridge), network_key), exception=Exception('DHCP IP was not removed from OpenFlow rules'), timeout=30 )
def test_router_add_route(self): lport = self.port1.port.get_logical_port() ip1 = lport.get_ip() dest = "10.{}.{}.0/24".format(random.randint(0, 254), random.randint(0, 254)) body = {"routes": [{"nexthop": ip1, "destination": dest}]} self.neutron.update_router(self.router.router.router_id, body={'router': body}) # table = 20, priority = 100, ip, nw_src = 192.168.10.0/24, # nw_dst = 10.110.10.0/24 # actions = dec_ttl, load:0x18->NXM_NX_REG7[], resubmit(, 64) utils.wait_until_true( lambda: any(self._get_route_flows('192.168.10.0/24', dest)), timeout=test_const.DEFAULT_RESOURCE_READY_TIMEOUT, exception=Exception('route flow entry is not installed')) body['routes'] = [] self.neutron.update_router(self.router.router.router_id, body={'router': body}) utils.wait_until_true( lambda: not any(self._get_route_flows('192.168.10.0/24', dest)), timeout=test_const.DEFAULT_RESOURCE_READY_TIMEOUT, exception=Exception('route flow entry is not deleted'))
def test_db_consistent(self): self.db_sync_time = self.conf.db_sync_time network = self.store(objects.NetworkTestObj(self.neutron, self.nb_api)) network_id = network.create() self.addCleanup(network.close) topic = network.get_topic() subnet = self.store(objects.SubnetTestObj(self.neutron, self.nb_api, network_id)) subnet_body = {'network_id': network_id, 'cidr': '10.50.0.0/24', 'gateway_ip': '10.50.0.1', 'ip_version': 4, 'name': 'private', 'enable_dhcp': True} subnet.create(subnet=subnet_body) self.addCleanup(subnet.close) time.sleep(constants.DEFAULT_RESOURCE_READY_TIMEOUT) self.assertTrue(network.exists()) self.assertTrue(subnet.exists()) vm = self.store(objects.VMTestObj(self, self.neutron)) vm.create(network=network) self.addCleanup(vm.close) self.assertIsNotNone(vm.server.addresses['mynetwork']) mac = vm.server.addresses['mynetwork'][0]['OS-EXT-IPS-MAC:mac_addr'] self.assertIsNotNone(mac) ovs = utils.OvsFlowsParser() utils.wait_until_true( lambda: self._check_l2_lookup_rule( ovs.dump(self.integration_bridge), mac), timeout=10, sleep=1, exception=Exception('no rule for vm in l2 lookup table') ) net_id = '11111111-1111-1111-1111-111111111111' df_network = l2.LogicalSwitch( id=net_id, topic=topic, name='df_nw1', network_type='vxlan', segmentation_id=4000, is_external=False, mtu=1500, unique_key=1, version=1) df_network_json = df_network.to_json() self.nb_api.driver.create_key(l2.LogicalSwitch.table_name, net_id, df_network_json, topic) self.addCleanup(self.nb_api.driver.delete_key, 'lswitch', net_id, topic) subnet_id = '22222222-2222-2222-2222-222222222222' df_subnet = l2.Subnet( id=subnet_id, topic=topic, name='df_sn1', enable_dhcp=True, cidr='10.60.0.0/24', dhcp_ip='10.60.0.2', gateway_ip='10.60.0.1', version=1, lswitch=net_id) self.nb_api.driver.create_key(l2.Subnet.table_name, subnet_id, df_subnet.to_json(), topic) self.addCleanup(self.nb_api.driver.delete_key, l2.Subnet.table_name, subnet_id, topic) port_id = '33333333-2222-2222-2222-222222222222,' dhcp_port = l2.LogicalPort( topic=topic, name='df_dhcp1', macs=['aa:bb:cc:dd:ee:ff'], id=port_id, ips=['10.60.0.2'], subnets=[df_subnet.id], device_owner=n_const.DEVICE_OWNER_DHCP, lswitch=df_network.id, unique_key=1 ).to_json() self.nb_api.driver.create_key( 'lport', port_id, dhcp_port, topic) df_net_unique_key = df_network.unique_key time.sleep(self.db_sync_time) utils.wait_until_true( lambda: utils.check_dhcp_network_rule( ovs.dump(self.integration_bridge), df_net_unique_key), timeout=self.db_sync_time + constants.DEFAULT_CMD_TIMEOUT, sleep=1, exception=Exception('no goto dhcp rule for lswitch') ) self.nb_api.driver.delete_key('lport', port_id, topic) time.sleep(self.db_sync_time) utils.wait_until_true( lambda: self._check_no_lswitch_dhcp_rule( ovs.dump(self.integration_bridge), df_net_unique_key), timeout=self.db_sync_time + constants.DEFAULT_CMD_TIMEOUT, sleep=1, exception=Exception('could not delete goto dhcp rule for lswitch') )
def test_icmp_responder(self): """ Add a VM. Verify the icmp flow is there. """ network = self.store(objects.NetworkTestObj(self.neutron, self.nb_api)) network_id = network.create(network={'name': 'icmp_responder_test'}) subnet_obj = self.store(objects.SubnetTestObj( self.neutron, self.nb_api, network_id, )) subnet = {'network_id': network_id, 'cidr': '10.10.10.0/24', 'gateway_ip': '10.10.10.1', 'ip_version': 4, 'name': 'arp_responder_test', 'enable_dhcp': True} subnet_id = subnet_obj.create(subnet) flows_before = self._get_l3_lookup_table_flows() router = self.store(objects.RouterTestObj(self.neutron, self.nb_api)) router_id = router.create() subnet_msg = {'subnet_id': subnet_id} interface = self.neutron.add_interface_router(router_id, body=subnet_msg) port_id = interface['port_id'] router_port = self.neutron.list_ports(id=port_id)['ports'][0] router_ip = None for ip in router_port['fixed_ips']: if ip['subnet_id'] == subnet_id: router_ip = ip['ip_address'] break vm = self.store(objects.VMTestObj(self, self.neutron)) vm.create(network=network) ip = vm.get_first_ipv4() self.assertIsNotNone(ip) flows_middle = self._get_l3_lookup_table_flows() vm.close() router.close() time.sleep(test_const.DEFAULT_RESOURCE_READY_TIMEOUT) flows_delta = [flow for flow in flows_middle if flow not in flows_before] self.assertIsNotNone( self._find_icmp_responder_flow_by_ip(flows_delta, router_ip) ) condition = lambda: self._check_icmp_flow_removal(router_ip) try: test_utils.wait_until_true( condition, timeout=test_const.DEFAULT_RESOURCE_READY_TIMEOUT, sleep=1, exception=RuntimeError( "Timed out waiting for icmp responder flow from %(ip)s" " to be removed" % {'ip': router_ip})) except Exception as e: self.assertIsNone(e) finally: network.close()
def test_db_consistent(self): self.db_sync_time = self.conf.db_sync_time network = self.store(objects.NetworkTestObj(self.neutron, self.nb_api)) network_id = network.create() topic = network.get_topic() subnet = self.store(objects.SubnetTestObj(self.neutron, self.nb_api, network_id)) subnet_body = {'network_id': network_id, 'cidr': '10.50.0.0/24', 'gateway_ip': '10.50.0.1', 'ip_version': 4, 'name': 'private', 'enable_dhcp': True} subnet.create(subnet=subnet_body) time.sleep(constants.DEFAULT_RESOURCE_READY_TIMEOUT) self.assertTrue(network.exists()) self.assertTrue(subnet.exists()) vm = self.store(objects.VMTestObj(self, self.neutron)) vm.create(network=network) self.assertIsNotNone(vm.server.addresses['mynetwork']) mac = vm.server.addresses['mynetwork'][0]['OS-EXT-IPS-MAC:mac_addr'] self.assertIsNotNone(mac) ovs = utils.OvsFlowsParser() utils.wait_until_true( lambda: self._check_l2_lookup_rule( ovs.dump(self.integration_bridge), mac), timeout=10, sleep=1, exception=Exception('no rule for vm in l2 lookup table') ) net_id = '11111111-1111-1111-1111-111111111111' df_network = l2.LogicalSwitch( id=net_id, topic=topic, name='df_nw1', network_type='vxlan', segmentation_id=4000, is_external=False, mtu=1500, unique_key=1, version=1) df_subnet = l2.Subnet( id='22222222-2222-2222-2222-222222222222', topic=topic, name='df_sn1', enable_dhcp=True, cidr='10.60.0.0/24', dhcp_ip='10.60.0.2', gateway_ip='10.60.0.1') df_network.add_subnet(df_subnet) df_network_json = df_network.to_json() self.nb_api.driver.create_key( 'lswitch', net_id, df_network_json, topic) time.sleep(self.db_sync_time) utils.wait_until_true( lambda: utils.check_dhcp_ip_rule( ovs.dump(self.integration_bridge), '10.60.0.2'), timeout=self.db_sync_time + constants.DEFAULT_CMD_TIMEOUT, sleep=1, exception=Exception('no goto dhcp rule for lswitch') ) df_network.version = 2 df_network.subnets[0].dhcp_ip = '10.60.0.3' df_network_json = df_network.to_json() self.nb_api.driver.set_key('lswitch', net_id, df_network_json, topic) time.sleep(self.db_sync_time) utils.wait_until_true( lambda: utils.check_dhcp_ip_rule( ovs.dump(self.integration_bridge), '10.60.0.3'), timeout=self.db_sync_time + constants.DEFAULT_CMD_TIMEOUT, sleep=1, exception=Exception('no goto dhcp rule for lswitch') ) self.nb_api.driver.delete_key('lswitch', net_id, topic) time.sleep(self.db_sync_time) utils.wait_until_true( lambda: self._check_no_lswitch_dhcp_rule( ovs.dump(self.integration_bridge), '10.60.0.3'), timeout=self.db_sync_time + constants.DEFAULT_CMD_TIMEOUT, sleep=1, exception=Exception('could not delete goto dhcp rule for lswitch') ) vm.close() subnet.close() network.close()