Merge branch 'feature/parse_unit_test_cases_from_test_files' into 'master'

Parse unit test cases from test files

As of now, we need to sync three different places when adding new unit test cases. The plan is to add a python script in tools/unit-test-app. This script would parse unit test cases from the C files with tests and generate the needed YAML files in components/idf_test/unit_test. CI would run this script in build stage to create the files and unit-test stage would use the generated files to run tests.

To get the needed test metadata, we need to add some more tags in the test case functions. For example:

```
TEST_CASE("SYS_LIB_0102 test time functions", "[stdlib][fails][env=UT_T1_APC]") 
{
    //...
}
```

Reason for this kind of implementation is that we need the YAML files for generating documents.

See merge request !275
This commit is contained in:
Ivan Grokhotkov
2017-01-18 17:23:04 +08:00
27 changed files with 438 additions and 527 deletions

View File

@@ -87,6 +87,8 @@ build_esp_idf_tests:
- ./tools/unit-test-app/build/*.elf
- ./tools/unit-test-app/build/*.map
- ./tools/unit-test-app/build/bootloader/*.bin
- ./components/idf_test/unit_test/TestCaseAll.yml
- ./components/idf_test/unit_test/CIConfigs/*.yml
expire_in: 6 mos
script:
@@ -94,6 +96,7 @@ build_esp_idf_tests:
- git checkout ${CI_BUILD_REF_NAME} || echo "Using default branch..."
- make defconfig
- make TESTS_ALL=1
- python UnitTestParser.py
build_examples:
<<: *build_template
@@ -160,6 +163,7 @@ test_report:
LOG_PATH: "$CI_PROJECT_DIR/$CI_BUILD_REF"
TEST_CASE_FILE_PATH: "$CI_PROJECT_DIR/components/idf_test"
REPORT_PATH: "$CI_PROJECT_DIR/CI_Test_Report"
MODULE_UPDATE_FILE: "$CI_PROJECT_DIR/components/idf_test/unit_test/ModuleDefinition.yml"
artifacts:
when: always
paths:
@@ -180,8 +184,7 @@ test_report:
- git clone $GITLAB_SSH_SERVER/yinling/auto_test_script.git
- cd auto_test_script
# generate report
- TEST_RESULT=Pass
- python CITestReport.py -l $LOG_PATH -t $TEST_CASE_FILE_PATH -p $REPORT_PATH -r $RESULT_PATH -a $ARTIFACTS_PATH || TEST_RESULT=Fail
- python CITestReport.py -l $LOG_PATH -t $TEST_CASE_FILE_PATH -p $REPORT_PATH -r $RESULT_PATH -a $ARTIFACTS_PATH -m $MODULE_UPDATE_FILE || FAIL=True
# commit to CI-test-result project
- git clone $GITLAB_SSH_SERVER/qa/CI-test-result.git
- rm -rf CI-test-result/RawData/$RESULT_PATH
@@ -263,6 +266,7 @@ deploy_docs:
# append test level folder to TEST_CASE_FILE_PATH in before_script of test job
TEST_CASE_FILE_PATH: "$CI_PROJECT_DIR/components/idf_test/integration_test"
# jobs MUST set CONFIG_FILE in before_script, and overwrite the variables above if necessary
MODULE_UPDATE_FILE: "$CI_PROJECT_DIR/components/idf_test/unit_test/ModuleDefinition.yml"
artifacts:
when: always
@@ -284,7 +288,7 @@ deploy_docs:
- git clone $GITLAB_SSH_SERVER/yinling/auto_test_script.git
- cd auto_test_script
# run test
- python CIRunner.py -l $LOG_PATH -c $CONFIG_FILE -e $LOCAL_ENV_CONFIG_PATH -t $TEST_CASE_FILE_PATH bin_path $APP_NAME $BIN_PATH
- python CIRunner.py -l $LOG_PATH -c $CONFIG_FILE -e $LOCAL_ENV_CONFIG_PATH -t $TEST_CASE_FILE_PATH -m $MODULE_UPDATE_FILE bin_path $APP_NAME $BIN_PATH
# template for overnight test jobs
@@ -309,7 +313,7 @@ deploy_docs:
- git clone $GITLAB_SSH_SERVER/yinling/auto_test_script.git
- cd auto_test_script
# run test
- python CIRunner.py -l $LOG_PATH -c $CONFIG_FILE -e $LOCAL_ENV_CONFIG_PATH -t $TEST_CASE_FILE_PATH bin_path $APP_NAME $BIN_PATH
- python CIRunner.py -l $LOG_PATH -c $CONFIG_FILE -e $LOCAL_ENV_CONFIG_PATH -t $TEST_CASE_FILE_PATH -m $MODULE_UPDATE_FILE bin_path $APP_NAME $BIN_PATH
# template for unit test jobs
.unit_test_template: &unit_test_template
@@ -324,6 +328,10 @@ deploy_docs:
LOG_PATH: "$CI_PROJECT_DIR/$CI_BUILD_REF"
APP_NAME: "ut"
TEST_CASE_FILE_PATH: "$CI_PROJECT_DIR/components/idf_test/unit_test"
MODULE_UPDATE_FILE: "$CI_PROJECT_DIR/components/idf_test/unit_test/ModuleDefinition.yml"
dependencies:
- build_esp_idf_tests
UT_Function_SYS_01:
<<: *unit_test_template
@@ -333,6 +341,14 @@ UT_Function_SYS_01:
before_script:
- CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/UT_Function_SYS_01.yml
UT_Function_SYS_02:
<<: *unit_test_template
tags:
- ESP32_IDF
- UT_T1_1
before_script:
- CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/UT_Function_SYS_02.yml
IT_Function_SYS_01:
<<: *test_template
tags:

View File

@@ -80,7 +80,7 @@ TEST_CASE("SPI Master clockdiv calculation routines", "[spi]")
}
TEST_CASE("SPI Master test", "[spi]")
TEST_CASE("SPI Master test", "[spi][ignore]")
{
spi_bus_config_t buscfg={
.mosi_io_num=4,

View File

@@ -269,7 +269,7 @@ static void tskTwo(void *pvParameters)
}
TEST_CASE("S32C1I vs AHB test (needs I2S)", "[hw]")
TEST_CASE("S32C1I vs AHB test (needs I2S)", "[hw][ignore]")
{
int i;
TaskHandle_t th[3];

View File

@@ -4,7 +4,7 @@
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
TEST_CASE("esp_deepsleep works", "[deepsleep]")
TEST_CASE("esp_deepsleep works", "[deepsleep][ignore]")
{
esp_deep_sleep(2000000);
}
@@ -25,20 +25,20 @@ static void do_deep_sleep_from_app_cpu()
}
}
TEST_CASE("wake up using timer", "[deepsleep]")
TEST_CASE("wake up using timer", "[deepsleep][ignore]")
{
esp_deep_sleep_enable_timer_wakeup(2000000);
esp_deep_sleep_start();
}
TEST_CASE("enter deep sleep on APP CPU and wake up using timer", "[deepsleep]")
TEST_CASE("enter deep sleep on APP CPU and wake up using timer", "[deepsleep][ignore]")
{
esp_deep_sleep_enable_timer_wakeup(2000000);
do_deep_sleep_from_app_cpu();
}
TEST_CASE("wake up using ext0 (13 high)", "[deepsleep]")
TEST_CASE("wake up using ext0 (13 high)", "[deepsleep][ignore]")
{
ESP_ERROR_CHECK(rtc_gpio_init(GPIO_NUM_13));
ESP_ERROR_CHECK(gpio_pullup_dis(GPIO_NUM_13));
@@ -47,7 +47,7 @@ TEST_CASE("wake up using ext0 (13 high)", "[deepsleep]")
esp_deep_sleep_start();
}
TEST_CASE("wake up using ext0 (13 low)", "[deepsleep]")
TEST_CASE("wake up using ext0 (13 low)", "[deepsleep][ignore]")
{
ESP_ERROR_CHECK(rtc_gpio_init(GPIO_NUM_13));
ESP_ERROR_CHECK(gpio_pullup_en(GPIO_NUM_13));
@@ -56,7 +56,7 @@ TEST_CASE("wake up using ext0 (13 low)", "[deepsleep]")
esp_deep_sleep_start();
}
TEST_CASE("wake up using ext1 when RTC_PERIPH is off (13 high)", "[deepsleep]")
TEST_CASE("wake up using ext1 when RTC_PERIPH is off (13 high)", "[deepsleep][ignore]")
{
// This test needs external pulldown
ESP_ERROR_CHECK(rtc_gpio_init(GPIO_NUM_13));
@@ -64,7 +64,7 @@ TEST_CASE("wake up using ext1 when RTC_PERIPH is off (13 high)", "[deepsleep]")
esp_deep_sleep_start();
}
TEST_CASE("wake up using ext1 when RTC_PERIPH is off (13 low)", "[deepsleep]")
TEST_CASE("wake up using ext1 when RTC_PERIPH is off (13 low)", "[deepsleep][ignore]")
{
// This test needs external pullup
ESP_ERROR_CHECK(rtc_gpio_init(GPIO_NUM_13));
@@ -72,7 +72,7 @@ TEST_CASE("wake up using ext1 when RTC_PERIPH is off (13 low)", "[deepsleep]")
esp_deep_sleep_start();
}
TEST_CASE("wake up using ext1 when RTC_PERIPH is on (13 high)", "[deepsleep]")
TEST_CASE("wake up using ext1 when RTC_PERIPH is on (13 high)", "[deepsleep][ignore]")
{
ESP_ERROR_CHECK(rtc_gpio_init(GPIO_NUM_13));
ESP_ERROR_CHECK(gpio_pullup_dis(GPIO_NUM_13));
@@ -82,7 +82,7 @@ TEST_CASE("wake up using ext1 when RTC_PERIPH is on (13 high)", "[deepsleep]")
esp_deep_sleep_start();
}
TEST_CASE("wake up using ext1 when RTC_PERIPH is on (13 low)", "[deepsleep]")
TEST_CASE("wake up using ext1 when RTC_PERIPH is on (13 low)", "[deepsleep][ignore]")
{
ESP_ERROR_CHECK(rtc_gpio_init(GPIO_NUM_13));
ESP_ERROR_CHECK(gpio_pullup_en(GPIO_NUM_13));

View File

@@ -37,7 +37,7 @@ static void test_delay_task(void* p)
vTaskDelete(NULL);
}
TEST_CASE("ets_delay produces correct delay on both CPUs", "[delay]")
TEST_CASE("ets_delay produces correct delay on both CPUs", "[delay][ignore]")
{
int delay_ms = 50;
const delay_test_arg_t args = { .delay_us = delay_ms * 1000, .method = 0 };

View File

@@ -96,7 +96,7 @@ static void tskTwo(void *pvParameters)
// TODO: split this thing into separate orthogonal tests
TEST_CASE("Fast I/O bus test", "[hw]")
TEST_CASE("Fast I/O bus test", "[hw][ignore]")
{
int i;
if ((REG_UART_BASE(0) >> 16) != 0x3ff4) {

View File

@@ -7,7 +7,7 @@
#define DATASIZE (1024*64)
TEST_CASE("Test miniz compression/decompression", "[miniz]")
TEST_CASE("Test miniz compression/decompression", "[miniz][ignore]")
{
int x;
char b;

View File

@@ -183,7 +183,7 @@ int mymemcmp(char *a, char *b, int len)
TEST_CASE("Unaligned DMA test (needs I2S)", "[hw]")
TEST_CASE("Unaligned DMA test (needs I2S)", "[hw][ignore]")
{
int x;
char src[2049], dest[2049];

View File

@@ -52,7 +52,7 @@ static void create_file_with_text(const char* name, const char* text)
TEST_ASSERT_EQUAL(0, fclose(f));
}
TEST_CASE("can create and write file on sd card", "[fatfs]")
TEST_CASE("can create and write file on sd card", "[fatfs][ignore]")
{
HEAP_SIZE_CAPTURE();
sdmmc_host_t host = SDMMC_HOST_DEFAULT();
@@ -69,7 +69,7 @@ TEST_CASE("can create and write file on sd card", "[fatfs]")
HEAP_SIZE_CHECK(0);
}
TEST_CASE("can read file on sd card", "[fatfs]")
TEST_CASE("can read file on sd card", "[fatfs][ignore]")
{
HEAP_SIZE_CAPTURE();
@@ -134,7 +134,7 @@ static void speed_test(void* buf, size_t buf_size, size_t file_size, bool write)
}
TEST_CASE("read speed test", "[fatfs]")
TEST_CASE("read speed test", "[fatfs][ignore]")
{
HEAP_SIZE_CAPTURE();
@@ -151,7 +151,7 @@ TEST_CASE("read speed test", "[fatfs]")
HEAP_SIZE_CHECK(0);
}
TEST_CASE("write speed test", "[fatfs]")
TEST_CASE("write speed test", "[fatfs][ignore]")
{
HEAP_SIZE_CAPTURE();
@@ -171,7 +171,7 @@ TEST_CASE("write speed test", "[fatfs]")
HEAP_SIZE_CHECK(0);
}
TEST_CASE("can lseek", "[fatfs]")
TEST_CASE("can lseek", "[fatfs][ignore]")
{
HEAP_SIZE_CAPTURE();
sdmmc_host_t host = SDMMC_HOST_DEFAULT();
@@ -208,7 +208,7 @@ TEST_CASE("can lseek", "[fatfs]")
HEAP_SIZE_CHECK(0);
}
TEST_CASE("stat returns correct values", "[fatfs]")
TEST_CASE("stat returns correct values", "[fatfs][ignore]")
{
HEAP_SIZE_CAPTURE();
sdmmc_host_t host = SDMMC_HOST_DEFAULT();
@@ -249,7 +249,7 @@ TEST_CASE("stat returns correct values", "[fatfs]")
HEAP_SIZE_CHECK(0);
}
TEST_CASE("unlink removes a file", "[fatfs]")
TEST_CASE("unlink removes a file", "[fatfs][ignore]")
{
HEAP_SIZE_CAPTURE();
sdmmc_host_t host = SDMMC_HOST_DEFAULT();
@@ -271,7 +271,7 @@ TEST_CASE("unlink removes a file", "[fatfs]")
HEAP_SIZE_CHECK(0);
}
TEST_CASE("link copies a file, rename moves a file", "[fatfs]")
TEST_CASE("link copies a file, rename moves a file", "[fatfs][ignore]")
{
HEAP_SIZE_CAPTURE();
sdmmc_host_t host = SDMMC_HOST_DEFAULT();
@@ -373,7 +373,7 @@ done:
}
TEST_CASE("multiple tasks can use same volume", "[fatfs]")
TEST_CASE("multiple tasks can use same volume", "[fatfs][ignore]")
{
HEAP_SIZE_CAPTURE();
sdmmc_host_t host = SDMMC_HOST_DEFAULT();
@@ -434,7 +434,7 @@ TEST_CASE("multiple tasks can use same volume", "[fatfs]")
HEAP_SIZE_CHECK(0);
}
TEST_CASE("can create and remove directories", "[fatfs]")
TEST_CASE("can create and remove directories", "[fatfs][ignore]")
{
HEAP_SIZE_CAPTURE();
sdmmc_host_t host = SDMMC_HOST_DEFAULT();
@@ -470,7 +470,7 @@ TEST_CASE("can create and remove directories", "[fatfs]")
HEAP_SIZE_CHECK(0);
}
TEST_CASE("opendir, readdir, rewinddir, seekdir work as expected", "[fatfs]")
TEST_CASE("opendir, readdir, rewinddir, seekdir work as expected", "[fatfs][ignore]")
{
HEAP_SIZE_CAPTURE();
sdmmc_host_t host = SDMMC_HOST_DEFAULT();

View File

@@ -187,7 +187,7 @@ static void uartRxInit(xQueueHandle q)
}
// TODO: split this thing into separate orthogonal tests
TEST_CASE("Bunch of FreeRTOS tests", "[freertos]")
TEST_CASE("Bunch of FreeRTOS tests", "[freertos][ignore]")
{
char *tst;
TaskHandle_t th[12];

View File

@@ -38,7 +38,7 @@ static void task_event_group_call_response(void *param)
vTaskDelete(NULL);
}
TEST_CASE("FreeRTOS Event Groups", "[freertos]")
TEST_CASE("FreeRTOS Event Groups", "[freertos][ignore]")
{
eg = xEventGroupCreate();
@@ -89,7 +89,7 @@ static void task_test_sync(void *param)
vTaskDelete(NULL);
}
TEST_CASE("FreeRTOS Event Group Sync", "[freertos]")
TEST_CASE("FreeRTOS Event Group Sync", "[freertos][ignore]")
{
eg = xEventGroupCreate();

View File

@@ -13,7 +13,7 @@ static void task_delete_self(void *param)
vTaskDelete(NULL);
}
TEST_CASE("FreeRTOS Delete Tasks", "[freertos]")
TEST_CASE("FreeRTOS Delete Tasks", "[freertos][ignore]")
{
xTaskCreatePinnedToCore(task_delete_self, "tsk_self_a", 4096, NULL, configMAX_PRIORITIES - 1, NULL, 0);
xTaskCreatePinnedToCore(task_delete_self, "tsk_self_a", 4096, NULL, configMAX_PRIORITIES - 1, NULL, 0);

View File

@@ -17,7 +17,7 @@
#include "soc/io_mux_reg.h"
TEST_CASE("Panic handler", "[freertos]")
TEST_CASE("Panic handler", "[freertos][ignore]")
{
volatile int *i;
i = (volatile int *)0x0;

View File

@@ -185,12 +185,12 @@ static void testRingbuffer(int type)
}
// TODO: split this thing into separate orthogonal tests
TEST_CASE("FreeRTOS ringbuffer test, no splitting items", "[freertos]")
TEST_CASE("FreeRTOS ringbuffer test, no splitting items", "[freertos][ignore]")
{
testRingbuffer(0);
}
TEST_CASE("FreeRTOS ringbuffer test, w/ splitting items", "[freertos]")
TEST_CASE("FreeRTOS ringbuffer test, w/ splitting items", "[freertos][ignore]")
{
testRingbuffer(1);
}

View File

@@ -1,7 +0,0 @@
Config: {execute count: 1, execute order: in order}
DUT: [UT1]
Filter:
- Add:
ID: [SYS_OS_0102, SYS_MISC_0102, SYS_MISC_0107, SYS_MISC_0106, SYS_MISC_0109,
SYS_MISC_0108, SYS_MISC_0112, SYS_MISC_0113, SYS_MISC_0110, SYS_MISC_0111, SYS_LIB_0103,
SYS_LIB_0102, SYS_LIB_0101, SYS_LIB_0106, SYS_LIB_0105, SYS_LIB_0104]

View File

@@ -1,461 +0,0 @@
test cases:
- CI ready: 'Yes'
ID: SYS_LIB_0101
SDK: ESP32_IDF
Test App: UT
auto test: 'Yes'
category: Function
cmd set:
- IDFUnitTest/UnitTest
- - test_case = "check if ROM or Flash is used for functions"
- [dummy]
comment: check if ROM or Flash is used for functions
execution time: 0
expected result: 1. set succeed
initial condition: UTINIT1
level: Unit
module: System
steps: 1. run lib test
sub module: Std Lib
summary: lib unit test
test environment: UT_T1_1
test point 1: basic function
test point 2: lib
version: v1 (2016-10-26)
- CI ready: 'Yes'
ID: SYS_LIB_0102
SDK: ESP32_IDF
Test App: UT
auto test: 'Yes'
category: Function
cmd set:
- IDFUnitTest/UnitTest
- - test_case = "test time functions"
- [dummy]
comment: test time functions
execution time: 0
expected result: 1. set succeed
initial condition: UTINIT1
level: Unit
module: System
steps: 1. run lib test
sub module: Std Lib
summary: lib unit test
test environment: UT_T1_1
test point 1: basic function
test point 2: lib
version: v1 (2016-10-26)
- CI ready: 'Yes'
ID: SYS_LIB_0103
SDK: ESP32_IDF
Test App: UT
auto test: 'Yes'
category: Function
cmd set:
- IDFUnitTest/UnitTest
- - test_case = "test sscanf function"
- [dummy]
comment: test sscanf function
execution time: 0
expected result: 1. set succeed
initial condition: UTINIT1
level: Unit
module: System
steps: 1. run lib test
sub module: Std Lib
summary: lib unit test
test environment: UT_T1_1
test point 1: basic function
test point 2: lib
version: v1 (2016-10-26)
- CI ready: 'Yes'
ID: SYS_LIB_0104
SDK: ESP32_IDF
Test App: UT
auto test: 'Yes'
category: Function
cmd set:
- IDFUnitTest/UnitTest
- - test_case = "test sprintf function"
- [dummy]
comment: test sprintf function
execution time: 0
expected result: 1. set succeed
initial condition: UTINIT1
level: Unit
module: System
steps: 1. run lib test
sub module: Std Lib
summary: lib unit test
test environment: UT_T1_1
test point 1: basic function
test point 2: lib
version: v1 (2016-10-26)
- CI ready: 'Yes'
ID: SYS_LIB_0105
SDK: ESP32_IDF
Test App: UT
auto test: 'Yes'
category: Function
cmd set:
- IDFUnitTest/UnitTest
- - test_case = "test atoX functions"
- [dummy]
comment: test atoX functions
execution time: 0
expected result: 1. set succeed
initial condition: UTINIT1
level: Unit
module: System
steps: 1. run lib test
sub module: Std Lib
summary: lib unit test
test environment: UT_T1_1
test point 1: basic function
test point 2: lib
version: v1 (2016-10-26)
- CI ready: 'Yes'
ID: SYS_LIB_0106
SDK: ESP32_IDF
Test App: UT
auto test: 'Yes'
category: Function
cmd set:
- IDFUnitTest/UnitTest
- - test_case = "test ctype functions"
- [dummy]
comment: test ctype functions
execution time: 0
expected result: 1. set succeed
initial condition: UTINIT1
level: Unit
module: System
steps: 1. run lib test
sub module: Std Lib
summary: lib unit test
test environment: UT_T1_1
test point 1: basic function
test point 2: lib
version: v1 (2016-10-26)
- CI ready: 'Yes'
ID: SYS_MISC_0102
SDK: ESP32_IDF
Test App: UT
auto test: 'Yes'
category: Function
cmd set:
- IDFUnitTest/UnitTest
- - test_case = "mbedtls MPI self-tests"
- [dummy]
comment: mbedtls MPI self-tests
execution time: 0
expected result: 1. set succeed
initial condition: UTINIT1
level: Unit
module: System
steps: 1. run bignum test
sub module: Misc
summary: bignum unit test
test environment: UT_T1_1
test point 1: basic function
test point 2: bignum
version: v1 (2016-10-26)
- CI ready: 'Yes'
ID: SYS_MISC_0103
SDK: ESP32_IDF
Test App: UT
auto test: 'Yes'
category: Function
cmd set:
- IDFUnitTest/UnitTest
- - test_case = "test AES thread safety"
- [dummy]
comment: test AES thread safety
execution time: 0
expected result: 1. set succeed
initial condition: UTINIT1
level: Unit
module: System
steps: 1. run hwcrypto test
sub module: Misc
summary: hwcrypto unit test
test environment: UT_T1_1
test point 1: basic function
test point 2: hwcrypto
version: v1 (2016-10-26)
- CI ready: 'Yes'
ID: SYS_MISC_0104
SDK: ESP32_IDF
Test App: UT
auto test: 'Yes'
category: Function
cmd set:
- IDFUnitTest/UnitTest
- - test_case = "test AES acceleration"
- [dummy]
comment: test AES acceleration
execution time: 0
expected result: 1. set succeed
initial condition: UTINIT1
level: Unit
module: System
steps: 1. run hwcrypto test
sub module: Misc
summary: hwcrypto unit test
test environment: UT_T1_1
test point 1: basic function
test point 2: hwcrypto
version: v1 (2016-10-26)
- CI ready: 'Yes'
ID: SYS_MISC_0105
SDK: ESP32_IDF
Test App: UT
auto test: 'Yes'
category: Function
cmd set:
- IDFUnitTest/UnitTest
- - test_case = "test SHA thread safety"
- [dummy]
comment: test SHA thread safety
execution time: 0
expected result: 1. set succeed
initial condition: UTINIT1
level: Unit
module: System
steps: 1. run hwcrypto test
sub module: Misc
summary: hwcrypto unit test
test environment: UT_T1_1
test point 1: basic function
test point 2: hwcrypto
version: v1 (2016-10-26)
- CI ready: 'Yes'
ID: SYS_MISC_0106
SDK: ESP32_IDF
Test App: UT
auto test: 'Yes'
category: Function
cmd set:
- IDFUnitTest/UnitTest
- - test_case = "context switch saves FP registers"
- [dummy]
comment: context switch saves FP registers
execution time: 0
expected result: 1. set succeed
initial condition: UTINIT1
level: Unit
module: System
steps: 1. run fp test
sub module: Misc
summary: fp unit test
test environment: UT_T1_1
test point 1: basic function
test point 2: fp
version: v1 (2016-10-26)
- CI ready: 'Yes'
ID: SYS_MISC_0107
SDK: ESP32_IDF
Test App: UT
auto test: 'Yes'
category: Function
cmd set:
- IDFUnitTest/UnitTest
- - test_case = "test FP sqrt"
- [dummy]
comment: test FP sqrt
execution time: 0
expected result: 1. set succeed
initial condition: UTINIT1
level: Unit
module: System
steps: 1. run fp test
sub module: Misc
summary: fp unit test
test environment: UT_T1_1
test point 1: basic function
test point 2: fp
version: v1 (2016-10-26)
- CI ready: 'Yes'
ID: SYS_MISC_0108
SDK: ESP32_IDF
Test App: UT
auto test: 'Yes'
category: Function
cmd set:
- IDFUnitTest/UnitTest
- - test_case = "test FP div"
- [dummy]
comment: test FP div
execution time: 0
expected result: 1. set succeed
initial condition: UTINIT1
level: Unit
module: System
steps: 1. run fp test
sub module: Misc
summary: fp unit test
test environment: UT_T1_1
test point 1: basic function
test point 2: fp
version: v1 (2016-10-26)
- CI ready: 'Yes'
ID: SYS_MISC_0109
SDK: ESP32_IDF
Test App: UT
auto test: 'Yes'
category: Function
cmd set:
- IDFUnitTest/UnitTest
- - test_case = "test FP mul"
- [dummy]
comment: test FP mul
execution time: 0
expected result: 1. set succeed
initial condition: UTINIT1
level: Unit
module: System
steps: 1. run fp test
sub module: Misc
summary: fp unit test
test environment: UT_T1_1
test point 1: basic function
test point 2: fp
version: v1 (2016-10-26)
- CI ready: 'Yes'
ID: SYS_MISC_0110
SDK: ESP32_IDF
Test App: UT
auto test: 'Yes'
category: Function
cmd set:
- IDFUnitTest/UnitTest
- - test_case = "test FP add"
- [dummy]
comment: test FP add
execution time: 0
expected result: 1. set succeed
initial condition: UTINIT1
level: Unit
module: System
steps: 1. run fp test
sub module: Misc
summary: fp unit test
test environment: UT_T1_1
test point 1: basic function
test point 2: fp
version: v1 (2016-10-26)
- CI ready: 'Yes'
ID: SYS_MISC_0111
SDK: ESP32_IDF
Test App: UT
auto test: 'Yes'
category: Function
cmd set:
- IDFUnitTest/UnitTest
- - test_case = "Test JPEG decompression library"
- [dummy]
comment: Test JPEG decompression library
execution time: 0
expected result: 1. set succeed
initial condition: UTINIT1
level: Unit
module: System
steps: 1. run JPEG decompression test
sub module: Misc
summary: JPEG decompression library unit test
test environment: UT_T1_1
test point 1: basic function
test point 2: tjpgd
version: v1 (2016-10-31)
- CI ready: 'Yes'
ID: SYS_MISC_0112
SDK: ESP32_IDF
Test App: UT
auto test: 'Yes'
category: Function
cmd set:
- IDFUnitTest/UnitTest
- - test_case = "mbedtls AES self-tests"
- [dummy]
comment: mbedtls AES self-tests
execution time: 0
expected result: 1. set succeed
initial condition: UTINIT1
level: Unit
module: System
steps: 1. run mbedtls AES self-tests
sub module: Misc
summary: mbedtls AES unit test
test environment: UT_T1_1
test point 1: basic function
test point 2: mbedtls AES
version: v1 (2016-10-31)
- CI ready: 'Yes'
ID: SYS_MISC_0113
SDK: ESP32_IDF
Test App: UT
auto test: 'Yes'
category: Function
cmd set:
- IDFUnitTest/UnitTest
- - test_case = "mbedtls SHA self-tests"
- [dummy]
comment: mbedtls SHA self-tests
execution time: 0
expected result: 1. set succeed
initial condition: UTINIT1
level: Unit
module: System
steps: 1. run mbedtls SHA self-tests
sub module: Misc
summary: mbedtls SHA unit test
test environment: UT_T1_1
test point 1: basic function
test point 2: mbedtls SHA
version: v1 (2016-10-31)
- CI ready: 'Yes'
ID: SYS_MISC_0115
SDK: ESP32_IDF
Test App: UT
auto test: 'Yes'
category: Function
cmd set:
- IDFUnitTest/UnitTest
- - test_case = "test SHA acceleration"
- [dummy]
comment: test SHA acceleration
execution time: 0
expected result: 1. set succeed
initial condition: UTINIT1
level: Unit
module: System
steps: 1. run SHA acceleration test
sub module: Misc
summary: SHA acceleration unit test
test environment: UT_T1_1
test point 1: basic function
test point 2: SHA acceleration
version: v1 (2016-10-31)
- CI ready: 'Yes'
ID: SYS_OS_0102
SDK: ESP32_IDF
Test App: UT
auto test: 'Yes'
category: Function
cmd set:
- IDFUnitTest/UnitTest
- - test_case = "Freertos TLS delete cb"
- [dummy]
comment: Freertos TLS delete cb
execution time: 0
expected result: 1. set succeed
initial condition: UTINIT1
level: Unit
module: System
steps: 1. run Freertos TLS delete cb test
sub module: OS
summary: Freertos TLS delete cb unit test
test environment: UT_T1_1
test point 1: basic function
test point 2: Freertos TLS delete cb
version: v1 (2016-10-31)

View File

@@ -16,7 +16,7 @@ class UnitTest(PerformanceTCBase.PerformanceTCBase):
# load param from excel
for i in range(1, len(cmd_set)):
if cmd_set[i][0] != "dummy":
cmd_string = "self." + cmd_set[i][0]
cmd_string = "self.test_case = " + "\"" + cmd_set[i][0] + "\""
exec cmd_string
self.result_cntx = TCActionBase.ResultCheckContext(self, test_env, self.tc_name)
pass
@@ -25,13 +25,12 @@ class UnitTest(PerformanceTCBase.PerformanceTCBase):
self.flush_data("UT1")
try:
# add case select by name mark " before case name
self.serial_write_line("UT1", "\"" + self.test_case)
self.serial_write_line("UT1", "\"" + self.test_case + "\"")
data = ""
for _ in range(self.timeout):
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:

View File

@@ -116,7 +116,7 @@ static void tskRunSHA256Test(void *pvParameters)
vTaskDelete(NULL);
}
TEST_CASE("mbedtls SHA multithreading", "[mbedtls]")
TEST_CASE("mbedtls SHA multithreading", "[mbedtls][ignore]")
{
done_sem = xSemaphoreCreateCounting(4, 0);
xTaskCreate(tskRunSHA1Test, "SHA1Task1", 8192, NULL, 3, NULL);

View File

@@ -19,7 +19,7 @@ TEST_CASE("test ctype functions", "[newlib]")
TEST_ASSERT_FALSE( isspace('0') || isspace('9') || isspace(')') || isspace('A') || isspace('*') || isspace('\x81') || isspace('a'));
}
TEST_CASE("test atoX functions", "[newlib]")
TEST_CASE("test atoX functions", "[newlib][ignore]")
{
TEST_ASSERT_EQUAL_INT(-2147483648, atoi("-2147483648"));
TEST_ASSERT_EQUAL_INT(2147483647, atoi("2147483647"));
@@ -153,7 +153,7 @@ TEST_CASE("test 64bit int formats", "[newlib]")
TEST_ASSERT_EQUAL(val, sval);
}
#else
TEST_CASE("test 64bit int formats", "[newlib]")
TEST_CASE("test 64bit int formats", "[newlib][ignore]")
{
char* res = NULL;
const uint64_t val = 123456789012LL;

View File

@@ -26,7 +26,7 @@ TEST_CASE("Can read partition table", "[partition]")
printf("%d\n", __builtin_clz(count));
}
TEST_CASE("Can write, read, mmap partition", "[partition]")
TEST_CASE("Can write, read, mmap partition", "[partition][ignore]")
{
const esp_partition_t *p = esp_partition_find_first(ESP_PARTITION_TYPE_DATA, ESP_PARTITION_SUBTYPE_ANY, NULL);
TEST_ASSERT_NOT_NULL(p);

View File

@@ -26,7 +26,7 @@
#include <sys/time.h>
TEST_CASE("can probe SD", "[sd]")
TEST_CASE("can probe SD", "[sd][ignore]")
{
sdmmc_host_t config = SDMMC_HOST_DEFAULT();
sdmmc_slot_config_t slot_config = SDMMC_SLOT_CONFIG_DEFAULT();
@@ -76,7 +76,7 @@ static void do_single_write_read_test(sdmmc_card_t* card,
free(buffer);
}
TEST_CASE("can write and read back blocks", "[sd]")
TEST_CASE("can write and read back blocks", "[sd][ignore]")
{
sdmmc_host_t config = SDMMC_HOST_DEFAULT();
config.max_freq_khz = SDMMC_FREQ_HIGHSPEED;

View File

@@ -62,7 +62,7 @@ static void flash_test_task(void *arg)
vTaskDelete(NULL);
}
TEST_CASE("flash write and erase work both on PRO CPU and on APP CPU", "[spi_flash]")
TEST_CASE("flash write and erase work both on PRO CPU and on APP CPU", "[spi_flash][ignore]")
{
TaskHandle_t procpu_task;
TaskHandle_t appcpu_task;

View File

@@ -64,7 +64,7 @@ TEST_CASE("ulp add test", "[ulp]")
TEST_ASSERT_EQUAL(10 + 11, RTC_SLOW_MEM[18] & 0xffff);
}
TEST_CASE("ulp branch test", "[ulp]")
TEST_CASE("ulp branch test", "[ulp][ignore]")
{
assert(CONFIG_ULP_COPROC_RESERVE_MEM >= 260 && "this test needs ULP_COPROC_RESERVE_MEM option set in menuconfig");
memset(RTC_SLOW_MEM, 0, CONFIG_ULP_COPROC_RESERVE_MEM);
@@ -95,7 +95,7 @@ TEST_CASE("ulp branch test", "[ulp]")
TEST_ASSERT_EQUAL(0, RTC_SLOW_MEM[64]);
}
TEST_CASE("ulp wakeup test", "[ulp]")
TEST_CASE("ulp wakeup test", "[ulp][ignore]")
{
assert(CONFIG_ULP_COPROC_RESERVE_MEM >= 260 && "this test needs ULP_COPROC_RESERVE_MEM option set in menuconfig");
memset(RTC_SLOW_MEM, 0, CONFIG_ULP_COPROC_RESERVE_MEM);
@@ -121,7 +121,7 @@ TEST_CASE("ulp wakeup test", "[ulp]")
esp_deep_sleep_start();
}
TEST_CASE("ulp controls RTC_IO", "[ulp]")
TEST_CASE("ulp controls RTC_IO", "[ulp][ignore]")
{
assert(CONFIG_ULP_COPROC_RESERVE_MEM >= 260 && "this test needs ULP_COPROC_RESERVE_MEM option set in menuconfig");
memset(RTC_SLOW_MEM, 0, CONFIG_ULP_COPROC_RESERVE_MEM);

View File

@@ -36,6 +36,7 @@ Contents:
Secure Boot <security/secure-boot>
Deep Sleep Wake Stubs <deep-sleep-stub>
ULP Coprocessor <ulp>
Unit Testing <unit-tests>
.. toctree::
:caption: API Reference
@@ -78,4 +79,3 @@ Indices
=======
* :ref:`genindex`

68
docs/unit-tests.rst Normal file
View File

@@ -0,0 +1,68 @@
Unit Testing in ESP32
=====================
ESP-IDF comes with a unit test app based on Unity - unit test framework. Unit tests are integrated in the ESP-IDF repository and are placed in ``test`` subdirectory of each component respectively.
Adding unit tests
-----------------
Unit tests are added in the ``test`` subdirectory of the respective component.
Tests are added in C files, a single C file can include multiple test cases.
Test files start with the word "test".
The test file should include unity.h and the header for the C module to be tested.
Tests are added in a function in the C file as follows::
TEST_CASE("test name", "[module name]"
{
// Add test here
}
First argument is a descriptive name for the test, second argument is an identifier in square brackets.
Identifiers are used to group related test, or tests with specific properties.
There is no need to add a main function with ``UNITY_BEGIN()`` and ``UNITY_END()`` in each test case.
``unity_platform.c`` will run ``UNITY_BEGIN()``, run the tests cases, and then call ``UNITY_END()``.
Each `test` subdirectory needs to include component.mk file with at least the following line of code::
COMPONENT_ADD_LDFLAGS = -Wl,--whole-archive -l$(COMPONENT_NAME) -Wl,--no-whole-archive
See http://www.throwtheswitch.org/unity for more information about writing tests in Unity.
Building unit test app
----------------------
Follow the setup instructions in the top-level esp-idf README.
Make sure that IDF_PATH environment variable is set to point to the path of esp-idf top-level directory.
Change into tools/unit-test-app directory to configure and build it:
* `make menuconfig` - configure unit test app.
* `make TESTS_ALL=1` - build unit test app with tests for each component having tests in the ``test`` subdirectory.
* `make TEST_COMPONENTS='xxx'` - build unit test app with tests for specific components.
When the build finishes, it will print instructions for flashing the chip. You can simply run ``make flash`` to flash all build output.
You can also run ``make flash TESTS_ALL=1`` or ``make TEST_COMPONENTS='xxx'`` to build and flash. Everything needed will be rebuilt automatically before flashing.
Use menuconfig to set the serial port for flashing.
Running unit tests
------------------
After flashing reset the ESP32 and it will boot the unit test app.
Unit test app prints a test menu with all available tests.
Test cases can be run by inputting one of the following:
- Test case name in quotation marks to run a single test case
- Test case index to run a single test case
- Module name in square brackets to run all test cases for a specific module
- An asterisk to run all test cases

View File

@@ -0,0 +1,127 @@
freertos:
module: System
module abbr: SYS
sub module: OS
sub module abbr: OS
nvs:
module: System
module abbr: SYS
sub module: NVS
sub module abbr: NVS
partition:
module: System
module abbr: SYS
sub module: Misc
sub module abbr: MISC
ulp:
module: System
module abbr: SYS
sub module: Misc
sub module abbr: MISC
fp:
module: System
module abbr: SYS
sub module: Misc
sub module abbr: MISC
hw:
module: System
module abbr: SYS
sub module: Misc
sub module abbr: MISC
tjpgd:
module: System
module abbr: SYS
sub module: Misc
sub module abbr: MISC
miniz:
module: System
module abbr: SYS
sub module: Misc
sub module abbr: MISC
mmap:
module: System
module abbr: SYS
sub module: Misc
sub module abbr: MISC
bignum:
module: System
module abbr: SYS
sub module: Misc
sub module abbr: MISC
newlib:
module: System
module abbr: SYS
sub module: Std Lib
sub module abbr: STD
aes:
module: System
module abbr: SYS
sub module: Misc
sub module abbr: MISC
mbedtls:
module: System
module abbr: SYS
sub module: Misc
sub module abbr: MISC
spi_flash:
module: Driver
module abbr: DRV
sub module: SPI
sub module abbr: SPI
spi_flash_read:
module: Driver
module abbr: DRV
sub module: SPI
sub module abbr: SPI
spi_flash_write:
module: Driver
module abbr: DRV
sub module: SPI
sub module abbr: SPI
esp32:
module: System
module abbr: SYS
sub module: Misc
sub module abbr: MISC
deepsleep:
module: RTC
module abbr: RTC
sub module: Deep Sleep
sub module abbr: SLEEP
sd:
module: System
module abbr: SYS
sub module: Misc
sub module abbr: MISC
cxx:
module: System
module abbr: SYS
sub module: Misc
sub module abbr: MISC
fatfs:
module: System
module abbr: SYS
sub module: Misc
sub module abbr: MISC
delay:
module: System
module abbr: SYS
sub module: Misc
sub module abbr: MISC
spi:
module: System
module abbr: SYS
sub module: Misc
sub module abbr: MISC
vfs:
module: System
module abbr: SYS
sub module: Misc
sub module abbr: MISC
misc:
module: System
module abbr: SYS
sub module: Misc
sub module abbr: MISC

View File

@@ -0,0 +1,169 @@
import yaml
import os
import re
import sys
import shutil
MODULE_MAP = yaml.load(open("ModuleDefinition.yml", "r"))
TEST_CASE_PATTERN = {
"initial condition": "UTINIT1",
"SDK": "ESP32_IDF",
"level": "Unit",
"execution time": 0,
"Test App": "UT",
"auto test": "Yes",
"category": "Function",
"test point 1": "basic function",
"version": "v1 (2016-12-06)",
"test environment": "UT_T1_1",
"expected result": "1. set succeed"
}
CONFIG_FILE_PATTERN = {
"Config": {"execute count": 1, "execute order": "in order"},
"DUT": [],
"Filter": [{"Add": {"ID": []}}]
}
test_cases = list()
test_ids = {}
test_ids_by_job = {}
unit_jobs = {}
os.chdir(os.path.join("..", ".."))
IDF_PATH = os.getcwd()
class Parser(object):
@classmethod
def parse_test_folders(cls):
test_folder_paths = list()
os.chdir(os.path.join(IDF_PATH, "components"))
component_dirs = os.listdir(".")
for dir in component_dirs:
os.chdir(dir)
if "test" in os.listdir("."):
test_folder_paths.append(os.path.join(os.getcwd(), "test"))
os.chdir("..")
Parser.parse_test_files(test_folder_paths)
@classmethod
def parse_test_files(cls, test_folder_paths):
for path in test_folder_paths:
os.chdir(path)
for file_path in os.listdir("."):
if file_path[-2:] == ".c":
Parser.read_test_file(os.path.join(os.getcwd(), file_path), len(test_cases)+1)
os.chdir(os.path.join("..", ".."))
Parser.dump_test_cases(test_cases)
@classmethod
def read_test_file(cls, test_file_path, file_index):
test_index = 0
with open(test_file_path, "r") as file:
for line in file:
if re.match("TEST_CASE", line):
test_index += 1
tags = re.split(r"[\[\]\"]", line)
Parser.parse_test_cases(file_index, test_index, tags)
@classmethod
def parse_test_cases(cls, file_index, test_index, tags):
ci_ready = "Yes"
test_env = "UT_T1_1"
for tag in tags:
if tag == "ignore":
ci_ready = "No"
if re.match("test_env=", tag):
test_env = tag[9:]
module_name = tags[4]
try:
MODULE_MAP[module_name]
except KeyError:
module_name = "misc"
id = "UT_%s_%s_%03d%02d" % (MODULE_MAP[module_name]['module abbr'],
MODULE_MAP[module_name]['sub module abbr'],
file_index, test_index)
test_case = dict(TEST_CASE_PATTERN)
test_case.update({"module": MODULE_MAP[module_name]['module'],
"CI ready": ci_ready,
"cmd set": ["IDFUnitTest/UnitTest", [tags[1]]],
"ID": id,
"test point 2": module_name,
"steps": tags[1],
"comment": tags[1],
"test environment": test_env,
"sub module": MODULE_MAP[module_name]['sub module'],
"summary": tags[1]})
if test_case["CI ready"] == "Yes":
if test_ids.has_key(test_env):
test_ids[test_env].append(id)
else:
test_ids.update({test_env: [id]})
test_cases.append(test_case)
@classmethod
def dump_test_cases(cls, test_cases):
os.chdir(os.path.join(IDF_PATH, "components", "idf_test", "unit_test"))
with open ("TestCaseAll.yml", "wb+") as f:
yaml.dump({"test cases": test_cases}, f, allow_unicode=True, default_flow_style=False)
@classmethod
def dump_ci_config(cls):
Parser.split_test_cases()
os.chdir(os.path.join(IDF_PATH, "components", "idf_test", "unit_test"))
if not os.path.exists("CIConfigs"):
os.makedirs("CIConfigs")
os.chdir("CIConfigs")
for unit_job in unit_jobs:
job = dict(CONFIG_FILE_PATTERN)
job.update({"DUT": ["UT1"]})
job.update({"Filter": [{"Add": {"ID": test_ids_by_job[unit_job]}}]})
with open (unit_job + ".yml", "wb+") as f:
yaml.dump(job, f, allow_unicode=True, default_flow_style=False)
@classmethod
def split_test_cases(cls):
for job in unit_jobs:
test_ids_by_job.update({job: list()})
for test_env in test_ids:
available_jobs = list()
for job in unit_jobs:
if test_env in unit_jobs[job]:
available_jobs.append(job)
for idx, job in enumerate(available_jobs):
test_ids_by_job[job] += (test_ids[test_env][idx*len(test_ids[test_env])/len(available_jobs):(idx+1)*len(test_ids[test_env])/len(available_jobs)])
@classmethod
def parse_gitlab_ci(cls):
os.chdir(IDF_PATH)
with open(".gitlab-ci.yml", "rb") as f:
gitlab_ci = yaml.load(f)
keys = gitlab_ci.keys()
for key in keys:
if re.match("UT_", key):
test_env = gitlab_ci[key]["tags"]
unit_job = key
key = {}
key.update({unit_job: test_env})
unit_jobs.update(key)
@classmethod
def copy_module_def_file(cls):
src = os.path.join(IDF_PATH, "tools", "unit-test-app", "ModuleDefinition.yml")
dst = os.path.join(IDF_PATH, "components", "idf_test", "unit_test")
shutil.copy(src, dst)
def main():
Parser.parse_test_folders()
Parser.parse_gitlab_ci()
Parser.dump_ci_config()
Parser.copy_module_def_file()
if __name__ == '__main__':
main()