mirror of
https://github.com/espressif/esp-protocols.git
synced 2025-07-19 13:32:21 +02:00
feat(esp_modem): Added target test
This commit is contained in:
65
.github/workflows/target-test.yml
vendored
65
.github/workflows/target-test.yml
vendored
@ -6,7 +6,7 @@ jobs:
|
||||
build_esp_modem:
|
||||
strategy:
|
||||
matrix:
|
||||
idf_ver: ["latest", "release-v4.1", "release-v4.2", "release-v4.3", "release-v4.4"]
|
||||
idf_ver: ["latest", "release-v4.1", "release-v4.2", "release-v4.3", "release-v4.4", "release-v5.0"]
|
||||
example: ["pppos_client", "modem_console", "ap_to_pppos", "simple_cmux_client"]
|
||||
idf_target: ["esp32"]
|
||||
exclude:
|
||||
@ -310,3 +310,66 @@ jobs:
|
||||
with:
|
||||
name: examples_results_${{ matrix.idf_target }}_${{ matrix.idf_ver }}_${{ matrix.example }}
|
||||
path: components/asio/examples/${{ matrix.example }}/*.xml
|
||||
|
||||
build_esp_modem_tests:
|
||||
strategy:
|
||||
matrix:
|
||||
idf_ver: ["latest"]
|
||||
idf_target: ["esp32c3"]
|
||||
test: [ { app: pppd, path: test/target }, { app: sim800, path: examples/pppos_client } ]
|
||||
runs-on: ubuntu-20.04
|
||||
container: espressif/idf:${{ matrix.idf_ver }}
|
||||
env:
|
||||
TEST_DIR: components/esp_modem/${{ matrix.test.path }}
|
||||
steps:
|
||||
- name: Checkout esp-protocols
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
submodules: recursive
|
||||
- name: Build esp-modem target tests with IDF-${{ matrix.idf_ver }} for ${{ matrix.idf_target }}
|
||||
env:
|
||||
IDF_TARGET: ${{ matrix.idf_target }}
|
||||
SDKCONFIG: sdkconfig.ci.${{ matrix.test.app }}
|
||||
shell: bash
|
||||
working-directory: ${{ env.TEST_DIR }}
|
||||
run: |
|
||||
. ${IDF_PATH}/export.sh
|
||||
rm -rf sdkconfig build
|
||||
[ -f ${SDKCONFIG} ] && cp ${SDKCONFIG} sdkconfig.defaults
|
||||
idf.py set-target ${{ matrix.idf_target }}
|
||||
idf.py build
|
||||
$GITHUB_WORKSPACE/ci/clean_build_artifacts.sh ${GITHUB_WORKSPACE}/${TEST_DIR}/build
|
||||
ls build
|
||||
- uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: modem_target_bin_${{ matrix.idf_target }}_${{ matrix.idf_ver }}_${{ matrix.test.app }}
|
||||
path: ${{ env.TEST_DIR }}/build
|
||||
if-no-files-found: error
|
||||
|
||||
run_esp_modem_tests:
|
||||
strategy:
|
||||
matrix:
|
||||
idf_ver: ["latest"]
|
||||
idf_target: ["esp32c3"]
|
||||
test: [ { app: pppd, path: test/target }, { app: sim800, path: examples/pppos_client } ]
|
||||
name: Run esp_modem Test on target
|
||||
needs: build_esp_modem_tests
|
||||
runs-on:
|
||||
- self-hosted
|
||||
- BrnoRPI-GH006
|
||||
env:
|
||||
TEST_DIR: components/esp_modem/${{ matrix.test.path }}
|
||||
# Skip running on forks since it won't have access to secrets
|
||||
if: github.repository == 'espressif/esp-protocols'
|
||||
steps:
|
||||
- name: Clear repository
|
||||
run: sudo rm -fr $GITHUB_WORKSPACE && mkdir $GITHUB_WORKSPACE
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/download-artifact@v2
|
||||
with:
|
||||
name: modem_target_bin_${{ matrix.idf_target }}_${{ matrix.idf_ver }}_${{ matrix.test.app }}
|
||||
path: ${{ env.TEST_DIR }}/build
|
||||
- name: Run Example Test on target
|
||||
working-directory: ${{ env.TEST_DIR }}
|
||||
run: |
|
||||
python -m pytest --log-cli-level DEBUG --target=${{ matrix.idf_target }}
|
||||
|
7
ci/clean_build_artifacts.sh
Executable file
7
ci/clean_build_artifacts.sh
Executable file
@ -0,0 +1,7 @@
|
||||
# Remove everything, but
|
||||
# - elf/bin files in the build dir
|
||||
# - partition-table and bootloader binaries
|
||||
# - flasher args
|
||||
# - sdkconfigs (header and json)
|
||||
# (Ignoring the command failure as it refuses to delete nonempty dirs)
|
||||
find $1 ! -regex ".*/build/[^/]+.\(bin\|elf\)" -a ! -regex ".*\(bootloader\|partition-table\).bin" -a ! -name "flasher_args.json" -a ! -regex ".*/build/config/sdkconfig.\(h\|json\)" -delete || true
|
@ -5,3 +5,4 @@ SimpleWebSocketServer
|
||||
dpkt
|
||||
pytest
|
||||
idf_build_apps
|
||||
netifaces
|
||||
|
@ -0,0 +1,24 @@
|
||||
# SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
|
||||
# SPDX-License-Identifier: Unlicense OR CC0-1.0
|
||||
from __future__ import print_function, unicode_literals
|
||||
|
||||
|
||||
def test_pppos_connect(dut):
|
||||
"""
|
||||
steps:
|
||||
1. initializes connection with SIM800
|
||||
2. checks we get an IP
|
||||
3. checks for the MQTT events
|
||||
4. checks that the client cleanly disconnects
|
||||
"""
|
||||
# Check the sequence of connecting, publishing, disconnecting
|
||||
dut.expect('Modem Connect to PPP Server')
|
||||
# Check for MQTT connection and the data event
|
||||
dut.expect('MQTT_EVENT_CONNECTED')
|
||||
dut.expect('MQTT_EVENT_DATA')
|
||||
dut.expect('TOPIC=/topic/esp-pppos')
|
||||
dut.expect('DATA=esp32-pppos')
|
||||
# Check that we have disconnected
|
||||
dut.expect('User interrupted event')
|
||||
# And can use commands again
|
||||
dut.expect('IMSI=[0-9]+')
|
@ -0,0 +1,13 @@
|
||||
# Override some defaults to enable PPP
|
||||
CONFIG_LWIP_PPP_SUPPORT=y
|
||||
CONFIG_LWIP_PPP_NOTIFY_PHASE_SUPPORT=y
|
||||
CONFIG_LWIP_PPP_PAP_SUPPORT=y
|
||||
CONFIG_LWIP_TCPIP_TASK_STACK_SIZE=4096
|
||||
CONFIG_LWIP_PPP_ENABLE_IPV6=n
|
||||
CONFIG_EXAMPLE_MODEM_UART_TX_PIN=4
|
||||
CONFIG_EXAMPLE_MODEM_UART_RX_PIN=5
|
||||
CONFIG_EXAMPLE_MODEM_DEVICE_SIM800=y
|
||||
CONFIG_EXAMPLE_MODEM_DEVICE_BG96=n
|
||||
CONFIG_EXAMPLE_MODEM_PPP_APN="lpwa.vodafone.com"
|
||||
CONFIG_ESP_SYSTEM_PANIC_PRINT_HALT=y
|
||||
CONFIG_ESP32_PANIC_PRINT_HALT=y
|
@ -8,3 +8,5 @@ set_target_properties(${COMPONENT_LIB} PROPERTIES
|
||||
CXX_STANDARD_REQUIRED ON
|
||||
CXX_EXTENSIONS ON
|
||||
)
|
||||
|
||||
target_compile_options(${COMPONENT_LIB} PRIVATE "-Wno-format")
|
||||
|
@ -1,26 +1,38 @@
|
||||
menu "Example Configuration"
|
||||
menu "Test App Configuration"
|
||||
|
||||
config ESP_WIFI_SSID
|
||||
string "WiFi SSID"
|
||||
default "myssid"
|
||||
config TEST_APP_PPP_SERVER_IP
|
||||
string "IP address of PPP server"
|
||||
default "10.0.0.1"
|
||||
help
|
||||
SSID (network name) for the example to connect to.
|
||||
IP address of PPP server. Note: this is also the address
|
||||
where the TCP server is started to test the connection
|
||||
|
||||
config ESP_WIFI_PASSWORD
|
||||
string "WiFi Password"
|
||||
default "mypassword"
|
||||
config TEST_APP_PPP_CLIENT_IP
|
||||
string "IP address of PPP client"
|
||||
default "10.0.0.2"
|
||||
help
|
||||
WiFi password (WPA or WPA2) for the example to use.
|
||||
config ESP_WIFI_CHANNEL
|
||||
int "WiFi Channel"
|
||||
range 1 13
|
||||
default 1
|
||||
help
|
||||
WiFi channel (network channel) for the example to use.
|
||||
IP address that PPP server assigns to PPP client.
|
||||
|
||||
config ESP_MAX_STA_CONN
|
||||
int "Maximal STA connections"
|
||||
default 4
|
||||
config TEST_APP_UART_TX_PIN
|
||||
int "TXD Pin Number"
|
||||
default 6
|
||||
range 0 31
|
||||
help
|
||||
Max number of the STA connects to AP.
|
||||
Pin number of UART TX.
|
||||
|
||||
config TEST_APP_UART_RX_PIN
|
||||
int "RXD Pin Number"
|
||||
default 7
|
||||
range 0 31
|
||||
help
|
||||
Pin number of UART RX.
|
||||
|
||||
config TEST_APP_TCP_PORT
|
||||
int "Port of test"
|
||||
range 0 65535
|
||||
default 2222
|
||||
help
|
||||
The remote port to which the client will connects to
|
||||
once the PPP connection established
|
||||
|
||||
endmenu
|
||||
|
@ -60,6 +60,8 @@ public:
|
||||
{
|
||||
// configure
|
||||
esp_modem_dte_config_t dte_config = ESP_MODEM_DTE_DEFAULT_CONFIG();
|
||||
dte_config.uart_config.tx_io_num = CONFIG_TEST_APP_UART_TX_PIN;
|
||||
dte_config.uart_config.rx_io_num = CONFIG_TEST_APP_UART_RX_PIN;
|
||||
esp_modem_dce_config dce_config = ESP_MODEM_DCE_DEFAULT_CONFIG("");
|
||||
|
||||
// create DTE and minimal network DCE
|
||||
@ -96,6 +98,7 @@ esp_err_t modem_init_network(esp_netif_t *netif)
|
||||
esp_err_t modem_start_network()
|
||||
{
|
||||
NetModule::start();
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
void modem_stop_network()
|
||||
|
83
components/esp_modem/test/target/pytest_pppd.py
Normal file
83
components/esp_modem/test/target/pytest_pppd.py
Normal file
@ -0,0 +1,83 @@
|
||||
# SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
|
||||
# SPDX-License-Identifier: Unlicense OR CC0-1.0
|
||||
from __future__ import print_function, unicode_literals
|
||||
|
||||
import subprocess
|
||||
import time
|
||||
from threading import Event, Thread
|
||||
|
||||
import netifaces
|
||||
|
||||
|
||||
def run_server(server_stop, port, server_ip, client_ip):
|
||||
print('Starting PPP server on port: {}'.format(port))
|
||||
try:
|
||||
arg_list = [
|
||||
'sudo', 'pppd', port, '115200',
|
||||
'{}:{}'.format(server_ip, client_ip), 'modem', 'local', 'noauth',
|
||||
'debug', 'nocrtscts', 'nodetach', '+ipv6'
|
||||
]
|
||||
p = subprocess.Popen(arg_list, stdout=subprocess.PIPE, bufsize=1)
|
||||
while not server_stop.is_set():
|
||||
if p.poll() is not None:
|
||||
if p.poll() == 16:
|
||||
print('[PPPD:] Terminated: hang-up received')
|
||||
break
|
||||
else:
|
||||
raise ValueError(
|
||||
'ENV_TEST_FAILURE: PPP terminated unexpectedly with {}'
|
||||
.format(p.poll()))
|
||||
line = p.stdout.readline()
|
||||
if line:
|
||||
print('[PPPD:]{}'.format(line.rstrip()))
|
||||
time.sleep(0.1)
|
||||
except Exception as e:
|
||||
print(e)
|
||||
raise ValueError('ENV_TEST_FAILURE: Error running PPP server')
|
||||
finally:
|
||||
p.terminate()
|
||||
print('PPP server stopped')
|
||||
|
||||
|
||||
def test_examples_protocol_pppos_connect(dut):
|
||||
"""
|
||||
steps:
|
||||
1. starts PPP server
|
||||
2. get DUT as PPP client to connect to the server
|
||||
3. run unit test FW
|
||||
"""
|
||||
|
||||
# Look for test case symbolic names
|
||||
try:
|
||||
server_ip = dut.app.sdkconfig.get('TEST_APP_PPP_SERVER_IP')
|
||||
client_ip = dut.app.sdkconfig.get('TEST_APP_PPP_CLIENT_IP')
|
||||
except Exception:
|
||||
print(
|
||||
'ENV_TEST_FAILURE: Some mandatory configuration not found in sdkconfig'
|
||||
)
|
||||
raise
|
||||
|
||||
# the PPP test env uses two ttyUSB's: one for ESP32 board, another one for ppp server
|
||||
# use the other port for PPP server than the DUT/ESP
|
||||
port = '/dev/ttyUSB0' if dut.serial.port == '/dev/ttyUSB1' else '/dev/ttyUSB1'
|
||||
# Start the PPP server
|
||||
server_stop = Event()
|
||||
t = Thread(target=run_server,
|
||||
args=(server_stop, port, server_ip, client_ip))
|
||||
t.start()
|
||||
try:
|
||||
ppp_server_timeout = time.time() + 30
|
||||
while 'ppp0' not in netifaces.interfaces():
|
||||
print(
|
||||
"PPP server haven't yet setup its netif, list of active netifs:{}"
|
||||
.format(netifaces.interfaces()))
|
||||
time.sleep(0.5)
|
||||
if time.time() > ppp_server_timeout:
|
||||
raise ValueError(
|
||||
'ENV_TEST_FAILURE: PPP server failed to setup ppp0 interface within timeout'
|
||||
)
|
||||
|
||||
dut.expect('All tests passed')
|
||||
finally:
|
||||
server_stop.set()
|
||||
t.join()
|
@ -1,3 +1,4 @@
|
||||
CONFIG_COMPILER_CXX_EXCEPTIONS=y
|
||||
CONFIG_CXX_EXCEPTIONS=y
|
||||
CONFIG_PPP_SUPPORT=y
|
||||
CONFIG_ESP_MAIN_TASK_STACK_SIZE=4096
|
||||
|
Reference in New Issue
Block a user