c9a3d49513
The fullstack test TestPlacementBandwidthReport. test_configurations_are_synced_towards_placement sporadically failing and one possible reason is that multiple agents are visible to the server after restart of the agent (perhaps due to parallel execution). Partial-Bug: #1862177 Change-Id: I79aa2cb9bcd69fc0cb35e0fd351a373e00feb062
255 lines
9.5 KiB
Python
255 lines
9.5 KiB
Python
# Copyright 2018 Ericsson
|
|
#
|
|
# 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 functools
|
|
|
|
from neutron_lib import constants
|
|
|
|
from neutron.common import utils
|
|
from neutron.tests.common import net_helpers
|
|
from neutron.tests.fullstack import base
|
|
from neutron.tests.fullstack.resources import config as f_const
|
|
from neutron.tests.fullstack.resources import environment
|
|
from neutron.tests.unit import testlib_api
|
|
|
|
load_tests = testlib_api.module_load_tests
|
|
|
|
BR_MAPPINGS = 'bridge_mappings'
|
|
DEV_MAPPINGS = 'device_mappings'
|
|
|
|
|
|
def _get_physnet_names_from_mapping(mapping):
|
|
physnets = []
|
|
for pair in mapping.split(','):
|
|
physnets.append(pair.split(':')[0])
|
|
return physnets
|
|
|
|
|
|
def _add_new_device_to_agent_config(l2_agent_config, mapping_key_name,
|
|
new_dev):
|
|
old_bw = l2_agent_config[constants.RP_BANDWIDTHS]
|
|
old_mappings = l2_agent_config[mapping_key_name]
|
|
if new_dev in old_bw or new_dev in old_mappings:
|
|
return
|
|
|
|
new_mappings = 'physnetnew:%s' % new_dev
|
|
new_bw = '%s:%s:%s' % (new_dev,
|
|
f_const.MINIMUM_BANDWIDTH_EGRESS_KBPS,
|
|
f_const.MINIMUM_BANDWIDTH_INGRESS_KBPS)
|
|
l2_agent_config[mapping_key_name] = '%s,%s' % (
|
|
old_mappings, new_mappings)
|
|
l2_agent_config[constants.RP_BANDWIDTHS] = '%s,%s' % (
|
|
old_bw, new_bw)
|
|
|
|
|
|
def _change_agent_conf(l2_agent_config, l2_agent,
|
|
mapping_key_name, new_dev):
|
|
_add_new_device_to_agent_config(l2_agent_config, mapping_key_name, new_dev)
|
|
l2_agent.agent_cfg_fixture.write_config_to_configfile()
|
|
|
|
|
|
def _add_new_bridge_and_restart_agent(host):
|
|
l2_agent = host.l2_agent
|
|
l2_agent_config = l2_agent.agent_cfg_fixture.config
|
|
|
|
if 'ovs' in host.agents:
|
|
new_dev = utils.get_rand_device_name(prefix='br-new')
|
|
_change_agent_conf(
|
|
l2_agent_config['ovs'], l2_agent, BR_MAPPINGS, new_dev)
|
|
physnets = _get_physnet_names_from_mapping(
|
|
l2_agent_config['ovs'][BR_MAPPINGS])
|
|
br_phys_new = host.useFixture(
|
|
net_helpers.OVSBridgeFixture(new_dev)).bridge
|
|
host.connect_to_central_network_via_vlans(br_phys_new)
|
|
elif 'sriov' in host.agents:
|
|
new_dev = utils.get_rand_device_name(prefix='ens7')
|
|
_change_agent_conf(
|
|
l2_agent_config['sriov_nic'], l2_agent,
|
|
'physical_device_mappings', new_dev)
|
|
physnets = _get_physnet_names_from_mapping(
|
|
l2_agent_config['sriov_nic']['physical_device_mappings'])
|
|
|
|
l2_agent.restart()
|
|
return physnets
|
|
|
|
|
|
class TestAgentBandwidthReport(base.BaseFullStackTestCase):
|
|
|
|
scenarios = [
|
|
(constants.AGENT_TYPE_OVS,
|
|
{'l2_agent_type': constants.AGENT_TYPE_OVS}),
|
|
(constants.AGENT_TYPE_NIC_SWITCH,
|
|
{'l2_agent_type': constants.AGENT_TYPE_NIC_SWITCH})
|
|
]
|
|
|
|
def setUp(self, env=None):
|
|
if not env:
|
|
host_desc = [environment.HostDescription(
|
|
l3_agent=False,
|
|
l2_agent_type=self.l2_agent_type)]
|
|
env_desc = environment.EnvironmentDescription(
|
|
network_type='vlan',
|
|
l2_pop=False,
|
|
report_bandwidths=True,
|
|
)
|
|
env = environment.Environment(env_desc, host_desc)
|
|
|
|
super(TestAgentBandwidthReport, self).setUp(env)
|
|
|
|
def _check_agent_configurations(self, agent_id, expected_physnets):
|
|
agent = self.client.show_agent(agent_id)['agent']
|
|
agent_configurations = agent['configurations']
|
|
if 'Open vSwitch' in agent['agent_type']:
|
|
mapping_key = BR_MAPPINGS
|
|
elif 'NIC Switch' in agent['agent_type']:
|
|
mapping_key = DEV_MAPPINGS
|
|
else:
|
|
return False
|
|
|
|
for physnet in expected_physnets:
|
|
if physnet not in agent_configurations[mapping_key]:
|
|
return False
|
|
bridge_or_devices = agent_configurations[mapping_key][physnet]
|
|
|
|
if (constants.RP_BANDWIDTHS not in agent_configurations or
|
|
constants.RP_INVENTORY_DEFAULTS not in
|
|
agent_configurations):
|
|
return False
|
|
|
|
if mapping_key == BR_MAPPINGS:
|
|
if (bridge_or_devices not in
|
|
agent_configurations[constants.RP_BANDWIDTHS]):
|
|
return False
|
|
else:
|
|
for device in bridge_or_devices:
|
|
if (device not in
|
|
agent_configurations[constants.RP_BANDWIDTHS]):
|
|
return False
|
|
|
|
for device in agent_configurations[constants.RP_BANDWIDTHS]:
|
|
conf_device = agent_configurations[constants.RP_BANDWIDTHS][device]
|
|
if (f_const.MINIMUM_BANDWIDTH_INGRESS_KBPS !=
|
|
conf_device['ingress'] and
|
|
f_const.MINIMUM_BANDWIDTH_EGRESS_KBPS !=
|
|
conf_device[device]['egress']):
|
|
return False
|
|
return True
|
|
|
|
def test_agent_configurations(self):
|
|
agents = self.client.list_agents()
|
|
|
|
self.assertEqual(1, len(agents['agents']))
|
|
self.assertTrue(agents['agents'][0]['alive'])
|
|
|
|
agent_config = self.environment.hosts[0].l2_agent.agent_config
|
|
if 'ovs' in self.environment.hosts[0].agents:
|
|
physnets = _get_physnet_names_from_mapping(
|
|
agent_config['ovs'][BR_MAPPINGS])
|
|
elif 'sriov' in self.environment.hosts[0].agents:
|
|
physnets = _get_physnet_names_from_mapping(
|
|
agent_config['sriov_nic']['physical_device_mappings'])
|
|
|
|
self.assertTrue(
|
|
self._check_agent_configurations(agents['agents'][0]['id'],
|
|
physnets))
|
|
|
|
# Add new physnet with bandwidth value to agent config and check
|
|
# if after agent restart and report_interval wait it is visible in
|
|
# the configurations field.
|
|
physnets = _add_new_bridge_and_restart_agent(self.environment.hosts[0])
|
|
|
|
agents = self.client.list_agents()
|
|
l2_agent = agents['agents'][0]
|
|
neutron_config = self.environment.hosts[0].l2_agent.neutron_config
|
|
report_interval = neutron_config['agent']['report_interval']
|
|
|
|
check_agent_alive = functools.partial(self._check_agent_configurations,
|
|
l2_agent['id'],
|
|
physnets)
|
|
utils.wait_until_true(
|
|
predicate=check_agent_alive,
|
|
timeout=float(report_interval) + 10,
|
|
sleep=5)
|
|
|
|
|
|
class TestPlacementBandwidthReport(base.BaseFullStackTestCase):
|
|
|
|
scenarios = [
|
|
(constants.AGENT_TYPE_OVS,
|
|
{'l2_agent_type': constants.AGENT_TYPE_OVS,
|
|
'mech_drivers': 'openvswitch,linuxbridge',
|
|
'placement_port': '8080'}),
|
|
(constants.AGENT_TYPE_NIC_SWITCH,
|
|
{'l2_agent_type': constants.AGENT_TYPE_NIC_SWITCH,
|
|
'mech_drivers': 'sriovnicswitch',
|
|
'placement_port': '8081'})
|
|
]
|
|
|
|
def setUp(self):
|
|
host_desc = [environment.HostDescription(
|
|
l3_agent=False,
|
|
l2_agent_type=self.l2_agent_type)]
|
|
env_desc = environment.EnvironmentDescription(
|
|
network_type='vlan',
|
|
l2_pop=False,
|
|
mech_drivers=self.mech_drivers,
|
|
report_bandwidths=True,
|
|
has_placement=True,
|
|
placement_port=self.placement_port
|
|
)
|
|
env = environment.Environment(env_desc, host_desc)
|
|
super(TestPlacementBandwidthReport, self).setUp(env)
|
|
|
|
def _check_agent_not_synced(self):
|
|
return not self._check_agent_synced()
|
|
|
|
def _check_agent_synced(self):
|
|
agents = self.client.list_agents(agent_type=self.l2_agent_type)
|
|
for agent in agents['agents']:
|
|
if (agent['id'] == self.original_agent_id and
|
|
agent['resources_synced']):
|
|
return True
|
|
return False
|
|
|
|
def test_configurations_are_synced_towards_placement(self):
|
|
neutron_config = self.environment.hosts[0].l2_agent.neutron_config
|
|
report_interval = int(neutron_config['agent']['report_interval'])
|
|
|
|
agents = self.client.list_agents(agent_type=self.l2_agent_type)
|
|
self.assertEqual(1, len(agents['agents']))
|
|
self.original_agent_id = agents['agents'][0]['id']
|
|
|
|
check_agent_synced = functools.partial(self._check_agent_synced)
|
|
utils.wait_until_true(
|
|
predicate=check_agent_synced,
|
|
timeout=report_interval + 10,
|
|
sleep=1)
|
|
|
|
self.environment.placement.process_fixture.stop()
|
|
_add_new_bridge_and_restart_agent(self.environment.hosts[0])
|
|
|
|
check_agent_not_synced = functools.partial(
|
|
self._check_agent_not_synced)
|
|
utils.wait_until_true(
|
|
predicate=check_agent_not_synced,
|
|
timeout=report_interval + 10,
|
|
sleep=1)
|
|
|
|
self.environment.placement.process_fixture.start()
|
|
check_agent_synced = functools.partial(self._check_agent_synced)
|
|
utils.wait_until_true(
|
|
predicate=check_agent_synced,
|
|
timeout=report_interval + 10,
|
|
sleep=1)
|