mirror of
https://github.com/espressif/esp-idf.git
synced 2026-10-02 11:10:54 +03:00
feat(usb_host): Host tests for individual USB Host layers
- Public API CMock based Host tests
- USB Host layer: driver install/uninstall unit test
- USBH layer: driver install/uninstall unit test
- Host tests are run in CI
This commit is contained in:
@@ -0,0 +1,13 @@
|
||||
cmake_minimum_required(VERSION 3.16)
|
||||
|
||||
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
|
||||
set(COMPONENTS main)
|
||||
|
||||
list(APPEND EXTRA_COMPONENT_DIRS
|
||||
"$ENV{IDF_PATH}/tools/mocks/usb/usbh_layer_mock/usb"
|
||||
|
||||
# The following line would be needed to include the freertos mock component if this test used mocked FreeRTOS.
|
||||
#"$ENV{IDF_PATH}/tools/mocks/freertos/"
|
||||
)
|
||||
|
||||
project(host_test_usbh_layer)
|
||||
@@ -0,0 +1,37 @@
|
||||
| Supported Targets | Linux |
|
||||
| ----------------- | ----- |
|
||||
|
||||
# Description
|
||||
|
||||
This directory contains test code for `USBH layer` of USB Host stack. Namely:
|
||||
* USBH public API calls to install and uninstall the USBH driver with partially mocked USB Host stack to test Linux build and Cmock run for this partial Mock
|
||||
* Mocked are all layers of the USB Host stack below the USBH layer, which is used as a real component
|
||||
|
||||
Tests are written using [Catch2](https://github.com/catchorg/Catch2) test framework, use CMock, so you must install Ruby on your machine to run them.
|
||||
|
||||
This test directory uses freertos as a real component
|
||||
|
||||
# Build
|
||||
|
||||
Tests build regularly like an idf project. Currently only working on Linux machines.
|
||||
|
||||
```
|
||||
idf.py --preview set-target linux
|
||||
idf.py build
|
||||
```
|
||||
|
||||
# Run
|
||||
|
||||
The build produces an executable in the build folder.
|
||||
|
||||
Just run:
|
||||
|
||||
```
|
||||
idf.py monitor
|
||||
```
|
||||
|
||||
or run the executable directly:
|
||||
|
||||
```
|
||||
./build/host_test_usbh_layer.elf
|
||||
```
|
||||
@@ -0,0 +1,12 @@
|
||||
set(srcs)
|
||||
list(APPEND srcs "test_main.cpp"
|
||||
"usbh_install_unit_test.cpp"
|
||||
)
|
||||
|
||||
idf_component_register(SRCS ${srcs}
|
||||
REQUIRES cmock usb
|
||||
WHOLE_ARCHIVE)
|
||||
|
||||
# The following line would be needed to provide the 'main' function if this test used mocked FreeRTOS.
|
||||
# As this test uses the real FreeRTOS implementation, we don't need Catch2 to provide 'main'.
|
||||
#target_link_libraries(${COMPONENT_LIB} PRIVATE Catch2WithMain)
|
||||
@@ -0,0 +1,2 @@
|
||||
dependencies:
|
||||
espressif/catch2: "^3.4.0"
|
||||
@@ -0,0 +1,27 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <catch2/catch_session.hpp>
|
||||
#include <catch2/catch_test_macros.hpp>
|
||||
|
||||
extern "C" void app_main(void)
|
||||
{
|
||||
int argc = 1;
|
||||
const char *argv[2] = {
|
||||
"target_test_main",
|
||||
NULL
|
||||
};
|
||||
|
||||
auto result = Catch::Session().run(argc, argv);
|
||||
if (result != 0) {
|
||||
printf("Test failed with result %d\n", result);
|
||||
} else {
|
||||
printf("Test passed.\n");
|
||||
}
|
||||
fflush(stdout);
|
||||
exit(result);
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <catch2/catch_test_macros.hpp>
|
||||
|
||||
#include "usbh.h" // Real implementation of usbh.h
|
||||
|
||||
// Test all the mocked headers defined for this mock
|
||||
extern "C" {
|
||||
#include "Mockhcd.h"
|
||||
#include "Mockusb_private.h"
|
||||
}
|
||||
|
||||
SCENARIO("USBH pre-uninstall")
|
||||
{
|
||||
// No USBH driver previously installed
|
||||
GIVEN("No USBH previously installed") {
|
||||
|
||||
// Uninstall not-installed USBH driver
|
||||
SECTION("Uninstalling not installed USBH driver") {
|
||||
|
||||
// Call the DUT function, expect ESP_ERR_INVALID_STATE
|
||||
REQUIRE(ESP_ERR_INVALID_STATE == usbh_uninstall());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SCENARIO("USBH install")
|
||||
{
|
||||
// USBH config is not valid, USBH driver is not previously installed
|
||||
GIVEN("No USBH config, USBH driver not installed") {
|
||||
|
||||
// Try to install the USBH driver with usbh_config set to nullptr
|
||||
SECTION("USBH config is nullptr") {
|
||||
|
||||
// Call the DUT function, expect ESP_ERR_INVALID_ARG
|
||||
REQUIRE(ESP_ERR_INVALID_ARG == usbh_install(nullptr));
|
||||
}
|
||||
}
|
||||
|
||||
// USBH config struct
|
||||
usbh_config_t usbh_config = {};
|
||||
|
||||
// USBH config is valid, USBH driver is not previously installed
|
||||
GIVEN("USBH config, USBH driver not installed") {
|
||||
|
||||
// Successfully install the USBH Driver
|
||||
SECTION("Successfully install the USBH Driver") {
|
||||
|
||||
// Call the DUT function, expect ESP_OK
|
||||
REQUIRE(ESP_OK == usbh_install(&usbh_config));
|
||||
}
|
||||
}
|
||||
|
||||
// USBH config is valid, USBH driver is previously installed
|
||||
GIVEN("USBH config, USBH driver previously installed") {
|
||||
|
||||
SECTION("Fail to install already installed USBH driver") {
|
||||
|
||||
// Call the DUT function, expect ESP_ERR_INVALID_STATE
|
||||
REQUIRE(ESP_ERR_INVALID_STATE == usbh_install(&usbh_config));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SCENARIO("USBH post-uninstall")
|
||||
{
|
||||
|
||||
// USBH driver successfully installed from previous test case
|
||||
GIVEN("USBH driver previously installed") {
|
||||
|
||||
// Uninstall successfully installed USBH driver
|
||||
SECTION("Successfully uninstall the USBH driver") {
|
||||
|
||||
// Call the DUT function, expect ESP_OK
|
||||
REQUIRE(ESP_OK == usbh_uninstall());
|
||||
}
|
||||
}
|
||||
|
||||
// USBH driver successfully uninstalled from previous test case
|
||||
GIVEN("USBH successfully uninstalled") {
|
||||
|
||||
// USBH successfully uninstalled, try to uninstall it again
|
||||
SECTION("Uninstall already uninstalled USBH driver") {
|
||||
|
||||
// Call the DUT function, expect ESP_ERR_INVALID_STATE
|
||||
REQUIRE(ESP_ERR_INVALID_STATE == usbh_uninstall());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
# SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
|
||||
# SPDX-License-Identifier: Unlicense OR CC0-1.0
|
||||
import pytest
|
||||
from pytest_embedded import Dut
|
||||
from pytest_embedded_idf.utils import idf_parametrize
|
||||
|
||||
|
||||
@pytest.mark.host_test
|
||||
@idf_parametrize('target', ['linux'], indirect=['target'])
|
||||
def test_usbh_layer_linux(dut: Dut) -> None:
|
||||
dut.expect_exact('All tests passed', timeout=5)
|
||||
@@ -0,0 +1,4 @@
|
||||
|
||||
CONFIG_IDF_TARGET="linux"
|
||||
CONFIG_COMPILER_CXX_EXCEPTIONS=y
|
||||
CONFIG_UNITY_ENABLE_IDF_TEST_RUNNER=n
|
||||
Reference in New Issue
Block a user