Merge branch 'feature/update_unit_test_app' into 'master'

Update unit-test-app

See merge request sdk/ESP8266_RTOS_SDK!845
This commit is contained in:
Dong Heng
2019-04-01 10:40:46 +08:00
32 changed files with 693 additions and 1594 deletions

View File

@ -1,4 +0,0 @@
#
#Component Makefile
#
COMPONENT_ADD_LDFLAGS = -Wl,--whole-archive -l$(COMPONENT_NAME) -Wl,--no-whole-archive

View File

@ -1,94 +0,0 @@
/*
* Tests for bootloader_support esp_load(ESP_IMAGE_VERIFY, ...)
*/
#include <esp_types.h>
#include <stdio.h>
#include "string.h"
#include "rom/ets_sys.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/semphr.h"
#include "freertos/queue.h"
#include "freertos/xtensa_api.h"
#include "unity.h"
#include "bootloader_common.h"
#include "esp_partition.h"
#include "esp_ota_ops.h"
#include "esp_image_format.h"
TEST_CASE("Verify bootloader image in flash", "[bootloader_support]")
{
const esp_partition_pos_t fake_bootloader_partition = {
.offset = ESP_BOOTLOADER_OFFSET,
.size = ESP_PARTITION_TABLE_OFFSET - ESP_BOOTLOADER_OFFSET,
};
esp_image_metadata_t data = { 0 };
TEST_ASSERT_EQUAL_HEX(ESP_OK, esp_image_load(ESP_IMAGE_VERIFY, &fake_bootloader_partition, &data));
TEST_ASSERT_NOT_EQUAL(0, data.image_len);
uint32_t bootloader_length = 0;
TEST_ASSERT_EQUAL_HEX(ESP_OK, esp_image_verify_bootloader(&bootloader_length));
TEST_ASSERT_EQUAL(data.image_len, bootloader_length);
}
TEST_CASE("Verify unit test app image", "[bootloader_support]")
{
esp_image_metadata_t data = { 0 };
const esp_partition_t *running = esp_ota_get_running_partition();
TEST_ASSERT_NOT_EQUAL(NULL, running);
const esp_partition_pos_t running_pos = {
.offset = running->address,
.size = running->size,
};
TEST_ASSERT_EQUAL_HEX(ESP_OK, esp_image_load(ESP_IMAGE_VERIFY, &running_pos, &data));
TEST_ASSERT_NOT_EQUAL(0, data.image_len);
TEST_ASSERT_TRUE(data.image_len <= running->size);
}
void check_label_search (int num_test, const char *list, const char *t_label, bool result)
{
// gen_esp32part.py trims up to 16 characters
// and the string may not have a null terminal symbol.
// below is cutting as it does the generator.
char label[16 + 1] = {0};
strncpy(label, t_label, sizeof(label) - 1);
bool ret = bootloader_common_label_search(list, label);
if (ret != result) {
printf("%d) %s | %s \n", num_test, list, label);
}
TEST_ASSERT_MESSAGE(ret == result, "Test failed");
}
TEST_CASE("Test label_search", "[bootloader_support]")
{
TEST_ASSERT_FALSE(bootloader_common_label_search(NULL, NULL));
TEST_ASSERT_FALSE(bootloader_common_label_search("nvs", NULL));
check_label_search(1, "nvs", "nvs", true);
check_label_search(2, "nvs, ", "nvs", true);
check_label_search(3, "nvs1", "nvs", false);
check_label_search(3, "nvs1, ", "nvs", false);
check_label_search(4, "nvs1nvs1, phy", "nvs1", false);
check_label_search(5, "nvs1, nvs1, phy", "nvs1", true);
check_label_search(6, "nvs12, nvs12, phy", "nvs1", false);
check_label_search(7, "nvs12, nvs1, phy", "nvs1", true);
check_label_search(8, "nvs12, nvs3, phy, nvs1","nvs1", true);
check_label_search(9, "nvs1nvs1, phy, nvs", "nvs", true);
check_label_search(10, "nvs1nvs1, phy, nvs1", "nvs", false);
check_label_search(11, "nvs1, nvs, phy, nvs1", "nvs", true);
check_label_search(12, "nvs1, nvs2, phy, nvs","nvs", true);
check_label_search(13, "ota_data, backup_nvs", "nvs", false);
check_label_search(14, "nvs1, nvs2, ota, nvs", "vs1", false);
check_label_search(20, "12345678901234, phy, nvs1", "12345678901234", true);
check_label_search(21, "123456789012345, phy, nvs1", "123456789012345", true);
check_label_search(22, "1234567890123456, phy, nvs1", "1234567890123456", true);
check_label_search(23, "12345678901234567, phy, nvs1", "12345678901234567", false);
check_label_search(24, "1234567890123456, phy, nvs1", "12345678901234567", true);
check_label_search(25, "phy, 1234567890123456, nvs1", "12345678901234567", true);
}

View File

@ -0,0 +1,25 @@
// Copyright 2015-2017 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#pragma once
/**
* @brief Return current CPU clock frequency
* When frequency switching is performed, this frequency may change.
* However it is guaranteed that the frequency never changes with a critical
* section.
*
* @return CPU clock frequency, in Hz
*/
int esp_clk_cpu_freq(void);

View File

@ -43,6 +43,14 @@ extern "C" {
#define ETS_WDT_INUM 8
#define ETS_FRC_TIMER1_INUM 9
typedef enum {
OK = 0,
FAIL,
PENDING,
BUSY,
CANCEL,
} STATUS;
extern char NMIIrqIsOn;
extern uint32_t WDEV_INTEREST_EVENT;

View File

@ -0,0 +1,127 @@
// Copyright 2010-2016 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef _ROM_UART_H_
#define _ROM_UART_H_
#include "esp_types.h"
#include "esp_attr.h"
#include "ets_sys.h"
#include "esp8266/uart_struct.h"
#include "esp8266/uart_register.h"
#include "esp8266/pin_mux_register.h"
#include "esp8266/eagle_soc.h"
#include "esp8266/rom_functions.h"
#include "driver/soc.h"
#ifdef __cplusplus
extern "C" {
#endif
/** \defgroup uart_apis, uart configuration and communication related apis
* @brief uart apis
*/
/** @addtogroup uart_apis
* @{
*/
/**
* @brief Wait until uart tx full empty and the last char send ok.
*
* @param uart_no : 0 for UART0, 1 for UART1, 2 for UART2
*
* The function defined in ROM code has a bug, so we define the correct version
* here for compatibility.
*/
static inline void IRAM_ATTR uart_tx_wait_idle(uint8_t uart_no) {
uint32_t tx_bytes;
uint32_t baudrate, byte_delay_us;
uart_dev_t *const UART[2] = {&uart0, &uart1};
uart_dev_t *const uart = UART[uart_no];
baudrate = (UART_CLK_FREQ / (uart->clk_div.val & 0xFFFFF));
byte_delay_us = (uint32_t)(10000000 / baudrate);
do {
tx_bytes = uart->status.txfifo_cnt;
/* either tx count or state is non-zero */
} while (tx_bytes);
ets_delay_us(byte_delay_us);
}
/**
* @brief Output a char to printf channel, wait until fifo not full.
*
* @param None
*
* @return OK.
*/
STATUS uart_tx_one_char(uint8_t TxChar);
/**
* @brief Get an input char from message channel.
* Please do not call this function in SDK.
*
* @param uint8_t *pRxChar : the pointer to store the char.
*
* @return OK for successful.
* FAIL for failed.
*/
STATUS uart_rx_one_char(uint8_t *pRxChar);
/**
* @brief Get an input string line from message channel.
* Please do not call this function in SDK.
*
* @param uint8_t *pString : the pointer to store the string.
*
* @param uint8_t MaxStrlen : the max string length, incude '\0'.
*
* @return OK.
*/
static inline STATUS UartRxString(uint8_t *pString, uint8_t MaxStrlen)
{
int rx_bytes = 0;
while(1) {
uint8_t data;
while (uart_rx_one_char(&data) != OK);
if (data == '\n' || data == '\r')
data = '\0';
pString[rx_bytes++] = data;
if (data == '\0')
return OK;
if (rx_bytes >= MaxStrlen)
return FAIL;
}
return OK;
}
/**
* @}
*/
#ifdef __cplusplus
}
#endif
#endif /* _ROM_UART_H_ */

View File

@ -0,0 +1,40 @@
// Copyright 2010-2016 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef _SOC_CPU_H
#define _SOC_CPU_H
#include <stdint.h>
#include <stdbool.h>
#include <stddef.h>
#include "xtensa/corebits.h"
#include "xtensa/config/core.h"
/* C macros for xtensa special register read/write/exchange */
#define RSR(reg, curval) asm volatile ("rsr %0, " #reg : "=r" (curval));
#define WSR(reg, newval) asm volatile ("wsr %0, " #reg : : "r" (newval));
#define XSR(reg, swapval) asm volatile ("xsr %0, " #reg : "+r" (swapval));
/** @brief Read current stack pointer address
*
*/
static inline void *get_sp()
{
void *sp;
asm volatile ("mov %0, sp;" : "=r" (sp));
return sp;
}
#endif

View File

@ -57,4 +57,5 @@ PROVIDE ( gpio_input_get = 0x40004cf0 );
PROVIDE ( gpio_pin_wakeup_disable = 0x40004ed4 );
PROVIDE ( gpio_pin_wakeup_enable = 0x40004e90 );
PROVIDE ( ets_io_vprintf = 0x40001f00 );
PROVIDE ( ets_io_vprintf = 0x40001f00 );
PROVIDE ( uart_rx_one_char = 0x40003b8c );

View File

@ -1,6 +0,0 @@
set(COMPONENT_SRCDIRS ".")
set(COMPONENT_ADD_INCLUDEDIRS ".")
set(COMPONENT_REQUIRES unity esp_http_server)
register_component()

View File

@ -1 +0,0 @@
COMPONENT_ADD_LDFLAGS = -Wl,--whole-archive -l$(COMPONENT_NAME) -Wl,--no-whole-archive

View File

@ -1,169 +0,0 @@
// Copyright 2018 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include <stdlib.h>
#include <stdbool.h>
#include <esp_system.h>
#include <esp_http_server.h>
#include "unity.h"
#include "test_utils.h"
int pre_start_mem, post_stop_mem, post_stop_min_mem;
bool basic_sanity = true;
esp_err_t null_func(httpd_req_t *req)
{
return ESP_OK;
}
httpd_uri_t handler_limit_uri (char* path)
{
httpd_uri_t uri = {
.uri = path,
.method = HTTP_GET,
.handler = null_func,
.user_ctx = NULL,
};
return uri;
};
static inline unsigned num_digits(unsigned x)
{
unsigned digits = 1;
while ((x = x/10) != 0) {
digits++;
}
return digits;
}
#define HTTPD_TEST_MAX_URI_HANDLERS 8
void test_handler_limit(httpd_handle_t hd)
{
int i;
char x[HTTPD_TEST_MAX_URI_HANDLERS+1][num_digits(HTTPD_TEST_MAX_URI_HANDLERS)+1];
httpd_uri_t uris[HTTPD_TEST_MAX_URI_HANDLERS+1];
for (i = 0; i < HTTPD_TEST_MAX_URI_HANDLERS + 1; i++) {
sprintf(x[i],"%d",i);
uris[i] = handler_limit_uri(x[i]);
}
/* Register multiple instances of the same handler for MAX URI Handlers */
for (i = 0; i < HTTPD_TEST_MAX_URI_HANDLERS; i++) {
TEST_ASSERT(httpd_register_uri_handler(hd, &uris[i]) == ESP_OK);
}
/* Register the MAX URI + 1 Handlers should fail */
TEST_ASSERT(httpd_register_uri_handler(hd, &uris[HTTPD_TEST_MAX_URI_HANDLERS]) != ESP_OK);
/* Unregister the one of the Handler should pass */
TEST_ASSERT(httpd_unregister_uri_handler(hd, uris[0].uri, uris[0].method) == ESP_OK);
/* Unregister non added Handler should fail */
TEST_ASSERT(httpd_unregister_uri_handler(hd, uris[0].uri, uris[0].method) != ESP_OK);
/* Register the MAX URI Handler should pass */
TEST_ASSERT(httpd_register_uri_handler(hd, &uris[0]) == ESP_OK);
/* Reregister same instance of handler should fail */
TEST_ASSERT(httpd_register_uri_handler(hd, &uris[0]) != ESP_OK);
/* Register the MAX URI + 1 Handlers should fail */
TEST_ASSERT(httpd_register_uri_handler(hd, &uris[HTTPD_TEST_MAX_URI_HANDLERS]) != ESP_OK);
/* Unregister the same handler for MAX URI Handlers */
for (i = 0; i < HTTPD_TEST_MAX_URI_HANDLERS; i++) {
TEST_ASSERT(httpd_unregister_uri_handler(hd, uris[i].uri, uris[i].method) == ESP_OK);
}
basic_sanity = false;
}
/********************* Test Handler Limit End *******************/
httpd_handle_t test_httpd_start(uint16_t id)
{
httpd_handle_t hd;
httpd_config_t config = HTTPD_DEFAULT_CONFIG();
config.max_uri_handlers = HTTPD_TEST_MAX_URI_HANDLERS;
config.server_port += id;
config.ctrl_port += id;
TEST_ASSERT(httpd_start(&hd, &config) == ESP_OK)
return hd;
}
#define SERVER_INSTANCES 2
/* Currently this only tests for the number of tasks.
* Heap leakage is not tested as LWIP allocates memory
* which may not be freed immedietly causing erroneous
* evaluation. Another test to implement would be the
* monitoring of open sockets, but LWIP presently provides
* no such API for getting the number of open sockets.
*/
TEST_CASE("Leak Test", "[HTTP SERVER]")
{
httpd_handle_t hd[SERVER_INSTANCES];
unsigned task_count;
bool res = true;
test_case_uses_tcpip();
task_count = uxTaskGetNumberOfTasks();
printf("Initial task count: %d\n", task_count);
pre_start_mem = esp_get_free_heap_size();
for (int i = 0; i < SERVER_INSTANCES; i++) {
hd[i] = test_httpd_start(i);
vTaskDelay(10);
unsigned num_tasks = uxTaskGetNumberOfTasks();
task_count++;
if (num_tasks != task_count) {
printf("Incorrect task count (starting): %d expected %d\n",
num_tasks, task_count);
res = false;
}
}
for (int i = 0; i < SERVER_INSTANCES; i++) {
if (httpd_stop(hd[i]) != ESP_OK) {
printf("Failed to stop httpd task %d\n", i);
res = false;
}
vTaskDelay(10);
unsigned num_tasks = uxTaskGetNumberOfTasks();
task_count--;
if (num_tasks != task_count) {
printf("Incorrect task count (stopping): %d expected %d\n",
num_tasks, task_count);
res = false;
}
}
post_stop_mem = esp_get_free_heap_size();
TEST_ASSERT(res == true);
}
TEST_CASE("Basic Functionality Tests", "[HTTP SERVER]")
{
httpd_handle_t hd;
httpd_config_t config = HTTPD_DEFAULT_CONFIG();
test_case_uses_tcpip();
TEST_ASSERT(httpd_start(&hd, &config) == ESP_OK);
test_handler_limit(hd);
TEST_ASSERT(httpd_stop(hd) == ESP_OK);
}

View File

@ -148,6 +148,14 @@ void TASK_SW_ATTR xPortSysTickHandle(void)
}
}
/**
* @brief Return current CPU clock frequency
*/
int esp_clk_cpu_freq(void)
{
return _xt_tick_divisor * XT_TICK_PER_SEC;
}
/*
* See header file for description.
*/

View File

@ -1,5 +0,0 @@
#
#Component Makefile
#
COMPONENT_ADD_LDFLAGS = -Wl,--whole-archive -l$(COMPONENT_NAME) -Wl,--no-whole-archive

View File

@ -1,97 +0,0 @@
#include <stdio.h>
#include <stdlib.h>
#include "unity.h"
#include "test_utils.h"
#include "esp_partition.h"
TEST_CASE("Can read partition table", "[partition]")
{
const esp_partition_t *p = esp_partition_find_first(ESP_PARTITION_TYPE_APP, ESP_PARTITION_SUBTYPE_ANY, NULL);
TEST_ASSERT_NOT_NULL(p);
TEST_ASSERT_EQUAL(0x10000, p->address);
TEST_ASSERT_EQUAL(ESP_PARTITION_SUBTYPE_APP_FACTORY, p->subtype);
esp_partition_iterator_t it = esp_partition_find(ESP_PARTITION_TYPE_DATA, ESP_PARTITION_SUBTYPE_ANY, NULL);
TEST_ASSERT_NOT_NULL(it);
int count = 0;
const esp_partition_t* prev = NULL;
for (; it != NULL; it = esp_partition_next(it)) {
const esp_partition_t *p = esp_partition_get(it);
TEST_ASSERT_NOT_NULL(p);
if (prev) {
TEST_ASSERT_TRUE_MESSAGE(prev->address < p->address, "incorrect partition order");
}
prev = p;
++count;
}
esp_partition_iterator_release(it);
TEST_ASSERT_EQUAL(4, count);
}
TEST_CASE("Can write, read, mmap partition", "[partition][ignore]")
{
const esp_partition_t *p = get_test_data_partition();
printf("Using partition %s at 0x%x, size 0x%x\n", p->label, p->address, p->size);
TEST_ASSERT_NOT_NULL(p);
const size_t max_size = 2 * SPI_FLASH_SEC_SIZE;
uint8_t *data = (uint8_t *) malloc(max_size);
TEST_ASSERT_NOT_NULL(data);
TEST_ASSERT_EQUAL(ESP_OK, esp_partition_erase_range(p, 0, p->size));
srand(0);
size_t block_size;
for (size_t offset = 0; offset < p->size; offset += block_size) {
block_size = ((rand() + 4) % max_size) & (~0x3);
size_t left = p->size - offset;
if (block_size > left) {
block_size = left;
}
for (size_t i = 0; i < block_size / 4; ++i) {
((uint32_t *) (data))[i] = rand();
}
TEST_ASSERT_EQUAL(ESP_OK, esp_partition_write(p, offset, data, block_size));
}
srand(0);
for (size_t offset = 0; offset < p->size; offset += block_size) {
block_size = ((rand() + 4) % max_size) & (~0x3);
size_t left = p->size - offset;
if (block_size > left) {
block_size = left;
}
TEST_ASSERT_EQUAL(ESP_OK, esp_partition_read(p, offset, data, block_size));
for (size_t i = 0; i < block_size / 4; ++i) {
TEST_ASSERT_EQUAL(rand(), ((uint32_t *) data)[i]);
}
}
free(data);
const uint32_t *mmap_data;
spi_flash_mmap_handle_t mmap_handle;
size_t begin = 3000;
size_t size = 64000; //chosen so size is smaller than 64K but the mmap straddles 2 MMU blocks
TEST_ASSERT_EQUAL(ESP_OK, esp_partition_mmap(p, begin, size, SPI_FLASH_MMAP_DATA,
(const void **)&mmap_data, &mmap_handle));
srand(0);
for (size_t offset = 0; offset < p->size; offset += block_size) {
block_size = ((rand() + 4) % max_size) & (~0x3);
size_t left = p->size - offset;
if (block_size > left) {
block_size = left;
}
for (size_t i = 0; i < block_size / 4; ++i) {
size_t pos = offset + i * 4;
uint32_t expected = rand();
if (pos < begin || pos >= (begin + size)) {
continue;
}
TEST_ASSERT_EQUAL(expected, mmap_data[(pos - begin) / 4]);
}
}
spi_flash_munmap(mmap_handle);
}

View File

@ -1,7 +0,0 @@
set(COMPONENT_SRCDIRS ".")
set(COMPONENT_ADD_INCLUDEDIRS ".")
set(COMPONENT_PRIV_INCLUDEDIRS "../proto-c/")
set(COMPONENT_REQUIRES unity mbedtls protocomm protobuf-c)
register_component()

View File

@ -1,2 +0,0 @@
COMPONENT_PRIV_INCLUDEDIRS := ../proto-c/
COMPONENT_ADD_LDFLAGS = -Wl,--whole-archive -l$(COMPONENT_NAME) -Wl,--no-whole-archive

File diff suppressed because it is too large Load Diff