From 900014fde0ddd232bf45b5dc07462191164649d3 Mon Sep 17 00:00:00 2001 From: Georgy Dyuldin Date: Wed, 12 Apr 2017 14:11:20 +0300 Subject: [PATCH] Fix SRIOV and DPDK tests Change-Id: I3f51bf3ce156efb0068691442a07b78212ee32e9 --- plugin_test/vapor/Dockerfile | 7 +- plugin_test/vapor/requirements.txt | 3 +- plugin_test/vapor/vapor/fixtures/skip.py | 6 +- plugin_test/vapor/vapor/helpers/sriov.py | 36 +++++----- .../vapor/vapor/helpers/vrouter_steps.py | 10 +-- plugin_test/vapor/vapor/settings.py | 3 + .../vapor/tests/common/test_security_group.py | 2 +- plugin_test/vapor/vapor/tests/test_dpdk.py | 7 +- plugin_test/vapor/vapor/tests/test_sriov.py | 65 +++++++++++++------ 9 files changed, 86 insertions(+), 53 deletions(-) diff --git a/plugin_test/vapor/Dockerfile b/plugin_test/vapor/Dockerfile index f9e38968a..4a19bf218 100644 --- a/plugin_test/vapor/Dockerfile +++ b/plugin_test/vapor/Dockerfile @@ -4,9 +4,6 @@ RUN apt-get update -qq && \ apt-get install -q -y \ python-dev \ libvirt-dev \ - # xvfb \ - # iceweasel \ - # libav-tools \ && \ apt-get clean && \ rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* @@ -15,9 +12,7 @@ WORKDIR /opt/app COPY . /opt/app/ -ENV OSLO_PACKAGE_VERSION=1.8 - -RUN pip install -e . -r requirements.txt +RUN pip install . -r requirements.txt ENV OS_USERNAME=admin ENV OS_PASSWORD=workshop diff --git a/plugin_test/vapor/requirements.txt b/plugin_test/vapor/requirements.txt index 7db5d0651..dcd88013b 100644 --- a/plugin_test/vapor/requirements.txt +++ b/plugin_test/vapor/requirements.txt @@ -1,4 +1,5 @@ -git+https://github.com/Mirantis/stepler.git#egg=stepler[libvirt] +# git+https://github.com/Mirantis/stepler.git#egg=stepler[libvirt] +git+https://review.gerrithub.io/Mirantis/stepler#egg=stepler[libvirt] git+https://github.com/morganfainberg/positional.git git+https://github.com/gdyuldin/contrail-python-api@R3.0 dpath diff --git a/plugin_test/vapor/vapor/fixtures/skip.py b/plugin_test/vapor/vapor/fixtures/skip.py index e5828fb85..8fd50ff3d 100644 --- a/plugin_test/vapor/vapor/fixtures/skip.py +++ b/plugin_test/vapor/vapor/fixtures/skip.py @@ -37,8 +37,10 @@ class Predicates(skip.Predicates): @_store_call def sriov_enabled(self): """Define whether sriov enabled.""" - agent_steps = self._get_fixture('agent_steps') - sriov_device_mappings = sriov.get_sriov_device_mapping(agent_steps) + os_faults_steps = self._get_fixture('os_faults_steps') + computes = self._get_fixture('computes') + sriov_device_mappings = sriov.get_sriov_devices(os_faults_steps, + computes) return len(sriov_device_mappings) > 0 @property diff --git a/plugin_test/vapor/vapor/helpers/sriov.py b/plugin_test/vapor/vapor/helpers/sriov.py index 42fb58371..85b0a321b 100644 --- a/plugin_test/vapor/vapor/helpers/sriov.py +++ b/plugin_test/vapor/vapor/helpers/sriov.py @@ -10,27 +10,29 @@ # License for the specific language governing permissions and limitations # under the License. -from vapor import settings +from stepler import config as stepler_config + +from vapor.helpers import nodes_steps -def get_sriov_device_mapping(agent_steps): - """Return computes with sriov neutron agents and them device mapping. +def get_sriov_devices(os_faults_steps, computes): + """Return computes with sriov neutron agents and them ifaces data. Example output: - {'node-4.test.domain.local': {"physnet2": ["ens11f1"]}} + {'node-4.test.domain.local': {"ens11f1": {"sriov_numvfs": 7}}} """ - agents = agent_steps.get_agents(binary=settings.NEUTRON_SRIOV_NIC_AGENT, - check=False) + cmd = "grep -v 0 /sys/class/net/*/device/sriov_numvfs" + result = os_faults_steps.execute_cmd(computes, cmd, check=False) mapping = {} - for agent in agents: - mapping[agent['host']] = agent['configurations']['device_mappings'] + for node_result in result: + node = nodes_steps.get_node_by_result(node_result, os_faults_steps) + if node_result.status == stepler_config.STATUS_OK: + node_data = {} + for line in node_result.payload['stdout_lines']: + path, sriov_numvfs = line.split(':') + sriov_numvfs = int(sriov_numvfs) + iface = path.split('/')[4] + node_data[iface] = {'sriov_numvfs': sriov_numvfs} + mapping[node.fqdn] = node_data + return mapping - - -def get_sriov_numvfs(os_faults_steps, node, iface): - """Return numvfs value from node for iface.""" - fqdn = os_faults_steps.get_fqdn_by_host_name(node) - node = os_faults_steps.get_node(fqdns=[fqdn]) - cmd = 'cat /sys/class/net/{}/device/sriov_numvfs'.format(iface) - result = os_faults_steps.execute_cmd(node, cmd) - return int(result[0].payload['stdout']) diff --git a/plugin_test/vapor/vapor/helpers/vrouter_steps.py b/plugin_test/vapor/vapor/helpers/vrouter_steps.py index f16ce5700..9cd41caa1 100644 --- a/plugin_test/vapor/vapor/helpers/vrouter_steps.py +++ b/plugin_test/vapor/vapor/helpers/vrouter_steps.py @@ -57,10 +57,12 @@ def get_interface_table(os_faults_steps, nodes): pairs = {key: value} else: pairs = line.split() - if ':' not in pairs[0]: - pairs = [ - u'{}_{}'.format(pairs[0], p) for p in pairs[1:] - ] + start = next(i for i, pair in enumerate(pairs) + if ':' in pair) + prefix = u'_'.join(pairs[:start]) + pairs = [ + u'{}_{}'.format(prefix, p) for p in pairs[start:] + ] pairs = dict(x.split(':', 1) for x in pairs) iface.update(pairs) if iface: diff --git a/plugin_test/vapor/vapor/settings.py b/plugin_test/vapor/vapor/settings.py index 0d76759fa..51fdbf42d 100644 --- a/plugin_test/vapor/vapor/settings.py +++ b/plugin_test/vapor/vapor/settings.py @@ -189,3 +189,6 @@ SERVER_ATTR_HYPERVISOR_HOSTNAME = 'OS-EXT-SRV-ATTR:hypervisor_hostname' NEUTRON_SRIOV_NIC_AGENT = "neutron-sriov-nic-agent" DPDK_NEC_BIND_PATH = '/opt/contrail/bin/dpdk_nic_bind.py' + +# SR-IOV +SRIOV_PHYSNET = 'physnet1' diff --git a/plugin_test/vapor/vapor/tests/common/test_security_group.py b/plugin_test/vapor/vapor/tests/common/test_security_group.py index 7fe32499b..c5def65f8 100644 --- a/plugin_test/vapor/vapor/tests/common/test_security_group.py +++ b/plugin_test/vapor/vapor/tests/common/test_security_group.py @@ -13,7 +13,7 @@ import time import attrdict -from hamcrest import assert_that, equal_to, greater_than # noqa: H301 +from hamcrest import assert_that, equal_to # noqa: H301 from pycontrail import types import pytest from stepler import config as stepler_config diff --git a/plugin_test/vapor/vapor/tests/test_dpdk.py b/plugin_test/vapor/vapor/tests/test_dpdk.py index 0b0f09f73..16402b43f 100644 --- a/plugin_test/vapor/vapor/tests/test_dpdk.py +++ b/plugin_test/vapor/vapor/tests/test_dpdk.py @@ -12,6 +12,7 @@ from hamcrest import (assert_that, has_entries, has_item, only_contains, is_not, empty, greater_than, has_length) +import pytest from vapor.helpers import contrail_status from vapor.helpers import dpdk @@ -66,6 +67,9 @@ def test_contrail_vrouter_dpdk_cpu_usage(os_faults_steps, computes): assert_that(usage, greater_than(50)) +@pytest.mark.parametrize( + 'flavor', [dict(metadata={"hw:mem_page_size": "small"})], indirect=True) +@pytest.mark.usefixtures('flavor') def test_vrouter_create_interface(request, os_faults_steps, computes): """Verify if vRouter creates interface after creation of a virtual machine. @@ -78,7 +82,8 @@ def test_vrouter_create_interface(request, os_faults_steps, computes): before_ifaces = vrouter_steps.get_interface_table(os_faults_steps, computes) server = request.getfixturevalue('server') - compute_fqdn = getattr(server, settings.SERVER_ATTR_HYPERVISOR_HOSTNAME) + compute = getattr(server, settings.SERVER_ATTR_HYPERVISOR_HOSTNAME) + compute_fqdn = os_faults_steps.get_fqdn_by_host_name(compute) after_ifaces = vrouter_steps.get_interface_table(os_faults_steps, computes) assert_that(after_ifaces[compute_fqdn], has_length(greater_than(len(before_ifaces[compute_fqdn])))) diff --git a/plugin_test/vapor/vapor/tests/test_sriov.py b/plugin_test/vapor/vapor/tests/test_sriov.py index 3e52f32bc..2f70443a6 100644 --- a/plugin_test/vapor/vapor/tests/test_sriov.py +++ b/plugin_test/vapor/vapor/tests/test_sriov.py @@ -16,13 +16,16 @@ from stepler import config as stepler_config from stepler.third_party import utils from vapor.helpers import sriov +from vapor import settings pytestmark = pytest.mark.requires('sriov_enabled') def test_virtual_function_exhaustion_and_reuse( - cirros_image, flavor, network, subnet, create_network, create_subnet, - create_port, agent_steps, os_faults_steps, server_steps): + ubuntu_xenial_image, flavor, network, subnet, net_subnet_router, + neutron_security_group, floating_ip, keypair, create_network, + create_subnet, create_port, os_faults_steps, computes, + floating_ip_steps, server_steps, nova_availability_zone_hosts): """Verify Nova can schedule VM to all the VF of a PF. Steps: @@ -32,7 +35,9 @@ def test_virtual_function_exhaustion_and_reuse( #. Create 1 port for management network and 1 port for SRIOV network #. Boot server with created 2 ports, check that is reaches ACTIVE status - #. Repeat last 2 steps `total_vfs` times + #. Create 1 port for SRIOV network + #. Repeat last 2 steps `total_vfs` - 1 times + #. Check ping from 1st server to all another #. Create 1 port for management network and 1 port for SRIOV network #. Create another one server with created 2 ports #. Check that server reaches ERROR status @@ -42,35 +47,56 @@ def test_virtual_function_exhaustion_and_reuse( #. Create another one server with created 2 ports, check that is reaches ACTIVE status """ - sriov_device_mappings = sriov.get_sriov_device_mapping(agent_steps) - compute_name, device_mapping = next(six.iteritems(sriov_device_mappings)) - sriov_physnet = next(six.iterkeys(device_mapping)) - sriov_iface = device_mapping[sriov_physnet][0] - numvfs = sriov.get_sriov_numvfs(os_faults_steps, compute_name, sriov_iface) + sriov_devices = sriov.get_sriov_devices(os_faults_steps, computes) + compute_name, ifaces = next(six.iteritems(sriov_devices)) + sriov_iface = next(six.iterkeys(ifaces)) + numvfs = ifaces[sriov_iface]['sriov_numvfs'] + + # Find availability zone compute host + compute_host = next( + host for host in nova_availability_zone_hosts + if compute_name.startswith(host)) # Create SRIOV net and subnet kwargs = { 'provider:network_type': 'vlan', - 'provider:physical_network': sriov_physnet, + 'provider:physical_network': settings.SRIOV_PHYSNET, 'provider:segmentation_id': 200 } sriov_net_name, = utils.generate_ids() sriov_net = create_network(sriov_net_name, **kwargs) - create_subnet(sriov_net_name + '__subnet', sriov_net, cidr="55.1.1.0/24") + create_subnet( + sriov_net_name + '__subnet', sriov_net, cidr="10.200.54.0/24") # Create servers servers = [] - sriov_port_kwargs = {'binding:vnic_type': 'direct'} + sriov_port_kwargs = { + 'binding:vnic_type': 'direct', + 'security_groups': [neutron_security_group['id']] + } server_create_args = dict( - image=cirros_image, + image=ubuntu_xenial_image, flavor=flavor, - availability_zone='nova:{}'.format(compute_name)) - for _ in range(numvfs): - mgmt_port = create_port(network) + availability_zone='nova:{}'.format(compute_host), + keypair=keypair, + username=stepler_config.UBUNTU_USERNAME) + for i in range(numvfs): sriov_port = create_port(sriov_net, **sriov_port_kwargs) + ports = [sriov_port] + if i == 0: + mgmt_port = create_port( + network, security_groups=[neutron_security_group['id']]) + ports.insert(0, mgmt_port) server = server_steps.create_servers( - ports=[mgmt_port, sriov_port], **server_create_args)[0] + ports=ports, **server_create_args)[0] servers.append(server) + if i == 0: + floating_ip_steps.attach_floating_ip(floating_ip, mgmt_port) + + # Check ping between servers + ping_plan = {servers[0]: servers[1:]} + server_steps.check_ping_by_plan( + ping_plan, timeout=stepler_config.PING_BETWEEN_SERVERS_TIMEOUT) # Try to create one more server mgmt_port = create_port(network) @@ -79,8 +105,7 @@ def test_virtual_function_exhaustion_and_reuse( error_server = server_steps.create_servers( ports=[mgmt_port, sriov_port], check=False, **server_create_args)[0] server_steps.check_server_status( - error_server, - [stepler_config.STATUS_ERROR], + error_server, [stepler_config.STATUS_ERROR], transit_statuses=[stepler_config.STATUS_BUILD], timeout=stepler_config.SERVER_ACTIVE_TIMEOUT) @@ -91,8 +116,6 @@ def test_virtual_function_exhaustion_and_reuse( server_steps.delete_servers(servers[:1]) # Create another server - mgmt_port = create_port(network) sriov_port = create_port(sriov_net, **sriov_port_kwargs) - server_steps.create_servers( - ports=[mgmt_port, sriov_port], **server_create_args)[0] + server_steps.create_servers(ports=[sriov_port], **server_create_args)[0]