From f80824a2d8c529ad11c95546421830c208cca0b9 Mon Sep 17 00:00:00 2001 From: houchenyao Date: Wed, 20 Sep 2017 17:17:51 +0800 Subject: [PATCH] test: support test for UT cases expect to reset --- components/esp32/panic.c | 81 ++++++++++++------- components/esp32/test/test_exception.c | 9 +++ components/esp32/test/test_restart.c | 10 +-- components/esp32/test/test_sleep.c | 14 ++-- .../TestCaseScript/IDFUnitTest/UnitTest.py | 43 ++++++---- tools/unit-test-app/tools/TagDefinition.yml | 3 + tools/unit-test-app/tools/UnitTestParser.py | 2 + 7 files changed, 103 insertions(+), 59 deletions(-) create mode 100644 components/esp32/test/test_exception.c diff --git a/components/esp32/panic.c b/components/esp32/panic.c index 906e1ee36..d09257268 100644 --- a/components/esp32/panic.c +++ b/components/esp32/panic.c @@ -129,14 +129,14 @@ static __attribute__((noreturn)) inline void invoke_abort() SEGGER_RTT_ESP32_FlushNoLock(CONFIG_ESP32_APPTRACE_POSTMORTEM_FLUSH_TRAX_THRESH, APPTRACE_ONPANIC_HOST_FLUSH_TMO); #else esp_apptrace_flush_nolock(ESP_APPTRACE_DEST_TRAX, CONFIG_ESP32_APPTRACE_POSTMORTEM_FLUSH_TRAX_THRESH, - APPTRACE_ONPANIC_HOST_FLUSH_TMO); + APPTRACE_ONPANIC_HOST_FLUSH_TMO); #endif #endif - while(1) { + while (1) { if (esp_cpu_in_ocd_debug_mode()) { __asm__ ("break 0,0"); } - *((int*) 0) = 0; + *((int *) 0) = 0; } } @@ -221,13 +221,17 @@ void panicHandler(XtExcFrame *frame) int debugRsn; asm("rsr.debugcause %0":"=r"(debugRsn)); panicPutStr("Debug exception reason: "); - if (debugRsn&XCHAL_DEBUGCAUSE_ICOUNT_MASK) panicPutStr("SingleStep "); - if (debugRsn&XCHAL_DEBUGCAUSE_IBREAK_MASK) panicPutStr("HwBreakpoint "); - if (debugRsn&XCHAL_DEBUGCAUSE_DBREAK_MASK) { + if (debugRsn & XCHAL_DEBUGCAUSE_ICOUNT_MASK) { + panicPutStr("SingleStep "); + } + if (debugRsn & XCHAL_DEBUGCAUSE_IBREAK_MASK) { + panicPutStr("HwBreakpoint "); + } + if (debugRsn & XCHAL_DEBUGCAUSE_DBREAK_MASK) { //Unlike what the ISA manual says, this core seemingly distinguishes from a DBREAK //reason caused by watchdog 0 and one caused by watchdog 1 by setting bit 8 of the //debugcause if the cause is watchdog 1 and clearing it if it's watchdog 0. - if (debugRsn&(1<<8)) { + if (debugRsn & (1 << 8)) { #if CONFIG_FREERTOS_WATCHPOINT_END_OF_STACK const char *name = pcTaskGetTaskName(xTaskGetCurrentTaskHandleForCPU(core_id)); panicPutStr("Stack canary watchpoint triggered ("); @@ -239,10 +243,16 @@ void panicHandler(XtExcFrame *frame) } else { panicPutStr("Watchpoint 0 triggered "); } - } - if (debugRsn&XCHAL_DEBUGCAUSE_BREAK_MASK) panicPutStr("BREAK instr "); - if (debugRsn&XCHAL_DEBUGCAUSE_BREAKN_MASK) panicPutStr("BREAKN instr "); - if (debugRsn&XCHAL_DEBUGCAUSE_DEBUGINT_MASK) panicPutStr("DebugIntr "); + } + if (debugRsn & XCHAL_DEBUGCAUSE_BREAK_MASK) { + panicPutStr("BREAK instr "); + } + if (debugRsn & XCHAL_DEBUGCAUSE_BREAKN_MASK) { + panicPutStr("BREAKN instr "); + } + if (debugRsn & XCHAL_DEBUGCAUSE_DEBUGINT_MASK) { + panicPutStr("DebugIntr "); + } panicPutStr("\r\n"); } @@ -252,7 +262,7 @@ void panicHandler(XtExcFrame *frame) SEGGER_RTT_ESP32_FlushNoLock(CONFIG_ESP32_APPTRACE_POSTMORTEM_FLUSH_TRAX_THRESH, APPTRACE_ONPANIC_HOST_FLUSH_TMO); #else esp_apptrace_flush_nolock(ESP_APPTRACE_DEST_TRAX, CONFIG_ESP32_APPTRACE_POSTMORTEM_FLUSH_TRAX_THRESH, - APPTRACE_ONPANIC_HOST_FLUSH_TMO); + APPTRACE_ONPANIC_HOST_FLUSH_TMO); #endif #endif setFirstBreakpoint(frame->pc); @@ -266,15 +276,16 @@ void xt_unhandled_exception(XtExcFrame *frame) haltOtherCore(); esp_dport_access_int_abort(); if (!abort_called) { - panicPutStr("Guru Meditation Error of type "); + panicPutStr("Guru Meditation Error: Core "); + panicPutDec(xPortGetCoreID()); + panicPutStr(" panic'ed ("); int exccause = frame->exccause; if (exccause < NUM_EDESCS) { panicPutStr(edesc[exccause]); } else { panicPutStr("Unknown"); } - panicPutStr(" occurred on core "); - panicPutDec(xPortGetCoreID()); + panicPutStr(")\r\n"); if (esp_cpu_in_ocd_debug_mode()) { panicPutStr(" at pc="); panicPutHex(frame->pc); @@ -284,7 +295,7 @@ void xt_unhandled_exception(XtExcFrame *frame) SEGGER_RTT_ESP32_FlushNoLock(CONFIG_ESP32_APPTRACE_POSTMORTEM_FLUSH_TRAX_THRESH, APPTRACE_ONPANIC_HOST_FLUSH_TMO); #else esp_apptrace_flush_nolock(ESP_APPTRACE_DEST_TRAX, CONFIG_ESP32_APPTRACE_POSTMORTEM_FLUSH_TRAX_THRESH, - APPTRACE_ONPANIC_HOST_FLUSH_TMO); + APPTRACE_ONPANIC_HOST_FLUSH_TMO); #endif #endif //Stick a hardware breakpoint on the address the handler returns to. This way, the OCD debugger @@ -458,7 +469,7 @@ static __attribute__((noreturn)) void commonErrorHandler(XtExcFrame *frame) SEGGER_RTT_ESP32_FlushNoLock(CONFIG_ESP32_APPTRACE_POSTMORTEM_FLUSH_TRAX_THRESH, APPTRACE_ONPANIC_HOST_FLUSH_TMO); #else esp_apptrace_flush_nolock(ESP_APPTRACE_DEST_TRAX, CONFIG_ESP32_APPTRACE_POSTMORTEM_FLUSH_TRAX_THRESH, - APPTRACE_ONPANIC_HOST_FLUSH_TMO); + APPTRACE_ONPANIC_HOST_FLUSH_TMO); #endif reconfigureAllWdts(); #endif @@ -515,28 +526,36 @@ void esp_set_breakpoint_if_jtag(void *fn) esp_err_t esp_set_watchpoint(int no, void *adr, int size, int flags) { int x; - if (no<0 || no>1) return ESP_ERR_INVALID_ARG; - if (flags&(~0xC0000000)) return ESP_ERR_INVALID_ARG; - int dbreakc=0x3F; - //We support watching 2^n byte values, from 1 to 64. Calculate the mask for that. - for (x=0; x<7; x++) { - if (size==(1< 1) { + return ESP_ERR_INVALID_ARG; + } + if (flags & (~0xC0000000)) { + return ESP_ERR_INVALID_ARG; + } + int dbreakc = 0x3F; + //We support watching 2^n byte values, from 1 to 64. Calculate the mask for that. + for (x = 0; x < 7; x++) { + if (size == (1 << x)) { + break; + } + dbreakc <<= 1; + } + if (x == 7) { + return ESP_ERR_INVALID_ARG; } - if (x==7) return ESP_ERR_INVALID_ARG; //Mask mask and add in flags. - dbreakc=(dbreakc&0x3f)|flags; + dbreakc = (dbreakc & 0x3f) | flags; - if (no==0) { + if (no == 0) { asm volatile( "wsr.dbreaka0 %0\n" \ "wsr.dbreakc0 %1\n" \ - ::"r"(adr),"r"(dbreakc)); + ::"r"(adr), "r"(dbreakc)); } else { asm volatile( "wsr.dbreaka1 %0\n" \ "wsr.dbreakc1 %1\n" \ - ::"r"(adr),"r"(dbreakc)); + ::"r"(adr), "r"(dbreakc)); } return ESP_OK; } @@ -544,8 +563,8 @@ esp_err_t esp_set_watchpoint(int no, void *adr, int size, int flags) void esp_clear_watchpoint(int no) { //Setting a dbreakc register to 0 makes it trigger on neither load nor store, effectively disabling it. - int dbreakc=0; - if (no==0) { + int dbreakc = 0; + if (no == 0) { asm volatile( "wsr.dbreakc0 %0\n" \ ::"r"(dbreakc)); diff --git a/components/esp32/test/test_exception.c b/components/esp32/test/test_exception.c new file mode 100644 index 000000000..4e5d6dec2 --- /dev/null +++ b/components/esp32/test/test_exception.c @@ -0,0 +1,9 @@ +#include "unity.h" +#include "esp_system.h" +#include "string.h" + + +TEST_CASE("make exception", "[restart][reset=StoreProhibited,SW_CPU_RESET]") +{ + *(int *) NULL = 0; +} diff --git a/components/esp32/test/test_restart.c b/components/esp32/test/test_restart.c index 94f5741af..a48ad26ea 100644 --- a/components/esp32/test/test_restart.c +++ b/components/esp32/test/test_restart.c @@ -4,23 +4,21 @@ #include "freertos/task.h" -TEST_CASE("restart from PRO CPU", "[restart][ignore]") +TEST_CASE("restart from PRO CPU", "[restart][reset=SW_CPU_RESET]") { esp_restart(); } -static void restart_task(void* arg) +static void restart_task(void *arg) { esp_restart(); } -TEST_CASE("restart from APP CPU", "[restart][ignore]") +TEST_CASE("restart from APP CPU", "[restart][reset=SW_CPU_RESET]") { xTaskCreatePinnedToCore(&restart_task, "restart", 2048, NULL, 5, NULL, 1); - - while(true) { + while (true) { ; } } - diff --git a/components/esp32/test/test_sleep.c b/components/esp32/test/test_sleep.c index 6f0a44403..9db305a4d 100644 --- a/components/esp32/test/test_sleep.c +++ b/components/esp32/test/test_sleep.c @@ -5,12 +5,12 @@ #include "freertos/FreeRTOS.h" #include "freertos/task.h" -TEST_CASE("esp_deepsleep works", "[deepsleep][ignore]") +TEST_CASE("esp_deepsleep works", "[deepsleep][reset=DEEPSLEEP_RESET]") { esp_deep_sleep(2000000); } -static void deep_sleep_task(void* arg) +static void deep_sleep_task(void *arg) { esp_deep_sleep_start(); } @@ -21,17 +21,19 @@ static void do_deep_sleep_from_app_cpu() // keep running some non-IRAM code vTaskSuspendAll(); - while(true) { + + while (true) { ; } } -TEST_CASE("wake up from deep sleep using timer", "[deepsleep][ignore]") +TEST_CASE("wake up using timer", "[deepsleep][reset=DEEPSLEEP_RESET]") { esp_sleep_enable_timer_wakeup(2000000); esp_deep_sleep_start(); } + TEST_CASE("wake up from light sleep using timer", "[deepsleep]") { esp_sleep_enable_timer_wakeup(2000000); @@ -40,11 +42,11 @@ TEST_CASE("wake up from light sleep using timer", "[deepsleep]") esp_light_sleep_start(); gettimeofday(&tv_stop, NULL); float dt = (tv_stop.tv_sec - tv_start.tv_sec) * 1e3f + - (tv_stop.tv_usec - tv_start.tv_usec) * 1e-3f; + (tv_stop.tv_usec - tv_start.tv_usec) * 1e-3f; TEST_ASSERT_INT32_WITHIN(500, 2000, (int) dt); } -TEST_CASE("enter deep sleep on APP CPU and wake up using timer", "[deepsleep][ignore]") +TEST_CASE("enter deep sleep on APP CPU and wake up using timer", "[deepsleep][reset=DEEPSLEEP_RESET]") { esp_sleep_enable_timer_wakeup(2000000); do_deep_sleep_from_app_cpu(); diff --git a/components/idf_test/unit_test/TestCaseScript/IDFUnitTest/UnitTest.py b/components/idf_test/unit_test/TestCaseScript/IDFUnitTest/UnitTest.py index 1625e4e36..2810c8e8e 100644 --- a/components/idf_test/unit_test/TestCaseScript/IDFUnitTest/UnitTest.py +++ b/components/idf_test/unit_test/TestCaseScript/IDFUnitTest/UnitTest.py @@ -1,3 +1,4 @@ +# -*- coding: utf-8 -*- import re import time @@ -5,46 +6,56 @@ from TCAction import PerformanceTCBase from TCAction import TCActionBase from NativeLog import NativeLog + class UnitTest(PerformanceTCBase.PerformanceTCBase): - def __init__(self, name, test_env, cmd_set, timeout=30, log_path=TCActionBase.LOG_PATH): - PerformanceTCBase.PerformanceTCBase.__init__(self, name, test_env, cmd_set=cmd_set, + def __init__(self, test_case, test_env, cmd_set, timeout=30, log_path=TCActionBase.LOG_PATH): + PerformanceTCBase.PerformanceTCBase.__init__(self, test_case, test_env, cmd_set=cmd_set, timeout=timeout, log_path=log_path) - - self.test_case = None + self.case = cmd_set[1][0] self.test_timeout = 20 - - # load param from excel - for i in range(1, len(cmd_set)): - if cmd_set[i][0] != "dummy": - cmd_string = "self.test_case = " + "\"" + cmd_set[i][0] + "\"" - exec cmd_string + self.reset_reason = test_case['reset'] self.result_cntx = TCActionBase.ResultCheckContext(self, test_env, self.tc_name) - pass def send_commands(self): self.flush_data("UT1") - try: - self.serial_write_line("UT1", "\"" + self.test_case + "\"") + self.serial_write_line("UT1", "\"" + self.case + "\"") data = "" + for _ in range(self.timeout): - time.sleep(1) #wait for test to run before reading result + time.sleep(1) # wait for test to run before reading result data += self.serial_read_data("UT1") - if re.search('[^0].* Tests 0 F', data): #check that number of tests run != 0 and number of tests failed == 0 + if re.search('[^0].* Tests 0 F', + data): # check that number of tests run != 0 and number of tests failed == 0 self.set_result("Succeed") break else: self.set_result("Fail") - except StandardError,e: + reset_list = self.reset_reason.split(",") if self.reset_reason else '' + pattern = re.compile(r"(ets [\w]{3} [\d]{1,2} [\d]{4} [\d]{2}:[\d]{2}:[\d]{2}[^(\)]*\([\w].*?\))" + r"|(Guru Meditation Error: Core [\d] panic'ed \([\w].*?\))") + reset_exception = pattern.findall(data) + if reset_list and len(reset_list) == len(reset_exception): + for i, reset in enumerate(reset_list): + temp_reset = reset_exception[i] + if reset not in "".join(temp_reset): + self.set_result("Fail") + break + else: + self.set_result("Succeed") + + except StandardError, e: NativeLog.add_exception_log(e) def execute(self): TCActionBase.TCActionBase.execute(self) self.send_commands() + def main(): pass + if __name__ == '__main__': pass diff --git a/tools/unit-test-app/tools/TagDefinition.yml b/tools/unit-test-app/tools/TagDefinition.yml index 3b952eaed..edc477564 100644 --- a/tools/unit-test-app/tools/TagDefinition.yml +++ b/tools/unit-test-app/tools/TagDefinition.yml @@ -6,3 +6,6 @@ ignore: test_env: default: "UT_T1_1" omitted: "UT_T1_1" +reset: + default: "POWERON_RESET" + omitted: " " \ No newline at end of file diff --git a/tools/unit-test-app/tools/UnitTestParser.py b/tools/unit-test-app/tools/UnitTestParser.py index 286468654..3ab911a8f 100644 --- a/tools/unit-test-app/tools/UnitTestParser.py +++ b/tools/unit-test-app/tools/UnitTestParser.py @@ -19,6 +19,7 @@ TEST_CASE_PATTERN = { "test point 1": "basic function", "version": "v1 (2016-12-06)", "test environment": "UT_T1_1", + "reset": "", "expected result": "1. set succeed" } @@ -182,6 +183,7 @@ class Parser(object): "test point 2": prop["module"], "steps": name, "test environment": prop["test_env"], + "reset": prop["reset"], "sub module": self.module_map[prop["module"]]['sub module'], "summary": name}) return test_case