You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
251 lines
9.0 KiB
Python
251 lines
9.0 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.fullstack import utils
|
|
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):
|
|
|
|
of_interface = None
|
|
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,
|
|
of_interface=self.of_interface,
|
|
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
|
|
network_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})]
|
|
scenarios = testscenarios.multiply_scenarios(
|
|
network_scenarios, utils.get_ovs_interface_scenarios())
|
|
|
|
def test_connectivity(self):
|
|
self._test_connectivity()
|
|
|
|
|
|
class TestOvsConnectivitySameNetworkOnOvsBridgeControllerStop(
|
|
BaseConnectivitySameNetworkTest):
|
|
|
|
num_hosts = 2
|
|
|
|
l2_agent_type = constants.AGENT_TYPE_OVS
|
|
network_scenarios = [
|
|
('VXLAN', {'network_type': 'vxlan',
|
|
'l2_pop': False}),
|
|
('GRE and l2pop', {'network_type': 'gre',
|
|
'l2_pop': True}),
|
|
('VLANs', {'network_type': 'vlan',
|
|
'l2_pop': False})]
|
|
|
|
# Do not test for CLI ofctl interface as controller is irrelevant for CLI
|
|
scenarios = testscenarios.multiply_scenarios(
|
|
network_scenarios,
|
|
[(m, v) for (m, v) in utils.get_ovs_interface_scenarios()
|
|
if v['of_interface'] != 'ovs-ofctl'])
|
|
|
|
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
|
|
of_interface = 'native'
|
|
|
|
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,
|
|
utils.get_ovs_interface_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)
|