neutron/neutron/tests/fullstack/test_connectivity.py

239 lines
8.4 KiB
Python

# 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)