Browse Source

[mocks]: freertos mock

[esp_event]: added preliminary host-based tests
Jakob Hasse 4 years ago
parent
commit
c9984faaef

+ 7 - 0
.gitlab/ci/host-test.yml

@@ -349,6 +349,13 @@ test_log:
     - idf.py build
     - build/test_log_host.elf
 
+test_esp_event:
+  extends: .host_test_template
+  script:
+    - cd ${IDF_PATH}/components/esp_event/host_test/esp_event_unit_test
+    - idf.py build
+    - build/test_esp_event_host.elf
+
 test_eh_frame_parser:
   extends: .host_test_template
   script:

+ 22 - 10
components/esp_event/CMakeLists.txt

@@ -1,17 +1,29 @@
-if(IDF_TARGET STREQUAL "esp32")
-    set(priv_requires esp_eth esp_timer)
+idf_build_get_property(target IDF_TARGET)
+set(priv_include_dirs "private_include")
+set(priv_requires "")
+set(requires "log" "esp_common" "freertos")
+set(srcs "default_event_loop.c"
+         "esp_event.c"
+         "esp_event_private.c")
+
+if(${target} STREQUAL "linux")
+    list(APPEND requires "linux")
+    # Temporary fix until esp_system is available for linux, too
+    list(APPEND priv_include_dirs "$ENV{IDF_PATH}/mocks/esp_system/include")
 else()
-    set(priv_requires esp_timer)
+    list(APPEND requires "esp_netif")
+    list(APPEND srcs "event_loop_legacy.c" "event_send.c")
+    if(${target} STREQUAL "esp32")
+        list(APPEND priv_requires esp_eth esp_timer)
+    else()
+        list(APPEND priv_requires esp_timer)
+    endif()
 endif()
 
-idf_component_register(SRCS "default_event_loop.c"
-                            "esp_event.c"
-                            "esp_event_private.c"
-                            "event_loop_legacy.c"
-                            "event_send.c"
+idf_component_register(SRCS ${srcs}
                     INCLUDE_DIRS "include"
-                    PRIV_INCLUDE_DIRS "private_include"
-                    REQUIRES log esp_netif
+                    PRIV_INCLUDE_DIRS ${priv_include_dirs}
+                    REQUIRES ${requires}
                     PRIV_REQUIRES ${priv_requires}
                     LDFRAGMENTS linker.lf)
 

+ 2 - 1
components/esp_event/default_event_loop.c

@@ -142,8 +142,9 @@ esp_err_t esp_event_loop_delete_default(void)
     return ESP_OK;
 }
 
-
+#if !CONFIG_IDF_TARGET_LINUX
 /* Include the code to forward legacy system_event_t events to the this default
  * event loop.
  */
 #include "event_send_compat.inc"
+#endif

+ 8 - 0
components/esp_event/host_test/esp_event_unit_test/CMakeLists.txt

@@ -0,0 +1,8 @@
+cmake_minimum_required(VERSION 3.5)
+
+include($ENV{IDF_PATH}/tools/cmake/project.cmake)
+set(COMPONENTS main)
+
+idf_build_set_property(COMPILE_DEFINITIONS "-DNO_DEBUG_STORAGE" APPEND)
+list(APPEND EXTRA_COMPONENT_DIRS "$ENV{IDF_PATH}/mocks/freertos/")
+project(test_esp_event_host)

+ 3 - 0
components/esp_event/host_test/esp_event_unit_test/main/CMakeLists.txt

@@ -0,0 +1,3 @@
+idf_component_register(SRCS "esp_event_test.cpp"
+                    INCLUDE_DIRS "../../" $ENV{IDF_PATH}/tools/catch
+                    REQUIRES esp_event cmock)

+ 152 - 0
components/esp_event/host_test/esp_event_unit_test/main/esp_event_test.cpp

@@ -0,0 +1,152 @@
+/* ESP Event Host-Based Test
+
+   This code is in the Public Domain (or CC0 licensed, at your option.)
+
+   Unless required by applicable law or agreed to in writing, this
+   software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
+   CONDITIONS OF ANY KIND, either express or implied.
+*/
+
+#define CATCH_CONFIG_MAIN
+
+#include <stdio.h>
+#include "esp_event.h"
+
+#include "catch.hpp"
+
+#include "fixtures.hpp"
+
+extern "C" {
+#include "Mocktask.h"
+#include "Mockqueue.h"
+}
+
+
+namespace {
+
+const uint32_t QUEUE_SIZE = 32;
+
+static UBaseType_t s_test_priority;
+
+static esp_event_loop_args_t test_event_get_default_loop_args(void)
+{
+    esp_event_loop_args_t loop_config = {
+        .queue_size = QUEUE_SIZE, // TODO: CONFIG_ESP_SYSTEM_EVENT_QUEUE_SIZE from esp_system should be used
+        .task_name = "loop",
+        .task_priority = s_test_priority,
+        .task_stack_size = 2048,
+        .task_core_id = 0
+    };
+
+    return loop_config;
+}
+
+void dummy_handler(void* event_handler_arg, esp_event_base_t event_base, int32_t event_id, void* event_data) { }
+
+}
+
+// TODO: IDF-2693, function definition just to satisfy linker, implement esp_common instead
+const char *esp_err_to_name(esp_err_t code) {
+    return "test";
+}
+
+TEST_CASE("create an event loop with any NULL argument fails")
+{
+    MockQueue queue(CreateAnd::IGNORE);
+    MockMutex sem(CreateAnd::IGNORE);
+    MockTask task(CreateAnd::IGNORE);
+    esp_event_loop_handle_t loop; // with dedicated task
+    esp_event_loop_args_t loop_args = test_event_get_default_loop_args();
+    CHECK(ESP_ERR_INVALID_ARG == esp_event_loop_create(NULL, &loop));
+    CHECK(ESP_ERR_INVALID_ARG == esp_event_loop_create(&loop_args, NULL));
+}
+
+TEST_CASE("test esp_event_loop_create create_queue_fails(void)")
+{
+    MockQueue queue(CreateAnd::FAIL);
+    MockMutex sem(CreateAnd::IGNORE);
+    MockTask task(CreateAnd::IGNORE);
+    esp_event_loop_handle_t loop;
+
+    esp_event_loop_args_t loop_args = test_event_get_default_loop_args();
+
+    CHECK(ESP_ERR_NO_MEM == esp_event_loop_create(&loop_args, &loop));
+}
+
+TEST_CASE("test esp_event_loop_create create_mutex_fails(void)")
+{
+    MockQueue queue(CreateAnd::IGNORE);
+    MockMutex sem(CreateAnd::FAIL);
+    MockTask task(CreateAnd::IGNORE);
+    esp_event_loop_handle_t loop;
+
+    esp_event_loop_args_t loop_args = test_event_get_default_loop_args();
+
+    CHECK(ESP_ERR_NO_MEM == esp_event_loop_create(&loop_args, &loop));
+}
+
+TEST_CASE("test esp_event_loop_create create_task_fails(void)")
+{
+    MockQueue queue(CreateAnd::IGNORE);
+    MockMutex sem(CreateAnd::IGNORE);
+    MockTask task(CreateAnd::FAIL);
+    esp_event_loop_handle_t loop;
+
+    esp_event_loop_args_t loop_args = test_event_get_default_loop_args();
+
+    CHECK(ESP_FAIL == esp_event_loop_create(&loop_args, &loop));
+}
+
+TEST_CASE("test esp_event_loop_create no_task(void)")
+{
+    MockQueue queue(CreateAnd::IGNORE);
+    MockMutex sem(CreateAnd::IGNORE);
+    xQueueTakeMutexRecursive_IgnoreAndReturn(0);
+    xQueueGiveMutexRecursive_IgnoreAndReturn(0);
+    xQueueReceive_IgnoreAndReturn(0);
+    esp_event_loop_handle_t loop = nullptr;
+
+    esp_event_loop_args_t loop_args = test_event_get_default_loop_args();
+    loop_args.task_name = nullptr;
+
+    CHECK(ESP_OK == esp_event_loop_create(&loop_args, &loop));
+    CHECK(loop != nullptr);
+
+    CHECK(ESP_OK == esp_event_loop_delete(loop));
+
+    xQueueReceive_StopIgnore();
+    xQueueTakeMutexRecursive_StopIgnore();
+    xQueueGiveMutexRecursive_StopIgnore();
+}
+
+TEST_CASE("test esp_event_loop_create with_task(void)")
+{
+    MockQueue queue(CreateAnd::IGNORE);
+    MockMutex sem(CreateAnd::IGNORE);
+    MockTask task(CreateAnd::SUCCEED);
+    xQueueTakeMutexRecursive_IgnoreAndReturn(0);
+    xQueueGiveMutexRecursive_IgnoreAndReturn(0);
+    xQueueReceive_IgnoreAndReturn(0);
+    esp_event_loop_handle_t loop = nullptr;
+
+    esp_event_loop_args_t loop_args = test_event_get_default_loop_args();
+    loop_args.task_name = "test";
+
+    CHECK(ESP_OK == esp_event_loop_create(&loop_args, &loop));
+    CHECK(loop != nullptr);
+
+    CHECK(ESP_OK == esp_event_loop_delete(loop));
+
+    xQueueReceive_StopIgnore();
+    xQueueTakeMutexRecursive_StopIgnore();
+    xQueueGiveMutexRecursive_StopIgnore();
+}
+
+TEST_CASE("registering with ANY_BASE but specific ID fails") {
+    esp_event_loop_handle_t loop = reinterpret_cast<esp_event_loop_handle_t>(1);
+    CHECK(esp_event_handler_register_with(loop,
+            ESP_EVENT_ANY_BASE,
+            47,
+            dummy_handler,
+            nullptr) == ESP_ERR_INVALID_ARG);
+}

+ 4 - 0
components/esp_event/host_test/esp_event_unit_test/sdkconfig.defaults

@@ -0,0 +1,4 @@
+CONFIG_UNITY_ENABLE_IDF_TEST_RUNNER=n
+CONFIG_IDF_TARGET="linux"
+CONFIG_CXX_EXCEPTIONS=y
+CONFIG_LOG_DEFAULT_LEVEL_NONE=y

+ 148 - 0
components/esp_event/host_test/fixtures.hpp

@@ -0,0 +1,148 @@
+/* ESP Event Fixtures
+
+   This code is in the Public Domain (or CC0 licensed, at your option.)
+
+   Unless required by applicable law or agreed to in writing, this
+   software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
+   CONDITIONS OF ANY KIND, either express or implied.
+*/
+
+#include "esp_event.h"
+
+#include "catch.hpp"
+
+extern "C" {
+#include "Mocktask.h"
+#include "Mockqueue.h"
+}
+
+/**
+ * Exception which is thrown if there is some internal cmock error which results in a
+ * longjump to the location of a TEST_PROTECT() call.
+ *
+ * @note This is a temporary solution until there is a better integration of CATCH into CMock.
+ *      Note also that usually there will be a segfault when cmock fails a second time.
+ *      This means paying attention to the first error message is crucial for removing errors.
+ */
+class CMockException : public std::exception {
+public:
+    virtual ~CMockException() { }
+
+    /**
+     * @return A reminder to look at the actual cmock log.
+     */
+    virtual const char *what() const noexcept
+    {
+        return "CMock encountered an error. Look at the CMock log";
+    }
+};
+
+/**
+ * Helper macro for setting up a test protect call for CMock.
+ *
+ * This macro should be used at the beginning of any test cases
+ * which use generated CMock mock functions.
+ * This is necessary because CMock uses longjmp which screws up C++ stacks and
+ * also the CATCH mechanisms.
+ *
+ * @note This is a temporary solution until there is a better integration of CATCH into CMock.
+ *      Note also that usually there will be a segfault when cmock fails a second time.
+ *      This means paying attention to the first error message is crucial for removing errors.
+ */
+#define CMOCK_SETUP() \
+    do { \
+        if (!TEST_PROTECT()) {      \
+            throw CMockException(); \
+        }                           \
+    } \
+    while (0)
+
+struct CMockFix {
+    CMockFix()
+    {
+        CMOCK_SETUP();
+    }
+
+    ~CMockFix()
+    {
+        Mocktask_Verify();
+        Mockqueue_Verify();
+    }
+};
+
+enum class CreateAnd {
+    FAIL,
+    SUCCEED,
+    IGNORE
+};
+
+struct MockQueue : public CMockFix {
+    MockQueue (CreateAnd flags) : queue(reinterpret_cast<QueueHandle_t>(0xdeadbeef))
+    {
+        if (flags == CreateAnd::FAIL) {
+            xQueueGenericCreate_ExpectAnyArgsAndReturn(nullptr);
+        } else if (flags == CreateAnd::IGNORE) {
+            xQueueGenericCreate_IgnoreAndReturn(queue);
+            vQueueDelete_Ignore();
+        } else {
+            xQueueGenericCreate_ExpectAnyArgsAndReturn(queue);
+            vQueueDelete_Expect(queue);
+        }
+    }
+
+    ~MockQueue()
+    {
+        xQueueGenericCreate_StopIgnore();
+        vQueueDelete_StopIgnore();
+    }
+
+    QueueHandle_t queue;
+};
+
+struct MockMutex : public CMockFix {
+    MockMutex (CreateAnd flags) : sem(reinterpret_cast<QueueHandle_t>(0xdeadbeef))
+    {
+        if (flags == CreateAnd::FAIL) {
+            xQueueCreateMutex_ExpectAnyArgsAndReturn(nullptr);
+        } else if (flags == CreateAnd::IGNORE) {
+            xQueueCreateMutex_IgnoreAndReturn(sem);
+            vQueueDelete_Ignore();
+        } else {
+            xQueueCreateMutex_ExpectAnyArgsAndReturn(sem);
+            vQueueDelete_Expect(sem);
+        }
+    }
+
+    ~MockMutex()
+    {
+        xQueueCreateMutex_StopIgnore();
+        vQueueDelete_StopIgnore();
+    }
+
+    QueueHandle_t sem;
+};
+
+struct MockTask : public CMockFix {
+    MockTask (CreateAnd flags) : task((void*) 1)
+    {
+        if (flags == CreateAnd::FAIL) {
+            xTaskCreatePinnedToCore_ExpectAnyArgsAndReturn(pdFALSE);
+        } else if (flags == CreateAnd::IGNORE) {
+            xTaskCreatePinnedToCore_IgnoreAndReturn(pdTRUE);
+            xTaskCreatePinnedToCore_ReturnThruPtr_pvCreatedTask(&task);
+            vTaskDelete_Ignore();
+        } else {
+            xTaskCreatePinnedToCore_ExpectAnyArgsAndReturn(pdTRUE);
+            xTaskCreatePinnedToCore_ReturnThruPtr_pvCreatedTask(&task);
+            vTaskDelete_Expect(task);
+        }
+    }
+
+    ~MockTask()
+    {
+        xTaskCreatePinnedToCore_StopIgnore();
+        vTaskDelete_StopIgnore();
+    }
+
+    TaskHandle_t task;
+};

+ 3 - 0
components/esp_event/include/esp_event.h

@@ -23,7 +23,10 @@
 #include "freertos/semphr.h"
 
 #include "esp_event_base.h"
+// Legacy event loop not implemented on Linux target
+#if !CONFIG_IDF_TARGET_LINUX
 #include "esp_event_legacy.h"
+#endif
 
 #ifdef __cplusplus
 extern "C" {

+ 2 - 0
components/esp_event/private_include/esp_event_internal.h

@@ -15,6 +15,8 @@
 #ifndef ESP_EVENT_INTERNAL_H_
 #define ESP_EVENT_INTERNAL_H_
 
+#include "sys/queue.h"
+#include <stdbool.h>
 #include "esp_event.h"
 #include "stdatomic.h"
 

+ 1 - 0
components/esp_event/private_include/esp_event_private.h

@@ -15,6 +15,7 @@
 #ifndef ESP_EVENT_PRIVATE_H_
 #define ESP_EVENT_PRIVATE_H_
 
+#include <stdbool.h>
 #include "esp_event.h"
 
 #ifdef __cplusplus

+ 0 - 8
components/esp_event/test/test_event.c

@@ -306,14 +306,6 @@ static void test_teardown(void)
 #define TIMER_SCALE           (TIMER_BASE_CLK / TIMER_DIVIDER)  // convert counter value to seconds
 #define TIMER_INTERVAL0_SEC   (2.0) // sample test interval for the first timer
 
-TEST_CASE("create and event loop with any NULL argument fails", "[event]")
-{
-    esp_event_loop_handle_t loop; // with dedicated task
-    esp_event_loop_args_t loop_args = test_event_get_default_loop_args();
-    TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, esp_event_loop_create(NULL, &loop));
-    TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, esp_event_loop_create(&loop_args, NULL));
-}
-
 TEST_CASE("can create and delete event loops", "[event]")
 {
     /* this test aims to verify that:

+ 5 - 1
components/freertos/include/freertos/FreeRTOSConfig.h

@@ -74,7 +74,9 @@
 // The arch-specific FreeRTOSConfig.h in port/<arch>/include.
 #include_next "freertos/FreeRTOSConfig.h"
 
-#if !(defined(FREERTOS_CONFIG_XTENSA_H) || defined(FREERTOS_CONFIG_RISCV_H))
+#if !(defined(FREERTOS_CONFIG_XTENSA_H) \
+        || defined(FREERTOS_CONFIG_RISCV_H) \
+        || defined(FREERTOS_CONFIG_LINUX_H))
 #error "Needs architecture-speific FreeRTOSConfig.h!"
 #endif
 
@@ -244,7 +246,9 @@
    kept at 1. */
 #define configKERNEL_INTERRUPT_PRIORITY                 1
 
+#if !CONFIG_IDF_TARGET_LINUX
 #define configUSE_NEWLIB_REENTRANT                      1
+#endif
 
 #define configSUPPORT_DYNAMIC_ALLOCATION                1
 #define configSUPPORT_STATIC_ALLOCATION                 1

+ 75 - 0
components/freertos/port/linux/include/freertos/FreeRTOSConfig.h

@@ -0,0 +1,75 @@
+/*
+    FreeRTOS V10 - Copyright (C) 2021 Real Time Engineers Ltd.
+    All rights reserved
+
+    VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
+
+    This file is part of the FreeRTOS distribution.
+
+    FreeRTOS is free software; you can redistribute it and/or modify it under
+    the terms of the GNU General Public License (version 2) as published by the
+    Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception.
+
+	***************************************************************************
+    >>!   NOTE: The modification to the GPL is included to allow you to     !<<
+    >>!   distribute a combined work that includes FreeRTOS without being   !<<
+    >>!   obliged to provide the source code for proprietary components     !<<
+    >>!   outside of the FreeRTOS kernel.                                   !<<
+	***************************************************************************
+
+    FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY
+    WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+    FOR A PARTICULAR PURPOSE.  Full license text is available on the following
+    link: http://www.freertos.org/a00114.html
+
+    ***************************************************************************
+     *                                                                       *
+     *    FreeRTOS provides completely free yet professionally developed,    *
+     *    robust, strictly quality controlled, supported, and cross          *
+     *    platform software that is more than just the market leader, it     *
+     *    is the industry's de facto standard.                               *
+     *                                                                       *
+     *    Help yourself get started quickly while simultaneously helping     *
+     *    to support the FreeRTOS project by purchasing a FreeRTOS           *
+     *    tutorial book, reference manual, or both:                          *
+     *    http://www.FreeRTOS.org/Documentation                              *
+     *                                                                       *
+    ***************************************************************************
+
+    http://www.FreeRTOS.org/FAQHelp.html - Having a problem?  Start by reading
+	the FAQ page "My application does not run, what could be wrong?".  Have you
+	defined configASSERT()?
+
+	http://www.FreeRTOS.org/support - In return for receiving this top quality
+	embedded software for free we request you assist our global community by
+	participating in the support forum.
+
+	http://www.FreeRTOS.org/training - Investing in training allows your team to
+	be as productive as possible as early as possible.  Now you can receive
+	FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers
+	Ltd, and the world's leading authority on the world's leading RTOS.
+
+    http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
+    including FreeRTOS+Trace - an indispensable productivity tool, a DOS
+    compatible FAT file system, and our tiny thread aware UDP/IP stack.
+
+    http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.
+    Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.
+
+    http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High
+    Integrity Systems ltd. to sell under the OpenRTOS brand.  Low cost OpenRTOS
+    licenses offer ticketed support, indemnification and commercial middleware.
+
+    http://www.SafeRTOS.com - High Integrity Systems also provide a safety
+    engineered and independently SIL3 certified version for use in safety and
+    mission critical applications that require provable dependability.
+
+    1 tab == 4 spaces!
+*/
+
+#ifndef FREERTOS_CONFIG_LINUX_H
+#define FREERTOS_CONFIG_LINUX_H
+
+// This file is included in the common FreeRTOSConfig.h.
+
+#endif // FREERTOS_CONFIG_LINUX_H

+ 32 - 0
components/freertos/port/linux/include/freertos/portmacro.h

@@ -0,0 +1,32 @@
+#pragma once
+
+#include "esp_attr.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define portBYTE_ALIGNMENT			16
+
+/* Type definitions. */
+#define portCHAR		uint8_t
+#define portFLOAT		float
+#define portDOUBLE		double
+#define portLONG		int32_t
+#define portSHORT		int16_t
+#define portSTACK_TYPE	uint8_t
+#define portBASE_TYPE	int
+// interrupt module will mask interrupt with priority less than threshold
+#define RVHAL_EXCM_LEVEL    4
+
+typedef portSTACK_TYPE			StackType_t;
+typedef portBASE_TYPE			BaseType_t;
+typedef unsigned portBASE_TYPE	UBaseType_t;
+typedef uint32_t TickType_t;
+#define portMAX_DELAY ( TickType_t ) 0xffffffffUL
+
+typedef int portMUX_TYPE;
+
+#ifdef __cplusplus
+}
+#endif

+ 7 - 0
components/linux/CMakeLists.txt

@@ -0,0 +1,7 @@
+idf_build_get_property(target IDF_TARGET)
+if(NOT "${target}" STREQUAL "linux")
+    return()
+endif()
+
+idf_component_register(INCLUDE_DIRS include
+                       REQUIRED_IDF_TARGETS linux)

+ 1 - 0
components/linux/include/sys/queue.h

@@ -0,0 +1 @@
+#include "bsd/sys/queue.h"

+ 6 - 0
examples/cxx/experimental/experimental_cpp_component/host_test/gpio/CMakeLists.txt

@@ -4,6 +4,12 @@ include($ENV{IDF_PATH}/tools/cmake/project.cmake)
 set(COMPONENTS main)
 
 idf_build_set_property(COMPILE_DEFINITIONS "-DNO_DEBUG_STORAGE" APPEND)
+
+# Overriding components which should be mocked
 list(APPEND EXTRA_COMPONENT_DIRS "$ENV{IDF_PATH}/mocks/driver/")
+list(APPEND EXTRA_COMPONENT_DIRS "$ENV{IDF_PATH}/mocks/freertos/")
+
+# Including experimental component here because it's outside IDF's main component directory
 list(APPEND EXTRA_COMPONENT_DIRS "$ENV{IDF_PATH}/examples/cxx/experimental/experimental_cpp_component/")
+
 project(test_gpio_cxx_host)

+ 1 - 1
mocks/driver/CMakeLists.txt

@@ -9,11 +9,11 @@ idf_component_get_property(original_driver_dir driver COMPONENT_OVERRIDEN_DIR)
 set(include_dirs
     "${original_driver_dir}/include"
     "${original_driver_dir}/include/driver"
-    "${CMAKE_CURRENT_SOURCE_DIR}/../freertos/include"
     "${CMAKE_CURRENT_SOURCE_DIR}/../hal/include"
     "${CMAKE_CURRENT_SOURCE_DIR}/../esp_hw_support/include")
 
 idf_component_mock(INCLUDE_DIRS ${include_dirs}
+    REQUIRES freertos
     MOCK_HEADER_FILES
     ${original_driver_dir}/include/driver/spi_master.h
     ${original_driver_dir}/include/driver/spi_common.h

+ 56 - 0
mocks/esp_system/include/esp_task.h

@@ -0,0 +1,56 @@
+// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+/* Notes:
+ * 1. Put all task priority and stack size definition in this file
+ * 2. If the task priority is less than 10, use ESP_TASK_PRIO_MIN + X style,
+ *    otherwise use ESP_TASK_PRIO_MAX - X style
+ * 3. If this is a daemon task, the macro prefix is ESP_TASKD_, otherwise
+ *    it's ESP_TASK_
+ * 4. If the configMAX_PRIORITIES is modified, please make all priority are
+ *    greater than 0
+ * 5. Make sure esp_task.h is consistent between wifi lib and idf
+ * 6. If changing system task priorities, please check the values documented in /api-guides/performance/speed.rst
+ * are up to date
+ */
+
+#ifndef _ESP_TASK_H_
+#define _ESP_TASK_H_
+
+#include "sdkconfig.h"
+
+#define ESP_TASK_PRIO_MAX (configMAX_PRIORITIES)
+#define ESP_TASK_PRIO_MIN (0)
+
+/* Temporary define until system is properly buildable on Linux */
+#define CONFIG_ESP_SYSTEM_EVENT_QUEUE_SIZE 10
+
+/* Bt contoller Task */
+/* controller */
+#define ESP_TASK_BT_CONTROLLER_PRIO   (ESP_TASK_PRIO_MAX - 2)
+#ifdef CONFIG_NEWLIB_NANO_FORMAT
+#define TASK_EXTRA_STACK_SIZE      (0)
+#else
+#define TASK_EXTRA_STACK_SIZE      (512)
+#endif
+
+#define BT_TASK_EXTRA_STACK_SIZE      TASK_EXTRA_STACK_SIZE
+#define ESP_TASK_BT_CONTROLLER_STACK  (3584 + TASK_EXTRA_STACK_SIZE)
+
+
+/* idf task */
+#define ESP_TASKD_EVENT_PRIO          (ESP_TASK_PRIO_MAX - 5)
+#define ESP_TASKD_EVENT_STACK         (2048)
+
+#endif

+ 16 - 0
mocks/freertos/CMakeLists.txt

@@ -0,0 +1,16 @@
+# NOTE: This kind of mocking currently works on Linux targets only.
+#       On Espressif chips, too many dependencies are missing at the moment.
+message(STATUS "building FREERTOS MOCKS (only task and queue)")
+
+idf_component_get_property(original_freertos_dir freertos COMPONENT_OVERRIDEN_DIR)
+
+set(include_dirs
+    "${original_freertos_dir}/include"
+    "${original_freertos_dir}/include/freertos" # this is due to the way includes are generated in CMock
+    "${original_freertos_dir}/port/linux/include")
+
+idf_component_mock(INCLUDE_DIRS ${include_dirs}
+    REQUIRES esp_common
+    MOCK_HEADER_FILES
+    ${original_freertos_dir}/include/freertos/task.h
+    ${original_freertos_dir}/include/freertos/queue.h)

+ 13 - 0
mocks/freertos/Kconfig

@@ -0,0 +1,13 @@
+menu "FreeRTOS"
+    config FREERTOS_MAX_TASK_NAME_LEN
+        int "Maximum task name length"
+        range 1 256
+        default 16
+        help
+            Changes the maximum task name length. Each task allocated will
+            include this many bytes for a task name. Using a shorter value
+            saves a small amount of RAM, a longer value allows more complex
+            names.
+
+            For most uses, the default of 16 is OK.
+endmenu

+ 0 - 14
mocks/freertos/include/freertos/FreeRTOS.h

@@ -1,14 +0,0 @@
-/*
- * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD
- *
- * SPDX-License-Identifier: Apache-2.0
- */
-
-/**
- * NOTE: this is not the original header file from the freertos component.
- * It is a stripped-down copy to support mocking.
- */
-
-#pragma once
-
-typedef uint32_t TickType_t;

+ 0 - 14
mocks/freertos/include/freertos/portmacro.h

@@ -1,14 +0,0 @@
-/*
- * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD
- *
- * SPDX-License-Identifier: Apache-2.0
- */
-
-/**
- * NOTE: this is not the original header file from the freertos component.
- * It is a stripped-down copy to support mocking.
- */
-
-#pragma once
-
-#define portMAX_DELAY ( uint32_t ) 0xffffffff

+ 18 - 0
mocks/freertos/mock/mock_config.yaml

@@ -0,0 +1,18 @@
+        :cmock:
+          :includes_h_pre_orig_header:
+            - FreeRTOS.h
+          :plugins:
+            - expect
+            - expect_any_args
+            - return_thru_ptr
+            - array
+            - ignore
+            - ignore_arg
+            - callback
+          :strippables:
+            - '(?:__attribute__\s*\(+.*?\)+)'
+            - '(?:vQueueAddToRegistry\s*\(+.*?\)+)'
+            - '(?:vQueueUnregisterQueue\s*\(+.*?\)+)'
+            - '(?:pcQueueGetName\s*\(+.*?\)+)'
+            - '(?:vTaskSetThreadLocalStoragePointerAndDelCallback\s*\(+.*?\)+)'
+            - PRIVILEGED_FUNCTION