forked from espressif/esp-idf
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:
7
components/usb/host_test/.build-test-rules.yml
Normal file
7
components/usb/host_test/.build-test-rules.yml
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
# Documentation: .gitlab/ci/README.md#manifest-file-to-control-the-buildtest-apps
|
||||||
|
|
||||||
|
components/usb/host_test:
|
||||||
|
enable:
|
||||||
|
- if: IDF_TARGET == "linux"
|
||||||
|
depends_components:
|
||||||
|
- usb
|
13
components/usb/host_test/usb_host_layer_test/CMakeLists.txt
Normal file
13
components/usb/host_test/usb_host_layer_test/CMakeLists.txt
Normal file
@@ -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/usb_host_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_usb_host_layer)
|
37
components/usb/host_test/usb_host_layer_test/README.md
Normal file
37
components/usb/host_test/usb_host_layer_test/README.md
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
| Supported Targets | Linux |
|
||||||
|
| ----------------- | ----- |
|
||||||
|
|
||||||
|
# Description
|
||||||
|
|
||||||
|
This directory contains test code for `USB Host layer` of USB Host stack. Namely:
|
||||||
|
* USB Host public API calls to install and uninstall the USB Host 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 USB Host 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 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_usb_host_layer.elf
|
||||||
|
```
|
@@ -0,0 +1,12 @@
|
|||||||
|
set(srcs)
|
||||||
|
list(APPEND srcs "test_main.cpp"
|
||||||
|
"usb_host_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,254 @@
|
|||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <catch2/catch_test_macros.hpp>
|
||||||
|
|
||||||
|
#include "usb_host.h" // Real implementation of usb_host.h
|
||||||
|
|
||||||
|
// Test all the mocked headers defined for this mock
|
||||||
|
extern "C" {
|
||||||
|
#include "Mockusb_phy.h"
|
||||||
|
#include "Mockhcd.h"
|
||||||
|
#include "Mockusbh.h"
|
||||||
|
#include "Mockenum.h"
|
||||||
|
#include "Mockhub.h"
|
||||||
|
}
|
||||||
|
|
||||||
|
SCENARIO("USB Host pre-uninstall")
|
||||||
|
{
|
||||||
|
// No USB Host driver previously installed
|
||||||
|
GIVEN("No USB Host previously installed") {
|
||||||
|
|
||||||
|
// Uninstall not-installed USB Host
|
||||||
|
SECTION("Uninstalling not installed USB Host") {
|
||||||
|
|
||||||
|
// Call the DUT function, expect ESP_ERR_INVALID_STATE
|
||||||
|
REQUIRE(ESP_ERR_INVALID_STATE == usb_host_uninstall());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SCENARIO("USB Host install")
|
||||||
|
{
|
||||||
|
// USB Host config is not valid, USB Host driver is not installed from previous test case
|
||||||
|
GIVEN("No USB Host config, USB Host driver not installed") {
|
||||||
|
|
||||||
|
// Try to install the USB Host driver with usb_host_config set to nullptr
|
||||||
|
SECTION("USB Host config is nullptr") {
|
||||||
|
|
||||||
|
// Call the DUT function, expect ESP_ERR_INVALID_ARG
|
||||||
|
REQUIRE(ESP_ERR_INVALID_ARG == usb_host_install(nullptr));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// USB Host config struct
|
||||||
|
usb_host_config_t usb_host_config = {
|
||||||
|
.skip_phy_setup = false,
|
||||||
|
.root_port_unpowered = false,
|
||||||
|
.intr_flags = 1,
|
||||||
|
.enum_filter_cb = nullptr,
|
||||||
|
};
|
||||||
|
|
||||||
|
// USB host config is valid, USB Host driver is not installed from previous test case
|
||||||
|
GIVEN("USB Host config, USB Host driver not installed") {
|
||||||
|
|
||||||
|
// Try to install the USB Host driver, with PHY install error
|
||||||
|
SECTION("Fail to install USB Host - PHY Install error") {
|
||||||
|
|
||||||
|
// Make the PHY install to fail
|
||||||
|
usb_new_phy_ExpectAnyArgsAndReturn(ESP_ERR_INVALID_STATE);
|
||||||
|
|
||||||
|
// Call the DUT function, expect ESP_ERR_INVALID_STATE
|
||||||
|
REQUIRE(ESP_ERR_INVALID_STATE == usb_host_install(&usb_host_config));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Try to install the USB Host driver, with HCD Install error, use internal PHY
|
||||||
|
SECTION("Fail to install USB Host - HCD Install error (internal PHY)") {
|
||||||
|
|
||||||
|
// Make the PHY install to pass
|
||||||
|
usb_phy_handle_t phy_handle;
|
||||||
|
usb_new_phy_ExpectAnyArgsAndReturn(ESP_OK);
|
||||||
|
usb_new_phy_ReturnThruPtr_handle_ret(&phy_handle);
|
||||||
|
|
||||||
|
// make the HCD port install to fail
|
||||||
|
hcd_install_ExpectAnyArgsAndReturn(ESP_ERR_INVALID_STATE);
|
||||||
|
|
||||||
|
// goto hcd_err: We must uninstall the PHY
|
||||||
|
usb_del_phy_ExpectAndReturn(phy_handle, ESP_OK);
|
||||||
|
|
||||||
|
// Call the DUT function, expect ESP_ERR_INVALID_STATE
|
||||||
|
REQUIRE(ESP_ERR_INVALID_STATE == usb_host_install(&usb_host_config));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Try to install the USB Host driver, with HCD Install error, use external PHY
|
||||||
|
SECTION("Fail to install USB Host - HCD Install error (external PHY)") {
|
||||||
|
|
||||||
|
// Skip the PHY Setup (external phy)
|
||||||
|
usb_host_config.skip_phy_setup = true;
|
||||||
|
|
||||||
|
// make the HCD port install to fail
|
||||||
|
hcd_install_ExpectAnyArgsAndReturn(ESP_ERR_INVALID_STATE);
|
||||||
|
|
||||||
|
// Call the DUT function, expect ESP_ERR_INVALID_STATE
|
||||||
|
REQUIRE(ESP_ERR_INVALID_STATE == usb_host_install(&usb_host_config));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Try to install the USB Host driver, with USBH Install error, use internal PHY
|
||||||
|
SECTION("Fail to install USB Host - USBH install error") {
|
||||||
|
|
||||||
|
// Make the PHY install to pass
|
||||||
|
usb_phy_handle_t phy_handle;
|
||||||
|
usb_new_phy_ExpectAnyArgsAndReturn(ESP_OK);
|
||||||
|
usb_new_phy_ReturnThruPtr_handle_ret(&phy_handle);
|
||||||
|
|
||||||
|
// make the HCD port install to pass
|
||||||
|
hcd_install_ExpectAnyArgsAndReturn(ESP_OK);
|
||||||
|
|
||||||
|
// Make the USBH install to fail
|
||||||
|
usbh_install_ExpectAnyArgsAndReturn(ESP_ERR_INVALID_STATE);
|
||||||
|
|
||||||
|
// goto usbh_err: We must uninstall HCD port and PHY
|
||||||
|
hcd_uninstall_ExpectAndReturn(ESP_OK);
|
||||||
|
usb_del_phy_ExpectAndReturn(phy_handle, ESP_OK);
|
||||||
|
|
||||||
|
// Call the DUT function, expect ESP_ERR_INVALID_STATE
|
||||||
|
REQUIRE(ESP_ERR_INVALID_STATE == usb_host_install(&usb_host_config));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Try to install the USB Host driver, with Enum driver Install error, use internal PHY
|
||||||
|
SECTION("Fail to install USB Host - Enum driver install error") {
|
||||||
|
|
||||||
|
// Make the PHY install to pass
|
||||||
|
usb_phy_handle_t phy_handle;
|
||||||
|
usb_new_phy_ExpectAnyArgsAndReturn(ESP_OK);
|
||||||
|
usb_new_phy_ReturnThruPtr_handle_ret(&phy_handle);
|
||||||
|
|
||||||
|
// make the HCD port install to pass
|
||||||
|
hcd_install_ExpectAnyArgsAndReturn(ESP_OK);
|
||||||
|
|
||||||
|
// Make the USBH install to pass
|
||||||
|
usbh_install_ExpectAnyArgsAndReturn(ESP_OK);
|
||||||
|
|
||||||
|
// Make the ENUM Driver to fail
|
||||||
|
enum_install_ExpectAnyArgsAndReturn(ESP_ERR_INVALID_STATE);
|
||||||
|
|
||||||
|
// goto enum_err: We must uninstall USBH, HCD port and PHY
|
||||||
|
usbh_uninstall_ExpectAndReturn(ESP_OK);
|
||||||
|
hcd_uninstall_ExpectAndReturn(ESP_OK);
|
||||||
|
usb_del_phy_ExpectAndReturn(phy_handle, ESP_OK);
|
||||||
|
|
||||||
|
// Call the DUT function, expect ESP_ERR_INVALID_STATE
|
||||||
|
REQUIRE(ESP_ERR_INVALID_STATE == usb_host_install(&usb_host_config));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Try to install the USB Host driver, with Hub driver Install error, use internal PHY
|
||||||
|
SECTION("Fail to install USB Host - Hub driver install error") {
|
||||||
|
|
||||||
|
// Make the PHY install to pass
|
||||||
|
usb_phy_handle_t phy_handle;
|
||||||
|
usb_new_phy_ExpectAnyArgsAndReturn(ESP_OK);
|
||||||
|
usb_new_phy_ReturnThruPtr_handle_ret(&phy_handle);
|
||||||
|
|
||||||
|
// make the HCD port install to pass
|
||||||
|
hcd_install_ExpectAnyArgsAndReturn(ESP_OK);
|
||||||
|
|
||||||
|
// Make the USBH install to pass
|
||||||
|
usbh_install_ExpectAnyArgsAndReturn(ESP_OK);
|
||||||
|
|
||||||
|
// Make the ENUM Driver to pass
|
||||||
|
enum_install_ExpectAnyArgsAndReturn(ESP_OK);
|
||||||
|
|
||||||
|
// Make the HUB Driver to fail
|
||||||
|
hub_install_ExpectAnyArgsAndReturn(ESP_ERR_INVALID_STATE);
|
||||||
|
|
||||||
|
// goto hub_err: We must uninstall Enum driver, USBH, HCD port and PHY
|
||||||
|
enum_uninstall_ExpectAndReturn(ESP_OK);
|
||||||
|
usbh_uninstall_ExpectAndReturn(ESP_OK);
|
||||||
|
hcd_uninstall_ExpectAndReturn(ESP_OK);
|
||||||
|
usb_del_phy_ExpectAndReturn(phy_handle, ESP_OK);
|
||||||
|
|
||||||
|
// Call the DUT function, expect ESP_ERR_INVALID_STATE
|
||||||
|
REQUIRE(ESP_ERR_INVALID_STATE == usb_host_install(&usb_host_config));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Successfully install the USB Host driver
|
||||||
|
SECTION("Successfully install the USB Host driver") {
|
||||||
|
|
||||||
|
// Make the PHY install to pass
|
||||||
|
usb_phy_handle_t phy_handle;
|
||||||
|
usb_new_phy_ExpectAnyArgsAndReturn(ESP_OK);
|
||||||
|
usb_new_phy_ReturnThruPtr_handle_ret(&phy_handle);
|
||||||
|
|
||||||
|
// make the HCD port install to pass
|
||||||
|
hcd_install_ExpectAnyArgsAndReturn(ESP_OK);
|
||||||
|
|
||||||
|
// Make the USBH install to pass
|
||||||
|
usbh_install_ExpectAnyArgsAndReturn(ESP_OK);
|
||||||
|
|
||||||
|
// Make the ENUM Driver to pass
|
||||||
|
enum_install_ExpectAnyArgsAndReturn(ESP_OK);
|
||||||
|
|
||||||
|
// Make the HUB Driver to pass
|
||||||
|
hub_install_ExpectAnyArgsAndReturn(ESP_OK);
|
||||||
|
|
||||||
|
// Make hub_root_start() to pass
|
||||||
|
hub_root_start_ExpectAndReturn(ESP_OK);
|
||||||
|
|
||||||
|
// Call the DUT function, expect ESP_OK
|
||||||
|
REQUIRE(ESP_OK == usb_host_install(&usb_host_config));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// USB Host config is valid, USB Host driver was successfully installed in previous test case
|
||||||
|
GIVEN("USB Host config, USB Host driver previously installed") {
|
||||||
|
|
||||||
|
// Try to install USB Host driver again, after it has been successfully installed
|
||||||
|
SECTION("Fail to install already installed USB Host driver") {
|
||||||
|
|
||||||
|
// Call the DUT function, expect ESP_ERR_INVALID_STATE
|
||||||
|
REQUIRE(ESP_ERR_INVALID_STATE == usb_host_install(&usb_host_config));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
SCENARIO("USB Host post-uninstall")
|
||||||
|
{
|
||||||
|
// USB Host driver successfully installed from previous test case
|
||||||
|
GIVEN("USB Host previously installed") {
|
||||||
|
|
||||||
|
// Uninstall successfully installed USB Host driver
|
||||||
|
SECTION("Successfully uninstall the USB Host driver") {
|
||||||
|
|
||||||
|
// Make the hub_root_stop() to pass
|
||||||
|
hub_root_stop_ExpectAndReturn(ESP_OK);
|
||||||
|
|
||||||
|
// Make uninstalling of all the drivers to pass
|
||||||
|
hub_uninstall_ExpectAndReturn(ESP_OK);
|
||||||
|
enum_uninstall_ExpectAndReturn(ESP_OK);
|
||||||
|
usbh_uninstall_ExpectAndReturn(ESP_OK);
|
||||||
|
hcd_uninstall_ExpectAndReturn(ESP_OK);
|
||||||
|
|
||||||
|
// Make the usb_del_phy() to pass
|
||||||
|
usb_del_phy_ExpectAnyArgsAndReturn(ESP_OK);
|
||||||
|
|
||||||
|
// Call the DUT function, expect ESP_OK
|
||||||
|
REQUIRE(ESP_OK == usb_host_uninstall());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// USB Host driver successfully uninstalled from previous test case
|
||||||
|
GIVEN("USB Host successfully uninstalled") {
|
||||||
|
|
||||||
|
// USB Host successfully uninstalled, try to uninstall it again
|
||||||
|
SECTION("Uninstall already uninstalled USB Host driver") {
|
||||||
|
|
||||||
|
// Call the DUT function, expect ESP_ERR_INVALID_STATE
|
||||||
|
REQUIRE(ESP_ERR_INVALID_STATE == usb_host_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_usb_host_host_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
|
13
components/usb/host_test/usbh_layer_test/CMakeLists.txt
Normal file
13
components/usb/host_test/usbh_layer_test/CMakeLists.txt
Normal file
@@ -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)
|
37
components/usb/host_test/usbh_layer_test/README.md
Normal file
37
components/usb/host_test/usbh_layer_test/README.md
Normal file
@@ -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
|
||||||
|
```
|
12
components/usb/host_test/usbh_layer_test/main/CMakeLists.txt
Normal file
12
components/usb/host_test/usbh_layer_test/main/CMakeLists.txt
Normal file
@@ -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"
|
27
components/usb/host_test/usbh_layer_test/main/test_main.cpp
Normal file
27
components/usb/host_test/usbh_layer_test/main/test_main.cpp
Normal file
@@ -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