[Fullstack] Add segmentation_id update test
This patch adds new fullstack test which spawns 2 "hosts" and 2 "VMs" on those hosts. Both VMs are plugged to the vlan network with some segmentation id. Next segmentation id of the network is updated and test ensures that new vlan id is configured in the physical bridge on both "hosts" and connectivity between VMs still works fine. Test runs only with Openvswitch agents as Linuxbridge doesn't supports live update of the segmentation_id in the network. Change-Id: I459aac7f4e9afe679d8ece1c27d0be49cec8e4ff
This commit is contained in:
parent
da2cc29ec0
commit
87a7a5e32e
|
@ -135,3 +135,22 @@ def wait_for_dscp_marked_packet(sender_vm, receiver_vm, dscp_mark):
|
|||
"to %(dst)s" % {'dscp_mark': dscp_mark,
|
||||
'src': sender_vm.ip,
|
||||
'dst': receiver_vm.ip})
|
||||
|
||||
|
||||
def extract_vlan_id(flows):
|
||||
if flows:
|
||||
flow_list = flows.splitlines()
|
||||
for flow in flow_list:
|
||||
if 'mod_vlan_vid' in flow:
|
||||
actions = flow.partition('actions=')[2]
|
||||
after_mod = actions.partition('mod_vlan_vid:')[2]
|
||||
return int(after_mod.partition(',')[0])
|
||||
|
||||
|
||||
def wait_for_mod_vlan_id_applied(bridge, expected_vlan_id):
|
||||
def _vlan_id_rule_applied():
|
||||
flows = bridge.dump_flows_for(table='0')
|
||||
vlan_id = extract_vlan_id(flows)
|
||||
return vlan_id == expected_vlan_id
|
||||
|
||||
common_utils.wait_until_true(_vlan_id_rule_applied)
|
||||
|
|
|
@ -30,6 +30,7 @@ from neutron.tests.common import helpers
|
|||
from neutron.tests.common import machine_fixtures
|
||||
from neutron.tests.common import net_helpers
|
||||
from neutron.tests.fullstack.resources import client as client_resource
|
||||
from neutron.tests.fullstack.resources import machine
|
||||
from neutron.tests.unit import testlib_api
|
||||
|
||||
|
||||
|
@ -159,6 +160,20 @@ class BaseFullStackTestCase(testlib_api.MySQLTestCaseMixin,
|
|||
"tag", network.get("provider:segmentation_id"))
|
||||
return vm
|
||||
|
||||
def _prepare_vms_in_net(self, tenant_uuid, network, use_dhcp=False):
|
||||
vms = machine.FakeFullstackMachinesList(
|
||||
self.useFixture(
|
||||
machine.FakeFullstackMachine(
|
||||
host,
|
||||
network['id'],
|
||||
tenant_uuid,
|
||||
self.safe_client,
|
||||
use_dhcp=use_dhcp))
|
||||
for host in self.environment.hosts)
|
||||
|
||||
vms.block_until_all_boot()
|
||||
return vms
|
||||
|
||||
def assert_namespace_exists(self, ns_name):
|
||||
common_utils.wait_until_true(
|
||||
lambda: ip_lib.network_namespace_exists(ns_name,
|
||||
|
|
|
@ -24,7 +24,6 @@ from neutron.tests.common import net_helpers
|
|||
from neutron.tests.fullstack import base
|
||||
from neutron.tests.fullstack.resources import config
|
||||
from neutron.tests.fullstack.resources import environment
|
||||
from neutron.tests.fullstack.resources import machine
|
||||
from neutron.tests.unit import testlib_api
|
||||
|
||||
load_tests = testlib_api.module_load_tests
|
||||
|
@ -74,24 +73,10 @@ class BaseConnectivitySameNetworkTest(base.BaseFullStackTestCase):
|
|||
|
||||
return network
|
||||
|
||||
def _prepare_vms_in_net(self, tenant_uuid, network):
|
||||
vms = machine.FakeFullstackMachinesList(
|
||||
self.useFixture(
|
||||
machine.FakeFullstackMachine(
|
||||
host,
|
||||
network['id'],
|
||||
tenant_uuid,
|
||||
self.safe_client,
|
||||
use_dhcp=self.use_dhcp))
|
||||
for host in self.environment.hosts)
|
||||
|
||||
vms.block_until_all_boot()
|
||||
return vms
|
||||
|
||||
def _prepare_vms_in_single_network(self):
|
||||
tenant_uuid = uuidutils.generate_uuid()
|
||||
network = self._prepare_network(tenant_uuid)
|
||||
return self._prepare_vms_in_net(tenant_uuid, network)
|
||||
return self._prepare_vms_in_net(tenant_uuid, network, self.use_dhcp)
|
||||
|
||||
def _test_connectivity(self):
|
||||
vms = self._prepare_vms_in_single_network()
|
||||
|
|
|
@ -14,6 +14,7 @@ from neutron_lib import constants
|
|||
from neutronclient.common import exceptions
|
||||
from oslo_utils import uuidutils
|
||||
|
||||
from neutron.tests.common.agents import l2_extensions
|
||||
from neutron.tests.fullstack import base
|
||||
from neutron.tests.fullstack.resources import config
|
||||
from neutron.tests.fullstack.resources import environment
|
||||
|
@ -22,28 +23,28 @@ from neutron.tests.unit import testlib_api
|
|||
load_tests = testlib_api.module_load_tests
|
||||
|
||||
|
||||
class TestSegmentationId(base.BaseFullStackTestCase):
|
||||
class BaseSegmentationIdTest(base.BaseFullStackTestCase):
|
||||
|
||||
scenarios = [
|
||||
('Open vSwitch Agent', {'l2_agent_type': constants.AGENT_TYPE_OVS}),
|
||||
('Linux Bridge Agent', {
|
||||
'l2_agent_type': constants.AGENT_TYPE_LINUXBRIDGE})]
|
||||
network_type = "vlan"
|
||||
|
||||
def setUp(self):
|
||||
hosts_description = [
|
||||
host_descriptions = [
|
||||
environment.HostDescription(
|
||||
l2_agent_type=self.l2_agent_type, l3_agent=False)]
|
||||
l2_agent_type=self.l2_agent_type, l3_agent=False
|
||||
) for _ in range(self.num_hosts)]
|
||||
env = environment.Environment(
|
||||
environment.EnvironmentDescription(),
|
||||
hosts_description)
|
||||
environment.EnvironmentDescription(
|
||||
network_type=self.network_type),
|
||||
host_descriptions)
|
||||
|
||||
super(TestSegmentationId, self).setUp(env)
|
||||
self.tenant_id = uuidutils.generate_uuid()
|
||||
super(BaseSegmentationIdTest, self).setUp(env)
|
||||
self.project_id = uuidutils.generate_uuid()
|
||||
|
||||
def _create_network(self):
|
||||
seg_id = 100
|
||||
network = self.safe_client.create_network(
|
||||
self.tenant_id, network_type="vlan", segmentation_id=seg_id,
|
||||
self.project_id, network_type=self.network_type,
|
||||
segmentation_id=seg_id,
|
||||
physical_network=config.PHYSICAL_NETWORK_NAME)
|
||||
self.assertEqual(seg_id, network['provider:segmentation_id'])
|
||||
|
||||
|
@ -54,7 +55,6 @@ class TestSegmentationId(base.BaseFullStackTestCase):
|
|||
return network
|
||||
|
||||
def _update_segmentation_id(self, network):
|
||||
# Now change segmentation_id to some other value
|
||||
new_seg_id = network['provider:segmentation_id'] + 1
|
||||
new_net_args = {'provider:segmentation_id': new_seg_id}
|
||||
network = self.safe_client.update_network(
|
||||
|
@ -65,21 +65,32 @@ class TestSegmentationId(base.BaseFullStackTestCase):
|
|||
network = self.safe_client.client.show_network(
|
||||
network['id'])['network']
|
||||
self.assertEqual(new_seg_id, network['provider:segmentation_id'])
|
||||
return network
|
||||
|
||||
|
||||
class TestSegmentationId(BaseSegmentationIdTest):
|
||||
|
||||
scenarios = [
|
||||
('Open vSwitch Agent', {'l2_agent_type': constants.AGENT_TYPE_OVS}),
|
||||
('Linux Bridge Agent', {
|
||||
'l2_agent_type': constants.AGENT_TYPE_LINUXBRIDGE})]
|
||||
num_hosts = 1
|
||||
|
||||
def test_change_segmentation_id_no_ports_in_network(self):
|
||||
network = self._create_network()
|
||||
# Now change segmentation_id to some other value
|
||||
self._update_segmentation_id(network)
|
||||
|
||||
def test_change_segmentation_id_with_unbound_ports_in_network(self):
|
||||
network = self._create_network()
|
||||
|
||||
self.safe_client.create_subnet(
|
||||
self.tenant_id, network['id'], '20.0.0.0/24')
|
||||
self.project_id, network['id'], '20.0.0.0/24')
|
||||
|
||||
# Unbound port
|
||||
self.safe_client.create_port(self.tenant_id, network['id'])
|
||||
self.safe_client.create_port(self.project_id, network['id'])
|
||||
# Port failed to bind
|
||||
self.safe_client.create_port(self.tenant_id, network['id'],
|
||||
self.safe_client.create_port(self.project_id, network['id'],
|
||||
"non-exisiting-host")
|
||||
|
||||
self._update_segmentation_id(network)
|
||||
|
@ -88,8 +99,8 @@ class TestSegmentationId(base.BaseFullStackTestCase):
|
|||
network = self._create_network()
|
||||
|
||||
self.safe_client.create_subnet(
|
||||
self.tenant_id, network['id'], '20.0.0.0/24')
|
||||
self.safe_client.create_port(self.tenant_id, network['id'],
|
||||
self.project_id, network['id'], '20.0.0.0/24')
|
||||
self.safe_client.create_port(self.project_id, network['id'],
|
||||
self.environment.hosts[0].hostname)
|
||||
|
||||
if self.l2_agent_type == constants.AGENT_TYPE_LINUXBRIDGE:
|
||||
|
@ -99,3 +110,32 @@ class TestSegmentationId(base.BaseFullStackTestCase):
|
|||
self._update_segmentation_id, network)
|
||||
else:
|
||||
self._update_segmentation_id(network)
|
||||
|
||||
|
||||
class TestSegmentationIdConnectivity(BaseSegmentationIdTest):
|
||||
|
||||
scenarios = [
|
||||
('Open vSwitch Agent', {'l2_agent_type': constants.AGENT_TYPE_OVS})]
|
||||
|
||||
num_hosts = 2
|
||||
|
||||
def _ensure_vlan_id_set_in_flows(self, vlan_id):
|
||||
for host in self.environment.hosts:
|
||||
l2_extensions.wait_for_mod_vlan_id_applied(host.br_phys, vlan_id)
|
||||
|
||||
def test_connectivity_after_segmentation_id_update(self):
|
||||
network = self._create_network()
|
||||
self.safe_client.create_subnet(
|
||||
self.project_id, network['id'],
|
||||
cidr='10.0.0.0/24',
|
||||
gateway_ip='10.0.0.1',
|
||||
name='subnet-test',
|
||||
enable_dhcp=False)
|
||||
|
||||
vms = self._prepare_vms_in_net(self.project_id, network, False)
|
||||
self._ensure_vlan_id_set_in_flows(network['provider:segmentation_id'])
|
||||
vms.ping_all()
|
||||
|
||||
network = self._update_segmentation_id(network)
|
||||
self._ensure_vlan_id_set_in_flows(network['provider:segmentation_id'])
|
||||
vms.ping_all()
|
||||
|
|
Loading…
Reference in New Issue