Skip to content

Commit e116236

Browse files
committed
Add PF support fixture for tests
1 parent b4c1020 commit e116236

File tree

62 files changed

+521
-180
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

62 files changed

+521
-180
lines changed

tests/validation/common/nicctl.py

Lines changed: 124 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,18 +24,18 @@ def _nicctl_path(self) -> str:
2424
return str(self.connection.path(self.mtl_path, "script", self.tool_name))
2525
return str(self.connection.path(nicctl_path, self.tool_name))
2626

27-
def _parse_vf_list(self, output: str, all: bool = True) -> list:
27+
def _parse_vf_list(self, output: str) -> list:
2828
if "No VFs found" in output:
2929
return []
30-
vf_info_regex = r"\d{1,3}\s+(.+)\s+vfio" if all else r"(\d{4}:\S+)"
30+
vf_info_regex = r"(\d{4}[0-9a-fA-F:.]+)\(?\S*\)?\s+\S*\s*vfio"
3131
return re.findall(vf_info_regex, output)
3232

3333
def vfio_list(self, pci_addr: str = "all") -> list:
3434
"""Returns list of VFs created on host."""
3535
resp = self.connection.execute_command(
3636
f"{self.nicctl} list {pci_addr}", shell=True
3737
)
38-
return self._parse_vf_list(resp.stdout, "all" in pci_addr)
38+
return self._parse_vf_list(resp.stdout)
3939

4040
def create_vfs(self, pci_id: str, num_of_vfs: int = 6) -> list:
4141
"""Create VFs on NIC.
@@ -68,3 +68,124 @@ def prepare_vfs_for_test(self, nic: NetworkInterface) -> list:
6868
self.create_vfs(nic_pci)
6969
self.host.vfs = self.vfio_list(nic_pci)
7070
return self.host.vfs
71+
72+
def bind_pmd(self, pci_id: str) -> None:
73+
"""Bind VF to DPDK PMD driver."""
74+
self.connection.execute_command(self.nicctl + " bind_pmd " + pci_id, shell=True)
75+
76+
def bind_kernel(self, pci_id: str) -> None:
77+
"""Bind VF to kernel driver."""
78+
self.connection.execute_command(
79+
self.nicctl + " bind_kernel " + pci_id, shell=True
80+
)
81+
82+
83+
class InterfaceSetup:
84+
def __init__(self, hosts, mtl_path):
85+
self.hosts = hosts
86+
self.mtl_path = mtl_path
87+
self.nicctl_objs = {
88+
host.name: Nicctl(mtl_path, host) for host in hosts.values()
89+
}
90+
self.customs = []
91+
self.cleanups = []
92+
93+
def get_test_interfaces(self, interface_type="VF", count=2, host=None) -> dict:
94+
"""
95+
Creates VFs and binds them into dpdk or bind PF into dpdk.
96+
97+
:param interface_type: VF - create X VFs on firt available test adapter,
98+
PF - prepare list of PFs PCI addresses for test,
99+
xxVFxPF - create xx number VFs per each PF. E.G if you need 3 VFs
100+
on every PF and you have 2 PF then pass 3VFxPF param with count=6
101+
if you type just VFxPF then one VF will be created on each PF.
102+
:param count: total number of VFs or PFs needed for test.
103+
:param host: You can specify host if you need to test only on this host
104+
:return: Returns dictionary with list of PCI addresses of VFs or PFs per host name.
105+
"""
106+
if host:
107+
hosts = [host]
108+
else:
109+
hosts = list(self.hosts.values())
110+
selected_interfaces = {k.name: [] for k in hosts}
111+
for host in hosts:
112+
if getattr(host.topology.extra_info, "custom_interface", None):
113+
selected_interfaces[host.name] = [
114+
host.topology.extra_info["custom_interface"]
115+
]
116+
self.customs.append(host.name)
117+
if len(selected_interfaces[host.name]) < count:
118+
raise Exception(
119+
f"Not enough interfaces for test on host {host.name} in extra_info.custom_interface"
120+
)
121+
else:
122+
if interface_type == "VF":
123+
vfs = self.nicctl_objs[host.name].create_vfs(
124+
host.network_interfaces[0].pci_address.lspci, count
125+
)
126+
selected_interfaces[host.name] = vfs
127+
self.register_cleanup(
128+
self.nicctl_objs[host.name],
129+
host.network_interfaces[0].pci_address.lspci,
130+
interface_type,
131+
)
132+
elif interface_type == "PF":
133+
try:
134+
selected_interfaces[host.name] = []
135+
for i in range(count):
136+
self.nicctl_objs[host.name].bind_pmd(
137+
host.network_interfaces[i].pci_address.lspci
138+
)
139+
selected_interfaces[host.name].append(
140+
str(host.network_interfaces[i])
141+
)
142+
self.register_cleanup(
143+
self.nicctl_objs[host.name],
144+
host.network_interfaces[i].pci_address.lspci,
145+
interface_type,
146+
)
147+
except IndexError:
148+
raise Exception(
149+
f"Not enough interfaces for test on host {host.name} in topology config."
150+
)
151+
elif "VFxPF" in interface_type:
152+
vfs_count = interface_type.split("VFxPF")[0]
153+
vfs_count = int(vfs_count) if vfs_count else 1
154+
for i in range(count // vfs_count):
155+
try:
156+
vfs = self.nicctl_objs[host.name].create_vfs(
157+
host.network_interfaces[i].pci_address.lspci, vfs_count
158+
)
159+
selected_interfaces[host.name].extend(vfs)
160+
self.register_cleanup(
161+
self.nicctl_objs[host.name],
162+
host.network_interfaces[i].pci_address.lspci,
163+
"VF",
164+
)
165+
except IndexError:
166+
raise Exception(
167+
f"Not enough interfaces for test on host {host.name} in topology config. "
168+
f"Expected {count // vfs_count} adapters "
169+
f"to be able to create total {count} VFs - {vfs_count} per adapter"
170+
)
171+
else:
172+
raise Exception(f"Unknown interface type {interface_type}")
173+
return selected_interfaces
174+
175+
def get_interfaces_list_single(self, interface_type="VF", count=2) -> list:
176+
"""
177+
Wrapper for get_test_interfaces method if you use only single node tests and need only list of interfaces
178+
"""
179+
host = list(self.hosts.values())[0]
180+
selected_interfaces = self.get_test_interfaces(interface_type, count, host=host)
181+
return selected_interfaces[host.name]
182+
183+
def register_cleanup(self, nicctl, interface, if_type):
184+
self.cleanups.append((nicctl, interface, if_type))
185+
186+
def cleanup(self):
187+
for nicctl, interface, if_type in self.cleanups:
188+
if if_type == "VF":
189+
nicctl.disable_vf(interface)
190+
elif if_type == "PF":
191+
nicctl.bind_kernel(interface)

tests/validation/configs/examples/test_config.yaml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,3 +18,7 @@ ebu_server:
1818
user: user
1919
password: password
2020
proxy: false
21+
interface_type: VF - create X VFs on firt available test adapter,
22+
PF - prepare list of PFs PCI addresses for test,
23+
xxVFxPF - create xx number VFs per each PF. E.G if you need 3 VFs on every PF and you have 2 PF then pass 3VFxPF param with count=6
24+
if you type just VFxPF then one VF will be created on each PF.

tests/validation/conftest.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111

1212
import pytest
1313
from common.mtl_manager.mtlManager import MtlManager
14-
from common.nicctl import Nicctl
14+
from common.nicctl import InterfaceSetup, Nicctl
1515
from compliance.compliance_client import PcapComplianceClient
1616
from create_pcap_file.netsniff import NetsniffRecorder, calculate_packets_per_frame
1717
from mfd_common_libs.custom_logger import add_logging_level
@@ -125,6 +125,13 @@ def nic_port_list(hosts: dict, mtl_path) -> None:
125125
host.vfs = vfs
126126

127127

128+
@pytest.fixture(scope="function")
129+
def setup_interfaces(hosts, test_config, mtl_path):
130+
interface_setup = InterfaceSetup(hosts, mtl_path)
131+
yield interface_setup
132+
interface_setup.cleanup()
133+
134+
128135
@pytest.fixture(scope="session")
129136
def test_time(test_config: dict) -> int:
130137
test_time = test_config.get("test_time", 30)

tests/validation/mtl_engine/ffmpeg_app.py

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ def execute_test(
5757
test_time: int,
5858
build: str,
5959
host,
60+
nic_port_list,
6061
type_: str,
6162
video_format: str,
6263
pg_format: str,
@@ -65,13 +66,9 @@ def execute_test(
6566
multiple_sessions: bool = False,
6667
tx_is_ffmpeg: bool = True,
6768
):
68-
# Initialize logging for this test
69-
init_test_logging()
70-
7169
case_id = os.environ.get("PYTEST_CURRENT_TEST", "ffmpeg_test")
7270
case_id = case_id[: case_id.rfind("(") - 1] if "(" in case_id else case_id
7371

74-
nic_port_list = host.vfs
7572
video_size, fps = decode_video_format_16_9(video_format)
7673
match output_format:
7774
case "yuv":
@@ -234,14 +231,14 @@ def execute_test_rgb24(
234231
test_time: int,
235232
build: str,
236233
host,
234+
nic_port_list,
237235
type_: str,
238236
video_format: str,
239237
pg_format: str,
240238
video_url: str,
241239
):
242240
# Initialize logging for this test
243241
init_test_logging()
244-
nic_port_list = host.vfs
245242
video_size, fps = decode_video_format_16_9(video_format)
246243
logger.info(f"Creating RX config for RGB24 test with video_format: {video_format}")
247244
try:

tests/validation/tests/single/ffmpeg/test_rx_ffmpeg_tx_ffmpeg.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import os
55

66
import pytest
7+
from common.nicctl import InterfaceSetup
78
from mtl_engine import ffmpeg_app
89
from mtl_engine.media_files import yuv_files
910

@@ -23,21 +24,25 @@ def test_rx_ffmpeg_tx_ffmpeg(
2324
test_time,
2425
build,
2526
media,
26-
nic_port_list,
27+
setup_interfaces: InterfaceSetup,
2728
video_format,
2829
test_time_multipler,
2930
output_format,
3031
test_config,
3132
prepare_ramdisk,
3233
):
3334
host = list(hosts.values())[0]
35+
interfaces_list = setup_interfaces.get_interfaces_list_single(
36+
test_config.get("interface_type", "VF")
37+
)
3438

3539
video_file = yuv_files[video_format]
3640

3741
ffmpeg_app.execute_test(
3842
test_time=test_time * test_time_multipler,
3943
build=build,
4044
host=host,
45+
nic_port_list=interfaces_list,
4146
type_="frame",
4247
video_format=video_format,
4348
pg_format=video_file["format"],

tests/validation/tests/single/ffmpeg/test_rx_ffmpeg_tx_ffmpeg_rgb24.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import os
55

66
import pytest
7+
from common.nicctl import InterfaceSetup
78
from mtl_engine import ffmpeg_app
89
from mtl_engine.media_files import yuv_files
910

@@ -23,13 +24,16 @@ def test_rx_ffmpeg_tx_ffmpeg_rgb24(
2324
test_time,
2425
build,
2526
media,
26-
nic_port_list,
27+
setup_interfaces: InterfaceSetup,
2728
video_format,
2829
test_time_mutlipler,
2930
test_config,
3031
prepare_ramdisk,
3132
):
3233
host = list(hosts.values())[0]
34+
interfaces_list = setup_interfaces.get_interfaces_list_single(
35+
test_config.get("interface_type", "VF")
36+
)
3337

3438
video_file = yuv_files[video_format]
3539

@@ -41,4 +45,5 @@ def test_rx_ffmpeg_tx_ffmpeg_rgb24(
4145
video_format=video_format,
4246
pg_format=video_file["format"],
4347
video_url=os.path.join(media, video_file["filename"]),
48+
nic_port_list=interfaces_list,
4449
)

tests/validation/tests/single/ffmpeg/test_rx_ffmpeg_tx_ffmpeg_rgb24_multiple.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import os
55

66
import pytest
7+
from common.nicctl import InterfaceSetup
78
from mtl_engine import ffmpeg_app
89
from mtl_engine.media_files import yuv_files
910

@@ -25,22 +26,25 @@ def test_rx_ffmpeg_tx_ffmpeg_rgb24_multiple(
2526
test_time,
2627
build,
2728
media,
28-
nic_port_list,
29+
setup_interfaces: InterfaceSetup,
2930
video_format_1,
3031
video_format_2,
3132
test_time_mutlipler,
3233
test_config,
3334
prepare_ramdisk,
3435
):
3536
host = list(hosts.values())[0]
37+
interfaces_list = setup_interfaces.get_interfaces_list_single(
38+
test_config.get("interface_type", "VF"), count=4
39+
)
3640

3741
video_file_1 = yuv_files[video_format_1]
3842
video_file_2 = yuv_files[video_format_2]
3943

4044
ffmpeg_app.execute_test_rgb24_multiple(
4145
test_time=test_time * test_time_mutlipler,
4246
build=build,
43-
nic_port_list=host.vfs,
47+
nic_port_list=interfaces_list,
4448
type_="frame",
4549
video_format_list=[video_format_1, video_format_2],
4650
pg_format=video_file_1["format"],

tests/validation/tests/single/ffmpeg/test_rx_ffmpeg_tx_rxtxapp.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import os
55

66
import pytest
7+
from common.nicctl import InterfaceSetup
78
from mtl_engine import ffmpeg_app
89
from mtl_engine.media_files import yuv_files
910

@@ -27,7 +28,7 @@ def test_rx_ffmpeg_tx_rxtxapp(
2728
test_time,
2829
build,
2930
media,
30-
nic_port_list,
31+
setup_interfaces: InterfaceSetup,
3132
video_format,
3233
multiple_sessions,
3334
test_time_multipler,
@@ -36,12 +37,16 @@ def test_rx_ffmpeg_tx_rxtxapp(
3637
prepare_ramdisk,
3738
):
3839
host = list(hosts.values())[0]
40+
interfaces_list = setup_interfaces.get_interfaces_list_single(
41+
test_config.get("interface_type", "VF")
42+
)
3943
video_file = yuv_files[video_format]
4044

4145
ffmpeg_app.execute_test(
4246
test_time=test_time * test_time_multipler,
4347
build=build,
4448
host=host,
49+
nic_port_list=interfaces_list,
4550
type_="frame",
4651
video_format=video_format,
4752
pg_format=video_file["format"],

0 commit comments

Comments
 (0)