diff --git a/.gitignore b/.gitignore index 2870b4a805..25a5a30910 100644 --- a/.gitignore +++ b/.gitignore @@ -24,3 +24,8 @@ examples/*/build docs/_build/ docs/doxygen-warning-log.txt docs/xml/ + +# Unit test app files +tools/unit-test-app/sdkconfig +tools/unit-test-app/sdkconfig.old +tools/unit-test-app/build diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 814279ce15..1d68d2f601 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -78,15 +78,14 @@ build_esp_idf_tests: <<: *build_template artifacts: paths: - - ./esp-idf-tests/build/*.bin - - ./esp-idf-tests/build/*.elf - - ./esp-idf-tests/build/*.map - - ./esp-idf-tests/build/bootloader/*.bin + - ./tools/unit-test-app/build/*.bin + - ./tools/unit-test-app/build/*.elf + - ./tools/unit-test-app/build/*.map + - ./tools/unit-test-app/build/bootloader/*.bin expire_in: 6 mos script: - - git clone $GITLAB_SSH_SERVER/idf/esp-idf-tests.git - - cd esp-idf-tests + - cd tools/unit-test-app - git checkout ${CI_BUILD_REF_NAME} || echo "Using default branch..." - make defconfig - make @@ -131,7 +130,7 @@ test_nvs_on_host: tags: - nvs_host_test script: - - cd components/nvs_flash/test + - cd components/nvs_flash/test_nvs_host - make test test_build_system: diff --git a/components/bootloader/Makefile.projbuild b/components/bootloader/Makefile.projbuild index 3faff53d62..a49f3d8686 100644 --- a/components/bootloader/Makefile.projbuild +++ b/components/bootloader/Makefile.projbuild @@ -20,7 +20,7 @@ export SECURE_BOOT_SIGNING_KEY # used by bootloader_support component # Custom recursive make for bootloader sub-project BOOTLOADER_MAKE=+$(MAKE) -C $(BOOTLOADER_COMPONENT_PATH)/src \ - V=$(V) BUILD_DIR_BASE=$(BOOTLOADER_BUILD_DIR) + V=$(V) BUILD_DIR_BASE=$(BOOTLOADER_BUILD_DIR) TEST_COMPONENTS= .PHONY: bootloader-clean bootloader-flash bootloader $(BOOTLOADER_BIN) diff --git a/components/esp32/test/Kconfig b/components/esp32/test/Kconfig new file mode 100644 index 0000000000..af5e5b45e7 --- /dev/null +++ b/components/esp32/test/Kconfig @@ -0,0 +1,9 @@ +menu "TESTS" + +config FP_TEST_ENABLE + bool "Enable test fp" + default "y" + help + For FPGA single core CPU which has no floating point support, floating point test should be disabled. + +endmenu diff --git a/components/esp32/test/component.mk b/components/esp32/test/component.mk new file mode 100644 index 0000000000..5e7d11ddf8 --- /dev/null +++ b/components/esp32/test/component.mk @@ -0,0 +1,17 @@ +# +#Component Makefile +# + +COMPONENT_EXTRA_CLEAN := test_tjpgd_logo.h + +COMPONENT_ADD_LDFLAGS = -Wl,--whole-archive -l$(COMPONENT_NAME) -Wl,--no-whole-archive + +COMPONENT_SRCDIRS := . test_vectors + +include $(IDF_PATH)/make/component_common.mk + +test_tjpgd.o: test_tjpgd_logo.h + +test_tjpgd_logo.h: $(COMPONENT_PATH)/logo.jpg + $(summary) XXD logo.jpg + $(Q) cd $(COMPONENT_PATH); xxd -i logo.jpg $(COMPONENT_BUILD_DIR)/test_tjpgd_logo.h diff --git a/components/esp32/test/logo.jpg b/components/esp32/test/logo.jpg new file mode 100644 index 0000000000..2bd9e775ea Binary files /dev/null and b/components/esp32/test/logo.jpg differ diff --git a/components/esp32/test/test_ahb_arb.c b/components/esp32/test/test_ahb_arb.c new file mode 100644 index 0000000000..65f4906fd5 --- /dev/null +++ b/components/esp32/test/test_ahb_arb.c @@ -0,0 +1,293 @@ + +#include +#include +#include +#include "rom/ets_sys.h" +#include "rom/lldesc.h" +#include "rom/gpio.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 "soc/uart_reg.h" +#include "soc/dport_reg.h" +#include "soc/io_mux_reg.h" +#include "soc/gpio_sig_map.h" +#include "soc/gpio_reg.h" +#include "soc/i2s_reg.h" + + +#define DPORT_I2S0_CLK_EN (BIT(4)) +#define DPORT_I2S0_RST (BIT(4)) + + +/* +This test tests the s32c1i instruction when the AHB bus is also used. To create some AHB traffic, we use the I2S interface +to copy bytes over from one memory location to another. DO NOT USE the i2s routines inhere, they've been trial-and-error'ed until +the point where they happened to do what I want. +*/ + +static void lcdIfaceInit() +{ + SET_PERI_REG_MASK(DPORT_PERIP_CLK_EN_REG, DPORT_I2S0_CLK_EN); + CLEAR_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG, DPORT_I2S0_RST); + + //Init pins to i2s functions + SET_PERI_REG_MASK(GPIO_ENABLE_W1TS_REG, (1 << 11) | (1 << 3) | (1 << 0) | (1 << 2) | (1 << 5) | (1 << 16) | (1 << 17) | (1 << 18) | (1 << 19) | (1 << 20)); //ENABLE GPIO oe_enable + + PIN_FUNC_SELECT(PERIPHS_IO_MUX_GPIO0_U, 0); + PIN_FUNC_SELECT(PERIPHS_IO_MUX_GPIO2_U, 0); + PIN_FUNC_SELECT(PERIPHS_IO_MUX_GPIO5_U, 0); + PIN_FUNC_SELECT(PERIPHS_IO_MUX_GPIO16_U, 0); + PIN_FUNC_SELECT(PERIPHS_IO_MUX_GPIO17_U, 0); + PIN_FUNC_SELECT(PERIPHS_IO_MUX_GPIO18_U, 0); + PIN_FUNC_SELECT(PERIPHS_IO_MUX_GPIO19_U, 0); + PIN_FUNC_SELECT(PERIPHS_IO_MUX_GPIO20_U, 0); + PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_CMD_U, 2); //11 + PIN_FUNC_SELECT(PERIPHS_IO_MUX_GPIO26_U, 0); //RS + + WRITE_PERI_REG(GPIO_FUNC0_OUT_SEL_CFG_REG, (148 << GPIO_FUNC0_OUT_SEL_S)); + WRITE_PERI_REG(GPIO_FUNC2_OUT_SEL_CFG_REG, (149 << GPIO_FUNC0_OUT_SEL_S)); + WRITE_PERI_REG(GPIO_FUNC5_OUT_SEL_CFG_REG, (150 << GPIO_FUNC0_OUT_SEL_S)); + WRITE_PERI_REG(GPIO_FUNC16_OUT_SEL_CFG_REG, (151 << GPIO_FUNC0_OUT_SEL_S)); + WRITE_PERI_REG(GPIO_FUNC17_OUT_SEL_CFG_REG, (152 << GPIO_FUNC0_OUT_SEL_S)); + WRITE_PERI_REG(GPIO_FUNC18_OUT_SEL_CFG_REG, (153 << GPIO_FUNC0_OUT_SEL_S)); + WRITE_PERI_REG(GPIO_FUNC19_OUT_SEL_CFG_REG, (154 << GPIO_FUNC0_OUT_SEL_S)); + WRITE_PERI_REG(GPIO_FUNC20_OUT_SEL_CFG_REG, (155 << GPIO_FUNC0_OUT_SEL_S)); + WRITE_PERI_REG(GPIO_FUNC26_OUT_SEL_CFG_REG, (156 << GPIO_FUNC0_OUT_SEL_S)); //RS + WRITE_PERI_REG(GPIO_FUNC11_OUT_SEL_CFG_REG, (I2S0O_WS_OUT_IDX << GPIO_FUNC0_OUT_SEL_S)); +// WRITE_PERI_REG(GPIO_FUNC11_OUT_SEL_CFG, (I2S0O_BCK_OUT_IDX< +#include +#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 "soc/uart_reg.h" +#include "soc/dport_reg.h" +#include "soc/io_mux_reg.h" + + +/* +This test tests the 'fast' peripherial bus at 0x3ff40000. This bus is connected directly to the core, and as such +can receive 'speculative' reads, that is, reads that may or may not actually be executed in the code flow. This +may mess with any FIFOs mapped in the region: if a byte gets dropped due to a missed speculative read, the fifo +may advance to the next byte anyway. + +This code tests reading/writing from the UART1 FIFO, using both cores. For this to work, it's required that the +UARTs RX and TX lines are connected. +*/ + + +void test_fastbus_cp(int fifo_addr, unsigned char *buf, int len, int *dummy); + +static volatile int state = 0; +static volatile int xor = 0; +static unsigned char res[128]; + +static void tskOne(void *pvParameters) +{ + int run = 0, err = 0; + int x; + int ct[256]; + volatile int w; + int dummy; + while (1) { + state = 1; + for (x = 0; x < 64; x++) { + WRITE_PERI_REG(UART_FIFO_REG(1), x ^ xor); + } + for (w = 0; w < (1 << 14); w++); //delay + state = 2; + test_fastbus_cp(UART_FIFO_REG(1), &res[0], 64, &dummy); + for (w = 0; w < (1 << 10); w++); //delay + for (x = 0; x < 255; x++) { + ct[x] = 0; //zero ctrs + } + for (x = 0; x < 128; x++) { + ct[(int)res[x]^xor]++; //count values + } + for (x = 0; x < 255; x++) { //check counts + if (ct[x] != (x < 128 ? 1 : 0)) { + //Disregard first few loops; there may be crap in the fifo. + if (run > 2) { + err++; + printf("Error! Received value %d %d times!\n", x, ct[x]); + } + } + } + run++; + if ((run & 255) == 0) { + printf("Loop %d errct %d\n", run, err); + } + xor = (xor + 1) & 0xff; + } +} + +#define FB2ADDR 0x40098000 + +static void tskTwo(void *pvParameters) +{ + int x; + int dummy; + int *p = (int *)FB2ADDR; + int *s = (int *)test_fastbus_cp; + for (x = 0; x < 100; x++) { + *p++ = *s++; + } + void (*test_fastbus_cp2)(int fifo_addr, unsigned char * buf, int len, int * dummy) = (void *)FB2ADDR; + + + while (1) { + while (state != 1) ; + for (x = 64; x < 128; x++) { + WRITE_PERI_REG(UART_FIFO_REG(1), x ^ xor); + } + while (state != 2); + test_fastbus_cp2(UART_FIFO_REG(1), &res[64], 64, &dummy); + } +} + + +// TODO: split this thing into separate orthogonal tests +TEST_CASE("Fast I/O bus test", "[hw]") +{ + int i; + if ((REG_UART_BASE(0) >> 16) != 0x3ff4) { + printf("Error! Uart base isn't on fast bus.\n"); + TEST_ASSERT(0); + } + + PIN_PULLUP_DIS(PERIPHS_IO_MUX_SD_DATA3_U); + PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_DATA2_U, FUNC_SD_DATA2_U1RXD); + PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_DATA3_U, FUNC_SD_DATA3_U1TXD); + + int reg_val = (1 << UART_RXFIFO_FULL_THRHD_S); + WRITE_PERI_REG(UART_CONF1_REG(1), reg_val); + WRITE_PERI_REG(UART_CLKDIV_REG(1), 0x30); //semi-random +// CLEAR_PERI_REG_MASK(UART_INT_ENA_REG(1), UART_TXFIFO_EMPTY_INT_ENA|UART_RXFIFO_TOUT_INT_ENA); + + TaskHandle_t th[2]; + printf("Creating tasks\n"); + xTaskCreatePinnedToCore(tskOne , "tskone" , 2048, NULL, 3, &th[0], 0); + xTaskCreatePinnedToCore(tskTwo , "tsktwo" , 2048, NULL, 3, &th[1], 1); + + // Let stuff run for 20s + while (1) { + vTaskDelay(20000 / portTICK_PERIOD_MS); + } + + //Shut down all the tasks + for (i = 0; i < 2; i++) { + vTaskDelete(th[i]); + } + xt_ints_off(1 << ETS_UART0_INUM); +} + diff --git a/components/esp32/test/test_fastbus_asm.S b/components/esp32/test/test_fastbus_asm.S new file mode 100644 index 0000000000..1ced09fcf7 --- /dev/null +++ b/components/esp32/test/test_fastbus_asm.S @@ -0,0 +1,32 @@ +/* +This little bit of code is executed in-place by one CPU, but copied to a different memory region +by the other CPU. Make sure it stays position-independent. +*/ + .text + .align 4 + .global test_fastbus_cp + .type test_fastbus_cp,@function +//Args: +//a2 - fifo addr +//a3 - buf addr +//a4 - len +//a5 - ptr to int to use +test_fastbus_cp: + entry a1,64 +back: + beqi a4, 0, out //check if loop done + s32i a4, a5, 0 //store value, for shits and/or giggles + memw //make sure write happens + l32i a4, a5, 0 //load value again, to thwart any prediction in the pipeline + bbsi a4, 0, pred //Random jump to check predictive reads. Both branches should do the same. + l32i a6, a2, 0 //read from fifo 1 + j predout +pred: + l32i a6, a2, 0 //read from fifo 2 +predout: + s8i a6, a3, 0 //store result + addi a3, a3, 1 //inc ptr + addi a4, a4, -1 //next + j back //loop again +out: + retw //and we are done diff --git a/components/esp32/test/test_fp.c b/components/esp32/test/test_fp.c new file mode 100644 index 0000000000..5c2573b227 --- /dev/null +++ b/components/esp32/test/test_fp.c @@ -0,0 +1,195 @@ +#include +#include +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "unity.h" + +#if CONFIG_FP_TEST_ENABLE +static float addsf(float a, float b) +{ + float result; + asm volatile ( + "wfr f0, %1\n" + "wfr f1, %2\n" + "add.s f2, f0, f1\n" + "rfr %0, f2\n" + :"=r"(result):"r"(a), "r"(b) + ); + return result; +} + +static float mulsf(float a, float b) +{ + float result; + asm volatile ( + "wfr f0, %1\n" + "wfr f1, %2\n" + "mul.s f2, f0, f1\n" + "rfr %0, f2\n" + :"=r"(result):"r"(a), "r"(b) + ); + return result; +} + +static float divsf(float a, float b) +{ + float result; + asm volatile ( + "wfr f0, %1\n" + "wfr f1, %2\n" + "div0.s f3, f1 \n" + "nexp01.s f4, f1 \n" + "const.s f5, 1 \n" + "maddn.s f5, f4, f3 \n" + "mov.s f6, f3 \n" + "mov.s f7, f1 \n" + "nexp01.s f8, f0 \n" + "maddn.s f6, f5, f3 \n" + "const.s f5, 1 \n" + "const.s f2, 0 \n" + "neg.s f9, f8 \n" + "maddn.s f5,f4,f6 \n" + "maddn.s f2, f0, f3 \n" + "mkdadj.s f7, f0 \n" + "maddn.s f6,f5,f6 \n" + "maddn.s f9,f4,f2 \n" + "const.s f5, 1 \n" + "maddn.s f5,f4,f6 \n" + "maddn.s f2,f9,f6 \n" + "neg.s f9, f8 \n" + "maddn.s f6,f5,f6 \n" + "maddn.s f9,f4,f2 \n" + "addexpm.s f2, f7 \n" + "addexp.s f6, f7 \n" + "divn.s f2,f9,f6\n" + "rfr %0, f2\n" + :"=r"(result):"r"(a), "r"(b) + ); + return result; +} + +static float sqrtsf(float a) +{ + float result; + asm volatile ( + "wfr f0, %1\n" + "sqrt0.s f2, f0\n" + "const.s f5, 0\n" + "maddn.s f5, f2, f2\n" + "nexp01.s f3, f0\n" + "const.s f4, 3\n" + "addexp.s f3, f4\n" + "maddn.s f4, f5, f3\n" + "nexp01.s f5, f0\n" + "neg.s f6, f5\n" + "maddn.s f2, f4, f2\n" + "const.s f1, 0\n" + "const.s f4, 0\n" + "const.s f7, 0\n" + "maddn.s f1, f6, f2\n" + "maddn.s f4, f2, f3\n" + "const.s f6, 3\n" + "maddn.s f7, f6, f2\n" + "maddn.s f5, f1, f1\n" + "maddn.s f6, f4, f2\n" + "neg.s f3, f7\n" + "maddn.s f1, f5, f3\n" + "maddn.s f7, f6, f7\n" + "mksadj.s f2, f0\n" + "nexp01.s f5, f0\n" + "maddn.s f5, f1, f1\n" + "neg.s f3, f7\n" + "addexpm.s f1, f2\n" + "addexp.s f3, f2\n" + "divn.s f1, f5, f3\n" + "rfr %0, f1\n" + :"=r"(result):"r"(a) + ); + return result; +} + +TEST_CASE("test FP add", "[fp]") +{ + float a = 100.0f; + float b = 0.5f; + float c = addsf(a, b); + float eps = c - 100.5f; + printf("a=%g b=%g c=%g eps=%g\r\n", a, b, c, eps); + TEST_ASSERT_TRUE(fabs(eps) < 0.000001); +} + +TEST_CASE("test FP mul", "[fp]") +{ + float a = 100.0f; + float b = 0.05f; + float c = mulsf(a, b); + float eps = c - 5.0f; + printf("a=%g b=%g c=%g eps=%g\r\n", a, b, c, eps); + TEST_ASSERT_TRUE(fabs(eps) < 0.000001); +} + +TEST_CASE("test FP div", "[fp]") +{ + float a = 100.0f; + float b = 5.0f; + float c = divsf(a, b); + float eps = c - 20.0f; + printf("a=%g b=%g c=%g eps=%g\r\n", a, b, c, eps); + TEST_ASSERT_TRUE(fabs(eps) < 0.000001); +} + +TEST_CASE("test FP sqrt", "[fp]") +{ + float a = 100.0f; + float c = sqrtsf(a); + float eps = c - 10.0f; + printf("a=%g c=%g eps=%g\r\n", a, c, eps); + TEST_ASSERT_TRUE(fabs(eps) < 0.000001); +} + + +struct TestFPState { + int fail; + int done; +}; + +static const int testFpIter = 100000; + +static void tskTestFP(void *pvParameters) +{ + struct TestFPState *state = (struct TestFPState *) pvParameters; + for (int i = 0; i < testFpIter; ++i) { + // calculate zero in a slightly obscure way + float y = sqrtsf(addsf(1.0f, divsf(mulsf(sqrtsf(2), sqrtsf(2)), 2.0f))); + y = mulsf(y, y); + y = addsf(y, -2.0f); + // check that result is not far from zero + float eps = fabs(y); + if (eps > 1e-6f) { + state->fail++; + printf("%s: i=%d y=%f eps=%f\r\n", __func__, i, y, eps); + } + } + state->done++; + vTaskDelete(NULL); +} + +TEST_CASE("context switch saves FP registers", "[fp]") +{ + struct TestFPState state; + state.done = 0; + state.fail = 0; + xTaskCreatePinnedToCore(tskTestFP, "tsk1", 2048, &state, 3, NULL, 0); + xTaskCreatePinnedToCore(tskTestFP, "tsk2", 2048, &state, 3, NULL, 0); + xTaskCreatePinnedToCore(tskTestFP, "tsk3", 2048, &state, 3, NULL, 1); + xTaskCreatePinnedToCore(tskTestFP, "tsk4", 2048, &state, 3, NULL, 0); + while (state.done != 4) { + vTaskDelay(100 / portTICK_PERIOD_MS); + } + if (state.fail) { + const int total = testFpIter * 4; + printf("Failed: %d, total: %d\r\n", state.fail, total); + } + TEST_ASSERT(state.fail == 0); +} +#endif diff --git a/components/esp32/test/test_miniz.c b/components/esp32/test/test_miniz.c new file mode 100644 index 0000000000..3453c859a9 --- /dev/null +++ b/components/esp32/test/test_miniz.c @@ -0,0 +1,77 @@ + + +#include +#include "rom/miniz.h" +#include "unity.h" + + +#define DATASIZE (1024*64) + +TEST_CASE("Test miniz compression/decompression", "[miniz]") +{ + int x; + char b; + char *inbuf, *outbuf; + tdefl_compressor *comp; + tinfl_decompressor *decomp; + tdefl_status status; + size_t inbytes = 0, outbytes = 0, inpos = 0, outpos = 0, compsz; + printf("Allocating data buffer and filling it with semi-random data\n"); + inbuf = malloc(DATASIZE); + TEST_ASSERT(inbuf != NULL); + srand(0); + for (x = 0; x < DATASIZE; x++) { + inbuf[x] = (x & 1) ? rand() & 0xff : 0; + } + printf("Allocating compressor & outbuf (%d bytes)\n", sizeof(tdefl_compressor)); + comp = malloc(sizeof(tdefl_compressor)); + TEST_ASSERT(comp != NULL); + outbuf = malloc(DATASIZE); + TEST_ASSERT(outbuf != NULL); + printf("Compressing...\n"); + status = tdefl_init(comp, NULL, NULL, TDEFL_WRITE_ZLIB_HEADER | 1500); + TEST_ASSERT(status == TDEFL_STATUS_OKAY); + while (inbytes != DATASIZE) { + outbytes = DATASIZE - outpos; + inbytes = DATASIZE - inpos; + tdefl_compress(comp, &inbuf[inpos], &inbytes, &outbuf[outpos], &outbytes, TDEFL_FINISH); + printf("...Compressed %d into %d bytes\n", inbytes, outbytes); + inpos += inbytes; outpos += outbytes; + } + compsz = outpos; + free(comp); + //Kill inbuffer + for (x = 0; x < DATASIZE; x++) { + inbuf[x] = 0; + } + free(inbuf); + + inbuf = outbuf; + outbuf = malloc(DATASIZE); + TEST_ASSERT(outbuf != NULL); + printf("Reinflating...\n"); + decomp = malloc(sizeof(tinfl_decompressor)); + TEST_ASSERT(decomp != NULL); + tinfl_init(decomp); + inpos = 0; outpos = 0; + while (inbytes != compsz) { + outbytes = DATASIZE - outpos; + inbytes = compsz - inpos; + tinfl_decompress(decomp, (const mz_uint8 *)&inbuf[inpos], &inbytes, (uint8_t *)outbuf, (mz_uint8 *)&outbuf[outpos], &outbytes, TINFL_FLAG_PARSE_ZLIB_HEADER); + printf("...Decompressed %d into %d bytes\n", inbytes, outbytes); + inpos += inbytes; outpos += outbytes; + } + printf("Checking if same...\n"); + srand(0); + for (x = 0; x < DATASIZE; x++) { + b = (x & 1) ? rand() & 0xff : 0; + if (outbuf[x] != b) { + printf("Pos %x: %hhx!=%hhx\n", x, outbuf[x], b); + TEST_ASSERT(0); + } + } + printf("Great Success!\n"); + free(inbuf); + free(outbuf); + free(decomp); +} diff --git a/components/esp32/test/test_tjpgd.c b/components/esp32/test/test_tjpgd.c new file mode 100644 index 0000000000..60c687f079 --- /dev/null +++ b/components/esp32/test/test_tjpgd.c @@ -0,0 +1,91 @@ + + +#include +#include "rom/tjpgd.h" +#include +#include +#include +#include "unity.h" + +#include "test_tjpgd_logo.h" + +typedef struct { + const unsigned char *inData; + int inPos; + unsigned char *outData; + int outW; + int outH; +} JpegDev; + + +static UINT infunc(JDEC *decoder, BYTE *buf, UINT len) +{ + JpegDev *jd = (JpegDev *)decoder->device; + printf("Reading %d bytes from pos %d\n", len, jd->inPos); + if (buf != NULL) { + memcpy(buf, jd->inData + jd->inPos, len); + } + jd->inPos += len; + return len; +} + + +static UINT outfunc(JDEC *decoder, void *bitmap, JRECT *rect) +{ + unsigned char *in = (unsigned char *)bitmap; + unsigned char *out; + int y; + printf("Rect %d,%d - %d,%d\n", rect->top, rect->left, rect->bottom, rect->right); + JpegDev *jd = (JpegDev *)decoder->device; + for (y = rect->top; y <= rect->bottom; y++) { + out = jd->outData + ((jd->outW * y) + rect->left) * 3; + memcpy(out, in, ((rect->right - rect->left) + 1) * 3); + in += ((rect->right - rect->left) + 1) * 3; + } + return 1; +} + +#define TESTW 48 +#define TESTH 48 +#define WORKSZ 3100 + +TEST_CASE("Test JPEG decompression library", "[tjpgd]") +{ + char aapix[] = " .:;+=xX$$"; + unsigned char *decoded, *p; + char *work; + int r; + int x, y, v; + JDEC decoder; + JpegDev jd; + decoded = malloc(48 * 48 * 3); + for (x = 0; x < 48 * 48 * 3; x += 2) { + decoded[x] = 0; decoded[x + 1] = 0xff; + } + work = malloc(WORKSZ); + memset(work, 0, WORKSZ); + + jd.inData = logo_jpg; + jd.inPos = 0; + jd.outData = decoded; + jd.outW = TESTW; + jd.outH = TESTH; + + r = jd_prepare(&decoder, infunc, work, WORKSZ, (void *)&jd); + TEST_ASSERT_EQUAL(r, JDR_OK); + r = jd_decomp(&decoder, outfunc, 0); + TEST_ASSERT_EQUAL(r, JDR_OK); + + p = decoded + 2; + for (y = 0; y < TESTH; y++) { + for (x = 0; x < TESTH; x++) { + v = ((*p) * (sizeof(aapix) - 2) * 2) / 256; + printf("%c%c", aapix[v / 2], aapix[(v + 1) / 2]); + p += 3; + } + printf("%c%c", ' ', '\n'); + } + + free(work); + free(decoded); +} diff --git a/components/esp32/test/test_unal_dma.c b/components/esp32/test/test_unal_dma.c new file mode 100644 index 0000000000..3726632a41 --- /dev/null +++ b/components/esp32/test/test_unal_dma.c @@ -0,0 +1,205 @@ + +#include +#include +#include +#include +#include "rom/ets_sys.h" +#include "rom/lldesc.h" +#include "rom/gpio.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 "soc/uart_reg.h" +#include "soc/dport_reg.h" +#include "soc/io_mux_reg.h" +#include "soc/gpio_sig_map.h" +#include "soc/gpio_reg.h" +#include "soc/i2s_reg.h" + + +#define DPORT_I2S0_CLK_EN (BIT(4)) +#define DPORT_I2S0_RST (BIT(4)) + +static volatile lldesc_t dmaDesc[2]; + + +//hacked up routine to essentially do a memcpy() using dma. Supports max 4K-1 bytes. +static void dmaMemcpy(void *in, void *out, int len) +{ + volatile int i; + SET_PERI_REG_MASK(DPORT_PERIP_CLK_EN_REG, DPORT_I2S0_CLK_EN); + CLEAR_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG, DPORT_I2S0_RST); + + //Init pins to i2s functions + SET_PERI_REG_MASK(GPIO_ENABLE_W1TS_REG, (1 << 11) | (1 << 3) | (1 << 0) | (1 << 2) | (1 << 5) | (1 << 16) | (1 << 17) | (1 << 18) | (1 << 19) | (1 << 20)); //ENABLE GPIO oe_enable + + PIN_FUNC_SELECT(PERIPHS_IO_MUX_GPIO0_U, 0); + PIN_FUNC_SELECT(PERIPHS_IO_MUX_GPIO2_U, 0); + PIN_FUNC_SELECT(PERIPHS_IO_MUX_GPIO5_U, 0); + PIN_FUNC_SELECT(PERIPHS_IO_MUX_GPIO16_U, 0); + PIN_FUNC_SELECT(PERIPHS_IO_MUX_GPIO17_U, 0); + PIN_FUNC_SELECT(PERIPHS_IO_MUX_GPIO18_U, 0); + PIN_FUNC_SELECT(PERIPHS_IO_MUX_GPIO19_U, 0); + PIN_FUNC_SELECT(PERIPHS_IO_MUX_GPIO20_U, 0); + PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_CMD_U, 2); //11 + PIN_FUNC_SELECT(PERIPHS_IO_MUX_GPIO26_U, 0); //RS + + WRITE_PERI_REG(GPIO_FUNC0_OUT_SEL_CFG_REG, (148 << GPIO_FUNC0_OUT_SEL_S)); + WRITE_PERI_REG(GPIO_FUNC2_OUT_SEL_CFG_REG, (149 << GPIO_FUNC0_OUT_SEL_S)); + WRITE_PERI_REG(GPIO_FUNC5_OUT_SEL_CFG_REG, (150 << GPIO_FUNC0_OUT_SEL_S)); + WRITE_PERI_REG(GPIO_FUNC16_OUT_SEL_CFG_REG, (151 << GPIO_FUNC0_OUT_SEL_S)); + WRITE_PERI_REG(GPIO_FUNC17_OUT_SEL_CFG_REG, (152 << GPIO_FUNC0_OUT_SEL_S)); + WRITE_PERI_REG(GPIO_FUNC18_OUT_SEL_CFG_REG, (153 << GPIO_FUNC0_OUT_SEL_S)); + WRITE_PERI_REG(GPIO_FUNC19_OUT_SEL_CFG_REG, (154 << GPIO_FUNC0_OUT_SEL_S)); + WRITE_PERI_REG(GPIO_FUNC20_OUT_SEL_CFG_REG, (155 << GPIO_FUNC0_OUT_SEL_S)); + WRITE_PERI_REG(GPIO_FUNC26_OUT_SEL_CFG_REG, (156 << GPIO_FUNC0_OUT_SEL_S)); //RS + WRITE_PERI_REG(GPIO_FUNC11_OUT_SEL_CFG_REG, (I2S0O_WS_OUT_IDX << GPIO_FUNC0_OUT_SEL_S)); +// WRITE_PERI_REG(GPIO_FUNC11_OUT_SEL_CFG, (I2S0O_BCK_OUT_IDX< +#include +#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 "soc/uart_reg.h" +#include "soc/dport_reg.h" +#include "soc/io_mux_reg.h" + + +void ets_isr_unmask(uint32_t unmask); + +static xQueueHandle myQueue; +static xQueueHandle uartRxQueue; + +int ctr; + +#if 1 +//Idle-loop for delay. Tests involuntary yielding +static void cvTaskDelay(int dummy) +{ + volatile int i; + for (i = 0; i < (1 << 17); i++); +} +#else +//Delay task execution using FreeRTOS methods. Tests voluntary yielding. +#define cvTaskDelay(x) vTaskDelay(x) +#endif + +#if 0 +static void dosegfault3(int i) +{ + volatile char *p = (volatile char *)0; + *p = i; +} + +static void dosegfault2(int i) +{ + if (i > 3) { + dosegfault3(i); + } +} + +static void dosegfault(int i) +{ + if (i < 5) { + dosegfault(i + 1); + } + dosegfault2(i); +} +#endif + +static void queueSender(void *pvParameters) +{ + int myCtr = xPortGetCoreID() * 100000; + while (1) { + printf("Core %d: Send to queue: %d\n", xPortGetCoreID(), myCtr); + xQueueSend(myQueue, (void *)(&myCtr), portMAX_DELAY); + printf("Send to queue done.\n"); + cvTaskDelay(100); + myCtr++; + } +} + +static void queueReceiver(void *pvParameters) +{ + int theCtr; + while (1) { + xQueueReceive(myQueue, &theCtr, portMAX_DELAY); + printf("Core %d: Receive from queue: %d\n", xPortGetCoreID(), theCtr); + } +} + + +static void tskone(void *pvParameters) +{ +// char *p=(char *)0; + while (1) { + ctr++; +// if (ctr>60) dosegfault(3); + printf("Task1, core %d, ctr=%d\n", xPortGetCoreID(), ctr); + cvTaskDelay(500); + } +} + +static void tsktwo(void *pvParameters) +{ + while (1) { + ctr++; + printf("Task2, core %d, ctr=%d\n", xPortGetCoreID(), ctr); + cvTaskDelay(500); + } +} + +static void tskthree(void *pvParameters) +{ + while (1) { + ctr++; + printf("Task3, core %d, ctr=%d\n", xPortGetCoreID(), ctr); + cvTaskDelay(500); + } +} + +static void tskfour(void *pvParameters) +{ + while (1) { + ctr++; + printf("Task4, core %d, ctr=%d\n", xPortGetCoreID(), ctr); + cvTaskDelay(500); + } +} + +static void tskfive(void *pvParameters) +{ + while (1) { + ctr++; + printf("Task5, core %d, ctr=%d\n", xPortGetCoreID(), ctr); + cvTaskDelay(500); + } +} + +static void tskyield(void *pvParameters) +{ + while (1) { + portYIELD(); + } +} + +static void tskUartRecv(void *pvParameters) +{ + char c; + while (1) { + xQueueReceive(uartRxQueue, &c, portMAX_DELAY); + printf("Uart received %c!\n", c); + } +} + + +static void uartIsrHdl(void *arg) +{ + char c; + BaseType_t xHigherPriorityTaskWoken; + SET_PERI_REG_MASK(UART_INT_CLR_REG(0), UART_RXFIFO_FULL_INT_CLR); + while (READ_PERI_REG(UART_STATUS_REG(0)) & (UART_RXFIFO_CNT << UART_RXFIFO_CNT_S)) { + c = READ_PERI_REG(UART_FIFO_REG(0)); + xQueueSendFromISR(uartRxQueue, &c, &xHigherPriorityTaskWoken); + printf("ISR: %c\n", c); + } + if (xHigherPriorityTaskWoken) { + portYIELD_FROM_ISR(); + } +} + +static void uartRxInit(xQueueHandle q) +{ + uint32_t reg_val; + + PIN_PULLUP_DIS(PERIPHS_IO_MUX_U0TXD_U); + PIN_FUNC_SELECT(PERIPHS_IO_MUX_U0RXD_U, FUNC_U0RXD_U0RXD); + PIN_FUNC_SELECT(PERIPHS_IO_MUX_U0TXD_U, FUNC_U0TXD_U0TXD); + + + PIN_FUNC_SELECT(PERIPHS_IO_MUX_U0RXD_U, FUNC_U0RXD_U0RXD); + +// reg_val = READ_PERI_REG(UART_CONF1(0)); + reg_val = (1 << UART_RXFIFO_FULL_THRHD_S); + WRITE_PERI_REG(UART_CONF1_REG(0), reg_val); + CLEAR_PERI_REG_MASK(UART_INT_ENA_REG(0), UART_TXFIFO_EMPTY_INT_ENA | UART_RXFIFO_TOUT_INT_ENA); + SET_PERI_REG_MASK(UART_INT_ENA_REG(0), UART_RXFIFO_FULL_INT_ENA); + + printf("Enabling int %d\n", ETS_UART0_INUM); + REG_SET_FIELD(DPORT_PRO_UART_INTR_MAP_REG, DPORT_PRO_UART_INTR_MAP, ETS_UART0_INUM); + REG_SET_FIELD(DPORT_PRO_UART1_INTR_MAP_REG, DPORT_PRO_UART1_INTR_MAP, ETS_UART0_INUM); + + xt_set_interrupt_handler(ETS_UART0_INUM, uartIsrHdl, NULL); + xt_ints_on(1 << ETS_UART0_INUM); + +} + +// TODO: split this thing into separate orthogonal tests +TEST_CASE("Bunch of FreeRTOS tests", "[freertos]") +{ + char *tst; + TaskHandle_t th[12]; + int i; + printf("%s\n", __FUNCTION__); + tst = pvPortMalloc(16); + printf("Test malloc returns addr %p\n", tst); + printf("Free heap: %u\n", xPortGetFreeHeapSize()); + myQueue = xQueueCreate(10, sizeof(int)); + uartRxQueue = xQueueCreate(256, sizeof(char)); + printf("Free heap: %u\n", xPortGetFreeHeapSize()); + + printf("Creating tasks\n"); + xTaskCreatePinnedToCore(tskyield , "tskyield1" , 2048, NULL, 3, &th[0], 0); + xTaskCreatePinnedToCore(tskyield , "tskyield2" , 2048, NULL, 3, &th[1], 1); + + xTaskCreatePinnedToCore(tskone , "tskone" , 2048, NULL, 3, &th[2], 0); + xTaskCreatePinnedToCore(tsktwo , "tsktwo" , 2048, NULL, 3, &th[3], 1); + xTaskCreatePinnedToCore(tskthree, "tskthree", 2048, NULL, 3, &th[4], 0); + xTaskCreatePinnedToCore(tskfour , "tskfour" , 2048, NULL, 3, &th[5], tskNO_AFFINITY); + xTaskCreatePinnedToCore(tskfive , "tskfive" , 2048, NULL, 3, &th[6], tskNO_AFFINITY); + xTaskCreatePinnedToCore(queueSender , "qsend1" , 2048, NULL, 3, &th[7], 0); + xTaskCreatePinnedToCore(queueSender , "qsend2" , 2048, NULL, 3, &th[8], 1); + xTaskCreatePinnedToCore(queueReceiver , "qrecv1" , 2048, NULL, 3, &th[9], 1); + xTaskCreatePinnedToCore(queueReceiver , "qrecv2" , 2048, NULL, 3, &th[10], 0); + xTaskCreatePinnedToCore(tskUartRecv , "tskuart" , 2048, NULL, 4, &th[11], 1); + printf("Free heap: %u\n", xPortGetFreeHeapSize()); + uartRxInit(uartRxQueue); + + // Let stuff run for 20s + vTaskDelay(20000 / portTICK_PERIOD_MS); + + //Shut down all the tasks + for (i = 0; i < 12; i++) { + vTaskDelete(th[i]); + } + xt_ints_off(1 << ETS_UART0_INUM); +} + diff --git a/components/freertos/test/test_freertos_eventgroups.c b/components/freertos/test/test_freertos_eventgroups.c new file mode 100644 index 0000000000..35a5cc4ed2 --- /dev/null +++ b/components/freertos/test/test_freertos_eventgroups.c @@ -0,0 +1,105 @@ +#include + +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "freertos/semphr.h" +#include "freertos/queue.h" +#include "freertos/event_groups.h" +#include "unity.h" + +#define BIT_CALL (1 << 0) +#define BIT_RESPONSE(TASK) (1 << (TASK+1)) +#define ALL_RESPONSE_BITS (((1 << NUM_TASKS) - 1) << 1) + +static const int NUM_TASKS = 4; +static const int COUNT = 4000; +static EventGroupHandle_t eg; + +static void task_event_group_call_response(void *param) +{ + int task_num = (int)param; + + printf("Started %d\n", task_num); + + for (int i = 0; i < COUNT; i++) { + /* Wait until the common "call" bit is set, starts off all tasks + (clear on return) */ + while (!xEventGroupWaitBits(eg, BIT_CALL, true, false, portMAX_DELAY)) { + } + + /* Set our individual "response" bit */ + xEventGroupSetBits(eg, BIT_RESPONSE(task_num)); + } + + printf("Task %d done\n", task_num); + + /* Delay is due to not-yet-fixed bug with deleting tasks at same time */ + vTaskDelay(100 / portTICK_RATE_MS); + vTaskDelete(NULL); +} + +TEST_CASE("FreeRTOS Event Groups", "[freertos]") +{ + eg = xEventGroupCreate(); + + /* Note: task_event_group_call_response all have higher priority than us, so will block together. + + This is important because we need to know they'll all have blocked on BIT_CALL each time we + signal it, or they get out of sync. + */ + for (int c = 0; c < NUM_TASKS; c++) { + xTaskCreatePinnedToCore(task_event_group_call_response, "tsk_call_resp", 4096, (void *)c, configMAX_PRIORITIES - 1, NULL, c % portNUM_PROCESSORS); + } + /* Scheduler weirdness, if we don't sleep a few ticks here then the tasks on the other CPU aren't running yet... */ + vTaskDelay(10); + + for (int i = 0; i < COUNT; i++) { + if (i % 100 == 0) { + //printf("Call %d\n", i); + } + /* signal all tasks with "CALL" bit... */ + xEventGroupSetBits(eg, BIT_CALL); + + while (xEventGroupWaitBits(eg, ALL_RESPONSE_BITS, true, true, portMAX_DELAY) != ALL_RESPONSE_BITS) { + } + } +} + + +#define BIT_DONE(X) (1<<(NUM_TASKS+1+X)) + +static void task_test_sync(void *param) +{ + int task_num = (int)param; + + printf("Started %d\n", task_num); + + for (int i = 0; i < COUNT; i++) { + /* set our bit, and wait on all tasks to set their bits */ + xEventGroupSync(eg, BIT_RESPONSE(task_num), ALL_RESPONSE_BITS, portMAX_DELAY); + /* clear our bit */ + xEventGroupClearBits(eg, BIT_RESPONSE(task_num)); + } + int after_done = xEventGroupSetBits(eg, BIT_DONE(task_num)); + + printf("Done %d = %x\n", task_num, after_done); + + /* Delay is due to not-yet-fixed bug with deleting tasks at same time */ + vTaskDelay(100 / portTICK_RATE_MS); + vTaskDelete(NULL); +} + +TEST_CASE("FreeRTOS Event Group Sync", "[freertos]") +{ + eg = xEventGroupCreate(); + + for (int c = 0; c < NUM_TASKS; c++) { + xTaskCreatePinnedToCore(task_test_sync, "task_test_sync", 4096, (void *)c, configMAX_PRIORITIES - 1, NULL, c % portNUM_PROCESSORS); + } + + for (int c = 0; c < NUM_TASKS; c++) { + printf("Waiting on %d (%x)\n", c, BIT_DONE(c)); + xEventGroupWaitBits(eg, BIT_DONE(c), false, false, portMAX_DELAY); + } +} + diff --git a/components/freertos/test/test_freertos_task_delete.c b/components/freertos/test/test_freertos_task_delete.c new file mode 100644 index 0000000000..3101db2564 --- /dev/null +++ b/components/freertos/test/test_freertos_task_delete.c @@ -0,0 +1,22 @@ +#include + +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "freertos/semphr.h" +#include "freertos/queue.h" +#include "freertos/event_groups.h" +#include "unity.h" + +static void task_delete_self(void *param) +{ + printf("Task %p running on core %d. Deleting shortly...\n", xTaskGetCurrentTaskHandle(), xPortGetCoreID()); + vTaskDelete(NULL); +} + +TEST_CASE("FreeRTOS Delete Tasks", "[freertos]") +{ + 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); + vTaskDelay(200 / portTICK_PERIOD_MS); + printf("Done?\n"); +} diff --git a/components/freertos/test/test_newlib_reent.c b/components/freertos/test/test_newlib_reent.c new file mode 100644 index 0000000000..e0ec4aa458 --- /dev/null +++ b/components/freertos/test/test_newlib_reent.c @@ -0,0 +1,60 @@ +/* + Test for multicore FreeRTOS. This test spins up threads, fiddles with queues etc. +*/ + +#include +#include +#include +#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 "soc/uart_reg.h" +#include "soc/dport_reg.h" +#include "soc/io_mux_reg.h" + + +volatile static int done; +volatile static int error; + +static void tskTestRand(void *pvParameters) +{ + int l; + srand(0x1234); + vTaskDelay((int)pvParameters / portTICK_PERIOD_MS); + l = rand(); + printf("Rand1: %d\n", l); + if (l != 869320854) { + error++; + } + vTaskDelay((int)pvParameters / portTICK_PERIOD_MS); + l = rand(); + printf("Rand2: %d\n", l); + if (l != 1148737841) { + error++; + } + done++; + vTaskDelete(NULL); +} + + + +// TODO: split this thing into separate orthogonal tests +TEST_CASE("Test for per-task non-reentrant tasks", "[freertos]") +{ + done = 0; + error = 0; + xTaskCreatePinnedToCore(tskTestRand, "tsk1", 2048, (void *)100, 3, NULL, 0); + xTaskCreatePinnedToCore(tskTestRand, "tsk2", 2048, (void *)200, 3, NULL, 0); + xTaskCreatePinnedToCore(tskTestRand, "tsk3", 2048, (void *)300, 3, NULL, 1); + xTaskCreatePinnedToCore(tskTestRand, "tsk4", 2048, (void *)400, 3, NULL, 0); + while (done != 4) { + vTaskDelay(1000 / portTICK_PERIOD_MS); + } + TEST_ASSERT(error == 0); +} + diff --git a/components/freertos/test/test_panic.c b/components/freertos/test/test_panic.c new file mode 100644 index 0000000000..782b7a5642 --- /dev/null +++ b/components/freertos/test/test_panic.c @@ -0,0 +1,26 @@ +/* + Test for multicore FreeRTOS. This test spins up threads, fiddles with queues etc. +*/ + +#include +#include +#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 "soc/uart_reg.h" +#include "soc/dport_reg.h" +#include "soc/io_mux_reg.h" + + +TEST_CASE("Panic handler", "[freertos]") +{ + volatile int *i; + i = (volatile int *)0x0; + *i = 1; +} + diff --git a/components/freertos/test/test_ringbuf.c b/components/freertos/test/test_ringbuf.c new file mode 100644 index 0000000000..7d3c8788c9 --- /dev/null +++ b/components/freertos/test/test_ringbuf.c @@ -0,0 +1,197 @@ +/* + Test for multicore FreeRTOS ringbuffer. +*/ + +#include +#include +#include "rom/ets_sys.h" + +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "freertos/semphr.h" +#include "freertos/queue.h" +#include "freertos/ringbuf.h" +#include "freertos/xtensa_api.h" +#include "unity.h" +#include "soc/uart_reg.h" +#include "soc/dport_reg.h" +#include "soc/io_mux_reg.h" + +#include +#include + +void ets_isr_unmask(uint32_t unmask); + +static RingbufHandle_t rb; +typedef enum { + TST_MOSTLYFILLED, + TST_MOSTLYEMPTY, + TST_INTTOTASK, + TST_TASKTOINT, +} testtype_t; + +static volatile testtype_t testtype; + +static void task1(void *arg) +{ + testtype_t oldtest; + char buf[100]; + int i = 0; + int x, r; + while (1) { + oldtest = testtype; + if (testtype == TST_MOSTLYFILLED || testtype == TST_MOSTLYEMPTY) { + for (x = 0; x < 10; x++) { + sprintf(buf, "This is test %d item %d.", (int)testtype, i++); + ets_printf("TSK w"); + xRingbufferPrintInfo(rb); + r = xRingbufferSend(rb, buf, strlen(buf) + 1, 2000 / portTICK_PERIOD_MS); + if (!r) { + printf("Test %d: Timeout on send!\n", (int)testtype); + } + if (testtype == TST_MOSTLYEMPTY) { + vTaskDelay(1000 / portTICK_PERIOD_MS); + } + } + //Send NULL event to stop other side. + r = xRingbufferSend(rb, NULL, 0, 10000 / portTICK_PERIOD_MS); + } + while (oldtest == testtype) { + vTaskDelay(1000 / portTICK_PERIOD_MS); + } + } +} + +static void task2(void *arg) +{ + testtype_t oldtest; + char *buf; + size_t len; + while (1) { + oldtest = testtype; + if (testtype == TST_MOSTLYFILLED || testtype == TST_MOSTLYEMPTY) { + while (1) { + ets_printf("TSK r"); + xRingbufferPrintInfo(rb); + buf = xRingbufferReceive(rb, &len, 2000 / portTICK_PERIOD_MS); + if (buf == NULL) { + printf("Test %d: Timeout on recv!\n", (int)testtype); + } else if (len == 0) { + printf("End packet received.\n"); + vRingbufferReturnItem(rb, buf); + break; + } else { + printf("Received: %s (%d bytes, %p)\n", buf, len, buf); + vRingbufferReturnItem(rb, buf); + } + if (testtype == TST_MOSTLYFILLED) { + vTaskDelay(1000 / portTICK_PERIOD_MS); + } + } + } + while (oldtest == testtype) { + vTaskDelay(1000 / portTICK_PERIOD_MS); + } + } +} + + + +static void uartIsrHdl(void *arg) +{ + char c; + char buf[50]; + char *item; + int r; + size_t len; + BaseType_t xHigherPriorityTaskWoken; + SET_PERI_REG_MASK(UART_INT_CLR_REG(0), UART_RXFIFO_FULL_INT_CLR); + while (READ_PERI_REG(UART_STATUS_REG(0)) & (UART_RXFIFO_CNT << UART_RXFIFO_CNT_S)) { + c = READ_PERI_REG(UART_FIFO_REG(0)); + if (c == 'r') { + ets_printf("ISR r"); + xRingbufferPrintInfo(rb); + item = xRingbufferReceiveFromISR(rb, &len); + if (item == NULL) { + ets_printf("ISR recv fail!\n"); + } else if (len == 0) { + ets_printf("ISR recv NULL!\n"); + vRingbufferReturnItemFromISR(rb, item, &xHigherPriorityTaskWoken); + } else { + ets_printf("ISR recv '%s' (%d bytes, %p)\n", buf, len, buf); + vRingbufferReturnItemFromISR(rb, item, &xHigherPriorityTaskWoken); + } + } else { + sprintf(buf, "UART: %c", c); + ets_printf("ISR w"); + xRingbufferPrintInfo(rb); + r = xRingbufferSendFromISR(rb, buf, strlen(buf) + 1, &xHigherPriorityTaskWoken); + if (!r) { + ets_printf("ISR send fail\n"); + } + } + } + if (xHigherPriorityTaskWoken) { + portYIELD_FROM_ISR(); + } +} + +static void uartRxInit() +{ + uint32_t reg_val; + PIN_PULLUP_DIS(PERIPHS_IO_MUX_U0TXD_U); + PIN_FUNC_SELECT(PERIPHS_IO_MUX_U0RXD_U, FUNC_U0RXD_U0RXD); + PIN_FUNC_SELECT(PERIPHS_IO_MUX_U0TXD_U, FUNC_U0TXD_U0TXD); + +// reg_val = READ_PERI_REG(UART_CONF1(0)); + reg_val = (1 << UART_RXFIFO_FULL_THRHD_S); + WRITE_PERI_REG(UART_CONF1_REG(0), reg_val); + CLEAR_PERI_REG_MASK(UART_INT_ENA_REG(0), UART_TXFIFO_EMPTY_INT_ENA | UART_RXFIFO_TOUT_INT_ENA); + SET_PERI_REG_MASK(UART_INT_ENA_REG(0), UART_RXFIFO_FULL_INT_ENA); + + printf("Enabling int %d\n", ETS_UART0_INUM); + REG_SET_FIELD(DPORT_PRO_UART_INTR_MAP_REG, DPORT_PRO_UART_INTR_MAP, ETS_UART0_INUM); + REG_SET_FIELD(DPORT_PRO_UART1_INTR_MAP_REG, DPORT_PRO_UART1_INTR_MAP, ETS_UART0_INUM); + + xt_set_interrupt_handler(ETS_UART0_INUM, uartIsrHdl, NULL); + xt_ints_on(1 << ETS_UART0_INUM); + +} + +static void testRingbuffer(int type) +{ + TaskHandle_t th[2]; + int i; + rb = xRingbufferCreate(32 * 3, type); + + testtype = TST_MOSTLYFILLED; + + xTaskCreatePinnedToCore(task1 , "tskone" , 2048, NULL, 3, &th[0], 0); + xTaskCreatePinnedToCore(task2 , "tsktwo" , 2048, NULL, 3, &th[1], 0); + uartRxInit(); + + printf("Press 'r' to read an event in isr, any other key to write one.\n"); + printf("Test: mostlyfilled; putting 10 items in ringbuff ASAP, reading 1 a second\n"); + vTaskDelay(15000 / portTICK_PERIOD_MS); + printf("Test: mostlyempty; putting 10 items in ringbuff @ 1/sec, reading as fast as possible\n"); + testtype = TST_MOSTLYEMPTY; + vTaskDelay(15000 / portTICK_PERIOD_MS); + + //Shut down all the tasks + for (i = 0; i < 2; i++) { + vTaskDelete(th[i]); + } + xt_ints_off(1 << ETS_UART0_INUM); +} + +// TODO: split this thing into separate orthogonal tests +TEST_CASE("FreeRTOS ringbuffer test, no splitting items", "[freertos]") +{ + testRingbuffer(0); +} + +TEST_CASE("FreeRTOS ringbuffer test, w/ splitting items", "[freertos]") +{ + testRingbuffer(1); +} + diff --git a/components/freertos/test/test_tls_deletecb.c b/components/freertos/test/test_tls_deletecb.c new file mode 100644 index 0000000000..5277b761ab --- /dev/null +++ b/components/freertos/test/test_tls_deletecb.c @@ -0,0 +1,58 @@ +#include +#include +#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 "soc/uart_reg.h" +#include "soc/dport_reg.h" +#include "soc/io_mux_reg.h" + + + +static void tskdelcb(int no, void *arg) +{ + printf("Delete callback: %d = %p!\n", no, arg); +} + + +static void tska(void *pvParameters) +{ + vTaskSetThreadLocalStoragePointerAndDelCallback(xTaskGetCurrentTaskHandle(), 0, (void *)0xAAAAAAAA, tskdelcb); + while (1) { + vTaskDelay(10000000 / portTICK_PERIOD_MS); + } +} + +static void tskb(void *pvParameters) +{ + vTaskSetThreadLocalStoragePointerAndDelCallback(xTaskGetCurrentTaskHandle(), 0, (void *)0xBBBBBBBB, tskdelcb); + vTaskDelay(2000 / portTICK_PERIOD_MS); + TaskHandle_t a = (TaskHandle_t)pvParameters; + printf("Killing task A\n"); + vTaskDelete(a); + while (1) { + vTaskDelay(10000000 / portTICK_PERIOD_MS); + } +} + + +// TODO: split this thing into separate orthogonal tests +TEST_CASE("Freertos TLS delete cb", "[freertos]") +{ + TaskHandle_t a, b; + + xTaskCreatePinnedToCore(tska , "tska" , 2048, NULL, 3, &a, 0); + xTaskCreatePinnedToCore(tskb , "tska" , 2048, a, 3, &b, 0); + + // Let stuff run for 20s + vTaskDelay(5000 / portTICK_PERIOD_MS); + printf("Killing task B\n"); + //Shut down b + vTaskDelete(b); +} + diff --git a/components/mbedtls/test/component.mk b/components/mbedtls/test/component.mk new file mode 100644 index 0000000000..5dd172bdb7 --- /dev/null +++ b/components/mbedtls/test/component.mk @@ -0,0 +1,5 @@ +# +#Component Makefile +# + +COMPONENT_ADD_LDFLAGS = -Wl,--whole-archive -l$(COMPONENT_NAME) -Wl,--no-whole-archive diff --git a/components/mbedtls/test/test_mbedtls.c b/components/mbedtls/test/test_mbedtls.c new file mode 100644 index 0000000000..797c107efb --- /dev/null +++ b/components/mbedtls/test/test_mbedtls.c @@ -0,0 +1,134 @@ +/* mbedTLS internal tests wrapped into Unity + + Focus on testing functionality where we use ESP32 hardware + accelerated crypto features. + + See also test_hwcrypto.c +*/ +#include +#include +#include "mbedtls/sha1.h" +#include "mbedtls/sha256.h" +#include "mbedtls/sha512.h" +#include "mbedtls/aes.h" +#include "mbedtls/bignum.h" +#include "unity.h" + +static int mbedtls_alt_sha256_self_test( int verbose ); + +TEST_CASE("mbedtls SHA self-tests", "[mbedtls]") +{ + TEST_ASSERT_FALSE_MESSAGE(mbedtls_sha1_self_test(1), "SHA1 self-tests should pass."); + TEST_ASSERT_FALSE_MESSAGE(mbedtls_alt_sha256_self_test(1), "SHA256 self-tests should pass."); + TEST_ASSERT_FALSE_MESSAGE(mbedtls_sha512_self_test(1), "SHA512 self-tests should pass."); +} + +TEST_CASE("mbedtls AES self-tests", "[aes]") +{ + TEST_ASSERT_FALSE_MESSAGE(mbedtls_aes_self_test(1), "AES self-tests should pass."); +} + +TEST_CASE("mbedtls MPI self-tests", "[bignum]") +{ + TEST_ASSERT_FALSE_MESSAGE(mbedtls_mpi_self_test(1), "MPI self-tests should pass."); +} + + +/* Following code is a copy of the mbedtls_sha256 test vectors, + with the SHA-224 support removed as we don't currently support this hash. +*/ + +/* + * FIPS-180-2 test vectors + */ +static const unsigned char sha256_test_buf[3][57] = { + { "abc" }, + { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" }, + { "" } +}; + +static const int sha256_test_buflen[3] = { + 3, 56, 1000 +}; + +static const unsigned char sha256_test_sum[6][32] = { + /* + * SHA-256 test vectors + */ + { + 0xBA, 0x78, 0x16, 0xBF, 0x8F, 0x01, 0xCF, 0xEA, + 0x41, 0x41, 0x40, 0xDE, 0x5D, 0xAE, 0x22, 0x23, + 0xB0, 0x03, 0x61, 0xA3, 0x96, 0x17, 0x7A, 0x9C, + 0xB4, 0x10, 0xFF, 0x61, 0xF2, 0x00, 0x15, 0xAD + }, + { + 0x24, 0x8D, 0x6A, 0x61, 0xD2, 0x06, 0x38, 0xB8, + 0xE5, 0xC0, 0x26, 0x93, 0x0C, 0x3E, 0x60, 0x39, + 0xA3, 0x3C, 0xE4, 0x59, 0x64, 0xFF, 0x21, 0x67, + 0xF6, 0xEC, 0xED, 0xD4, 0x19, 0xDB, 0x06, 0xC1 + }, + { + 0xCD, 0xC7, 0x6E, 0x5C, 0x99, 0x14, 0xFB, 0x92, + 0x81, 0xA1, 0xC7, 0xE2, 0x84, 0xD7, 0x3E, 0x67, + 0xF1, 0x80, 0x9A, 0x48, 0xA4, 0x97, 0x20, 0x0E, + 0x04, 0x6D, 0x39, 0xCC, 0xC7, 0x11, 0x2C, 0xD0 + } +}; + +/* + * Checkup routine + */ +static int mbedtls_alt_sha256_self_test( int verbose ) +{ + int j, n, buflen, ret = 0; + unsigned char buf[1024]; + unsigned char sha256sum[32]; + mbedtls_sha256_context ctx; + + for ( j = 0; j < 3; j++ ) { + mbedtls_sha256_init( &ctx ); + + if ( verbose != 0 ) { + printf( " SHA-%d test #%d: ", 256, j + 1 ); + } + + mbedtls_sha256_starts( &ctx, 0 ); + + if ( j == 2 ) { + memset( buf, 'a', buflen = 1000 ); + + for ( n = 0; n < 1000; n++ ) { + mbedtls_sha256_update( &ctx, buf, buflen ); + } + } else + mbedtls_sha256_update( &ctx, sha256_test_buf[j], + sha256_test_buflen[j] ); + + mbedtls_sha256_finish( &ctx, sha256sum ); + + if ( memcmp( sha256sum, sha256_test_sum[j], 32 ) != 0 ) { + if ( verbose != 0 ) { + printf( "failed\n" ); + } + + mbedtls_sha256_free( &ctx ); + + ret = 1; + goto exit; + } + + if ( verbose != 0 ) { + printf( "passed\n" ); + } + + mbedtls_sha256_free( &ctx ); + } + + if ( verbose != 0 ) { + printf( "\n" ); + } + +exit: + + return ( ret ); +} diff --git a/components/newlib/test/component.mk b/components/newlib/test/component.mk new file mode 100644 index 0000000000..5dd172bdb7 --- /dev/null +++ b/components/newlib/test/component.mk @@ -0,0 +1,5 @@ +# +#Component Makefile +# + +COMPONENT_ADD_LDFLAGS = -Wl,--whole-archive -l$(COMPONENT_NAME) -Wl,--no-whole-archive diff --git a/components/newlib/test/test_newlib.c b/components/newlib/test/test_newlib.c new file mode 100644 index 0000000000..b498b4bd43 --- /dev/null +++ b/components/newlib/test/test_newlib.c @@ -0,0 +1,102 @@ +#include +#include +#include +#include +#include +#include "unity.h" + + +TEST_CASE("test ctype functions", "[newlib]") +{ + TEST_ASSERT_TRUE( isalnum('a') && isalnum('A') && isalnum('z') && isalnum('Z') && isalnum('0') && isalnum('9') ); + TEST_ASSERT_FALSE( isalnum('(') || isalnum('-') || isalnum(' ') || isalnum('\x81') || isalnum('.') || isalnum('\\') ); + TEST_ASSERT_TRUE( isalpha('a') && isalpha('A') && isalpha('z') && isalpha('Z') ); + TEST_ASSERT_FALSE( isalpha('0') || isalpha('9') || isalpha(')') || isalpha('\t') || isalpha(' ') || isalpha('\x81') ); + TEST_ASSERT_TRUE( isspace(' ') && isspace('\t') && isspace('\n') && isspace('\r') ); + TEST_ASSERT_FALSE( isspace('0') || isspace('9') || isspace(')') || isspace('A') || isspace('*') || isspace('\x81') || isspace('a')); +} + +TEST_CASE("test atoX functions", "[newlib]") +{ + TEST_ASSERT_EQUAL_INT(-2147483648, atoi("-2147483648")); + TEST_ASSERT_EQUAL_INT(2147483647, atoi("2147483647")); + TEST_ASSERT_EQUAL_INT(42, atoi("000000042")); + TEST_ASSERT_EQUAL_INT(0, strtol("foo", NULL, 10)); +} + +TEST_CASE("test sprintf function", "[newlib]") +{ + char *res = NULL; + asprintf(&res, "%d %011i %lu %p %x %c %.4f\n", 42, 2147483647, 2147483648UL, (void *) 0x40010000, 0x40020000, 'Q', 1.0f / 137.0f); + TEST_ASSERT_NOT_NULL(res); + TEST_ASSERT_EQUAL_STRING(res, "42 02147483647 2147483648 0x40010000 40020000 Q 0.0073\n"); + free(res); +} + +TEST_CASE("test sscanf function", "[newlib]") +{ + const char *src = "42 02147483647 2147483648 0x40010000 40020000 Q 0.0073\n"; + int fourty_two; + int int_max; + unsigned long int_max_plus_one; + void *iram_ptr; + int irom_ptr; + char department; + float inv_fine_structure_constant; + int res = sscanf(src, "%d %d %lu %p %x %c %f", &fourty_two, &int_max, &int_max_plus_one, &iram_ptr, &irom_ptr, &department, &inv_fine_structure_constant); + TEST_ASSERT_EQUAL(7, res); + TEST_ASSERT_EQUAL(42, fourty_two); + TEST_ASSERT_EQUAL(2147483647, int_max); + TEST_ASSERT_EQUAL_UINT32(2147483648UL, int_max_plus_one); + TEST_ASSERT_EQUAL(0x40010000, iram_ptr); + TEST_ASSERT_EQUAL(0x40020000, irom_ptr); + TEST_ASSERT_EQUAL('Q', department); + TEST_ASSERT_TRUE(1.0f / inv_fine_structure_constant > 136 && 1.0f / inv_fine_structure_constant < 138); +} + +TEST_CASE("test time functions", "[newlib]") +{ + time_t now = 1464248488; + setenv("TZ", "UTC-8", 1); + struct tm *tm_utc = gmtime(&now); + TEST_ASSERT_EQUAL( 28, tm_utc->tm_sec); + TEST_ASSERT_EQUAL( 41, tm_utc->tm_min); + TEST_ASSERT_EQUAL( 7, tm_utc->tm_hour); + TEST_ASSERT_EQUAL( 26, tm_utc->tm_mday); + TEST_ASSERT_EQUAL( 4, tm_utc->tm_mon); + TEST_ASSERT_EQUAL(116, tm_utc->tm_year); + TEST_ASSERT_EQUAL( 4, tm_utc->tm_wday); + TEST_ASSERT_EQUAL(146, tm_utc->tm_yday); + + struct tm *tm_local = localtime(&now); + TEST_ASSERT_EQUAL( 28, tm_local->tm_sec); + TEST_ASSERT_EQUAL( 41, tm_local->tm_min); + TEST_ASSERT_EQUAL( 15, tm_local->tm_hour); + TEST_ASSERT_EQUAL( 26, tm_local->tm_mday); + TEST_ASSERT_EQUAL( 4, tm_local->tm_mon); + TEST_ASSERT_EQUAL(116, tm_local->tm_year); + TEST_ASSERT_EQUAL( 4, tm_local->tm_wday); + TEST_ASSERT_EQUAL(146, tm_local->tm_yday); + +} + + +static int checkFnRom(void *fn, char *name) +{ + int fnaddr = (int)fn; + printf("%s: 0X%x\n", name, fnaddr); + if ((fnaddr >= 0x40000000) && (fnaddr < 0x40070000)) { + return 1; + } else { + return 0; + } +} + + +TEST_CASE("check if ROM is used for functions", "[newlib]") +{ + TEST_ASSERT(checkFnRom(printf, "printf")); + TEST_ASSERT(checkFnRom(sscanf, "sscanf")); + TEST_ASSERT(checkFnRom(atoi, "atoi")); + TEST_ASSERT(checkFnRom(strtol, "strtol")); +} \ No newline at end of file diff --git a/components/nvs_flash/test/component.mk b/components/nvs_flash/test/component.mk new file mode 100644 index 0000000000..5dd172bdb7 --- /dev/null +++ b/components/nvs_flash/test/component.mk @@ -0,0 +1,5 @@ +# +#Component Makefile +# + +COMPONENT_ADD_LDFLAGS = -Wl,--whole-archive -l$(COMPONENT_NAME) -Wl,--no-whole-archive diff --git a/components/nvs_flash/test/test_nvs.c b/components/nvs_flash/test/test_nvs.c new file mode 100644 index 0000000000..c523026432 --- /dev/null +++ b/components/nvs_flash/test/test_nvs.c @@ -0,0 +1,54 @@ +#include +#include +#include +#include +#include +#include "unity.h" +#include "nvs.h" +#include "nvs_flash.h" +#include "esp_spi_flash.h" +#include + +#define NVS_FLASH_SECTOR 6 +#define NVS_FLASH_SECTOR_COUNT_MIN 3 +#define NVS_FLASH_SECTOR_COUNT_MAX 10 + +TEST_CASE("various nvs tests", "[nvs]") +{ + nvs_handle handle_1; + TEST_ESP_ERR(nvs_open("namespace1", NVS_READWRITE, &handle_1), ESP_ERR_NVS_NOT_INITIALIZED); + for (uint16_t i = NVS_FLASH_SECTOR; i < NVS_FLASH_SECTOR + NVS_FLASH_SECTOR_COUNT_MIN; ++i) { + spi_flash_erase_sector(i); + } + TEST_ESP_OK(nvs_flash_init_custom(NVS_FLASH_SECTOR, NVS_FLASH_SECTOR_COUNT_MIN)); + + TEST_ESP_ERR(nvs_open("namespace1", NVS_READONLY, &handle_1), ESP_ERR_NVS_NOT_FOUND); + + // TEST_ESP_ERR(nvs_set_i32(handle_1, "foo", 0x12345678), ESP_ERR_NVS_READ_ONLY); + // nvs_close(handle_1); + + TEST_ESP_OK(nvs_open("namespace1", NVS_READWRITE, &handle_1)); + TEST_ESP_OK(nvs_set_i32(handle_1, "foo", 0x12345678)); + TEST_ESP_OK(nvs_set_i32(handle_1, "foo", 0x23456789)); + + nvs_handle handle_2; + TEST_ESP_OK(nvs_open("namespace2", NVS_READWRITE, &handle_2)); + TEST_ESP_OK(nvs_set_i32(handle_2, "foo", 0x3456789a)); + const char *str = "value 0123456789abcdef0123456789abcdef"; + TEST_ESP_OK(nvs_set_str(handle_2, "key", str)); + + int32_t v1; + TEST_ESP_OK(nvs_get_i32(handle_1, "foo", &v1)); + TEST_ASSERT_EQUAL_INT32(0x23456789, v1); + + int32_t v2; + TEST_ESP_OK(nvs_get_i32(handle_2, "foo", &v2)); + TEST_ASSERT_EQUAL_INT32(0x3456789a, v2); + + char buf[strlen(str) + 1]; + size_t buf_len = sizeof(buf); + + TEST_ESP_OK(nvs_get_str(handle_2, "key", buf, &buf_len)); + + TEST_ASSERT_EQUAL_INT32(0, strcmp(buf, str)); +} diff --git a/components/nvs_flash/test/Makefile b/components/nvs_flash/test_nvs_host/Makefile similarity index 100% rename from components/nvs_flash/test/Makefile rename to components/nvs_flash/test_nvs_host/Makefile diff --git a/components/nvs_flash/test/catch.hpp b/components/nvs_flash/test_nvs_host/catch.hpp similarity index 100% rename from components/nvs_flash/test/catch.hpp rename to components/nvs_flash/test_nvs_host/catch.hpp diff --git a/components/nvs_flash/test/crc.cpp b/components/nvs_flash/test_nvs_host/crc.cpp similarity index 100% rename from components/nvs_flash/test/crc.cpp rename to components/nvs_flash/test_nvs_host/crc.cpp diff --git a/components/nvs_flash/test/crc.h b/components/nvs_flash/test_nvs_host/crc.h similarity index 100% rename from components/nvs_flash/test/crc.h rename to components/nvs_flash/test_nvs_host/crc.h diff --git a/components/nvs_flash/test/main.cpp b/components/nvs_flash/test_nvs_host/main.cpp similarity index 100% rename from components/nvs_flash/test/main.cpp rename to components/nvs_flash/test_nvs_host/main.cpp diff --git a/components/nvs_flash/test/sdkconfig.h b/components/nvs_flash/test_nvs_host/sdkconfig.h similarity index 100% rename from components/nvs_flash/test/sdkconfig.h rename to components/nvs_flash/test_nvs_host/sdkconfig.h diff --git a/components/nvs_flash/test/spi_flash_emulation.cpp b/components/nvs_flash/test_nvs_host/spi_flash_emulation.cpp similarity index 100% rename from components/nvs_flash/test/spi_flash_emulation.cpp rename to components/nvs_flash/test_nvs_host/spi_flash_emulation.cpp diff --git a/components/nvs_flash/test/spi_flash_emulation.h b/components/nvs_flash/test_nvs_host/spi_flash_emulation.h similarity index 100% rename from components/nvs_flash/test/spi_flash_emulation.h rename to components/nvs_flash/test_nvs_host/spi_flash_emulation.h diff --git a/components/nvs_flash/test/test_compressed_enum_table.cpp b/components/nvs_flash/test_nvs_host/test_compressed_enum_table.cpp similarity index 100% rename from components/nvs_flash/test/test_compressed_enum_table.cpp rename to components/nvs_flash/test_nvs_host/test_compressed_enum_table.cpp diff --git a/components/nvs_flash/test/test_intrusive_list.cpp b/components/nvs_flash/test_nvs_host/test_intrusive_list.cpp similarity index 100% rename from components/nvs_flash/test/test_intrusive_list.cpp rename to components/nvs_flash/test_nvs_host/test_intrusive_list.cpp diff --git a/components/nvs_flash/test/test_nvs.cpp b/components/nvs_flash/test_nvs_host/test_nvs.cpp similarity index 100% rename from components/nvs_flash/test/test_nvs.cpp rename to components/nvs_flash/test_nvs_host/test_nvs.cpp diff --git a/components/nvs_flash/test/test_spi_flash_emulation.cpp b/components/nvs_flash/test_nvs_host/test_spi_flash_emulation.cpp similarity index 100% rename from components/nvs_flash/test/test_spi_flash_emulation.cpp rename to components/nvs_flash/test_nvs_host/test_spi_flash_emulation.cpp diff --git a/components/partition_table/test/component.mk b/components/partition_table/test/component.mk new file mode 100644 index 0000000000..5dd172bdb7 --- /dev/null +++ b/components/partition_table/test/component.mk @@ -0,0 +1,5 @@ +# +#Component Makefile +# + +COMPONENT_ADD_LDFLAGS = -Wl,--whole-archive -l$(COMPONENT_NAME) -Wl,--no-whole-archive diff --git a/components/partition_table/test/test_partition.c b/components/partition_table/test/test_partition.c new file mode 100644 index 0000000000..a4288d8e1d --- /dev/null +++ b/components/partition_table/test/test_partition.c @@ -0,0 +1,95 @@ +#include +#include +#include "unity.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(p->address, 0x10000); + TEST_ASSERT_EQUAL(p->subtype, ESP_PARTITION_SUBTYPE_APP_FACTORY); + + 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; + for (; it != NULL; it = esp_partition_next(it)) { + const esp_partition_t *p = esp_partition_get(it); + TEST_ASSERT_NOT_NULL(p); + ++count; + } + esp_partition_iterator_release(it); + TEST_ASSERT_EQUAL(count, 2); + + printf("%d\n", __builtin_clz(count)); +} + +TEST_CASE("Can write, read, mmap partition", "[partition]") +{ + const esp_partition_t *p = esp_partition_find_first(ESP_PARTITION_TYPE_DATA, ESP_PARTITION_SUBTYPE_ANY, NULL); + 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(); + if (i == 0 && offset == 0) { + printf("write: %08x\n", ((uint32_t *) (data))[i]); + } + } + 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 = 12000; + 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); +} diff --git a/components/spi_flash/test/component.mk b/components/spi_flash/test/component.mk new file mode 100644 index 0000000000..5dd172bdb7 --- /dev/null +++ b/components/spi_flash/test/component.mk @@ -0,0 +1,5 @@ +# +#Component Makefile +# + +COMPONENT_ADD_LDFLAGS = -Wl,--whole-archive -l$(COMPONENT_NAME) -Wl,--no-whole-archive diff --git a/components/spi_flash/test/test_mmap.c b/components/spi_flash/test/test_mmap.c new file mode 100644 index 0000000000..28d9ae6dda --- /dev/null +++ b/components/spi_flash/test/test_mmap.c @@ -0,0 +1,83 @@ +#include +#include +#include +#include +#include + +#include +#include +#include + +uint32_t buffer[1024]; + +static const uint32_t start = 0x200000; +static const uint32_t end = 0x300000; + + + +TEST_CASE("Prepare data for mmap tests", "[mmap]") +{ + srand(0); + for (int block = start / 0x10000; block < end / 0x10000; ++block) { + printf("Writing block %d\n", block); + for (int sector = 0; sector < 16; ++sector) { + for (uint32_t word = 0; word < 1024; ++word) { + uint32_t val = rand(); + if (block == start / 0x10000 && sector == 0 && word == 0) { + printf("first word: %08x\n", val); + } + buffer[word] = val; + } + uint32_t abs_sector = (block) * 16 + sector; + printf("Writing sector %d\n", abs_sector); + ESP_ERROR_CHECK( spi_flash_erase_sector((uint16_t) abs_sector) ); + ESP_ERROR_CHECK( spi_flash_write(abs_sector * SPI_FLASH_SEC_SIZE, (const uint8_t *) buffer, sizeof(buffer)) ); + } + } +} + +TEST_CASE("Can mmap into data address space", "[mmap]") +{ + + printf("Mapping %x (+%x)\n", start, end - start); + spi_flash_mmap_handle_t handle1; + const void *ptr1; + ESP_ERROR_CHECK( spi_flash_mmap(start, end - start, SPI_FLASH_MMAP_DATA, &ptr1, &handle1) ); + printf("mmap_res: handle=%d ptr=%p\n", handle1, ptr1); + + spi_flash_mmap_dump(); + + srand(0); + const uint32_t *data = (const uint32_t *) ptr1; + for (int block = 0; block < (end - start) / 0x10000; ++block) { + for (int sector = 0; sector < 16; ++sector) { + for (uint32_t word = 0; word < 1024; ++word) { + TEST_ASSERT_EQUAL_UINT32(rand(), data[(block * 16 + sector) * 1024 + word]); + } + } + } + printf("Mapping %x (+%x)\n", start - 0x10000, 0x20000); + spi_flash_mmap_handle_t handle2; + const void *ptr2; + ESP_ERROR_CHECK( spi_flash_mmap(start - 0x10000, 0x20000, SPI_FLASH_MMAP_DATA, &ptr2, &handle2) ); + printf("mmap_res: handle=%d ptr=%p\n", handle2, ptr2); + spi_flash_mmap_dump(); + + printf("Mapping %x (+%x)\n", start, 0x10000); + spi_flash_mmap_handle_t handle3; + const void *ptr3; + ESP_ERROR_CHECK( spi_flash_mmap(start, 0x10000, SPI_FLASH_MMAP_DATA, &ptr3, &handle3) ); + printf("mmap_res: handle=%d ptr=%p\n", handle3, ptr3); + spi_flash_mmap_dump(); + + printf("Unmapping handle1\n"); + spi_flash_munmap(handle1); + spi_flash_mmap_dump(); + + printf("Unmapping handle2\n"); + spi_flash_munmap(handle2); + spi_flash_mmap_dump(); + + printf("Unmapping handle3\n"); + spi_flash_munmap(handle3); +} diff --git a/components/spi_flash/test/test_spi_flash.c b/components/spi_flash/test/test_spi_flash.c new file mode 100644 index 0000000000..330e37bb82 --- /dev/null +++ b/components/spi_flash/test/test_spi_flash.c @@ -0,0 +1,92 @@ +#include +#include +#include +#include + +#include +#include +#include + +struct flash_test_ctx { + uint32_t offset[2]; + bool fail[2]; + SemaphoreHandle_t done; +}; + +static void flash_test_task(void *arg) +{ + const uint32_t coreid = xPortGetCoreID(); + ets_printf("t%d\n", coreid); + struct flash_test_ctx *ctx = (struct flash_test_ctx *) arg; + vTaskDelay(100 / portTICK_PERIOD_MS); + const uint32_t sector = ctx->offset[coreid]; + ets_printf("es%d\n", coreid); + if (spi_flash_erase_sector(sector) != ESP_OK) { + ctx->fail[coreid] = true; + ets_printf("Erase failed\r\n"); + xSemaphoreGive(ctx->done); + vTaskDelete(NULL); + } + ets_printf("ed%d\n", coreid); + + vTaskDelay(0 / portTICK_PERIOD_MS); + + uint32_t val = 0xabcd1234; + const uint32_t n = 4096; + for (uint32_t offset = 0; offset < n; offset += 4) { + if (spi_flash_write(sector * SPI_FLASH_SEC_SIZE + offset, (const uint8_t *) &val, 4) != ESP_OK) { + ets_printf("Write failed at offset=%d\r\n", offset); + ctx->fail[coreid] = true; + break; + } + } + ets_printf("wd%d\n", coreid); + + vTaskDelay(0 / portTICK_PERIOD_MS); + + uint32_t val_read; + for (uint32_t offset = 0; offset < n; offset += 4) { + if (spi_flash_read(sector * SPI_FLASH_SEC_SIZE + offset, (uint8_t *) &val_read, 4) != ESP_OK) { + ets_printf("Read failed at offset=%d\r\n", offset); + ctx->fail[coreid] = true; + break; + } + if (val_read != val) { + ets_printf("Read invalid value=%08x at offset=%d\r\n", val_read, offset); + ctx->fail[coreid] = true; + break; + } + } + ets_printf("td%d\n", coreid); + xSemaphoreGive(ctx->done); + vTaskDelete(NULL); +} + +TEST_CASE("flash write and erase work both on PRO CPU and on APP CPU", "[spi_flash]") +{ + TaskHandle_t procpu_task; + TaskHandle_t appcpu_task; + struct flash_test_ctx ctx; + + ctx.offset[0] = 6; + ctx.offset[1] = 7; + ctx.fail[0] = 0; + ctx.fail[1] = 0; + ctx.done = xSemaphoreCreateBinary(); + + xTaskCreatePinnedToCore(flash_test_task, "1", 2048, &ctx, 3, &procpu_task, 0); + if (portNUM_PROCESSORS == 2) { + xTaskCreatePinnedToCore(flash_test_task, "2", 2048, &ctx, 3, &appcpu_task, 1); + } + + xSemaphoreTake(ctx.done, portMAX_DELAY); + if (portNUM_PROCESSORS == 2) { + xSemaphoreTake(ctx.done, portMAX_DELAY); + } + + TEST_ASSERT_EQUAL(false, ctx.fail[0]); + if (portNUM_PROCESSORS == 2) { + TEST_ASSERT_EQUAL(false, ctx.fail[1]); + } +} + diff --git a/make/component_wrapper.mk b/make/component_wrapper.mk index 3018c18b55..16c9c02b5f 100644 --- a/make/component_wrapper.mk +++ b/make/component_wrapper.mk @@ -32,9 +32,6 @@ include $(IDF_PATH)/make/common.mk # Some of the following defaults may be overriden by the component's component.mk makefile, # during the next step: -# Name of the component -COMPONENT_NAME := $(lastword $(subst /, ,$(realpath $(COMPONENT_PATH)))) - # Absolute path of the .a file COMPONENT_LIBRARY = lib$(COMPONENT_NAME).a diff --git a/make/project.mk b/make/project.mk index 870db55f97..0dfce4368a 100644 --- a/make/project.mk +++ b/make/project.mk @@ -94,6 +94,12 @@ COMPONENT_PATHS += $(abspath $(SRCDIRS)) # A component is buildable if it has a component.mk makefile in it COMPONENT_PATHS_BUILDABLE := $(foreach cp,$(COMPONENT_PATHS),$(if $(wildcard $(cp)/component.mk),$(cp))) +# If TEST_COMPONENTS is set on the command line, create variables for building unit tests +ifdef TEST_COMPONENTS +TEST_COMPONENT_PATHS := $(foreach comp,$(TEST_COMPONENTS),$(IDF_PATH)/components/$(comp)/test) +TEST_COMPONENT_NAMES := $(foreach comp,$(TEST_COMPONENTS),$(comp)_test) +endif + # Initialise project-wide variables which can be added to by # each component. # @@ -113,7 +119,7 @@ COMPONENT_SUBMODULES := # dependencies. # # See the component_project_vars.mk target in component_wrapper.mk -COMPONENT_PROJECT_VARS := $(addsuffix /component_project_vars.mk,$(notdir $(COMPONENT_PATHS_BUILDABLE))) +COMPONENT_PROJECT_VARS := $(addsuffix /component_project_vars.mk,$(notdir $(COMPONENT_PATHS_BUILDABLE) ) $(TEST_COMPONENT_NAMES)) COMPONENT_PROJECT_VARS := $(addprefix $(BUILD_DIR_BASE)/,$(COMPONENT_PROJECT_VARS)) # this line is -include instead of include to prevent a spurious error message on make 3.81 -include $(COMPONENT_PROJECT_VARS) @@ -140,7 +146,7 @@ endif LDFLAGS ?= -nostdlib \ -L$(IDF_PATH)/lib \ -L$(IDF_PATH)/ld \ - $(addprefix -L$(BUILD_DIR_BASE)/,$(COMPONENTS) $(SRCDIRS)) \ + $(addprefix -L$(BUILD_DIR_BASE)/,$(COMPONENTS) $(TEST_COMPONENT_NAMES) $(SRCDIRS) ) \ -u call_user_start_cpu0 \ $(EXTRA_LDFLAGS) \ -Wl,--gc-sections \ @@ -257,7 +263,7 @@ endif # A "component" library is any library in the LDFLAGS where # the name of the library is also a name of the component APP_LIBRARIES = $(patsubst -l%,%,$(filter -l%,$(LDFLAGS))) -COMPONENT_LIBRARIES = $(filter $(notdir $(COMPONENT_PATHS_BUILDABLE)),$(APP_LIBRARIES)) +COMPONENT_LIBRARIES = $(filter $(notdir $(COMPONENT_PATHS_BUILDABLE)) $(TEST_COMPONENT_NAMES),$(APP_LIBRARIES)) # ELF depends on the library archive files for COMPONENT_LIBRARIES # the rules to build these are emitted as part of GenerateComponentTarget below @@ -282,7 +288,7 @@ $(BUILD_DIR_BASE): # # Is recursively expanded by the GenerateComponentTargets macro define ComponentMake -+$(MAKE) -C $(BUILD_DIR_BASE)/$(2) -f $(IDF_PATH)/make/component_wrapper.mk COMPONENT_MAKEFILE=$(1)/component.mk ++$(MAKE) -C $(BUILD_DIR_BASE)/$(2) -f $(IDF_PATH)/make/component_wrapper.mk COMPONENT_MAKEFILE=$(1)/component.mk COMPONENT_NAME=$(2) endef # Generate top-level component-specific targets for each component @@ -325,6 +331,7 @@ $(BUILD_DIR_BASE)/$(2)/component_project_vars.mk: $(1)/component.mk $(COMMON_MAK endef $(foreach component,$(COMPONENT_PATHS_BUILDABLE),$(eval $(call GenerateComponentTargets,$(component),$(notdir $(component))))) +$(foreach component,$(TEST_COMPONENT_PATHS),$(eval $(call GenerateComponentTargets,$(component),$(lastword $(subst /, ,$(dir $(component))))_test))) app-clean: $(addsuffix -clean,$(notdir $(COMPONENT_PATHS_BUILDABLE))) $(summary) RM $(APP_ELF) diff --git a/tools/unit-test-app/Makefile b/tools/unit-test-app/Makefile new file mode 100644 index 0000000000..128e8a0804 --- /dev/null +++ b/tools/unit-test-app/Makefile @@ -0,0 +1,9 @@ +# +# This is a project Makefile. It is assumed the directory this Makefile resides in is a +# project subdirectory. +# + +PROJECT_NAME := unit-test-app + +include $(IDF_PATH)/make/project.mk + diff --git a/tools/unit-test-app/README.md b/tools/unit-test-app/README.md new file mode 100644 index 0000000000..cf45ce287b --- /dev/null +++ b/tools/unit-test-app/README.md @@ -0,0 +1,12 @@ +# Unit Test App + +ESP-IDF unit tests are run using Unit Test App. The app can be built with the unit tests for a specific component. Unit tests are in `test` subdirectories of respective components. + +# Building Unit Test App + +* Follow the setup instructions in the top-level esp-idf README. +* Set IDF_PATH environment variable to point to the path to the esp-idf top-level directory. +* Change into `tools/unit-test-app` directory +* `make menuconfig` to configure the Unit Test App. +* `make TEST_COMPONENTS=` with `TEST_COMPONENTS` set to names of the components to be included in the test app. +* Follow the printed instructions to flash, or run `make flash`. diff --git a/tools/unit-test-app/components/unity/component.mk b/tools/unit-test-app/components/unity/component.mk new file mode 100644 index 0000000000..ebd7a7d59b --- /dev/null +++ b/tools/unit-test-app/components/unity/component.mk @@ -0,0 +1,3 @@ +# +# Component Makefile +# diff --git a/tools/unit-test-app/components/unity/include/unity.h b/tools/unit-test-app/components/unity/include/unity.h new file mode 100644 index 0000000000..3ffc14c0b8 --- /dev/null +++ b/tools/unit-test-app/components/unity/include/unity.h @@ -0,0 +1,292 @@ +/* ========================================== + Unity Project - A Test Framework for C + Copyright (c) 2007-14 Mike Karlesky, Mark VanderVoord, Greg Williams + [Released under MIT License. Please refer to license.txt for details] +========================================== */ + +#ifndef UNITY_FRAMEWORK_H +#define UNITY_FRAMEWORK_H +#define UNITY + +#ifdef __cplusplus +extern "C" +{ +#endif + +#define UNITY_INCLUDE_CONFIG_H +#include "unity_internals.h" + +void setUp(void); +void tearDown(void); + +/*------------------------------------------------------- + * Configuration Options + *------------------------------------------------------- + * All options described below should be passed as a compiler flag to all files using Unity. If you must add #defines, place them BEFORE the #include above. + + * Integers/longs/pointers + * - Unity attempts to automatically discover your integer sizes + * - define UNITY_EXCLUDE_STDINT_H to stop attempting to look in + * - define UNITY_EXCLUDE_LIMITS_H to stop attempting to look in + * - define UNITY_EXCLUDE_SIZEOF to stop attempting to use sizeof in macros + * - If you cannot use the automatic methods above, you can force Unity by using these options: + * - define UNITY_SUPPORT_64 + * - define UNITY_INT_WIDTH + * - UNITY_LONG_WIDTH + * - UNITY_POINTER_WIDTH + + * Floats + * - define UNITY_EXCLUDE_FLOAT to disallow floating point comparisons + * - define UNITY_FLOAT_PRECISION to specify the precision to use when doing TEST_ASSERT_EQUAL_FLOAT + * - define UNITY_FLOAT_TYPE to specify doubles instead of single precision floats + * - define UNITY_FLOAT_VERBOSE to print floating point values in errors (uses sprintf) + * - define UNITY_INCLUDE_DOUBLE to allow double floating point comparisons + * - define UNITY_EXCLUDE_DOUBLE to disallow double floating point comparisons (default) + * - define UNITY_DOUBLE_PRECISION to specify the precision to use when doing TEST_ASSERT_EQUAL_DOUBLE + * - define UNITY_DOUBLE_TYPE to specify something other than double + * - define UNITY_DOUBLE_VERBOSE to print floating point values in errors (uses sprintf) + * - define UNITY_VERBOSE_NUMBER_MAX_LENGTH to change maximum length of printed numbers (used by sprintf) + + * Output + * - by default, Unity prints to standard out with putchar. define UNITY_OUTPUT_CHAR(a) with a different function if desired + * - define UNITY_DIFFERENTIATE_FINAL_FAIL to print FAILED (vs. FAIL) at test end summary - for automated search for failure + + * Optimization + * - by default, line numbers are stored in unsigned shorts. Define UNITY_LINE_TYPE with a different type if your files are huge + * - by default, test and failure counters are unsigned shorts. Define UNITY_COUNTER_TYPE with a different type if you want to save space or have more than 65535 Tests. + + * Test Cases + * - define UNITY_SUPPORT_TEST_CASES to include the TEST_CASE macro, though really it's mostly about the runner generator script + + * Parameterized Tests + * - you'll want to create a define of TEST_CASE(...) which basically evaluates to nothing + + *------------------------------------------------------- + * Basic Fail and Ignore + *-------------------------------------------------------*/ + +#define TEST_FAIL_MESSAGE(message) UNITY_TEST_FAIL(__LINE__, (message)) +#define TEST_FAIL() UNITY_TEST_FAIL(__LINE__, NULL) +#define TEST_IGNORE_MESSAGE(message) UNITY_TEST_IGNORE(__LINE__, (message)) +#define TEST_IGNORE() UNITY_TEST_IGNORE(__LINE__, NULL) +#define TEST_ONLY() + +/* It is not necessary for you to call PASS. A PASS condition is assumed if nothing fails. + * This method allows you to abort a test immediately with a PASS state, ignoring the remainder of the test. */ +#define TEST_PASS() longjmp(Unity.AbortFrame, 1) + +/*------------------------------------------------------- + * Test Asserts (simple) + *-------------------------------------------------------*/ + +/* Boolean */ +#define TEST_ASSERT(condition) UNITY_TEST_ASSERT( (condition), __LINE__, " Expression Evaluated To FALSE") +#define TEST_ASSERT_TRUE(condition) UNITY_TEST_ASSERT( (condition), __LINE__, " Expected TRUE Was FALSE") +#define TEST_ASSERT_UNLESS(condition) UNITY_TEST_ASSERT( !(condition), __LINE__, " Expression Evaluated To TRUE") +#define TEST_ASSERT_FALSE(condition) UNITY_TEST_ASSERT( !(condition), __LINE__, " Expected FALSE Was TRUE") +#define TEST_ASSERT_NULL(pointer) UNITY_TEST_ASSERT_NULL( (pointer), __LINE__, " Expected NULL") +#define TEST_ASSERT_NOT_NULL(pointer) UNITY_TEST_ASSERT_NOT_NULL((pointer), __LINE__, " Expected Non-NULL") + +/* Integers (of all sizes) */ +#define TEST_ASSERT_EQUAL_INT(expected, actual) UNITY_TEST_ASSERT_EQUAL_INT((expected), (actual), __LINE__, NULL) +#define TEST_ASSERT_EQUAL_INT8(expected, actual) UNITY_TEST_ASSERT_EQUAL_INT8((expected), (actual), __LINE__, NULL) +#define TEST_ASSERT_EQUAL_INT16(expected, actual) UNITY_TEST_ASSERT_EQUAL_INT16((expected), (actual), __LINE__, NULL) +#define TEST_ASSERT_EQUAL_INT32(expected, actual) UNITY_TEST_ASSERT_EQUAL_INT32((expected), (actual), __LINE__, NULL) +#define TEST_ASSERT_EQUAL_INT64(expected, actual) UNITY_TEST_ASSERT_EQUAL_INT64((expected), (actual), __LINE__, NULL) +#define TEST_ASSERT_EQUAL(expected, actual) UNITY_TEST_ASSERT_EQUAL_INT((expected), (actual), __LINE__, NULL) +#define TEST_ASSERT_NOT_EQUAL(expected, actual) UNITY_TEST_ASSERT(((expected) != (actual)), __LINE__, " Expected Not-Equal") +#define TEST_ASSERT_EQUAL_UINT(expected, actual) UNITY_TEST_ASSERT_EQUAL_UINT( (expected), (actual), __LINE__, NULL) +#define TEST_ASSERT_EQUAL_UINT8(expected, actual) UNITY_TEST_ASSERT_EQUAL_UINT8( (expected), (actual), __LINE__, NULL) +#define TEST_ASSERT_EQUAL_UINT16(expected, actual) UNITY_TEST_ASSERT_EQUAL_UINT16( (expected), (actual), __LINE__, NULL) +#define TEST_ASSERT_EQUAL_UINT32(expected, actual) UNITY_TEST_ASSERT_EQUAL_UINT32( (expected), (actual), __LINE__, NULL) +#define TEST_ASSERT_EQUAL_UINT64(expected, actual) UNITY_TEST_ASSERT_EQUAL_UINT64( (expected), (actual), __LINE__, NULL) +#define TEST_ASSERT_EQUAL_HEX(expected, actual) UNITY_TEST_ASSERT_EQUAL_HEX32((expected), (actual), __LINE__, NULL) +#define TEST_ASSERT_EQUAL_HEX8(expected, actual) UNITY_TEST_ASSERT_EQUAL_HEX8( (expected), (actual), __LINE__, NULL) +#define TEST_ASSERT_EQUAL_HEX16(expected, actual) UNITY_TEST_ASSERT_EQUAL_HEX16((expected), (actual), __LINE__, NULL) +#define TEST_ASSERT_EQUAL_HEX32(expected, actual) UNITY_TEST_ASSERT_EQUAL_HEX32((expected), (actual), __LINE__, NULL) +#define TEST_ASSERT_EQUAL_HEX64(expected, actual) UNITY_TEST_ASSERT_EQUAL_HEX64((expected), (actual), __LINE__, NULL) +#define TEST_ASSERT_BITS(mask, expected, actual) UNITY_TEST_ASSERT_BITS((mask), (expected), (actual), __LINE__, NULL) +#define TEST_ASSERT_BITS_HIGH(mask, actual) UNITY_TEST_ASSERT_BITS((mask), (_UU32)(-1), (actual), __LINE__, NULL) +#define TEST_ASSERT_BITS_LOW(mask, actual) UNITY_TEST_ASSERT_BITS((mask), (_UU32)(0), (actual), __LINE__, NULL) +#define TEST_ASSERT_BIT_HIGH(bit, actual) UNITY_TEST_ASSERT_BITS(((_UU32)1 << (bit)), (_UU32)(-1), (actual), __LINE__, NULL) +#define TEST_ASSERT_BIT_LOW(bit, actual) UNITY_TEST_ASSERT_BITS(((_UU32)1 << (bit)), (_UU32)(0), (actual), __LINE__, NULL) + +/* Integer Ranges (of all sizes) */ +#define TEST_ASSERT_INT_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_INT_WITHIN((delta), (expected), (actual), __LINE__, NULL) +#define TEST_ASSERT_INT8_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_INT8_WITHIN((delta), (expected), (actual), __LINE__, NULL) +#define TEST_ASSERT_INT16_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_INT16_WITHIN((delta), (expected), (actual), __LINE__, NULL) +#define TEST_ASSERT_INT32_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_INT32_WITHIN((delta), (expected), (actual), __LINE__, NULL) +#define TEST_ASSERT_INT64_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_INT64_WITHIN((delta), (expected), (actual), __LINE__, NULL) +#define TEST_ASSERT_UINT_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_UINT_WITHIN((delta), (expected), (actual), __LINE__, NULL) +#define TEST_ASSERT_UINT8_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_UINT8_WITHIN((delta), (expected), (actual), __LINE__, NULL) +#define TEST_ASSERT_UINT16_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_UINT16_WITHIN((delta), (expected), (actual), __LINE__, NULL) +#define TEST_ASSERT_UINT32_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_UINT32_WITHIN((delta), (expected), (actual), __LINE__, NULL) +#define TEST_ASSERT_UINT64_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_UINT64_WITHIN((delta), (expected), (actual), __LINE__, NULL) +#define TEST_ASSERT_HEX_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_HEX32_WITHIN((delta), (expected), (actual), __LINE__, NULL) +#define TEST_ASSERT_HEX8_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_HEX8_WITHIN((delta), (expected), (actual), __LINE__, NULL) +#define TEST_ASSERT_HEX16_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_HEX16_WITHIN((delta), (expected), (actual), __LINE__, NULL) +#define TEST_ASSERT_HEX32_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_HEX32_WITHIN((delta), (expected), (actual), __LINE__, NULL) +#define TEST_ASSERT_HEX64_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_HEX64_WITHIN((delta), (expected), (actual), __LINE__, NULL) + +/* Structs and Strings */ +#define TEST_ASSERT_EQUAL_PTR(expected, actual) UNITY_TEST_ASSERT_EQUAL_PTR((expected), (actual), __LINE__, NULL) +#define TEST_ASSERT_EQUAL_STRING(expected, actual) UNITY_TEST_ASSERT_EQUAL_STRING((expected), (actual), __LINE__, NULL) +#define TEST_ASSERT_EQUAL_STRING_LEN(expected, actual, len) UNITY_TEST_ASSERT_EQUAL_STRING_LEN((expected), (actual), (len), __LINE__, NULL) +#define TEST_ASSERT_EQUAL_MEMORY(expected, actual, len) UNITY_TEST_ASSERT_EQUAL_MEMORY((expected), (actual), (len), __LINE__, NULL) + +/* Arrays */ +#define TEST_ASSERT_EQUAL_INT_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_INT_ARRAY((expected), (actual), (num_elements), __LINE__, NULL) +#define TEST_ASSERT_EQUAL_INT8_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_INT8_ARRAY((expected), (actual), (num_elements), __LINE__, NULL) +#define TEST_ASSERT_EQUAL_INT16_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_INT16_ARRAY((expected), (actual), (num_elements), __LINE__, NULL) +#define TEST_ASSERT_EQUAL_INT32_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_INT32_ARRAY((expected), (actual), (num_elements), __LINE__, NULL) +#define TEST_ASSERT_EQUAL_INT64_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_INT64_ARRAY((expected), (actual), (num_elements), __LINE__, NULL) +#define TEST_ASSERT_EQUAL_UINT_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_UINT_ARRAY((expected), (actual), (num_elements), __LINE__, NULL) +#define TEST_ASSERT_EQUAL_UINT8_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_UINT8_ARRAY((expected), (actual), (num_elements), __LINE__, NULL) +#define TEST_ASSERT_EQUAL_UINT16_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_UINT16_ARRAY((expected), (actual), (num_elements), __LINE__, NULL) +#define TEST_ASSERT_EQUAL_UINT32_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_UINT32_ARRAY((expected), (actual), (num_elements), __LINE__, NULL) +#define TEST_ASSERT_EQUAL_UINT64_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_UINT64_ARRAY((expected), (actual), (num_elements), __LINE__, NULL) +#define TEST_ASSERT_EQUAL_HEX_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_HEX32_ARRAY((expected), (actual), (num_elements), __LINE__, NULL) +#define TEST_ASSERT_EQUAL_HEX8_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_HEX8_ARRAY((expected), (actual), (num_elements), __LINE__, NULL) +#define TEST_ASSERT_EQUAL_HEX16_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_HEX16_ARRAY((expected), (actual), (num_elements), __LINE__, NULL) +#define TEST_ASSERT_EQUAL_HEX32_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_HEX32_ARRAY((expected), (actual), (num_elements), __LINE__, NULL) +#define TEST_ASSERT_EQUAL_HEX64_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_HEX64_ARRAY((expected), (actual), (num_elements), __LINE__, NULL) +#define TEST_ASSERT_EQUAL_PTR_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_PTR_ARRAY((expected), (actual), (num_elements), __LINE__, NULL) +#define TEST_ASSERT_EQUAL_STRING_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_STRING_ARRAY((expected), (actual), (num_elements), __LINE__, NULL) +#define TEST_ASSERT_EQUAL_MEMORY_ARRAY(expected, actual, len, num_elements) UNITY_TEST_ASSERT_EQUAL_MEMORY_ARRAY((expected), (actual), (len), (num_elements), __LINE__, NULL) + +/* Floating Point (If Enabled) */ +#define TEST_ASSERT_FLOAT_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_FLOAT_WITHIN((delta), (expected), (actual), __LINE__, NULL) +#define TEST_ASSERT_EQUAL_FLOAT(expected, actual) UNITY_TEST_ASSERT_EQUAL_FLOAT((expected), (actual), __LINE__, NULL) +#define TEST_ASSERT_EQUAL_FLOAT_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_FLOAT_ARRAY((expected), (actual), (num_elements), __LINE__, NULL) +#define TEST_ASSERT_FLOAT_IS_INF(actual) UNITY_TEST_ASSERT_FLOAT_IS_INF((actual), __LINE__, NULL) +#define TEST_ASSERT_FLOAT_IS_NEG_INF(actual) UNITY_TEST_ASSERT_FLOAT_IS_NEG_INF((actual), __LINE__, NULL) +#define TEST_ASSERT_FLOAT_IS_NAN(actual) UNITY_TEST_ASSERT_FLOAT_IS_NAN((actual), __LINE__, NULL) +#define TEST_ASSERT_FLOAT_IS_DETERMINATE(actual) UNITY_TEST_ASSERT_FLOAT_IS_DETERMINATE((actual), __LINE__, NULL) +#define TEST_ASSERT_FLOAT_IS_NOT_INF(actual) UNITY_TEST_ASSERT_FLOAT_IS_NOT_INF((actual), __LINE__, NULL) +#define TEST_ASSERT_FLOAT_IS_NOT_NEG_INF(actual) UNITY_TEST_ASSERT_FLOAT_IS_NOT_NEG_INF((actual), __LINE__, NULL) +#define TEST_ASSERT_FLOAT_IS_NOT_NAN(actual) UNITY_TEST_ASSERT_FLOAT_IS_NOT_NAN((actual), __LINE__, NULL) +#define TEST_ASSERT_FLOAT_IS_NOT_DETERMINATE(actual) UNITY_TEST_ASSERT_FLOAT_IS_NOT_DETERMINATE((actual), __LINE__, NULL) + +/* Double (If Enabled) */ +#define TEST_ASSERT_DOUBLE_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_DOUBLE_WITHIN((delta), (expected), (actual), __LINE__, NULL) +#define TEST_ASSERT_EQUAL_DOUBLE(expected, actual) UNITY_TEST_ASSERT_EQUAL_DOUBLE((expected), (actual), __LINE__, NULL) +#define TEST_ASSERT_EQUAL_DOUBLE_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_DOUBLE_ARRAY((expected), (actual), (num_elements), __LINE__, NULL) +#define TEST_ASSERT_DOUBLE_IS_INF(actual) UNITY_TEST_ASSERT_DOUBLE_IS_INF((actual), __LINE__, NULL) +#define TEST_ASSERT_DOUBLE_IS_NEG_INF(actual) UNITY_TEST_ASSERT_DOUBLE_IS_NEG_INF((actual), __LINE__, NULL) +#define TEST_ASSERT_DOUBLE_IS_NAN(actual) UNITY_TEST_ASSERT_DOUBLE_IS_NAN((actual), __LINE__, NULL) +#define TEST_ASSERT_DOUBLE_IS_DETERMINATE(actual) UNITY_TEST_ASSERT_DOUBLE_IS_DETERMINATE((actual), __LINE__, NULL) +#define TEST_ASSERT_DOUBLE_IS_NOT_INF(actual) UNITY_TEST_ASSERT_DOUBLE_IS_NOT_INF((actual), __LINE__, NULL) +#define TEST_ASSERT_DOUBLE_IS_NOT_NEG_INF(actual) UNITY_TEST_ASSERT_DOUBLE_IS_NOT_NEG_INF((actual), __LINE__, NULL) +#define TEST_ASSERT_DOUBLE_IS_NOT_NAN(actual) UNITY_TEST_ASSERT_DOUBLE_IS_NOT_NAN((actual), __LINE__, NULL) +#define TEST_ASSERT_DOUBLE_IS_NOT_DETERMINATE(actual) UNITY_TEST_ASSERT_DOUBLE_IS_NOT_DETERMINATE((actual), __LINE__, NULL) + +/*------------------------------------------------------- + * Test Asserts (with additional messages) + *-------------------------------------------------------*/ + +/* Boolean */ +#define TEST_ASSERT_MESSAGE(condition, message) UNITY_TEST_ASSERT( (condition), __LINE__, (message)) +#define TEST_ASSERT_TRUE_MESSAGE(condition, message) UNITY_TEST_ASSERT( (condition), __LINE__, (message)) +#define TEST_ASSERT_UNLESS_MESSAGE(condition, message) UNITY_TEST_ASSERT( !(condition), __LINE__, (message)) +#define TEST_ASSERT_FALSE_MESSAGE(condition, message) UNITY_TEST_ASSERT( !(condition), __LINE__, (message)) +#define TEST_ASSERT_NULL_MESSAGE(pointer, message) UNITY_TEST_ASSERT_NULL( (pointer), __LINE__, (message)) +#define TEST_ASSERT_NOT_NULL_MESSAGE(pointer, message) UNITY_TEST_ASSERT_NOT_NULL((pointer), __LINE__, (message)) + +/* Integers (of all sizes) */ +#define TEST_ASSERT_EQUAL_INT_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_INT((expected), (actual), __LINE__, (message)) +#define TEST_ASSERT_EQUAL_INT8_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_INT8((expected), (actual), __LINE__, (message)) +#define TEST_ASSERT_EQUAL_INT16_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_INT16((expected), (actual), __LINE__, (message)) +#define TEST_ASSERT_EQUAL_INT32_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_INT32((expected), (actual), __LINE__, (message)) +#define TEST_ASSERT_EQUAL_INT64_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_INT64((expected), (actual), __LINE__, (message)) +#define TEST_ASSERT_EQUAL_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_INT((expected), (actual), __LINE__, (message)) +#define TEST_ASSERT_NOT_EQUAL_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT(((expected) != (actual)), __LINE__, (message)) +#define TEST_ASSERT_EQUAL_UINT_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_UINT( (expected), (actual), __LINE__, (message)) +#define TEST_ASSERT_EQUAL_UINT8_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_UINT8( (expected), (actual), __LINE__, (message)) +#define TEST_ASSERT_EQUAL_UINT16_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_UINT16( (expected), (actual), __LINE__, (message)) +#define TEST_ASSERT_EQUAL_UINT32_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_UINT32( (expected), (actual), __LINE__, (message)) +#define TEST_ASSERT_EQUAL_UINT64_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_UINT64( (expected), (actual), __LINE__, (message)) +#define TEST_ASSERT_EQUAL_HEX_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_HEX32((expected), (actual), __LINE__, (message)) +#define TEST_ASSERT_EQUAL_HEX8_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_HEX8( (expected), (actual), __LINE__, (message)) +#define TEST_ASSERT_EQUAL_HEX16_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_HEX16((expected), (actual), __LINE__, (message)) +#define TEST_ASSERT_EQUAL_HEX32_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_HEX32((expected), (actual), __LINE__, (message)) +#define TEST_ASSERT_EQUAL_HEX64_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_HEX64((expected), (actual), __LINE__, (message)) +#define TEST_ASSERT_BITS_MESSAGE(mask, expected, actual, message) UNITY_TEST_ASSERT_BITS((mask), (expected), (actual), __LINE__, (message)) +#define TEST_ASSERT_BITS_HIGH_MESSAGE(mask, actual, message) UNITY_TEST_ASSERT_BITS((mask), (_UU32)(-1), (actual), __LINE__, (message)) +#define TEST_ASSERT_BITS_LOW_MESSAGE(mask, actual, message) UNITY_TEST_ASSERT_BITS((mask), (_UU32)(0), (actual), __LINE__, (message)) +#define TEST_ASSERT_BIT_HIGH_MESSAGE(bit, actual, message) UNITY_TEST_ASSERT_BITS(((_UU32)1 << (bit)), (_UU32)(-1), (actual), __LINE__, (message)) +#define TEST_ASSERT_BIT_LOW_MESSAGE(bit, actual, message) UNITY_TEST_ASSERT_BITS(((_UU32)1 << (bit)), (_UU32)(0), (actual), __LINE__, (message)) + +/* Integer Ranges (of all sizes) */ +#define TEST_ASSERT_INT_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_INT_WITHIN((delta), (expected), (actual), __LINE__, (message)) +#define TEST_ASSERT_INT8_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_INT8_WITHIN((delta), (expected), (actual), __LINE__, (message)) +#define TEST_ASSERT_INT16_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_INT16_WITHIN((delta), (expected), (actual), __LINE__, (message)) +#define TEST_ASSERT_INT32_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_INT32_WITHIN((delta), (expected), (actual), __LINE__, (message)) +#define TEST_ASSERT_INT64_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_INT64_WITHIN((delta), (expected), (actual), __LINE__, (message)) +#define TEST_ASSERT_UINT_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_UINT_WITHIN((delta), (expected), (actual), __LINE__, (message)) +#define TEST_ASSERT_UINT8_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_UINT8_WITHIN((delta), (expected), (actual), __LINE__, (message)) +#define TEST_ASSERT_UINT16_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_UINT16_WITHIN((delta), (expected), (actual), __LINE__, (message)) +#define TEST_ASSERT_UINT32_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_UINT32_WITHIN((delta), (expected), (actual), __LINE__, (message)) +#define TEST_ASSERT_UINT64_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_UINT64_WITHIN((delta), (expected), (actual), __LINE__, (message)) +#define TEST_ASSERT_HEX_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_HEX32_WITHIN((delta), (expected), (actual), __LINE__, (message)) +#define TEST_ASSERT_HEX8_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_HEX8_WITHIN((delta), (expected), (actual), __LINE__, (message)) +#define TEST_ASSERT_HEX16_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_HEX16_WITHIN((delta), (expected), (actual), __LINE__, (message)) +#define TEST_ASSERT_HEX32_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_HEX32_WITHIN((delta), (expected), (actual), __LINE__, (message)) +#define TEST_ASSERT_HEX64_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_HEX64_WITHIN((delta), (expected), (actual), __LINE__, (message)) + +/* Structs and Strings */ +#define TEST_ASSERT_EQUAL_PTR_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_PTR((expected), (actual), __LINE__, (message)) +#define TEST_ASSERT_EQUAL_STRING_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_STRING((expected), (actual), __LINE__, (message)) +#define TEST_ASSERT_EQUAL_STRING_LEN_MESSAGE(expected, actual, len, message) UNITY_TEST_ASSERT_EQUAL_STRING_LEN((expected), (actual), (len), __LINE__, (message)) +#define TEST_ASSERT_EQUAL_MEMORY_MESSAGE(expected, actual, len, message) UNITY_TEST_ASSERT_EQUAL_MEMORY((expected), (actual), (len), __LINE__, (message)) + +/* Arrays */ +#define TEST_ASSERT_EQUAL_INT_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_INT_ARRAY((expected), (actual), (num_elements), __LINE__, (message)) +#define TEST_ASSERT_EQUAL_INT8_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_INT8_ARRAY((expected), (actual), (num_elements), __LINE__, (message)) +#define TEST_ASSERT_EQUAL_INT16_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_INT16_ARRAY((expected), (actual), (num_elements), __LINE__, (message)) +#define TEST_ASSERT_EQUAL_INT32_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_INT32_ARRAY((expected), (actual), (num_elements), __LINE__, (message)) +#define TEST_ASSERT_EQUAL_INT64_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_INT64_ARRAY((expected), (actual), (num_elements), __LINE__, (message)) +#define TEST_ASSERT_EQUAL_UINT_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_UINT_ARRAY((expected), (actual), (num_elements), __LINE__, (message)) +#define TEST_ASSERT_EQUAL_UINT8_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_UINT8_ARRAY((expected), (actual), (num_elements), __LINE__, (message)) +#define TEST_ASSERT_EQUAL_UINT16_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_UINT16_ARRAY((expected), (actual), (num_elements), __LINE__, (message)) +#define TEST_ASSERT_EQUAL_UINT32_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_UINT32_ARRAY((expected), (actual), (num_elements), __LINE__, (message)) +#define TEST_ASSERT_EQUAL_UINT64_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_UINT64_ARRAY((expected), (actual), (num_elements), __LINE__, (message)) +#define TEST_ASSERT_EQUAL_HEX_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_HEX32_ARRAY((expected), (actual), (num_elements), __LINE__, (message)) +#define TEST_ASSERT_EQUAL_HEX8_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_HEX8_ARRAY((expected), (actual), (num_elements), __LINE__, (message)) +#define TEST_ASSERT_EQUAL_HEX16_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_HEX16_ARRAY((expected), (actual), (num_elements), __LINE__, (message)) +#define TEST_ASSERT_EQUAL_HEX32_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_HEX32_ARRAY((expected), (actual), (num_elements), __LINE__, (message)) +#define TEST_ASSERT_EQUAL_HEX64_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_HEX64_ARRAY((expected), (actual), (num_elements), __LINE__, (message)) +#define TEST_ASSERT_EQUAL_PTR_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_PTR_ARRAY((expected), (actual), (num_elements), __LINE__, (message)) +#define TEST_ASSERT_EQUAL_STRING_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_STRING_ARRAY((expected), (actual), (num_elements), __LINE__, (message)) +#define TEST_ASSERT_EQUAL_MEMORY_ARRAY_MESSAGE(expected, actual, len, num_elements, message) UNITY_TEST_ASSERT_EQUAL_MEMORY_ARRAY((expected), (actual), (len), (num_elements), __LINE__, (message)) + +/* Floating Point (If Enabled) */ +#define TEST_ASSERT_FLOAT_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_FLOAT_WITHIN((delta), (expected), (actual), __LINE__, (message)) +#define TEST_ASSERT_EQUAL_FLOAT_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_FLOAT((expected), (actual), __LINE__, (message)) +#define TEST_ASSERT_EQUAL_FLOAT_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_FLOAT_ARRAY((expected), (actual), (num_elements), __LINE__, (message)) +#define TEST_ASSERT_FLOAT_IS_INF_MESSAGE(actual, message) UNITY_TEST_ASSERT_FLOAT_IS_INF((actual), __LINE__, (message)) +#define TEST_ASSERT_FLOAT_IS_NEG_INF_MESSAGE(actual, message) UNITY_TEST_ASSERT_FLOAT_IS_NEG_INF((actual), __LINE__, (message)) +#define TEST_ASSERT_FLOAT_IS_NAN_MESSAGE(actual, message) UNITY_TEST_ASSERT_FLOAT_IS_NAN((actual), __LINE__, (message)) +#define TEST_ASSERT_FLOAT_IS_DETERMINATE_MESSAGE(actual, message) UNITY_TEST_ASSERT_FLOAT_IS_DETERMINATE((actual), __LINE__, (message)) +#define TEST_ASSERT_FLOAT_IS_NOT_INF_MESSAGE(actual, message) UNITY_TEST_ASSERT_FLOAT_IS_NOT_INF((actual), __LINE__, (message)) +#define TEST_ASSERT_FLOAT_IS_NOT_NEG_INF_MESSAGE(actual, message) UNITY_TEST_ASSERT_FLOAT_IS_NOT_NEG_INF((actual), __LINE__, (message)) +#define TEST_ASSERT_FLOAT_IS_NOT_NAN_MESSAGE(actual, message) UNITY_TEST_ASSERT_FLOAT_IS_NOT_NAN((actual), __LINE__, (message)) +#define TEST_ASSERT_FLOAT_IS_NOT_DETERMINATE_MESSAGE(actual, message) UNITY_TEST_ASSERT_FLOAT_IS_NOT_DETERMINATE((actual), __LINE__, (message)) + +/* Double (If Enabled) */ +#define TEST_ASSERT_DOUBLE_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_DOUBLE_WITHIN((delta), (expected), (actual), __LINE__, (message)) +#define TEST_ASSERT_EQUAL_DOUBLE_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_DOUBLE((expected), (actual), __LINE__, (message)) +#define TEST_ASSERT_EQUAL_DOUBLE_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_DOUBLE_ARRAY((expected), (actual), (num_elements), __LINE__, (message)) +#define TEST_ASSERT_DOUBLE_IS_INF_MESSAGE(actual, message) UNITY_TEST_ASSERT_DOUBLE_IS_INF((actual), __LINE__, (message)) +#define TEST_ASSERT_DOUBLE_IS_NEG_INF_MESSAGE(actual, message) UNITY_TEST_ASSERT_DOUBLE_IS_NEG_INF((actual), __LINE__, (message)) +#define TEST_ASSERT_DOUBLE_IS_NAN_MESSAGE(actual, message) UNITY_TEST_ASSERT_DOUBLE_IS_NAN((actual), __LINE__, (message)) +#define TEST_ASSERT_DOUBLE_IS_DETERMINATE_MESSAGE(actual, message) UNITY_TEST_ASSERT_DOUBLE_IS_DETERMINATE((actual), __LINE__, (message)) +#define TEST_ASSERT_DOUBLE_IS_NOT_INF_MESSAGE(actual, message) UNITY_TEST_ASSERT_DOUBLE_IS_NOT_INF((actual), __LINE__, (message)) +#define TEST_ASSERT_DOUBLE_IS_NOT_NEG_INF_MESSAGE(actual, message) UNITY_TEST_ASSERT_DOUBLE_IS_NOT_NEG_INF((actual), __LINE__, (message)) +#define TEST_ASSERT_DOUBLE_IS_NOT_NAN_MESSAGE(actual, message) UNITY_TEST_ASSERT_DOUBLE_IS_NOT_NAN((actual), __LINE__, (message)) +#define TEST_ASSERT_DOUBLE_IS_NOT_DETERMINATE_MESSAGE(actual, message) UNITY_TEST_ASSERT_DOUBLE_IS_NOT_DETERMINATE((actual), __LINE__, (message)) + +/* end of UNITY_FRAMEWORK_H */ +#ifdef __cplusplus +} +#endif +#endif diff --git a/tools/unit-test-app/components/unity/include/unity_config.h b/tools/unit-test-app/components/unity/include/unity_config.h new file mode 100644 index 0000000000..b8e56a79c1 --- /dev/null +++ b/tools/unit-test-app/components/unity/include/unity_config.h @@ -0,0 +1,75 @@ +#ifndef UNITY_CONFIG_H +#define UNITY_CONFIG_H + +// This file gets included from unity.h via unity_internals.h +// It is inside #ifdef __cplusplus / extern "C" block, so we can +// only use C features here + +// Adapt Unity to our environment, disable FP support + +#include + +#define UNITY_EXCLUDE_FLOAT +#define UNITY_EXCLUDE_DOUBLE + +#define UNITY_OUTPUT_CHAR unity_putc +#define UNITY_OUTPUT_FLUSH unity_flush + +// Define helpers to register test cases from multiple files + +#define UNITY_EXPAND2(a, b) a ## b +#define UNITY_EXPAND(a, b) UNITY_EXPAND2(a, b) +#define UNITY_TEST_UID(what) UNITY_EXPAND(what, __LINE__) + +#define UNITY_TEST_REG_HELPER reg_helper ## UNITY_TEST_UID +#define UNITY_TEST_DESC_UID desc ## UNITY_TEST_UID +struct test_desc_t +{ + const char* name; + const char* desc; + void (*fn)(void); + const char* file; + int line; + struct test_desc_t* next; +}; + +void unity_testcase_register(struct test_desc_t* desc); + +void unity_run_menu(); + +void unity_run_tests_with_filter(const char* filter); + +void unity_run_all_tests(); + +/* Test case macro, a-la CATCH framework. + First argument is a free-form description, + second argument is (by convention) a list of identifiers, each one in square brackets. + Identifiers are used to group related tests, or tests with specific properties. + Use like: + + TEST_CASE("Frobnicator forbnicates", "[frobnicator][rom]") + { + // test goes here + } +*/ +#define TEST_CASE(name_, desc_) \ + static void UNITY_TEST_UID(test_func_) (void); \ + static void __attribute__((constructor)) UNITY_TEST_UID(test_reg_helper_) () \ + { \ + static struct test_desc_t UNITY_TEST_UID(test_desc_) = { \ + .name = name_, \ + .desc = desc_, \ + .fn = &UNITY_TEST_UID(test_func_), \ + .file = __FILE__, \ + .line = __LINE__ \ + }; \ + unity_testcase_register( & UNITY_TEST_UID(test_desc_) ); \ + }\ + static void UNITY_TEST_UID(test_func_) (void) + +// shorthand to check esp_err_t return code +#define TEST_ESP_OK(rc) TEST_ASSERT_EQUAL_INT32(ESP_OK, rc) +#define TEST_ESP_ERR(err, rc) TEST_ASSERT_EQUAL_INT32(err, rc) + + +#endif //UNITY_CONFIG_H diff --git a/tools/unit-test-app/components/unity/include/unity_internals.h b/tools/unit-test-app/components/unity/include/unity_internals.h new file mode 100644 index 0000000000..03d196f4f6 --- /dev/null +++ b/tools/unit-test-app/components/unity/include/unity_internals.h @@ -0,0 +1,772 @@ +/* ========================================== + Unity Project - A Test Framework for C + Copyright (c) 2007-14 Mike Karlesky, Mark VanderVoord, Greg Williams + [Released under MIT License. Please refer to license.txt for details] +========================================== */ + +#ifndef UNITY_INTERNALS_H +#define UNITY_INTERNALS_H + +#ifdef UNITY_INCLUDE_CONFIG_H +#include "unity_config.h" +#endif + +#include + +/* Unity Attempts to Auto-Detect Integer Types + * Attempt 1: UINT_MAX, ULONG_MAX, etc in + * Attempt 2: UINT_MAX, ULONG_MAX, etc in + * Attempt 3: Deduced from sizeof() macros */ +#ifndef UNITY_EXCLUDE_STDINT_H +#include +#endif + +#ifndef UNITY_EXCLUDE_LIMITS_H +#include +#endif + +#ifndef UNITY_EXCLUDE_SIZEOF +#ifndef UINT_MAX +#define UINT_MAX (sizeof(unsigned int) * 256 - 1) +#endif +#ifndef ULONG_MAX +#define ULONG_MAX (sizeof(unsigned long) * 256 - 1) +#endif +#ifndef UINTPTR_MAX +/* apparently this is not a constant expression: (sizeof(unsigned int *) * 256 - 1) so we have to just let this fall through */ +#endif +#endif + +#ifndef UNITY_EXCLUDE_MATH_H +#include +#endif + +/*------------------------------------------------------- + * Guess Widths If Not Specified + *-------------------------------------------------------*/ + +/* Determine the size of an int, if not already specificied. + * We cannot use sizeof(int), because it is not yet defined + * at this stage in the trnslation of the C program. + * Therefore, infer it from UINT_MAX if possible. */ +#ifndef UNITY_INT_WIDTH + #ifdef UINT_MAX + #if (UINT_MAX == 0xFFFF) + #define UNITY_INT_WIDTH (16) + #elif (UINT_MAX == 0xFFFFFFFF) + #define UNITY_INT_WIDTH (32) + #elif (UINT_MAX == 0xFFFFFFFFFFFFFFFF) + #define UNITY_INT_WIDTH (64) + #endif + #endif +#endif +#ifndef UNITY_INT_WIDTH + #define UNITY_INT_WIDTH (32) +#endif + +/* Determine the size of a long, if not already specified, + * by following the process used above to define + * UNITY_INT_WIDTH. */ +#ifndef UNITY_LONG_WIDTH + #ifdef ULONG_MAX + #if (ULONG_MAX == 0xFFFF) + #define UNITY_LONG_WIDTH (16) + #elif (ULONG_MAX == 0xFFFFFFFF) + #define UNITY_LONG_WIDTH (32) + #elif (ULONG_MAX == 0xFFFFFFFFFFFFFFFF) + #define UNITY_LONG_WIDTH (64) + #endif + #endif +#endif +#ifndef UNITY_LONG_WIDTH + #define UNITY_LONG_WIDTH (32) +#endif + +/* Determine the size of a pointer, if not already specified, + * by following the process used above to define + * UNITY_INT_WIDTH. */ +#ifndef UNITY_POINTER_WIDTH + #ifdef UINTPTR_MAX + #if (UINTPTR_MAX+0 <= 0xFFFF) + #define UNITY_POINTER_WIDTH (16) + #elif (UINTPTR_MAX+0 <= 0xFFFFFFFF) + #define UNITY_POINTER_WIDTH (32) + #elif (UINTPTR_MAX+0 <= 0xFFFFFFFFFFFFFFFF) + #define UNITY_POINTER_WIDTH (64) + #endif + #endif +#endif +#ifndef UNITY_POINTER_WIDTH + #ifdef INTPTR_MAX + #if (INTPTR_MAX+0 <= 0x7FFF) + #define UNITY_POINTER_WIDTH (16) + #elif (INTPTR_MAX+0 <= 0x7FFFFFFF) + #define UNITY_POINTER_WIDTH (32) + #elif (INTPTR_MAX+0 <= 0x7FFFFFFFFFFFFFFF) + #define UNITY_POINTER_WIDTH (64) + #endif + #endif +#endif +#ifndef UNITY_POINTER_WIDTH + #define UNITY_POINTER_WIDTH UNITY_LONG_WIDTH +#endif + +/*------------------------------------------------------- + * Int Support (Define types based on detected sizes) + *-------------------------------------------------------*/ + +#if (UNITY_INT_WIDTH == 32) + typedef unsigned char _UU8; + typedef unsigned short _UU16; + typedef unsigned int _UU32; + typedef signed char _US8; + typedef signed short _US16; + typedef signed int _US32; +#elif (UNITY_INT_WIDTH == 16) + typedef unsigned char _UU8; + typedef unsigned int _UU16; + typedef unsigned long _UU32; + typedef signed char _US8; + typedef signed int _US16; + typedef signed long _US32; +#else + #error Invalid UNITY_INT_WIDTH specified! (16 or 32 are supported) +#endif + +/*------------------------------------------------------- + * 64-bit Support + *-------------------------------------------------------*/ + +#ifndef UNITY_SUPPORT_64 +#if UNITY_LONG_WIDTH > 32 +#define UNITY_SUPPORT_64 +#endif +#endif +#ifndef UNITY_SUPPORT_64 +#if UNITY_POINTER_WIDTH > 32 +#define UNITY_SUPPORT_64 +#endif +#endif + +#ifndef UNITY_SUPPORT_64 + +/* No 64-bit Support */ +typedef _UU32 _U_UINT; +typedef _US32 _U_SINT; + +#else + +/* 64-bit Support */ +#if (UNITY_LONG_WIDTH == 32) + typedef unsigned long long _UU64; + typedef signed long long _US64; +#elif (UNITY_LONG_WIDTH == 64) + typedef unsigned long _UU64; + typedef signed long _US64; +#else + #error Invalid UNITY_LONG_WIDTH specified! (32 or 64 are supported) +#endif +typedef _UU64 _U_UINT; +typedef _US64 _U_SINT; + +#endif + +/*------------------------------------------------------- + * Pointer Support + *-------------------------------------------------------*/ + +#if (UNITY_POINTER_WIDTH == 32) + typedef _UU32 _UP; +#define UNITY_DISPLAY_STYLE_POINTER UNITY_DISPLAY_STYLE_HEX32 +#elif (UNITY_POINTER_WIDTH == 64) + typedef _UU64 _UP; +#define UNITY_DISPLAY_STYLE_POINTER UNITY_DISPLAY_STYLE_HEX64 +#elif (UNITY_POINTER_WIDTH == 16) + typedef _UU16 _UP; +#define UNITY_DISPLAY_STYLE_POINTER UNITY_DISPLAY_STYLE_HEX16 +#else + #error Invalid UNITY_POINTER_WIDTH specified! (16, 32 or 64 are supported) +#endif + +#ifndef UNITY_PTR_ATTRIBUTE +#define UNITY_PTR_ATTRIBUTE +#endif + +#ifndef UNITY_INTERNAL_PTR +#define UNITY_INTERNAL_PTR UNITY_PTR_ATTRIBUTE const void* +/* #define UNITY_INTERNAL_PTR UNITY_PTR_ATTRIBUTE const _UU8* */ +#endif + +/*------------------------------------------------------- + * Float Support + *-------------------------------------------------------*/ + +#ifdef UNITY_EXCLUDE_FLOAT + +/* No Floating Point Support */ +#undef UNITY_INCLUDE_FLOAT +#undef UNITY_FLOAT_PRECISION +#undef UNITY_FLOAT_TYPE +#undef UNITY_FLOAT_VERBOSE + +#else + +#ifndef UNITY_INCLUDE_FLOAT +#define UNITY_INCLUDE_FLOAT +#endif + +/* Floating Point Support */ +#ifndef UNITY_FLOAT_PRECISION +#define UNITY_FLOAT_PRECISION (0.00001f) +#endif +#ifndef UNITY_FLOAT_TYPE +#define UNITY_FLOAT_TYPE float +#endif +typedef UNITY_FLOAT_TYPE _UF; + +#ifndef isinf +#define isinf(n) (((1.0f / f_zero) == n) ? 1 : 0) || (((-1.0f / f_zero) == n) ? 1 : 0) +#define UNITY_FLOAT_NEEDS_ZERO +#endif + +#ifndef isnan +#define isnan(n) ((n != n) ? 1 : 0) +#endif + +#ifndef isneg +#define isneg(n) ((n < 0.0f) ? 1 : 0) +#endif + +#ifndef ispos +#define ispos(n) ((n > 0.0f) ? 1 : 0) +#endif + +#endif + +/*------------------------------------------------------- + * Double Float Support + *-------------------------------------------------------*/ + +/* unlike FLOAT, we DON'T include by default */ +#ifndef UNITY_EXCLUDE_DOUBLE +#ifndef UNITY_INCLUDE_DOUBLE +#define UNITY_EXCLUDE_DOUBLE +#endif +#endif + +#ifdef UNITY_EXCLUDE_DOUBLE + +/* No Floating Point Support */ +#undef UNITY_DOUBLE_PRECISION +#undef UNITY_DOUBLE_TYPE +#undef UNITY_DOUBLE_VERBOSE + +#ifdef UNITY_INCLUDE_DOUBLE +#undef UNITY_INCLUDE_DOUBLE +#endif + +#else + +/* Double Floating Point Support */ +#ifndef UNITY_DOUBLE_PRECISION +#define UNITY_DOUBLE_PRECISION (1e-12f) +#endif +#ifndef UNITY_DOUBLE_TYPE +#define UNITY_DOUBLE_TYPE double +#endif +typedef UNITY_DOUBLE_TYPE _UD; + +#endif + +#ifdef UNITY_DOUBLE_VERBOSE +#ifndef UNITY_FLOAT_VERBOSE +#define UNITY_FLOAT_VERBOSE +#endif +#endif + +/*------------------------------------------------------- + * Output Method: stdout (DEFAULT) + *-------------------------------------------------------*/ +#ifndef UNITY_OUTPUT_CHAR +/* Default to using putchar, which is defined in stdio.h */ +#include +#define UNITY_OUTPUT_CHAR(a) (void)putchar(a) +#else + /* If defined as something else, make sure we declare it here so it's ready for use */ + #ifndef UNITY_OMIT_OUTPUT_CHAR_HEADER_DECLARATION +extern void UNITY_OUTPUT_CHAR(int); + #endif +#endif + +#ifndef UNITY_OUTPUT_FLUSH +/* Default to using putchar, which is defined in stdio.h */ +#include +#define UNITY_OUTPUT_FLUSH() (void)fflush(stdout) +#else + /* If defined as something else, make sure we declare it here so it's ready for use */ + #ifndef UNITY_OMIT_OUTPUT_FLUSH_HEADER_DECLARATION +extern void UNITY_OUTPUT_FLUSH(void); + #endif +#endif + +#ifndef UNITY_PRINT_EOL +#define UNITY_PRINT_EOL() UNITY_OUTPUT_CHAR('\n') +#endif + +#ifndef UNITY_OUTPUT_START +#define UNITY_OUTPUT_START() +#endif + +#ifndef UNITY_OUTPUT_COMPLETE +#define UNITY_OUTPUT_COMPLETE() +#endif + +/*------------------------------------------------------- + * Footprint + *-------------------------------------------------------*/ + +#ifndef UNITY_LINE_TYPE +#define UNITY_LINE_TYPE _U_UINT +#endif + +#ifndef UNITY_COUNTER_TYPE +#define UNITY_COUNTER_TYPE _U_UINT +#endif + +/*------------------------------------------------------- + * Language Features Available + *-------------------------------------------------------*/ +#if !defined(UNITY_WEAK_ATTRIBUTE) && !defined(UNITY_WEAK_PRAGMA) +# ifdef __GNUC__ /* includes clang */ +# if !(defined(__WIN32__) && defined(__clang__)) +# define UNITY_WEAK_ATTRIBUTE __attribute__((weak)) +# endif +# endif +#endif + +#ifdef UNITY_NO_WEAK +# undef UNITY_WEAK_ATTRIBUTE +# undef UNITY_WEAK_PRAGMA +#endif + + +/*------------------------------------------------------- + * Internal Structs Needed + *-------------------------------------------------------*/ + +typedef void (*UnityTestFunction)(void); + +#define UNITY_DISPLAY_RANGE_INT (0x10) +#define UNITY_DISPLAY_RANGE_UINT (0x20) +#define UNITY_DISPLAY_RANGE_HEX (0x40) +#define UNITY_DISPLAY_RANGE_AUTO (0x80) + +typedef enum +{ +#if (UNITY_INT_WIDTH == 16) + UNITY_DISPLAY_STYLE_INT = 2 + UNITY_DISPLAY_RANGE_INT + UNITY_DISPLAY_RANGE_AUTO, +#elif (UNITY_INT_WIDTH == 32) + UNITY_DISPLAY_STYLE_INT = 4 + UNITY_DISPLAY_RANGE_INT + UNITY_DISPLAY_RANGE_AUTO, +#elif (UNITY_INT_WIDTH == 64) + UNITY_DISPLAY_STYLE_INT = 8 + UNITY_DISPLAY_RANGE_INT + UNITY_DISPLAY_RANGE_AUTO, +#endif + UNITY_DISPLAY_STYLE_INT8 = 1 + UNITY_DISPLAY_RANGE_INT, + UNITY_DISPLAY_STYLE_INT16 = 2 + UNITY_DISPLAY_RANGE_INT, + UNITY_DISPLAY_STYLE_INT32 = 4 + UNITY_DISPLAY_RANGE_INT, +#ifdef UNITY_SUPPORT_64 + UNITY_DISPLAY_STYLE_INT64 = 8 + UNITY_DISPLAY_RANGE_INT, +#endif + +#if (UNITY_INT_WIDTH == 16) + UNITY_DISPLAY_STYLE_UINT = 2 + UNITY_DISPLAY_RANGE_UINT + UNITY_DISPLAY_RANGE_AUTO, +#elif (UNITY_INT_WIDTH == 32) + UNITY_DISPLAY_STYLE_UINT = 4 + UNITY_DISPLAY_RANGE_UINT + UNITY_DISPLAY_RANGE_AUTO, +#elif (UNITY_INT_WIDTH == 64) + UNITY_DISPLAY_STYLE_UINT = 8 + UNITY_DISPLAY_RANGE_UINT + UNITY_DISPLAY_RANGE_AUTO, +#endif + UNITY_DISPLAY_STYLE_UINT8 = 1 + UNITY_DISPLAY_RANGE_UINT, + UNITY_DISPLAY_STYLE_UINT16 = 2 + UNITY_DISPLAY_RANGE_UINT, + UNITY_DISPLAY_STYLE_UINT32 = 4 + UNITY_DISPLAY_RANGE_UINT, +#ifdef UNITY_SUPPORT_64 + UNITY_DISPLAY_STYLE_UINT64 = 8 + UNITY_DISPLAY_RANGE_UINT, +#endif + UNITY_DISPLAY_STYLE_HEX8 = 1 + UNITY_DISPLAY_RANGE_HEX, + UNITY_DISPLAY_STYLE_HEX16 = 2 + UNITY_DISPLAY_RANGE_HEX, + UNITY_DISPLAY_STYLE_HEX32 = 4 + UNITY_DISPLAY_RANGE_HEX, +#ifdef UNITY_SUPPORT_64 + UNITY_DISPLAY_STYLE_HEX64 = 8 + UNITY_DISPLAY_RANGE_HEX, +#endif + UNITY_DISPLAY_STYLE_UNKNOWN +} UNITY_DISPLAY_STYLE_T; + +#ifndef UNITY_EXCLUDE_FLOAT +typedef enum _UNITY_FLOAT_TRAIT_T +{ + UNITY_FLOAT_IS_NOT_INF = 0, + UNITY_FLOAT_IS_INF, + UNITY_FLOAT_IS_NOT_NEG_INF, + UNITY_FLOAT_IS_NEG_INF, + UNITY_FLOAT_IS_NOT_NAN, + UNITY_FLOAT_IS_NAN, + UNITY_FLOAT_IS_NOT_DET, + UNITY_FLOAT_IS_DET, + UNITY_FLOAT_INVALID_TRAIT +} UNITY_FLOAT_TRAIT_T; +#endif + +struct _Unity +{ + const char* TestFile; + const char* CurrentTestName; +#ifndef UNITY_EXCLUDE_DETAILS + const char* CurrentDetail1; + const char* CurrentDetail2; +#endif + UNITY_LINE_TYPE CurrentTestLineNumber; + UNITY_COUNTER_TYPE NumberOfTests; + UNITY_COUNTER_TYPE TestFailures; + UNITY_COUNTER_TYPE TestIgnores; + UNITY_COUNTER_TYPE CurrentTestFailed; + UNITY_COUNTER_TYPE CurrentTestIgnored; + jmp_buf AbortFrame; +}; + +extern struct _Unity Unity; + +/*------------------------------------------------------- + * Test Suite Management + *-------------------------------------------------------*/ + +void UnityBegin(const char* filename); +int UnityEnd(void); +void UnityConcludeTest(void); +void UnityDefaultTestRun(UnityTestFunction Func, const char* FuncName, const int FuncLineNum); + +/*------------------------------------------------------- + * Details Support + *-------------------------------------------------------*/ + +#ifdef UNITY_EXCLUDE_DETAILS +#define UNITY_CLR_DETAILS() +#define UNITY_SET_DETAIL(d1) +#define UNITY_SET_DETAILS(d1,d2) +#else +#define UNITY_CLR_DETAILS() { Unity.CurrentDetail1 = 0; Unity.CurrentDetail2 = 0; } +#define UNITY_SET_DETAIL(d1) { Unity.CurrentDetail1 = d1; Unity.CurrentDetail2 = 0; } +#define UNITY_SET_DETAILS(d1,d2) { Unity.CurrentDetail1 = d1; Unity.CurrentDetail2 = d2; } + +#ifndef UNITY_DETAIL1_NAME +#define UNITY_DETAIL1_NAME "Function" +#endif + +#ifndef UNITY_DETAIL2_NAME +#define UNITY_DETAIL2_NAME "Argument" +#endif +#endif + +/*------------------------------------------------------- + * Test Output + *-------------------------------------------------------*/ + +void UnityPrint(const char* string); +void UnityPrintMask(const _U_UINT mask, const _U_UINT number); +void UnityPrintNumberByStyle(const _U_SINT number, const UNITY_DISPLAY_STYLE_T style); +void UnityPrintNumber(const _U_SINT number); +void UnityPrintNumberUnsigned(const _U_UINT number); +void UnityPrintNumberHex(const _U_UINT number, const char nibbles); + +#ifdef UNITY_FLOAT_VERBOSE +void UnityPrintFloat(const _UF number); +#endif + +/*------------------------------------------------------- + * Test Assertion Fuctions + *------------------------------------------------------- + * Use the macros below this section instead of calling + * these directly. The macros have a consistent naming + * convention and will pull in file and line information + * for you. */ + +void UnityAssertEqualNumber(const _U_SINT expected, + const _U_SINT actual, + const char* msg, + const UNITY_LINE_TYPE lineNumber, + const UNITY_DISPLAY_STYLE_T style); + +void UnityAssertEqualIntArray(UNITY_INTERNAL_PTR expected, + UNITY_INTERNAL_PTR actual, + const _UU32 num_elements, + const char* msg, + const UNITY_LINE_TYPE lineNumber, + const UNITY_DISPLAY_STYLE_T style); + +void UnityAssertBits(const _U_SINT mask, + const _U_SINT expected, + const _U_SINT actual, + const char* msg, + const UNITY_LINE_TYPE lineNumber); + +void UnityAssertEqualString(const char* expected, + const char* actual, + const char* msg, + const UNITY_LINE_TYPE lineNumber); + +void UnityAssertEqualStringLen(const char* expected, + const char* actual, + const _UU32 length, + const char* msg, + const UNITY_LINE_TYPE lineNumber); + +void UnityAssertEqualStringArray( const char** expected, + const char** actual, + const _UU32 num_elements, + const char* msg, + const UNITY_LINE_TYPE lineNumber); + +void UnityAssertEqualMemory( UNITY_INTERNAL_PTR expected, + UNITY_INTERNAL_PTR actual, + const _UU32 length, + const _UU32 num_elements, + const char* msg, + const UNITY_LINE_TYPE lineNumber); + +void UnityAssertNumbersWithin(const _U_UINT delta, + const _U_SINT expected, + const _U_SINT actual, + const char* msg, + const UNITY_LINE_TYPE lineNumber, + const UNITY_DISPLAY_STYLE_T style); + +void UnityFail(const char* message, const UNITY_LINE_TYPE line); + +void UnityIgnore(const char* message, const UNITY_LINE_TYPE line); + +#ifndef UNITY_EXCLUDE_FLOAT +void UnityAssertFloatsWithin(const _UF delta, + const _UF expected, + const _UF actual, + const char* msg, + const UNITY_LINE_TYPE lineNumber); + +void UnityAssertEqualFloatArray(UNITY_PTR_ATTRIBUTE const _UF* expected, + UNITY_PTR_ATTRIBUTE const _UF* actual, + const _UU32 num_elements, + const char* msg, + const UNITY_LINE_TYPE lineNumber); + +void UnityAssertFloatSpecial(const _UF actual, + const char* msg, + const UNITY_LINE_TYPE lineNumber, + const UNITY_FLOAT_TRAIT_T style); +#endif + +#ifndef UNITY_EXCLUDE_DOUBLE +void UnityAssertDoublesWithin(const _UD delta, + const _UD expected, + const _UD actual, + const char* msg, + const UNITY_LINE_TYPE lineNumber); + +void UnityAssertEqualDoubleArray(UNITY_PTR_ATTRIBUTE const _UD* expected, + UNITY_PTR_ATTRIBUTE const _UD* actual, + const _UU32 num_elements, + const char* msg, + const UNITY_LINE_TYPE lineNumber); + +void UnityAssertDoubleSpecial(const _UD actual, + const char* msg, + const UNITY_LINE_TYPE lineNumber, + const UNITY_FLOAT_TRAIT_T style); +#endif + +/*------------------------------------------------------- + * Error Strings We Might Need + *-------------------------------------------------------*/ + +extern const char UnityStrErrFloat[]; +extern const char UnityStrErrDouble[]; +extern const char UnityStrErr64[]; + +/*------------------------------------------------------- + * Test Running Macros + *-------------------------------------------------------*/ + +#define TEST_PROTECT() (setjmp(Unity.AbortFrame) == 0) + +#define TEST_ABORT() {longjmp(Unity.AbortFrame, 1);} + +/* This tricky series of macros gives us an optional line argument to treat it as RUN_TEST(func, num=__LINE__) */ +#ifndef RUN_TEST +#ifdef __STDC_VERSION__ +#if __STDC_VERSION__ >= 199901L +#define RUN_TEST(...) UnityDefaultTestRun(RUN_TEST_FIRST(__VA_ARGS__), RUN_TEST_SECOND(__VA_ARGS__)) +#define RUN_TEST_FIRST(...) RUN_TEST_FIRST_HELPER(__VA_ARGS__, throwaway) +#define RUN_TEST_FIRST_HELPER(first, ...) (first), #first +#define RUN_TEST_SECOND(...) RUN_TEST_SECOND_HELPER(__VA_ARGS__, __LINE__, throwaway) +#define RUN_TEST_SECOND_HELPER(first, second, ...) (second) +#endif +#endif +#endif + +/* If we can't do the tricky version, we'll just have to require them to always include the line number */ +#ifndef RUN_TEST +#ifdef CMOCK +#define RUN_TEST(func, num) UnityDefaultTestRun(func, #func, num) +#else +#define RUN_TEST(func) UnityDefaultTestRun(func, #func, __LINE__) +#endif +#endif + +#define TEST_LINE_NUM (Unity.CurrentTestLineNumber) +#define TEST_IS_IGNORED (Unity.CurrentTestIgnored) +#define UNITY_NEW_TEST(a) \ + Unity.CurrentTestName = (a); \ + Unity.CurrentTestLineNumber = (UNITY_LINE_TYPE)(__LINE__); \ + Unity.NumberOfTests++; + +#ifndef UNITY_BEGIN +#define UNITY_BEGIN() UnityBegin(__FILE__) +#endif + +#ifndef UNITY_END +#define UNITY_END() UnityEnd() +#endif + +#define UNITY_UNUSED(x) (void)(sizeof(x)) + +/*------------------------------------------------------- + * Basic Fail and Ignore + *-------------------------------------------------------*/ + +#define UNITY_TEST_FAIL(line, message) UnityFail( (message), (UNITY_LINE_TYPE)(line)) +#define UNITY_TEST_IGNORE(line, message) UnityIgnore( (message), (UNITY_LINE_TYPE)(line)) + +/*------------------------------------------------------- + * Test Asserts + *-------------------------------------------------------*/ + +#define UNITY_TEST_ASSERT(condition, line, message) if (condition) {} else {UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), (message));} +#define UNITY_TEST_ASSERT_NULL(pointer, line, message) UNITY_TEST_ASSERT(((pointer) == NULL), (UNITY_LINE_TYPE)(line), (message)) +#define UNITY_TEST_ASSERT_NOT_NULL(pointer, line, message) UNITY_TEST_ASSERT(((pointer) != NULL), (UNITY_LINE_TYPE)(line), (message)) + +#define UNITY_TEST_ASSERT_EQUAL_INT(expected, actual, line, message) UnityAssertEqualNumber((_U_SINT)(expected), (_U_SINT)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT) +#define UNITY_TEST_ASSERT_EQUAL_INT8(expected, actual, line, message) UnityAssertEqualNumber((_U_SINT)(_US8 )(expected), (_U_SINT)(_US8 )(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT8) +#define UNITY_TEST_ASSERT_EQUAL_INT16(expected, actual, line, message) UnityAssertEqualNumber((_U_SINT)(_US16)(expected), (_U_SINT)(_US16)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT16) +#define UNITY_TEST_ASSERT_EQUAL_INT32(expected, actual, line, message) UnityAssertEqualNumber((_U_SINT)(_US32)(expected), (_U_SINT)(_US32)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT32) +#define UNITY_TEST_ASSERT_EQUAL_UINT(expected, actual, line, message) UnityAssertEqualNumber((_U_SINT)(expected), (_U_SINT)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT) +#define UNITY_TEST_ASSERT_EQUAL_UINT8(expected, actual, line, message) UnityAssertEqualNumber((_U_SINT)(_UU8 )(expected), (_U_SINT)(_UU8 )(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT8) +#define UNITY_TEST_ASSERT_EQUAL_UINT16(expected, actual, line, message) UnityAssertEqualNumber((_U_SINT)(_UU16)(expected), (_U_SINT)(_UU16)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT16) +#define UNITY_TEST_ASSERT_EQUAL_UINT32(expected, actual, line, message) UnityAssertEqualNumber((_U_SINT)(_UU32)(expected), (_U_SINT)(_UU32)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT32) +#define UNITY_TEST_ASSERT_EQUAL_HEX8(expected, actual, line, message) UnityAssertEqualNumber((_U_SINT)(_US8 )(expected), (_U_SINT)(_US8 )(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX8) +#define UNITY_TEST_ASSERT_EQUAL_HEX16(expected, actual, line, message) UnityAssertEqualNumber((_U_SINT)(_US16)(expected), (_U_SINT)(_US16)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX16) +#define UNITY_TEST_ASSERT_EQUAL_HEX32(expected, actual, line, message) UnityAssertEqualNumber((_U_SINT)(_US32)(expected), (_U_SINT)(_US32)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX32) +#define UNITY_TEST_ASSERT_BITS(mask, expected, actual, line, message) UnityAssertBits((_U_SINT)(mask), (_U_SINT)(expected), (_U_SINT)(actual), (message), (UNITY_LINE_TYPE)(line)) + +#define UNITY_TEST_ASSERT_INT_WITHIN(delta, expected, actual, line, message) UnityAssertNumbersWithin((delta), (_U_SINT)(expected), (_U_SINT)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT) +#define UNITY_TEST_ASSERT_INT8_WITHIN(delta, expected, actual, line, message) UnityAssertNumbersWithin((_UU8 )(delta), (_U_SINT)(_US8 )(expected), (_U_SINT)(_US8 )(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT8) +#define UNITY_TEST_ASSERT_INT16_WITHIN(delta, expected, actual, line, message) UnityAssertNumbersWithin((_UU16)(delta), (_U_SINT)(_US16)(expected), (_U_SINT)(_US16)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT16) +#define UNITY_TEST_ASSERT_INT32_WITHIN(delta, expected, actual, line, message) UnityAssertNumbersWithin((_UU32)(delta), (_U_SINT)(_US32)(expected), (_U_SINT)(_US32)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT32) +#define UNITY_TEST_ASSERT_UINT_WITHIN(delta, expected, actual, line, message) UnityAssertNumbersWithin((delta), (_U_SINT)(expected), (_U_SINT)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT) +#define UNITY_TEST_ASSERT_UINT8_WITHIN(delta, expected, actual, line, message) UnityAssertNumbersWithin((_UU8 )(delta), (_U_SINT)(_U_UINT)(_UU8 )(expected), (_U_SINT)(_U_UINT)(_UU8 )(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT8) +#define UNITY_TEST_ASSERT_UINT16_WITHIN(delta, expected, actual, line, message) UnityAssertNumbersWithin((_UU16)(delta), (_U_SINT)(_U_UINT)(_UU16)(expected), (_U_SINT)(_U_UINT)(_UU16)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT16) +#define UNITY_TEST_ASSERT_UINT32_WITHIN(delta, expected, actual, line, message) UnityAssertNumbersWithin((_UU32)(delta), (_U_SINT)(_U_UINT)(_UU32)(expected), (_U_SINT)(_U_UINT)(_UU32)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT32) +#define UNITY_TEST_ASSERT_HEX8_WITHIN(delta, expected, actual, line, message) UnityAssertNumbersWithin((_UU8 )(delta), (_U_SINT)(_U_UINT)(_UU8 )(expected), (_U_SINT)(_U_UINT)(_UU8 )(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX8) +#define UNITY_TEST_ASSERT_HEX16_WITHIN(delta, expected, actual, line, message) UnityAssertNumbersWithin((_UU16)(delta), (_U_SINT)(_U_UINT)(_UU16)(expected), (_U_SINT)(_U_UINT)(_UU16)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX16) +#define UNITY_TEST_ASSERT_HEX32_WITHIN(delta, expected, actual, line, message) UnityAssertNumbersWithin((_UU32)(delta), (_U_SINT)(_U_UINT)(_UU32)(expected), (_U_SINT)(_U_UINT)(_UU32)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX32) + +#define UNITY_TEST_ASSERT_EQUAL_PTR(expected, actual, line, message) UnityAssertEqualNumber((_U_SINT)(_UP)(expected), (_U_SINT)(_UP)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_POINTER) +#define UNITY_TEST_ASSERT_EQUAL_STRING(expected, actual, line, message) UnityAssertEqualString((const char*)(expected), (const char*)(actual), (message), (UNITY_LINE_TYPE)(line)) +#define UNITY_TEST_ASSERT_EQUAL_STRING_LEN(expected, actual, len, line, message) UnityAssertEqualStringLen((const char*)(expected), (const char*)(actual), (_UU32)(len), (message), (UNITY_LINE_TYPE)(line)) +#define UNITY_TEST_ASSERT_EQUAL_MEMORY(expected, actual, len, line, message) UnityAssertEqualMemory((UNITY_INTERNAL_PTR)(expected), (UNITY_INTERNAL_PTR)(actual), (_UU32)(len), 1, (message), (UNITY_LINE_TYPE)(line)) + +#define UNITY_TEST_ASSERT_EQUAL_INT_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualIntArray((UNITY_INTERNAL_PTR)(expected), (UNITY_INTERNAL_PTR)(actual), (_UU32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT) +#define UNITY_TEST_ASSERT_EQUAL_INT8_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualIntArray((UNITY_INTERNAL_PTR)(expected), (UNITY_INTERNAL_PTR)(actual), (_UU32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT8) +#define UNITY_TEST_ASSERT_EQUAL_INT16_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualIntArray((UNITY_INTERNAL_PTR)(expected), (UNITY_INTERNAL_PTR)(actual), (_UU32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT16) +#define UNITY_TEST_ASSERT_EQUAL_INT32_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualIntArray((UNITY_INTERNAL_PTR)(expected), (UNITY_INTERNAL_PTR)(actual), (_UU32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT32) +#define UNITY_TEST_ASSERT_EQUAL_UINT_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualIntArray((UNITY_INTERNAL_PTR)(expected), (UNITY_INTERNAL_PTR)(actual), (_UU32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT) +#define UNITY_TEST_ASSERT_EQUAL_UINT8_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualIntArray((UNITY_INTERNAL_PTR)(expected), (UNITY_INTERNAL_PTR)(actual), (_UU32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT8) +#define UNITY_TEST_ASSERT_EQUAL_UINT16_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualIntArray((UNITY_INTERNAL_PTR)(expected), (UNITY_INTERNAL_PTR)(actual), (_UU32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT16) +#define UNITY_TEST_ASSERT_EQUAL_UINT32_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualIntArray((UNITY_INTERNAL_PTR)(expected), (UNITY_INTERNAL_PTR)(actual), (_UU32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT32) +#define UNITY_TEST_ASSERT_EQUAL_HEX8_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualIntArray((UNITY_INTERNAL_PTR)(expected), (UNITY_INTERNAL_PTR)(actual), (_UU32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX8) +#define UNITY_TEST_ASSERT_EQUAL_HEX16_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualIntArray((UNITY_INTERNAL_PTR)(expected), (UNITY_INTERNAL_PTR)(actual), (_UU32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX16) +#define UNITY_TEST_ASSERT_EQUAL_HEX32_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualIntArray((UNITY_INTERNAL_PTR)(expected), (UNITY_INTERNAL_PTR)(actual), (_UU32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX32) +#define UNITY_TEST_ASSERT_EQUAL_PTR_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualIntArray((UNITY_INTERNAL_PTR)(_UP*)(expected), (UNITY_INTERNAL_PTR)(_UP*)(actual), (_UU32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_POINTER) +#define UNITY_TEST_ASSERT_EQUAL_STRING_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualStringArray((const char**)(expected), (const char**)(actual), (_UU32)(num_elements), (message), (UNITY_LINE_TYPE)(line)) +#define UNITY_TEST_ASSERT_EQUAL_MEMORY_ARRAY(expected, actual, len, num_elements, line, message) UnityAssertEqualMemory((UNITY_INTERNAL_PTR)(expected), (UNITY_INTERNAL_PTR)(actual), (_UU32)(len), (_UU32)(num_elements), (message), (UNITY_LINE_TYPE)(line)) + +#ifdef UNITY_SUPPORT_64 +#define UNITY_TEST_ASSERT_EQUAL_INT64(expected, actual, line, message) UnityAssertEqualNumber((_U_SINT)(expected), (_U_SINT)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT64) +#define UNITY_TEST_ASSERT_EQUAL_UINT64(expected, actual, line, message) UnityAssertEqualNumber((_U_SINT)(expected), (_U_SINT)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT64) +#define UNITY_TEST_ASSERT_EQUAL_HEX64(expected, actual, line, message) UnityAssertEqualNumber((_U_SINT)(expected), (_U_SINT)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX64) +#define UNITY_TEST_ASSERT_EQUAL_INT64_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualIntArray((UNITY_INTERNAL_PTR)(expected), (UNITY_INTERNAL_PTR)(actual), (_UU32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT64) +#define UNITY_TEST_ASSERT_EQUAL_UINT64_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualIntArray((UNITY_INTERNAL_PTR)(expected), (UNITY_INTERNAL_PTR)(actual), (_UU32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT64) +#define UNITY_TEST_ASSERT_EQUAL_HEX64_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualIntArray((UNITY_INTERNAL_PTR)(expected), (UNITY_INTERNAL_PTR)(actual), (_UU32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX64) +#define UNITY_TEST_ASSERT_INT64_WITHIN(delta, expected, actual, line, message) UnityAssertNumbersWithin((delta), (_U_SINT)(expected), (_U_SINT)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT64) +#define UNITY_TEST_ASSERT_UINT64_WITHIN(delta, expected, actual, line, message) UnityAssertNumbersWithin((delta), (_U_SINT)(expected), (_U_SINT)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT64) +#define UNITY_TEST_ASSERT_HEX64_WITHIN(delta, expected, actual, line, message) UnityAssertNumbersWithin((delta), (_U_SINT)(expected), (_U_SINT)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX64) +#else +#define UNITY_TEST_ASSERT_EQUAL_INT64(expected, actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErr64) +#define UNITY_TEST_ASSERT_EQUAL_UINT64(expected, actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErr64) +#define UNITY_TEST_ASSERT_EQUAL_HEX64(expected, actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErr64) +#define UNITY_TEST_ASSERT_EQUAL_INT64_ARRAY(expected, actual, num_elements, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErr64) +#define UNITY_TEST_ASSERT_EQUAL_UINT64_ARRAY(expected, actual, num_elements, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErr64) +#define UNITY_TEST_ASSERT_EQUAL_HEX64_ARRAY(expected, actual, num_elements, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErr64) +#define UNITY_TEST_ASSERT_INT64_WITHIN(delta, expected, actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErr64) +#define UNITY_TEST_ASSERT_UINT64_WITHIN(delta, expected, actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErr64) +#define UNITY_TEST_ASSERT_HEX64_WITHIN(delta, expected, actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErr64) +#endif + +#ifdef UNITY_EXCLUDE_FLOAT +#define UNITY_TEST_ASSERT_FLOAT_WITHIN(delta, expected, actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErrFloat) +#define UNITY_TEST_ASSERT_EQUAL_FLOAT(expected, actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErrFloat) +#define UNITY_TEST_ASSERT_EQUAL_FLOAT_ARRAY(expected, actual, num_elements, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErrFloat) +#define UNITY_TEST_ASSERT_FLOAT_IS_INF(actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErrFloat) +#define UNITY_TEST_ASSERT_FLOAT_IS_NEG_INF(actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErrFloat) +#define UNITY_TEST_ASSERT_FLOAT_IS_NAN(actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErrFloat) +#define UNITY_TEST_ASSERT_FLOAT_IS_DETERMINATE(actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErrFloat) +#define UNITY_TEST_ASSERT_FLOAT_IS_NOT_INF(actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErrFloat) +#define UNITY_TEST_ASSERT_FLOAT_IS_NOT_NEG_INF(actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErrFloat) +#define UNITY_TEST_ASSERT_FLOAT_IS_NOT_NAN(actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErrFloat) +#define UNITY_TEST_ASSERT_FLOAT_IS_NOT_DETERMINATE(actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErrFloat) +#else +#define UNITY_TEST_ASSERT_FLOAT_WITHIN(delta, expected, actual, line, message) UnityAssertFloatsWithin((_UF)(delta), (_UF)(expected), (_UF)(actual), (message), (UNITY_LINE_TYPE)(line)) +#define UNITY_TEST_ASSERT_EQUAL_FLOAT(expected, actual, line, message) UNITY_TEST_ASSERT_FLOAT_WITHIN((_UF)(expected) * (_UF)UNITY_FLOAT_PRECISION, (_UF)(expected), (_UF)(actual), (UNITY_LINE_TYPE)(line), (message)) +#define UNITY_TEST_ASSERT_EQUAL_FLOAT_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualFloatArray((_UF*)(expected), (_UF*)(actual), (_UU32)(num_elements), (message), (UNITY_LINE_TYPE)(line)) +#define UNITY_TEST_ASSERT_FLOAT_IS_INF(actual, line, message) UnityAssertFloatSpecial((_UF)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_FLOAT_IS_INF) +#define UNITY_TEST_ASSERT_FLOAT_IS_NEG_INF(actual, line, message) UnityAssertFloatSpecial((_UF)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_FLOAT_IS_NEG_INF) +#define UNITY_TEST_ASSERT_FLOAT_IS_NAN(actual, line, message) UnityAssertFloatSpecial((_UF)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_FLOAT_IS_NAN) +#define UNITY_TEST_ASSERT_FLOAT_IS_DETERMINATE(actual, line, message) UnityAssertFloatSpecial((_UF)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_FLOAT_IS_DET) +#define UNITY_TEST_ASSERT_FLOAT_IS_NOT_INF(actual, line, message) UnityAssertFloatSpecial((_UF)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_FLOAT_IS_NOT_INF) +#define UNITY_TEST_ASSERT_FLOAT_IS_NOT_NEG_INF(actual, line, message) UnityAssertFloatSpecial((_UF)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_FLOAT_IS_NOT_NEG_INF) +#define UNITY_TEST_ASSERT_FLOAT_IS_NOT_NAN(actual, line, message) UnityAssertFloatSpecial((_UF)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_FLOAT_IS_NOT_NAN) +#define UNITY_TEST_ASSERT_FLOAT_IS_NOT_DETERMINATE(actual, line, message) UnityAssertFloatSpecial((_UF)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_FLOAT_IS_NOT_DET) +#endif + +#ifdef UNITY_EXCLUDE_DOUBLE +#define UNITY_TEST_ASSERT_DOUBLE_WITHIN(delta, expected, actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErrDouble) +#define UNITY_TEST_ASSERT_EQUAL_DOUBLE(expected, actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErrDouble) +#define UNITY_TEST_ASSERT_EQUAL_DOUBLE_ARRAY(expected, actual, num_elements, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErrDouble) +#define UNITY_TEST_ASSERT_DOUBLE_IS_INF(actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErrDouble) +#define UNITY_TEST_ASSERT_DOUBLE_IS_NEG_INF(actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErrDouble) +#define UNITY_TEST_ASSERT_DOUBLE_IS_NAN(actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErrDouble) +#define UNITY_TEST_ASSERT_DOUBLE_IS_DETERMINATE(actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErrDouble) +#define UNITY_TEST_ASSERT_DOUBLE_IS_NOT_INF(actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErrDouble) +#define UNITY_TEST_ASSERT_DOUBLE_IS_NOT_NEG_INF(actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErrDouble) +#define UNITY_TEST_ASSERT_DOUBLE_IS_NOT_NAN(actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErrDouble) +#define UNITY_TEST_ASSERT_DOUBLE_IS_NOT_DETERMINATE(actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErrDouble) +#else +#define UNITY_TEST_ASSERT_DOUBLE_WITHIN(delta, expected, actual, line, message) UnityAssertDoublesWithin((_UD)(delta), (_UD)(expected), (_UD)(actual), (message), (UNITY_LINE_TYPE)line) +#define UNITY_TEST_ASSERT_EQUAL_DOUBLE(expected, actual, line, message) UNITY_TEST_ASSERT_DOUBLE_WITHIN((_UD)(expected) * (_UD)UNITY_DOUBLE_PRECISION, (_UD)expected, (_UD)actual, (UNITY_LINE_TYPE)(line), message) +#define UNITY_TEST_ASSERT_EQUAL_DOUBLE_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualDoubleArray((_UD*)(expected), (_UD*)(actual), (_UU32)(num_elements), (message), (UNITY_LINE_TYPE)line) +#define UNITY_TEST_ASSERT_DOUBLE_IS_INF(actual, line, message) UnityAssertDoubleSpecial((_UD)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_FLOAT_IS_INF) +#define UNITY_TEST_ASSERT_DOUBLE_IS_NEG_INF(actual, line, message) UnityAssertDoubleSpecial((_UD)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_FLOAT_IS_NEG_INF) +#define UNITY_TEST_ASSERT_DOUBLE_IS_NAN(actual, line, message) UnityAssertDoubleSpecial((_UD)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_FLOAT_IS_NAN) +#define UNITY_TEST_ASSERT_DOUBLE_IS_DETERMINATE(actual, line, message) UnityAssertDoubleSpecial((_UD)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_FLOAT_IS_DET) +#define UNITY_TEST_ASSERT_DOUBLE_IS_NOT_INF(actual, line, message) UnityAssertDoubleSpecial((_UD)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_FLOAT_IS_NOT_INF) +#define UNITY_TEST_ASSERT_DOUBLE_IS_NOT_NEG_INF(actual, line, message) UnityAssertDoubleSpecial((_UD)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_FLOAT_IS_NOT_NEG_INF) +#define UNITY_TEST_ASSERT_DOUBLE_IS_NOT_NAN(actual, line, message) UnityAssertDoubleSpecial((_UD)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_FLOAT_IS_NOT_NAN) +#define UNITY_TEST_ASSERT_DOUBLE_IS_NOT_DETERMINATE(actual, line, message) UnityAssertDoubleSpecial((_UD)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_FLOAT_IS_NOT_DET) +#endif + +/* End of UNITY_INTERNALS_H */ +#endif diff --git a/tools/unit-test-app/components/unity/license.txt b/tools/unit-test-app/components/unity/license.txt new file mode 100644 index 0000000000..d66fba53e5 --- /dev/null +++ b/tools/unit-test-app/components/unity/license.txt @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2007-14 Mike Karlesky, Mark VanderVoord, Greg Williams + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/tools/unit-test-app/components/unity/unity.c b/tools/unit-test-app/components/unity/unity.c new file mode 100644 index 0000000000..4a99208d8a --- /dev/null +++ b/tools/unit-test-app/components/unity/unity.c @@ -0,0 +1,1306 @@ +/* ========================================================================= + Unity Project - A Test Framework for C + Copyright (c) 2007-14 Mike Karlesky, Mark VanderVoord, Greg Williams + [Released under MIT License. Please refer to license.txt for details] +============================================================================ */ + +#include "unity.h" +#include + +/* If omitted from header, declare overrideable prototypes here so they're ready for use */ +#ifdef UNITY_OMIT_OUTPUT_CHAR_HEADER_DECLARATION +int UNITY_OUTPUT_CHAR(int); +#endif +#ifdef UNITY_OMIT_OUTPUT_FLUSH_HEADER_DECLARATION +int UNITY_OUTPUT_FLUSH(void); +#endif + +/* Helpful macros for us to use here */ +#define UNITY_FAIL_AND_BAIL { Unity.CurrentTestFailed = 1; longjmp(Unity.AbortFrame, 1); } +#define UNITY_IGNORE_AND_BAIL { Unity.CurrentTestIgnored = 1; longjmp(Unity.AbortFrame, 1); } + +/* return prematurely if we are already in failure or ignore state */ +#define UNITY_SKIP_EXECUTION { if ((Unity.CurrentTestFailed != 0) || (Unity.CurrentTestIgnored != 0)) {return;} } + +struct _Unity Unity; + +static const char UnityStrOk[] = "OK"; +static const char UnityStrPass[] = "PASS"; +static const char UnityStrFail[] = "FAIL"; +static const char UnityStrIgnore[] = "IGNORE"; +static const char UnityStrNull[] = "NULL"; +static const char UnityStrSpacer[] = ". "; +static const char UnityStrExpected[] = " Expected "; +static const char UnityStrWas[] = " Was "; +static const char UnityStrElement[] = " Element "; +static const char UnityStrByte[] = " Byte "; +static const char UnityStrMemory[] = " Memory Mismatch."; +static const char UnityStrDelta[] = " Values Not Within Delta "; +static const char UnityStrPointless[] = " You Asked Me To Compare Nothing, Which Was Pointless."; +static const char UnityStrNullPointerForExpected[] = " Expected pointer to be NULL"; +static const char UnityStrNullPointerForActual[] = " Actual pointer was NULL"; +static const char UnityStrNot[] = "Not "; +static const char UnityStrInf[] = "Infinity"; +static const char UnityStrNegInf[] = "Negative Infinity"; +static const char UnityStrNaN[] = "NaN"; +static const char UnityStrDet[] = "Determinate"; +static const char UnityStrInvalidFloatTrait[] = "Invalid Float Trait"; +const char UnityStrErrFloat[] = "Unity Floating Point Disabled"; +const char UnityStrErrDouble[] = "Unity Double Precision Disabled"; +const char UnityStrErr64[] = "Unity 64-bit Support Disabled"; +static const char UnityStrBreaker[] = "-----------------------"; +static const char UnityStrResultsTests[] = " Tests "; +static const char UnityStrResultsFailures[] = " Failures "; +static const char UnityStrResultsIgnored[] = " Ignored "; +static const char UnityStrDetail1Name[] = UNITY_DETAIL1_NAME " "; +static const char UnityStrDetail2Name[] = " " UNITY_DETAIL2_NAME " "; + +#ifdef UNITY_FLOAT_NEEDS_ZERO +/* Dividing by these constants produces +/- infinity. + * The rationale is given in UnityAssertFloatIsInf's body. */ +static const _UF f_zero = 0.0f; +#endif + +/* compiler-generic print formatting masks */ +static const _U_UINT UnitySizeMask[] = +{ + 255u, /* 0xFF */ + 65535u, /* 0xFFFF */ + 65535u, + 4294967295u, /* 0xFFFFFFFF */ + 4294967295u, + 4294967295u, + 4294967295u +#ifdef UNITY_SUPPORT_64 + ,0xFFFFFFFFFFFFFFFF +#endif +}; + +/*----------------------------------------------- + * Pretty Printers & Test Result Output Handlers + *-----------------------------------------------*/ + +void UnityPrint(const char* string) +{ + const char* pch = string; + + if (pch != NULL) + { + while (*pch) + { + /* printable characters plus CR & LF are printed */ + if ((*pch <= 126) && (*pch >= 32)) + { + UNITY_OUTPUT_CHAR(*pch); + } + /* write escaped carriage returns */ + else if (*pch == 13) + { + UNITY_OUTPUT_CHAR('\\'); + UNITY_OUTPUT_CHAR('r'); + } + /* write escaped line feeds */ + else if (*pch == 10) + { + UNITY_OUTPUT_CHAR('\\'); + UNITY_OUTPUT_CHAR('n'); + } + /* unprintable characters are shown as codes */ + else + { + UNITY_OUTPUT_CHAR('\\'); + UnityPrintNumberHex((_U_UINT)*pch, 2); + } + pch++; + } + } +} + +void UnityPrintLen(const char* string, const _UU32 length); +void UnityPrintLen(const char* string, const _UU32 length) +{ + const char* pch = string; + + if (pch != NULL) + { + while (*pch && (_UU32)(pch - string) < length) + { + /* printable characters plus CR & LF are printed */ + if ((*pch <= 126) && (*pch >= 32)) + { + UNITY_OUTPUT_CHAR(*pch); + } + /* write escaped carriage returns */ + else if (*pch == 13) + { + UNITY_OUTPUT_CHAR('\\'); + UNITY_OUTPUT_CHAR('r'); + } + /* write escaped line feeds */ + else if (*pch == 10) + { + UNITY_OUTPUT_CHAR('\\'); + UNITY_OUTPUT_CHAR('n'); + } + /* unprintable characters are shown as codes */ + else + { + UNITY_OUTPUT_CHAR('\\'); + UnityPrintNumberHex((_U_UINT)*pch, 2); + } + pch++; + } + } +} + +/*-----------------------------------------------*/ +void UnityPrintNumberByStyle(const _U_SINT number, const UNITY_DISPLAY_STYLE_T style) +{ + if ((style & UNITY_DISPLAY_RANGE_INT) == UNITY_DISPLAY_RANGE_INT) + { + UnityPrintNumber(number); + } + else if ((style & UNITY_DISPLAY_RANGE_UINT) == UNITY_DISPLAY_RANGE_UINT) + { + UnityPrintNumberUnsigned( (_U_UINT)number & UnitySizeMask[((_U_UINT)style & (_U_UINT)0x0F) - 1] ); + } + else + { + UnityPrintNumberHex((_U_UINT)number, (char)((style & 0x000F) << 1)); + } +} + +/*-----------------------------------------------*/ +void UnityPrintNumber(const _U_SINT number_to_print) +{ + _U_UINT number = (_U_UINT)number_to_print; + + if (number_to_print < 0) + { + /* A negative number, including MIN negative */ + UNITY_OUTPUT_CHAR('-'); + number = (_U_UINT)(-number_to_print); + } + UnityPrintNumberUnsigned(number); +} + +/*----------------------------------------------- + * basically do an itoa using as little ram as possible */ +void UnityPrintNumberUnsigned(const _U_UINT number) +{ + _U_UINT divisor = 1; + + /* figure out initial divisor */ + while (number / divisor > 9) + { + divisor *= 10; + } + + /* now mod and print, then divide divisor */ + do + { + UNITY_OUTPUT_CHAR((char)('0' + (number / divisor % 10))); + divisor /= 10; + } + while (divisor > 0); +} + +/*-----------------------------------------------*/ +void UnityPrintNumberHex(const _U_UINT number, const char nibbles_to_print) +{ + _U_UINT nibble; + char nibbles = nibbles_to_print; + UNITY_OUTPUT_CHAR('0'); + UNITY_OUTPUT_CHAR('x'); + + while (nibbles > 0) + { + nibble = (number >> (--nibbles << 2)) & 0x0000000F; + if (nibble <= 9) + { + UNITY_OUTPUT_CHAR((char)('0' + nibble)); + } + else + { + UNITY_OUTPUT_CHAR((char)('A' - 10 + nibble)); + } + } +} + +/*-----------------------------------------------*/ +void UnityPrintMask(const _U_UINT mask, const _U_UINT number) +{ + _U_UINT current_bit = (_U_UINT)1 << (UNITY_INT_WIDTH - 1); + _US32 i; + + for (i = 0; i < UNITY_INT_WIDTH; i++) + { + if (current_bit & mask) + { + if (current_bit & number) + { + UNITY_OUTPUT_CHAR('1'); + } + else + { + UNITY_OUTPUT_CHAR('0'); + } + } + else + { + UNITY_OUTPUT_CHAR('X'); + } + current_bit = current_bit >> 1; + } +} + +/*-----------------------------------------------*/ +#ifdef UNITY_FLOAT_VERBOSE +#include + +#ifndef UNITY_VERBOSE_NUMBER_MAX_LENGTH +# ifdef UNITY_DOUBLE_VERBOSE +# define UNITY_VERBOSE_NUMBER_MAX_LENGTH 317 +# else +# define UNITY_VERBOSE_NUMBER_MAX_LENGTH 47 +# endif +#endif + +void UnityPrintFloat(_UF number) +{ + char TempBuffer[UNITY_VERBOSE_NUMBER_MAX_LENGTH + 1]; + snprintf(TempBuffer, sizeof(TempBuffer), "%.6f", number); + UnityPrint(TempBuffer); +} +#endif + +/*-----------------------------------------------*/ + +void UnityPrintFail(void); +void UnityPrintFail(void) +{ + UnityPrint(UnityStrFail); +} + +void UnityPrintOk(void); +void UnityPrintOk(void) +{ + UnityPrint(UnityStrOk); +} + +/*-----------------------------------------------*/ +static void UnityTestResultsBegin(const char* file, const UNITY_LINE_TYPE line); +static void UnityTestResultsBegin(const char* file, const UNITY_LINE_TYPE line) +{ +#ifndef UNITY_FIXTURES + UnityPrint(file); + UNITY_OUTPUT_CHAR(':'); + UnityPrintNumber((_U_SINT)line); + UNITY_OUTPUT_CHAR(':'); + UnityPrint(Unity.CurrentTestName); + UNITY_OUTPUT_CHAR(':'); +#else + UNITY_UNUSED(file); + UNITY_UNUSED(line); +#endif +} + +/*-----------------------------------------------*/ +static void UnityTestResultsFailBegin(const UNITY_LINE_TYPE line); +static void UnityTestResultsFailBegin(const UNITY_LINE_TYPE line) +{ +#ifndef UNITY_FIXTURES + UnityTestResultsBegin(Unity.TestFile, line); +#else + UNITY_UNUSED(line); +#endif + UnityPrint(UnityStrFail); + UNITY_OUTPUT_CHAR(':'); +} + +/*-----------------------------------------------*/ +void UnityConcludeTest(void) +{ + if (Unity.CurrentTestIgnored) + { + Unity.TestIgnores++; + } + else if (!Unity.CurrentTestFailed) + { + UnityTestResultsBegin(Unity.TestFile, Unity.CurrentTestLineNumber); + UnityPrint(UnityStrPass); + } + else + { + Unity.TestFailures++; + } + + Unity.CurrentTestFailed = 0; + Unity.CurrentTestIgnored = 0; + UNITY_PRINT_EOL(); + UNITY_OUTPUT_FLUSH(); +} + +/*-----------------------------------------------*/ +static void UnityAddMsgIfSpecified(const char* msg); +static void UnityAddMsgIfSpecified(const char* msg) +{ + if (msg) + { + UnityPrint(UnityStrSpacer); +#ifndef UNITY_EXCLUDE_DETAILS + if (Unity.CurrentDetail1) + { + UnityPrint(UnityStrDetail1Name); + UnityPrint(Unity.CurrentDetail1); + if (Unity.CurrentDetail2) + { + UnityPrint(UnityStrDetail2Name); + UnityPrint(Unity.CurrentDetail2); + } + UnityPrint(UnityStrSpacer); + } +#endif + UnityPrint(msg); + } +} + +/*-----------------------------------------------*/ +static void UnityPrintExpectedAndActualStrings(const char* expected, const char* actual); +static void UnityPrintExpectedAndActualStrings(const char* expected, const char* actual) +{ + UnityPrint(UnityStrExpected); + if (expected != NULL) + { + UNITY_OUTPUT_CHAR('\''); + UnityPrint(expected); + UNITY_OUTPUT_CHAR('\''); + } + else + { + UnityPrint(UnityStrNull); + } + UnityPrint(UnityStrWas); + if (actual != NULL) + { + UNITY_OUTPUT_CHAR('\''); + UnityPrint(actual); + UNITY_OUTPUT_CHAR('\''); + } + else + { + UnityPrint(UnityStrNull); + } +} + +/*-----------------------------------------------*/ +static void UnityPrintExpectedAndActualStringsLen(const char* expected, const char* actual, const _UU32 length) +{ + UnityPrint(UnityStrExpected); + if (expected != NULL) + { + UNITY_OUTPUT_CHAR('\''); + UnityPrintLen(expected, length); + UNITY_OUTPUT_CHAR('\''); + } + else + { + UnityPrint(UnityStrNull); + } + UnityPrint(UnityStrWas); + if (actual != NULL) + { + UNITY_OUTPUT_CHAR('\''); + UnityPrintLen(actual, length); + UNITY_OUTPUT_CHAR('\''); + } + else + { + UnityPrint(UnityStrNull); + } +} + + + +/*----------------------------------------------- + * Assertion & Control Helpers + *-----------------------------------------------*/ + +static int UnityCheckArraysForNull(UNITY_INTERNAL_PTR expected, UNITY_INTERNAL_PTR actual, const UNITY_LINE_TYPE lineNumber, const char* msg) +{ + /* return true if they are both NULL */ + if ((expected == NULL) && (actual == NULL)) + return 1; + + /* throw error if just expected is NULL */ + if (expected == NULL) + { + UnityTestResultsFailBegin(lineNumber); + UnityPrint(UnityStrNullPointerForExpected); + UnityAddMsgIfSpecified(msg); + UNITY_FAIL_AND_BAIL; + } + + /* throw error if just actual is NULL */ + if (actual == NULL) + { + UnityTestResultsFailBegin(lineNumber); + UnityPrint(UnityStrNullPointerForActual); + UnityAddMsgIfSpecified(msg); + UNITY_FAIL_AND_BAIL; + } + + /* return false if neither is NULL */ + return 0; +} + +/*----------------------------------------------- + * Assertion Functions + *-----------------------------------------------*/ + +void UnityAssertBits(const _U_SINT mask, + const _U_SINT expected, + const _U_SINT actual, + const char* msg, + const UNITY_LINE_TYPE lineNumber) +{ + UNITY_SKIP_EXECUTION; + + if ((mask & expected) != (mask & actual)) + { + UnityTestResultsFailBegin(lineNumber); + UnityPrint(UnityStrExpected); + UnityPrintMask((_U_UINT)mask, (_U_UINT)expected); + UnityPrint(UnityStrWas); + UnityPrintMask((_U_UINT)mask, (_U_UINT)actual); + UnityAddMsgIfSpecified(msg); + UNITY_FAIL_AND_BAIL; + } +} + +/*-----------------------------------------------*/ +void UnityAssertEqualNumber(const _U_SINT expected, + const _U_SINT actual, + const char* msg, + const UNITY_LINE_TYPE lineNumber, + const UNITY_DISPLAY_STYLE_T style) +{ + UNITY_SKIP_EXECUTION; + + if (expected != actual) + { + UnityTestResultsFailBegin(lineNumber); + UnityPrint(UnityStrExpected); + UnityPrintNumberByStyle(expected, style); + UnityPrint(UnityStrWas); + UnityPrintNumberByStyle(actual, style); + UnityAddMsgIfSpecified(msg); + UNITY_FAIL_AND_BAIL; + } +} + +#define UnityPrintPointlessAndBail() \ +{ \ + UnityTestResultsFailBegin(lineNumber); \ + UnityPrint(UnityStrPointless); \ + UnityAddMsgIfSpecified(msg); \ + UNITY_FAIL_AND_BAIL; } + +/*-----------------------------------------------*/ +void UnityAssertEqualIntArray(UNITY_INTERNAL_PTR expected, + UNITY_INTERNAL_PTR actual, + const _UU32 num_elements, + const char* msg, + const UNITY_LINE_TYPE lineNumber, + const UNITY_DISPLAY_STYLE_T style) +{ + _UU32 elements = num_elements; + UNITY_INTERNAL_PTR ptr_exp = (UNITY_INTERNAL_PTR)expected; + UNITY_INTERNAL_PTR ptr_act = (UNITY_INTERNAL_PTR)actual; + + UNITY_SKIP_EXECUTION; + + if (elements == 0) + { + UnityPrintPointlessAndBail(); + } + + if (UnityCheckArraysForNull((UNITY_INTERNAL_PTR)expected, (UNITY_INTERNAL_PTR)actual, lineNumber, msg) == 1) + return; + + /* If style is UNITY_DISPLAY_STYLE_INT, we'll fall into the default case rather than the INT16 or INT32 (etc) case + * as UNITY_DISPLAY_STYLE_INT includes a flag for UNITY_DISPLAY_RANGE_AUTO, which the width-specific + * variants do not. Therefore remove this flag. */ + switch(style & (UNITY_DISPLAY_STYLE_T)(~UNITY_DISPLAY_RANGE_AUTO)) + { + case UNITY_DISPLAY_STYLE_HEX8: + case UNITY_DISPLAY_STYLE_INT8: + case UNITY_DISPLAY_STYLE_UINT8: + while (elements--) + { + if (*(UNITY_PTR_ATTRIBUTE const _US8*)ptr_exp != *(UNITY_PTR_ATTRIBUTE const _US8*)ptr_act) + { + UnityTestResultsFailBegin(lineNumber); + UnityPrint(UnityStrElement); + UnityPrintNumberUnsigned(num_elements - elements - 1); + UnityPrint(UnityStrExpected); + UnityPrintNumberByStyle(*(UNITY_PTR_ATTRIBUTE const _US8*)ptr_exp, style); + UnityPrint(UnityStrWas); + UnityPrintNumberByStyle(*(UNITY_PTR_ATTRIBUTE const _US8*)ptr_act, style); + UnityAddMsgIfSpecified(msg); + UNITY_FAIL_AND_BAIL; + } + ptr_exp = (UNITY_INTERNAL_PTR)((_UP)ptr_exp + 1); + ptr_act = (UNITY_INTERNAL_PTR)((_UP)ptr_act + 1); + } + break; + case UNITY_DISPLAY_STYLE_HEX16: + case UNITY_DISPLAY_STYLE_INT16: + case UNITY_DISPLAY_STYLE_UINT16: + while (elements--) + { + if (*(UNITY_PTR_ATTRIBUTE const _US16*)ptr_exp != *(UNITY_PTR_ATTRIBUTE const _US16*)ptr_act) + { + UnityTestResultsFailBegin(lineNumber); + UnityPrint(UnityStrElement); + UnityPrintNumberUnsigned(num_elements - elements - 1); + UnityPrint(UnityStrExpected); + UnityPrintNumberByStyle(*(UNITY_PTR_ATTRIBUTE const _US16*)ptr_exp, style); + UnityPrint(UnityStrWas); + UnityPrintNumberByStyle(*(UNITY_PTR_ATTRIBUTE const _US16*)ptr_act, style); + UnityAddMsgIfSpecified(msg); + UNITY_FAIL_AND_BAIL; + } + ptr_exp = (UNITY_INTERNAL_PTR)((_UP)ptr_exp + 2); + ptr_act = (UNITY_INTERNAL_PTR)((_UP)ptr_act + 2); + } + break; +#ifdef UNITY_SUPPORT_64 + case UNITY_DISPLAY_STYLE_HEX64: + case UNITY_DISPLAY_STYLE_INT64: + case UNITY_DISPLAY_STYLE_UINT64: + while (elements--) + { + if (*(UNITY_PTR_ATTRIBUTE const _US64*)ptr_exp != *(UNITY_PTR_ATTRIBUTE const _US64*)ptr_act) + { + UnityTestResultsFailBegin(lineNumber); + UnityPrint(UnityStrElement); + UnityPrintNumberUnsigned(num_elements - elements - 1); + UnityPrint(UnityStrExpected); + UnityPrintNumberByStyle(*(UNITY_PTR_ATTRIBUTE const _US64*)ptr_exp, style); + UnityPrint(UnityStrWas); + UnityPrintNumberByStyle(*(UNITY_PTR_ATTRIBUTE const _US64*)ptr_act, style); + UnityAddMsgIfSpecified(msg); + UNITY_FAIL_AND_BAIL; + } + ptr_exp = (UNITY_INTERNAL_PTR)((_UP)ptr_exp + 8); + ptr_act = (UNITY_INTERNAL_PTR)((_UP)ptr_act + 8); + } + break; +#endif + default: + while (elements--) + { + if (*(UNITY_PTR_ATTRIBUTE const _US32*)ptr_exp != *(UNITY_PTR_ATTRIBUTE const _US32*)ptr_act) + { + UnityTestResultsFailBegin(lineNumber); + UnityPrint(UnityStrElement); + UnityPrintNumberUnsigned(num_elements - elements - 1); + UnityPrint(UnityStrExpected); + UnityPrintNumberByStyle(*(UNITY_PTR_ATTRIBUTE const _US32*)ptr_exp, style); + UnityPrint(UnityStrWas); + UnityPrintNumberByStyle(*(UNITY_PTR_ATTRIBUTE const _US32*)ptr_act, style); + UnityAddMsgIfSpecified(msg); + UNITY_FAIL_AND_BAIL; + } + ptr_exp = (UNITY_INTERNAL_PTR)((_UP)ptr_exp + 4); + ptr_act = (UNITY_INTERNAL_PTR)((_UP)ptr_act + 4); + } + break; + } +} + +/*-----------------------------------------------*/ +#ifndef UNITY_EXCLUDE_FLOAT +void UnityAssertEqualFloatArray(UNITY_PTR_ATTRIBUTE const _UF* expected, + UNITY_PTR_ATTRIBUTE const _UF* actual, + const _UU32 num_elements, + const char* msg, + const UNITY_LINE_TYPE lineNumber) +{ + _UU32 elements = num_elements; + UNITY_PTR_ATTRIBUTE const _UF* ptr_expected = expected; + UNITY_PTR_ATTRIBUTE const _UF* ptr_actual = actual; + _UF diff, tol; + + UNITY_SKIP_EXECUTION; + + if (elements == 0) + { + UnityPrintPointlessAndBail(); + } + + if (UnityCheckArraysForNull((UNITY_INTERNAL_PTR)expected, (UNITY_INTERNAL_PTR)actual, lineNumber, msg) == 1) + return; + + while (elements--) + { + diff = *ptr_expected - *ptr_actual; + if (diff < 0.0f) + diff = 0.0f - diff; + tol = UNITY_FLOAT_PRECISION * *ptr_expected; + if (tol < 0.0f) + tol = 0.0f - tol; + + /* This first part of this condition will catch any NaN or Infinite values */ + if (isnan(diff) || isinf(diff) || (diff > tol)) + { + UnityTestResultsFailBegin(lineNumber); + UnityPrint(UnityStrElement); + UnityPrintNumberUnsigned(num_elements - elements - 1); +#ifdef UNITY_FLOAT_VERBOSE + UnityPrint(UnityStrExpected); + UnityPrintFloat(*ptr_expected); + UnityPrint(UnityStrWas); + UnityPrintFloat(*ptr_actual); +#else + UnityPrint(UnityStrDelta); +#endif + UnityAddMsgIfSpecified(msg); + UNITY_FAIL_AND_BAIL; + } + ptr_expected++; + ptr_actual++; + } +} + +/*-----------------------------------------------*/ +void UnityAssertFloatsWithin(const _UF delta, + const _UF expected, + const _UF actual, + const char* msg, + const UNITY_LINE_TYPE lineNumber) +{ + _UF diff = actual - expected; + _UF pos_delta = delta; + + UNITY_SKIP_EXECUTION; + + if (diff < 0.0f) + { + diff = 0.0f - diff; + } + if (pos_delta < 0.0f) + { + pos_delta = 0.0f - pos_delta; + } + + /* This first part of this condition will catch any NaN or Infinite values */ + if (isnan(diff) || isinf(diff) || (pos_delta < diff)) + { + UnityTestResultsFailBegin(lineNumber); +#ifdef UNITY_FLOAT_VERBOSE + UnityPrint(UnityStrExpected); + UnityPrintFloat(expected); + UnityPrint(UnityStrWas); + UnityPrintFloat(actual); +#else + UnityPrint(UnityStrDelta); +#endif + UnityAddMsgIfSpecified(msg); + UNITY_FAIL_AND_BAIL; + } +} + +/*-----------------------------------------------*/ +void UnityAssertFloatSpecial(const _UF actual, + const char* msg, + const UNITY_LINE_TYPE lineNumber, + const UNITY_FLOAT_TRAIT_T style) +{ + const char* trait_names[] = { UnityStrInf, UnityStrNegInf, UnityStrNaN, UnityStrDet }; + _U_SINT should_be_trait = ((_U_SINT)style & 1); + _U_SINT is_trait = !should_be_trait; + _U_SINT trait_index = (_U_SINT)(style >> 1); + + UNITY_SKIP_EXECUTION; + + switch(style) + { + /* To determine Inf / Neg Inf, we compare to an Inf / Neg Inf value we create on the fly + * We are using a variable to hold the zero value because some compilers complain about dividing by zero otherwise */ + case UNITY_FLOAT_IS_INF: + case UNITY_FLOAT_IS_NOT_INF: + is_trait = isinf(actual) & ispos(actual); + break; + case UNITY_FLOAT_IS_NEG_INF: + case UNITY_FLOAT_IS_NOT_NEG_INF: + is_trait = isinf(actual) & isneg(actual); + break; + + /* NaN is the only floating point value that does NOT equal itself. Therefore if Actual == Actual, then it is NOT NaN. */ + case UNITY_FLOAT_IS_NAN: + case UNITY_FLOAT_IS_NOT_NAN: + is_trait = isnan(actual); + break; + + /* A determinate number is non infinite and not NaN. (therefore the opposite of the two above) */ + case UNITY_FLOAT_IS_DET: + case UNITY_FLOAT_IS_NOT_DET: + if (isinf(actual) | isnan(actual)) + is_trait = 0; + else + is_trait = 1; + break; + + default: + trait_index = 0; + trait_names[0] = UnityStrInvalidFloatTrait; + break; + } + + if (is_trait != should_be_trait) + { + UnityTestResultsFailBegin(lineNumber); + UnityPrint(UnityStrExpected); + if (!should_be_trait) + UnityPrint(UnityStrNot); + UnityPrint(trait_names[trait_index]); + UnityPrint(UnityStrWas); +#ifdef UNITY_FLOAT_VERBOSE + UnityPrintFloat(actual); +#else + if (should_be_trait) + UnityPrint(UnityStrNot); + UnityPrint(trait_names[trait_index]); +#endif + UnityAddMsgIfSpecified(msg); + UNITY_FAIL_AND_BAIL; + } +} + +#endif /* not UNITY_EXCLUDE_FLOAT */ + +/*-----------------------------------------------*/ +#ifndef UNITY_EXCLUDE_DOUBLE +void UnityAssertEqualDoubleArray(UNITY_PTR_ATTRIBUTE const _UD* expected, + UNITY_PTR_ATTRIBUTE const _UD* actual, + const _UU32 num_elements, + const char* msg, + const UNITY_LINE_TYPE lineNumber) +{ + _UU32 elements = num_elements; + UNITY_PTR_ATTRIBUTE const _UD* ptr_expected = expected; + UNITY_PTR_ATTRIBUTE const _UD* ptr_actual = actual; + _UD diff, tol; + + UNITY_SKIP_EXECUTION; + + if (elements == 0) + { + UnityPrintPointlessAndBail(); + } + + if (UnityCheckArraysForNull((UNITY_INTERNAL_PTR)expected, (UNITY_INTERNAL_PTR)actual, lineNumber, msg) == 1) + return; + + while (elements--) + { + diff = *ptr_expected - *ptr_actual; + if (diff < 0.0) + diff = 0.0 - diff; + tol = UNITY_DOUBLE_PRECISION * *ptr_expected; + if (tol < 0.0) + tol = 0.0 - tol; + + /* This first part of this condition will catch any NaN or Infinite values */ + if (isnan(diff) || isinf(diff) || (diff > tol)) + { + UnityTestResultsFailBegin(lineNumber); + UnityPrint(UnityStrElement); + UnityPrintNumberUnsigned(num_elements - elements - 1); +#ifdef UNITY_DOUBLE_VERBOSE + UnityPrint(UnityStrExpected); + UnityPrintFloat((float)(*ptr_expected)); + UnityPrint(UnityStrWas); + UnityPrintFloat((float)(*ptr_actual)); +#else + UnityPrint(UnityStrDelta); +#endif + UnityAddMsgIfSpecified(msg); + UNITY_FAIL_AND_BAIL; + } + ptr_expected++; + ptr_actual++; + } +} + +/*-----------------------------------------------*/ +void UnityAssertDoublesWithin(const _UD delta, + const _UD expected, + const _UD actual, + const char* msg, + const UNITY_LINE_TYPE lineNumber) +{ + _UD diff = actual - expected; + _UD pos_delta = delta; + + UNITY_SKIP_EXECUTION; + + if (diff < 0.0) + { + diff = 0.0 - diff; + } + if (pos_delta < 0.0) + { + pos_delta = 0.0 - pos_delta; + } + + /* This first part of this condition will catch any NaN or Infinite values */ + if (isnan(diff) || isinf(diff) || (pos_delta < diff)) + { + UnityTestResultsFailBegin(lineNumber); +#ifdef UNITY_DOUBLE_VERBOSE + UnityPrint(UnityStrExpected); + UnityPrintFloat((float)expected); + UnityPrint(UnityStrWas); + UnityPrintFloat((float)actual); +#else + UnityPrint(UnityStrDelta); +#endif + UnityAddMsgIfSpecified(msg); + UNITY_FAIL_AND_BAIL; + } +} + +/*-----------------------------------------------*/ + +void UnityAssertDoubleSpecial(const _UD actual, + const char* msg, + const UNITY_LINE_TYPE lineNumber, + const UNITY_FLOAT_TRAIT_T style) +{ + const char* trait_names[] = { UnityStrInf, UnityStrNegInf, UnityStrNaN, UnityStrDet }; + _U_SINT should_be_trait = ((_U_SINT)style & 1); + _U_SINT is_trait = !should_be_trait; + _U_SINT trait_index = (_U_SINT)(style >> 1); + + UNITY_SKIP_EXECUTION; + + switch(style) + { + /* To determine Inf / Neg Inf, we compare to an Inf / Neg Inf value we create on the fly + * We are using a variable to hold the zero value because some compilers complain about dividing by zero otherwise */ + case UNITY_FLOAT_IS_INF: + case UNITY_FLOAT_IS_NOT_INF: + is_trait = isinf(actual) & ispos(actual); + break; + case UNITY_FLOAT_IS_NEG_INF: + case UNITY_FLOAT_IS_NOT_NEG_INF: + is_trait = isinf(actual) & isneg(actual); + break; + + /* NaN is the only floating point value that does NOT equal itself. Therefore if Actual == Actual, then it is NOT NaN. */ + case UNITY_FLOAT_IS_NAN: + case UNITY_FLOAT_IS_NOT_NAN: + is_trait = isnan(actual); + break; + + /* A determinate number is non infinite and not NaN. (therefore the opposite of the two above) */ + case UNITY_FLOAT_IS_DET: + case UNITY_FLOAT_IS_NOT_DET: + if (isinf(actual) | isnan(actual)) + is_trait = 0; + else + is_trait = 1; + break; + + default: + trait_index = 0; + trait_names[0] = UnityStrInvalidFloatTrait; + break; + } + + if (is_trait != should_be_trait) + { + UnityTestResultsFailBegin(lineNumber); + UnityPrint(UnityStrExpected); + if (!should_be_trait) + UnityPrint(UnityStrNot); + UnityPrint(trait_names[trait_index]); + UnityPrint(UnityStrWas); +#ifdef UNITY_DOUBLE_VERBOSE + UnityPrintFloat(actual); +#else + if (should_be_trait) + UnityPrint(UnityStrNot); + UnityPrint(trait_names[trait_index]); +#endif + UnityAddMsgIfSpecified(msg); + UNITY_FAIL_AND_BAIL; + } +} + + +#endif /* not UNITY_EXCLUDE_DOUBLE */ + +/*-----------------------------------------------*/ +void UnityAssertNumbersWithin( const _U_UINT delta, + const _U_SINT expected, + const _U_SINT actual, + const char* msg, + const UNITY_LINE_TYPE lineNumber, + const UNITY_DISPLAY_STYLE_T style) +{ + UNITY_SKIP_EXECUTION; + + if ((style & UNITY_DISPLAY_RANGE_INT) == UNITY_DISPLAY_RANGE_INT) + { + if (actual > expected) + Unity.CurrentTestFailed = ((_U_UINT)(actual - expected) > delta); + else + Unity.CurrentTestFailed = ((_U_UINT)(expected - actual) > delta); + } + else + { + if ((_U_UINT)actual > (_U_UINT)expected) + Unity.CurrentTestFailed = ((_U_UINT)(actual - expected) > delta); + else + Unity.CurrentTestFailed = ((_U_UINT)(expected - actual) > delta); + } + + if (Unity.CurrentTestFailed) + { + UnityTestResultsFailBegin(lineNumber); + UnityPrint(UnityStrDelta); + UnityPrintNumberByStyle((_U_SINT)delta, style); + UnityPrint(UnityStrExpected); + UnityPrintNumberByStyle(expected, style); + UnityPrint(UnityStrWas); + UnityPrintNumberByStyle(actual, style); + UnityAddMsgIfSpecified(msg); + UNITY_FAIL_AND_BAIL; + } +} + +/*-----------------------------------------------*/ +void UnityAssertEqualString(const char* expected, + const char* actual, + const char* msg, + const UNITY_LINE_TYPE lineNumber) +{ + _UU32 i; + + UNITY_SKIP_EXECUTION; + + /* if both pointers not null compare the strings */ + if (expected && actual) + { + for (i = 0; expected[i] || actual[i]; i++) + { + if (expected[i] != actual[i]) + { + Unity.CurrentTestFailed = 1; + break; + } + } + } + else + { /* handle case of one pointers being null (if both null, test should pass) */ + if (expected != actual) + { + Unity.CurrentTestFailed = 1; + } + } + + if (Unity.CurrentTestFailed) + { + UnityTestResultsFailBegin(lineNumber); + UnityPrintExpectedAndActualStrings(expected, actual); + UnityAddMsgIfSpecified(msg); + UNITY_FAIL_AND_BAIL; + } +} + +/*-----------------------------------------------*/ +void UnityAssertEqualStringLen(const char* expected, + const char* actual, + const _UU32 length, + const char* msg, + const UNITY_LINE_TYPE lineNumber) +{ + _UU32 i; + + UNITY_SKIP_EXECUTION; + + /* if both pointers not null compare the strings */ + if (expected && actual) + { + for (i = 0; (expected[i] || actual[i]) && i < length; i++) + { + if (expected[i] != actual[i]) + { + Unity.CurrentTestFailed = 1; + break; + } + } + } + else + { /* handle case of one pointers being null (if both null, test should pass) */ + if (expected != actual) + { + Unity.CurrentTestFailed = 1; + } + } + + if (Unity.CurrentTestFailed) + { + UnityTestResultsFailBegin(lineNumber); + UnityPrintExpectedAndActualStringsLen(expected, actual, length); + UnityAddMsgIfSpecified(msg); + UNITY_FAIL_AND_BAIL; + } +} + + +/*-----------------------------------------------*/ +void UnityAssertEqualStringArray( const char** expected, + const char** actual, + const _UU32 num_elements, + const char* msg, + const UNITY_LINE_TYPE lineNumber) +{ + _UU32 i, j = 0; + + UNITY_SKIP_EXECUTION; + + /* if no elements, it's an error */ + if (num_elements == 0) + { + UnityPrintPointlessAndBail(); + } + + if (UnityCheckArraysForNull((UNITY_INTERNAL_PTR)expected, (UNITY_INTERNAL_PTR)actual, lineNumber, msg) == 1) + return; + + do + { + /* if both pointers not null compare the strings */ + if (expected[j] && actual[j]) + { + for (i = 0; expected[j][i] || actual[j][i]; i++) + { + if (expected[j][i] != actual[j][i]) + { + Unity.CurrentTestFailed = 1; + break; + } + } + } + else + { /* handle case of one pointers being null (if both null, test should pass) */ + if (expected[j] != actual[j]) + { + Unity.CurrentTestFailed = 1; + } + } + + if (Unity.CurrentTestFailed) + { + UnityTestResultsFailBegin(lineNumber); + if (num_elements > 1) + { + UnityPrint(UnityStrElement); + UnityPrintNumberUnsigned(j); + } + UnityPrintExpectedAndActualStrings((const char*)(expected[j]), (const char*)(actual[j])); + UnityAddMsgIfSpecified(msg); + UNITY_FAIL_AND_BAIL; + } + } while (++j < num_elements); +} + +/*-----------------------------------------------*/ +void UnityAssertEqualMemory( UNITY_INTERNAL_PTR expected, + UNITY_INTERNAL_PTR actual, + const _UU32 length, + const _UU32 num_elements, + const char* msg, + const UNITY_LINE_TYPE lineNumber) +{ + UNITY_PTR_ATTRIBUTE const unsigned char* ptr_exp = (UNITY_PTR_ATTRIBUTE const unsigned char*)expected; + UNITY_PTR_ATTRIBUTE const unsigned char* ptr_act = (UNITY_PTR_ATTRIBUTE const unsigned char*)actual; + _UU32 elements = num_elements; + _UU32 bytes; + + UNITY_SKIP_EXECUTION; + + if ((elements == 0) || (length == 0)) + { + UnityPrintPointlessAndBail(); + } + + if (UnityCheckArraysForNull((UNITY_INTERNAL_PTR)expected, (UNITY_INTERNAL_PTR)actual, lineNumber, msg) == 1) + return; + + while (elements--) + { + /* /////////////////////////////////// */ + bytes = length; + while (bytes--) + { + if (*ptr_exp != *ptr_act) + { + UnityTestResultsFailBegin(lineNumber); + UnityPrint(UnityStrMemory); + if (num_elements > 1) + { + UnityPrint(UnityStrElement); + UnityPrintNumberUnsigned(num_elements - elements - 1); + } + UnityPrint(UnityStrByte); + UnityPrintNumberUnsigned(length - bytes - 1); + UnityPrint(UnityStrExpected); + UnityPrintNumberByStyle(*ptr_exp, UNITY_DISPLAY_STYLE_HEX8); + UnityPrint(UnityStrWas); + UnityPrintNumberByStyle(*ptr_act, UNITY_DISPLAY_STYLE_HEX8); + UnityAddMsgIfSpecified(msg); + UNITY_FAIL_AND_BAIL; + } + ptr_exp = (UNITY_INTERNAL_PTR)((_UP)ptr_exp + 1); + ptr_act = (UNITY_INTERNAL_PTR)((_UP)ptr_act + 1); + } + /* /////////////////////////////////// */ + + } +} + +/*----------------------------------------------- + * Control Functions + *-----------------------------------------------*/ + +void UnityFail(const char* msg, const UNITY_LINE_TYPE line) +{ + UNITY_SKIP_EXECUTION; + + UnityTestResultsBegin(Unity.TestFile, line); + UnityPrintFail(); + if (msg != NULL) + { + UNITY_OUTPUT_CHAR(':'); + +#ifndef UNITY_EXCLUDE_DETAILS + if (Unity.CurrentDetail1) + { + UnityPrint(UnityStrDetail1Name); + UnityPrint(Unity.CurrentDetail1); + if (Unity.CurrentDetail2) + { + UnityPrint(UnityStrDetail2Name); + UnityPrint(Unity.CurrentDetail2); + } + UnityPrint(UnityStrSpacer); + } +#endif + if (msg[0] != ' ') + { + UNITY_OUTPUT_CHAR(' '); + } + UnityPrint(msg); + } + + UNITY_FAIL_AND_BAIL; +} + +/*-----------------------------------------------*/ +void UnityIgnore(const char* msg, const UNITY_LINE_TYPE line) +{ + UNITY_SKIP_EXECUTION; + + UnityTestResultsBegin(Unity.TestFile, line); + UnityPrint(UnityStrIgnore); + if (msg != NULL) + { + UNITY_OUTPUT_CHAR(':'); + UNITY_OUTPUT_CHAR(' '); + UnityPrint(msg); + } + UNITY_IGNORE_AND_BAIL; +} + +/*-----------------------------------------------*/ +#if defined(UNITY_WEAK_ATTRIBUTE) + UNITY_WEAK_ATTRIBUTE void setUp(void) { } + UNITY_WEAK_ATTRIBUTE void tearDown(void) { } +#elif defined(UNITY_WEAK_PRAGMA) +# pragma weak setUp + void setUp(void) { } +# pragma weak tearDown + void tearDown(void) { } +#endif +/*-----------------------------------------------*/ +void UnityDefaultTestRun(UnityTestFunction Func, const char* FuncName, const int FuncLineNum) +{ + Unity.CurrentTestName = FuncName; + Unity.CurrentTestLineNumber = (UNITY_LINE_TYPE)FuncLineNum; + Unity.NumberOfTests++; + UNITY_CLR_DETAILS(); + if (TEST_PROTECT()) + { + setUp(); + Func(); + } + if (TEST_PROTECT() && !(Unity.CurrentTestIgnored)) + { + tearDown(); + } + UnityConcludeTest(); +} + +/*-----------------------------------------------*/ +void UnityBegin(const char* filename) +{ + Unity.TestFile = filename; + Unity.CurrentTestName = NULL; + Unity.CurrentTestLineNumber = 0; + Unity.NumberOfTests = 0; + Unity.TestFailures = 0; + Unity.TestIgnores = 0; + Unity.CurrentTestFailed = 0; + Unity.CurrentTestIgnored = 0; + + UNITY_CLR_DETAILS(); + UNITY_OUTPUT_START(); +} + +/*-----------------------------------------------*/ +int UnityEnd(void) +{ + UNITY_PRINT_EOL(); + UnityPrint(UnityStrBreaker); + UNITY_PRINT_EOL(); + UnityPrintNumber((_U_SINT)(Unity.NumberOfTests)); + UnityPrint(UnityStrResultsTests); + UnityPrintNumber((_U_SINT)(Unity.TestFailures)); + UnityPrint(UnityStrResultsFailures); + UnityPrintNumber((_U_SINT)(Unity.TestIgnores)); + UnityPrint(UnityStrResultsIgnored); + UNITY_PRINT_EOL(); + if (Unity.TestFailures == 0U) + { + UnityPrintOk(); + } + else + { + UnityPrintFail(); +#ifdef UNITY_DIFFERENTIATE_FINAL_FAIL + UNITY_OUTPUT_CHAR('E'); UNITY_OUTPUT_CHAR('D'); +#endif + } + UNITY_PRINT_EOL(); + UNITY_OUTPUT_FLUSH(); + UNITY_OUTPUT_COMPLETE(); + return (int)(Unity.TestFailures); +} + +/*-----------------------------------------------*/ diff --git a/tools/unit-test-app/components/unity/unity_platform.c b/tools/unit-test-app/components/unity/unity_platform.c new file mode 100644 index 0000000000..4e1c0b8e07 --- /dev/null +++ b/tools/unit-test-app/components/unity/unity_platform.c @@ -0,0 +1,165 @@ +#include +#include +#include +#include "unity.h" +#include "rom/ets_sys.h" + +#define unity_printf ets_printf + +// Functions which are defined in ROM, linker script provides addresses for these: +int uart_tx_one_char(uint8_t c); +void uart_tx_wait_idle(uint8_t uart_no); +int UartRxString(uint8_t* dst, uint8_t max_length); + +// Pointers to the head and tail of linked list of test description structs: +static struct test_desc_t* s_unity_tests_first = NULL; +static struct test_desc_t* s_unity_tests_last = NULL; + + +void unity_putc(int c) +{ + if (c == '\n') + { + uart_tx_one_char('\n'); + uart_tx_one_char('\r'); + } + else if (c == '\r') + { + } + else + { + uart_tx_one_char(c); + } +} + +void unity_flush() +{ + uart_tx_wait_idle(0); // assume that output goes to UART0 +} + +void unity_testcase_register(struct test_desc_t* desc) +{ + if (!s_unity_tests_first) + { + s_unity_tests_first = desc; + } + else + { + s_unity_tests_last->next = desc; + } + s_unity_tests_last = desc; + desc->next = NULL; +} + +static void unity_run_single_test(const struct test_desc_t* test) +{ + Unity.TestFile = test->file; + Unity.CurrentDetail1 = test->desc; + UnityDefaultTestRun(test->fn, test->name, test->line); +} + +static void unity_run_single_test_by_index(int index) +{ + const struct test_desc_t* test; + for (test = s_unity_tests_first; test != NULL && index != 0; test = test->next, --index) + { + } + if (test != NULL) + { + unity_run_single_test(test); + } + +} + +static void unity_run_single_test_by_name(const char* filter) +{ + char tmp[256]; + strncpy(tmp, filter + 1, sizeof(tmp) - 1); + tmp[strlen(filter) - 2] = 0; + for (const struct test_desc_t* test = s_unity_tests_first; test != NULL; test = test->next) + { + if (strstr(test->name, tmp) != NULL) + { + unity_run_single_test(test); + } + } +} + +void unity_run_all_tests() +{ + for (const struct test_desc_t* test = s_unity_tests_first; test != NULL; test = test->next) + { + unity_run_single_test(test); + } +} + +void unity_run_tests_with_filter(const char* filter) +{ + for (const struct test_desc_t* test = s_unity_tests_first; test != NULL; test = test->next) + { + if (strstr(test->desc, filter) != NULL) + { + unity_run_single_test(test); + } + } +} + +static void trim_trailing_space(char* str) +{ + char* end = str + strlen(str) - 1; + while (end >= str && isspace((int) *end)) + { + *end = 0; + --end; + } +} + +void unity_run_menu() +{ + while (true) + { + int test_counter = 0; + unity_printf("\n\nHere's the test menu, pick your combo:\n"); + for (const struct test_desc_t* test = s_unity_tests_first; + test != NULL; + test = test->next, ++test_counter) + { + unity_printf("(%d)\t\"%s\" %s\n", test_counter + 1, test->name, test->desc); + } + + char cmdline[256]; + UartRxString((uint8_t*) cmdline, sizeof(cmdline) - 1); + trim_trailing_space(cmdline); + + if (strlen(cmdline) == 0) + { + continue; + } + + UNITY_BEGIN(); + + if (cmdline[0] == '*') + { + unity_run_all_tests(); + } + else if (cmdline[0] =='[') + { + unity_run_tests_with_filter(cmdline); + } + else if (cmdline[0] =='"') + { + unity_run_single_test_by_name(cmdline); + } + else + { + int test_index = strtol(cmdline, NULL, 10); + if (test_index >= 1 && test_index <= test_counter) + { + unity_run_single_test_by_index(test_index - 1); + } + } + + UNITY_END(); + } +} + diff --git a/tools/unit-test-app/main/app_main.c b/tools/unit-test-app/main/app_main.c new file mode 100644 index 0000000000..b00034adf1 --- /dev/null +++ b/tools/unit-test-app/main/app_main.c @@ -0,0 +1,18 @@ +#include +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "unity.h" + + +void unityTask(void *pvParameters) +{ + vTaskDelay(1000 / portTICK_PERIOD_MS); + unity_run_menu(); + while(1); +} + +void app_main() +{ + xTaskCreatePinnedToCore(unityTask, "unityTask", 4096, NULL, 5, NULL, 0); +} + diff --git a/tools/unit-test-app/main/component.mk b/tools/unit-test-app/main/component.mk new file mode 100644 index 0000000000..fd2dbe7b84 --- /dev/null +++ b/tools/unit-test-app/main/component.mk @@ -0,0 +1,5 @@ +# +# Main Makefile. This is basically the same as a component makefile. +# + +include $(IDF_PATH)/make/component_common.mk diff --git a/tools/unit-test-app/sdkconfig b/tools/unit-test-app/sdkconfig new file mode 100644 index 0000000000..cde49f3c8d --- /dev/null +++ b/tools/unit-test-app/sdkconfig @@ -0,0 +1,125 @@ +# +# Automatically generated file; DO NOT EDIT. +# Espressif IoT Development Framework Configuration +# + +# +# SDK tool configuration +# +CONFIG_TOOLPREFIX="xtensa-esp32-elf-" +CONFIG_PYTHON="python" + +# +# Serial flasher config +# +CONFIG_ESPTOOLPY_PORT="/dev/ttyUSB0" +# CONFIG_ESPTOOLPY_BAUD_115200B is not set +# CONFIG_ESPTOOLPY_BAUD_230400B is not set +CONFIG_ESPTOOLPY_BAUD_921600B=y +# CONFIG_ESPTOOLPY_BAUD_2MB is not set +# CONFIG_ESPTOOLPY_BAUD_OTHER is not set +CONFIG_ESPTOOLPY_BAUD_OTHER_VAL=115200 +CONFIG_ESPTOOLPY_BAUD=921600 +CONFIG_ESPTOOLPY_COMPRESSED=y +# CONFIG_ESPTOOLPY_FLASHMODE_QIO is not set +# CONFIG_ESPTOOLPY_FLASHMODE_QOUT is not set +CONFIG_ESPTOOLPY_FLASHMODE_DIO=y +# CONFIG_ESPTOOLPY_FLASHMODE_DOUT is not set +CONFIG_ESPTOOLPY_FLASHMODE="dio" +# CONFIG_ESPTOOLPY_FLASHFREQ_80M is not set +CONFIG_ESPTOOLPY_FLASHFREQ_40M=y +# CONFIG_ESPTOOLPY_FLASHFREQ_26M is not set +# CONFIG_ESPTOOLPY_FLASHFREQ_20M is not set +CONFIG_ESPTOOLPY_FLASHFREQ="40m" + +# +# Partition Table +# +CONFIG_PARTITION_TABLE_SINGLE_APP=y +# CONFIG_PARTITION_TABLE_TWO_OTA is not set +# CONFIG_PARTITION_TABLE_CUSTOM is not set +CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions.csv" +CONFIG_PARTITION_TABLE_CUSTOM_APP_BIN_OFFSET=0x10000 +CONFIG_PARTITION_TABLE_FILENAME="partitions_singleapp.csv" +CONFIG_APP_OFFSET=0x10000 + +# +# Component config +# + +# +# ESP32-specific config +# +# CONFIG_ESP32_DEFAULT_CPU_FREQ_80 is not set +# CONFIG_ESP32_DEFAULT_CPU_FREQ_160 is not set +CONFIG_ESP32_DEFAULT_CPU_FREQ_240=y +CONFIG_ESP32_DEFAULT_CPU_FREQ_MHZ=240 +# CONFIG_ESP32_ENABLE_STACK_WIFI is not set +# CONFIG_ESP32_ENABLE_STACK_BT is not set +CONFIG_ESP32_ENABLE_STACK_NONE=y +CONFIG_MEMMAP_SMP=y +# CONFIG_MEMMAP_TRACEMEM is not set +# CONFIG_MEMMAP_SPISRAM is not set +CONFIG_SYSTEM_EVENT_QUEUE_SIZE=32 +CONFIG_SYSTEM_EVENT_TASK_STACK_SIZE=2048 +CONFIG_MAIN_TASK_STACK_SIZE=4096 +CONFIG_NEWLIB_STDOUT_ADDCR=y + +# +# FreeRTOS +# +# CONFIG_FREERTOS_UNICORE is not set +CONFIG_FREERTOS_CORETIMER_0=y +# CONFIG_FREERTOS_CORETIMER_1 is not set +# CONFIG_FREERTOS_CORETIMER_2 is not set +CONFIG_FREERTOS_HZ=1000 +# CONFIG_FREERTOS_CHECK_STACKOVERFLOW_NONE is not set +# CONFIG_FREERTOS_CHECK_STACKOVERFLOW_PTRVAL is not set +CONFIG_FREERTOS_CHECK_STACKOVERFLOW_CANARY=y +CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=3 +# CONFIG_FREERTOS_PANIC_PRINT_HALT is not set +CONFIG_FREERTOS_PANIC_PRINT_REBOOT=y +# CONFIG_FREERTOS_PANIC_SILENT_REBOOT is not set +# CONFIG_FREERTOS_PANIC_GDBSTUB is not set +CONFIG_FREERTOS_DEBUG_OCDAWARE=y +CONFIG_FREERTOS_ASSERT_FAIL_ABORT=y +# CONFIG_FREERTOS_ASSERT_FAIL_PRINT_CONTINUE is not set +# CONFIG_FREERTOS_ASSERT_DISABLE is not set +CONFIG_FREERTOS_BREAK_ON_SCHEDULER_START_JTAG=y +# CONFIG_ENABLE_MEMORY_DEBUG is not set +# CONFIG_FREERTOS_DEBUG_INTERNALS is not set + +# +# Log output +# +# CONFIG_LOG_DEFAULT_LEVEL_NONE is not set +# CONFIG_LOG_DEFAULT_LEVEL_ERROR is not set +# CONFIG_LOG_DEFAULT_LEVEL_WARN is not set +CONFIG_LOG_DEFAULT_LEVEL_INFO=y +# CONFIG_LOG_DEFAULT_LEVEL_DEBUG is not set +# CONFIG_LOG_DEFAULT_LEVEL_VERBOSE is not set +CONFIG_LOG_DEFAULT_LEVEL=3 +CONFIG_LOG_COLORS=y + +# +# LWIP +# +CONFIG_LWIP_MAX_SOCKETS=4 +CONFIG_LWIP_THREAD_LOCAL_STORAGE_INDEX=0 +# CONFIG_LWIP_SO_REUSE is not set + +# +# mbedTLS +# +CONFIG_MBEDTLS_SSL_MAX_CONTENT_LEN=16384 +# CONFIG_MBEDTLS_DEBUG is not set + +# +# SPI Flash driver +# +# CONFIG_SPI_FLASH_ENABLE_COUNTERS is not set + +# +# TESTS +# +CONFIG_FP_TEST_ENABLE=y