]> granicus.if.org Git - esp-idf/commitdiff
test: support test for UT cases expect to reset
authorhouchenyao <houchenyao@espressif.com>
Wed, 20 Sep 2017 09:17:51 +0000 (17:17 +0800)
committerIvan Grokhotkov <ivan@espressif.com>
Tue, 7 Nov 2017 04:19:39 +0000 (12:19 +0800)
components/esp32/panic.c
components/esp32/test/test_exception.c [new file with mode: 0644]
components/esp32/test/test_restart.c
components/esp32/test/test_sleep.c
components/idf_test/unit_test/TestCaseScript/IDFUnitTest/UnitTest.py
tools/unit-test-app/tools/TagDefinition.yml
tools/unit-test-app/tools/UnitTestParser.py

index 906e1ee3657a92a96be0796435bf1e5eeb84c668..d09257268fcfe9019338e3e4ad201f4f47ae8e26 100644 (file)
@@ -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;
+    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<<x)) break;
-        dbreakc<<=1;
+    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 (file)
index 0000000..4e5d6de
--- /dev/null
@@ -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;
+}
index 94f5741affad035b4ba45a37c101d952592d55b1..a48ad26ea1f8a312126ae796edf89107be2b5009 100644 (file)
@@ -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(voidarg)
+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) {
         ;
     }
 }
 
-
index 6f0a44403f461779a52891e7bd09ce35fe3b23d4..9db305a4d5a7f52fbdf40c0914fcd74b59b80209 100644 (file)
@@ -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(voidarg)
+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();
index 1625e4e36ceba440af7d441201394fb72b97c4cb..2810c8e8ec3a94931483afb8ff6d11c6703e6ca9 100644 (file)
@@ -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
index 3b952eaed657ddef634aae07e012019ae80b288a..edc477564e34b7440615a4765a33482625298f9d 100644 (file)
@@ -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
index 286468654c9ed651ba359466d9b1c40c4fbfdbf8..3ab911a8fe39feaff4b76682f78d380550a312a9 100644 (file)
@@ -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