Skip to content

Commit 2e3e1da

Browse files
authored
Merge pull request #12 from SmithChart/cfi/2025-04
Mixed bag of new tests for the 25.04 release
2 parents 4f885c4 + 3725b9b commit 2e3e1da

File tree

3 files changed

+135
-10
lines changed

3 files changed

+135
-10
lines changed

tests/test_labgrid_resources.py

+17-8
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import logging
12
import time
23

34
import pytest
@@ -9,15 +10,15 @@
910
# resources on the fly.
1011

1112

13+
@pytest.mark.slow
1214
def test_labgrid_resources_simple(strategy, shell, check):
1315
"""Test non-managed resources."""
1416

15-
def retry_loop():
17+
def retry_loop(logger):
1618
rpm = RemotePlaceManager.get()
1719
exporter = strategy.target_hostname
1820

19-
for _ in range(300):
20-
time.sleep(1)
21+
for _ in range(300 // 15):
2122
rpm.poll()
2223

2324
try:
@@ -44,26 +45,30 @@ def retry_loop():
4445
except Exception:
4546
pass
4647

48+
logger.info("(Still) waiting for labgrid resources to appear...")
49+
time.sleep(15)
50+
4751
pytest.fail("Failed to get resources, even after trying for 5 minutes")
4852

49-
serial_port_params, power_port_params, _out_0, _out_1 = retry_loop()
53+
logger = logging.getLogger("test_labgrid_resources_simple")
54+
serial_port_params, power_port_params, _out_0, _out_1 = retry_loop(logger)
5055

5156
with check:
5257
assert serial_port_params["extra"]["path"].startswith("/dev/ttySTM")
5358
with check:
5459
assert power_port_params["model"] == "rest"
5560

5661

62+
@pytest.mark.slow
5763
def test_labgrid_resources_usb(strategy, shell, eet):
5864
"""Test ManagedResources (udev)."""
5965

60-
def retry_loop():
66+
def retry_loop(logger):
6167
rpm = RemotePlaceManager.get()
6268
exporter = strategy.target_hostname
6369
match = ResourceMatch.fromstr(f"{exporter}/lxatac-usb-ports-p*/*")
6470

65-
for _ in range(300):
66-
time.sleep(1)
71+
for _ in range(300 // 15):
6772
rpm.poll()
6873

6974
try:
@@ -81,11 +86,15 @@ def retry_loop():
8186
except Exception:
8287
pass
8388

89+
logger.info("(Still) waiting for labgrid resources to appear...")
90+
time.sleep(15)
91+
8492
pytest.fail("Failed to get resources, even after trying for 5 minutes")
8593

8694
if eet:
8795
eet.link("USB1_IN -> USB1_OUT, USB2_IN -> USB2_OUT, USB3_IN -> USB3_OUT")
88-
usb_resources = retry_loop()
96+
logger = logging.getLogger("test_labgrid_resources_usb")
97+
usb_resources = retry_loop(logger)
8998

9099
# make sure at least one USB resource is available
91100
assert usb_resources != []

tests/test_linux_pstore.py

+29
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,35 @@
1+
import re
2+
3+
14
def test_pstore_fs(shell):
25
"""
36
Test if the pstore filesystem exists.
47
"""
58

69
shell.run_check("test -d /sys/fs/pstore")
10+
11+
12+
def test_kernel_messages(shell, check):
13+
"""
14+
Test if the kernel only logs messages that we expect.
15+
16+
This test will ignore some harmless messages that can happen during normal operation.
17+
"""
18+
19+
expected = {
20+
"spi_stm32 44009000.spi: failed to request tx dma channel",
21+
"spi_stm32 44009000.spi: failed to request rx dma channel",
22+
"clk: failed to reparent ethck_k to pll4_p: -22",
23+
"stm32-dwmac 5800a000.ethernet switch: Adding VLAN ID 0 is not supported",
24+
}
25+
26+
allowed = {
27+
# The following messages can happen during other tests and are harmless
28+
"sd 0:0:0:0: [sda] No Caching mode page found",
29+
"sd 0:0:0:0: [sda] Assuming drive cache: write through",
30+
}
31+
32+
messages = shell.run_check("dmesg -l warn -l err -l crit -l alert -l emerg -k")
33+
messages = set(re.sub(r"^\[\s*\d+\.\d+\] ", "", m) for m in messages)
34+
35+
assert messages - allowed == expected

tests/test_userspace.py

+89-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
import csv
22
import json
3+
import re
4+
from dataclasses import dataclass
5+
6+
import pytest
37

48

59
def test_chrony(shell):
@@ -66,7 +70,7 @@ def test_switch_configuration(shell, check):
6670
assert global_v6.endswith(v6_tail)
6771

6872

69-
def test_hostname(shell):
73+
def test_hostname(shell, check):
7074
"""Test whether the serial number is contained in the hostname"""
7175

7276
[serial_number] = shell.run_check("cat /sys/firmware/devicetree/base/chosen/baseboard-factory-data/serial-number")
@@ -75,4 +79,87 @@ def test_hostname(shell):
7579

7680
[hostname] = shell.run_check("hostname")
7781

78-
assert serial_number in hostname
82+
with check:
83+
assert serial_number in hostname
84+
85+
[etc_hostname] = shell.run_check("cat /etc/hostname")
86+
87+
with check:
88+
assert etc_hostname != "localhost"
89+
90+
with check:
91+
assert serial_number in etc_hostname
92+
93+
94+
def test_system_running(shell):
95+
"""
96+
Test if the system state is running.
97+
"""
98+
99+
# This will exit non-zero if we have any other state than "running", but we are interested in the string output.
100+
# So let's ignore the returncode.
101+
[state], _, _ = shell.run("systemctl is-system-running")
102+
103+
assert state == "running"
104+
105+
106+
@pytest.fixture
107+
def clocktree(shell):
108+
"""
109+
Read the clock tree from the DUT and parse it into a data structure.
110+
"""
111+
re_entry = re.compile(r"^\s*(\S+)\s+\d+\s+\d+\s+\d+\s+(\d+)\s+\d+\s+\d+\s+(\d+)\s+\S\s+(\S+)\s+")
112+
re_2nd = re.compile(r"^\s+(\S+)\s+\S+\s+$")
113+
114+
@dataclass
115+
class Clk:
116+
clk_name: str
117+
rate: int
118+
duty: int
119+
consumer: list
120+
121+
clks = {}
122+
clk = None
123+
for line in shell.run_check("cat /sys/kernel/debug/clk/clk_summary"):
124+
if match := re_entry.match(line):
125+
if clk:
126+
clks[clk.clk_name] = clk
127+
clk = Clk(clk_name=match.group(1), rate=int(match.group(2)), duty=int(match.group(3)), consumer=[])
128+
if match.group(4) != "deviceless":
129+
clk.consumer.append(match.group(4))
130+
continue
131+
132+
match = re_2nd.match(line)
133+
if match and match.group(1) != "deviceless":
134+
clk.consumer.append(match.group(1))
135+
136+
return clks
137+
138+
139+
@pytest.mark.parametrize(
140+
"clock_name, rate, consumer",
141+
(
142+
# Ethernet Clocks: Needed for the communication with the phy to work
143+
("ethptp_k", 125000000, ("5800a000.ethernet",)),
144+
("ethck_k", 125000000, ("5800a000.ethernet",)),
145+
("ethrx", 125000000, ("5800a000.ethernet",)),
146+
# CAN Clock: Chosen to be 48MHz for minimum baudrate error across all rates
147+
("fdcan_k", 48000000, ("4400f000.can", "4400e000.can")),
148+
),
149+
)
150+
def test_clocktree(clocktree, check, clock_name, rate, consumer):
151+
"""
152+
Make sure a few selected devices have their fixed clock rates applied.
153+
In this test we check the association of the clock signal with the actual
154+
device and the clocks rate.
155+
"""
156+
assert clock_name in clocktree
157+
158+
clk = clocktree[clock_name]
159+
160+
with check:
161+
assert clk.rate == rate
162+
163+
for c in consumer:
164+
with check:
165+
assert c in clk.consumer

0 commit comments

Comments
 (0)