mirror of
https://github.com/espressif/esp-idf.git
synced 2024-10-05 20:47:46 -04:00
feat(tools/monitor): move target tests to monitor repo
This commit is contained in:
parent
a9349f4ad4
commit
3981aae79f
@ -1336,7 +1336,6 @@ tools/test_apps/system/cxx_no_except/main/main.cpp
|
||||
tools/test_apps/system/gdb_loadable_elf/main/hello_world_main.c
|
||||
tools/test_apps/system/longjmp_test/main/hello_world_main.c
|
||||
tools/test_apps/system/memprot/main/esp32s2/test_memprot_main.c
|
||||
tools/test_apps/system/monitor_ide_integration/main/main.c
|
||||
tools/test_apps/system/no_embedded_paths/check_for_file_paths.py
|
||||
tools/test_apps/system/no_embedded_paths/main/test_no_embedded_paths_main.c
|
||||
tools/test_apps/system/startup/main/test_startup_main.c
|
||||
|
@ -22,6 +22,3 @@ pygobject; sys_platform != 'win32'
|
||||
# esp_prov
|
||||
bleak
|
||||
protobuf
|
||||
|
||||
# tools/test_apps/system/monitor_ide_integration
|
||||
SimpleWebSocketServer
|
||||
|
@ -136,16 +136,6 @@ tools/test_apps/system/memprot:
|
||||
temporary: true
|
||||
reason: the other targets are not tested yet
|
||||
|
||||
tools/test_apps/system/monitor_ide_integration:
|
||||
enable:
|
||||
- if: IDF_TARGET == "esp32" or IDF_TARGET == "esp32s2"
|
||||
temporary: true
|
||||
reason: the other targets are not tested yet
|
||||
disable_test:
|
||||
- if: IDF_TARGET == "esp32s2"
|
||||
temporary: true
|
||||
reason: lack of runners
|
||||
|
||||
tools/test_apps/system/no_embedded_paths:
|
||||
enable:
|
||||
- if: IDF_TARGET in ["esp32", "esp32c3", "esp32s2"]
|
||||
|
@ -1,5 +0,0 @@
|
||||
cmake_minimum_required(VERSION 3.16)
|
||||
|
||||
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
|
||||
set(COMPONENTS main)
|
||||
project(monitor_addr_lookup)
|
@ -1,2 +0,0 @@
|
||||
| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 |
|
||||
| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- | -------- |
|
@ -1,2 +0,0 @@
|
||||
idf_component_register(SRCS "main.c"
|
||||
INCLUDE_DIRS "")
|
@ -1,7 +0,0 @@
|
||||
config TEST_ADDR_LOOKUP_IN_APP
|
||||
bool "TEST_ADDR_LOOKUP_IN_APP"
|
||||
default n
|
||||
|
||||
config TEST_ADDR_LOOKUP_IN_ROM
|
||||
bool "TEST_ADDR_LOOKUP_IN_ROM"
|
||||
default n
|
@ -1,54 +0,0 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Unlicense OR CC0-1.0
|
||||
*/
|
||||
#include <time.h>
|
||||
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
|
||||
#if CONFIG_TEST_ADDR_LOOKUP_IN_APP
|
||||
static volatile bool s_initialization_done = false;
|
||||
|
||||
static void initialize(void)
|
||||
{
|
||||
srand(time(0));
|
||||
}
|
||||
|
||||
static int get_random_number(void)
|
||||
{
|
||||
if (!s_initialization_done) {
|
||||
initialize();
|
||||
s_initialization_done = true;
|
||||
}
|
||||
return rand();
|
||||
}
|
||||
#endif // CONFIG_TEST_ADDR_LOOKUP_IN_APP
|
||||
|
||||
void app_main(void)
|
||||
{
|
||||
printf("app_main is running from 0x%x\n", (int) app_main);
|
||||
|
||||
#if CONFIG_TEST_ADDR_LOOKUP_IN_APP
|
||||
volatile int number = get_random_number();
|
||||
int *n = malloc(sizeof(int));
|
||||
|
||||
assert(n);
|
||||
|
||||
*n = number;
|
||||
|
||||
printf("Initializer function at 0x%x\n", (int) initialize);
|
||||
printf("Got %d stored at 0x%x and 0x%x from a function from 0x%x\n", *n, (int) n, (int) (&number), (int) get_random_number);
|
||||
printf("This is the end of the report\n");
|
||||
|
||||
free(n);
|
||||
#endif // CONFIG_TEST_ADDR_LOOKUP_IN_APP
|
||||
|
||||
#if CONFIG_TEST_ADDR_LOOKUP_IN_ROM
|
||||
printf("Crashing now!\n");
|
||||
|
||||
esp_rom_install_channel_putc(1, (void (*)(char)) abort);
|
||||
esp_rom_printf("a");
|
||||
#endif // CONFIG_TEST_ADDR_LOOKUP_IN_ROM
|
||||
}
|
@ -1,60 +0,0 @@
|
||||
# SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
|
||||
# SPDX-License-Identifier: Unlicense OR CC0-1.0
|
||||
import os
|
||||
import re
|
||||
import sys
|
||||
|
||||
import pexpect
|
||||
import pytest
|
||||
from pytest_embedded import Dut
|
||||
|
||||
|
||||
@pytest.mark.generic
|
||||
@pytest.mark.supported_targets
|
||||
@pytest.mark.parametrize('config', [
|
||||
'addr_lookup_in_app',
|
||||
'addr_lookup_in_ROM',
|
||||
], indirect=True)
|
||||
def test_monitor_addr_lookup(config: str, dut: Dut) -> None:
|
||||
# The port needs to be closed because esp_idf_monitor will connect to it
|
||||
dut.serial.stop_redirect_thread()
|
||||
|
||||
monitor_cmd = ' '.join([sys.executable, '-m', 'esp_idf_monitor', os.path.join(dut.app.binary_path, 'monitor_addr_lookup.elf'),
|
||||
'--port', str(dut.serial.port)])
|
||||
monitor_log_path = os.path.join(dut.logdir, 'monitor.txt')
|
||||
|
||||
with open(monitor_log_path, 'w') as log, pexpect.spawn(monitor_cmd, logfile=log, timeout=5, encoding='utf-8', codec_errors='ignore') as p:
|
||||
p.expect_exact('main_task: Calling app_main()')
|
||||
|
||||
ADDRESS = r'0x[a-f0-9]{8}'
|
||||
FUNC_NAME = r'[a-zA-Z_][\w]*'
|
||||
|
||||
p.expect(re.compile(rf'app_main is running from ({ADDRESS})'))
|
||||
addr = p.match.group(1)
|
||||
p.expect_exact(f'{addr}: app_main at')
|
||||
|
||||
if config == 'addr_lookup_in_app':
|
||||
p.expect(re.compile(rf'Initializer function at ({ADDRESS})'))
|
||||
addr = p.match.group(1)
|
||||
p.expect_exact(f'{addr}: initialize at')
|
||||
|
||||
p.expect(re.compile(rf'Got \d+ stored at ({ADDRESS}) and ({ADDRESS}) from a function from ({ADDRESS})'))
|
||||
var1 = p.match.group(1)
|
||||
var2 = p.match.group(2)
|
||||
func = p.match.group(3)
|
||||
match_index = p.expect([str(var1), str(var2), pexpect.TIMEOUT])
|
||||
assert match_index == 2 # should be TIMEOUT because addr2line should not match addresses of variables
|
||||
p.expect_exact(f'{func}: get_random_number at')
|
||||
|
||||
p.expect_exact('This is the end of the report')
|
||||
|
||||
elif config == 'addr_lookup_in_ROM':
|
||||
p.expect_exact('Crashing now!')
|
||||
|
||||
p.expect(re.compile(rf'abort\(\) was called at PC ({ADDRESS}) on core 0'))
|
||||
addr = p.match.group(1)
|
||||
p.expect_exact(f'abort() was called at PC {addr} on core 0')
|
||||
|
||||
p.expect(re.compile(rf'({ADDRESS}): ({FUNC_NAME}) in ROM'))
|
||||
addr, func = p.match.group(1), p.match.group(2)
|
||||
p.expect_exact(f'{addr}: {func} in ROM')
|
@ -1 +0,0 @@
|
||||
CONFIG_TEST_ADDR_LOOKUP_IN_ROM=y
|
@ -1 +0,0 @@
|
||||
CONFIG_TEST_ADDR_LOOKUP_IN_APP=y
|
@ -1,5 +0,0 @@
|
||||
cmake_minimum_required(VERSION 3.16)
|
||||
|
||||
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
|
||||
set(COMPONENTS main esp_gdbstub espcoredump)
|
||||
project(panic)
|
@ -1,2 +0,0 @@
|
||||
| Supported Targets | ESP32 | ESP32-S2 |
|
||||
| ----------------- | ----- | -------- |
|
@ -1,2 +0,0 @@
|
||||
idf_component_register(SRCS "main.c"
|
||||
INCLUDE_DIRS "")
|
@ -1,18 +0,0 @@
|
||||
/* Monitor-IDE integration test
|
||||
|
||||
This example code is in the Public Domain (or CC0 licensed, at your option.)
|
||||
|
||||
Unless required by applicable law or agreed to in writing, this
|
||||
software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
CONDITIONS OF ANY KIND, either express or implied.
|
||||
*/
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "esp_system.h"
|
||||
|
||||
void app_main(void)
|
||||
{
|
||||
int *p = (int *)4;
|
||||
vTaskDelay(2000 / portTICK_PERIOD_MS);
|
||||
*p = 0;
|
||||
}
|
@ -1,92 +0,0 @@
|
||||
# SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
|
||||
# SPDX-License-Identifier: Unlicense OR CC0-1.0
|
||||
import json
|
||||
import logging
|
||||
import multiprocessing
|
||||
import os
|
||||
import re
|
||||
import sys
|
||||
from types import TracebackType
|
||||
from typing import Optional, Type, TypeVar
|
||||
|
||||
import pexpect
|
||||
import pytest
|
||||
from pytest_embedded import Dut
|
||||
from SimpleWebSocketServer import SimpleWebSocketServer, WebSocket
|
||||
|
||||
WebSocketServerType = TypeVar('WebSocketServerType')
|
||||
|
||||
|
||||
class IDEWSProtocol(WebSocket):
|
||||
|
||||
def handleMessage(self) -> None:
|
||||
try:
|
||||
j = json.loads(self.data)
|
||||
except Exception as e:
|
||||
logging.info(f'Server ignores error: {e}')
|
||||
return
|
||||
event = j.get('event')
|
||||
if event and 'prog' in j and ((event == 'gdb_stub' and 'port' in j) or
|
||||
(event == 'coredump' and 'file' in j)):
|
||||
payload = {'event': 'debug_finished'}
|
||||
self.sendMessage(json.dumps(payload))
|
||||
logging.info(f'Server sent: {payload}')
|
||||
else:
|
||||
logging.info(f'Server received: {j}')
|
||||
|
||||
def handleConnected(self) -> None:
|
||||
logging.info(f'{self.address} connected to server')
|
||||
|
||||
def handleClose(self) -> None:
|
||||
logging.info(f'{self.address} closed the connection')
|
||||
|
||||
|
||||
class WebSocketServer(object):
|
||||
HOST = '127.0.0.1'
|
||||
PORT = 1123
|
||||
|
||||
def run(self) -> None:
|
||||
server = SimpleWebSocketServer(self.HOST, self.PORT, IDEWSProtocol)
|
||||
while not self.exit_event.is_set():
|
||||
server.serveonce()
|
||||
|
||||
def __init__(self) -> None:
|
||||
self.exit_event = multiprocessing.Event()
|
||||
self.proc = multiprocessing.Process(target=self.run)
|
||||
self.proc.start()
|
||||
|
||||
def __enter__(self: WebSocketServerType) -> WebSocketServerType:
|
||||
return self
|
||||
|
||||
def __exit__(self, exc_type: Optional[Type[BaseException]], exc_value: Optional[BaseException], traceback:
|
||||
Optional[TracebackType]) -> None:
|
||||
self.exit_event.set()
|
||||
self.proc.join(10)
|
||||
if self.proc.is_alive():
|
||||
logging.info('Process cannot be joined')
|
||||
|
||||
|
||||
@pytest.mark.esp32
|
||||
@pytest.mark.generic
|
||||
@pytest.mark.parametrize('config', ['gdb_stub', 'coredump'], indirect=True)
|
||||
def test_monitor_ide_integration(config: str, dut: Dut) -> None:
|
||||
# The port needs to be closed because esp_idf_monitor will connect to it
|
||||
dut.serial.stop_redirect_thread()
|
||||
|
||||
monitor_cmd = ' '.join([sys.executable, '-m', 'esp_idf_monitor', os.path.join(dut.app.binary_path, 'panic.elf'),
|
||||
'--port', str(dut.serial.port),
|
||||
'--ws', f'ws://{WebSocketServer.HOST}:{WebSocketServer.PORT}'])
|
||||
monitor_log_path = os.path.join(dut.logdir, 'monitor.txt')
|
||||
|
||||
with open(monitor_log_path, 'w') as log, WebSocketServer(), pexpect.spawn(monitor_cmd,
|
||||
logfile=log,
|
||||
timeout=5,
|
||||
encoding='utf-8',
|
||||
codec_errors='ignore') as p:
|
||||
p.expect(re.compile(r'Guru Meditation Error'), timeout=10)
|
||||
p.expect_exact('Communicating through WebSocket')
|
||||
# The elements of dictionary can be printed in different order depending on the Python version.
|
||||
p.expect(re.compile(r"WebSocket sent: \{.*'event': '" + config + "'"))
|
||||
p.expect_exact('Waiting for debug finished event')
|
||||
p.expect(re.compile(r"WebSocket received: \{'event': 'debug_finished'\}"))
|
||||
p.expect_exact('Communications through WebSocket is finished')
|
@ -1 +0,0 @@
|
||||
CONFIG_ESP_COREDUMP_ENABLE_TO_UART=y
|
@ -1 +0,0 @@
|
||||
CONFIG_ESP_SYSTEM_PANIC_GDBSTUB=y
|
Loading…
Reference in New Issue
Block a user