Skip to content

Commit 9969ac9

Browse files
committed
Add PF support fixture for tests
1 parent cae46cf commit 9969ac9

File tree

61 files changed

+515
-178
lines changed

Some content is hidden

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

61 files changed

+515
-178
lines changed

tests/validation/common/nicctl.py

Lines changed: 121 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,121 @@ 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, PF - prepare list of PFs PCI addresses for test,
98+
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
99+
:param count: total number of VFs or PFs needed for test.
100+
:param host: You can specify host if you need to test only on this host
101+
:return: Returns dictionary with list of PCI addresses of VFs or PFs per host name.
102+
"""
103+
if host:
104+
hosts = [host]
105+
else:
106+
hosts = list(self.hosts.values())
107+
selected_interfaces = {k.name: [] for k in hosts}
108+
for host in hosts:
109+
if getattr(host.topology.extra_info, "custom_interface", None):
110+
selected_interfaces[host.name] = [
111+
host.topology.extra_info["custom_interface"]
112+
]
113+
self.customs.append(host.name)
114+
if len(selected_interfaces[host.name]) < count:
115+
raise Exception(
116+
f"Not enough interfaces for test on host {host.name} in extra_info.custom_interface"
117+
)
118+
else:
119+
if interface_type == "VF":
120+
vfs = self.nicctl_objs[host.name].create_vfs(
121+
host.network_interfaces[0].pci_address.lspci, count
122+
)
123+
selected_interfaces[host.name] = vfs
124+
self.register_cleanup(
125+
self.nicctl_objs[host.name],
126+
host.network_interfaces[0].pci_address.lspci,
127+
interface_type,
128+
)
129+
elif interface_type == "PF":
130+
try:
131+
selected_interfaces[host.name] = []
132+
for i in range(count):
133+
self.nicctl_objs[host.name].bind_pmd(
134+
host.network_interfaces[i].pci_address.lspci
135+
)
136+
selected_interfaces[host.name].append(
137+
str(host.network_interfaces[i])
138+
)
139+
self.register_cleanup(
140+
self.nicctl_objs[host.name],
141+
host.network_interfaces[i].pci_address.lspci,
142+
interface_type,
143+
)
144+
except IndexError:
145+
raise Exception(
146+
f"Not enough interfaces for test on host {host.name} in topology config."
147+
)
148+
elif "VFxPF" in interface_type:
149+
vfs_count = interface_type.split("VFxPF")[0]
150+
vfs_count = int(vfs_count) if vfs_count else 1
151+
for i in range(count // vfs_count):
152+
try:
153+
vfs = self.nicctl_objs[host.name].create_vfs(
154+
host.network_interfaces[i].pci_address.lspci, vfs_count
155+
)
156+
selected_interfaces[host.name].extend(vfs)
157+
self.register_cleanup(
158+
self.nicctl_objs[host.name],
159+
host.network_interfaces[i].pci_address.lspci,
160+
"VF",
161+
)
162+
except IndexError:
163+
raise Exception(
164+
f"Not enough interfaces for test on host {host.name} in topology config. "
165+
f"Expected {count // vfs_count} adapters "
166+
f"to be able to create total {count} VFs - {vfs_count} per adapter"
167+
)
168+
else:
169+
raise Exception(f"Unknown interface type {interface_type}")
170+
return selected_interfaces
171+
172+
def get_interfaces_list_single(self, interface_type="VF", count=2) -> list:
173+
"""
174+
Wrapper for get_test_interfaces method if you use only single node tests and need only list of interfaces
175+
"""
176+
host = list(self.hosts.values())[0]
177+
selected_interfaces = self.get_test_interfaces(interface_type, count, host=host)
178+
return selected_interfaces[host.name]
179+
180+
def register_cleanup(self, nicctl, interface, if_type):
181+
self.cleanups.append((nicctl, interface, if_type))
182+
183+
def cleanup(self):
184+
for nicctl, interface, if_type in self.cleanups:
185+
if if_type == "VF":
186+
nicctl.disable_vf(interface)
187+
elif if_type == "PF":
188+
nicctl.bind_kernel(interface)

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)