Skip to content

Commit 0e383a3

Browse files
committed
tests: Add basic wlan test.
Includes adding some ESP8266 port output to the ignored output list for the multitest runner. This test passes on ESP8266 and various ESP32s (including talking to each other). Without the fix in the parent commit, ESP32 AP will fail if the station can report its channel (i.e. channel is wrong). Testing with a CYW43 (RPI_PICO_W) currently fails but I have some fixes to submit so it can pass as well. Signed-off-by: Angus Gratton <[email protected]>
1 parent 951a10e commit 0e383a3

File tree

3 files changed

+135
-6
lines changed

3 files changed

+135
-6
lines changed

tests/multi_wlan/01_ap_sta.py

Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
# Basic Wi-Fi MAC layer test where one device creates an Access Point and the
2+
# other device connects to it as a Station. Also tests channel assignment (where
3+
# possible) and disconnection.
4+
5+
try:
6+
import network
7+
8+
network.WLAN
9+
except (ImportError, NameError):
10+
print("SKIP")
11+
raise SystemExit
12+
13+
import os
14+
import sys
15+
import time
16+
17+
CHANNEL = 8
18+
19+
# Note that on slower Wi-Fi stacks this bumps up against the run-multitests.py
20+
# timeout which expects <10s between lines of output. We work around this by
21+
# logging something half way through the wait_for loop...
22+
CONNECT_TIMEOUT = 15000
23+
24+
25+
def wait_for(test_func):
26+
has_printed = False
27+
start = time.ticks_ms()
28+
while not test_func():
29+
time.sleep(0.1)
30+
delta = time.ticks_diff(time.ticks_ms(), start)
31+
if not has_printed and delta > CONNECT_TIMEOUT / 2:
32+
print("...")
33+
has_printed = True
34+
elif delta > CONNECT_TIMEOUT:
35+
break
36+
37+
if not has_printed:
38+
print("...") # keep the output consistent
39+
40+
return test_func()
41+
42+
43+
# AP
44+
def instance0():
45+
ap = network.WLAN(network.WLAN.IF_AP)
46+
ssid = "MP-test-" + os.urandom(6).hex()
47+
psk = "Secret-" + os.urandom(6).hex()
48+
49+
# stop any previous activity
50+
network.WLAN(network.WLAN.IF_STA).active(False)
51+
ap.active(False)
52+
53+
ap.active(True)
54+
ap.config(ssid=ssid, key=psk, channel=CHANNEL, security=network.WLAN.SEC_WPA_WPA2)
55+
56+
# print("AP setup", ssid, psk)
57+
print("AP started")
58+
59+
multitest.globals(SSID=ssid, PSK=psk)
60+
multitest.next()
61+
62+
# Wait for station
63+
if not wait_for(ap.isconnected):
64+
raise RuntimeError("Timed out waiting for station, status ", ap.status())
65+
66+
print("AP got station")
67+
time.sleep(
68+
3
69+
) # depending on port, may still need to negotiate DHCP lease for STA to see connection
70+
71+
print("AP disabling...")
72+
ap.active(False)
73+
74+
75+
# STA
76+
def instance1():
77+
sta = network.WLAN(network.WLAN.IF_STA)
78+
79+
# stop any previous activity
80+
network.WLAN(network.WLAN.IF_AP).active(False)
81+
sta.active(False)
82+
83+
multitest.next()
84+
ssid = SSID
85+
psk = PSK
86+
87+
# print("STA setup", ssid, psk)
88+
89+
sta.active(True)
90+
sta.connect(ssid, psk)
91+
92+
print("STA connecting...")
93+
94+
if not wait_for(sta.isconnected):
95+
raise RuntimeError("Timed out waiting to connect, status ", sta.status())
96+
97+
print("STA connected")
98+
99+
# Print the current channel, if the port support this
100+
try:
101+
print("channel", sta.config("channel"))
102+
except OSError as e:
103+
if "AP" in str(e):
104+
# ESP8266 only supports reading channel on the AP interface, so fake this result
105+
print("channel", CHANNEL)
106+
else:
107+
raise
108+
109+
print("STA waiting for disconnect...")
110+
111+
# Expect the AP to disconnect us immediately
112+
if not wait_for(lambda: not sta.isconnected()):
113+
raise RuntimeError("Timed out waiting for AP to disconnect us, status ", sta.status())
114+
115+
print("STA disconnected")
116+
117+
sta.active(False)

tests/multi_wlan/01_ap_sta.py.exp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
--- instance0 ---
2+
AP started
3+
...
4+
AP got station
5+
AP disabling...
6+
--- instance1 ---
7+
STA connecting...
8+
...
9+
STA connected
10+
channel 8
11+
STA waiting for disconnect...
12+
...
13+
STA disconnected

tests/run-multitests.py

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -105,15 +105,14 @@ def output_metric(data):
105105
multitest.flush()
106106
"""
107107

108-
# The btstack implementation on Unix generates some spurious output that we
109-
# can't control. Also other platforms may output certain warnings/errors that
110-
# can be safely ignored.
108+
# Some ports generate output we can't control, and that can be safely ignored.
111109
IGNORE_OUTPUT_MATCHES = (
112-
"libusb: error ", # It tries to open devices that it doesn't have access to (libusb prints unconditionally).
110+
"libusb: error ", # unix btstack tries to open devices that it doesn't have access to (libusb prints unconditionally).
113111
"hci_transport_h2_libusb.c", # Same issue. We enable LOG_ERROR in btstack.
114-
"USB Path: ", # Hardcoded in btstack's libusb transport.
115-
"hci_number_completed_packet", # Warning from btstack.
112+
"USB Path: ", # Hardcoded in unix btstack's libusb transport.
113+
"hci_number_completed_packet", # Warning from unix btstack.
116114
"lld_pdu_get_tx_flush_nb HCI packet count mismatch (", # From ESP-IDF, see https://github.com/espressif/esp-idf/issues/5105
115+
" ets_task(", # ESP8266 port debug output
117116
)
118117

119118

0 commit comments

Comments
 (0)