Skip to content

Commit 238f6f7

Browse files
committed
Fix: Remove phc2sys setup action & replace it with fixture
Signed-off-by: Kasiewicz, Marek <marek.kasiewicz@intel.com>
1 parent bd86c36 commit 238f6f7

File tree

4 files changed

+100
-98
lines changed

4 files changed

+100
-98
lines changed

.github/actions/setup-capture-phc2sys/action.yml

Lines changed: 0 additions & 68 deletions
This file was deleted.

.github/workflows/nightly-pytest.yml

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -83,11 +83,10 @@ jobs:
8383
sudo killall -SIGINT pytest || true
8484
sudo killall -SIGINT MtlManager || true
8585
sudo killall -SIGINT phc2sys || true
86-
- name: Setup capture PTP device and phc2sys
87-
uses: ./.github/actions/setup-capture-phc2sys
88-
with:
89-
pci_device: ${{ env.PCI_DEVICE }}
90-
mtl_github_workflow: ${{ github.workflow }}:${{ matrix.nic }}
86+
- name: Export workflow tag for PCAP naming
87+
shell: bash
88+
run: |
89+
echo "MTL_GITHUB_WORKFLOW=${{ github.workflow }}:${{ matrix.nic }}" >> "$GITHUB_ENV"
9190
- name: 'preparation: Start MtlManager at background'
9291
run: |
9392
sudo MtlManager &

.github/workflows/smoke-tests.yml

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -95,12 +95,11 @@ jobs:
9595
sudo killall -SIGINT pytest || true
9696
sudo killall -SIGINT MtlManager || true
9797
sudo killall -SIGINT phc2sys || true
98-
- name: Setup capture PTP device and phc2sys
98+
- name: Export workflow tag for PCAP naming
9999
if: ${{ needs.smoke-check-for-changes.outputs.changed == 'true' }}
100-
uses: ./.github/actions/setup-capture-phc2sys
101-
with:
102-
pci_device: ${{ env.PCI_DEVICE }}
103-
mtl_github_workflow: ${{ github.workflow }}:${{ matrix.nic }}
100+
shell: bash
101+
run: |
102+
echo "MTL_GITHUB_WORKFLOW=${{ github.workflow }}:${{ matrix.nic }}" >> "$GITHUB_ENV"
104103
- name: 'preparation: Start MtlManager at background'
105104
if: ${{ needs.smoke-check-for-changes.outputs.changed == 'true' }}
106105
run: |

tests/validation/conftest.py

Lines changed: 92 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -42,27 +42,27 @@
4242
phase_report_key = pytest.StashKey[Dict[str, pytest.CollectReport]]()
4343

4444

45-
def _select_sniff_interface_name(host, capture_cfg: dict) -> str:
45+
def _select_sniff_interface(host, capture_cfg: dict):
4646
def _pci_device_id(nic) -> str:
4747
"""Return lowercased PCI vendor:device identifier (e.g., '8086:1592')."""
48-
pci_device = getattr(nic, "pci_device", None)
49-
if pci_device is None:
50-
return ""
51-
52-
vendor_id = getattr(pci_device, "vendor_id", None)
53-
device_id = getattr(pci_device, "device_id", None)
54-
if vendor_id is None or device_id is None:
55-
return ""
56-
57-
return f"{vendor_id}:{device_id}".lower()
48+
return f"{nic.pci_device.vendor_id}:{nic.pci_device.device_id}".lower()
5849

5950
sniff_interface = capture_cfg.get("sniff_interface")
6051
if sniff_interface:
61-
return str(sniff_interface)
52+
for nic in host.network_interfaces:
53+
if nic.name == str(sniff_interface):
54+
return nic
55+
available = []
56+
for nic in host.network_interfaces:
57+
available.append(f"{nic.name} ({nic.pci_address.lspci})")
58+
raise RuntimeError(
59+
f"capture_cfg.sniff_interface={sniff_interface} not found on host {host.name}. "
60+
f"Available interfaces: {', '.join(available)}"
61+
)
6262

6363
sniff_interface_index = capture_cfg.get("sniff_interface_index")
6464
if sniff_interface_index is not None:
65-
return host.network_interfaces[int(sniff_interface_index)].name
65+
return host.network_interfaces[int(sniff_interface_index)]
6666

6767
sniff_pci_device = capture_cfg.get("sniff_pci_device")
6868
if sniff_pci_device:
@@ -72,14 +72,11 @@ def _pci_device_id(nic) -> str:
7272
nic for nic in host.network_interfaces if target == _pci_device_id(nic)
7373
]
7474
if direct_matches:
75-
return (
76-
direct_matches[1] if len(direct_matches) > 1 else direct_matches[0]
77-
).name
75+
return direct_matches[1] if len(direct_matches) > 1 else direct_matches[0]
7876

7977
available = []
8078
for nic in host.network_interfaces:
81-
pci_addr = getattr(getattr(nic, "pci_address", None), "lspci", None)
82-
available.append(f"{nic.name} ({pci_addr})")
79+
available.append(f"{nic.name} ({nic.pci_address.lspci})")
8380
raise RuntimeError(
8481
f"capture_cfg.sniff_pci_device={sniff_pci_device} not found on host {host.name}. "
8582
f"Available interfaces: {', '.join(available)}"
@@ -92,7 +89,82 @@ def _pci_device_id(nic) -> str:
9289
f"Cannot select 2nd PF for capture. Add more interfaces to config or turn off capture."
9390
)
9491

95-
return host.network_interfaces[1].name
92+
return host.network_interfaces[1]
93+
94+
95+
def _select_sniff_interface_name(host, capture_cfg: dict) -> str:
96+
return _select_sniff_interface(host, capture_cfg).name
97+
98+
99+
def _select_capture_host(hosts: dict):
100+
return hosts["client"] if "client" in hosts else list(hosts.values())[0]
101+
102+
103+
@pytest.fixture(scope="session")
104+
def phc2sys_session(test_config: dict, hosts):
105+
"""Start phc2sys for the capture interface before any tests.
106+
107+
- Uses the same interface selection logic as PCAP capture.
108+
- Detects the PTP Hardware Clock via `ethtool -T`.
109+
- Runs `phc2sys -s /dev/ptpX -c CLOCK_REALTIME -O 0 -m`.
110+
111+
The process is stopped at the end of the session.
112+
"""
113+
114+
capture_cfg = test_config.get("capture_cfg", {})
115+
if not (capture_cfg and capture_cfg.get("enable")):
116+
yield
117+
return
118+
119+
host = _select_capture_host(hosts)
120+
sniff_nic = _select_sniff_interface(host, capture_cfg)
121+
capture_iface = sniff_nic.name
122+
123+
ptp_details = host.connection.execute_command(
124+
f"sudo ethtool -T '{capture_iface}' 2>/dev/null || true"
125+
)
126+
ptp_idx = ""
127+
for line in (ptp_details.stdout or "").splitlines():
128+
# Keep this equivalent to: awk -F': ' '/PTP Hardware Clock:/ {print $2; exit}'
129+
if "PTP Hardware Clock:" in line:
130+
ptp_idx = line.split(": ", 1)[1].strip() if ": " in line else ""
131+
break
132+
133+
if not ptp_idx.isdigit():
134+
raise RuntimeError(
135+
"ERROR: failed to parse PTP Hardware Clock index for "
136+
f"{capture_iface}. Details: {ptp_details.stdout}{ptp_details.stderr}"
137+
)
138+
139+
capture_ptp = f"/dev/ptp{ptp_idx}"
140+
141+
logger.info(
142+
f"Starting phc2sys: {capture_ptp} -> CLOCK_REALTIME (iface={capture_iface})"
143+
)
144+
145+
log_path = f"/tmp/phc2sys-{capture_iface}.log"
146+
start_cmd = (
147+
"sudo phc2sys "
148+
f"-s '{capture_ptp}' -c CLOCK_REALTIME -O 0 -m "
149+
f"> '{log_path}' 2>&1 < /dev/null & echo $!"
150+
)
151+
start_res = host.connection.execute_command(start_cmd)
152+
pid = (
153+
(start_res.stdout or "").strip().splitlines()[-1].strip()
154+
if start_res.stdout
155+
else ""
156+
)
157+
158+
if not pid.isdigit():
159+
raise RuntimeError(
160+
f"Failed to start phc2sys (iface={capture_iface}, ptp={capture_ptp}). "
161+
f"stdout={start_res.stdout!r}, stderr={start_res.stderr!r}, log={log_path}"
162+
)
163+
164+
try:
165+
yield
166+
finally:
167+
host.connection.execute_command(f"sudo kill -SIGINT {pid} || true")
96168

97169

98170
@pytest.hookimpl(wrapper=True, tryfirst=True)
@@ -346,7 +418,7 @@ def log_session():
346418

347419

348420
@pytest.fixture(scope="function")
349-
def pcap_capture(request, media_file, test_config, hosts, mtl_path):
421+
def pcap_capture(request, media_file, test_config, hosts, mtl_path, phc2sys_session):
350422
capture_cfg = test_config.get("capture_cfg", {})
351423
capturer = None
352424
if capture_cfg and capture_cfg.get("enable"):

0 commit comments

Comments
 (0)