tests: vpp_qemu_utils with concurrency handling
Type: test Enhance vpp_qemu_utils functions with mutex locking, handle namespace and host interface existence, unique namespace/interface name, error handling and retries, check error code explicitly. Change-Id: I1ea66eeefbc1fee9b58e8b9886f4dd6fd8d33444 Signed-off-by: Ivan Ivanets <iivanets@cisco.com>
This commit is contained in:
parent
a2bc88bb69
commit
9765e27635
@ -1,13 +1,14 @@
|
||||
from config import config
|
||||
from asfframework import VppAsfTestCase, VppTestRunner
|
||||
from asfframework import VppAsfTestCase, VppTestRunner, get_testcase_dirname
|
||||
import unittest
|
||||
import subprocess
|
||||
import tempfile
|
||||
import os
|
||||
from vpp_qemu_utils import (
|
||||
create_host_interface,
|
||||
delete_host_interfaces,
|
||||
delete_all_host_interfaces,
|
||||
create_namespace,
|
||||
delete_namespace,
|
||||
delete_all_namespaces,
|
||||
)
|
||||
|
||||
|
||||
@ -28,23 +29,36 @@ class TestHttpStaticVapi(VppAsfTestCase):
|
||||
cls.temp2 = tempfile.NamedTemporaryFile()
|
||||
cls.temp2.write(b"Hello world2")
|
||||
|
||||
cls.ns_history_name = (
|
||||
f"{config.tmp_dir}/{get_testcase_dirname(cls.__name__)}/history_ns.txt"
|
||||
)
|
||||
cls.if_history_name = (
|
||||
f"{config.tmp_dir}/{get_testcase_dirname(cls.__name__)}/history_if.txt"
|
||||
)
|
||||
|
||||
try:
|
||||
create_namespace("HttpStatic")
|
||||
except Exception:
|
||||
cls.logger.warning("Unable to create a namespace, retrying.")
|
||||
delete_namespace("HttpStatic")
|
||||
create_namespace("HttpStatic")
|
||||
# CleanUp
|
||||
delete_all_namespaces(cls.ns_history_name)
|
||||
delete_all_host_interfaces(cls.if_history_name)
|
||||
|
||||
create_host_interface("vppHost", "vppOut", "HttpStatic", "10.10.1.1/24")
|
||||
cls.ns_name = create_namespace(cls.ns_history_name)
|
||||
cls.host_if_name, cls.vpp_if_name = create_host_interface(
|
||||
cls.if_history_name, cls.ns_name, "10.10.1.1/24"
|
||||
)
|
||||
|
||||
cls.vapi.cli("create host-interface name vppOut")
|
||||
cls.vapi.cli("set int state host-vppOut up")
|
||||
cls.vapi.cli("set int ip address host-vppOut 10.10.1.2/24")
|
||||
except Exception as e:
|
||||
cls.logger.warning(f"Unable to complete setup: {e}")
|
||||
raise unittest.SkipTest("Skipping tests due to setup failure.")
|
||||
|
||||
cls.vapi.cli(f"create host-interface name {cls.vpp_if_name}")
|
||||
cls.vapi.cli(f"set int state host-{cls.vpp_if_name} up")
|
||||
cls.vapi.cli(f"set int ip address host-{cls.vpp_if_name} 10.10.1.2/24")
|
||||
|
||||
@classmethod
|
||||
def tearDownClass(cls):
|
||||
delete_namespace("HttpStatic")
|
||||
delete_host_interfaces("vppHost")
|
||||
delete_all_namespaces(cls.ns_history_name)
|
||||
delete_all_host_interfaces(cls.if_history_name)
|
||||
|
||||
cls.temp.close()
|
||||
cls.temp2.close()
|
||||
super(TestHttpStaticVapi, cls).tearDownClass()
|
||||
@ -61,7 +75,7 @@ class TestHttpStaticVapi(VppAsfTestCase):
|
||||
"ip",
|
||||
"netns",
|
||||
"exec",
|
||||
"HttpStatic",
|
||||
self.ns_name,
|
||||
"curl",
|
||||
"-v",
|
||||
f"10.10.1.2/{self.temp.name[5:]}",
|
||||
@ -77,7 +91,7 @@ class TestHttpStaticVapi(VppAsfTestCase):
|
||||
"ip",
|
||||
"netns",
|
||||
"exec",
|
||||
"HttpStatic",
|
||||
self.ns_name,
|
||||
"curl",
|
||||
f"10.10.1.2/{self.temp2.name[5:]}",
|
||||
],
|
||||
@ -103,23 +117,35 @@ class TestHttpStaticCli(VppAsfTestCase):
|
||||
cls.temp2 = tempfile.NamedTemporaryFile()
|
||||
cls.temp2.write(b"Hello world2")
|
||||
|
||||
cls.ns_history_name = (
|
||||
f"{config.tmp_dir}/{get_testcase_dirname(cls.__name__)}/history_ns.txt"
|
||||
)
|
||||
cls.if_history_name = (
|
||||
f"{config.tmp_dir}/{get_testcase_dirname(cls.__name__)}/history_if.txt"
|
||||
)
|
||||
|
||||
try:
|
||||
create_namespace("HttpStatic2")
|
||||
except Exception:
|
||||
cls.logger.warning("Unable to create namespace, retrying.")
|
||||
delete_namespace("HttpStatic2")
|
||||
create_namespace("HttpStatic2")
|
||||
delete_all_namespaces(cls.ns_history_name)
|
||||
delete_all_host_interfaces(cls.if_history_name)
|
||||
|
||||
create_host_interface("vppHost2", "vppOut2", "HttpStatic2", "10.10.1.1/24")
|
||||
cls.ns_name = create_namespace(cls.ns_history_name)
|
||||
cls.host_if_name, cls.vpp_if_name = create_host_interface(
|
||||
cls.if_history_name, cls.ns_name, "10.10.1.1/24"
|
||||
)
|
||||
|
||||
cls.vapi.cli("create host-interface name vppOut2")
|
||||
cls.vapi.cli("set int state host-vppOut2 up")
|
||||
cls.vapi.cli("set int ip address host-vppOut2 10.10.1.2/24")
|
||||
except Exception as e:
|
||||
cls.logger.warning(f"Unable to complete setup: {e}")
|
||||
raise unittest.SkipTest("Skipping tests due to setup failure.")
|
||||
|
||||
cls.vapi.cli(f"create host-interface name {cls.vpp_if_name}")
|
||||
cls.vapi.cli(f"set int state host-{cls.vpp_if_name} up")
|
||||
cls.vapi.cli(f"set int ip address host-{cls.vpp_if_name} 10.10.1.2/24")
|
||||
|
||||
@classmethod
|
||||
def tearDownClass(cls):
|
||||
delete_namespace("HttpStatic2")
|
||||
delete_host_interfaces("vppHost2")
|
||||
delete_all_namespaces(cls.ns_history_name)
|
||||
delete_all_host_interfaces(cls.if_history_name)
|
||||
|
||||
cls.temp.close()
|
||||
cls.temp2.close()
|
||||
super(TestHttpStaticCli, cls).tearDownClass()
|
||||
@ -135,7 +161,7 @@ class TestHttpStaticCli(VppAsfTestCase):
|
||||
"ip",
|
||||
"netns",
|
||||
"exec",
|
||||
"HttpStatic2",
|
||||
self.ns_name,
|
||||
"curl",
|
||||
f"10.10.1.2/{self.temp.name[5:]}",
|
||||
],
|
||||
@ -149,7 +175,7 @@ class TestHttpStaticCli(VppAsfTestCase):
|
||||
"ip",
|
||||
"netns",
|
||||
"exec",
|
||||
"HttpStatic2",
|
||||
self.ns_name,
|
||||
"curl",
|
||||
f"10.10.1.2/{self.temp2.name[5:]}",
|
||||
],
|
||||
|
@ -1,12 +1,13 @@
|
||||
from config import config
|
||||
from asfframework import VppAsfTestCase, VppTestRunner
|
||||
from asfframework import VppAsfTestCase, VppTestRunner, get_testcase_dirname
|
||||
import unittest
|
||||
import subprocess
|
||||
import os
|
||||
from vpp_qemu_utils import (
|
||||
create_host_interface,
|
||||
delete_host_interfaces,
|
||||
delete_all_host_interfaces,
|
||||
create_namespace,
|
||||
delete_namespace,
|
||||
delete_all_namespaces,
|
||||
)
|
||||
|
||||
|
||||
@ -22,17 +23,36 @@ class TestProm(VppAsfTestCase):
|
||||
def setUpClass(cls):
|
||||
super(TestProm, cls).setUpClass()
|
||||
|
||||
create_namespace("HttpStaticProm")
|
||||
create_host_interface("vppHost", "vppOut", "HttpStaticProm", "10.10.1.1/24")
|
||||
cls.ns_history_name = (
|
||||
f"{config.tmp_dir}/{get_testcase_dirname(cls.__name__)}/history_ns.txt"
|
||||
)
|
||||
cls.if_history_name = (
|
||||
f"{config.tmp_dir}/{get_testcase_dirname(cls.__name__)}/history_if.txt"
|
||||
)
|
||||
|
||||
cls.vapi.cli("create host-interface name vppOut")
|
||||
cls.vapi.cli("set int state host-vppOut up")
|
||||
cls.vapi.cli("set int ip address host-vppOut 10.10.1.2/24")
|
||||
try:
|
||||
# CleanUp
|
||||
delete_all_namespaces(cls.ns_history_name)
|
||||
delete_all_host_interfaces(cls.if_history_name)
|
||||
|
||||
cls.ns_name = create_namespace(cls.ns_history_name)
|
||||
|
||||
cls.host_if_name, cls.vpp_if_name = create_host_interface(
|
||||
cls.if_history_name, cls.ns_name, "10.10.1.1/24"
|
||||
)
|
||||
except Exception as e:
|
||||
cls.logger.warning(f"Unable to complete setup: {e}")
|
||||
raise unittest.SkipTest("Skipping tests due to setup failure.")
|
||||
|
||||
cls.vapi.cli(f"create host-interface name {cls.vpp_if_name}")
|
||||
cls.vapi.cli(f"set int state host-{cls.vpp_if_name} up")
|
||||
cls.vapi.cli(f"set int ip address host-{cls.vpp_if_name} 10.10.1.2/24")
|
||||
|
||||
@classmethod
|
||||
def tearDownClass(cls):
|
||||
delete_namespace(["HttpStaticProm"])
|
||||
delete_host_interfaces("vppHost")
|
||||
delete_all_namespaces(cls.ns_history_name)
|
||||
delete_all_host_interfaces(cls.if_history_name)
|
||||
|
||||
super(TestProm, cls).tearDownClass()
|
||||
|
||||
def test_prom(self):
|
||||
@ -46,7 +66,7 @@ class TestProm(VppAsfTestCase):
|
||||
"ip",
|
||||
"netns",
|
||||
"exec",
|
||||
"HttpStaticProm",
|
||||
self.ns_name,
|
||||
"curl",
|
||||
f"10.10.1.2/stats.prom",
|
||||
],
|
||||
|
@ -3,9 +3,9 @@ import unittest
|
||||
from ipaddress import ip_address, ip_interface
|
||||
from vpp_qemu_utils import (
|
||||
create_namespace,
|
||||
delete_namespace,
|
||||
delete_all_namespaces,
|
||||
create_host_interface,
|
||||
delete_host_interfaces,
|
||||
delete_all_host_interfaces,
|
||||
set_interface_mtu,
|
||||
disable_interface_gso,
|
||||
add_namespace_route,
|
||||
@ -18,6 +18,7 @@ from config import config
|
||||
from vpp_papi import VppEnum
|
||||
import time
|
||||
import sys
|
||||
import os
|
||||
from vm_test_config import test_config
|
||||
|
||||
#
|
||||
@ -226,7 +227,16 @@ class TestVPPInterfacesQemu:
|
||||
# prevent conflicts when TEST_JOBS > 1
|
||||
self.client_namespace = test_config["client_namespace"] + str(test["id"])
|
||||
self.server_namespace = test_config["server_namespace"] + str(test["id"])
|
||||
create_namespace([self.client_namespace, self.server_namespace])
|
||||
self.ns_history_file = (
|
||||
f"{config.tmp_dir}/vpp-unittest-{self.__class__.__name__}/history_ns.txt"
|
||||
)
|
||||
self.if_history_name = (
|
||||
f"{config.tmp_dir}/vpp-unittest-{self.__class__.__name__}/history_if.txt"
|
||||
)
|
||||
delete_all_namespaces(self.ns_history_file)
|
||||
create_namespace(
|
||||
self.ns_history_file, ns=[self.client_namespace, self.server_namespace]
|
||||
)
|
||||
# Set a unique iPerf port for parallel server and client runs
|
||||
self.iperf_port = 5000 + test["id"]
|
||||
# IPerf client & server ingress/egress interface indexes in VPP
|
||||
@ -258,11 +268,11 @@ class TestVPPInterfacesQemu:
|
||||
"iprf_server_interface_on_vpp"
|
||||
] + str(test["id"])
|
||||
# Handle client interface types
|
||||
delete_all_host_interfaces(self.if_history_name)
|
||||
for client_if_type in client_if_types:
|
||||
if client_if_type == "af_packet":
|
||||
create_host_interface(
|
||||
self.iprf_client_host_interface_on_linux,
|
||||
self.iprf_client_host_interface_on_vpp,
|
||||
self.if_history_name,
|
||||
self.client_namespace,
|
||||
(
|
||||
layer2["client_ip4_prefix"]
|
||||
@ -274,6 +284,8 @@ class TestVPPInterfacesQemu:
|
||||
if x_connect_mode == "L2"
|
||||
else layer3["client_ip6_prefix"]
|
||||
),
|
||||
vpp_if_name=self.iprf_client_host_interface_on_vpp,
|
||||
host_if_name=self.iprf_client_host_interface_on_linux,
|
||||
)
|
||||
self.ingress_if_idx = self.create_af_packet(
|
||||
version=client_if_version,
|
||||
@ -352,11 +364,12 @@ class TestVPPInterfacesQemu:
|
||||
for server_if_type in server_if_types:
|
||||
if server_if_type == "af_packet":
|
||||
create_host_interface(
|
||||
self.iprf_server_host_interface_on_linux,
|
||||
self.iprf_server_host_interface_on_vpp,
|
||||
self.if_history_name,
|
||||
self.server_namespace,
|
||||
server_ip4_prefix,
|
||||
server_ip6_prefix,
|
||||
vpp_if_name=self.iprf_server_host_interface_on_vpp,
|
||||
host_if_name=self.iprf_server_host_interface_on_linux,
|
||||
)
|
||||
self.egress_if_idx = self.create_af_packet(
|
||||
version=server_if_version,
|
||||
@ -480,12 +493,7 @@ class TestVPPInterfacesQemu:
|
||||
except Exception:
|
||||
pass
|
||||
try:
|
||||
delete_host_interfaces(
|
||||
self.iprf_client_host_interface_on_linux,
|
||||
self.iprf_server_host_interface_on_linux,
|
||||
self.iprf_client_host_interface_on_vpp,
|
||||
self.iprf_server_host_interface_on_vpp,
|
||||
)
|
||||
delete_all_host_interfaces(self.if_history_name)
|
||||
except Exception:
|
||||
pass
|
||||
try:
|
||||
@ -506,12 +514,7 @@ class TestVPPInterfacesQemu:
|
||||
except Exception:
|
||||
pass
|
||||
try:
|
||||
delete_namespace(
|
||||
[
|
||||
self.client_namespace,
|
||||
self.server_namespace,
|
||||
]
|
||||
)
|
||||
delete_all_namespaces(self.ns_history_file)
|
||||
except Exception:
|
||||
pass
|
||||
try:
|
||||
|
File diff suppressed because it is too large
Load Diff
Loading…
x
Reference in New Issue
Block a user