-
Notifications
You must be signed in to change notification settings - Fork 21
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(cmock): Enable linux target build to run Cmock tests on class dr…
…ivers - HID, CDC-ACM, UVC class drivers can be build on linux target - Added linux build test and simple Cmock test run in CI
- Loading branch information
1 parent
fbf07ac
commit 74598f7
Showing
20 changed files
with
395 additions
and
18 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
77 changes: 77 additions & 0 deletions
77
host/class/cdc/usb_host_cdc_acm/host_test/main/test_unit_public_api.cpp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
|
||
/* | ||
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD | ||
* | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
#include <stdio.h> | ||
#include <catch2/catch_test_macros.hpp> | ||
|
||
#include "usb/cdc_acm_host.h" | ||
|
||
extern "C" { | ||
#include "Mockusb_host.h" | ||
#include "Mockqueue.h" | ||
#include "Mocktask.h" | ||
#include "Mockidf_additions.h" | ||
#include "Mockportmacro.h" | ||
#include "Mockevent_groups.h" | ||
} | ||
|
||
SCENARIO("CDC-ACM Host install") | ||
{ | ||
// CDC-ACM Host driver config set to nullptr | ||
GIVEN("NO CDC-ACM Host driver config, driver not installed") { | ||
TaskHandle_t task_handle; | ||
int sem; | ||
int event_group; | ||
|
||
// Call cdc_acm_host_install with cdc_acm_host_driver_config set to nullptr, fail to create EventGroup | ||
SECTION("Fail to create EventGroup") { | ||
// Create an EventGroup, return nullptr, so the EventGroup is not created successfully | ||
xEventGroupCreate_ExpectAndReturn(nullptr); | ||
// We should be calling xSemaphoreCreteMutex_ExpectAnyArgsAndRetrun instead of xQueueCreateMutex_ExpectAnyArgsAndReturn | ||
// Because of missing Freertos Mocks | ||
// Create a semaphore, return the semaphore handle (Queue Handle in this scenario), so the semaphore is created successfully | ||
xQueueCreateMutex_ExpectAnyArgsAndReturn(reinterpret_cast<QueueHandle_t>(&sem)); | ||
// Create a task, return pdTRUE, so the task is created successfully | ||
xTaskCreatePinnedToCore_ExpectAnyArgsAndReturn(pdTRUE); | ||
// Return task handle by pointer | ||
xTaskCreatePinnedToCore_ReturnThruPtr_pxCreatedTask(&task_handle); | ||
|
||
// goto err: (xEventGroupCreate returned nullptr), delete the queue and the task | ||
vQueueDelete_Expect(reinterpret_cast<QueueHandle_t>(&sem)); | ||
vTaskDelete_Expect(task_handle); | ||
|
||
// Call the DUT function, expect ESP_ERR_NO_MEM | ||
REQUIRE(ESP_ERR_NO_MEM == cdc_acm_host_install(nullptr)); | ||
} | ||
|
||
// Call cdc_acm_host_install, expect to successfully install the CDC ACM host | ||
SECTION("Successfully install CDC ACM Host") { | ||
// Create an EventGroup, return event group handle, so the EventGroup is created successfully | ||
xEventGroupCreate_ExpectAndReturn(reinterpret_cast<EventGroupHandle_t>(&event_group)); | ||
// We should be calling xSemaphoreCreteMutex_ExpectAnyArgsAndRetrun instead of xQueueCreateMutex_ExpectAnyArgsAndReturn | ||
// Because of missing Freertos Mocks | ||
// Create a semaphore, return the semaphore handle (Queue Handle in this scenario), so the semaphore is created successfully | ||
xQueueCreateMutex_ExpectAnyArgsAndReturn(reinterpret_cast<QueueHandle_t>(&sem)); | ||
// Create a task, return pdTRUE, so the task is created successfully | ||
vPortEnterCritical_Expect(); | ||
vPortExitCritical_Expect(); | ||
xTaskCreatePinnedToCore_ExpectAnyArgsAndReturn(pdTRUE); | ||
// Return task handle by pointer | ||
xTaskCreatePinnedToCore_ReturnThruPtr_pxCreatedTask(&task_handle); | ||
|
||
// Call mocked function from USB Host | ||
// return ESP_OK, so the client si registered successfully | ||
usb_host_client_register_ExpectAnyArgsAndReturn(ESP_OK); | ||
|
||
// Resume the task | ||
vTaskResume_Expect(task_handle); | ||
|
||
// Call the DUT Function, expect ESP_OK | ||
REQUIRE(ESP_OK == cdc_acm_host_install(nullptr)); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
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/" | ||
"$ENV{IDF_PATH}/tools/mocks/freertos/" | ||
) | ||
|
||
project(host_test_usb_hid) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
| Supported Targets | Linux | | ||
| ----------------- | ----- | | ||
|
||
# Description | ||
|
||
This directory contains test code for `USB Host HID` driver. Namely: | ||
* Simple public API call with mocked USB component to test Linux build and Cmock run for this class driver | ||
|
||
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. | ||
|
||
# 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: | ||
|
||
``` | ||
./build/host_test_usb_hid.elf | ||
``` | ||
|
||
The test executable have some options provided by the test framework. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
idf_component_register(SRC_DIRS . | ||
REQUIRES cmock usb | ||
INCLUDE_DIRS . | ||
WHOLE_ARCHIVE) | ||
|
||
# Currently 'main' for IDF_TARGET=linux is defined in freertos component. | ||
# Since we are using a freertos mock here, need to let Catch2 provide 'main'. | ||
target_link_libraries(${COMPONENT_LIB} PRIVATE Catch2WithMain) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
dependencies: | ||
espressif/catch2: "^3.4.0" | ||
usb_host_hid: | ||
version: "*" | ||
override_path: "../../" |
145 changes: 145 additions & 0 deletions
145
host/class/hid/usb_host_hid/host_test/main/test_unit_public_api.cpp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,145 @@ | ||
/* | ||
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD | ||
* | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
#include <stdio.h> | ||
#include <catch2/catch_test_macros.hpp> | ||
|
||
#include "usb/hid_host.h" | ||
#include "usb/hid.h" | ||
|
||
extern "C" { | ||
#include "Mockusb_host.h" | ||
#include "Mockqueue.h" | ||
#include "Mocktask.h" | ||
#include "Mockidf_additions.h" | ||
#include "Mockportmacro.h" | ||
} | ||
|
||
SCENARIO("HID Host install") | ||
{ | ||
hid_host_driver_config_t hid_host_driver_config = { | ||
.create_background_task = true, | ||
.task_priority = 5, | ||
.stack_size = 4096, | ||
.core_id = 0, | ||
.callback = (reinterpret_cast<hid_host_driver_event_cb_t>(0xdeadbeef)), | ||
.callback_arg = nullptr | ||
}; | ||
|
||
// HID Host driver config set to nullptr | ||
GIVEN("NO HID Host driver config, driver not already installed") { | ||
|
||
// Call hid_host_install with hid_host_driver_config set to nullptr | ||
SECTION("Config is nullptr") { | ||
REQUIRE(ESP_ERR_INVALID_ARG == hid_host_install(nullptr)); | ||
} | ||
} | ||
|
||
// HID Host driver config set to config from HID Host example, but without callback | ||
GIVEN("Minimal HID Host driver config, driver not already installed") { | ||
hid_host_driver_config.callback = nullptr; | ||
|
||
SECTION("Config error: no callback") { | ||
// Call the DUT function, expect ESP_ERR_INVALID_ARG | ||
REQUIRE(ESP_ERR_INVALID_ARG == hid_host_install(&hid_host_driver_config)); | ||
} | ||
|
||
SECTION("Config error: stack size is 0") { | ||
hid_host_driver_config.stack_size = 0; | ||
// Call the DUT function, expect ESP_ERR_INVALID_ARG | ||
REQUIRE(ESP_ERR_INVALID_ARG == hid_host_install(&hid_host_driver_config)); | ||
} | ||
|
||
SECTION("Config error: task priority is 0") { | ||
hid_host_driver_config.task_priority = 0; | ||
// Call the DUT function, expect ESP_ERR_INVALID_ARG | ||
REQUIRE(ESP_ERR_INVALID_ARG == hid_host_install(&hid_host_driver_config)); | ||
} | ||
} | ||
|
||
// HID Host driver config set to config from HID Host example | ||
GIVEN("Full HID Host config, driver not already installed") { | ||
int mtx; | ||
|
||
// Install error: failed to create semaphore | ||
SECTION("Install error: unable to create semaphore") { | ||
// We must call xQueueGenericCreate_ExpectAnyArgsAndReturn instead of xSemaphoreCreateBinary_ExpectAnyArgsAndReturn | ||
// Because of missing Freertos Mocks | ||
// Create a semaphore, return nullptr, so the semaphore is not created successfully | ||
xQueueGenericCreate_ExpectAnyArgsAndReturn(nullptr); | ||
|
||
// Call the DUT function, expect ESP_ERR_NO_MEM | ||
REQUIRE(ESP_ERR_NO_MEM == hid_host_install(&hid_host_driver_config)); | ||
} | ||
|
||
// Unable to register client: Invalid state, goto fail | ||
SECTION("Client register not successful: goto fail") { | ||
// We must call xQueueGenericCreate_ExpectAnyArgsAndReturn instead of xSemaphoreCreateBinary_ExpectAnyArgsAndReturn | ||
// Because of missing Freertos Mocks | ||
// Create a semaphore, return the semaphore handle (Queue Handle in this scenario), so the semaphore is created successfully | ||
xQueueGenericCreate_ExpectAnyArgsAndReturn(reinterpret_cast<QueueHandle_t>(&mtx)); | ||
// Register a client, return ESP_ERR_INVALID_STATE, so the client is not registered successfully | ||
usb_host_client_register_ExpectAnyArgsAndReturn(ESP_ERR_INVALID_STATE); | ||
|
||
// goto fail: delete the semaphore (Queue in this scenario) | ||
vQueueDelete_Expect(reinterpret_cast<QueueHandle_t>(&mtx)); | ||
|
||
// Call the DUT function, expect ESP_ERR_INVALID_STATE | ||
REQUIRE(ESP_ERR_INVALID_STATE == hid_host_install(&hid_host_driver_config)); | ||
} | ||
|
||
SECTION("Client register successful: create background task fail") { | ||
usb_host_client_handle_t client_handle; | ||
|
||
// Create a semaphore, return the semaphore handle (Queue Handle in this scenario), so the semaphore is created successfully | ||
xQueueGenericCreate_ExpectAnyArgsAndReturn(reinterpret_cast<QueueHandle_t>(&mtx)); | ||
// Register a client, return ESP_OK, so the client is registered successfully | ||
usb_host_client_register_ExpectAnyArgsAndReturn(ESP_OK); | ||
// Fill the pointer to the client_handle, which is used in goto fail, to deregister the client | ||
usb_host_client_register_ReturnThruPtr_client_hdl_ret(&client_handle); | ||
|
||
// Create a background task, return pdFALSE, so the task in not created successfully | ||
vPortEnterCritical_Expect(); | ||
vPortExitCritical_Expect(); | ||
xTaskCreatePinnedToCore_ExpectAnyArgsAndReturn(pdFALSE); | ||
|
||
// goto fail: delete the semaphore and deregister the client | ||
// usb_host_client_deregister is not being checked for the return value !! Consider adding it to the host driver | ||
usb_host_client_deregister_ExpectAndReturn(client_handle, ESP_OK); | ||
// Delete the semaphore (Queue in this scenario) | ||
vQueueDelete_Expect(reinterpret_cast<QueueHandle_t>(&mtx)); | ||
|
||
// Call the DUT function, expect ESP_ERR_NO_MEM | ||
REQUIRE(ESP_ERR_NO_MEM == hid_host_install(&hid_host_driver_config)); | ||
} | ||
|
||
// Call hid_host_install and expect successful installation | ||
SECTION("Client register successful: hid_host_install successful") { | ||
// Create semaphore, return semaphore handle (Queue Handle in this scenario), so the semaphore is created successfully | ||
xQueueGenericCreate_ExpectAnyArgsAndReturn(reinterpret_cast<QueueHandle_t>(&mtx)); | ||
// return ESP_OK, so the client is registered successfully | ||
usb_host_client_register_ExpectAnyArgsAndReturn(ESP_OK); | ||
|
||
// Create a background task successfully by returning pdTRUE | ||
vPortEnterCritical_Expect(); | ||
vPortExitCritical_Expect(); | ||
xTaskCreatePinnedToCore_ExpectAnyArgsAndReturn(pdTRUE); | ||
|
||
// Call the DUT function, expect ESP_OK | ||
REQUIRE(ESP_OK == hid_host_install(&hid_host_driver_config)); | ||
} | ||
} | ||
|
||
// HID Host driver config set to config from HID Host example | ||
GIVEN("Full HID Host config, driver already installed") { | ||
|
||
// Driver is already installed | ||
SECTION("Install error: driver already installed") { | ||
// Call the DUT function again to get the ESP_ERR_INVALID_STATE error | ||
REQUIRE(ESP_ERR_INVALID_STATE == hid_host_install(&hid_host_driver_config)); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
# This file was generated using idf.py save-defconfig. It can be edited manually. | ||
# Espressif IoT Development Framework (ESP-IDF) 5.4.0 Project Minimal Configuration | ||
# | ||
CONFIG_IDF_TARGET="linux" | ||
CONFIG_COMPILER_CXX_EXCEPTIONS=y | ||
CONFIG_ESP_MAIN_TASK_STACK_SIZE=12000 | ||
CONFIG_FREERTOS_HZ=1000 | ||
CONFIG_UNITY_ENABLE_IDF_TEST_RUNNER=n |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
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/" | ||
"$ENV{IDF_PATH}/tools/mocks/freertos/" | ||
) | ||
|
||
project(host_test_usb_uvc) |
Oops, something went wrong.