Multi-Device Test Cases: unity_send_signal() and unity_wait_for_signal() not working

fevang
Posts: 6
Joined: Thu Jun 04, 2020 7:11 pm

Multi-Device Test Cases: unity_send_signal() and unity_wait_for_signal() not working

Postby fevang » Mon Aug 31, 2020 9:13 pm

The documentation https://docs.espressif.com/projects/esp ... test-cases summarizes how to perform multi-device-test-cases and synchronize multiple devices using unity_send_signal() and unity_wait_for_signal()

Here is the provided sample multi-device test case code from that documentation:

Code: Select all

void gpio_master_test()
{
    gpio_config_t slave_config = {
            .pin_bit_mask = 1 << MASTER_GPIO_PIN,
            .mode = GPIO_MODE_INPUT,
    };
    gpio_config(&slave_config);
    unity_wait_for_signal("output high level");
    TEST_ASSERT(gpio_get_level(MASTER_GPIO_PIN) == 1);
}

void gpio_slave_test()
{
    gpio_config_t master_config = {
            .pin_bit_mask = 1 << SLAVE_GPIO_PIN,
            .mode = GPIO_MODE_OUTPUT,
    };
    gpio_config(&master_config);
    gpio_set_level(SLAVE_GPIO_PIN, 1);
    unity_send_signal("output high level");
}

TEST_CASE_MULTIPLE_DEVICES("gpio multiple devices test example", "[driver]", gpio_master_test, gpio_slave_test);
I copied that sample code into the example unit test application here: https://github.com/espressif/esp-idf/tr ... /unit_test
Into components/testable/tests/test_mean.c, and the two functions unity_send_signal() and unity_wait_for_signal() are undefined

I determined these functions are defined in esp-idf/tools/unit-test-app/components/test_utils/include/test_utils.h
I modified the EXTRA_COMPONENT_DIRS CMake variable to include the test_utils component,

Code: Select all

set(EXTRA_COMPONENT_DIRS "../components;$ENV{IDF_PATH}/tools/unit-test-app/components")

Added the test_utils component in the testable component

Code: Select all

idf_component_register(SRC_DIRS "."
                    INCLUDE_DIRS "."
                    REQUIRES unity test_utils testable)
and included the file in testable/test/test_mean.c

Code: Select all

#include "test_utils.h"
Now unity_send_signal() and unity_wait_for_signal() are defined and everything builds.

BUT it still doesn't work.
When I run the tests, every single test now fails with error "Expected Non-NULL", even tests that don't call unity_send_signal() or unity_wait_for_signal(). If I remove both calls to unity_send_signal() or unity_wait_for_signal() then all the tests pass as expected again.

What am I missing? The tests for the esp-idf components use these functions and they seem to work when I run the unit-test-app. This feature will be very useful for me, but I cannot figure it out.
Thanks!

kraxor
Posts: 7
Joined: Wed Jan 13, 2021 12:08 pm

Re: Multi-Device Test Cases: unity_send_signal() and unity_wait_for_signal() not working

Postby kraxor » Wed Jan 27, 2021 4:07 am

I tried to do the same, got the same results. As far as I can tell, an internal TEST_ASSERT_NOT_NULL fails somewhere, but strangely it doesn't print the line number or anything, so I gave up. The way I see it, most of the testing features in IDF are supposed to be used internally, and / or to test IDF itself.

For now, I'm gonna try and send signals "manually" via UART between the test devices, shouldn't be that hard, but we'll see.

kraxor
Posts: 7
Joined: Wed Jan 13, 2021 12:08 pm

Re: Multi-Device Test Cases: unity_send_signal() and unity_wait_for_signal() not working

Postby kraxor » Wed Jan 27, 2021 6:01 am

So I implemented my own signal functions. Note that I'm using C++ but the concept is the same for C.

Code: Select all

#include <unity.h>

#include <iostream>
#include <string>

#include <driver/gpio.h>
#include <driver/uart.h>

#define MASTER_GPIO_PIN GPIO_NUM_27
#define SLAVE_GPIO_PIN GPIO_NUM_27

using std::cout;
using std::endl;
using std::string;

void setup_uart() {
    ESP_ERROR_CHECK(uart_driver_install(UART_NUM_1, 2 * 1024, 0, 0, nullptr, 0));
    uart_config_t uart_config = {
            .baud_rate = 115200,
            .data_bits = UART_DATA_8_BITS,
            .parity = UART_PARITY_DISABLE,
            .stop_bits = UART_STOP_BITS_1,
            .flow_ctrl = UART_HW_FLOWCTRL_CTS_RTS,
            .rx_flow_ctrl_thresh = 122,
    };
    ESP_ERROR_CHECK(uart_param_config(UART_NUM_1, &uart_config));
    ESP_ERROR_CHECK(uart_set_pin(UART_NUM_1, 33, 32, 25, 26));
}

void wait_for_signal(const string &signal) {
    auto buffer = new char[1024];
    while (true) {
        int len = uart_read_bytes(UART_NUM_1, buffer, 1024, 20 / portTICK_RATE_MS);
        if (len > 0 && signal == buffer) {
            cout << "signal \"" << buffer << "\" received" << endl;
            break;
        }
    }
}

void send_signal(const string &signal) {
    uart_write_bytes(UART_NUM_1, signal.c_str(), signal.length() + 1);
}

void gpio_master_test() {
    setup_uart();

    gpio_config_t slave_config = {
            .pin_bit_mask = 1 << MASTER_GPIO_PIN,
            .mode = GPIO_MODE_INPUT,
    };
    gpio_config(&slave_config);

//    unity_wait_for_signal("output high level");
    wait_for_signal("output high level");

    TEST_ASSERT(gpio_get_level(MASTER_GPIO_PIN) == 1);
}

void gpio_slave_test() {
    setup_uart();

    gpio_config_t master_config = {
            .pin_bit_mask = 1 << SLAVE_GPIO_PIN,
            .mode = GPIO_MODE_OUTPUT,
    };
    gpio_config(&master_config);
    gpio_set_level(SLAVE_GPIO_PIN, 1);

//    unity_send_signal("output high level");
    send_signal("output high level");
}

TEST_CASE_MULTIPLE_DEVICES("gpio multiple devices test example", "[driver]", gpio_master_test, gpio_slave_test);

Who is online

Users browsing this forum: No registered users and 443 guests