Skip to content

Commit b36b890

Browse files
committed
test: Add GPS test
Only possible to run on virtual Qemu instances right now.
1 parent ac9c2ce commit b36b890

10 files changed

Lines changed: 415 additions & 2 deletions

File tree

test/case/hardware/all.yaml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,6 @@
77

88
- name: Watchdog reset on system lockup
99
case: watchdog/test.py
10+
11+
- name: GPS receiver basic test
12+
case: gps_simple/test.py
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
test.adoc
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
=== GPS receiver basic test
2+
3+
ifdef::topdoc[:imagesdir: {topdoc}../../test/case/hardware/gps_simple]
4+
5+
==== Description
6+
7+
Verify that a simulated GPS receiver is detected and reports a valid
8+
fix via the ietf-hardware operational datastore.
9+
10+
The test injects NMEA sentences through a QEMU pipe chardev FIFO,
11+
which appears as a virtio serial port inside the guest.
12+
13+
==== Topology
14+
15+
image::topology.svg[GPS receiver basic test topology, align=center, scaledwidth=75%]
16+
17+
==== Sequence
18+
19+
. Set up topology and attach to target DUT
20+
. Configure GPS hardware component
21+
. Verify GPS is activated
22+
. Verify GPS has a fix
23+
. Verify the position is near the coordinates you test with
24+
. Save the configuration to startup configuration and reboot
25+
. Verify GPS is activated
26+
. Verify GPS has a fix
27+
. Verify the position is near the coordinates you test with
28+
29+
Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
#!/usr/bin/env python3
2+
"""GPS receiver basic test
3+
4+
Verify that two simulated GPS receivers are detected and report valid
5+
fixes via the ietf-hardware operational datastore.
6+
7+
The test injects NMEA sentences through QEMU pipe chardev FIFOs,
8+
which appear as virtio serial ports inside the guest.
9+
"""
10+
import infamy
11+
import infamy.gps as gps
12+
from infamy.util import until, wait_boot
13+
14+
# Fun facts: The top of mount everest
15+
test_lat = 27.9881
16+
test_lon = 86.9250
17+
test_alt = 8848.86
18+
19+
20+
def _near(a, b, tol):
21+
return abs(a - b) <= tol
22+
23+
def verify_position(target, name="gps0"):
24+
state = gps.get_gps_state(target, name)
25+
26+
try:
27+
lat = float(state["latitude"])
28+
lon = float(state["longitude"])
29+
alt = float(state["altitude"])
30+
except (KeyError, TypeError, ValueError):
31+
test.fail()
32+
33+
if not _near(lat, test_lat, 0.01):
34+
test.fail()
35+
if not _near(lon, test_lon, 0.01):
36+
test.fail()
37+
if not _near(alt, test_alt, 100):
38+
test.fail()
39+
40+
try:
41+
sat_used = int(state["satellites-used"])
42+
except (KeyError, TypeError, ValueError):
43+
test.fail()
44+
45+
if sat_used != 8:
46+
test.fail()
47+
48+
with infamy.Test() as test:
49+
with test.step("Set up topology and attach to target DUT"):
50+
env = infamy.Env()
51+
target = env.attach("target", "mgmt")
52+
53+
phys_name = env.ltop.mapping["target"][None]
54+
55+
if not target.has_feature("infix-hardware", "gps"):
56+
test.skip()
57+
58+
# These are hacks, will only work on virtual devices
59+
pipe0 = f"/tmp/{phys_name}-gps"
60+
pipe1 = f"/tmp/{phys_name}-gps1"
61+
62+
with gps.NMEAGenerator(pipe0, lat=test_lat, lon=test_lon, alt=test_alt), \
63+
gps.NMEAGenerator(pipe1, lat=test_lat, lon=test_lon, alt=test_alt):
64+
65+
with test.step("Configure GPS hardware components"):
66+
target.put_config_dicts({"ietf-hardware": {
67+
"hardware": {
68+
"component": [
69+
{
70+
"name": "gps0",
71+
"class": "infix-hardware:gps",
72+
"infix-hardware:gps-receiver": {}
73+
},
74+
{
75+
"name": "gps1",
76+
"class": "infix-hardware:gps",
77+
"infix-hardware:gps-receiver": {}
78+
}
79+
]
80+
}
81+
}})
82+
83+
with test.step("Verify both GPS receivers are activated"):
84+
until(lambda: gps.is_activated(target, "gps0"), attempts=500)
85+
until(lambda: gps.is_activated(target, "gps1"), attempts=500)
86+
87+
with test.step("Verify both GPS receivers have a fix"):
88+
until(lambda: gps.has_fix(target, "gps0"), attempts=60)
89+
until(lambda: gps.has_fix(target, "gps1"), attempts=60)
90+
91+
with test.step("Verify gps0 position is near the coordinates"):
92+
verify_position(target, "gps0")
93+
94+
with test.step("Verify gps1 position is near the coordinates"):
95+
verify_position(target, "gps1")
96+
97+
with test.step("Save the configuration to startup configuration and reboot"):
98+
target.startup_override()
99+
target.copy("running", "startup")
100+
target.reboot()
101+
if not wait_boot(target, env):
102+
test.fail()
103+
target = env.attach("target", "mgmt", test_reset=False)
104+
105+
with test.step("Verify both GPS receivers are activated"):
106+
until(lambda: gps.is_activated(target, "gps0"), attempts=500)
107+
until(lambda: gps.is_activated(target, "gps1"), attempts=500)
108+
109+
with test.step("Verify both GPS receivers have a fix"):
110+
until(lambda: gps.has_fix(target, "gps0"), attempts=60)
111+
until(lambda: gps.has_fix(target, "gps1"), attempts=60)
112+
113+
with test.step("Verify gps0 position is near the coordinates"):
114+
verify_position(target, "gps0")
115+
116+
with test.step("Verify gps1 position is near the coordinates"):
117+
verify_position(target, "gps1")
118+
119+
test.succeed()
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
graph "1x1" {
2+
layout="neato";
3+
overlap="false";
4+
esep="+80";
5+
6+
node [shape=record, fontname="DejaVu Sans Mono, Book"];
7+
edge [color="cornflowerblue", penwidth="2", fontname="DejaVu Serif, Book"];
8+
9+
host [
10+
label="host | { <mgmt> mgmt }",
11+
pos="0,12!",
12+
requires="controller",
13+
];
14+
15+
target [
16+
label="{ <mgmt> mgmt } | target",
17+
pos="10,12!",
18+
requires="infix gps",
19+
];
20+
21+
host:mgmt -- target:mgmt [requires="mgmt", color="lightgray"]
22+
}
Lines changed: 33 additions & 0 deletions
Loading

0 commit comments

Comments
 (0)