tools/idf_monitor: add WebSocket client for IDE integration

This commit is contained in:
Roland Dobai
2020-05-28 14:47:38 +02:00
committed by bot
parent 5c783e60e1
commit e67314f646
9 changed files with 269 additions and 28 deletions

View File

@@ -0,0 +1,4 @@
cmake_minimum_required(VERSION 3.5)
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
project(panic)

View File

@@ -0,0 +1,90 @@
from __future__ import unicode_literals
from SimpleWebSocketServer import SimpleWebSocketServer, WebSocket
from tiny_test_fw import Utility
import glob
import json
import os
import re
import threading
import ttfw_idf
class IDEWSProtocol(WebSocket):
def handleMessage(self):
try:
j = json.loads(self.data)
except Exception as e:
Utility.console_log('Server ignores error: {}'.format(e), 'orange')
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))
Utility.console_log('Server sent: {}'.format(payload))
else:
Utility.console_log('Server received: {}'.format(j), 'orange')
def handleConnected(self):
Utility.console_log('{} connected to server'.format(self.address))
def handleClose(self):
Utility.console_log('{} closed the connection'.format(self.address))
class WebSocketServer(object):
HOST = '127.0.0.1'
PORT = 1123
def run(self):
server = SimpleWebSocketServer(self.HOST, self.PORT, IDEWSProtocol)
while not self.exit_event.is_set():
server.serveonce()
def __init__(self):
self.exit_event = threading.Event()
self.thread = threading.Thread(target=self.run)
self.thread.start()
def __enter__(self):
return self
def __exit__(self, exc_type, exc_value, traceback):
self.exit_event.set()
self.thread.join(10)
if self.thread.is_alive():
Utility.console_log('Thread cannot be joined', 'orange')
@ttfw_idf.idf_custom_test(env_tag='test_jtag_arm', group='test-apps')
def test_monitor_ide_integration(env, extra_data):
config_files = glob.glob(os.path.join(os.path.dirname(__file__), 'sdkconfig.ci.*'))
config_names = [os.path.basename(s).replace('sdkconfig.ci.', '') for s in config_files]
rel_proj_path = 'tools/test_apps/system/monitor_ide_integration'
for name in config_names:
Utility.console_log('Checking config "{}"... '.format(name), 'green', end='')
dut = env.get_dut('panic', rel_proj_path, app_config_name=name)
monitor_path = os.path.join(dut.app.get_sdk_path(), 'tools/idf_monitor.py')
elf_path = os.path.join(dut.app.get_binary_path(rel_proj_path), 'panic.elf')
dut.start_app()
# Closing the DUT because we will reconnect with IDF Monitor
env.close_dut(dut.name)
with WebSocketServer(), ttfw_idf.CustomProcess(' '.join([monitor_path,
elf_path,
'--ws', 'ws://{}:{}'.format(WebSocketServer.HOST,
WebSocketServer.PORT)]),
logfile='monitor_{}.log'.format(name)) as p:
p.pexpect_proc.expect(re.compile(r'Guru Meditation Error'), timeout=10)
p.pexpect_proc.expect_exact('Communicating through WebSocket', timeout=5)
# "u?" is for Python 2 only in the following regular expressions.
# The elements of dictionary can be printed in different order depending on the Python version.
p.pexpect_proc.expect(re.compile(r"WebSocket sent: \{u?.*'event': u?'" + name + "'"), timeout=5)
p.pexpect_proc.expect_exact('Waiting for debug finished event', timeout=5)
p.pexpect_proc.expect(re.compile(r"WebSocket received: \{u?'event': u?'debug_finished'\}"), timeout=5)
p.pexpect_proc.expect_exact('Communications through WebSocket is finished', timeout=5)
if __name__ == '__main__':
test_monitor_ide_integration()

View File

@@ -0,0 +1,2 @@
idf_component_register(SRCS "main.c"
INCLUDE_DIRS "")

View File

@@ -0,0 +1,18 @@
/* 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(1000 / portTICK_PERIOD_MS);
*p = 0;
}

View File

@@ -0,0 +1 @@
CONFIG_ESP32_ENABLE_COREDUMP_TO_UART=y

View File

@@ -0,0 +1 @@
CONFIG_ESP_SYSTEM_PANIC_GDBSTUB=y