mirror of
https://github.com/espressif/esp-protocols.git
synced 2025-07-20 05:52:22 +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:
|
build_esp_modem:
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
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"]
|
example: ["pppos_client", "modem_console", "ap_to_pppos", "simple_cmux_client"]
|
||||||
idf_target: ["esp32"]
|
idf_target: ["esp32"]
|
||||||
exclude:
|
exclude:
|
||||||
@ -310,3 +310,66 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
name: examples_results_${{ matrix.idf_target }}_${{ matrix.idf_ver }}_${{ matrix.example }}
|
name: examples_results_${{ matrix.idf_target }}_${{ matrix.idf_ver }}_${{ matrix.example }}
|
||||||
path: components/asio/examples/${{ matrix.example }}/*.xml
|
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
|
dpkt
|
||||||
pytest
|
pytest
|
||||||
idf_build_apps
|
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_STANDARD_REQUIRED ON
|
||||||
CXX_EXTENSIONS 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
|
config TEST_APP_PPP_SERVER_IP
|
||||||
string "WiFi SSID"
|
string "IP address of PPP server"
|
||||||
default "myssid"
|
default "10.0.0.1"
|
||||||
help
|
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
|
config TEST_APP_PPP_CLIENT_IP
|
||||||
string "WiFi Password"
|
string "IP address of PPP client"
|
||||||
default "mypassword"
|
default "10.0.0.2"
|
||||||
help
|
help
|
||||||
WiFi password (WPA or WPA2) for the example to use.
|
IP address that PPP server assigns to PPP client.
|
||||||
config ESP_WIFI_CHANNEL
|
|
||||||
int "WiFi Channel"
|
|
||||||
range 1 13
|
|
||||||
default 1
|
|
||||||
help
|
|
||||||
WiFi channel (network channel) for the example to use.
|
|
||||||
|
|
||||||
config ESP_MAX_STA_CONN
|
config TEST_APP_UART_TX_PIN
|
||||||
int "Maximal STA connections"
|
int "TXD Pin Number"
|
||||||
default 4
|
default 6
|
||||||
|
range 0 31
|
||||||
help
|
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
|
endmenu
|
||||||
|
@ -60,6 +60,8 @@ public:
|
|||||||
{
|
{
|
||||||
// configure
|
// configure
|
||||||
esp_modem_dte_config_t dte_config = ESP_MODEM_DTE_DEFAULT_CONFIG();
|
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("");
|
esp_modem_dce_config dce_config = ESP_MODEM_DCE_DEFAULT_CONFIG("");
|
||||||
|
|
||||||
// create DTE and minimal network DCE
|
// 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()
|
esp_err_t modem_start_network()
|
||||||
{
|
{
|
||||||
NetModule::start();
|
NetModule::start();
|
||||||
|
return ESP_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
void modem_stop_network()
|
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_COMPILER_CXX_EXCEPTIONS=y
|
||||||
CONFIG_CXX_EXCEPTIONS=y
|
CONFIG_CXX_EXCEPTIONS=y
|
||||||
CONFIG_PPP_SUPPORT=y
|
CONFIG_PPP_SUPPORT=y
|
||||||
|
CONFIG_ESP_MAIN_TASK_STACK_SIZE=4096
|
||||||
|
Reference in New Issue
Block a user