# Copyright 2015 Red Hat, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. import signal from neutron_lib import constants from oslo_log import log as logging from oslo_utils import uuidutils import testscenarios from neutron.common import utils as common_utils 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 SEGMENTATION_ID = 1234 LOG = logging.getLogger(__name__) class BaseConnectivitySameNetworkTest(base.BaseFullStackTestCase): arp_responder = False use_dhcp = True num_hosts = 3 def setUp(self): host_descriptions = [ # There's value in enabling L3 agents registration when l2pop # is enabled, because l2pop code makes assumptions about the # agent types present on machines. environment.HostDescription( l3_agent=self.l2_pop, l2_agent_type=self.l2_agent_type, dhcp_agent=self.use_dhcp, ) for _ in range(self.num_hosts)] env = environment.Environment( environment.EnvironmentDescription( network_type=self.network_type, l2_pop=self.l2_pop, arp_responder=self.arp_responder), host_descriptions) super(BaseConnectivitySameNetworkTest, self).setUp(env) def _prepare_network(self, tenant_uuid): net_args = {'network_type': self.network_type} if self.network_type in ['flat', 'vlan']: net_args['physical_network'] = config.PHYSICAL_NETWORK_NAME if self.network_type in ['vlan', 'gre', 'vxlan']: net_args['segmentation_id'] = SEGMENTATION_ID network = self.safe_client.create_network(tenant_uuid, **net_args) self.safe_client.create_subnet( tenant_uuid, network['id'], '20.0.0.0/24', enable_dhcp=self.use_dhcp) 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) def _test_connectivity(self): vms = self._prepare_vms_in_single_network() vms.ping_all() class TestOvsConnectivitySameNetwork(BaseConnectivitySameNetworkTest): l2_agent_type = constants.AGENT_TYPE_OVS scenarios = [ ('VXLAN', {'network_type': 'vxlan', 'l2_pop': False}), ('GRE-l2pop-arp_responder', {'network_type': 'gre', 'l2_pop': True, 'arp_responder': True}), ('VLANs', {'network_type': 'vlan', 'l2_pop': False})] def test_connectivity(self): self._test_connectivity() class TestOvsConnectivitySameNetworkOnOvsBridgeControllerStop( BaseConnectivitySameNetworkTest): num_hosts = 2 l2_agent_type = constants.AGENT_TYPE_OVS scenarios = [ ('VXLAN', {'network_type': 'vxlan', 'l2_pop': False}), ('GRE and l2pop', {'network_type': 'gre', 'l2_pop': True}), ('VLANs', {'network_type': 'vlan', 'l2_pop': False})] def _test_controller_timeout_does_not_break_connectivity(self, kill_signal=None): # Environment preparation is effectively the same as connectivity test vms = self._prepare_vms_in_single_network() vms.ping_all() ns0 = vms[0].namespace ip1 = vms[1].ip LOG.debug("Stopping agents (hence also OVS bridge controllers)") for host in self.environment.hosts: if kill_signal is not None: host.l2_agent.stop(kill_signal=kill_signal) else: host.l2_agent.stop() # Ping to make sure that 3 x 5 seconds is overcame even under a high # load. The time was chosen to match three times inactivity_probe time, # which is the time after which the OVS vswitchd # treats the controller as dead and starts managing the bridge # by itself when the fail type settings is not set to secure (see # ovs-vsctl man page for further details) with net_helpers.async_ping(ns0, [ip1], timeout=2, count=25) as done: common_utils.wait_until_true( done, exception=RuntimeError("Networking interrupted after " "controllers have vanished")) def test_controller_timeout_does_not_break_connectivity_sigterm(self): self._test_controller_timeout_does_not_break_connectivity() def test_controller_timeout_does_not_break_connectivity_sigkill(self): self._test_controller_timeout_does_not_break_connectivity( signal.SIGKILL) class TestLinuxBridgeConnectivitySameNetwork(BaseConnectivitySameNetworkTest): l2_agent_type = constants.AGENT_TYPE_LINUXBRIDGE scenarios = [ ('VXLAN', {'network_type': 'vxlan', 'l2_pop': False}), ('VLANs', {'network_type': 'vlan', 'l2_pop': False}), ('VXLAN and l2pop', {'network_type': 'vxlan', 'l2_pop': True}) ] def test_connectivity(self): self._test_connectivity() class TestConnectivitySameNetworkNoDhcp(BaseConnectivitySameNetworkTest): scenarios = [ (constants.AGENT_TYPE_OVS, {'l2_agent_type': constants.AGENT_TYPE_OVS}), (constants.AGENT_TYPE_LINUXBRIDGE, {'l2_agent_type': constants.AGENT_TYPE_LINUXBRIDGE}) ] use_dhcp = False network_type = 'vxlan' l2_pop = False def test_connectivity(self): self._test_connectivity() class TestUninterruptedConnectivityOnL2AgentRestart( BaseConnectivitySameNetworkTest): num_hosts = 2 ovs_agent_scenario = [('OVS', {'l2_agent_type': constants.AGENT_TYPE_OVS})] lb_agent_scenario = [('LB', {'l2_agent_type': constants.AGENT_TYPE_LINUXBRIDGE})] network_scenarios = [ ('Flat network', {'network_type': 'flat', 'l2_pop': False}), ('VLANs', {'network_type': 'vlan', 'l2_pop': False}), ('VXLAN', {'network_type': 'vxlan', 'l2_pop': False}), ] scenarios = ( testscenarios.multiply_scenarios(ovs_agent_scenario, network_scenarios) + testscenarios.multiply_scenarios(lb_agent_scenario, network_scenarios) ) def test_l2_agent_restart(self, agent_restart_timeout=20): # Environment preparation is effectively the same as connectivity test vms = self._prepare_vms_in_single_network() vms.ping_all() ns0 = vms[0].namespace ip1 = vms[1].ip agents = [host.l2_agent for host in self.environment.hosts] # Restart agents on all nodes simultaneously while pinging across # the hosts. The ping has to cross int and phys bridges and travels # via central bridge as the vms are on separate hosts. self._assert_ping_during_agents_restart( agents, ns0, [ip1], restart_timeout=agent_restart_timeout, ping_timeout=2, count=agent_restart_timeout)