diff --git a/CMakeLists.txt b/CMakeLists.txt index c70f953c..40c5fc7e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -43,6 +43,7 @@ add_subdirectory(ivi-layermanagement-examples) add_subdirectory(ivi-layermanagement-api/ilmInput) add_subdirectory(ivi-input-modules/ivi-input-controller) add_subdirectory(ivi-id-agent-modules/ivi-id-agent) +add_subdirectory(unittest) #============================================================================================= diff --git a/README b/README index fba77970..82a78727 100644 --- a/README +++ b/README @@ -57,10 +57,18 @@ EGLWLMockNavigation: Syntax: [wayland_display_to_connect_to] /bin/EGLWLMockNavigation Example: WAYLAND_DISPLAY=wayland-1 $HOME/bin/EGLWLMockNavigation -How to test +How to test functional testing ==================================== 1. Build the testsuite by setting BUILD_ILM_API_TESTS option. Example: cmake -DBUILD_ILM_API_TESTS 2. After starting up Weston run the testsuite. Syntax: [wayland_display_to_connect_to] /bin/ivi-layermanagement-api-test Example: WAYLAND_DISPLAY=wayland-1 $HOME/bin/ivi-layermanagement-api-test + +How to test unit testing +==================================== +1. Build the testsuite by setting BUILD_ILM_UNIT_TESTS option. + Example: cmake -DBUILD_ILM_UNIT_TESTS=ON +2. After build successfully, just run the testsuite right away. + Syntax: /bin/unittest* + Example: $HOME/install/bin/unittest-ivi-controller diff --git a/unittest/CMakeLists.txt b/unittest/CMakeLists.txt new file mode 100644 index 00000000..46b9298e --- /dev/null +++ b/unittest/CMakeLists.txt @@ -0,0 +1,33 @@ +############################################################################ +# +# Copyright (C) 2023 Advanced Driver Information Technology Joint Venture GmbH +# +# +# 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. +# +############################################################################ + +CMAKE_MINIMUM_REQUIRED(VERSION 2.6) + +find_package(gtest REQUIRED) + +IF(NOT gtest_FOUND) + MESSAGE(STATUS "gtest not found, disabling unit tests (BUILD_ILM_UNIT_TESTS=OFF)") + SET(BUILD_ILM_UNIT_TESTS FALSE CACHE BOOL "Build unit tests for IVI LayerManagement API" FORCE) +ENDIF() + +IF(BUILD_ILM_UNIT_TESTS) + enable_testing() + add_subdirectory(client) + add_subdirectory(server) +ENDIF() diff --git a/unittest/client/CMakeLists.txt b/unittest/client/CMakeLists.txt new file mode 100644 index 00000000..66e4c6b3 --- /dev/null +++ b/unittest/client/CMakeLists.txt @@ -0,0 +1,95 @@ +############################################################################ +# +# Copyright (C) 2023 Advanced Driver Information Technology Joint Venture GmbH +# +# +# 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. +# +############################################################################ + +CMAKE_MINIMUM_REQUIRED(VERSION 2.6) +cmake_policy(SET CMP0046 OLD) + +PROJECT(ilm_client_unittest) + +INCLUDE_DIRECTORIES( + ${CMAKE_CURRENT_SOURCE_DIR}/../../ivi-layermanagement-api/ilmControl/src + ${CMAKE_CURRENT_SOURCE_DIR}/../../ivi-layermanagement-api/ilmCommon/include + ${CMAKE_CURRENT_SOURCE_DIR}/../../ivi-layermanagement-api/ilmControl/include + ${CMAKE_CURRENT_SOURCE_DIR}/../../ivi-layermanagement-api/ilmInput/include + ${CMAKE_CURRENT_BINARY_DIR}/../../ivi-layermanagement-api/ilmControl + ${CMAKE_CURRENT_BINARY_DIR}/../../protocol + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${CMAKE_CURRENT_SOURCE_DIR}/../common + ${WAYLAND_CLIENT_INCLUDE_DIRS} + ${WESTON_INCLUDE_DIRS} + ${gtest_INCLUDE_DIRS} +) + +LINK_DIRECTORIES( + ${WAYLAND_CLIENT_LIBRARY_DIRS} +) + +SET(LIBS + ${gtest_LIBRARIES} +) + +SET(SRC_COMMON_FILES + ${CMAKE_CURRENT_SOURCE_DIR}/src/client_api_fake.c + ${CMAKE_CURRENT_SOURCE_DIR}/../common/common_fake_api.c +) + +SET(SRC_IVI_COMMON_FILES + ${CMAKE_CURRENT_SOURCE_DIR}/src/ilm_common_unittests.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/../../ivi-layermanagement-api/ilmCommon/src/ilm_common.c + ${CMAKE_CURRENT_SOURCE_DIR}/../../ivi-layermanagement-api/ilmCommon/src/ilm_common_wayland_platform.c +) + +SET(SRC_IVI_CONTROL_FILES + ${CMAKE_CURRENT_SOURCE_DIR}/src/ilm_control_unittests.cpp +) + +SET(SRC_IVI_INPUT_FILES + ${CMAKE_CURRENT_SOURCE_DIR}/src/ilm_input_uinttests.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/../../ivi-layermanagement-api/ilmInput/src/ilm_input.c +) + +SET(GCC_SANITIZER_COMPILE_FLAGS "-fsanitize=address -fsanitize=undefined -fno-sanitize-recover -fstack-protector-all -fpermissive") +IF(BUILD_CODE_COVERAGE) + SET(COVERAGE_COMPILER_FLAGS "-g --coverage") + SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${COVERAGE_COMPILER_FLAGS}") + SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${GCC_SANITIZER_COMPILE_FLAGS} -pthread ${COVERAGE_COMPILER_FLAGS}") + SET(CMAKE_CXX_LINK_FLAGS "${CMAKE_CXX_LINK_FLAGS} -static-libasan -static-libubsan ${COVERAGE_COMPILER_FLAGS}") +ELSE() + SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${GCC_SANITIZER_COMPILE_FLAGS} -pthread") + SET(CMAKE_CXX_LINK_FLAGS "${CMAKE_CXX_LINK_FLAGS} -static-libasan -static-libubsan") +ENDIF() + +ADD_EXECUTABLE(unittest-ilm-common ${SRC_COMMON_FILES} ${SRC_IVI_COMMON_FILES}) +TARGET_LINK_LIBRARIES(unittest-ilm-common ${LIBS}) +ADD_DEPENDENCIES(unittest-ilm-common ${LIBS}) +INSTALL(TARGETS unittest-ilm-common DESTINATION bin) + +ADD_EXECUTABLE(unittest-ilm-input ${SRC_COMMON_FILES} ${SRC_IVI_INPUT_FILES}) +TARGET_LINK_LIBRARIES(unittest-ilm-input ${LIBS}) +ADD_DEPENDENCIES(unittest-ilm-input ${LIBS}) +INSTALL(TARGETS unittest-ilm-input DESTINATION bin) + +ADD_EXECUTABLE(unittest-ilm-control ${SRC_COMMON_FILES} ${SRC_IVI_CONTROL_FILES}) +TARGET_LINK_LIBRARIES(unittest-ilm-control ${LIBS}) +ADD_DEPENDENCIES(unittest-ilm-control ${LIBS}) +INSTALL(TARGETS unittest-ilm-control DESTINATION bin) + +ADD_TEST(Unittest-ilm-common unittest-ilm-common) +ADD_TEST(Unittest-ilm-input unittest-ilm-input) +ADD_TEST(Unittest-ilm-control unittest-ilm-control) diff --git a/unittest/client/include/client_api_fake.h b/unittest/client/include/client_api_fake.h new file mode 100644 index 00000000..3fa972cc --- /dev/null +++ b/unittest/client/include/client_api_fake.h @@ -0,0 +1,96 @@ +/*************************************************************************** + * + * Copyright (C) 2023 Advanced Driver Information Technology Joint Venture GmbH + * + * + * 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. + * + ****************************************************************************/ + +#ifndef CLIENT_API_FAKE +#define CLIENT_API_FAKE + +#include "stdint.h" +#include +#include "fff.h" +#include "common_fake_api.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef void (**registerHandler) (void); +typedef void *(*threadEntry) (void *); + +DECLARE_FAKE_VALUE_FUNC(struct wl_display *, wl_display_connect, const char *); +DECLARE_FAKE_VALUE_FUNC(struct wl_event_queue *, wl_display_create_queue, struct wl_display *); +DECLARE_FAKE_VALUE_FUNC(int, wl_display_roundtrip, struct wl_display *); +DECLARE_FAKE_VALUE_FUNC(int, wl_proxy_add_listener, struct wl_proxy *, registerHandler, void *); +DECLARE_FAKE_VALUE_FUNC(int, wl_display_roundtrip_queue, struct wl_display *, struct wl_event_queue *); +DECLARE_FAKE_VALUE_FUNC(int, pthread_create, pthread_t *, const pthread_attr_t *, threadEntry, void *); +DECLARE_FAKE_VALUE_FUNC(int, wl_display_flush, struct wl_display *); +DECLARE_FAKE_VALUE_FUNC(int, wl_display_dispatch_queue, struct wl_display *, struct wl_event_queue *); +DECLARE_FAKE_VALUE_FUNC(int, wl_display_dispatch_queue_pending, struct wl_display *, struct wl_event_queue *); +DECLARE_FAKE_VALUE_FUNC(int, wl_display_get_error, struct wl_display *); +DECLARE_FAKE_VALUE_FUNC(int, wl_display_get_fd, struct wl_display *); +DECLARE_FAKE_VALUE_FUNC(int, wl_display_prepare_read_queue, struct wl_display *, struct wl_event_queue *); +DECLARE_FAKE_VALUE_FUNC(int, wl_display_read_events, struct wl_display *); +DECLARE_FAKE_VALUE_FUNC(uint32_t, wl_proxy_get_version, struct wl_proxy *); +DECLARE_FAKE_VOID_FUNC(wl_display_disconnect, struct wl_display *); +DECLARE_FAKE_VOID_FUNC(wl_event_queue_destroy, struct wl_event_queue *); +DECLARE_FAKE_VOID_FUNC(wl_proxy_set_queue, struct wl_proxy *, struct wl_event_queue *); +DECLARE_FAKE_VOID_FUNC(wl_proxy_destroy, struct wl_proxy *); +DECLARE_FAKE_VOID_FUNC(wl_display_cancel_read, struct wl_display *); +DECLARE_FAKE_VOID_FUNC(wl_list_insert, struct wl_list *, struct wl_list *); +DECLARE_FAKE_VALUE_FUNC(void *, wl_array_add, struct wl_array *, size_t); +DECLARE_FAKE_VALUE_FUNC_VARARG(struct wl_proxy *, wl_proxy_marshal_flags, struct wl_proxy *, uint32_t, const struct wl_interface *, uint32_t, uint32_t, ...); +DECLARE_FAKE_VOID_FUNC(wl_array_init, struct wl_array *); +DECLARE_FAKE_VOID_FUNC(wl_array_release, struct wl_array *); +DECLARE_FAKE_VOID_FUNC(wl_list_init, struct wl_list *); +DECLARE_FAKE_VOID_FUNC(wl_list_remove, struct wl_list *); +DECLARE_FAKE_VALUE_FUNC(int, wl_list_length, const struct wl_list *); + +#define CLIENT_API_FAKE_LIST(FAKE) \ + FAKE(wl_display_connect) \ + FAKE(wl_display_create_queue) \ + FAKE(wl_display_roundtrip) \ + FAKE(wl_proxy_add_listener) \ + FAKE(wl_display_roundtrip_queue) \ + FAKE(pthread_create) \ + FAKE(wl_display_flush) \ + FAKE(wl_display_dispatch_queue) \ + FAKE(wl_display_dispatch_queue_pending) \ + FAKE(wl_display_get_error) \ + FAKE(wl_display_get_fd) \ + FAKE(wl_display_prepare_read_queue) \ + FAKE(wl_display_read_events) \ + FAKE(wl_proxy_get_version) \ + FAKE(wl_display_disconnect) \ + FAKE(wl_event_queue_destroy) \ + FAKE(wl_proxy_set_queue) \ + FAKE(wl_proxy_destroy) \ + FAKE(wl_display_cancel_read) \ + FAKE(wl_list_insert) \ + FAKE(wl_array_add) \ + FAKE(wl_proxy_marshal_flags) \ + FAKE(wl_array_init) \ + FAKE(wl_array_release) \ + FAKE(wl_list_init) \ + FAKE(wl_list_remove) \ + FAKE(wl_list_length) \ + FFF_RESET_HISTORY() + +#ifdef __cplusplus +} +#endif +#endif // CLIENT_API_FAKE diff --git a/unittest/client/src/client_api_fake.c b/unittest/client/src/client_api_fake.c new file mode 100644 index 00000000..c04704d6 --- /dev/null +++ b/unittest/client/src/client_api_fake.c @@ -0,0 +1,52 @@ +/*************************************************************************** + * + * Copyright (C) 2023 Advanced Driver Information Technology Joint Venture GmbH + * + * + * 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. + * + ****************************************************************************/ + +#include "client_api_fake.h" +#include "ilm_control_platform.h" +#include "wayland-client-protocol.h" + +DEFINE_FFF_GLOBALS; + +DEFINE_FAKE_VALUE_FUNC(struct wl_display *, wl_display_connect, const char *); +DEFINE_FAKE_VALUE_FUNC(struct wl_event_queue *, wl_display_create_queue, struct wl_display *); +DEFINE_FAKE_VALUE_FUNC(int, wl_display_roundtrip, struct wl_display *); +DEFINE_FAKE_VALUE_FUNC(int, wl_proxy_add_listener, struct wl_proxy *, registerHandler, void *); +DEFINE_FAKE_VALUE_FUNC(int, wl_display_roundtrip_queue, struct wl_display *, struct wl_event_queue *); +DEFINE_FAKE_VALUE_FUNC(int, pthread_create, pthread_t *, const pthread_attr_t *, threadEntry, void *); +DEFINE_FAKE_VALUE_FUNC(int, wl_display_flush, struct wl_display *); +DEFINE_FAKE_VALUE_FUNC(int, wl_display_dispatch_queue, struct wl_display *, struct wl_event_queue *); +DEFINE_FAKE_VALUE_FUNC(int, wl_display_dispatch_queue_pending, struct wl_display *, struct wl_event_queue *); +DEFINE_FAKE_VALUE_FUNC(int, wl_display_get_error, struct wl_display *); +DEFINE_FAKE_VALUE_FUNC(int, wl_display_get_fd, struct wl_display *); +DEFINE_FAKE_VALUE_FUNC(int, wl_display_prepare_read_queue, struct wl_display *, struct wl_event_queue *); +DEFINE_FAKE_VALUE_FUNC(int, wl_display_read_events, struct wl_display *); +DEFINE_FAKE_VOID_FUNC(wl_display_cancel_read, struct wl_display *); +DEFINE_FAKE_VALUE_FUNC(uint32_t, wl_proxy_get_version, struct wl_proxy *); +DEFINE_FAKE_VOID_FUNC(wl_display_disconnect, struct wl_display *); +DEFINE_FAKE_VOID_FUNC(wl_event_queue_destroy, struct wl_event_queue *); +DEFINE_FAKE_VOID_FUNC(wl_proxy_set_queue, struct wl_proxy *, struct wl_event_queue *); +DEFINE_FAKE_VOID_FUNC(wl_proxy_destroy, struct wl_proxy *); +DEFINE_FAKE_VALUE_FUNC(void *, wl_array_add, struct wl_array *, size_t); +DEFINE_FAKE_VOID_FUNC(wl_list_insert, struct wl_list *, struct wl_list *); +DEFINE_FAKE_VALUE_FUNC_VARARG(struct wl_proxy *, wl_proxy_marshal_flags, struct wl_proxy *, uint32_t, const struct wl_interface *, uint32_t, uint32_t, ...); +DEFINE_FAKE_VOID_FUNC(wl_list_remove, struct wl_list *); +DEFINE_FAKE_VOID_FUNC(wl_list_init, struct wl_list *); +DEFINE_FAKE_VOID_FUNC(wl_array_init, struct wl_array *); +DEFINE_FAKE_VOID_FUNC(wl_array_release, struct wl_array *); +DEFINE_FAKE_VALUE_FUNC(int, wl_list_length, const struct wl_list *); diff --git a/unittest/client/src/ilm_common_unittests.cpp b/unittest/client/src/ilm_common_unittests.cpp new file mode 100644 index 00000000..4001e904 --- /dev/null +++ b/unittest/client/src/ilm_common_unittests.cpp @@ -0,0 +1,258 @@ +/*************************************************************************** + * + * Copyright (C) 2023 Advanced Driver Information Technology Joint Venture GmbH + * + * + * 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. + * + ****************************************************************************/ + +#include +#include "ilm_common.h" +#include "ilm_common_platform.h" +#include "client_api_fake.h" + +extern "C" +{ + FAKE_VALUE_FUNC(ilmErrorTypes, ilmControl_init, t_ilm_nativedisplay); + FAKE_VOID_FUNC(ilmControl_destroy); + FAKE_VALUE_FUNC(ilmErrorTypes, ilmControl_registerShutdownNotification, shutdownNotificationFunc, void*); +} + +class IlmCommonTest : public ::testing::Test +{ +public: + void SetUp() + { + CLIENT_API_FAKE_LIST(RESET_FAKE); + RESET_FAKE(ilmControl_init); + RESET_FAKE(ilmControl_destroy); + RESET_FAKE(ilmControl_registerShutdownNotification); + } + + void TearDown() + { + if(ilm_isInitialized()) + { + ilm_destroy(); + } + } + + void mock_ilmInitSuccess() + { + mpp_wlDisplays[0] = (struct wl_display*)&m_wlDisplayFakePointer; + SET_RETURN_SEQ(wl_display_connect, mpp_wlDisplays, MAX_NUMBER); + + mp_ilmErrorType[0] = ILM_SUCCESS; + SET_RETURN_SEQ(ilmControl_init, mp_ilmErrorType, MAX_NUMBER); + } + + static constexpr uint8_t MAX_NUMBER = 1; + uint8_t m_wlDisplayFakePointer = 0; + struct wl_display* mpp_wlDisplays [MAX_NUMBER] = {nullptr}; + ilmErrorTypes mp_ilmErrorType[MAX_NUMBER] = {ILM_FAILED}; +}; + +/** ================================================================================================ + * @test_id ilm_init_cannotGetDisplay + * @brief Test case of ilm_init() where wl_display_connect() fails, returns null object + * @test_procedure Steps: + * -# Mocking the wl_display_connect() to return a null object + * -# Calling the ilm_init() + * -# Verification point: + * +# ilm_init() must return ILM_FAILED + * +# wl_display_connect() must be called once time and return nullptr + */ +TEST_F(IlmCommonTest, ilm_init_cannotGetDisplay) +{ + mpp_wlDisplays[0] = nullptr; + SET_RETURN_SEQ(wl_display_connect, mpp_wlDisplays, MAX_NUMBER); + + ASSERT_EQ(ILM_FAILED, ilm_init()); + + ASSERT_EQ(wl_display_connect_fake.call_count, 1); + ASSERT_EQ(wl_display_connect_fake.return_val_history[0], nullptr); +} + +/** ================================================================================================ + * @test_id ilm_init_getFailedOnilmControl_init + * @brief Test case of ilm_init() where the internal function ilmControl_init() fails + * @test_procedure Steps: + * -# Mocking the wl_display_connect() doesn't return null object + * -# Mocking the ilmControl_init() returns ILM_FAILED + * -# Calling the ilm_init() + * -# Verification point: + * +# ilm_init() must return ILM_FAILED + * +# ilmControl_init() must be called once time and return ILM_FAILED + */ +TEST_F(IlmCommonTest, ilm_init_getFailedOnilmControl_init) +{ + mpp_wlDisplays[0] = (struct wl_display*)&m_wlDisplayFakePointer; + SET_RETURN_SEQ(wl_display_connect, mpp_wlDisplays, MAX_NUMBER); + mp_ilmErrorType[0] = ILM_FAILED; + SET_RETURN_SEQ(ilmControl_init, mp_ilmErrorType, MAX_NUMBER); + + ASSERT_EQ(ILM_FAILED, ilm_init()); + + ASSERT_EQ(ilmControl_init_fake.call_count, 1); + ASSERT_EQ(mp_ilmErrorType[0], ilmControl_init_fake.return_val_history[0]); +} + +/** ================================================================================================ + * @test_id ilm_init_getSuccess + * @brief Test case of ilm_init() where wl_display_connect() success, return an object + * and the internal function ilmControl_init() success + * @test_procedure Steps: + * -# Call mock_ilmInitSuccess() to mocking the wl_display_connect() + * doesn't return null object and mocking the ilmControl_init() returns ILM_SUCCESS + * -# Calling the ilm_init() + * -# Verification point: + * +# ilm_init() must return ILM_SUCCESS + * +# wl_display_connect() must be called once time + * +# ilmControl_init() must be called once time and retrun ILM_SUCCESS + */ +TEST_F(IlmCommonTest, ilm_init_getSuccess) +{ + mock_ilmInitSuccess(); + + ASSERT_EQ(ILM_SUCCESS, ilm_init()); + + ASSERT_EQ(wl_display_connect_fake.call_count, 1); + ASSERT_EQ(ilmControl_init_fake.call_count, 1); + ASSERT_EQ(ILM_SUCCESS, ilmControl_init_fake.return_val_history[0]); +} + +/** ================================================================================================ + * @test_id ilm_init_manyTimes + * @brief Test case to ensure the number of calls to ilm_init() and ilm_destroy() must correspond + * Can't destroy without init + * @test_procedure Steps: + * -# Call mock_ilmInitSuccess() to mocking the wl_display_connect() + * doesn't return null object and mocking the ilmControl_init() returns ILM_SUCCESS + * -# Calling multiple the ilm_init() and ilm_destroy() + * -# Verification point: + * +# 2 calls to ilm_init() must return ILM_SUCCESS + * +# 2 calls to ilm_destroy() respectively must return ILM_SUCCESS + * +# The last call ilm_destroy() does not correspond to lm_init(), so it must return ILM_FAILED + */ +TEST_F(IlmCommonTest, ilm_init_manyTimes) +{ + mock_ilmInitSuccess(); + + ASSERT_EQ(ILM_SUCCESS, ilm_init()); + ASSERT_EQ(ILM_SUCCESS, ilm_init()); + ASSERT_EQ(ILM_SUCCESS, ilm_destroy()); + ASSERT_EQ(ILM_SUCCESS, ilm_destroy()); + ASSERT_EQ(ILM_FAILED, ilm_destroy()); +} + +/** ================================================================================================ + * @test_id ilm_initWithNativedisplay_existDisplay + * @brief Test case of ilm_initWithNativedisplay() where wl_display_connect() success, return an object + * and the internal function ilmControl_init() success, but input exists a display + * @test_procedure Steps: + * -# Call mock_ilmInitSuccess() to mocking the wl_display_connect() + * doesn't return null object and mocking the ilmControl_init() returns ILM_SUCCESS + * -# Calling the ilm_initWithNativedisplay() with input nativedisplay is 1 (exist) + * -# Verification point: + * +# ilm_initWithNativedisplay() must return ILM_SUCCESS + * +# wl_display_connect() not be called because exist a display + * +# ilmControl_init() must be called once time and retrun ILM_SUCCESS + */ +TEST_F(IlmCommonTest, ilm_initWithNativedisplay_existDisplay) +{ + mock_ilmInitSuccess(); + + ASSERT_EQ(ILM_SUCCESS, ilm_initWithNativedisplay(1)); + + ASSERT_EQ(wl_display_connect_fake.call_count, 0); + ASSERT_EQ(ilmControl_init_fake.call_count, 1); + ASSERT_EQ(ILM_SUCCESS, ilmControl_init_fake.return_val_history[0]); +} + +/** ================================================================================================ + * @test_id ilm_isInitialized_getFalse + * @brief Test case of ilm_isInitialized() where ilm_init() is not called, ilmControl is not inittialized + * @test_procedure Steps: + * -# Calling the ilm_isInitialized() + * -# Verification point: + * +# ilm_isInitialized() must return ILM_FALSE + */ +TEST_F(IlmCommonTest, ilm_isInitialized_getFalse) +{ + ASSERT_EQ(ILM_FALSE, ilm_isInitialized()); +} + +/** ================================================================================================ + * @test_id ilm_isInitialized_getTrue + * @brief Test case of ilm_isInitialized() where ilm_init() is called, ilmControl is inittialized + * @test_procedure Steps: + * -# Call mock_ilmInitSuccess() to mocking the wl_display_connect() + * doesn't return null object and mocking the ilmControl_init() returns ILM_SUCCESS + * -# Calling the ilm_init() + * -# Calling the ilm_isInitialized() + * -# Verification point: + * +# ilm_init() must return ILM_SUCCESS + * +# ilm_isInitialized() must return ILM_TRUE + */ +TEST_F(IlmCommonTest, ilm_isInitialized_getTrue) +{ + mock_ilmInitSuccess(); + + ASSERT_EQ(ILM_SUCCESS, ilm_init()); + ASSERT_EQ(ILM_TRUE, ilm_isInitialized()); +} + +/** ================================================================================================ + * @test_id ilm_registerShutdownNotification_getFailure + * @brief Test case of ilm_registerShutdownNotification() + * where the internal function ilmControl_registerShutdownNotification fails, return ILM_FAILED + * @test_procedure Steps: + * -# Mocking the ilmControl_registerShutdownNotification() does return ILM_FAILED + * -# Calling the ilm_registerShutdownNotification() + * -# Verification point: + * +# ilm_registerShutdownNotification() must return ILM_FAILED + * +# ilmControl_registerShutdownNotification() must be called once time and retrun ILM_FAILED + */ +TEST_F(IlmCommonTest, ilm_registerShutdownNotification_getFailure) +{ + mp_ilmErrorType[0] = ILM_FAILED; + SET_RETURN_SEQ(ilmControl_registerShutdownNotification, mp_ilmErrorType, MAX_NUMBER); + + ASSERT_EQ(ILM_FAILED, ilm_registerShutdownNotification(nullptr, nullptr)); + + ASSERT_EQ(1, ilmControl_registerShutdownNotification_fake.call_count); + ASSERT_EQ(mp_ilmErrorType[0], ilmControl_registerShutdownNotification_fake.return_val_history[0]); +} + +/** ================================================================================================ + * @test_id ilm_registerShutdownNotification_getSuccess + * @brief Test case of ilm_registerShutdownNotification() + * where the internal function ilmControl_registerShutdownNotification() success, return ILM_SUCCESS + * @test_procedure Steps: + * -# Mocking the ilmControl_registerShutdownNotification() does return ILM_SUCCESS + * -# Calling the ilm_registerShutdownNotification() + * -# Verification point: + * +# ilm_registerShutdownNotification() must return ILM_SUCCESS + * +# ilmControl_registerShutdownNotification() must be called once time and retrun ILM_SUCCESS + */ +TEST_F(IlmCommonTest, ilm_registerShutdownNotification_getSuccess) +{ + mp_ilmErrorType[0] = ILM_SUCCESS; + SET_RETURN_SEQ(ilmControl_registerShutdownNotification, mp_ilmErrorType, MAX_NUMBER); + + ASSERT_EQ(ILM_SUCCESS, ilm_registerShutdownNotification(nullptr, nullptr)); + + ASSERT_EQ(1, ilmControl_registerShutdownNotification_fake.call_count); + ASSERT_EQ(mp_ilmErrorType[0], ilmControl_registerShutdownNotification_fake.return_val_history[0]); +} diff --git a/unittest/client/src/ilm_control_unittests.cpp b/unittest/client/src/ilm_control_unittests.cpp new file mode 100644 index 00000000..6d0fc800 --- /dev/null +++ b/unittest/client/src/ilm_control_unittests.cpp @@ -0,0 +1,5071 @@ +/*************************************************************************** + * + * Copyright (C) 2023 Advanced Driver Information Technology Joint Venture GmbH + * + * + * 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. + * + ****************************************************************************/ + +#include +#include "wayland-util.h" +#include "ilm_control.h" +#include "ilm_control_platform.h" +#include "client_api_fake.h" +#include "ivi-wm-client-protocol.h" +#include "ivi-input-client-protocol.h" + +extern "C"{ +WL_EXPORT const struct wl_interface ivi_screenshot_interface = { + "ivi_screenshot", 1, + 0, NULL, + 0, NULL, +}; + +WL_EXPORT const struct wl_interface ivi_wm_screen_interface = { + "ivi_wm_screen", 1, + 0, NULL, + 0, NULL, +}; + +WL_EXPORT const struct wl_interface ivi_wm_interface = { + "ivi_wm", 1, + 0, NULL, + 0, NULL, +}; + +WL_EXPORT const struct wl_interface ivi_input_interface = { + "ivi_input", 1, + 0, NULL, + 0, NULL, +}; + +WL_EXPORT const struct wl_interface wl_registry_interface = { + "wl_registry", 1, + 0, NULL, + 0, NULL, +}; + +WL_EXPORT const struct wl_interface wl_buffer_interface = { + "wl_buffer", 1, + 0, NULL, + 0, NULL, +}; + +WL_EXPORT const struct wl_interface wl_shm_pool_interface = { + "wl_shm_pool", 1, + 0, NULL, + 0, NULL, +}; + +WL_EXPORT const struct wl_interface wl_shm_interface = { + "wl_shm", 1, + 0, NULL, + 0, NULL, +}; + +WL_EXPORT const struct wl_interface wl_output_interface = { + "wl_output", 1, + 0, NULL, + 0, NULL, +}; + +FAKE_VALUE_FUNC(int, save_as_png, const char *, const char *, int32_t , int32_t , uint32_t ); +FAKE_VALUE_FUNC(int, save_as_bitmap, const char *, const char *, int32_t , int32_t , uint32_t ); + +struct screenshot_data_t { + std::atomic fd; + std::atomic error; + ilmErrorTypes result = ILM_SUCCESS; +}; + +} + +extern "C"{ +#include "ilm_control_wayland_platform.c" +} + +static constexpr uint8_t MAX_NUMBER = 5; + +enum ilmControlStatus +{ + CREATE_LAYER = 0, + DESTROY_LAYER = 1, + CREATE_SURFACE = 2, + DESTROY_SURFACE = 3, + NONE = 4 +}; + +static ilmControlStatus g_ilmControlStatus = NONE; +static t_ilm_notification_mask g_ilm_notification_mask; + +static void notificationCallback(ilmObjectType object, t_ilm_uint id, t_ilm_bool created, void *user_data) +{ + if (object == ILM_SURFACE) + { + g_ilmControlStatus = created ? CREATE_SURFACE : DESTROY_SURFACE; + } else if (object == ILM_LAYER) + { + g_ilmControlStatus = created ? CREATE_LAYER : DESTROY_LAYER; + } +} + +static void surfaceCallbackFunction(t_ilm_surface surface, struct ilmSurfaceProperties* surfaceProperties, t_ilm_notification_mask mask) +{ + g_ilm_notification_mask = mask; + std::cout << "Notification: surface " << surface << "\n"; +} + +static void layerCallbackFunction(t_ilm_layer layer, struct ilmLayerProperties* layerProperties, t_ilm_notification_mask mask) +{ + g_ilm_notification_mask = mask; + std::cout << "Notification: layer " << layer << "\n"; +} + +class IlmControlTest : public ::testing::Test +{ +public: + void SetUp() + { + init_ctx_list_content(); + CLIENT_API_FAKE_LIST(RESET_FAKE); + g_ilmControlStatus = NONE; + g_ilm_notification_mask = ILM_NOTIFICATION_ALL; + } + + void TearDown() + { + deinit_ctx_list_content(); + } + + void init_ctx_list_content() + { + custom_wl_list_init(&ilm_context.wl.list_seat); + custom_wl_list_init(&ilm_context.wl.list_surface); + custom_wl_list_init(&ilm_context.wl.list_screen); + custom_wl_list_init(&ilm_context.wl.list_layer); + ilm_context.wl.controller = (struct ivi_wm*)&m_iviWmControllerFakePointer; + + for(uint8_t i = 0; i < 3; i++) + { + // prepare the seats + mp_ctxSeat[i] = (struct seat_context*)malloc(sizeof(struct seat_context)); + mp_ctxSeat[i]->seat_name = strdup(mp_ilmSeatNames[i]); + mp_ctxSeat[i]->capabilities = 1; + custom_wl_list_insert(&ilm_context.wl.list_seat, &mp_ctxSeat[i]->link); + } + for(uint8_t i = 0; i < MAX_NUMBER; i++) + { + // prepare the surfaces + mp_ctxSurface[i] = (struct surface_context*)malloc(sizeof(struct surface_context)); + mp_ctxSurface[i]->id_surface = mp_ilmSurfaceIds[i]; + mp_ctxSurface[i]->ctx = &ilm_context.wl; + mp_ctxSurface[i]->prop = mp_surfaceProps[i]; + mp_ctxSurface[i]->notification = NULL; + custom_wl_list_init(&mp_ctxSurface[i]->list_accepted_seats); + mp_accepted_seat[i] = (struct accepted_seat*)malloc(sizeof(struct accepted_seat)); + mp_accepted_seat[i]->seat_name = strdup("KEYBOARD"); + custom_wl_list_insert(&mp_ctxSurface[i]->list_accepted_seats, &mp_accepted_seat[i]->link); + custom_wl_list_insert(&ilm_context.wl.list_surface, &mp_ctxSurface[i]->link); + //prepare the layers + mp_ctxLayer[i] = (struct layer_context*)malloc(sizeof(struct layer_context)); + mp_ctxLayer[i]->id_layer = mp_ilmLayerIds[i]; + mp_ctxLayer[i]->ctx = &ilm_context.wl; + mp_ctxLayer[i]->prop = mp_layerProps[i]; + mp_ctxLayer[i]->notification = NULL; + custom_wl_list_insert(&ilm_context.wl.list_layer, &mp_ctxLayer[i]->link); + custom_wl_array_init(&mp_ctxLayer[i]->render_order); + // prepare the screens + mp_ctxScreen[i] = (struct screen_context*)malloc(sizeof(struct screen_context)); + mp_ctxScreen[i]->id_screen = mp_ilmScreenIds[i]; + mp_ctxScreen[i]->name = i; + mp_ctxScreen[i]->ctx = &ilm_context.wl; + mp_ctxScreen[i]->prop = mp_screenProps[i]; + custom_wl_list_insert(&ilm_context.wl.list_screen, &mp_ctxScreen[i]->link); + custom_wl_array_init(&mp_ctxScreen[i]->render_order); + } + } + + void deinit_ctx_list_content() + { + { + struct surface_context *l, *n; + wl_list_for_each_safe(l, n, &ilm_context.wl.list_surface, link) + { + custom_wl_list_remove(&l->link); + } + } + { + struct layer_context *l, *n; + wl_list_for_each_safe(l, n, &ilm_context.wl.list_layer, link) + { + custom_wl_list_remove(&l->link); + } + } + { + struct screen_context *l, *n; + wl_list_for_each_safe(l, n, &ilm_context.wl.list_screen, link) + { + custom_wl_list_remove(&l->link); + } + } + { + struct seat_context *l, *n; + wl_list_for_each_safe(l, n, &ilm_context.wl.list_seat, link) + { + custom_wl_list_remove(&l->link); + } + } + for(uint8_t i = 0; i < MAX_NUMBER; i++) + { + if(mp_ctxSurface[i] != nullptr) + { + free(mp_ctxSurface[i]); + } + if(mp_ctxLayer[i] != nullptr) + { + free(mp_ctxLayer[i]); + } + if(mp_ctxScreen[i] != nullptr) + { + free(mp_ctxScreen[i]); + } + if(mp_accepted_seat[i] != nullptr) + { + free(mp_accepted_seat[i]->seat_name); + free(mp_accepted_seat[i]); + } + } + for(uint8_t i = 0; i < 3; i++) + { + if(mp_ctxSeat[i] != nullptr) + { + free(mp_ctxSeat[i]->seat_name); + free(mp_ctxSeat[i]); + } + } + ilm_context.wl.controller = nullptr; + ilm_context.wl.notification = nullptr; + ilm_context.initialized = false; + } + + char *mp_ilmSeatNames[3] = {(char*)"KEYBOARD", (char*)"POINTER", (char*)"TOUCH"}; + t_ilm_surface mp_ilmSurfaceIds[MAX_NUMBER] = {1, 2, 3, 4, 5}; + t_ilm_surface mp_ilmScreenIds[MAX_NUMBER] = {10, 20, 30, 40, 50}; + t_ilm_surface mp_ilmLayerIds[MAX_NUMBER] = {100, 200, 300, 400, 500}; + struct surface_context *mp_ctxSurface[MAX_NUMBER] = {nullptr}; + struct accepted_seat *mp_accepted_seat[MAX_NUMBER] = {nullptr}; + struct layer_context *mp_ctxLayer[MAX_NUMBER] = {nullptr}; + struct screen_context *mp_ctxScreen[MAX_NUMBER] = {nullptr}; + struct seat_context *mp_ctxSeat[3] = {nullptr}; + uint8_t m_iviWmControllerFakePointer = 0; + struct ilmSurfaceProperties mp_surfaceProps[MAX_NUMBER] = { + {0.6, 0, 0, 500, 500, 500, 500, 0, 0, 500, 500, ILM_TRUE, 10, 100, ILM_INPUT_DEVICE_ALL}, + {0.7, 10, 50, 600, 400, 600, 400, 50, 40, 200, 1000, ILM_FALSE, 30, 300, ILM_INPUT_DEVICE_POINTER|ILM_INPUT_DEVICE_KEYBOARD}, + {0.8, 20, 60, 700, 300, 700, 300, 60, 30, 300, 900, ILM_FALSE, 60, 1230, ILM_INPUT_DEVICE_KEYBOARD}, + {0.9, 30, 70, 800, 200, 800, 200, 70, 20, 400, 800, ILM_TRUE, 90, 4561, ILM_INPUT_DEVICE_KEYBOARD|ILM_INPUT_DEVICE_TOUCH}, + {1.0, 40, 80, 900, 100, 900, 100, 80, 10, 600, 700, ILM_TRUE, 100, 5646, ILM_INPUT_DEVICE_TOUCH}, + }; + struct ilmLayerProperties mp_layerProps[MAX_NUMBER] = { + {0.1, 0, 0, 1280, 720, 0, 0, 1920, 1080, ILM_TRUE}, + {0.2, 10, 80, 1380, 520, 80, 10, 2920, 9080, ILM_FALSE}, + {0.3, 20, 70, 1480, 420, 70, 20, 3920, 8080, ILM_FALSE}, + {0.4, 30, 60, 1580, 320, 60, 30, 4920, 7080, ILM_FALSE}, + {0.5, 40, 50, 1680, 220, 50, 40, 5920, 6080, ILM_TRUE}, + }; + + struct ilmScreenProperties mp_screenProps[MAX_NUMBER] = { + {0, nullptr, 1920, 1080, "screen_1"}, + {0, nullptr, 3000, 10000, "screen_2"}, + {0, nullptr, 4000, 9000, "screen_3"}, + {0, nullptr, 5000, 8000, "screen_4"}, + {0, nullptr, 6000, 7000, "screen_5"}, + }; + + int mp_successResult[1] = {0}; + int mp_failureResult[1] = {-1}; + ilmErrorTypes mp_ilmErrorType[1]; + + static ilmErrorTypes ScreenshotDoneCallbackFunc(void *user_data, t_ilm_int fd, t_ilm_uint width, t_ilm_uint height, t_ilm_uint stride, t_ilm_uint format, t_ilm_uint timestamp) + { + screenshot_data_t *screenshotData = static_cast(user_data); + screenshotData->fd.store(fd); + return screenshotData->result; + } + + static void ScreenshotErrorCallbackFunc(void *user_data, t_ilm_uint error, const char *message) + { + screenshot_data_t *screenshotData = static_cast(user_data); + screenshotData->error.store(error); + } + +}; + +/** ================================================================================================ + * @test_id ilm_getPropertiesOfSurface_invalidInput + * @brief Test case of ilm_getPropertiesOfSurface() where input pSurfaceProperties is null object + * @test_procedure Steps: + * -# Calling the ilm_getPropertiesOfSurface() with input pSurfaceProperties is null object + * -# Verification point: + * +# ilm_getPropertiesOfSurface() must return ILM_FAILED + * +# wl_proxy_marshal_flags() not be called + * +# wl_display_roundtrip_queue() not be called + */ +TEST_F(IlmControlTest, ilm_getPropertiesOfSurface_invalidInput) +{ + ASSERT_EQ(ILM_FAILED, ilm_getPropertiesOfSurface(MAX_NUMBER + 1, nullptr)); + + ASSERT_EQ(0, wl_proxy_marshal_flags_fake.call_count); + ASSERT_EQ(0, wl_display_roundtrip_queue_fake.call_count); +} + +/** ================================================================================================ + * @test_id ilm_getPropertiesOfSurface_cannotGetRoundTripQueue + * @brief Test case of ilm_getPropertiesOfSurface() where wl_display_roundtrip_queue() fails, return -1 + * @test_procedure Steps: + * -# Mocking the wl_display_roundtrip_queue() does return -1 + * -# Calling the ilm_getPropertiesOfSurface() + * -# Verification point: + * +# ilm_getPropertiesOfSurface() must return ILM_FAILED + * +# wl_proxy_marshal_flags() must be called once time + * +# wl_display_roundtrip_queue() must be called once time and return -1 + */ +TEST_F(IlmControlTest, ilm_getPropertiesOfSurface_cannotGetRoundTripQueue) +{ + SET_RETURN_SEQ(wl_display_roundtrip_queue, mp_failureResult, 1); + + struct ilmSurfaceProperties *l_surfaceProp = (struct ilmSurfaceProperties *)0xFFFFFFFF; + ASSERT_EQ(ILM_FAILED, ilm_getPropertiesOfSurface(1, l_surfaceProp)); + + ASSERT_EQ(1, wl_proxy_marshal_flags_fake.call_count); + ASSERT_EQ(1, wl_display_roundtrip_queue_fake.call_count); + ASSERT_EQ(mp_failureResult[0], wl_display_roundtrip_queue_fake.return_val_history[0]); +} + +/** ================================================================================================ + * @test_id ilm_getPropertiesOfSurface_cannotGetSurface + * @brief Test case of ilm_getPropertiesOfSurface() where wl_display_roundtrip_queue() success, return 0 + * but invalid surface id {MAX_NUMBER + 1} + * @test_procedure Steps: + * -# Mocking the wl_display_roundtrip_queue() does return 0 + * -# Calling the ilm_getPropertiesOfSurface() + * -# Verification point: + * +# ilm_getPropertiesOfSurface() must return ILM_FAILED + * +# wl_proxy_marshal_flags() must be called once time + * +# wl_display_roundtrip_queue() must be called once time and return 0 + */ +TEST_F(IlmControlTest, ilm_getPropertiesOfSurface_cannotGetSurface) +{ + SET_RETURN_SEQ(wl_display_roundtrip_queue, mp_successResult, 1); + + struct ilmSurfaceProperties *l_surfaceProp = (struct ilmSurfaceProperties *)0xFFFFFFFF; + ASSERT_EQ(ILM_FAILED, ilm_getPropertiesOfSurface(MAX_NUMBER + 1, l_surfaceProp)); + + ASSERT_EQ(1, wl_proxy_marshal_flags_fake.call_count); + ASSERT_EQ(1, wl_display_roundtrip_queue_fake.call_count); + ASSERT_EQ(mp_successResult[0], wl_display_roundtrip_queue_fake.return_val_history[0]); +} + +/** ================================================================================================ + * @test_id ilm_getPropertiesOfSurface_success + * @brief Test case of ilm_getPropertiesOfSurface() where wl_display_roundtrip_queue() success, return 0 + * and valid surface id {1} + * @test_procedure Steps: + * -# Mocking the wl_display_roundtrip_queue() does return 0 + * -# Calling the ilm_getPropertiesOfSurface() + * -# Verification point: + * +# ilm_getPropertiesOfSurface() must return ILM_SUCCESS + * +# Surface properties output should same with prepare data + * +# Free resources are allocated when running the test + */ +TEST_F(IlmControlTest, ilm_getPropertiesOfSurface_success) +{ + SET_RETURN_SEQ(wl_display_roundtrip_queue, mp_successResult, 1); + + struct ilmSurfaceProperties *l_surfaceProp = (struct ilmSurfaceProperties *)malloc(sizeof(struct ilmSurfaceProperties)); + ASSERT_EQ(ILM_SUCCESS, ilm_getPropertiesOfSurface(1, l_surfaceProp)); + + ASSERT_EQ(l_surfaceProp->opacity, mp_surfaceProps[0].opacity); + ASSERT_EQ(l_surfaceProp->sourceX, mp_surfaceProps[0].sourceX); + ASSERT_EQ(l_surfaceProp->sourceY, mp_surfaceProps[0].sourceY); + ASSERT_EQ(l_surfaceProp->sourceWidth, mp_surfaceProps[0].sourceWidth); + ASSERT_EQ(l_surfaceProp->sourceHeight, mp_surfaceProps[0].sourceHeight); + ASSERT_EQ(l_surfaceProp->origSourceWidth, mp_surfaceProps[0].origSourceWidth); + ASSERT_EQ(l_surfaceProp->origSourceHeight, mp_surfaceProps[0].origSourceHeight); + ASSERT_EQ(l_surfaceProp->destX, mp_surfaceProps[0].destX); + ASSERT_EQ(l_surfaceProp->destY, mp_surfaceProps[0].destY); + ASSERT_EQ(l_surfaceProp->destWidth, mp_surfaceProps[0].destWidth); + ASSERT_EQ(l_surfaceProp->destHeight, mp_surfaceProps[0].destHeight); + ASSERT_EQ(l_surfaceProp->visibility, mp_surfaceProps[0].visibility); + ASSERT_EQ(l_surfaceProp->frameCounter, mp_surfaceProps[0].frameCounter); + ASSERT_EQ(l_surfaceProp->creatorPid, mp_surfaceProps[0].creatorPid); + ASSERT_EQ(l_surfaceProp->focus, mp_surfaceProps[0].focus); + + free(l_surfaceProp); +} + +/** ================================================================================================ + * @test_id ilm_getPropertiesOfLayer_invalidInput + * @brief Test case of ilm_getPropertiesOfLayer() where input pLayerProperties is null object + * @test_procedure Steps: + * -# Calling the ilm_getPropertiesOfLayer() with input pLayerProperties is null object + * -# Verification point: + * +# ilm_getPropertiesOfLayer() must return ILM_FAILED + * +# wl_proxy_marshal_flags() not be called + * +# wl_display_roundtrip_queue() not be called + */ +TEST_F(IlmControlTest, ilm_getPropertiesOfLayer_invalidInput) +{ + ASSERT_EQ(ILM_FAILED, ilm_getPropertiesOfLayer((MAX_NUMBER + 1) *100, nullptr)); + + ASSERT_EQ(0, wl_proxy_marshal_flags_fake.call_count); + ASSERT_EQ(0, wl_display_roundtrip_queue_fake.call_count); +} + +/** ================================================================================================ + * @test_id ilm_getPropertiesOfLayer_cannotGetRoundTripQueue + * @brief Test case of ilm_getPropertiesOfLayer() where wl_display_roundtrip_queue() fails, return -1 + * @test_procedure Steps: + * -# Mocking the wl_display_roundtrip_queue() does return -1 + * -# Calling the ilm_getPropertiesOfLayer() + * -# Verification point: + * +# ilm_getPropertiesOfLayer() must return ILM_FAILED + * +# wl_proxy_marshal_flags() must be called once time + * +# wl_display_roundtrip_queue() must be called once time and return -1 + */ +TEST_F(IlmControlTest, ilm_getPropertiesOfLayer_cannotGetRoundTripQueue) +{ + SET_RETURN_SEQ(wl_display_roundtrip_queue, mp_failureResult, 1); + + struct ilmLayerProperties *l_layerProp = (struct ilmLayerProperties *)0xFFFFFFFF; + ASSERT_EQ(ILM_FAILED, ilm_getPropertiesOfLayer(100, l_layerProp)); + + ASSERT_EQ(1, wl_proxy_marshal_flags_fake.call_count); + ASSERT_EQ(1, wl_display_roundtrip_queue_fake.call_count); + ASSERT_EQ(mp_failureResult[0], wl_display_roundtrip_queue_fake.return_val_history[0]); +} + +/** ================================================================================================ + * @test_id ilm_getPropertiesOfLayer_cannotGetLayer + * @brief Test case of ilm_getPropertiesOfLayer() where wl_display_roundtrip_queue() success, return 0 + * but invalid layer id {(MAX_NUMBER + 1) * 100} + * @test_procedure Steps: + * -# Mocking the wl_display_roundtrip_queue() does return 0 + * -# Calling the ilm_getPropertiesOfLayer() + * -# Verification point: + * +# ilm_getPropertiesOfLayer() must return ILM_FAILED + * +# wl_proxy_marshal_flags() must be called once time + * +# wl_display_roundtrip_queue() must be called once time and return 0 + */ +TEST_F(IlmControlTest, ilm_getPropertiesOfLayer_cannotGetLayer) +{ + SET_RETURN_SEQ(wl_display_roundtrip_queue, mp_successResult, 1); + + struct ilmLayerProperties *l_layerProp = (struct ilmLayerProperties *)0xFFFFFFFF; + ASSERT_EQ(ILM_FAILED, ilm_getPropertiesOfLayer((MAX_NUMBER + 1) *100, l_layerProp)); + + ASSERT_EQ(1, wl_proxy_marshal_flags_fake.call_count); + ASSERT_EQ(1, wl_display_roundtrip_queue_fake.call_count); + ASSERT_EQ(mp_successResult[0], wl_display_roundtrip_queue_fake.return_val_history[0]); +} + +/** ================================================================================================ + * @test_id ilm_getPropertiesOfLayer_success + * @brief Test case of ilm_getPropertiesOfLayer() where wl_display_roundtrip_queue() success, return 0 + * and valid surface id {100} + * @test_procedure Steps: + * -# Mocking the wl_display_roundtrip_queue() does return 0 + * -# Calling the ilm_getPropertiesOfLayer() + * -# Verification point: + * +# ilm_getPropertiesOfLayer() must return ILM_SUCCESS + * +# Surface properties output should same with prepare data + * +# Free resources are allocated when running the test + */ +TEST_F(IlmControlTest, ilm_getPropertiesOfLayer_success) +{ + SET_RETURN_SEQ(wl_display_roundtrip_queue, mp_successResult, 1); + + struct ilmLayerProperties *l_layerProp = (struct ilmLayerProperties *)malloc(sizeof(struct ilmLayerProperties)); + ASSERT_EQ(ILM_SUCCESS, ilm_getPropertiesOfLayer(100, l_layerProp)); + + ASSERT_EQ(l_layerProp->opacity, mp_layerProps[0].opacity); + ASSERT_EQ(l_layerProp->sourceX, mp_layerProps[0].sourceX); + ASSERT_EQ(l_layerProp->sourceY, mp_layerProps[0].sourceY); + ASSERT_EQ(l_layerProp->sourceWidth, mp_layerProps[0].sourceWidth); + ASSERT_EQ(l_layerProp->sourceHeight, mp_layerProps[0].sourceHeight); + ASSERT_EQ(l_layerProp->destX, mp_layerProps[0].destX); + ASSERT_EQ(l_layerProp->destY, mp_layerProps[0].destY); + ASSERT_EQ(l_layerProp->destWidth, mp_layerProps[0].destWidth); + ASSERT_EQ(l_layerProp->destHeight, mp_layerProps[0].destHeight); + ASSERT_EQ(l_layerProp->visibility, mp_layerProps[0].visibility); + + free(l_layerProp); +} + +/** ================================================================================================ + * @test_id ilm_getPropertiesOfScreen_invalidInput + * @brief Test case of ilm_getPropertiesOfScreen() where input param wrong + * @test_procedure Steps: + * -# Calling the ilm_getPropertiesOfScreen() time 1 with input pScreenProperties is null object + * -# Calling the ilm_getPropertiesOfScreen() time 2 with invalid input screen id {(MAX_NUMBER + 1) *10} + * -# Verification point: + * +# ilm_getPropertiesOfScreen() time 1 must return ILM_ERROR_INVALID_ARGUMENTS + * +# ilm_getPropertiesOfScreen() time 2 must return ILM_FAILED + * +# wl_proxy_marshal_flags() not be called + * +# wl_display_roundtrip_queue() not be called + */ +TEST_F(IlmControlTest, ilm_getPropertiesOfScreen_invalidInput) +{ + struct ilmScreenProperties *l_ScreenProp = (struct ilmScreenProperties *)0xFFFFFFFF; + ASSERT_EQ(ILM_ERROR_INVALID_ARGUMENTS, ilm_getPropertiesOfScreen(MAX_NUMBER, nullptr)); + ASSERT_EQ(ILM_FAILED, ilm_getPropertiesOfScreen((MAX_NUMBER + 1) *10, l_ScreenProp)); + + ASSERT_EQ(0, wl_proxy_marshal_flags_fake.call_count); + ASSERT_EQ(0, wl_display_roundtrip_queue_fake.call_count); +} + +/** ================================================================================================ + * @test_id ilm_getPropertiesOfScreen_cannotGetRoundTripQueue + * @brief Test case of ilm_getPropertiesOfScreen() where wl_display_roundtrip_queue() fails, return -1 + * @test_procedure Steps: + * -# Mocking the wl_display_roundtrip_queue() does return -1 + * -# Calling the ilm_getPropertiesOfScreen() + * -# Verification point: + * +# ilm_getPropertiesOfScreen() must return ILM_FAILED + * +# wl_proxy_marshal_flags() must be called once time + * +# wl_display_roundtrip_queue() must be called once time and return -1 + */ +TEST_F(IlmControlTest, ilm_getPropertiesOfScreen_cannotGetRoundTripQueue) +{ + SET_RETURN_SEQ(wl_display_roundtrip_queue, mp_failureResult, 1); + + struct ilmScreenProperties *l_ScreenProp = (struct ilmScreenProperties *)0xFFFFFFFF; + ASSERT_EQ(ILM_FAILED, ilm_getPropertiesOfScreen(10, l_ScreenProp)); + + ASSERT_EQ(1, wl_proxy_marshal_flags_fake.call_count); + ASSERT_EQ(1, wl_display_roundtrip_queue_fake.call_count); + ASSERT_EQ(mp_failureResult[0], wl_display_roundtrip_queue_fake.return_val_history[0]); +} + +/** ================================================================================================ + * @test_id ilm_getPropertiesOfScreen_success + * @brief Test case of ilm_getPropertiesOfScreen() where wl_display_roundtrip_queue() success, return 0 + * @test_procedure Steps: + * -# Mocking the wl_display_roundtrip_queue() does return 0 + * -# Prepare the data output of ilm_getPropertiesOfScreen + * -# Calling the ilm_getPropertiesOfScreen() + * -# Verification point: + * +# ilm_getPropertiesOfScreen() must return ILM_SUCCESS + * +# Properties screen output should same with preapre data + * +# Free resources are allocated when running the test + */ +TEST_F(IlmControlTest, ilm_getPropertiesOfScreen_success) +{ + SET_RETURN_SEQ(wl_display_roundtrip_queue, mp_successResult, 1); + + uint32_t *l_addLayer = (uint32_t*)custom_wl_array_add(&mp_ctxScreen[0]->render_order, sizeof(uint32_t)); + *l_addLayer = 100; + l_addLayer = (uint32_t*)custom_wl_array_add(&mp_ctxScreen[0]->render_order, sizeof(uint32_t)); + *l_addLayer = 200; + + struct ilmScreenProperties *l_ScreenProp = (struct ilmScreenProperties *)malloc(sizeof(struct ilmScreenProperties)); + ASSERT_EQ(ILM_SUCCESS, ilm_getPropertiesOfScreen(10, l_ScreenProp)); + + EXPECT_EQ(l_ScreenProp->layerCount, 2); + EXPECT_EQ(l_ScreenProp->layerIds[0], 100); + EXPECT_EQ(l_ScreenProp->layerIds[1], 200); + EXPECT_EQ(l_ScreenProp->screenWidth, mp_ctxScreen[0]->prop.screenWidth); + EXPECT_EQ(l_ScreenProp->screenHeight, mp_ctxScreen[0]->prop.screenHeight); + EXPECT_EQ(0, strcmp(l_ScreenProp->connectorName, mp_ctxScreen[0]->prop.connectorName)); + + free(l_ScreenProp->layerIds); + free(l_ScreenProp); + custom_wl_array_release(&mp_ctxScreen[0]->render_order); +} + +/** ================================================================================================ + * @test_id ilm_getScreenIDs_cannotSyncAcquireInstance + * @brief Test case of ilm_getScreenIDs() where ilm context initialized is false, not ready init + * and wl_display_roundtrip_queue() fails, return -1 + * @test_procedure Steps: + * -# Set the ilm context initialized is false, not ready init + * -# Calling the ilm_getScreenIDs() time 1 + * -# Set the ilm context initialized is true, ready init + * -# Mocking the wl_display_roundtrip_queue() does return -1 + * -# Calling the ilm_getScreenIDs() time 2 + * -# Verification point: + * +# Both of ilm_getScreenIDs() time 1 and time 2 must return ILM_FAILED + * +# wl_display_roundtrip_queue() must be called once time and return -1 + */ +TEST_F(IlmControlTest, ilm_getScreenIDs_cannotSyncAcquireInstance) +{ + wl_list_length_fake.custom_fake = custom_wl_list_length; + t_ilm_uint l_numberIds = 0; + t_ilm_uint *lp_listIds = nullptr; + + ilm_context.initialized = false; + ASSERT_EQ(ILM_FAILED, ilm_getScreenIDs(&l_numberIds, &lp_listIds)); + + ilm_context.initialized = true; + SET_RETURN_SEQ(wl_display_roundtrip_queue, mp_failureResult, 1); + ASSERT_EQ(ILM_FAILED, ilm_getScreenIDs(&l_numberIds, &lp_listIds)); + + ASSERT_EQ(1, wl_display_roundtrip_queue_fake.call_count); + ASSERT_EQ(mp_failureResult[0], wl_display_roundtrip_queue_fake.return_val_history[0]); +} + +/** ================================================================================================ + * @test_id ilm_getScreenIDs_invaildInput + * @brief Test case of ilm_getScreenIDs() where input param wrong + * @test_procedure Steps: + * -# Set the ilm context initialized is true, ready init + * -# Mocking the wl_display_roundtrip_queue() does return 0 (success) + * -# Calling the ilm_getScreenIDs() time 1 with pNumberOfIDs is null pointer + * -# Calling the ilm_getScreenIDs() time 2 with ppIDs is null pointer + * -# Verification point: + * +# Both of ilm_getScreenIDs() time 1 and time 2 must return ILM_FAILED + */ +TEST_F(IlmControlTest, ilm_getScreenIDs_invaildInput) +{ + ilm_context.initialized = true; + SET_RETURN_SEQ(wl_display_roundtrip_queue, mp_successResult, 1); + + t_ilm_uint l_numberIds = 0; + t_ilm_uint *lp_listIds = nullptr; + ASSERT_EQ(ILM_FAILED, ilm_getScreenIDs(nullptr, &lp_listIds)); + ASSERT_EQ(ILM_FAILED, ilm_getScreenIDs(&l_numberIds, nullptr)); +} + +/** ================================================================================================ + * @test_id ilm_getScreenIDs_success + * @brief Test case of ilm_getScreenIDs() where wl_display_roundtrip_queue() success, return 0 + * and valid input param + * @test_procedure Steps: + * -# Set the ilm context initialized is true, ready init + * -# Mocking the wl_display_roundtrip_queue() does return 0 (success) + * -# Calling the ilm_getScreenIDs() + * -# Verification point: + * +# ilm_getScreenIDs() must return ILM_SUCCESS + * +# The result output should same with the prepare input + * +# Free resources are allocated when running the test + */ +TEST_F(IlmControlTest, ilm_getScreenIDs_success) +{ + wl_list_length_fake.custom_fake = custom_wl_list_length; + ilm_context.initialized = true; + SET_RETURN_SEQ(wl_display_roundtrip_queue, mp_successResult, 1); + + t_ilm_uint l_numberIds = 0; + t_ilm_uint *lp_listIds = nullptr; + ASSERT_EQ(ILM_SUCCESS, ilm_getScreenIDs(&l_numberIds, &lp_listIds)); + + EXPECT_EQ(MAX_NUMBER, l_numberIds); + for(uint8_t i = 0; i< l_numberIds; i++) + { + EXPECT_EQ(lp_listIds[i], mp_ilmScreenIds[i]); + } + + free(lp_listIds); +} + +/** ================================================================================================ + * @test_id ilm_getScreenResolution_cannotSyncAcquireInstance + * @brief Test case of ilm_getScreenResolution() where ilm context initialized is false, not ready init + * and wl_display_roundtrip_queue() fails, return -1 + * @test_procedure Steps: + * -# Set the ilm context initialized is false, not ready init + * -# Calling the ilm_getScreenResolution() time 1 + * -# Set the ilm context initialized is true, ready init + * -# Mocking the wl_display_roundtrip_queue() does return -1 + * -# Calling the ilm_getScreenResolution() time 2 + * -# Verification point: + * +# Both of ilm_getScreenResolution() time 1 and time 2 must return ILM_FAILED + * +# wl_display_roundtrip_queue() must be called once time and return -1 + */ +TEST_F(IlmControlTest, ilm_getScreenResolution_cannotSyncAcquireInstance) +{ + t_ilm_uint l_screenWidth = 0, l_screenHeight = 0; + + ilm_context.initialized = false; + ASSERT_EQ(ILM_FAILED, ilm_getScreenResolution(10, &l_screenWidth, &l_screenHeight)); + + ilm_context.initialized = true; + SET_RETURN_SEQ(wl_display_roundtrip_queue, mp_failureResult, 1); + ASSERT_EQ(ILM_FAILED, ilm_getScreenResolution(10, &l_screenWidth, &l_screenHeight)); + + ASSERT_EQ(1, wl_display_roundtrip_queue_fake.call_count); + ASSERT_EQ(mp_failureResult[0], wl_display_roundtrip_queue_fake.return_val_history[0]); +} + +/** ================================================================================================ + * @test_id ilm_getScreenResolution_invaildInput + * @brief Test case of ilm_getScreenResolution() where input param wrong + * @test_procedure Steps: + * -# Set the ilm context initialized is true, ready init + * -# Mocking the wl_display_roundtrip_queue() does return 0 (success) + * -# Calling the ilm_getScreenResolution() time 1 with pWidth is null pointer + * -# Calling the ilm_getScreenResolution() time 2 with pHeight is null pointer + * -# Calling the ilm_getScreenResolution() time 3 with invalid screen id + * -# Verification point: + * +# ilm_getScreenResolution() time 1, time 2 and time 3 must return ILM_FAILED + */ +TEST_F(IlmControlTest, ilm_getScreenResolution_invaildInput) +{ + ilm_context.initialized = true; + SET_RETURN_SEQ(wl_display_roundtrip_queue, mp_successResult, 1); + + t_ilm_uint l_screenWidth = 0, l_screenHeight = 0; + ASSERT_EQ(ILM_FAILED, ilm_getScreenResolution(10, nullptr, &l_screenHeight)); + ASSERT_EQ(ILM_FAILED, ilm_getScreenResolution(10, &l_screenWidth, nullptr)); + ASSERT_EQ(ILM_FAILED, ilm_getScreenResolution(1, &l_screenWidth, &l_screenHeight)); +} + +/** ================================================================================================ + * @test_id ilm_getScreenResolution_success + * @brief Test case of ilm_getScreenResolution() where wl_display_roundtrip_queue() success, return 0 + * and valid input param + * @test_procedure Steps: + * -# Set the ilm context initialized is true, ready init + * -# Mocking the wl_display_roundtrip_queue() does return 0 (success) + * -# Calling the ilm_getScreenResolution() + * -# Verification point: + * +# ilm_getScreenResolution() must return ILM_SUCCESS + * +# The result output should same with the prepare input + */ +TEST_F(IlmControlTest, ilm_getScreenResolution_success) +{ + ilm_context.initialized = true; + SET_RETURN_SEQ(wl_display_roundtrip_queue, mp_successResult, 1); + + t_ilm_uint l_screenWidth = 0, l_screenHeight = 0; + ASSERT_EQ(ILM_SUCCESS, ilm_getScreenResolution(10, &l_screenWidth, &l_screenHeight)); + + EXPECT_EQ(1920, l_screenWidth); + EXPECT_EQ(1080, l_screenHeight); +} + +/** ================================================================================================ + * @test_id ilm_getLayerIDs_cannotSyncAcquireInstance + * @brief Test case of ilm_getLayerIDs() where ilm context initialized is false, not ready init + * and wl_display_roundtrip_queue() fails, return -1 + * @test_procedure Steps: + * -# Set the ilm context initialized is false, not ready init + * -# Calling the ilm_getLayerIDs() time 1 + * -# Set the ilm context initialized is true, ready init + * -# Mocking the wl_display_roundtrip_queue() does return -1 + * -# Calling the ilm_getLayerIDs() time 2 + * -# Verification point: + * +# Both of ilm_getLayerIDs() time 1 and time 2 must return ILM_FAILED + * +# wl_display_roundtrip_queue() must be called once time and return -1 + */ +TEST_F(IlmControlTest, ilm_getLayerIDs_cannotSyncAcquireInstance) +{ + wl_list_length_fake.custom_fake = custom_wl_list_length; + t_ilm_int l_numberLayers = 0; + t_ilm_layer *lp_listLayers = nullptr; + + ilm_context.initialized = false; + ASSERT_EQ(ILM_FAILED, ilm_getLayerIDs(&l_numberLayers, &lp_listLayers)); + + ilm_context.initialized = true; + SET_RETURN_SEQ(wl_display_roundtrip_queue, mp_failureResult, 1); + ASSERT_EQ(ILM_FAILED, ilm_getLayerIDs(&l_numberLayers, &lp_listLayers)); + + ASSERT_EQ(1, wl_display_roundtrip_queue_fake.call_count); + ASSERT_EQ(mp_failureResult[0], wl_display_roundtrip_queue_fake.return_val_history[0]); +} + +/** ================================================================================================ + * @test_id ilm_getLayerIDs_invaildInput + * @brief Test case of ilm_getLayerIDs() where input param wrong + * @test_procedure Steps: + * -# Set the ilm context initialized is true, ready init + * -# Mocking the wl_display_roundtrip_queue() does return 0 (success) + * -# Calling the ilm_getLayerIDs() time 1 with pLength is null pointer + * -# Calling the ilm_getLayerIDs() time 2 with ppArray is null pointer + * -# Verification point: + * +# ilm_getLayerIDs() time 1 and time 2 must return ILM_FAILED + */ +TEST_F(IlmControlTest, ilm_getLayerIDs_invaildInput) +{ + ilm_context.initialized = true; + SET_RETURN_SEQ(wl_display_roundtrip_queue, mp_successResult, 1); + + t_ilm_int l_numberLayers = 0; + t_ilm_layer *lp_listLayers = nullptr; + ASSERT_EQ(ILM_FAILED, ilm_getLayerIDs(nullptr, &lp_listLayers)); + ASSERT_EQ(ILM_FAILED, ilm_getLayerIDs(&l_numberLayers, nullptr)); +} + +/** ================================================================================================ + * @test_id ilm_getLayerIDs_success + * @brief Test case of ilm_getLayerIDs() where wl_display_roundtrip_queue() success, return 0 + * and valid input param + * @test_procedure Steps: + * -# Set the ilm context initialized is true, ready init + * -# Mocking the wl_display_roundtrip_queue() does return 0 (success) + * -# Calling the ilm_getLayerIDs() + * -# Verification point: + * +# ilm_getLayerIDs() must return ILM_SUCCESS + * +# The result output should same with the prepare input + * +# Free resources are allocated when running the test + */ +TEST_F(IlmControlTest, ilm_getLayerIDs_success) +{ + wl_list_length_fake.custom_fake = custom_wl_list_length; + ilm_context.initialized = true; + SET_RETURN_SEQ(wl_display_roundtrip_queue, mp_successResult, 1); + + t_ilm_int l_numberLayers = 0; + t_ilm_layer *lp_listLayers = nullptr; + ASSERT_EQ(ILM_SUCCESS, ilm_getLayerIDs(&l_numberLayers, &lp_listLayers)); + + EXPECT_EQ(MAX_NUMBER, l_numberLayers); + for(uint8_t i = 0; i< l_numberLayers; i++) + { + EXPECT_EQ(lp_listLayers[i], mp_ilmLayerIds[i]); + } + + free(lp_listLayers); +} + +/** ================================================================================================ + * @test_id ilm_getLayerIDsOnScreen_invalidInput + * @brief Test case of ilm_getLayerIDsOnScreen() where input param wrong + * @test_procedure Steps: + * -# Calling the ilm_getLayerIDsOnScreen() time 1 with ppArray is null pointer + * -# Calling the ilm_getLayerIDsOnScreen() time 2 with pLength is null pointer + * -# Calling the ilm_getLayerIDsOnScreen() time 3 with invalid screen id + * -# Verification point: + * +# ilm_getLayerIDsOnScreen() time 1, time 2 and time 3 must return ILM_FAILED + */ +TEST_F(IlmControlTest, ilm_getLayerIDsOnScreen_invalidInput) +{ + t_ilm_int l_numberLayers = 0; + t_ilm_layer *lp_listLayers = nullptr; + ASSERT_EQ(ILM_FAILED, ilm_getLayerIDsOnScreen(10, &l_numberLayers, nullptr)); + ASSERT_EQ(ILM_FAILED, ilm_getLayerIDsOnScreen(10, nullptr, &lp_listLayers)); + ASSERT_EQ(ILM_FAILED, ilm_getLayerIDsOnScreen(1, &l_numberLayers, &lp_listLayers)); +} + +/** ================================================================================================ + * @test_id ilm_getLayerIDsOnScreen_cannotGetRoundTripQueue + * @brief Test case of ilm_getLayerIDsOnScreen() where wl_display_roundtrip_queue() fails, return -1 + * @test_procedure Steps: + * -# Mocking the wl_display_roundtrip_queue() does return -1 + * -# Calling the ilm_getLayerIDsOnScreen() + * -# Verification point: + * +# ilm_getLayerIDsOnScreen() must return ILM_FAILED + * +# wl_proxy_marshal_flags() must be called once time + * +# wl_display_roundtrip_queue() must be called once time and return -1 + */ +TEST_F(IlmControlTest, ilm_getLayerIDsOnScreen_cannotGetRoundTripQueue) +{ + SET_RETURN_SEQ(wl_display_roundtrip_queue, mp_failureResult, 1); + + t_ilm_int l_numberLayers = 0; + t_ilm_layer *lp_listLayers = nullptr; + ASSERT_EQ(ILM_FAILED, ilm_getLayerIDsOnScreen(10, &l_numberLayers, &lp_listLayers)); + + ASSERT_EQ(1, wl_proxy_marshal_flags_fake.call_count); + ASSERT_EQ(1, wl_display_roundtrip_queue_fake.call_count); + ASSERT_EQ(mp_failureResult[0], wl_display_roundtrip_queue_fake.return_val_history[0]); +} + +/** ================================================================================================ + * @test_id ilm_getLayerIDsOnScreen_success + * @brief Test case of ilm_getLayerIDsOnScreen() where wl_display_roundtrip_queue() success, return 0 + * @test_procedure Steps: + * -# Mocking the wl_display_roundtrip_queue() does return 0 + * -# Prepare the data output of ilm_getLayerIDsOnScreen + * -# Calling the ilm_getLayerIDsOnScreen() + * -# Verification point: + * +# ilm_getLayerIDsOnScreen() must return ILM_SUCCESS + * +# The result output should same with prepare data + * +# Free resources are allocated when running the test + */ +TEST_F(IlmControlTest, ilm_getLayerIDsOnScreen_success) +{ + SET_RETURN_SEQ(wl_display_roundtrip_queue, mp_successResult, 1); + + uint32_t *l_addLayer = (uint32_t*)custom_wl_array_add(&mp_ctxScreen[0]->render_order, sizeof(uint32_t)); + *l_addLayer = 100; + l_addLayer = (uint32_t*)custom_wl_array_add(&mp_ctxScreen[0]->render_order, sizeof(uint32_t)); + *l_addLayer = 200; + + t_ilm_int l_numberLayers = 0; + t_ilm_layer *lp_listLayers = nullptr; + ASSERT_EQ(ILM_SUCCESS, ilm_getLayerIDsOnScreen(10, &l_numberLayers, &lp_listLayers)); + + EXPECT_EQ(l_numberLayers, 2); + EXPECT_EQ(lp_listLayers[0], 100); + EXPECT_EQ(lp_listLayers[1], 200); + + free(lp_listLayers); + custom_wl_array_release(&mp_ctxScreen[0]->render_order); +} + +/** ================================================================================================ + * @test_id ilm_getSurfaceIDs_cannotSyncAcquireInstance + * @brief Test case of ilm_getSurfaceIDs() where ilm context initialized is false, not ready init + * and wl_display_roundtrip_queue() fails, return -1 + * @test_procedure Steps: + * -# Set the ilm context initialized is false, not ready init + * -# Calling the ilm_getSurfaceIDs() time 1 + * -# Set the ilm context initialized is true, ready init + * -# Mocking the wl_display_roundtrip_queue() does return -1 + * -# Calling the ilm_getSurfaceIDs() time 2 + * -# Verification point: + * +# Both of ilm_getSurfaceIDs() time 1 and time 2 must return ILM_FAILED + * +# wl_display_roundtrip_queue() must be called once time and return -1 + */ +TEST_F(IlmControlTest, ilm_getSurfaceIDs_cannotSyncAcquireInstance) +{ + wl_list_length_fake.custom_fake = custom_wl_list_length; + t_ilm_int l_numberSurfaces = 0; + t_ilm_surface *lp_listSurfaces = nullptr; + + ilm_context.initialized = false; + ASSERT_EQ(ILM_FAILED, ilm_getSurfaceIDs(&l_numberSurfaces, &lp_listSurfaces)); + + ilm_context.initialized = true; + SET_RETURN_SEQ(wl_display_roundtrip_queue, mp_failureResult, 1); + ASSERT_EQ(ILM_FAILED, ilm_getSurfaceIDs(&l_numberSurfaces, &lp_listSurfaces)); + + ASSERT_EQ(1, wl_display_roundtrip_queue_fake.call_count); + ASSERT_EQ(mp_failureResult[0], wl_display_roundtrip_queue_fake.return_val_history[0]); +} + +/** ================================================================================================ + * @test_id ilm_getSurfaceIDs_invaildInput + * @brief Test case of ilm_getSurfaceIDs() where input param wrong + * @test_procedure Steps: + * -# Mocking the wl_display_roundtrip_queue() does return 0 (success) + * -# Calling the ilm_getSurfaceIDs() time 1 with pLength is null pointer + * -# Calling the ilm_getSurfaceIDs() time 2 with ppArray is null pointer + * -# Verification point: + * +# ilm_getLayerIDsOnScreen() time 1 and time 2 must return ILM_FAILED + */ +TEST_F(IlmControlTest, ilm_getSurfaceIDs_invaildInput) +{ + ilm_context.initialized = true; + SET_RETURN_SEQ(wl_display_roundtrip_queue, mp_successResult, 1); + + t_ilm_int l_numberSurfaces = 0; + t_ilm_surface *lp_listSurfaces = nullptr; + ASSERT_EQ(ILM_FAILED, ilm_getSurfaceIDs(nullptr, &lp_listSurfaces)); + ASSERT_EQ(ILM_FAILED, ilm_getSurfaceIDs(&l_numberSurfaces, nullptr)); +} + +/** ================================================================================================ + * @test_id ilm_getSurfaceIDs_success + * @brief Test case of ilm_getSurfaceIDs() where wl_display_roundtrip_queue() success, return 0 + * and valid input param + * @test_procedure Steps: + * -# Mocking the wl_display_roundtrip_queue() does return 0 (success) + * -# Calling the ilm_getSurfaceIDs() + * -# Verification point: + * +# ilm_getSurfaceIDs() must return ILM_SUCCESS + * +# The result output should same with prepare data + * +# Free resources are allocated when running the test + */ +TEST_F(IlmControlTest, ilm_getSurfaceIDs_success) +{ + wl_list_length_fake.custom_fake = custom_wl_list_length; + ilm_context.initialized = true; + SET_RETURN_SEQ(wl_display_roundtrip_queue, mp_successResult, 1); + + t_ilm_int l_numberSurfaces = 0; + t_ilm_surface *lp_listSurfaces = nullptr; + ASSERT_EQ(ILM_SUCCESS, ilm_getSurfaceIDs(&l_numberSurfaces, &lp_listSurfaces)); + + EXPECT_EQ(MAX_NUMBER, l_numberSurfaces); + for(uint8_t i = 0; i< l_numberSurfaces; i++) + { + EXPECT_EQ(lp_listSurfaces[i], mp_ilmSurfaceIds[i]); + } + + free(lp_listSurfaces); +} + +/** ================================================================================================ + * @test_id ilm_getSurfaceIDsOnLayer_invalidInput + * @brief Test case of ilm_getSurfaceIDsOnLayer() where input param wrong + * @test_procedure Steps: + * -# Calling the ilm_getSurfaceIDsOnLayer() time 1 with ppArray is null pointer + * -# Calling the ilm_getSurfaceIDsOnLayer() time 2 with pLength is null pointer + * -# Calling the ilm_getSurfaceIDsOnLayer() time 3 with invalid layer id + * -# Verification point: + * +# ilm_getSurfaceIDsOnLayer() time 1, time 2 and time 3 must return ILM_FAILED + */ +TEST_F(IlmControlTest, ilm_getSurfaceIDsOnLayer_invalidInput) +{ + t_ilm_int l_numberSurfaces = 0; + t_ilm_layer *lp_listSurfaces = nullptr; + ASSERT_EQ(ILM_FAILED, ilm_getSurfaceIDsOnLayer(100, &l_numberSurfaces, nullptr)); + ASSERT_EQ(ILM_FAILED, ilm_getSurfaceIDsOnLayer(100, nullptr, &lp_listSurfaces)); + ASSERT_EQ(ILM_FAILED, ilm_getSurfaceIDsOnLayer(1, &l_numberSurfaces, &lp_listSurfaces)); +} + +/** ================================================================================================ + * @test_id ilm_getSurfaceIDsOnLayer_cannotGetRoundTripQueue + * @brief Test case of ilm_getSurfaceIDsOnLayer() where wl_display_roundtrip_queue() fails, return -1 + * @test_procedure Steps: + * -# Mocking the wl_display_roundtrip_queue() does return -1 + * -# Calling the ilm_getSurfaceIDsOnLayer() + * -# Verification point: + * +# ilm_getSurfaceIDsOnLayer() must return ILM_FAILED + * +# wl_proxy_marshal_flags() must be called once time + * +# wl_display_roundtrip_queue() must be called once time and return -1 + */ +TEST_F(IlmControlTest, ilm_getSurfaceIDsOnLayer_cannotGetRoundTripQueue) +{ + SET_RETURN_SEQ(wl_display_roundtrip_queue, mp_failureResult, 1); + + t_ilm_int l_numberSurfaces = 0; + t_ilm_layer *lp_listSurfaces = nullptr; + ASSERT_EQ(ILM_FAILED, ilm_getSurfaceIDsOnLayer(100, &l_numberSurfaces, &lp_listSurfaces)); + + ASSERT_EQ(1, wl_proxy_marshal_flags_fake.call_count); + ASSERT_EQ(1, wl_display_roundtrip_queue_fake.call_count); + ASSERT_EQ(mp_failureResult[0], wl_display_roundtrip_queue_fake.return_val_history[0]); +} + +/** ================================================================================================ + * @test_id ilm_getSurfaceIDsOnLayer_success + * @brief Test case of ilm_getSurfaceIDsOnLayer() where wl_display_roundtrip_queue() success, return 0 + * and valid input param + * @test_procedure Steps: + * -# Mocking the wl_display_roundtrip_queue() does return 0 (success) + * -# Prepare the data output + * -# Calling the ilm_getSurfaceIDsOnLayer() + * -# Verification point: + * +# ilm_getSurfaceIDsOnLayer() must return ILM_SUCCESS + * +# The result output should same with prepare data + * +# Free resources are allocated when running the test + */ +TEST_F(IlmControlTest, ilm_getSurfaceIDsOnLayer_success) +{ + SET_RETURN_SEQ(wl_display_roundtrip_queue, mp_successResult, 1); + + uint32_t *l_addSurface = (uint32_t*)custom_wl_array_add(&mp_ctxLayer[0]->render_order, sizeof(uint32_t)); + *l_addSurface = 1; + l_addSurface = (uint32_t*)custom_wl_array_add(&mp_ctxLayer[0]->render_order, sizeof(uint32_t)); + *l_addSurface = 2; + + t_ilm_int l_numberSurfaces = 0; + t_ilm_layer *lp_listSurfaces = nullptr; + ASSERT_EQ(ILM_SUCCESS, ilm_getSurfaceIDsOnLayer(100, &l_numberSurfaces, &lp_listSurfaces)); + + EXPECT_EQ(l_numberSurfaces, 2); + EXPECT_EQ(lp_listSurfaces[0], 1); + EXPECT_EQ(lp_listSurfaces[1], 2); + + free(lp_listSurfaces); + custom_wl_array_release(&mp_ctxLayer[0]->render_order); +} + +/** ================================================================================================ + * @test_id ilm_layerCreateWithDimension_cannotSyncAcquireInstance + * @brief Test case of ilm_layerCreateWithDimension() where ilm context initialized is false, not ready init + * and wl_display_roundtrip_queue() fails, return -1 + * @test_procedure Steps: + * -# Set the ilm context initialized is false, not ready init + * -# Calling the ilm_layerCreateWithDimension() time 1 + * -# Set the ilm context initialized is true, ready init + * -# Mocking the wl_display_roundtrip_queue() does return -1 + * -# Calling the ilm_layerCreateWithDimension() time 2 + * -# Verification point: + * +# Both of ilm_layerCreateWithDimension() time 1 and time 2 must return ILM_FAILED + * +# wl_display_roundtrip_queue() must be called once time and return -1 + */ +TEST_F(IlmControlTest, ilm_layerCreateWithDimension_cannotSyncAcquireInstance) +{ + t_ilm_layer l_layerId = 600; + + ilm_context.initialized = false; + ASSERT_EQ(ILM_FAILED, ilm_layerCreateWithDimension(&l_layerId, 640, 480)); + + ilm_context.initialized = true; + SET_RETURN_SEQ(wl_display_roundtrip_queue, mp_failureResult, 1); + ASSERT_EQ(ILM_FAILED, ilm_layerCreateWithDimension(&l_layerId, 640, 480)); + + ASSERT_EQ(1, wl_display_roundtrip_queue_fake.call_count); + ASSERT_EQ(mp_failureResult[0], wl_display_roundtrip_queue_fake.return_val_history[0]); +} + +/** ================================================================================================ + * @test_id ilm_layerCreateWithDimension_invaildInput + * @brief Test case of ilm_layerCreateWithDimension() where input param wrong + * @test_procedure Steps: + * -# Mocking the wl_display_roundtrip_queue() does return 0 (success) + * -# Calling the ilm_layerCreateWithDimension() time 1 with pLayerId is null pointer + * -# Calling the ilm_layerCreateWithDimension() time 2 with valid layer id + * -# Verification point: + * +# ilm_layerCreateWithDimension() time 1 and time 2 must return ILM_FAILED + */ +TEST_F(IlmControlTest, ilm_layerCreateWithDimension_invaildInput) +{ + ilm_context.initialized = true; + SET_RETURN_SEQ(wl_display_roundtrip_queue, mp_successResult, 1); + + t_ilm_layer l_layerId = 100; + ASSERT_EQ(ILM_FAILED, ilm_layerCreateWithDimension(nullptr, 640, 480)); + ASSERT_EQ(ILM_FAILED, ilm_layerCreateWithDimension(&l_layerId, 640, 480)); +} + +/** ================================================================================================ + * @test_id ilm_layerCreateWithDimension_success + * @brief Test case of ilm_layerCreateWithDimension() where wl_display_roundtrip_queue() success, return 0 + * and invalid input param + * @test_procedure Steps: + * -# Set the ilm context initialized is true, ready init + * -# Mocking the wl_display_roundtrip_queue() does return 0 (success) + * -# Calling the ilm_layerCreateWithDimension() + * -# Verification point: + * +# ilm_layerCreateWithDimension() must return ILM_SUCCESS + * +# The result output should same with prepare data + */ +TEST_F(IlmControlTest, ilm_layerCreateWithDimension_success) +{ + wl_list_length_fake.custom_fake = custom_wl_list_length; + ilm_context.initialized = true; + SET_RETURN_SEQ(wl_display_roundtrip_queue, mp_successResult, 1); + + t_ilm_layer l_layerId = INVALID_ID; + ASSERT_EQ(ILM_SUCCESS, ilm_layerCreateWithDimension(&l_layerId, 640, 480)); + + ASSERT_EQ(0, l_layerId); +} + +/** ================================================================================================ + * @test_id ilm_layerRemove_wrongCtx + * @brief Test case of ilm_layerRemove() where ilm context wl.controller is null object + * @test_procedure Steps: + * -# Set the ilm context wl.controller is null object + * -# Calling the ilm_layerRemove() + * -# Verification point: + * +# ilm_layerRemove() must return ILM_FAILED + * +# wl_proxy_marshal_flags() not be called + * +# wl_display_roundtrip_queue() not be called + */ +TEST_F(IlmControlTest, ilm_layerRemove_wrongCtx) +{ + ilm_context.wl.controller = nullptr; + + t_ilm_layer l_layerId = 100; + ASSERT_EQ(ILM_FAILED, ilm_layerRemove(l_layerId)); + + ASSERT_EQ(0, wl_proxy_marshal_flags_fake.call_count); + ASSERT_EQ(0, wl_display_roundtrip_queue_fake.call_count); +} + +/** ================================================================================================ + * @test_id ilm_layerRemove_removeOne + * @brief Test case of ilm_layerRemove() where ilm context is initilized and valid layer id + * @test_procedure Steps: + * -# Calling the ilm_layerRemove() + * -# Verification point: + * +# ilm_layerRemove() must return ILM_SUCCESS + * +# wl_proxy_marshal_flags() must be called once time + * +# wl_display_roundtrip_queue() must be called once time + */ +TEST_F(IlmControlTest, ilm_layerRemove_removeOne) +{ + t_ilm_layer l_layerId = 100; + ASSERT_EQ(ILM_SUCCESS, ilm_layerRemove(l_layerId)); + + ASSERT_EQ(1, wl_proxy_marshal_flags_fake.call_count); + ASSERT_EQ(1, wl_display_roundtrip_queue_fake.call_count); +} + +/** ================================================================================================ + * @test_id ilm_layerAddSurface_wrongCtx + * @brief Test case of ilm_layerAddSurface() where ilm context wl.controller is null object + * @test_procedure Steps: + * -# Set the ilm context wl.controller is null object + * -# Calling the ilm_layerAddSurface() + * -# Verification point: + * +# ilm_layerAddSurface() must return ILM_FAILED + * +# wl_proxy_marshal_flags() not be called + * +# wl_display_flush() not be called + */ +TEST_F(IlmControlTest, ilm_layerAddSurface_wrongCtx) +{ + ilm_context.wl.controller = nullptr; + + t_ilm_layer l_layerId = 100; + t_ilm_surface l_surfaceId = 1; + ASSERT_EQ(ILM_FAILED, ilm_layerAddSurface(l_layerId, l_surfaceId)); + + ASSERT_EQ(0, wl_proxy_marshal_flags_fake.call_count); + ASSERT_EQ(0, wl_display_flush_fake.call_count); +} + +/** ================================================================================================ + * @test_id ilm_layerAddSurface_addOne + * @brief Test case of ilm_layerAddSurface() where ilm context is initilized and valid layer id, surface id + * @test_procedure Steps: + * -# Calling the ilm_layerAddSurface() + * -# Verification point: + * +# ilm_layerAddSurface() must return ILM_SUCCESS + * +# wl_proxy_marshal_flags() must be called once time + * +# wl_display_flush() must be called once time + */ +TEST_F(IlmControlTest, ilm_layerAddSurface_addOne) +{ + t_ilm_layer l_layerId = 100; + t_ilm_surface l_surfaceId = 1; + ASSERT_EQ(ILM_SUCCESS, ilm_layerAddSurface(l_layerId, l_surfaceId)); + + ASSERT_EQ(1, wl_proxy_marshal_flags_fake.call_count); + ASSERT_EQ(1, wl_display_flush_fake.call_count); +} + +/** ================================================================================================ + * @test_id ilm_layerRemoveSurface_wrongCtx + * @brief Test case of ilm_layerRemoveSurface() where ilm context wl.controller is null object + * @test_procedure Steps: + * -# Set the ilm context wl.controller is null object + * -# Calling the ilm_layerRemoveSurface() + * -# Verification point: + * +# ilm_layerRemoveSurface() must return ILM_FAILED + * +# wl_proxy_marshal_flags() not be called + * +# wl_display_flush() not be called + */ +TEST_F(IlmControlTest, ilm_layerRemoveSurface_wrongCtx) +{ + ilm_context.wl.controller = nullptr; + + t_ilm_layer l_layerId = 100; + t_ilm_surface l_surfaceId = 1; + ASSERT_EQ(ILM_FAILED, ilm_layerRemoveSurface(l_layerId, l_surfaceId)); + + ASSERT_EQ(0, wl_proxy_marshal_flags_fake.call_count); + ASSERT_EQ(0, wl_display_flush_fake.call_count); +} + +/** ================================================================================================ + * @test_id ilm_layerRemoveSurface_removeOne + * @brief Test case of ilm_layerRemoveSurface() where ilm context is initilized and valid layer id, surface id + * @test_procedure Steps: + * -# Calling the ilm_layerRemoveSurface() + * -# Verification point: + * +# ilm_layerRemoveSurface() must return ILM_SUCCESS + * +# wl_proxy_marshal_flags() must be called once time + * +# wl_display_flush() must be called once time + */ +TEST_F(IlmControlTest, ilm_layerRemoveSurface_removeOne) +{ + t_ilm_layer l_layerId = 100; + t_ilm_surface l_surfaceId = 1; + ASSERT_EQ(ILM_SUCCESS, ilm_layerRemoveSurface(l_layerId, l_surfaceId)); + + ASSERT_EQ(1, wl_proxy_marshal_flags_fake.call_count); + ASSERT_EQ(1, wl_display_flush_fake.call_count); +} + +/** ================================================================================================ + * @test_id ilm_layerSetVisibility_wrongCtx + * @brief Test case of ilm_layerSetVisibility() where ilm context wl.controller is null object + * @test_procedure Steps: + * -# Set the ilm context wl.controller is null object + * -# Calling the ilm_layerSetVisibility() + * -# Verification point: + * +# ilm_layerSetVisibility() must return ILM_FAILED + * +# wl_proxy_marshal_flags() not be called + * +# wl_display_flush() not be called + */ +TEST_F(IlmControlTest, ilm_layerSetVisibility_wrongCtx) +{ + ilm_context.wl.controller = nullptr; + + t_ilm_layer l_layerId = 100; + t_ilm_bool l_newVisibility = ILM_FALSE; + ASSERT_EQ(ILM_FAILED, ilm_layerSetVisibility(l_layerId, l_newVisibility)); + + ASSERT_EQ(0, wl_proxy_marshal_flags_fake.call_count); + ASSERT_EQ(0, wl_display_flush_fake.call_count); +} + +/** ================================================================================================ + * @test_id ilm_layerSetVisibility_success + * @brief Test case of ilm_layerSetVisibility() where ilm context is initilized and valid layer id + * @test_procedure Steps: + * -# Calling the ilm_layerSetVisibility() + * -# Verification point: + * +# ilm_layerSetVisibility() must return ILM_SUCCESS + * +# wl_proxy_marshal_flags() must be called once time + * +# wl_display_flush() must be called once time + */ +TEST_F(IlmControlTest, ilm_layerSetVisibility_success) +{ + t_ilm_layer l_layerId = 100; + t_ilm_bool l_newVisibility = ILM_TRUE; + ASSERT_EQ(ILM_SUCCESS, ilm_layerSetVisibility(l_layerId, l_newVisibility)); + + ASSERT_EQ(1, wl_proxy_marshal_flags_fake.call_count); + ASSERT_EQ(1, wl_display_flush_fake.call_count); +} + +/** ================================================================================================ + * @test_id ilm_layerGetVisibility_wrongVisibility + * @brief Test case of ilm_layerGetVisibility() where input pVisibility is null pointer + * @test_procedure Steps: + * -# Set pVisibility is null pointer + * -# Calling the ilm_layerGetVisibility() + * -# Verification point: + * +# ilm_layerGetVisibility() must return ILM_FAILED + * +# wl_proxy_marshal_flags() not be called + * +# wl_display_roundtrip_queue() not be called + */ +TEST_F(IlmControlTest, ilm_layerGetVisibility_wrongVisibility) +{ + t_ilm_layer l_layerId = 100; + t_ilm_bool* p_Visibility = nullptr; + ASSERT_EQ(ILM_FAILED, ilm_layerGetVisibility(l_layerId, p_Visibility)); + + ASSERT_EQ(0, wl_proxy_marshal_flags_fake.call_count); + ASSERT_EQ(0, wl_display_roundtrip_queue_fake.call_count); +} + +/** ================================================================================================ + * @test_id ilm_layerGetVisibility_cannotGetRoundTripQueue + * @brief Test case of ilm_layerGetVisibility() where wl_display_roundtrip_queue() fails, return -1 + * @test_procedure Steps: + * -# Mocking the wl_display_roundtrip_queue() does return -1 + * -# Calling the ilm_layerGetVisibility() + * -# Verification point: + * +# ilm_layerGetVisibility() must return ILM_FAILED + * +# wl_proxy_marshal_flags() must be called once time + * +# wl_display_roundtrip_queue() must be called once time + */ +TEST_F(IlmControlTest, ilm_layerGetVisibility_cannotGetRoundTripQueue) +{ + SET_RETURN_SEQ(wl_display_roundtrip_queue, mp_failureResult, 1); + + t_ilm_layer l_layerId = 100; + t_ilm_bool l_visibility = 1; + ASSERT_EQ(ILM_FAILED, ilm_layerGetVisibility(l_layerId, &l_visibility)); + + ASSERT_EQ(1, wl_proxy_marshal_flags_fake.call_count); + ASSERT_EQ(1, wl_display_roundtrip_queue_fake.call_count); +} + +/** ================================================================================================ + * @test_id ilm_layerGetVisibility_invalidLayerId + * @brief Test case of ilm_layerGetVisibility() where invalid layer id + * @test_procedure Steps: + * -# Mocking the wl_display_roundtrip_queue() does return 0 (success) + * -# Calling the ilm_layerGetVisibility() with invalid layer id + * -# Verification point: + * +# ilm_layerGetVisibility() must return ILM_FAILED + * +# wl_proxy_marshal_flags() must be called once time + * +# wl_display_roundtrip_queue() must be called once time + */ +TEST_F(IlmControlTest, ilm_layerGetVisibility_invalidLayerId) +{ + SET_RETURN_SEQ(wl_display_roundtrip_queue, mp_successResult, 1); + + t_ilm_layer l_layerId = 600; + t_ilm_bool l_visibility = 1; + ASSERT_EQ(ILM_FAILED, ilm_layerGetVisibility(l_layerId, &l_visibility)); + + ASSERT_EQ(1, wl_proxy_marshal_flags_fake.call_count); + ASSERT_EQ(1, wl_display_roundtrip_queue_fake.call_count); +} + +/** ================================================================================================ + * @test_id ilm_layerGetVisibility_success + * @brief Test case of ilm_layerGetVisibility() where wl_display_roundtrip_queue() success, return 0 + * and valid layer id + * @test_procedure Steps: + * -# Mocking the wl_display_roundtrip_queue() does return 0 + * -# Calling the ilm_layerGetVisibility() + * -# Verification point: + * +# ilm_layerGetVisibility() must return ILM_SUCCESS + * +# wl_proxy_marshal_flags() must be called once time + * +# wl_display_roundtrip_queue() must be called once time + */ +TEST_F(IlmControlTest, ilm_layerGetVisibility_success) +{ + SET_RETURN_SEQ(wl_display_roundtrip_queue, mp_successResult, 1); + + t_ilm_layer l_layerId = 100; + t_ilm_bool l_visibility = 1; + ASSERT_EQ(ILM_SUCCESS, ilm_layerGetVisibility(l_layerId, &l_visibility)); + + ASSERT_EQ(1, wl_proxy_marshal_flags_fake.call_count); + ASSERT_EQ(1, wl_display_roundtrip_queue_fake.call_count); +} + +/** ================================================================================================ + * @test_id ilm_layerSetOpacity_wrongCtx + * @brief Test case of ilm_layerSetOpacity() where ilm context wl.controller is null object + * @test_procedure Steps: + * -# Set the ilm context wl.controller is null object + * -# Calling the ilm_layerSetOpacity() + * -# Verification point: + * +# ilm_layerSetOpacity() must return ILM_FAILED + * +# wl_proxy_marshal_flags() not be called + * +# wl_display_flush() not be called + */ +TEST_F(IlmControlTest, ilm_layerSetOpacity_wrongCtx) +{ + ilm_context.wl.controller = nullptr; + + t_ilm_layer l_layerId = 100; + t_ilm_float l_opacity = 1; + ASSERT_EQ(ILM_FAILED, ilm_layerSetOpacity(l_layerId, l_opacity)); + + ASSERT_EQ(0, wl_proxy_marshal_flags_fake.call_count); + ASSERT_EQ(0, wl_display_flush_fake.call_count); +} + +/** ================================================================================================ + * @test_id ilm_layerSetOpacity_success + * @brief Test case of ilm_layerSetOpacity() where ilm context is initilized and valid layer id + * @test_procedure Steps: + * -# Calling the ilm_layerSetOpacity() + * -# Verification point: + * +# ilm_layerSetOpacity() must return ILM_SUCCESS + * +# wl_proxy_marshal_flags() must be called once time + * +# wl_display_flush() must be called once time + */ +TEST_F(IlmControlTest, ilm_layerSetOpacity_success) +{ + t_ilm_layer l_layerId = 100; + t_ilm_float l_opacity = 1; + ASSERT_EQ(ILM_SUCCESS, ilm_layerSetOpacity(l_layerId, l_opacity)); + + ASSERT_EQ(1, wl_proxy_marshal_flags_fake.call_count); + ASSERT_EQ(1, wl_display_flush_fake.call_count); +} + +/** ================================================================================================ + * @test_id ilm_layerGetOpacity_wrongVisibility + * @brief Test case of ilm_layerGetOpacity() where input pOpacity is null pointer + * @test_procedure Steps: + * -# Set pOpacity is null pointer + * -# Calling the ilm_layerGetOpacity() + * -# Verification point: + * +# ilm_layerGetOpacity() must return ILM_FAILED + * +# wl_proxy_marshal_flags() not be called + * +# wl_display_roundtrip_queue() not be called + */ +TEST_F(IlmControlTest, ilm_layerGetOpacity_wrongVisibility) +{ + t_ilm_layer l_layerId = 100; + t_ilm_float *p_opacity = nullptr; + ASSERT_EQ(ILM_FAILED, ilm_layerGetOpacity(l_layerId, p_opacity)); + + ASSERT_EQ(0, wl_proxy_marshal_flags_fake.call_count); + ASSERT_EQ(0, wl_display_roundtrip_queue_fake.call_count); +} + +/** ================================================================================================ + * @test_id ilm_layerGetOpacity_cannotGetRoundTripQueue + * @brief Test case of ilm_layerGetOpacity() where wl_display_roundtrip_queue() fails, return -1 + * @test_procedure Steps: + * -# Mocking the wl_display_roundtrip_queue() does return -1 + * -# Calling the ilm_layerGetOpacity() + * -# Verification point: + * +# ilm_layerGetOpacity() must return ILM_FAILED + * +# wl_proxy_marshal_flags() must be called once time + * +# wl_display_roundtrip_queue() must be called once time + */ +TEST_F(IlmControlTest, ilm_layerGetOpacity_cannotGetRoundTripQueue) +{ + SET_RETURN_SEQ(wl_display_roundtrip_queue, mp_failureResult, 1); + + t_ilm_layer l_layerId = 100; + t_ilm_float l_opacity = 0.5; + ASSERT_EQ(ILM_FAILED, ilm_layerGetOpacity(l_layerId, &l_opacity)); + + ASSERT_EQ(1, wl_proxy_marshal_flags_fake.call_count); + ASSERT_EQ(1, wl_display_roundtrip_queue_fake.call_count); +} + +/** ================================================================================================ + * @test_id iilm_layerGetOpacity_invalidLayerId + * @brief Test case of ilm_layerGetOpacity() where invalid layer id + * @test_procedure Steps: + * -# Mocking the wl_display_roundtrip_queue() does return 0 (success) + * -# Calling the ilm_layerGetOpacity() with invalid layer id + * -# Verification point: + * +# ilm_layerGetOpacity() must return ILM_FAILED + * +# wl_proxy_marshal_flags() must be called once time + * +# wl_display_roundtrip_queue() must be called once time + */ +TEST_F(IlmControlTest, iilm_layerGetOpacity_invalidLayerId) +{ + SET_RETURN_SEQ(wl_display_roundtrip_queue, mp_successResult, 1); + + t_ilm_layer l_layerId = 600; + t_ilm_float l_opacity = 0.5; + ASSERT_EQ(ILM_FAILED, ilm_layerGetOpacity(l_layerId, &l_opacity)); + + ASSERT_EQ(1, wl_proxy_marshal_flags_fake.call_count); + ASSERT_EQ(1, wl_display_roundtrip_queue_fake.call_count); +} + +/** ================================================================================================ + * @test_id ilm_layerGetOpacity_success + * @brief Test case of ilm_layerGetOpacity() where wl_display_roundtrip_queue() success, return 0 + * and valid layer id + * @test_procedure Steps: + * -# Mocking the wl_display_roundtrip_queue() does return 0 + * -# Calling the ilm_layerGetOpacity() + * -# Verification point: + * +# ilm_layerGetOpacity() must return ILM_SUCCESS + * +# wl_proxy_marshal_flags() must be called once time + * +# wl_display_roundtrip_queue() must be called once time + */ +TEST_F(IlmControlTest, ilm_layerGetOpacity_success) +{ + SET_RETURN_SEQ(wl_display_roundtrip_queue, mp_successResult, 1); + + t_ilm_layer l_layerId = 100; + t_ilm_float l_opacity = 0.5; + ASSERT_EQ(ILM_SUCCESS, ilm_layerGetOpacity(l_layerId, &l_opacity)); + + ASSERT_EQ(1, wl_proxy_marshal_flags_fake.call_count); + ASSERT_EQ(1, wl_display_roundtrip_queue_fake.call_count); +} + +/** ================================================================================================ + * @test_id ilm_layerSetSourceRectangle_wrongCtx + * @brief Test case of ilm_layerSetSourceRectangle() where ilm context wl.controller is null object + * @test_procedure Steps: + * -# Set the ilm context wl.controller is null object + * -# Calling the ilm_layerSetSourceRectangle() + * -# Verification point: + * +# ilm_layerSetSourceRectangle() must return ILM_FAILED + * +# wl_proxy_marshal_flags() not be called + * +# wl_display_flush() not be called + */ +TEST_F(IlmControlTest, ilm_layerSetSourceRectangle_wrongCtx) +{ + ilm_context.wl.controller = nullptr; + + t_ilm_layer l_layerId = 100; + ASSERT_EQ(ILM_FAILED, ilm_layerSetSourceRectangle(l_layerId, 0, 0, 640, 480)); + + ASSERT_EQ(0, wl_proxy_marshal_flags_fake.call_count); + ASSERT_EQ(0, wl_display_flush_fake.call_count); +} + +/** ================================================================================================ + * @test_id ilm_layerSetSourceRectangle_success + * @brief Test case of ilm_layerSetSourceRectangle() where ilm context is initilized and valid layer id + * @test_procedure Steps: + * -# Calling the ilm_layerSetSourceRectangle() + * -# Verification point: + * +# ilm_layerSetSourceRectangle() must return ILM_SUCCESS + * +# wl_proxy_marshal_flags() must be called once time + * +# wl_display_flush() must be called once time + */ +TEST_F(IlmControlTest, ilm_layerSetSourceRectangle_success) +{ + t_ilm_layer l_layerId = 100; + ASSERT_EQ(ILM_SUCCESS, ilm_layerSetSourceRectangle(l_layerId, 0, 0, 640, 480)); + + ASSERT_EQ(1, wl_proxy_marshal_flags_fake.call_count); + ASSERT_EQ(1, wl_display_flush_fake.call_count); +} + +/** ================================================================================================ + * @test_id ilm_layerSetDestinationRectangle_wrongCtx + * @brief Test case of ilm_layerSetDestinationRectangle() where ilm context wl.controller is null object + * @test_procedure Steps: + * -# Set the ilm context wl.controller is null object + * -# Calling the ilm_layerSetDestinationRectangle() + * -# Verification point: + * +# ilm_layerSetDestinationRectangle() must return ILM_FAILED + * +# wl_proxy_marshal_flags() not be called + * +# wl_display_flush() not be called + */ +TEST_F(IlmControlTest, ilm_layerSetDestinationRectangle_wrongCtx) +{ + ilm_context.wl.controller = nullptr; + + t_ilm_layer l_layerId = 100; + ASSERT_EQ(ILM_FAILED, ilm_layerSetDestinationRectangle(l_layerId, 0, 0, 640, 480)); + + ASSERT_EQ(0, wl_proxy_marshal_flags_fake.call_count); + ASSERT_EQ(0, wl_display_flush_fake.call_count); +} + +/** ================================================================================================ + * @test_id ilm_layerSetDestinationRectangle_success + * @brief Test case of ilm_layerSetDestinationRectangle() where ilm context is initilized and valid layer id + * @test_procedure Steps: + * -# Calling the ilm_layerSetDestinationRectangle() + * -# Verification point: + * +# ilm_layerSetDestinationRectangle() must return ILM_SUCCESS + * +# wl_proxy_marshal_flags() must be called once time + * +# wl_display_flush() must be called once time + */ +TEST_F(IlmControlTest, ilm_layerSetDestinationRectangle_success) +{ + t_ilm_layer l_layerId = 100; + ASSERT_EQ(ILM_SUCCESS, ilm_layerSetDestinationRectangle(l_layerId, 0, 0, 640, 480)); + + ASSERT_EQ(1, wl_proxy_marshal_flags_fake.call_count); + ASSERT_EQ(1, wl_display_flush_fake.call_count); +} + +/** ================================================================================================ + * @test_id ilm_layerSetRenderOrder_wrongCtx + * @brief Test case of ilm_layerSetRenderOrder() where ilm context wl.controller is null object + * @test_procedure Steps: + * -# Set the ilm context wl.controller is null object + * -# Calling the ilm_layerSetRenderOrder() + * -# Verification point: + * +# ilm_layerSetRenderOrder() must return ILM_FAILED + * +# wl_proxy_marshal_flags() not be called + * +# wl_display_flush() not be called + */ +TEST_F(IlmControlTest, ilm_layerSetRenderOrder_wrongCtx) +{ + ilm_context.wl.controller = nullptr; + + t_ilm_layer l_layerId = 100; + t_ilm_int l_number = 1; + ASSERT_EQ(ILM_FAILED, ilm_layerSetRenderOrder(l_layerId, mp_ilmSurfaceIds, l_number)); + + ASSERT_EQ(0, wl_proxy_marshal_flags_fake.call_count); + ASSERT_EQ(0, wl_display_flush_fake.call_count); +} + +/** ================================================================================================ + * @test_id ilm_layerSetRenderOrder_success + * @brief Test case of ilm_layerSetRenderOrder() where ilm context is initilized and valid layer id + * @test_procedure Steps: + * -# Calling the ilm_layerSetRenderOrder() + * -# Verification point: + * +# ilm_layerSetRenderOrder() must return ILM_SUCCESS + * +# wl_proxy_marshal_flags() must be called {1+l_number} time + * +# wl_display_flush() must be called once time + */ +TEST_F(IlmControlTest, ilm_layerSetRenderOrder_success) +{ + t_ilm_layer l_layerId = 100; + t_ilm_int l_number = MAX_NUMBER; + ASSERT_EQ(ILM_SUCCESS, ilm_layerSetRenderOrder(l_layerId, mp_ilmSurfaceIds, l_number)); + + ASSERT_EQ(1 + l_number, wl_proxy_marshal_flags_fake.call_count); + ASSERT_EQ(1, wl_display_flush_fake.call_count); +} + +/** ================================================================================================ + * @test_id ilm_surfaceSetVisibility_wrongCtx + * @brief Test case of ilm_surfaceSetVisibility() where ilm context wl.controller is null object + * @test_procedure Steps: + * -# Set the ilm context wl.controller is null object + * -# Calling the ilm_surfaceSetVisibility() + * -# Verification point: + * +# ilm_surfaceSetVisibility() must return ILM_FAILED + * +# wl_proxy_marshal_flags() not be called + * +# wl_display_flush() not be called + */ +TEST_F(IlmControlTest, ilm_surfaceSetVisibility_wrongCtx) +{ + ilm_context.wl.controller = nullptr; + + t_ilm_surface l_surfaceId = 1; + t_ilm_bool l_newVisibility = ILM_FALSE; + ASSERT_EQ(ILM_FAILED, ilm_surfaceSetVisibility(l_surfaceId, l_newVisibility)); + + ASSERT_EQ(0, wl_proxy_marshal_flags_fake.call_count); + ASSERT_EQ(0, wl_display_flush_fake.call_count); +} + +/** ================================================================================================ + * @test_id ilm_surfaceSetVisibility_success + * @brief Test case of ilm_surfaceSetVisibility() where ilm context is initilized and valid surface id + * @test_procedure Steps: + * -# Calling the ilm_surfaceSetVisibility() + * -# Verification point: + * +# ilm_surfaceSetVisibility() must return ILM_SUCCESS + * +# wl_proxy_marshal_flags() must be called once time + * +# wl_display_flush() must be called once time + */ +TEST_F(IlmControlTest, ilm_surfaceSetVisibility_success) +{ + t_ilm_surface l_surfaceId = 1; + t_ilm_bool l_newVisibility = ILM_TRUE; + ASSERT_EQ(ILM_SUCCESS, ilm_surfaceSetVisibility(l_surfaceId, l_newVisibility)); + + ASSERT_EQ(1, wl_proxy_marshal_flags_fake.call_count); + ASSERT_EQ(1, wl_display_flush_fake.call_count); +} + +/** ================================================================================================ + * @test_id ilm_surfaceGetVisibility_wrongVisibility + * @brief Test case of ilm_surfaceGetVisibility() where input pVisibility is null pointer + * @test_procedure Steps: + * -# Set pVisibility is null pointer + * -# Calling the ilm_surfaceGetVisibility() + * -# Verification point: + * +# ilm_surfaceGetVisibility() must return ILM_FAILED + * +# wl_proxy_marshal_flags() not be called + * +# wl_display_roundtrip_queue() not be called + */ +TEST_F(IlmControlTest, ilm_surfaceGetVisibility_wrongVisibility) +{ + t_ilm_surface l_surfaceId = 1; + t_ilm_bool* p_visibility = nullptr; + ASSERT_EQ(ILM_FAILED, ilm_surfaceGetVisibility(l_surfaceId, p_visibility)); + + ASSERT_EQ(0, wl_proxy_marshal_flags_fake.call_count); + ASSERT_EQ(0, wl_display_roundtrip_queue_fake.call_count); +} + +/** ================================================================================================ + * @test_id ilm_surfaceGetVisibility_cannotGetRoundTripQueue + * @brief Test case of ilm_surfaceGetVisibility() where wl_display_roundtrip_queue() fails, return -1 + * @test_procedure Steps: + * -# Mocking the wl_display_roundtrip_queue() does return -1 + * -# Calling the ilm_surfaceGetVisibility() + * -# Verification point: + * +# ilm_surfaceGetVisibility() must return ILM_FAILED + * +# wl_proxy_marshal_flags() must be called once time + * +# wl_display_roundtrip_queue() must be called once time + */ +TEST_F(IlmControlTest, ilm_surfaceGetVisibility_cannotGetRoundTripQueue) +{ + SET_RETURN_SEQ(wl_display_roundtrip_queue, mp_failureResult, 1); + + t_ilm_surface l_surfaceId = 1; + t_ilm_bool l_visibility = 1; + ASSERT_EQ(ILM_FAILED, ilm_surfaceGetVisibility(l_surfaceId, &l_visibility)); + + ASSERT_EQ(1, wl_proxy_marshal_flags_fake.call_count); + ASSERT_EQ(1, wl_display_roundtrip_queue_fake.call_count); +} + +/** ================================================================================================ + * @test_id ilm_surfaceGetVisibility_invalidSurfaceId + * @brief Test case of ilm_surfaceGetVisibility() where invalid surface id + * @test_procedure Steps: + * -# Mocking the wl_display_roundtrip_queue() does return 0 (success) + * -# Calling the ilm_surfaceGetVisibility() with invalid surface id + * -# Verification point: + * +# ilm_surfaceGetVisibility() must return ILM_FAILED + * +# wl_proxy_marshal_flags() must be called once time + * +# wl_display_roundtrip_queue() must be called once time + */ +TEST_F(IlmControlTest, ilm_surfaceGetVisibility_invalidSurfaceId) +{ + SET_RETURN_SEQ(wl_display_roundtrip_queue, mp_successResult, 1); + + t_ilm_surface l_surfaceId = 6; + t_ilm_bool l_visibility = 1; + ASSERT_EQ(ILM_FAILED, ilm_surfaceGetVisibility(l_surfaceId, &l_visibility)); + + ASSERT_EQ(1, wl_proxy_marshal_flags_fake.call_count); + ASSERT_EQ(1, wl_display_roundtrip_queue_fake.call_count); +} + +/** ================================================================================================ + * @test_id ilm_surfaceGetVisibility_success + * @brief Test case of ilm_surfaceGetVisibility() where wl_display_roundtrip_queue() success, return 0 + * and valid surface id + * @test_procedure Steps: + * -# Mocking the wl_display_roundtrip_queue() does return 0 (success) + * -# Calling the ilm_surfaceGetVisibility() + * -# Verification point: + * +# ilm_surfaceGetVisibility() must return ILM_SUCCESS + * +# wl_proxy_marshal_flags() must be called once time + * +# wl_display_roundtrip_queue() must be called once time + */ +TEST_F(IlmControlTest, ilm_surfaceGetVisibility_success) +{ + SET_RETURN_SEQ(wl_display_roundtrip_queue, mp_successResult, 1); + + t_ilm_surface l_surfaceId = 1; + t_ilm_bool l_visibility = 1; + ASSERT_EQ(ILM_SUCCESS, ilm_surfaceGetVisibility(l_surfaceId, &l_visibility)); + + ASSERT_EQ(1, wl_proxy_marshal_flags_fake.call_count); + ASSERT_EQ(1, wl_display_roundtrip_queue_fake.call_count); +} + +/** ================================================================================================ + * @test_id ilm_surfaceSetOpacity_wrongCtx + * @brief Test case of ilm_surfaceSetOpacity() where ilm context wl.controller is null object + * @test_procedure Steps: + * -# Set the ilm context wl.controller is null object + * -# Calling the ilm_surfaceSetOpacity() + * -# Verification point: + * +# ilm_surfaceSetOpacity() must return ILM_FAILED + * +# wl_proxy_marshal_flags() not be called + * +# wl_display_flush() not be called + */ +TEST_F(IlmControlTest, ilm_surfaceSetOpacity_wrongCtx) +{ + ilm_context.wl.controller = nullptr; + + t_ilm_surface l_surfaceId = 1; + t_ilm_float opacity = 0.5; + ASSERT_EQ(ILM_FAILED, ilm_surfaceSetOpacity(l_surfaceId, opacity)); + + ASSERT_EQ(0, wl_proxy_marshal_flags_fake.call_count); + ASSERT_EQ(0, wl_display_flush_fake.call_count); +} + +/** ================================================================================================ + * @test_id ilm_surfaceSetOpacity_success + * @brief Test case of ilm_surfaceSetOpacity() where ilm context is initilized and valid surface id + * @test_procedure Steps: + * -# Calling the ilm_surfaceSetOpacity() + * -# Verification point: + * +# ilm_surfaceSetOpacity() must return ILM_SUCCESS + * +# wl_proxy_marshal_flags() must be called once time + * +# wl_display_flush() must be called once time + */ +TEST_F(IlmControlTest, ilm_surfaceSetOpacity_success) +{ + t_ilm_surface l_surfaceId = 1; + t_ilm_float opacity = 0.5; + ASSERT_EQ(ILM_SUCCESS, ilm_surfaceSetOpacity(l_surfaceId, opacity)); + + ASSERT_EQ(1, wl_proxy_marshal_flags_fake.call_count); + ASSERT_EQ(1, wl_display_flush_fake.call_count); +} + +/** ================================================================================================ + * @test_id ilm_surfaceGetOpacity_wrongVisibility + * @brief Test case of ilm_surfaceGetOpacity() where input pOpacity is null pointer + * @test_procedure Steps: + * -# Set pOpacity is null pointer + * -# Calling the ilm_surfaceGetOpacity() + * -# Verification point: + * +# ilm_surfaceGetOpacity() must return ILM_FAILED + * +# wl_proxy_marshal_flags() not be called + * +# wl_display_roundtrip_queue() not be called + */ +TEST_F(IlmControlTest, ilm_surfaceGetOpacity_wrongVisibility) +{ + t_ilm_surface l_surfaceId = 1; + t_ilm_float *p_opacity = nullptr; + ASSERT_EQ(ILM_FAILED, ilm_surfaceGetOpacity(l_surfaceId, p_opacity)); + + ASSERT_EQ(0, wl_proxy_marshal_flags_fake.call_count); + ASSERT_EQ(0, wl_display_roundtrip_queue_fake.call_count); +} + +/** ================================================================================================ + * @test_id ilm_surfaceGetOpacity_cannotGetRoundTripQueue + * @brief Test case of ilm_surfaceGetOpacity() where wl_display_roundtrip_queue() fails, return -1 + * and ilm_context wl.controller does return null object + * @test_procedure Steps: + * -# Mocking the wl_display_roundtrip_queue() does return -1 + * -# Calling the ilm_surfaceGetOpacity() time 1 with ilm_context wl.controller doesn't return null object + * -# Calling the ilm_surfaceGetOpacity() time 2 with ilm_context wl.controller does return null object + * -# Verification point: + * +# Both of ilm_surfaceGetOpacity() time 1 and time 2 must return ILM_FAILED + * +# wl_proxy_marshal_flags() must be called + * +# wl_display_roundtrip_queue() must be called + */ +TEST_F(IlmControlTest, ilm_surfaceGetOpacity_cannotGetRoundTripQueue) +{ + SET_RETURN_SEQ(wl_display_roundtrip_queue, mp_failureResult, 1); + + t_ilm_surface l_surfaceId = 1; + t_ilm_float l_opacity = 1; + ASSERT_EQ(ILM_FAILED, ilm_surfaceGetOpacity(l_surfaceId, &l_opacity)); + + ASSERT_EQ(1, wl_proxy_marshal_flags_fake.call_count); + ASSERT_EQ(1, wl_display_roundtrip_queue_fake.call_count); + + ilm_context.wl.controller = nullptr; + ASSERT_EQ(ILM_FAILED, ilm_surfaceGetOpacity(l_surfaceId, &l_opacity)); + + ASSERT_EQ(2, wl_proxy_marshal_flags_fake.call_count); + ASSERT_EQ(2, wl_display_roundtrip_queue_fake.call_count); +} + +/** ================================================================================================ + * @test_id ilm_surfaceGetOpacity_invalidLayerId + * @brief Test case of ilm_surfaceGetOpacity() where invalid layer id + * @test_procedure Steps: + * -# Mocking the wl_display_roundtrip_queue() does return 0 (success) + * -# Calling the ilm_surfaceGetOpacity() with invalid layer id + * -# Verification point: + * +# ilm_surfaceGetOpacity() must return ILM_FAILED + * +# wl_proxy_marshal_flags() must be called once time + * +# wl_display_roundtrip_queue() must be called once time + */ +TEST_F(IlmControlTest, ilm_surfaceGetOpacity_invalidLayerId) +{ + SET_RETURN_SEQ(wl_display_roundtrip_queue, mp_successResult, 1); + + t_ilm_surface l_surfaceId = 6; + t_ilm_float l_opacity = 1; + ASSERT_EQ(ILM_FAILED, ilm_surfaceGetOpacity(l_surfaceId, &l_opacity)); + + ASSERT_EQ(1, wl_proxy_marshal_flags_fake.call_count); + ASSERT_EQ(1, wl_display_roundtrip_queue_fake.call_count); +} + +/** ================================================================================================ + * @test_id ilm_surfaceGetOpacity_success + * @brief Test case of ilm_surfaceGetOpacity() where wl_display_roundtrip_queue() success, return 0 + * and valid surface id + * @test_procedure Steps: + * -# Mocking the wl_display_roundtrip_queue() does return 0 (success) + * -# Calling the ilm_surfaceGetOpacity() + * -# Verification point: + * +# ilm_surfaceGetOpacity() must return ILM_SUCCESS + * +# wl_proxy_marshal_flags() must be called once time + * +# wl_display_roundtrip_queue() must be called once time + */ +TEST_F(IlmControlTest, ilm_surfaceGetOpacity_success) +{ + SET_RETURN_SEQ(wl_display_roundtrip_queue, mp_successResult, 1); + + t_ilm_surface l_surfaceId = 1; + t_ilm_float l_opacity = 1; + ASSERT_EQ(ILM_SUCCESS, ilm_surfaceGetOpacity(l_surfaceId, &l_opacity)); + + ASSERT_EQ(1, wl_proxy_marshal_flags_fake.call_count); + ASSERT_EQ(1, wl_display_roundtrip_queue_fake.call_count); +} + +/** ================================================================================================ + * @test_id ilm_surfaceSetSourceRectangle_wrongCtx + * @brief Test case of ilm_surfaceSetSourceRectangle() where ilm context wl.controller is null object + * @test_procedure Steps: + * -# Set the ilm context wl.controller is null object + * -# Calling the ilm_surfaceSetSourceRectangle() + * -# Verification point: + * +# ilm_surfaceSetSourceRectangle() must return ILM_FAILED + * +# wl_proxy_marshal_flags() not be called + * +# wl_display_flush() not be called + */ +TEST_F(IlmControlTest, ilm_surfaceSetSourceRectangle_wrongCtx) +{ + ilm_context.wl.controller = nullptr; + + t_ilm_surface l_surfaceId = 1; + ASSERT_EQ(ILM_FAILED, ilm_surfaceSetSourceRectangle(l_surfaceId, 0, 0, 640, 480)); + + ASSERT_EQ(0, wl_proxy_marshal_flags_fake.call_count); + ASSERT_EQ(0, wl_display_flush_fake.call_count); +} + +/** ================================================================================================ + * @test_id ilm_surfaceSetSourceRectangle_success + * @brief Test case of ilm_surfaceSetSourceRectangle() where ilm context is initilized + * and valid surface id + * @test_procedure Steps: + * -# Calling the ilm_surfaceSetSourceRectangle() + * -# Verification point: + * +# ilm_surfaceSetSourceRectangle() must return ILM_SUCCESS + * +# wl_proxy_marshal_flags() must be called once time + * +# wl_display_flush() must be called once time + */ +TEST_F(IlmControlTest, ilm_surfaceSetSourceRectangle_success) +{ + t_ilm_surface l_surfaceId = 1; + ASSERT_EQ(ILM_SUCCESS, ilm_surfaceSetSourceRectangle(l_surfaceId, 0, 0, 640, 480)); + + ASSERT_EQ(1, wl_proxy_marshal_flags_fake.call_count); + ASSERT_EQ(1, wl_display_flush_fake.call_count); +} + +/** ================================================================================================ + * @test_id ilm_surfaceSetDestinationRectangle_wrongCtx + * @brief Test case of ilm_surfaceSetDestinationRectangle() where ilm context wl.controller is null object + * @test_procedure Steps: + * -# Set the ilm context wl.controller is null object + * -# Calling the ilm_surfaceSetDestinationRectangle() + * -# Verification point: + * +# ilm_surfaceSetDestinationRectangle() must return ILM_FAILED + * +# wl_proxy_marshal_flags() not be called + * +# wl_display_flush() not be called + */ +TEST_F(IlmControlTest, ilm_surfaceSetDestinationRectangle_wrongCtx) +{ + ilm_context.wl.controller = nullptr; + + t_ilm_surface l_surfaceId = 1; + ASSERT_EQ(ILM_FAILED, ilm_surfaceSetDestinationRectangle(l_surfaceId, 0, 0, 640, 480)); + + ASSERT_EQ(0, wl_proxy_marshal_flags_fake.call_count); + ASSERT_EQ(0, wl_display_flush_fake.call_count); +} + +/** ================================================================================================ + * @test_id ilm_surfaceSetDestinationRectangle_success + * @brief Test case of ilm_surfaceSetDestinationRectangle() where ilm context is initilized + * and valid surface id + * @test_procedure Steps: + * -# Calling the ilm_surfaceSetDestinationRectangle() + * -# Verification point: + * +# ilm_surfaceSetDestinationRectangle() must return ILM_SUCCESS + * +# wl_proxy_marshal_flags() must be called once time + * +# wl_display_flush() must be called once time + */ +TEST_F(IlmControlTest, ilm_surfaceSetDestinationRectangle_success) +{ + t_ilm_surface l_surfaceId = 1; + ASSERT_EQ(ILM_SUCCESS, ilm_surfaceSetDestinationRectangle(l_surfaceId, 0, 0, 640, 480)); + + ASSERT_EQ(1, wl_proxy_marshal_flags_fake.call_count); + ASSERT_EQ(1, wl_display_flush_fake.call_count); +} + +/** ================================================================================================ + * @test_id ilm_surfaceSetType_wrongType + * @brief Test case of ilm_surfaceSetType() where input ilmSurfaceType is wrong + * @test_procedure Steps: + * -# Calling the ilm_surfaceSetType() with invalid input ilmSurfaceType + * -# Verification point: + * +# ilm_surfaceSetType() must return ILM_ERROR_INVALID_ARGUMENTS + * +# wl_proxy_marshal_flags() not be called + * +# wl_display_flush() not be called + */ +TEST_F(IlmControlTest, ilm_surfaceSetType_wrongType) +{ + t_ilm_surface l_surfaceId = 1; + ilmSurfaceType l_type = (ilmSurfaceType)3; + ASSERT_EQ(ILM_ERROR_INVALID_ARGUMENTS, ilm_surfaceSetType(l_surfaceId, l_type)); + + ASSERT_EQ(0, wl_proxy_marshal_flags_fake.call_count); + ASSERT_EQ(0, wl_display_flush_fake.call_count); +} + +/** ================================================================================================ + * @test_id ilm_surfaceSetType_wrongCtx + * @brief Test case of ilm_surfaceSetType() where ilm context wl.controller is null object + * @test_procedure Steps: + * -# Set the ilm context wl.controller is null object + * -# Calling the ilm_surfaceSetType() time 1 with input ilmSurfaceType is ILM_SURFACETYPE_RESTRICTED + * -# Calling the ilm_surfaceSetType() time 2 with input ilmSurfaceType is ILM_SURFACETYPE_DESKTOP + * -# Verification point: + * +# Both of ilm_surfaceSetType() time 1 and time 2 must return ILM_FAILED + * +# wl_proxy_marshal_flags() not be called + * +# wl_display_flush() not be called + */ +TEST_F(IlmControlTest, ilm_surfaceSetType_wrongCtx) +{ + ilm_context.wl.controller = nullptr; + + t_ilm_surface l_surfaceId = 1; + ASSERT_EQ(ILM_FAILED, ilm_surfaceSetType(l_surfaceId, ILM_SURFACETYPE_RESTRICTED)); + ASSERT_EQ(ILM_FAILED, ilm_surfaceSetType(l_surfaceId, ILM_SURFACETYPE_DESKTOP)); + + ASSERT_EQ(0, wl_proxy_marshal_flags_fake.call_count); + ASSERT_EQ(0, wl_display_flush_fake.call_count); +} + +/** ================================================================================================ + * @test_id ilm_surfaceSetType_success + * @brief Test case of ilm_surfaceSetType() where ilm context is initilized + * and valid surface id + * @test_procedure Steps: + * -# Calling the ilm_surfaceSetType() time 1 with input ilmSurfaceType is ILM_SURFACETYPE_RESTRICTED + * -# Calling the ilm_surfaceSetType() time 2 with input ilmSurfaceType is ILM_SURFACETYPE_DESKTOP + * -# Verification point: + * +# Both of ilm_surfaceSetType() time 1 and time 2 must return ILM_SUCCESS + * +# wl_proxy_marshal_flags() must be called + * +# wl_display_flush() must be called + */ +TEST_F(IlmControlTest, ilm_surfaceSetType_success) +{ + t_ilm_surface l_surfaceId = 1; + + ASSERT_EQ(ILM_SUCCESS, ilm_surfaceSetType(l_surfaceId, ILM_SURFACETYPE_RESTRICTED)); + + ASSERT_EQ(1, wl_proxy_marshal_flags_fake.call_count); + ASSERT_EQ(1, wl_display_flush_fake.call_count); + + ASSERT_EQ(ILM_SUCCESS, ilm_surfaceSetType(l_surfaceId, ILM_SURFACETYPE_DESKTOP)); + + ASSERT_EQ(2, wl_proxy_marshal_flags_fake.call_count); + ASSERT_EQ(2, wl_display_flush_fake.call_count); +} + +/** ================================================================================================ + * @test_id ilm_displaySetRenderOrder_wrongCtx + * @brief Test case of ilm_displaySetRenderOrder() where ilm context wl.controller is null object + * @test_procedure Steps: + * -# Set the ilm context wl.controller is null object + * -# Calling the ilm_displaySetRenderOrder() + * -# Verification point: + * +# ilm_displaySetRenderOrder() must return ILM_FAILED + * +# wl_proxy_marshal_flags() not be called + * +# wl_display_flush() not be called + */ +TEST_F(IlmControlTest, ilm_displaySetRenderOrder_wrongCtx) +{ + ilm_context.wl.controller = nullptr; + + t_ilm_display l_displayId = 10; + t_ilm_int l_number = 1; + ASSERT_EQ(ILM_FAILED, ilm_displaySetRenderOrder(l_displayId, mp_ilmLayerIds, l_number)); + + ASSERT_EQ(0, wl_proxy_marshal_flags_fake.call_count); + ASSERT_EQ(0, wl_display_flush_fake.call_count); +} + +/** ================================================================================================ + * @test_id ilm_displaySetRenderOrder_invalidDisplayId + * @brief Test case of ilm_displaySetRenderOrder() where input display invalid + * @test_procedure Steps: + * -# Calling the ilm_displaySetRenderOrder() with input display invalid + * -# Verification point: + * +# ilm_displaySetRenderOrder() must return ILM_FAILED + * +# wl_proxy_marshal_flags() not be called + * +# wl_display_flush() not be called + */ +TEST_F(IlmControlTest, ilm_displaySetRenderOrder_invalidDisplayId) +{ + t_ilm_display l_displayId = 11; + t_ilm_int l_number = 1; + ASSERT_EQ(ILM_FAILED, ilm_displaySetRenderOrder(l_displayId, mp_ilmLayerIds, l_number)); + + ASSERT_EQ(0, wl_proxy_marshal_flags_fake.call_count); + ASSERT_EQ(0, wl_display_flush_fake.call_count); +} + +/** ================================================================================================ + * @test_id ilm_displaySetRenderOrder_success + * @brief Test case of ilm_displaySetRenderOrder() where ilm context is initilized + * and valid display id + * @test_procedure Steps: + * -# Calling the ilm_displaySetRenderOrder() + * -# Verification point: + * +# ilm_displaySetRenderOrder() must return ILM_SUCCESS + * +# wl_proxy_marshal_flags() must be called {1+l_number} time + * +# wl_display_flush() must be called once time + */ +TEST_F(IlmControlTest, ilm_displaySetRenderOrder_success) +{ + t_ilm_layer l_displayId = 10; + t_ilm_int l_number = MAX_NUMBER; + ASSERT_EQ(ILM_SUCCESS, ilm_displaySetRenderOrder(l_displayId, mp_ilmLayerIds, l_number)); + + ASSERT_EQ(1 + l_number, wl_proxy_marshal_flags_fake.call_count); + ASSERT_EQ(1, wl_display_flush_fake.call_count); +} + +/** ================================================================================================ + * @test_id ilm_layerAddNotification_cannotGetRoundTripQueue + * @brief Test case of ilm_layerAddNotification() where wl_display_roundtrip_queue() fails, return -1 + * @test_procedure Steps: + * -# Set the ilm context initialized is true, ready init + * -# Mocking the wl_display_roundtrip_queue() does return -1 + * -# Calling the ilm_layerAddNotification() + * -# Verification point: + * +# ilm_layerAddNotification() must return ILM_FAILED + * +# wl_proxy_marshal_flags() not be called + * +# wl_display_roundtrip_queue() must be called once time + */ +TEST_F(IlmControlTest, ilm_layerAddNotification_cannotGetRoundTripQueue) +{ + ilm_context.initialized = true; + SET_RETURN_SEQ(wl_display_roundtrip_queue, mp_failureResult, 1); + + t_ilm_layer l_layerId = 10; + ASSERT_EQ(ILM_FAILED, ilm_layerAddNotification(l_layerId, nullptr)); + + ASSERT_EQ(0, wl_proxy_marshal_flags_fake.call_count); + ASSERT_EQ(1, wl_display_roundtrip_queue_fake.call_count); +} + +/** ================================================================================================ + * @test_id ilm_layerAddNotification_invalidLayerId + * @brief Test case of ilm_layerAddNotification() where input layer invalid + * @test_procedure Steps: + * -# Set the ilm context initialized is true, ready init + * -# Calling the ilm_layerAddNotification() with input layer invalid + * -# Verification point: + * +# ilm_layerAddNotification() must return ILM_ERROR_INVALID_ARGUMENTS + * +# wl_proxy_marshal_flags() not be called + * +# wl_display_roundtrip_queue() must be called once time + */ +TEST_F(IlmControlTest, ilm_layerAddNotification_invalidLayerId) +{ + ilm_context.initialized = true; + + t_ilm_layer l_layerId = 10; + ASSERT_EQ(ILM_ERROR_INVALID_ARGUMENTS, ilm_layerAddNotification(l_layerId, nullptr)); + + ASSERT_EQ(0, wl_proxy_marshal_flags_fake.call_count); + ASSERT_EQ(1, wl_display_roundtrip_queue_fake.call_count); +} + +/** ================================================================================================ + * @test_id ilm_layerAddNotification_success + * @brief Test case of ilm_layerAddNotification() where ilm context is initilized + * and valid layer id + * @test_procedure Steps: + * -# Set the ilm context initialized is true, ready init + * -# Calling the ilm_layerAddNotification() + * -# Verification point: + * +# ilm_layerAddNotification() must return ILM_SUCCESS + * +# wl_proxy_marshal_flags() must be called once time + * +# wl_display_roundtrip_queue() must be called 2 times + */ +TEST_F(IlmControlTest, ilm_layerAddNotification_success) +{ + ilm_context.initialized = true; + + t_ilm_layer l_layerId = 100; + ASSERT_EQ(ILM_SUCCESS, ilm_layerAddNotification(l_layerId, nullptr)); + + ASSERT_EQ(1, wl_proxy_marshal_flags_fake.call_count); + ASSERT_EQ(2, wl_display_roundtrip_queue_fake.call_count); +} + +/** ================================================================================================ + * @test_id ilm_layerRemoveNotification_invalidLayer + * @brief Test case of ilm_layerRemoveNotification() where input layer invalid + * @test_procedure Steps: + * -# Set the ilm context initialized is true, ready init + * -# Calling the ilm_layerRemoveNotification() with input layer invalid + * -# Verification point: + * +# ilm_layerRemoveNotification() must return ILM_FAILED + * +# wl_proxy_marshal_flags() not be called + * +# wl_display_roundtrip_queue() must be called once time + */ +TEST_F(IlmControlTest, ilm_layerRemoveNotification_invalidLayer) +{ + ilm_context.initialized = true; + + t_ilm_layer l_layerId = 10; + ASSERT_EQ(ILM_FAILED, ilm_layerRemoveNotification(l_layerId)); + + ASSERT_EQ(0, wl_proxy_marshal_flags_fake.call_count); + ASSERT_EQ(1, wl_display_roundtrip_queue_fake.call_count); +} + +/** ================================================================================================ + * @test_id ilm_layerRemoveNotification_cannotGetRoundTripQueue + * @brief Test case of ilm_layerRemoveNotification() where wl_display_roundtrip_queue() fails, return -1 + * @test_procedure Steps: + * -# Set the ilm context initialized is true, ready init + * -# Mocking the wl_display_roundtrip_queue() does return -1 + * -# Calling the ilm_layerRemoveNotification() + * -# Verification point: + * +# ilm_layerRemoveNotification() must return ILM_FAILED + * +# wl_proxy_marshal_flags() not be called + * +# wl_display_roundtrip_queue() must be called once time + */ +TEST_F(IlmControlTest, ilm_layerRemoveNotification_cannotGetRoundTripQueue) +{ + ilm_context.initialized = true; + + t_ilm_layer l_layerId = 100; + SET_RETURN_SEQ(wl_display_roundtrip_queue, mp_failureResult, 1); + ASSERT_EQ(ILM_FAILED, ilm_layerRemoveNotification(l_layerId)); + + ASSERT_EQ(0, wl_proxy_marshal_flags_fake.call_count); + ASSERT_EQ(1, wl_display_roundtrip_queue_fake.call_count); +} + +/** ================================================================================================ + * @test_id ilm_layerRemoveNotification_invalidNotification + * @brief Test case of ilm_layerRemoveNotification() where input callback is null pointer + * @test_procedure Steps: + * -# Set the ilm context initialized is true, ready init + * -# Calling the ilm_layerAddNotification() to add notification + * -# Calling the ilm_layerRemoveNotification() + * -# Verification point: + * +# ilm_layerAddNotification() must return ILM_SUCCESS + * +# ilm_layerRemoveNotification() must return ILM_ERROR_INVALID_ARGUMENTS + * +# wl_proxy_marshal_flags() must be called once time + * +# wl_display_roundtrip_queue() must be called 3 times + */ +TEST_F(IlmControlTest, ilm_layerRemoveNotification_invalidNotification) +{ + ilm_context.initialized = true; + + t_ilm_layer l_layerId = 100; + ASSERT_EQ(ILM_SUCCESS, ilm_layerAddNotification(l_layerId, nullptr)); + ASSERT_EQ(ILM_ERROR_INVALID_ARGUMENTS, ilm_layerRemoveNotification(l_layerId)); + + ASSERT_EQ(1, wl_proxy_marshal_flags_fake.call_count); + ASSERT_EQ(3, wl_display_roundtrip_queue_fake.call_count); +} + +/** ================================================================================================ + * @test_id ilm_layerRemoveNotification_success + * @brief Test case of ilm_layerRemoveNotification() where and ilm context is initilized + * input callback is not null pointer + * @test_procedure Steps: + * -# Set the ilm context initialized is true, ready init + * -# Calling the ilm_layerAddNotification() to add notification + * -# Calling the ilm_layerRemoveNotification() + * -# Verification point: + * +# ilm_layerAddNotification() must return ILM_SUCCESS + * +# ilm_layerRemoveNotification() must return ILM_SUCCESS + * +# wl_proxy_marshal_flags() must be called 2 times + * +# wl_display_roundtrip_queue() must be called 4 times + */ +TEST_F(IlmControlTest, ilm_layerRemoveNotification_success) +{ + ilm_context.initialized = true; + + t_ilm_layer l_layerId = 100; + ASSERT_EQ(ILM_SUCCESS, ilm_layerAddNotification(l_layerId, &layerCallbackFunction)); + ASSERT_EQ(ILM_SUCCESS, ilm_layerRemoveNotification(l_layerId)); + + ASSERT_EQ(2, wl_proxy_marshal_flags_fake.call_count); + ASSERT_EQ(4, wl_display_roundtrip_queue_fake.call_count); +} + +/** ================================================================================================ + * @test_id ilm_surfaceAddNotification_addNewSurface + * @brief Test case of ilm_surfaceAddNotification() where ilm context is initilized + * and valid callback, invalid surface + * @test_procedure Steps: + * -# Set the ilm context initialized is true, ready init + * -# Calling the ilm_surfaceAddNotification() + * -# Verification point: + * +# ilm_surfaceAddNotification() must return ILM_SUCCESS + * +# wl_proxy_marshal_flags() not be called + * +# wl_display_roundtrip_queue() must be called once time + * +# Free resources are allocated when running the test + */ +TEST_F(IlmControlTest, ilm_surfaceAddNotification_addNewSurface) +{ + ilm_context.initialized = true; + + t_ilm_surface l_surface = 6; + ASSERT_EQ(ILM_SUCCESS, ilm_surfaceAddNotification(l_surface, &surfaceCallbackFunction)); + + ASSERT_EQ(0, wl_proxy_marshal_flags_fake.call_count); + ASSERT_EQ(1, wl_display_roundtrip_queue_fake.call_count); + + struct surface_context *lp_createSurface = (struct surface_context*)(uintptr_t(wl_list_insert_fake.arg1_history[0]) - offsetof(struct surface_context, link)); + free(lp_createSurface); +} + +/** ================================================================================================ + * @test_id ilm_surfaceAddNotification_noAddNewSurface + * @brief Test case of ilm_surfaceAddNotification() where ilm context is initilized + * and invalid callback, invalid surface + * @test_procedure Steps: + * -# Set the ilm context initialized is true, ready init + * -# Calling the ilm_surfaceAddNotification() + * -# Verification point: + * +# ilm_surfaceAddNotification() must return ILM_ERROR_INVALID_ARGUMENTS + * +# wl_proxy_marshal_flags() not be called + * +# wl_display_roundtrip_queue() must be called once time + */ +TEST_F(IlmControlTest, ilm_surfaceAddNotification_noAddNewSurface) +{ + ilm_context.initialized = true; + + t_ilm_surface l_surface = 6; + ASSERT_EQ(ILM_ERROR_INVALID_ARGUMENTS, ilm_surfaceAddNotification(l_surface, nullptr)); + + ASSERT_EQ(0, wl_proxy_marshal_flags_fake.call_count); + ASSERT_EQ(1, wl_display_roundtrip_queue_fake.call_count); +} + +/** ================================================================================================ + * @test_id ilm_surfaceAddNotification_cannotGetRoundTripQueue + * @brief Test case of ilm_surfaceAddNotification() where wl_display_roundtrip_queue() fails, return -1 + * @test_procedure Steps: + * -# Set the ilm context initialized is true, ready init + * -# Mocking the wl_display_roundtrip_queue() does return -1 + * -# Calling the ilm_surfaceAddNotification() + * -# Verification point: + * +# ilm_surfaceAddNotification() must return ILM_FAILED + * +# wl_proxy_marshal_flags() not be called + * +# wl_display_roundtrip_queue() must be called once time + */ +TEST_F(IlmControlTest, ilm_surfaceAddNotification_cannotGetRoundTripQueue) +{ + ilm_context.initialized = true; + SET_RETURN_SEQ(wl_display_roundtrip_queue, mp_failureResult, 1); + + t_ilm_surface l_surface = 1; + ASSERT_EQ(ILM_FAILED, ilm_surfaceAddNotification(l_surface, nullptr)); + + ASSERT_EQ(0, wl_proxy_marshal_flags_fake.call_count); + ASSERT_EQ(1, wl_display_roundtrip_queue_fake.call_count); +} + +/** ================================================================================================ + * @test_id ilm_surfaceAddNotification_nullNotification + * @brief Test case of ilm_surfaceAddNotification() where input callback is null pointer + * @test_procedure Steps: + * -# Set the ilm context initialized is true, ready init + * -# Calling the ilm_surfaceAddNotification() + * -# Verification point: + * +# ilm_surfaceAddNotification() must return ILM_SUCCESS + * +# wl_proxy_marshal_flags() not be called + * +# wl_display_roundtrip_queue() must be called once time + */ +TEST_F(IlmControlTest, ilm_surfaceAddNotification_nullNotification) +{ + ilm_context.initialized = true; + + t_ilm_surface l_surface = 1; + ASSERT_EQ(ILM_SUCCESS, ilm_surfaceAddNotification(l_surface, nullptr)); + + ASSERT_EQ(0, wl_proxy_marshal_flags_fake.call_count); + ASSERT_EQ(1, wl_display_roundtrip_queue_fake.call_count); +} + +/** ================================================================================================ + * @test_id ilm_surfaceAddNotification_success + * @brief Test case of ilm_surfaceAddNotification() where input callback is not null pointer + * @test_procedure Steps: + * -# Set the ilm context initialized is true, ready init + * -# Calling the ilm_surfaceAddNotification() + * -# Verification point: + * +# ilm_surfaceAddNotification() must return ILM_SUCCESS + * +# wl_proxy_marshal_flags() must be called once time + * +# wl_display_roundtrip_queue() must be called 2 times + */ +TEST_F(IlmControlTest, ilm_surfaceAddNotification_success) +{ + ilm_context.initialized = true; + + t_ilm_surface l_surface = 1; + ASSERT_EQ(ILM_SUCCESS, ilm_surfaceAddNotification(l_surface, &surfaceCallbackFunction)); + + ASSERT_EQ(1, wl_proxy_marshal_flags_fake.call_count); + ASSERT_EQ(2, wl_display_roundtrip_queue_fake.call_count); +} + +/** ================================================================================================ + * @test_id ilm_surfaceRemoveNotification_cannotGetRoundTripQueue + * @brief Test case of ilm_surfaceRemoveNotification() where wl_display_roundtrip_queue() fails, return -1 + * @test_procedure Steps: + * -# Set the ilm context initialized is true, ready init + * -# Mocking the wl_display_roundtrip_queue() does return -1 + * -# Calling the ilm_surfaceRemoveNotification() + * -# Verification point: + * +# ilm_surfaceRemoveNotification() must return ILM_FAILED + * +# wl_proxy_marshal_flags() not be called + * +# wl_display_roundtrip_queue() must be called once time + */ +TEST_F(IlmControlTest, ilm_surfaceRemoveNotification_cannotGetRoundTripQueue) +{ + ilm_context.initialized = true; + SET_RETURN_SEQ(wl_display_roundtrip_queue, mp_failureResult, 1); + + t_ilm_surface l_surface = 1; + ASSERT_EQ(ILM_FAILED, ilm_surfaceRemoveNotification(l_surface)); + + ASSERT_EQ(0, wl_proxy_marshal_flags_fake.call_count); + ASSERT_EQ(1, wl_display_roundtrip_queue_fake.call_count); +} + +/** ================================================================================================ + * @test_id ilm_surfaceRemoveNotification_nullNotification + * @brief Test case of ilm_surfaceRemoveNotification() where callback is null pointer + * @test_procedure Steps: + * -# Set the ilm context initialized is true, ready init + * -# Calling the ilm_surfaceRemoveNotification() + * -# Verification point: + * +# ilm_surfaceRemoveNotification() must return ILM_ERROR_INVALID_ARGUMENTS + * +# wl_proxy_marshal_flags() not be called + * +# wl_display_roundtrip_queue() must be called once time + */ +TEST_F(IlmControlTest, ilm_surfaceRemoveNotification_nullNotification) +{ + ilm_context.initialized = true; + + t_ilm_surface l_surface = 1; + ASSERT_EQ(ILM_ERROR_INVALID_ARGUMENTS, ilm_surfaceRemoveNotification(l_surface)); + + ASSERT_EQ(0, wl_proxy_marshal_flags_fake.call_count); + ASSERT_EQ(1, wl_display_roundtrip_queue_fake.call_count); +} + +/** ================================================================================================ + * @test_id ilm_surfaceRemoveNotification_invalidSurface + * @brief Test case of ilm_surfaceRemoveNotification() where invalid input surface id + * @test_procedure Steps: + * -# Set the ilm context initialized is true, ready init + * -# Calling the ilm_surfaceRemoveNotification() with invalid surface id + * -# Verification point: + * +# ilm_surfaceRemoveNotification() must return ILM_FAILED + * +# wl_proxy_marshal_flags() not be called + * +# wl_display_roundtrip_queue() must be called once time + */ +TEST_F(IlmControlTest, ilm_surfaceRemoveNotification_invalidSurface) +{ + ilm_context.initialized = true; + + t_ilm_surface l_surface = 6; + ASSERT_EQ(ILM_FAILED, ilm_surfaceRemoveNotification(l_surface)); + + ASSERT_EQ(0, wl_proxy_marshal_flags_fake.call_count); + ASSERT_EQ(1, wl_display_roundtrip_queue_fake.call_count); +} + +/** ================================================================================================ + * @test_id ilm_surfaceRemoveNotification_success + * @brief Test case of ilm_surfaceRemoveNotification() where callback is not null pointer + * @test_procedure Steps: + * -# Set the ilm context initialized is true, ready init + * -# Calling the ilm_surfaceAddNotification() to add callback notification + * -# Calling the ilm_surfaceRemoveNotification() + * -# Verification point: + * +# ilm_surfaceRemoveNotification() must return ILM_SUCCESS + * +# wl_proxy_marshal_flags() must be called 2 times + * +# wl_display_roundtrip_queue() must be called 4 times + */ +TEST_F(IlmControlTest, ilm_surfaceRemoveNotification_success) +{ + ilm_context.initialized = true; + + t_ilm_surface l_surface = 1; + ASSERT_EQ(ILM_SUCCESS, ilm_surfaceAddNotification(l_surface, &surfaceCallbackFunction)); + ASSERT_EQ(ILM_SUCCESS, ilm_surfaceRemoveNotification(l_surface)); + + ASSERT_EQ(2, wl_proxy_marshal_flags_fake.call_count); + ASSERT_EQ(4, wl_display_roundtrip_queue_fake.call_count); +} + +/** ================================================================================================ + * @test_id ilm_registerNotification_cannotGetRoundTripQueue + * @brief Test case of ilm_registerNotification() where wl_display_roundtrip_queue() fails, return -1 + * @test_procedure Steps: + * -# Set the ilm context initialized is true, ready init + * -# Mocking the wl_display_roundtrip_queue() does return -1 + * -# Calling the ilm_registerNotification() + * -# Verification point: + * +# ilm_registerNotification() must return ILM_FAILED + * +# wl_display_roundtrip_queue() must be called once time + */ +TEST_F(IlmControlTest, ilm_registerNotification_cannotGetRoundTripQueue) +{ + ilm_context.initialized = true; + SET_RETURN_SEQ(wl_display_roundtrip_queue, mp_failureResult, 1); + + ASSERT_EQ(ILM_FAILED, ilm_registerNotification(¬ificationCallback, nullptr)); + + ASSERT_EQ(1, wl_display_roundtrip_queue_fake.call_count); +} + +/** ================================================================================================ + * @test_id ilm_registerNotification_success + * @brief Test case of ilm_registerNotification() where callback is not null pointer + * @test_procedure Steps: + * -# Set the ilm context initialized is true, ready init + * -# Calling the ilm_registerNotification() + * -# Verification point: + * +# ilm_registerNotification() must return ILM_SUCCESS + * +# wl_display_roundtrip_queue() must be called once time + */ +TEST_F(IlmControlTest, ilm_registerNotification_success) +{ + ilm_context.initialized = true; + + ASSERT_EQ(ILM_SUCCESS, ilm_registerNotification(¬ificationCallback, nullptr)); + + ASSERT_EQ(1, wl_display_roundtrip_queue_fake.call_count); +} + +/** ================================================================================================ + * @test_id ilm_unregisterNotification_success + * @brief Test case of ilm_unregisterNotification() where ilm context is initilized + * @test_procedure Steps: + * -# Set the ilm context initialized is true, ready init + * -# Calling the ilm_unregisterNotification() + * -# Verification point: + * +# ilm_unregisterNotification() must return ILM_SUCCESS + */ +TEST_F(IlmControlTest, ilm_unregisterNotification_success) +{ + ilm_context.initialized = true; + ASSERT_EQ(ILM_SUCCESS, ilm_unregisterNotification()); +} + +/** ================================================================================================ + * @test_id ilm_commitChanges_wrongCtx + * @brief Test case of ilm_commitChanges() where ilm context wl.controller is null object + * @test_procedure Steps: + * -# Set the ilm context wl.controller is null object + * -# Calling the ilm_commitChanges() + * -# Verification point: + * +# ilm_commitChanges() must return ILM_FAILED + * +# wl_display_roundtrip_queue() not be called + */ +TEST_F(IlmControlTest, ilm_commitChanges_wrongCtx) +{ + ilm_context.wl.controller = nullptr; + + ASSERT_EQ(ILM_FAILED, ilm_commitChanges()); + + ASSERT_EQ(0, wl_display_roundtrip_queue_fake.call_count); +} + +/** ================================================================================================ + * @test_id ilm_commitChanges_cannotGetRoundTripQueue + * @brief Test case of ilm_commitChanges() where wl_display_roundtrip_queue() fails, return -1 + * @test_procedure Steps: + * -# Mocking the wl_display_roundtrip_queue() does return -1 + * -# Calling the ilm_commitChanges() + * -# Verification point: + * +# ilm_commitChanges() must return ILM_FAILED + * +# wl_display_roundtrip_queue() must be called once time and return -1 + */ +TEST_F(IlmControlTest, ilm_commitChanges_cannotGetRoundTripQueue) +{ + SET_RETURN_SEQ(wl_display_roundtrip_queue, mp_failureResult, 1); + + ASSERT_EQ(ILM_FAILED, ilm_commitChanges()); + + ASSERT_EQ(1, wl_display_roundtrip_queue_fake.call_count); + ASSERT_EQ(mp_failureResult[0], wl_display_roundtrip_queue_fake.return_val_history[0]); +} + +/** ================================================================================================ + * @test_id ilm_commitChanges_success + * @brief Test case of ilm_commitChanges() where wl_display_roundtrip_queue() success, return 0 + * @test_procedure Steps: + * -# Mocking the wl_display_roundtrip_queue() does return 0 + * -# Calling the ilm_commitChanges() + * -# Verification point: + * +# ilm_commitChanges() must return ILM_SUCCESS + * +# wl_display_roundtrip_queue() must be called once time and return 0 + */ +TEST_F(IlmControlTest, ilm_commitChanges_success) +{ + SET_RETURN_SEQ(wl_display_roundtrip_queue, mp_successResult, 1); + + ASSERT_EQ(ILM_SUCCESS, ilm_commitChanges()); + + ASSERT_EQ(1, wl_display_roundtrip_queue_fake.call_count); + ASSERT_EQ(mp_successResult[0], wl_display_roundtrip_queue_fake.return_val_history[0]); +} + +/** ================================================================================================ + * @test_id ilm_getError_wrongCtx + * @brief Test case of ilm_getError() where ilm context wl.controller is null object + * @test_procedure Steps: + * -# Set the ilm context wl.controller is null object + * -# Calling the ilm_getError() + * -# Verification point: + * +# ilm_getError() must return ILM_FAILED + * +# wl_display_roundtrip_queue() not be called + */ +TEST_F(IlmControlTest, ilm_getError_wrongCtx) +{ + ilm_context.wl.controller = nullptr; + + ASSERT_EQ(ILM_FAILED, ilm_getError()); + + ASSERT_EQ(0, wl_display_roundtrip_queue_fake.call_count); +} + +/** ================================================================================================ + * @test_id ilm_getError_cannotGetRoundTripQueue + * @brief Test case of ilm_getError() where wl_display_roundtrip_queue() fails, return -1 + * @test_procedure Steps: + * -# Mocking the wl_display_roundtrip_queue() does return -1 + * -# Calling the ilm_getError() + * -# Verification point: + * +# ilm_getError() must return ILM_FAILED + * +# wl_display_roundtrip_queue() must be called once time and return -1 + */ +TEST_F(IlmControlTest, ilm_getError_cannotGetRoundTripQueue) +{ + SET_RETURN_SEQ(wl_display_roundtrip_queue, mp_failureResult, 1); + + ASSERT_EQ(ILM_FAILED, ilm_getError()); + + ASSERT_EQ(1, wl_display_roundtrip_queue_fake.call_count); + ASSERT_EQ(mp_failureResult[0], wl_display_roundtrip_queue_fake.return_val_history[0]); +} + +/** ================================================================================================ + * @test_id ilm_getError_success + * @brief Test case of ilm_getError() where wl_display_roundtrip_queue() success, return 0 + * @test_procedure Steps: + * -# Mocking the wl_display_roundtrip_queue() does return 0 + * -# Calling the ilm_getError() + * -# Verification point: + * +# ilm_getError() must return ILM_SUCCESS + * +# wl_display_roundtrip_queue() must be called once time and return 0 + */ +TEST_F(IlmControlTest, ilm_getError_success) +{ + SET_RETURN_SEQ(wl_display_roundtrip_queue, mp_successResult, 1); + + ASSERT_EQ(ILM_SUCCESS, ilm_getError()); + + ASSERT_EQ(1, wl_display_roundtrip_queue_fake.call_count); + ASSERT_EQ(mp_successResult[0], wl_display_roundtrip_queue_fake.return_val_history[0]); +} + +/** ================================================================================================ + * @test_id wm_listener_layer_created_sameLayerId + * @brief Test case of wm_listener_layer_created() where valid layer id + * @test_procedure Steps: + * -# Calling the wm_listener_layer_created() with layer id exist + * -# Verification point: + * +# wl_list_insert() not be called + */ +TEST_F(IlmControlTest, wm_listener_layer_created_sameLayerId) +{ + wm_listener_layer_created(&ilm_context.wl, nullptr, 100); + + ASSERT_EQ(0, wl_list_insert_fake.call_count); +} + +/** ================================================================================================ + * @test_id wm_listener_layer_created_addNewOne + * @brief Test case of wm_listener_layer_created() where invalid layer id + * and notication callback is not null pointer + * @test_procedure Steps: + * -# Calling the wm_listener_layer_created() time 1 with invalid layer id and null notication callback + * -# Set notication callback + * -# Calling the wm_listener_layer_created() time 2 with invalid layer id and a notication callback + * -# Verification point: + * +# wl_list_insert() must be called + * +# when invoke callback function, g_ilmControlStatus must be seted to CREATE_LAYER + * +# Free resources are allocated when running the test time 1 and time 2 + */ +TEST_F(IlmControlTest, wm_listener_layer_created_addNewOne) +{ + wm_listener_layer_created(&ilm_context.wl, nullptr, 600); + + ASSERT_EQ(1, wl_list_insert_fake.call_count); + + struct layer_context *lp_createLayer = (struct layer_context*)(uintptr_t(wl_list_insert_fake.arg1_history[0]) - offsetof(struct layer_context, link)); + free(lp_createLayer); + + ilm_context.wl.notification = notificationCallback; + wm_listener_layer_created(&ilm_context.wl, nullptr, 600); + + ASSERT_EQ(2, wl_list_insert_fake.call_count); + ASSERT_EQ(CREATE_LAYER, g_ilmControlStatus); + + lp_createLayer = (struct layer_context*)(uintptr_t(wl_list_insert_fake.arg1_history[1]) - offsetof(struct layer_context, link)); + free(lp_createLayer); +} + +/** ================================================================================================ + * @test_id wm_listener_layer_destroyed_wrongLayerId + * @brief Test case of wm_listener_layer_destroyed() where invalid layer id + * @test_procedure Steps: + * -# Calling the wm_listener_layer_destroyed() with invalid layer id + * -# Verification point: + * +# wl_list_remove() not be called + */ +TEST_F(IlmControlTest, wm_listener_layer_destroyed_wrongLayerId) +{ + wm_listener_layer_destroyed(&ilm_context.wl, nullptr, 1); + ASSERT_EQ(0, wl_list_remove_fake.call_count); +} + +/** ================================================================================================ + * @test_id wm_listener_layer_destroyed_removeOne + * @brief Test case of wm_listener_layer_destroyed() where valid layer id + * and notication callback is not null pointer + * @test_procedure Steps: + * -# Prepare mock for wl_list_remove(), to remove real object + * -# Calling the wm_listener_layer_destroyed() time 1 with valid layer id and null callback + * -# Calling the wm_listener_layer_destroyed() time 2 with valid layer id and a callback + * -# Verification point: + * +# wl_list_remove() must be called + * +# When invoke callback function, g_ilmControlStatus must be seted to DESTROY_LAYER + * +# set ctx_layer to nullptr + */ +TEST_F(IlmControlTest, wm_listener_layer_destroyed_removeOne) +{ + wl_list_remove_fake.custom_fake = custom_wl_list_remove; + + wm_listener_layer_destroyed(&ilm_context.wl, nullptr, 100); + + ASSERT_EQ(1, wl_list_remove_fake.call_count); + mp_ctxLayer[0] = nullptr; + + ilm_context.wl.notification = notificationCallback; + wm_listener_layer_destroyed(&ilm_context.wl, nullptr, 200); + + ASSERT_EQ(2, wl_list_remove_fake.call_count); + ASSERT_EQ(DESTROY_LAYER, g_ilmControlStatus); + mp_ctxLayer[1] = nullptr; +} + +/** ================================================================================================ + * @test_id wm_listener_layer_surface_added_wrongLayerId + * @brief Test case of wm_listener_layer_surface_added() where invalid layer id + * @test_procedure Steps: + * -# Calling the wm_listener_layer_surface_added() with invalid layer id + * -# Verification point: + * +# wl_array_add() not be called + */ +TEST_F(IlmControlTest, wm_listener_layer_surface_added_wrongLayerId) +{ + wm_listener_layer_surface_added(&ilm_context.wl, nullptr, 1, 1); + ASSERT_EQ(0, wl_array_add_fake.call_count); +} + +/** ================================================================================================ + * @test_id wm_listener_layer_surface_added_addNewOne + * @brief Test case of wm_listener_layer_surface_added() where valid layer id + * @test_procedure Steps: + * -# Mocking the wl_array_add() does return a add_id + * -# Calling the wm_listener_layer_surface_added() with valid layer id + * -# Verification point: + * +# wl_array_add() must be called once time + * +# l_dataSurface must be seted same input surface id + */ +TEST_F(IlmControlTest, wm_listener_layer_surface_added_addNewOne) +{ + uint32_t l_dataSurface = 0; + void *lp_elemData = &l_dataSurface; + SET_RETURN_SEQ(wl_array_add, &lp_elemData, 1); + + wm_listener_layer_surface_added(&ilm_context.wl, nullptr, 100, 1); + + ASSERT_EQ(1, wl_array_add_fake.call_count); + ASSERT_EQ(1, l_dataSurface); +} + +/** ================================================================================================ + * @test_id wm_listener_surface_created_sameSurfaceId + * @brief Test case of wm_listener_surface_created() where valid surface id + * @test_procedure Steps: + * -# Calling the wm_listener_surface_created() with valid surface id + * -# Verification point: + * +# wl_list_insert() not be called + */ +TEST_F(IlmControlTest, wm_listener_surface_created_sameSurfaceId) +{ + wm_listener_surface_created(&ilm_context.wl, nullptr, 1); + ASSERT_EQ(0, wl_list_insert_fake.call_count); +} + +/** ================================================================================================ + * @test_id wm_listener_surface_created_addNewOne + * @brief Test case of wm_listener_surface_created() where valid surface id + * and notication callback is not null pointer + * @test_procedure Steps: + * -# Calling the wm_listener_surface_created() time 1 with valid surface id and null callback + * -# Calling the wm_listener_surface_created() time 2 with valid surface id and a callback + * -# Verification point: + * +# wl_list_insert() must be called + * +# When invoke callback function, g_ilmControlStatus must be seted to CREATE_SURFACE + * +# Free resources are allocated when running the test time 1 and time 2 + */ +TEST_F(IlmControlTest, wm_listener_surface_created_addNewOne) +{ + wm_listener_surface_created(&ilm_context.wl, nullptr, MAX_NUMBER + 1); + + ASSERT_EQ(1, wl_list_insert_fake.call_count); + + struct surface_context *lp_createSurface = (struct surface_context*)(uintptr_t(wl_list_insert_fake.arg1_history[0]) - offsetof(struct surface_context, link)); + free(lp_createSurface); + + ilm_context.wl.notification = notificationCallback; + wm_listener_surface_created(&ilm_context.wl, nullptr, MAX_NUMBER + 1); + + ASSERT_EQ(2, wl_list_insert_fake.call_count); + ASSERT_EQ(CREATE_SURFACE, g_ilmControlStatus); + + lp_createSurface = (struct surface_context*)(uintptr_t(wl_list_insert_fake.arg1_history[1]) - offsetof(struct surface_context, link)); + free(lp_createSurface); +} + +/** ================================================================================================ + * @test_id wm_listener_surface_destroyed_wrongSurfaceId + * @brief Test case of wm_listener_surface_destroyed() where invalid surface id + * @test_procedure Steps: + * -# Calling the wm_listener_surface_destroyed() with invalid surface id + * -# Verification point: + * +# wl_list_remove() not be called + */ +TEST_F(IlmControlTest, wm_listener_surface_destroyed_wrongSurfaceId) +{ + wm_listener_surface_destroyed(&ilm_context.wl, nullptr, MAX_NUMBER + 1); + ASSERT_EQ(0, wl_list_remove_fake.call_count); +} + +/** ================================================================================================ + * @test_id wm_listener_surface_destroyed_removeOnewithNullNotification + * @brief Test case of wm_listener_surface_destroyed() where valid surface id + * and notication callback is null pointer + * @test_procedure Steps: + * -# Prepare mock for wl_list_remove(), to remove real object + * -# Calling the wm_listener_surface_destroyed() with valid surface id and null callback + * -# Verification point: + * +# wl_list_remove() must be called 2 times + * +# set ctx_layer to nullptr + * +# Allocate memory for resources are freed when running the test + */ +TEST_F(IlmControlTest, wm_listener_surface_destroyed_removeOnewithNullNotification) +{ + wl_list_remove_fake.custom_fake = custom_wl_list_remove; + + wm_listener_surface_destroyed(&ilm_context.wl, nullptr, 1); + + ASSERT_EQ(2, wl_list_remove_fake.call_count); + mp_ctxSurface[0] = nullptr; + + mp_accepted_seat[0] = (struct accepted_seat*)malloc(sizeof(struct accepted_seat)); + mp_accepted_seat[0]->seat_name = strdup("KEYBOARD"); +} + +/** ================================================================================================ + * @test_id wm_listener_surface_destroyed_removeOnewithCtxNotification + * @brief Test case of wm_listener_surface_destroyed() where valid surface id + * and notication callback added from ilm_surfaceAddNotification() + * @test_procedure Steps: + * -# Prepare mock for wl_list_remove(), to remove real object + * -# Set the ilm context initialized is true, ready init + * -# Calling the ilm_surfaceAddNotification() to add callback + * -# Calling the wm_listener_surface_destroyed() with valid surface id + * -# Verification point: + * +# ilm_surfaceAddNotification() must return ILM_SUCCESS + * +# wl_list_remove() must be called 2 times + * +# When invoke callback function, g_ilm_notification_mask must be seted to ILM_NOTIFICATION_CONTENT_REMOVED + * +# set ctx_layer to nullptr + * +# Allocate memory for resources are freed when running the test + */ +TEST_F(IlmControlTest, wm_listener_surface_destroyed_removeOnewithCtxNotification) +{ + wl_list_remove_fake.custom_fake = custom_wl_list_remove; + ilm_context.initialized = true; + + ASSERT_EQ(ILM_SUCCESS, ilm_surfaceAddNotification(2, &surfaceCallbackFunction)); + wm_listener_surface_destroyed(&ilm_context.wl, nullptr, 2); + + ASSERT_EQ(2, wl_list_remove_fake.call_count); + ASSERT_EQ(ILM_NOTIFICATION_CONTENT_REMOVED, g_ilm_notification_mask); + mp_ctxSurface[1] = nullptr; + + mp_accepted_seat[1] = (struct accepted_seat*)malloc(sizeof(struct accepted_seat)); + mp_accepted_seat[1]->seat_name = strdup("KEYBOARD"); +} + +/** ================================================================================================ + * @test_id wm_listener_surface_destroyed_removeOnewithCallbackNotification + * @brief Test case of wm_listener_surface_destroyed() where valid surface id + * and notication callback is not null pointer + * @test_procedure Steps: + * -# Prepare mock for wl_list_remove(), to remove real object + * -# Set the ilm context wl.notification to callback function + * -# Calling the wm_listener_surface_destroyed() with valid surface id + * -# Verification point: + * +# wl_list_remove() must be called 2 times + * +# When invoke callback function, g_ilmControlStatus must be seted to DESTROY_SURFACE + * +# set ctx_layer to nullptr + * +# Allocate memory for resources are freed when running the test + */ +TEST_F(IlmControlTest, wm_listener_surface_destroyed_removeOnewithCallbackNotification) +{ + wl_list_remove_fake.custom_fake = custom_wl_list_remove; + ilm_context.wl.notification = notificationCallback; + + wm_listener_surface_destroyed(&ilm_context.wl, nullptr, 3); + + ASSERT_EQ(2, wl_list_remove_fake.call_count); + ASSERT_EQ(DESTROY_SURFACE, g_ilmControlStatus); + mp_ctxSurface[2] = nullptr; + + mp_accepted_seat[2] = (struct accepted_seat*)malloc(sizeof(struct accepted_seat)); + mp_accepted_seat[2]->seat_name = strdup("KEYBOARD"); +} + +/** ================================================================================================ + * @test_id wm_listener_surface_visibility_invalidSurface + * @brief Test case of wm_listener_surface_visibility() where invalid surface id + * and notication callback is null pointer + * @test_procedure Steps: + * -# Calling the wm_listener_surface_visibility() + * -# Verification point: + * +# When invoke callback function, g_ilm_notification_mask must be seted to default ILM_NOTIFICATION_ALL + */ +TEST_F(IlmControlTest, wm_listener_surface_visibility_invalidSurface) +{ + uint32_t l_surface_id = 6; + wm_listener_surface_visibility(&ilm_context.wl, nullptr, l_surface_id, 0.5); + + ASSERT_EQ(ILM_NOTIFICATION_ALL, g_ilm_notification_mask); +} + +/** ================================================================================================ + * @test_id wm_listener_surface_visibility_nullNotification + * @brief Test case of wm_listener_surface_visibility() where valid surface id + * and notication callback is null pointer + * @test_procedure Steps: + * -# Calling the wm_listener_surface_visibility() + * -# Verification point: + * +# When invoke callback function, g_ilm_notification_mask must be seted to default ILM_NOTIFICATION_ALL + */ +TEST_F(IlmControlTest, wm_listener_surface_visibility_nullNotification) +{ + uint32_t l_surface_id = 5; + wm_listener_surface_visibility(&ilm_context.wl, nullptr, l_surface_id, 0.5); + + ASSERT_EQ(ILM_NOTIFICATION_ALL, g_ilm_notification_mask); +} + +/** ================================================================================================ + * @test_id wm_listener_surface_visibility_success + * @brief Test case of wm_listener_surface_visibility() where valid surface id + * and notication callback is not null pointer + * @test_procedure Steps: + * -# Set the ilm context initialized is true, ready init + * -# Calling the ilm_surfaceAddNotification() to add a callback + * -# Calling the wm_listener_surface_visibility() time 1 with visibility is 1 + * -# Calling the wm_listener_surface_visibility() time 2 with visibility is 0.5 + * -# Verification point: + * +# ilm_surfaceAddNotification() must return ILM_SUCCESS + * +# When invoke callback function, g_ilm_notification_mask must be seted to ILM_NOTIFICATION_VISIBILITY + */ +TEST_F(IlmControlTest, wm_listener_surface_visibility_success) +{ + ilm_context.initialized = true; + + uint32_t l_surface_id = 1; + ASSERT_EQ(ILM_SUCCESS, ilm_surfaceAddNotification(l_surface_id, &surfaceCallbackFunction)); + wm_listener_surface_visibility(&ilm_context.wl, nullptr, l_surface_id, 1); + wm_listener_surface_visibility(&ilm_context.wl, nullptr, l_surface_id, 0.5); + + ASSERT_EQ(ILM_NOTIFICATION_VISIBILITY, g_ilm_notification_mask); +} + +/** ================================================================================================ + * @test_id wm_listener_layer_visibility_invalidLayer + * @brief Test case of wm_listener_layer_visibility() where invalid layer id + * and notication callback is null pointer + * @test_procedure Steps: + * -# Set the ilm context wl.controller is null pointer + * -# Calling the wm_listener_layer_visibility() + * -# Verification point: + * +# When invoke callback function, g_ilm_notification_mask must be seted to default ILM_NOTIFICATION_ALL + */ +TEST_F(IlmControlTest, wm_listener_layer_visibility_invalidLayer) +{ + ilm_context.wl.controller = nullptr; + uint32_t l_layer_id = 1; + wm_listener_layer_visibility(&ilm_context.wl, nullptr, l_layer_id, 0.5); + + ASSERT_EQ(ILM_NOTIFICATION_ALL, g_ilm_notification_mask); +} + +/** ================================================================================================ + * @test_id wm_listener_layer_visibility_nullNotification + * @brief Test case of wm_listener_layer_visibility() where valid layer id + * and notication callback is null pointer + * @test_procedure Steps: + * -# Calling the wm_listener_layer_visibility() + * -# Verification point: + * +# When invoke callback function, g_ilm_notification_mask must be seted to default ILM_NOTIFICATION_ALL + */ +TEST_F(IlmControlTest, wm_listener_layer_visibility_nullNotification) +{ + uint32_t l_layer_id = 500; + wm_listener_layer_visibility(&ilm_context.wl, nullptr, l_layer_id, 0.5); + + ASSERT_EQ(ILM_NOTIFICATION_ALL, g_ilm_notification_mask); +} + +/** ================================================================================================ + * @test_id wm_listener_layer_visibility_success + * @brief Test case of wm_listener_layer_visibility() where valid layer id + * and notication callback is not null pointer + * @test_procedure Steps: + * -# Set the ilm context initialized is true, ready init + * -# Calling the ilm_layerAddNotification() to add a callback + * -# Calling the wm_listener_layer_visibility() time 1 with visibility is 1 + * -# Calling the wm_listener_layer_visibility() time 2 with visibility is 0.5 + * -# Verification point: + * +# ilm_layerAddNotification() must return ILM_SUCCESS + * +# When invoke callback function, g_ilm_notification_mask must be seted to ILM_NOTIFICATION_VISIBILITY + */ +TEST_F(IlmControlTest, wm_listener_layer_visibility_success) +{ + ilm_context.initialized = true; + + uint32_t l_layer_id = 100; + ASSERT_EQ(ILM_SUCCESS, ilm_layerAddNotification(l_layer_id, &layerCallbackFunction)); + wm_listener_layer_visibility(&ilm_context.wl, nullptr, l_layer_id, 1); + wm_listener_layer_visibility(&ilm_context.wl, nullptr, l_layer_id, 0.5); + + ASSERT_EQ(ILM_NOTIFICATION_VISIBILITY, g_ilm_notification_mask); +} + +/** ================================================================================================ + * @test_id wm_listener_surface_opacity_invalidSurface + * @brief Test case of wm_listener_surface_opacity() where invalid surface id + * and notication callback is null pointer + * @test_procedure Steps: + * -# Calling the wm_listener_surface_opacity() + * -# Verification point: + * +# When invoke callback function, g_ilm_notification_mask must be seted to default ILM_NOTIFICATION_ALL + */ +TEST_F(IlmControlTest, wm_listener_surface_opacity_invalidSurface) +{ + uint32_t l_surface_id = 6; + wm_listener_surface_opacity(&ilm_context.wl, nullptr, l_surface_id, 0.5); + + ASSERT_EQ(ILM_NOTIFICATION_ALL, g_ilm_notification_mask); +} + +/** ================================================================================================ + * @test_id wm_listener_surface_opacity_nullNotification + * @brief Test case of wm_listener_surface_opacity() where valid surface id + * and notication callback is null pointer + * @test_procedure Steps: + * -# Calling the wm_listener_surface_opacity() + * -# Verification point: + * +# When invoke callback function, g_ilm_notification_mask must be seted to default ILM_NOTIFICATION_ALL + */ +TEST_F(IlmControlTest, wm_listener_surface_opacity_nullNotification) +{ + uint32_t l_surface_id = 5; + wm_listener_surface_opacity(&ilm_context.wl, nullptr, l_surface_id, 0.5); + + ASSERT_EQ(ILM_NOTIFICATION_ALL, g_ilm_notification_mask); +} + +/** ================================================================================================ + * @test_id wm_listener_surface_opacity_success + * @brief Test case of wm_listener_surface_opacity() where valid surface id + * and notication callback is not null pointer + * @test_procedure Steps: + * -# Set the ilm context initialized is true, ready init + * -# Calling the ilm_surfaceAddNotification() to add a callback + * -# Calling the wm_listener_surface_opacity() time 1 with opacity is 0 + * -# Calling the wm_listener_surface_opacity() time 2 with opacity is 0.5 + * -# Verification point: + * +# ilm_surfaceAddNotification() must return ILM_SUCCESS + * +# When invoke callback function, g_ilm_notification_mask must be seted to ILM_NOTIFICATION_OPACITY + */ +TEST_F(IlmControlTest, wm_listener_surface_opacity_success) +{ + ilm_context.initialized = true; + + uint32_t l_surface_id = 1; + ASSERT_EQ(ILM_SUCCESS, ilm_surfaceAddNotification(l_surface_id, &surfaceCallbackFunction)); + wm_listener_surface_opacity(&ilm_context.wl, nullptr, l_surface_id, 0); + wm_listener_surface_opacity(&ilm_context.wl, nullptr, l_surface_id, 0.5); + + ASSERT_EQ(ILM_NOTIFICATION_OPACITY, g_ilm_notification_mask); +} + +/** ================================================================================================ + * @test_id wm_listener_layer_opacity_invalidLayer + * @brief Test case of wm_listener_layer_opacity() where invalid layer id + * and notication callback is null pointer + * @test_procedure Steps: + * -# Calling the wm_listener_layer_opacity() + * -# Verification point: + * +# When invoke callback function, g_ilm_notification_mask must be seted to default ILM_NOTIFICATION_ALL + */ +TEST_F(IlmControlTest, wm_listener_layer_opacity_invalidLayer) +{ + uint32_t l_layer_id = 1; + wm_listener_layer_opacity(&ilm_context.wl, nullptr, l_layer_id, 0.5); + + ASSERT_EQ(ILM_NOTIFICATION_ALL, g_ilm_notification_mask); +} + +/** ================================================================================================ + * @test_id wm_listener_layer_opacity_nullNotification + * @brief Test case of wm_listener_layer_opacity() where valid layer id + * and notication callback is null pointer + * @test_procedure Steps: + * -# Calling the wm_listener_layer_opacity() + * -# Verification point: + * +# When invoke callback function, g_ilm_notification_mask must be seted to default ILM_NOTIFICATION_ALL + */ +TEST_F(IlmControlTest, wm_listener_layer_opacity_nullNotification) +{ + uint32_t l_layer_id = 500; + wm_listener_layer_opacity(&ilm_context.wl, nullptr, l_layer_id, 0.5); + + ASSERT_EQ(ILM_NOTIFICATION_ALL, g_ilm_notification_mask); +} + +/** ================================================================================================ + * @test_id wm_listener_layer_opacity_success + * @brief Test case of wm_listener_layer_opacity() where valid layer id + * and notication callback is not null pointer + * @test_procedure Steps: + * -# Set the ilm context initialized is true, ready init + * -# Calling the ilm_layerAddNotification() to add a callback + * -# Calling the wm_listener_layer_opacity() time 1 with opacity is 0 + * -# Calling the wm_listener_layer_opacity() time 2 with opacity is 0.5 + * -# Verification point: + * +# ilm_layerAddNotification() must return ILM_SUCCESS + * +# When invoke callback function, g_ilm_notification_mask must be seted to ILM_NOTIFICATION_OPACITY + */ +TEST_F(IlmControlTest, wm_listener_layer_opacity_success) +{ + ilm_context.initialized = true; + + uint32_t l_layer_id = 100; + ASSERT_EQ(ILM_SUCCESS, ilm_layerAddNotification(l_layer_id, &layerCallbackFunction)); + wm_listener_layer_opacity(&ilm_context.wl, nullptr, l_layer_id, 0); + wm_listener_layer_opacity(&ilm_context.wl, nullptr, l_layer_id, 0.5); + + ASSERT_EQ(ILM_NOTIFICATION_OPACITY, g_ilm_notification_mask); +} + +/** ================================================================================================ + * @test_id wm_listener_surface_source_rectangle_invalidSurface + * @brief Test case of wm_listener_surface_source_rectangle() where invalid surface id + * and notication callback is null pointer + * @test_procedure Steps: + * -# Calling the wm_listener_surface_source_rectangle() + * -# Verification point: + * +# When invoke callback function, g_ilm_notification_mask must be seted to default ILM_NOTIFICATION_ALL + */ +TEST_F(IlmControlTest, wm_listener_surface_source_rectangle_invalidSurface) +{ + uint32_t l_surface_id = 6; + wm_listener_surface_source_rectangle(&ilm_context.wl, nullptr, l_surface_id, 0, 0, 450, 450); + + ASSERT_EQ(ILM_NOTIFICATION_ALL, g_ilm_notification_mask); +} + +/** ================================================================================================ + * @test_id wm_listener_surface_source_rectangle_nullNotification + * @brief Test case of wm_listener_surface_source_rectangle() where valid surface id + * and notication callback is null pointer + * @test_procedure Steps: + * -# Calling the wm_listener_surface_source_rectangle() + * -# Verification point: + * +# When invoke callback function, g_ilm_notification_mask must be seted to default ILM_NOTIFICATION_ALL + */ +TEST_F(IlmControlTest, wm_listener_surface_source_rectangle_nullNotification) +{ + uint32_t l_surface_id = 5; + wm_listener_surface_source_rectangle(&ilm_context.wl, nullptr, l_surface_id, 1, 0, 500, 500); + + ASSERT_EQ(ILM_NOTIFICATION_ALL, g_ilm_notification_mask); +} + +/** ================================================================================================ + * @test_id wm_listener_surface_source_rectangle_success + * @brief Test case of wm_listener_surface_source_rectangle() where valid surface id + * and notication callback is not null pointer + * @test_procedure Steps: + * -# Set the ilm context initialized is true, ready init + * -# Calling the ilm_surfaceAddNotification() to add a callback + * -# Calling the wm_listener_surface_source_rectangle() multiple times with different input param x, y, width, height + * -# Verification point: + * +# ilm_surfaceAddNotification() must return ILM_SUCCESS + * +# When invoke callback function, g_ilm_notification_mask must be seted to ILM_NOTIFICATION_SOURCE_RECT + */ +TEST_F(IlmControlTest, wm_listener_surface_source_rectangle_success) +{ + ilm_context.initialized = true; + + uint32_t l_surface_id = 1; + ASSERT_EQ(ILM_SUCCESS, ilm_surfaceAddNotification(l_surface_id, &surfaceCallbackFunction)); + wm_listener_surface_source_rectangle(&ilm_context.wl, nullptr, l_surface_id, 1, 0, 500, 500); + wm_listener_surface_source_rectangle(&ilm_context.wl, nullptr, l_surface_id, 0, 1, 500, 500); + wm_listener_surface_source_rectangle(&ilm_context.wl, nullptr, l_surface_id, 0, 0, 1, 500); + wm_listener_surface_source_rectangle(&ilm_context.wl, nullptr, l_surface_id, 0, 0, 500, 1); + wm_listener_surface_source_rectangle(&ilm_context.wl, nullptr, l_surface_id, 0, 0, 500, 500); + wm_listener_surface_source_rectangle(&ilm_context.wl, nullptr, l_surface_id, 0, 0, 500, 500); + + ASSERT_EQ(ILM_NOTIFICATION_SOURCE_RECT, g_ilm_notification_mask); +} + +/** ================================================================================================ + * @test_id wm_listener_layer_source_rectangle_invalidLayer + * @brief Test case of wm_listener_layer_source_rectangle() where invalid layer id + * and notication callback is null pointer + * @test_procedure Steps: + * -# Calling the wm_listener_layer_source_rectangle() + * -# Verification point: + * +# When invoke callback function, g_ilm_notification_mask must be seted to default ILM_NOTIFICATION_ALL + */ +TEST_F(IlmControlTest, wm_listener_layer_source_rectangle_invalidLayer) +{ + uint32_t l_layer_id = 1; + wm_listener_layer_source_rectangle(&ilm_context.wl, nullptr, l_layer_id, 0, 0, 450, 450); + + ASSERT_EQ(ILM_NOTIFICATION_ALL, g_ilm_notification_mask); +} + +/** ================================================================================================ + * @test_id wm_listener_layer_source_rectangle_nullNotification + * @brief Test case of wm_listener_layer_source_rectangle() where valid layer id + * and notication callback is null pointer + * @test_procedure Steps: + * -# Calling the wm_listener_layer_source_rectangle() + * -# Verification point: + * +# When invoke callback function, g_ilm_notification_mask must be seted to default ILM_NOTIFICATION_ALL + */ +TEST_F(IlmControlTest, wm_listener_layer_source_rectangle_nullNotification) +{ + uint32_t l_layer_id = 500; + wm_listener_layer_source_rectangle(&ilm_context.wl, nullptr, l_layer_id, 0, 0, 1280, 0); + + ASSERT_EQ(ILM_NOTIFICATION_ALL, g_ilm_notification_mask); +} + +/** ================================================================================================ + * @test_id wm_listener_layer_source_rectangle_success + * @brief Test case of wm_listener_layer_source_rectangle() where valid layer id + * and notication callback is not null pointer + * @test_procedure Steps: + * -# Set the ilm context initialized is true, ready init + * -# Calling the ilm_layerAddNotification() to add a callback + * -# Calling the wm_listener_layer_source_rectangle() multiple times with different input param x, y, width, height + * -# Verification point: + * +# ilm_layerAddNotification() must return ILM_SUCCESS + * +# When invoke callback function, g_ilm_notification_mask must be seted to ILM_NOTIFICATION_SOURCE_RECT + */ +TEST_F(IlmControlTest, wm_listener_layer_source_rectangle_success) +{ + ilm_context.initialized = true; + + uint32_t l_layer_id = 100; + ASSERT_EQ(ILM_SUCCESS, ilm_layerAddNotification(l_layer_id, &layerCallbackFunction)); + wm_listener_layer_source_rectangle(&ilm_context.wl, nullptr, l_layer_id, 1, 0, 1280, 720); + wm_listener_layer_source_rectangle(&ilm_context.wl, nullptr, l_layer_id, 0, 1, 1280, 720); + wm_listener_layer_source_rectangle(&ilm_context.wl, nullptr, l_layer_id, 0, 0, 1, 720); + wm_listener_layer_source_rectangle(&ilm_context.wl, nullptr, l_layer_id, 0, 0, 1280, 1); + wm_listener_layer_source_rectangle(&ilm_context.wl, nullptr, l_layer_id, 0, 0, 1280, 720); + wm_listener_layer_source_rectangle(&ilm_context.wl, nullptr, l_layer_id, 0, 0, 1280, 720); + + ASSERT_EQ(ILM_NOTIFICATION_SOURCE_RECT, g_ilm_notification_mask); +} + +/** ================================================================================================ + * @test_id wm_listener_surface_destination_rectangle_invalidSurface + * @brief Test case of wm_listener_surface_destination_rectangle() where invalid surface id + * and notication callback is null pointer + * @test_procedure Steps: + * -# Calling the wm_listener_surface_destination_rectangle() + * -# Verification point: + * +# When invoke callback function, g_ilm_notification_mask must be seted to default ILM_NOTIFICATION_ALL + */ +TEST_F(IlmControlTest, wm_listener_surface_destination_rectangle_invalidSurface) +{ + uint32_t l_surface_id = 6; + wm_listener_surface_destination_rectangle(&ilm_context.wl, nullptr, l_surface_id, 0, 0, 450, 450); + + ASSERT_EQ(ILM_NOTIFICATION_ALL, g_ilm_notification_mask); +} + +/** ================================================================================================ + * @test_id wm_listener_surface_destination_rectangle_nullNotification + * @brief Test case of wm_listener_surface_destination_rectangle() where valid surface id + * and notication callback is null pointer + * @test_procedure Steps: + * -# Calling the wm_listener_surface_destination_rectangle() + * -# Verification point: + * +# When invoke callback function, g_ilm_notification_mask must be seted to default ILM_NOTIFICATION_ALL + */ +TEST_F(IlmControlTest, wm_listener_surface_destination_rectangle_nullNotification) +{ + uint32_t l_surface_id = 5; + wm_listener_surface_destination_rectangle(&ilm_context.wl, nullptr, l_surface_id, 0, 0, 500, 0); + + ASSERT_EQ(ILM_NOTIFICATION_ALL, g_ilm_notification_mask); +} + +/** ================================================================================================ + * @test_id wm_listener_surface_destination_rectangle_success + * @brief Test case of wm_listener_surface_destination_rectangle() where valid surface id + * and notication callback is not null pointer + * @test_procedure Steps: + * -# Set the ilm context initialized is true, ready init + * -# Calling the ilm_surfaceAddNotification() to add a callback + * -# Calling the wm_listener_surface_destination_rectangle() multiple times with different input param x, y, width, height + * -# Verification point: + * +# ilm_surfaceAddNotification() must return ILM_SUCCESS + * +# When invoke callback function, g_ilm_notification_mask must be seted to ILM_NOTIFICATION_DEST_RECT + */ +TEST_F(IlmControlTest, wm_listener_surface_destination_rectangle_success) +{ + ilm_context.initialized = true; + + uint32_t l_surface_id = 1; + ASSERT_EQ(ILM_SUCCESS, ilm_surfaceAddNotification(l_surface_id, &surfaceCallbackFunction)); + wm_listener_surface_destination_rectangle(&ilm_context.wl, nullptr, l_surface_id, 1, 0, 500, 500); + wm_listener_surface_destination_rectangle(&ilm_context.wl, nullptr, l_surface_id, 0, 1, 500, 500); + wm_listener_surface_destination_rectangle(&ilm_context.wl, nullptr, l_surface_id, 0, 0, 1, 500); + wm_listener_surface_destination_rectangle(&ilm_context.wl, nullptr, l_surface_id, 0, 0, 500, 1); + wm_listener_surface_destination_rectangle(&ilm_context.wl, nullptr, l_surface_id, 0, 0, 500, 500); + wm_listener_surface_destination_rectangle(&ilm_context.wl, nullptr, l_surface_id, 0, 0, 500, 500); + + ASSERT_EQ(ILM_NOTIFICATION_DEST_RECT, g_ilm_notification_mask); +} + +/** ================================================================================================ + * @test_id wm_listener_layer_destination_rectangle_invalidLayer + * @brief Test case of wm_listener_layer_destination_rectangle() where invalid layer id + * and notication callback is null pointer + * @test_procedure Steps: + * -# Calling the wm_listener_layer_source_rectangle() + * -# Verification point: + * +# When invoke callback function, g_ilm_notification_mask must be seted to default ILM_NOTIFICATION_ALL + */ +TEST_F(IlmControlTest, wm_listener_layer_destination_rectangle_invalidLayer) +{ + uint32_t l_layer_id = 1; + wm_listener_layer_destination_rectangle(&ilm_context.wl, nullptr, l_layer_id, 0, 0, 450, 450); + + ASSERT_EQ(ILM_NOTIFICATION_ALL, g_ilm_notification_mask); +} + +/** ================================================================================================ + * @test_id wm_listener_layer_destination_rectangle_nullNotification + * @brief Test case of wm_listener_layer_destination_rectangle() where valid layer id + * and notication callback is null pointer + * @test_procedure Steps: + * -# Calling the wm_listener_layer_source_rectangle() + * -# Verification point: + * +# When invoke callback function, g_ilm_notification_mask must be seted to default ILM_NOTIFICATION_ALL + */ +TEST_F(IlmControlTest, wm_listener_layer_destination_rectangle_nullNotification) +{ + uint32_t l_layer_id = 500; + wm_listener_layer_destination_rectangle(&ilm_context.wl, nullptr, l_layer_id, 0, 0, 1280, 0); + + ASSERT_EQ(ILM_NOTIFICATION_ALL, g_ilm_notification_mask); +} + +/** ================================================================================================ + * @test_id wm_listener_layer_destination_rectangle_success + * @brief Test case of wm_listener_layer_destination_rectangle() where valid layer id + * and notication callback is not null pointer + * @test_procedure Steps: + * -# Set the ilm context initialized is true, ready init + * -# Calling the ilm_layerAddNotification() to add a callback + * -# Calling the wm_listener_layer_destination_rectangle() multiple times with different input param x, y, width, height + * -# Verification point: + * +# ilm_layerAddNotification() must return ILM_SUCCESS + * +# When invoke callback function, g_ilm_notification_mask must be seted to ILM_NOTIFICATION_DEST_RECT + */ +TEST_F(IlmControlTest, wm_listener_layer_destination_rectangle_success) +{ + ilm_context.initialized = true; + + uint32_t l_layer_id = 100; + ASSERT_EQ(ILM_SUCCESS, ilm_layerAddNotification(l_layer_id, &layerCallbackFunction)); + wm_listener_layer_destination_rectangle(&ilm_context.wl, nullptr, l_layer_id, 1, 0, 1920, 1080); + wm_listener_layer_destination_rectangle(&ilm_context.wl, nullptr, l_layer_id, 0, 1, 1920, 1080); + wm_listener_layer_destination_rectangle(&ilm_context.wl, nullptr, l_layer_id, 0, 0, 1, 1080); + wm_listener_layer_destination_rectangle(&ilm_context.wl, nullptr, l_layer_id, 0, 0, 1920, 1); + wm_listener_layer_destination_rectangle(&ilm_context.wl, nullptr, l_layer_id, 0, 0, 1920, 1080); + wm_listener_layer_destination_rectangle(&ilm_context.wl, nullptr, l_layer_id, 0, 0, 1920, 1080); + + ASSERT_EQ(ILM_NOTIFICATION_DEST_RECT, g_ilm_notification_mask); +} + +/** ================================================================================================ + * @test_id wm_listener_surface_error_success + * @brief Test case of wm_listener_surface_error() where ilm context wl.error_flag is ILM_SUCCESS + * @test_procedure Steps: + * -# Set the ilm context wl.error_flag is ILM_SUCCESS + * -# Calling the wm_listener_surface_error() multiple times with different input param error type + */ +TEST_F(IlmControlTest, wm_listener_surface_error_success) +{ + ilm_context.wl.error_flag = ILM_SUCCESS; + + wm_listener_surface_error(&ilm_context.wl, nullptr, 0, IVI_WM_SURFACE_ERROR_NO_SURFACE, ""); + wm_listener_surface_error(&ilm_context.wl, nullptr, 0, IVI_WM_SURFACE_ERROR_BAD_PARAM, ""); + wm_listener_surface_error(&ilm_context.wl, nullptr, 0, IVI_WM_SURFACE_ERROR_NOT_SUPPORTED, ""); + wm_listener_surface_error(&ilm_context.wl, nullptr, 0, 3, ""); +} + +/** ================================================================================================ + * @test_id wm_listener_layer_error_success + * @brief Test case of wm_listener_layer_error() where ilm context wl.error_flag is ILM_SUCCESS + * @test_procedure Steps: + * -# Set the ilm context wl.error_flag is ILM_SUCCESS + * -# Calling the wm_listener_layer_error() multiple times with different input param error type + */ +TEST_F(IlmControlTest, wm_listener_layer_error_success) +{ + ilm_context.wl.error_flag = ILM_SUCCESS; + + wm_listener_layer_error(&ilm_context.wl, nullptr, 0, IVI_WM_LAYER_ERROR_NO_SURFACE, ""); + wm_listener_layer_error(&ilm_context.wl, nullptr, 0, IVI_WM_LAYER_ERROR_NO_LAYER, ""); + wm_listener_layer_error(&ilm_context.wl, nullptr, 0, IVI_WM_LAYER_ERROR_BAD_PARAM, ""); + wm_listener_layer_error(&ilm_context.wl, nullptr, 0, 3, ""); +} + +/** ================================================================================================ + * @test_id wm_listener_surface_size_invalidSurface + * @brief Test case of wm_listener_surface_size() where invalid surface id + * and notication callback is null pointer + * @test_procedure Steps: + * -# Calling the wm_listener_surface_size() + * -# Verification point: + * +# When invoke callback function, g_ilm_notification_mask must be seted to default ILM_NOTIFICATION_ALL + */ +TEST_F(IlmControlTest, wm_listener_surface_size_invalidSurface) +{ + uint32_t l_surface_id = 6; + wm_listener_surface_size(&ilm_context.wl, nullptr, l_surface_id, 450, 450); + + ASSERT_EQ(ILM_NOTIFICATION_ALL, g_ilm_notification_mask); +} + +/** ================================================================================================ + * @test_id wm_listener_surface_size_nullNotification + * @brief Test case of wm_listener_surface_size() where valid surface id + * and notication callback is null pointer + * @test_procedure Steps: + * -# Calling the wm_listener_surface_size() + * -# Verification point: + * +# When invoke callback function, g_ilm_notification_mask must be seted to default ILM_NOTIFICATION_ALL + */ +TEST_F(IlmControlTest, wm_listener_surface_size_nullNotification) +{ + uint32_t l_surface_id = 5; + wm_listener_surface_size(&ilm_context.wl, nullptr, l_surface_id, 0, 500); + + ASSERT_EQ(ILM_NOTIFICATION_ALL, g_ilm_notification_mask); +} + +/** ================================================================================================ + * @test_id wm_listener_surface_size_success + * @brief Test case of wm_listener_surface_size() where valid surface id + * and notication callback is not null pointer + * @test_procedure Steps: + * -# Set the ilm context initialized is true, ready init + * -# Calling the ilm_surfaceAddNotification() to add a callback + * -# Calling the wm_listener_surface_size() multiple times with different input param width, height + * -# Verification point: + * +# ilm_surfaceAddNotification() must return ILM_SUCCESS + * +# When invoke callback function, g_ilm_notification_mask must be seted to ILM_NOTIFICATION_CONFIGURED + */ +TEST_F(IlmControlTest, wm_listener_surface_size_success) +{ + ilm_context.initialized = true; + + uint32_t l_surface_id = 1; + ASSERT_EQ(ILM_SUCCESS, ilm_surfaceAddNotification(l_surface_id, &surfaceCallbackFunction)); + wm_listener_surface_size(&ilm_context.wl, nullptr, l_surface_id, 0, 500); + wm_listener_surface_size(&ilm_context.wl, nullptr, l_surface_id, 500, 0); + wm_listener_surface_size(&ilm_context.wl, nullptr, l_surface_id, 500, 500); + wm_listener_surface_size(&ilm_context.wl, nullptr, l_surface_id, 500, 500); + + ASSERT_EQ(ILM_NOTIFICATION_CONFIGURED, g_ilm_notification_mask); +} + +/** ================================================================================================ + * @test_id wm_listener_surface_stats_invalidSurface + * @brief Test case of wm_listener_surface_stats() where invalid surface id + * @test_procedure Steps: + * -# Calling the wm_listener_surface_stats() + */ +TEST_F(IlmControlTest, wm_listener_surface_stats_invalidSurface) +{ + uint32_t l_surface_id = 6; + wm_listener_surface_stats(&ilm_context.wl, nullptr, l_surface_id, 0, 0); +} + +/** ================================================================================================ + * @test_id wm_listener_surface_stats_success + * @brief Test case of wm_listener_surface_stats() where valid surface id + * @test_procedure Steps: + * -# Calling the wm_listener_surface_stats() + */ +TEST_F(IlmControlTest, wm_listener_surface_stats_success) +{ + uint32_t l_surface_id = 1; + wm_listener_surface_stats(&ilm_context.wl, nullptr, l_surface_id, 0, 0); +} + +/** ================================================================================================ + * @test_id output_listener_geometry_success + * @brief Test case of output_listener_geometry() where passing valid input params + * @test_procedure Steps: + * -# Calling the output_listener_geometry() + */ +TEST_F(IlmControlTest, output_listener_geometry_success) +{ + output_listener_geometry(mp_ctxScreen[0], nullptr, 0, 0, 0, 0, 0, nullptr, nullptr, 0); +} + +/** ================================================================================================ + * @test_id output_listener_mode_failure + * @brief Test case of output_listener_mode() where passing valid input params + * and input flag is false {0} + * @test_procedure Steps: + * -# Calling the output_listener_mode() + */ +TEST_F(IlmControlTest, output_listener_mode_failure) +{ + output_listener_mode(mp_ctxScreen[0], nullptr, 0, 0, 0, 0); +} + +/** ================================================================================================ + * @test_id output_listener_mode_success + * @brief Test case of output_listener_mode() where passing valid input params + * and input flag is true {1} + * @test_procedure Steps: + * -# Calling the output_listener_mode() multiples times with different input transform types + */ +TEST_F(IlmControlTest, output_listener_mode_success) +{ + output_listener_mode(mp_ctxScreen[0], nullptr, 1, 0, 0, 0); + + mp_ctxScreen[0]->transform = WL_OUTPUT_TRANSFORM_90; + output_listener_mode(mp_ctxScreen[0], nullptr, 1, 0, 0, 0); + + mp_ctxScreen[0]->transform = WL_OUTPUT_TRANSFORM_270; + output_listener_mode(mp_ctxScreen[0], nullptr, 1, 0, 0, 0); + + mp_ctxScreen[0]->transform = WL_OUTPUT_TRANSFORM_FLIPPED_90; + output_listener_mode(mp_ctxScreen[0], nullptr, 1, 0, 0, 0); + + mp_ctxScreen[0]->transform = WL_OUTPUT_TRANSFORM_FLIPPED_270; + output_listener_mode(mp_ctxScreen[0], nullptr, 1, 0, 0, 0); +} + +/** ================================================================================================ + * @test_id output_listener_done_success + * @brief Test case of output_listener_done() where passing valid input params + * @test_procedure Steps: + * -# Calling the output_listener_done() + */ +TEST_F(IlmControlTest, output_listener_done_success) +{ + output_listener_done(nullptr, nullptr); +} + +/** ================================================================================================ + * @test_id output_listener_scale_success + * @brief Test case of output_listener_scale() where passing valid input params + * @test_procedure Steps: + * -# Calling the output_listener_scale() + */ +TEST_F(IlmControlTest, output_listener_scale_success) +{ + output_listener_scale(nullptr, nullptr, 0); +} + +/** ================================================================================================ + * @test_id wm_screen_listener_screen_id_success + * @brief Test case of wm_screen_listener_screen_id() where passing valid input params + * @test_procedure Steps: + * -# Calling the wm_screen_listener_screen_id() + */ +TEST_F(IlmControlTest, wm_screen_listener_screen_id_success) +{ + wm_screen_listener_screen_id(mp_ctxScreen[0], nullptr, 0); +} + +/** ================================================================================================ + * @test_id wm_screen_listener_layer_added_success + * @brief Test case of wm_screen_listener_layer_added() where wl_array_add() success, return a variable + * @test_procedure Steps: + * -# Mocking the wl_array_add() does return a variable + * -# Calling the wm_screen_listener_layer_added() with input layer id is 100 + * -# Verification point: + * +# wl_array_add() must be called once time + * +# The variable must same input layer id + * +# Free resources are allocated when running the test + */ +TEST_F(IlmControlTest, wm_screen_listener_layer_added_success) +{ + uint32_t l_dataScreen = 0; + void *lp_elemData = &l_dataScreen; + SET_RETURN_SEQ(wl_array_add, &lp_elemData, 100); + + wm_screen_listener_layer_added(&mp_ctxScreen[0], nullptr, 100); + + ASSERT_EQ(1, wl_array_add_fake.call_count); + ASSERT_EQ(100, l_dataScreen); + + custom_wl_array_release(&mp_ctxScreen[0]->render_order); +} + +/** ================================================================================================ + * @test_id wm_screen_listener_connector_name_success + * @brief Test case of wm_screen_listener_connector_name() where passing valid input params + * @test_procedure Steps: + * -# Calling the wm_screen_listener_connector_name() + */ +TEST_F(IlmControlTest, wm_screen_listener_connector_name_success) +{ + wm_screen_listener_connector_name(mp_ctxScreen[0], nullptr, "TEST"); +} + +/** ================================================================================================ + * @test_id wm_screen_listener_error_success + * @brief Test case of wm_screen_listener_error() where passing valid input params + * @test_procedure Steps: + * -# Set input data id_screen is 1 and ctx->error_flag is ILM_SUCCESS + * -# Calling the wm_screen_listener_error() multiples times with different input error types + */ +TEST_F(IlmControlTest, wm_screen_listener_error_success) +{ + mp_ctxScreen[0]->id_screen = 1; + mp_ctxScreen[0]->ctx->error_flag = ILM_SUCCESS; + wm_screen_listener_error(mp_ctxScreen[0], nullptr, IVI_WM_SCREEN_ERROR_NO_LAYER, ""); + wm_screen_listener_error(mp_ctxScreen[0], nullptr, IVI_WM_SCREEN_ERROR_NO_SCREEN, ""); + wm_screen_listener_error(mp_ctxScreen[0], nullptr, IVI_WM_SCREEN_ERROR_BAD_PARAM, ""); + wm_screen_listener_error(mp_ctxScreen[0], nullptr, 3, ""); +} + +/** ================================================================================================ + * @test_id input_listener_seat_created_validSeat + * @brief Test case of input_listener_seat_created() where valid input seat + * @test_procedure Steps: + * -# Calling the input_listener_seat_created() + * -# Verification point: + * +# wl_list_insert() not be called + */ +TEST_F(IlmControlTest, input_listener_seat_created_validSeat) +{ + input_listener_seat_created(&ilm_context.wl, nullptr, "TOUCH", 0, 1); + + ASSERT_EQ(0, wl_list_insert_fake.call_count); +} + +/** ================================================================================================ + * @test_id input_listener_seat_created_newOne + * @brief Test case of input_listener_seat_created() where invalid input seat + * @test_procedure Steps: + * -# Calling the input_listener_seat_created() + * -# Verification point: + * +# wl_list_insert() must be called once time + * +# Free resources are allocated when running the test + */ +TEST_F(IlmControlTest, input_listener_seat_created_newOne) +{ + input_listener_seat_created(&ilm_context.wl, nullptr, "", 0, 1); + + ASSERT_EQ(1, wl_list_insert_fake.call_count); + + struct seat_context *lp_createSeat = (struct seat_context*)(uintptr_t(wl_list_insert_fake.arg1_history[0]) - offsetof(struct seat_context, link)); + free(lp_createSeat->seat_name); + free(lp_createSeat); +} + +/** ================================================================================================ + * @test_id input_listener_seat_capabilities_invalidSeat + * @brief Test case of input_listener_seat_capabilities() where invalid input seat + * @test_procedure Steps: + * -# Calling the input_listener_seat_capabilities() + */ +TEST_F(IlmControlTest, input_listener_seat_capabilities_invalidSeat) +{ + input_listener_seat_capabilities(&ilm_context.wl, nullptr, "", 0); +} + +/** ================================================================================================ + * @test_id input_listener_seat_capabilities_success + * @brief Test case of input_listener_seat_capabilities() where valid input seat + * @test_procedure Steps: + * -# Calling the input_listener_seat_capabilities() + */ +TEST_F(IlmControlTest, input_listener_seat_capabilities_success) +{ + input_listener_seat_capabilities(&ilm_context.wl, nullptr, "TOUCH", 0); +} + +/** ================================================================================================ + * @test_id input_listener_seat_destroyed_invalidSeat + * @brief Test case of input_listener_seat_destroyed() where invalid input seat + * @test_procedure Steps: + * -# Calling the input_listener_seat_destroyed() + * -# Verification point: + * +# wl_list_remove() not be called + */ +TEST_F(IlmControlTest, input_listener_seat_destroyed_invalidSeat) +{ + input_listener_seat_destroyed(&ilm_context.wl, nullptr, ""); + + ASSERT_EQ(0, wl_list_remove_fake.call_count); +} + +/** ================================================================================================ + * @test_id input_listener_seat_destroyed_success + * @brief Test case of input_listener_seat_destroyed() where valid input seat + * @test_procedure Steps: + * -# Prepare mock for wl_list_remove(), to remove real object + * -# Calling the input_listener_seat_destroyed() + * -# Verification point: + * +# wl_list_remove() must be called once time + * +# Allocate memory for resources are freed when running the test + */ +TEST_F(IlmControlTest, input_listener_seat_destroyed_success) +{ + wl_list_remove_fake.custom_fake = custom_wl_list_remove; + + input_listener_seat_destroyed(&ilm_context.wl, nullptr, "KEYBOARD"); + + ASSERT_EQ(1, wl_list_remove_fake.call_count); + + mp_ctxSeat[0] = (struct seat_context*)malloc(sizeof(struct seat_context)); + mp_ctxSeat[0]->seat_name = strdup(mp_ilmSeatNames[0]); +} + +/** ================================================================================================ + * @test_id input_listener_input_focus_invalidSurface + * @brief Test case of input_listener_input_focus() where invalid input surface id + * and input enabled is false {0} + * @test_procedure Steps: + * -# Calling the input_listener_input_focus() + */ +TEST_F(IlmControlTest, input_listener_input_focus_invalidSurface) +{ + uint32_t l_surface_id = 6; + int32_t l_enabled = 0; + input_listener_input_focus(&ilm_context.wl, nullptr, l_surface_id, 0, l_enabled); +} + +/** ================================================================================================ + * @test_id input_listener_input_focus_unenabled + * @brief Test case of input_listener_input_focus() where valid input surface id + * and input enabled is false {0} + * @test_procedure Steps: + * -# Calling the input_listener_input_focus() + */ +TEST_F(IlmControlTest, input_listener_input_focus_unenabled) +{ + uint32_t l_surface_id = 1; + int32_t l_enabled = 0; + input_listener_input_focus(&ilm_context.wl, nullptr, l_surface_id, 0, l_enabled); +} + +/** ================================================================================================ + * @test_id input_listener_input_focus_enabled + * @brief Test case of input_listener_input_focus() where valid input surface id + * and input enabled is true {1} + * @test_procedure Steps: + * -# Calling the input_listener_input_focus() + */ +TEST_F(IlmControlTest, input_listener_input_focus_enabled) +{ + uint32_t l_surface_id = 1; + int32_t l_enabled = 1; + input_listener_input_focus(&ilm_context.wl, nullptr, l_surface_id, 0, l_enabled); +} + +/** ================================================================================================ + * @test_id input_listener_input_acceptance_invalidSurface + * @brief Test case of input_listener_input_acceptance() where invalid input surface id + * and input accepted is true {1} and invalid input seat + * @test_procedure Steps: + * -# Calling the input_listener_input_acceptance() + * -# Verification point: + * +# wl_list_remove() not be called + * +# wl_list_insert() not be called + */ +TEST_F(IlmControlTest, input_listener_input_acceptance_invalidSurface) +{ + uint32_t l_surface_id = 6; + int32_t l_accepted = 1; + input_listener_input_acceptance(&ilm_context.wl, nullptr, l_surface_id, "", l_accepted); + + ASSERT_EQ(0, wl_list_remove_fake.call_count); + ASSERT_EQ(0, wl_list_insert_fake.call_count); +} + +/** ================================================================================================ + * @test_id input_listener_input_acceptance_invalidSeatAndAccepted + * @brief Test case of input_listener_input_acceptance() where valid input surface id + * and input accepted is true {1} and invalid input seat + * @test_procedure Steps: + * -# Calling the input_listener_input_acceptance() + * -# Verification point: + * +# wl_list_remove() not be called + * +# wl_list_insert() must be called once time + * +# Free resources are allocated when running the test + */ +TEST_F(IlmControlTest, input_listener_input_acceptance_invalidSeatAndAccepted) +{ + uint32_t l_surface_id = 1; + int32_t l_accepted = 1; + input_listener_input_acceptance(&ilm_context.wl, nullptr, l_surface_id, "", l_accepted); + + ASSERT_EQ(0, wl_list_remove_fake.call_count); + ASSERT_EQ(1, wl_list_insert_fake.call_count); + + struct seat_context *lp_accepted_seat = (struct seat_context*)(uintptr_t(wl_list_insert_fake.arg1_history[0]) - offsetof(struct seat_context, link)); + free(lp_accepted_seat->seat_name); + free(lp_accepted_seat); +} + +/** ================================================================================================ + * @test_id input_listener_input_acceptance_invalidSeatAndUnaccepted + * @brief Test case of input_listener_input_acceptance() where valid input surface id + * and input accepted is false {0} and invalid input seat + * @test_procedure Steps: + * -# Calling the input_listener_input_acceptance() + * -# Verification point: + * +# wl_list_remove() not be called + * +# wl_list_insert() not be called + */ +TEST_F(IlmControlTest, input_listener_input_acceptance_invalidSeatAndUnaccepted) +{ + uint32_t l_surface_id = 1; + int32_t l_accepted = 0; + input_listener_input_acceptance(&ilm_context.wl, nullptr, l_surface_id, "", l_accepted); + + ASSERT_EQ(0, wl_list_remove_fake.call_count); + ASSERT_EQ(0, wl_list_insert_fake.call_count); +} + +/** ================================================================================================ + * @test_id input_listener_input_acceptance_validSeatAndAccepted + * @brief Test case of input_listener_input_acceptance() where valid input surface id + * and input accepted is true {1} and valid input seat + * @test_procedure Steps: + * -# Prepare mock for wl_list_remove(), to remove real object + * -# Calling the input_listener_input_acceptance() + * -# Verification point: + * +# wl_list_remove() not be called + * +# wl_list_insert() not be called + */ +TEST_F(IlmControlTest, input_listener_input_acceptance_validSeatAndAccepted) +{ + wl_list_remove_fake.custom_fake = custom_wl_list_remove; + + uint32_t l_surface_id = 1; + int32_t l_accepted = 1; + input_listener_input_acceptance(&ilm_context.wl, nullptr, l_surface_id, "KEYBOARD", l_accepted); + + ASSERT_EQ(0, wl_list_remove_fake.call_count); + ASSERT_EQ(0, wl_list_insert_fake.call_count); +} + +/** ================================================================================================ + * @test_id input_listener_input_acceptance_validSeatAndUnaccepted + * @brief Test case of input_listener_input_acceptance() where valid input surface id + * and input accepted is false {0} and valid input seat + * @test_procedure Steps: + * -# Prepare mock for wl_list_remove(), to remove real object + * -# Calling the input_listener_input_acceptance() + * -# Verification point: + * +# wl_list_remove() must be called once time + * +# wl_list_insert() not be called + * +# Allocate memory for resources are freed when running the test + */ +TEST_F(IlmControlTest, input_listener_input_acceptance_validSeatAndUnaccepted) +{ + wl_list_remove_fake.custom_fake = custom_wl_list_remove; + + uint32_t surface_id = 1; + int32_t accepted = 0; + input_listener_input_acceptance(&ilm_context.wl, nullptr, surface_id, "KEYBOARD", accepted); + + ASSERT_EQ(1, wl_list_remove_fake.call_count); + ASSERT_EQ(0, wl_list_insert_fake.call_count); + + mp_accepted_seat[0] = (struct accepted_seat*)malloc(sizeof(struct accepted_seat)); + mp_accepted_seat[0]->seat_name = strdup("KEYBOARD"); +} + +/** ================================================================================================ + * @test_id registry_handle_control_success + * @brief Test case of registry_handle_control() where passing different input params + * @test_procedure Steps: + * -# Calling the registry_handle_control() time 1 with null interface + * -# Calling the registry_handle_control() time 2 with interface is ivi_wm + * -# Calling the registry_handle_control() time 3 with interface is ivi_input + * -# Calling the registry_handle_control() time 4 with interface is wl_output + * -# Mocking the wl_proxy_marshal_flags() does return an object + * -# Mocking the wl_proxy_add_listener() does return -1 (failure) + * -# Calling the registry_handle_control() time 5 with interface is wl_output + * -# Mocking the wl_proxy_marshal_flags() does return an object + * -# Mocking the wl_proxy_add_listener() does return 0 (success) + * -# Calling the registry_handle_control() time 6 with interface is wl_output + * -# Verification point: + * +# wl_proxy_marshal_flags() not be called when calling time 1 + * +# wl_proxy_marshal_flags() must be called when calling time 2, time 3, time 4, time 5, time 6 + * +# wl_proxy_add_listener() not be called when calling time 1, time 2, time 3, time 4 + * +# wl_proxy_add_listener() must be called when calling time 5, time 6 + * +# wl_list_insert() must be called when calling time 6 + * +# Free resources are allocated when running the test + * + */ +TEST_F(IlmControlTest, registry_handle_control_success) +{ + registry_handle_control(&ilm_context.wl, nullptr, 0 ,"", 0); + + ASSERT_EQ(0, wl_proxy_marshal_flags_fake.call_count); + ASSERT_EQ(0, wl_proxy_add_listener_fake.call_count); + + registry_handle_control(&ilm_context.wl, nullptr, 0 ,"ivi_wm", 0); + + ASSERT_EQ(1, wl_proxy_marshal_flags_fake.call_count); + ASSERT_EQ(0, wl_proxy_add_listener_fake.call_count); + + registry_handle_control(&ilm_context.wl, nullptr, 0 ,"ivi_input", 0); + + ASSERT_EQ(2, wl_proxy_marshal_flags_fake.call_count); + ASSERT_EQ(0, wl_proxy_add_listener_fake.call_count); + + registry_handle_control(&ilm_context.wl, nullptr, 0 ,"wl_output", 0); + + ASSERT_EQ(3, wl_proxy_marshal_flags_fake.call_count); + ASSERT_EQ(0, wl_proxy_add_listener_fake.call_count); + + struct wl_proxy *id[1] = {(struct wl_proxy *)0xFFFFFFFF}; + SET_RETURN_SEQ(wl_proxy_marshal_flags, id, 1); + SET_RETURN_SEQ(wl_proxy_add_listener, mp_failureResult, 1); + + registry_handle_control(&ilm_context.wl, nullptr, 0 ,"wl_output", 0); + + ASSERT_EQ(4, wl_proxy_marshal_flags_fake.call_count); + ASSERT_EQ(1, wl_proxy_add_listener_fake.call_count); + + SET_RETURN_SEQ(wl_proxy_marshal_flags, id, 1); + SET_RETURN_SEQ(wl_proxy_add_listener, mp_successResult, 1); + + registry_handle_control(&ilm_context.wl, nullptr, 0 ,"wl_output", 0); + + ASSERT_EQ(5, wl_proxy_marshal_flags_fake.call_count); + ASSERT_EQ(2, wl_proxy_add_listener_fake.call_count); + ASSERT_EQ(1, wl_list_insert_fake.call_count); + + struct screen_context *lp_createScreen = (struct screen_context*)(uintptr_t(wl_list_insert_fake.arg1_history[0]) - offsetof(struct screen_context, link)); + free(lp_createScreen); +} + +/** ================================================================================================ + * @test_id registry_handle_control_remove_invalidName + * @brief Test case of registry_handle_control_remove() where invalid input name + * @test_procedure Steps: + * -# Prepare mock for wl_list_remove(), to remove real object + * -# Calling the registry_handle_control_remove() + * -# Verification point: + * +# wl_list_remove() not be called + */ +TEST_F(IlmControlTest, registry_handle_control_remove_invalidName) +{ + wl_list_remove_fake.custom_fake = custom_wl_list_remove; + + registry_handle_control_remove(&ilm_context.wl, nullptr, 10); + + ASSERT_EQ(0, wl_list_remove_fake.call_count); +} + +/** ================================================================================================ + * @test_id registry_handle_control_remove_oneNode + * @brief Test case of registry_handle_control_remove() where valid input name + * @test_procedure Steps: + * -# Prepare mock for wl_list_remove(), to remove real object + * -# Calling the registry_handle_control_remove() time 1 + * -# Set input data controller and output to null pointer + * -# Calling the registry_handle_control_remove() time 2 + * -# Verification point: + * +# wl_list_remove() must be called + * +# Allocate memory for resources are freed when running the test + */ +TEST_F(IlmControlTest, registry_handle_control_remove_oneNode) +{ + wl_list_remove_fake.custom_fake = custom_wl_list_remove; + + registry_handle_control_remove(&ilm_context.wl, nullptr, 0); + + ASSERT_EQ(1, wl_list_remove_fake.call_count); + + mp_ctxScreen[0] = (struct screen_context*)malloc(sizeof(struct screen_context)); + + mp_ctxScreen[1]->controller = nullptr; + mp_ctxScreen[1]->output = nullptr; + registry_handle_control_remove(&ilm_context.wl, nullptr, 1); + + ASSERT_EQ(2, wl_list_remove_fake.call_count); + + mp_ctxScreen[1] = (struct screen_context*)malloc(sizeof(struct screen_context)); +} + +/** ================================================================================================ + * @test_id ilmControl_init_failed + * @brief Test case of ilmControl_init() where do not mock for some functions + * and ilm context initialized is false + * @test_procedure Steps: + * -# Set the ilm context initialized is true, ready init + * -# Calling the ilmControl_init() time 1 + * -# Set the ilm context initialized is false, not ready init + * -# Calling the ilmControl_init() time 2 + * -# Verification point: + * +# Both of ilmControl_init() time 1 and time 2 must return ILM_FAILED + */ +TEST_F(IlmControlTest, ilmControl_init_failed) +{ + ilm_context.initialized = true; + ASSERT_EQ(ILM_FAILED, ilmControl_init(1)); + + ilm_context.initialized = false; + ASSERT_EQ(ILM_FAILED, ilmControl_init(1)); +} + +/** ================================================================================================ + * @test_id ilmControl_init_error + * @brief Test case of ilmControl_init() where input nativedisplay is 0 + * @test_procedure Steps: + * -# Calling the ilmControl_init() + * -# Verification point: + * +# ilmControl_init() must return ILM_ERROR_INVALID_ARGUMENTS + */ +TEST_F(IlmControlTest, ilmControl_init_error) +{ + ASSERT_EQ(ILM_ERROR_INVALID_ARGUMENTS, ilmControl_init(0)); +} + +/** ================================================================================================ + * @test_id ilmControl_init_failedByInitControl + * @brief Test case of ilmControl_init() where init_control() return false {-1} + * @test_procedure Steps: + * -# Set the ilm context initialized is false, not ready init + * -# Mocking the wl_display_create_queue() does return an object + * -# Mocking the wl_proxy_add_listener() does return -1 (failure) + * -# Mocking the wl_display_roundtrip_queue() does return 0 (success) + * -# Calling the ilmControl_init() time 1 + * -# Mocking the wl_proxy_marshal_flags() does return an object + * -# Mocking the wl_proxy_add_listener() does return -1 (failure) + * -# Mocking the wl_display_roundtrip_queue() does return 0 (success) + * -# Calling the ilmControl_init() time 2 + * -# Mocking the wl_proxy_marshal_flags() does return an object + * -# Mocking the wl_proxy_add_listener() does return 0 (success) + * -# Mocking the wl_display_roundtrip_queue() does return -1 (failure) + * -# Calling the ilmControl_init() time 3 + * -# Verification point: + * +# ilmControl_init() time 1 and time 2 and time 3 must return ILM_FAILED + */ +TEST_F(IlmControlTest, ilmControl_init_failedByInitControl) +{ + ilm_context.initialized = false; + + uint64_t l_wlEventQueueFakePointer = 0, l_wlProxyFakePointer = 0; + struct wl_event_queue *lpp_wlEventQueue[] = {(struct wl_event_queue*)&l_wlEventQueueFakePointer}; + struct wl_proxy *lpp_wlProxy[] = {(struct wl_proxy*)&l_wlProxyFakePointer}; + SET_RETURN_SEQ(wl_display_create_queue, lpp_wlEventQueue, 1); + SET_RETURN_SEQ(wl_proxy_add_listener, mp_failureResult, 1); + SET_RETURN_SEQ(wl_display_roundtrip_queue, mp_successResult, 1); + + ASSERT_EQ(ILM_FAILED, ilmControl_init(1)); + + SET_RETURN_SEQ(wl_proxy_marshal_flags, lpp_wlProxy, 1); + SET_RETURN_SEQ(wl_proxy_add_listener, mp_failureResult, 1); + SET_RETURN_SEQ(wl_display_roundtrip_queue, mp_successResult, 1); + + ASSERT_EQ(ILM_FAILED, ilmControl_init(1)); + + SET_RETURN_SEQ(wl_proxy_marshal_flags, lpp_wlProxy, 1); + SET_RETURN_SEQ(wl_proxy_add_listener, mp_successResult, 1); + SET_RETURN_SEQ(wl_display_roundtrip_queue, mp_failureResult, 1); + + ASSERT_EQ(ILM_FAILED, ilmControl_init(1)); +} + +/** ================================================================================================ + * @test_id ilmControl_init_success + * @brief Test case of ilmControl_init() where init_control() return success {0} + * @test_procedure Steps: + * -# Set the ilm context initialized is false, not ready init + * -# Mocking the wl_display_create_queue() does return an object + * -# Mocking the wl_proxy_marshal_flags() does return an object + * -# Mocking the wl_proxy_add_listener() does return 0 (success) + * -# Mocking the wl_display_roundtrip_queue() does return 0 (success) + * -# Calling the ilmControl_init() + * -# Verification point: + * +# ilmControl_init() must return ILM_SUCCESS + */ +TEST_F(IlmControlTest, ilmControl_init_success) +{ + ilm_context.initialized = false; + + uint64_t l_wlEventQueueFakePointer = 0, l_wlProxyFakePointer = 0; + struct wl_event_queue *lpp_wlEventQueue[] = {(struct wl_event_queue*)&l_wlEventQueueFakePointer}; + struct wl_proxy *lpp_wlProxy[] = {(struct wl_proxy*)&l_wlProxyFakePointer}; + ilm_context.wl.controller = (struct ivi_wm*)&m_iviWmControllerFakePointer; + SET_RETURN_SEQ(wl_display_create_queue, lpp_wlEventQueue, 1); + SET_RETURN_SEQ(wl_proxy_marshal_flags, lpp_wlProxy, 1); + SET_RETURN_SEQ(wl_proxy_add_listener, mp_successResult, 1); + SET_RETURN_SEQ(wl_display_roundtrip_queue, mp_successResult, 1); + + ASSERT_EQ(ILM_SUCCESS, ilmControl_init(1)); +} + +/** ================================================================================================ + * @test_id ilm_takeScreenshot_invalidScreen + * @brief Test case of ilm_takeScreenshot() where invalid input screen ID + * @test_procedure Steps: + * -# Calling the ilm_takeScreenshot() + * -# Verification point: + * +# ilm_takeScreenshot() must return ILM_FAILED + */ +TEST_F(IlmControlTest, ilm_takeScreenshot_invalidScreen) +{ + t_ilm_uint lScreenID{1}; + t_ilm_const_string filename{"name_test"}; + ASSERT_EQ(ILM_FAILED, ilm_takeScreenshot(lScreenID, filename)); +} + +/** ================================================================================================ + * @test_id ilm_takeScreenshot_validScreen + * @brief ilm_takeScreenshot() is called with valid screen ID and valid/invalid file name + * @test_procedure Steps: + * -# Calling the ilm_takeScreenshot() time 1 with valid screen ID and invalid file name + * -# Calling the ilm_takeScreenshot() time 2 with valid screen ID and valid file name + * -# Verification point: + * +# ilm_takeScreenshot() time 1 should return ILM_SUCCESS + * +# ilm_takeScreenshot() time 2 should return ILM_FAILED + */ +TEST_F(IlmControlTest, ilm_takeScreenshot_validScreen) +{ + t_ilm_uint lScreenID{10}; + t_ilm_const_string filename(NULL); + /*- valid screen ID + - invalid file name*/ + ASSERT_EQ(ILM_SUCCESS, ilm_takeScreenshot(lScreenID, filename)); + /*- valid screen ID + - valid file name*/ + filename = "name_test"; + ASSERT_EQ(ILM_FAILED, ilm_takeScreenshot(lScreenID, filename)); +} + +/** ================================================================================================ + * @test_id ilm_takeScreenshot_SupportArgb8888AndUnsupportWlshmGlobal + * @brief ilm_takeScreenshot() is called when argb8888 is supported and wl_shm global is unsupported + * @test_procedure Steps: + * -# make argb8888 is supported + * -# point wl_shm to NULL + * -# call ilm_takeScreenshot with valid screenID and file name + * -# Verification point: + * +# ilm_takeScreenshot() must return ILM_FAILED + * +# wl_proxy_marshal_flags should not be called + */ +TEST_F(IlmControlTest, ilm_takeScreenshot_SupportArgb8888AndUnsupportWlshmGlobal) +{ + t_ilm_uint lScreenID{10}; + t_ilm_const_string filename{"name_test"}; + constexpr uint32_t lValidAddress{0xFFFFFFFF}; + + ilm_context.wl.wl_shm = NULL; + ilm_context.wl.has_argb8888 = true; + ASSERT_EQ(ILM_FAILED, ilm_takeScreenshot(lScreenID, filename)); + ASSERT_EQ(wl_proxy_marshal_flags_fake.call_count, 0); + ilm_context.wl.wl_shm = NULL; + ilm_context.wl.has_argb8888 = false; +} + +/** ================================================================================================ + * @test_id ilm_takeScreenshot_SupportWlshmGlobalAndUnsupportArgb8888 + * @brief ilm_takeScreenshot() is called when wl_shm global is supported and argb8888 is unsupported + * @test_procedure Steps: + * -# make wl_shm global is supported + * -# make argb8888 is unsupported + * -# call ilm_takeScreenshot with valid screenID and file name + * -# Verification point: + * +# ilm_takeScreenshot() must return ILM_FAILED + * +# wl_proxy_marshal_flags should not be called + */ +TEST_F(IlmControlTest, ilm_takeScreenshot_SupportWlshmGlobalAndUnsupportArgb8888) +{ + t_ilm_uint lScreenID{10}; + t_ilm_const_string filename{"name_test"}; + constexpr uint32_t lValidAddress{0xFFFFFFFF}; + // prepare data + ilm_context.wl.wl_shm = lValidAddress; + ilm_context.wl.has_argb8888 = false; + // call and verify data + ASSERT_EQ(ILM_FAILED, ilm_takeScreenshot(lScreenID, filename)); + ASSERT_EQ(wl_proxy_marshal_flags_fake.call_count, 0); + // revert to default data + ilm_context.wl.wl_shm = NULL; + ilm_context.wl.has_argb8888 = false; +} + +/** ================================================================================================ + * @test_id ilm_takeScreenshot_SendScreenshotRequestFailed + * @brief Send request take screenshot to server failed when ilm_takeScreenshot() is called + * @test_procedure Steps: + * -# make wl_shm global and argb8888 are supported + * -# Mocking the wl_proxy_get_version() to return success object + * -# Mocking the wl_proxy_marshal_flags() to return NULL object when ivi_wm_screen_screenshot() + * is called to send request to server + * -# Verification point: + * +# ilm_takeScreenshot() must return ILM_FAILED + * +# wl_proxy_marshal_flags should be called 5 times + */ +TEST_F(IlmControlTest, ilm_takeScreenshot_SendScreenshotRequestFailed) +{ + t_ilm_uint lScreenID{10}; + t_ilm_const_string filename{"name_test"}; + constexpr uint32_t lValidAddress{0xFFFFFFFF}; + // prepare data + ilm_context.wl.wl_shm = lValidAddress; + ilm_context.wl.has_argb8888 = true; + void *lScreenshotRetList[3] = {(void *)lValidAddress, (void *)lValidAddress, NULL}; + int lVersionRetList[1] = {1}; + // mock wayland APIs + SET_RETURN_SEQ(wl_proxy_get_version, lVersionRetList, 1); + SET_RETURN_SEQ(wl_proxy_marshal_flags, lScreenshotRetList, 3); + // call and verify data + ASSERT_EQ(ILM_FAILED, ilm_takeScreenshot(lScreenID, filename)); + ASSERT_EQ(wl_proxy_marshal_flags_fake.call_count, 5); + // revert to default data + ilm_context.wl.wl_shm = NULL; + ilm_context.wl.has_argb8888 = false; +} + +/** ================================================================================================ + * @test_id ilm_takeScreenshot_CreateBufferFailed + * @brief Create buffer in sharemem pool failed when ilm_takeScreenshot() is called + * @test_procedure Steps: + * -# make wl_shm global and argb8888 are supported + * -# Mocking the wl_proxy_get_version() to return success object + * -# Mocking the wl_proxy_marshal_flags() to return NULL object when wl_shm_pool_create_buffer() + * is called to create buffer in sharemem pool + * -# Call ilm_takeScreenshot() + * -# Verification point: + * +# ilm_takeScreenshot() must return ILM_FAILED + * +# wl_proxy_marshal_flags should be called 3 times + */ +TEST_F(IlmControlTest, ilm_takeScreenshot_CreateBufferFailed) +{ + t_ilm_uint lScreenID{10}; + t_ilm_const_string filename{"name_test"}; + constexpr uint32_t lValidAddress{0xFFFFFFFF}; + // prepare data + ilm_context.wl.wl_shm = lValidAddress; + ilm_context.wl.has_argb8888 = true; + void *lScreenshotRetList[3] = {(void *)lValidAddress, NULL}; + int lVersionRetList[1] = {1}; + // mock wayland APIs + SET_RETURN_SEQ(wl_proxy_get_version, lVersionRetList, 1); + SET_RETURN_SEQ(wl_proxy_marshal_flags, lScreenshotRetList, 2); + // call and verify data + ASSERT_EQ(ILM_FAILED, ilm_takeScreenshot(lScreenID, filename)); + ASSERT_EQ(wl_proxy_marshal_flags_fake.call_count, 3); + // revert to default data + ilm_context.wl.wl_shm = NULL; + ilm_context.wl.has_argb8888 = false; +} + +/** ================================================================================================ + * @test_id ilm_takeScreenshot_Successfully + * @brief ilm_takeScreenshot() is called with all valid data + * @test_procedure Steps: + * -# make wl_shm global and argb8888 are supported + * -# Mocking the wl_proxy_get_version() to return success object + * -# Mocking the wl_proxy_marshal_flags() to return success object + * -# Mocking the wl_display_dispatch_queue() to return failure object + * -# Verification point: + * +# ilm_takeScreenshot() must return ILM_FAILED - Attually this function is done + * with successfully status, but need to assert with ILM_FAILED because in unittest + * context, client side does not get event from server, so need to make wl_display_dispatch_queue() + * return failure object to finish ilm_takeScreenshot() function. + * +# wl_proxy_marshal_flags should be called 5 times + * +# wl_proxy_add_listener should be called 1 times + */ +TEST_F(IlmControlTest, ilm_takeScreenshot_Successfully) +{ + t_ilm_uint lScreenID{10}; + t_ilm_const_string filename{"name_test"}; + constexpr uint32_t lValidAddress{0xFFFFFFFF}; + // prepare data + ilm_context.wl.wl_shm = lValidAddress; + ilm_context.wl.has_argb8888 = true; + void *lScreenshotRetList[1] = {(void *)lValidAddress}; + int lVersionRetList[1] = {1}; + // mock wayland APIs + SET_RETURN_SEQ(wl_proxy_get_version, lVersionRetList, 1); + SET_RETURN_SEQ(wl_proxy_marshal_flags, lScreenshotRetList, 1); + SET_RETURN_SEQ(wl_display_dispatch_queue, mp_failureResult, 1); + // call and verify data + ASSERT_EQ(ILM_FAILED, ilm_takeScreenshot(lScreenID, filename)); + ASSERT_EQ(wl_proxy_marshal_flags_fake.call_count, 5); + ASSERT_EQ(wl_proxy_add_listener_fake.call_count, 1); + // revert to default data + ilm_context.wl.wl_shm = NULL; + ilm_context.wl.has_argb8888 = false; +} + +/** ================================================================================================ + * @test_id ilm_takeAsyncScreenshot_Successfully + * @brief ilm_takeAsyncScreenshot() is called with all valid data + * @test_procedure Steps: + * -# make wl_shm global and argb8888 are supported + * -# Mocking the wl_proxy_get_version() to return success object + * -# Mocking the wl_proxy_marshal_flags() to return success object + * -# Call ilm_takeAsyncScreenshot() with valid screenID, callback_done, callback_error, user_data + * -# Verification point: + * +# ilm_takeAsyncScreenshot() must return ILM_SUCCESS + * +# wl_proxy_marshal_flags should be called 4 times + * +# wl_proxy_add_listener should be called 1 times + * +# wl_display_flush should be called 1 times + * +# All callback of screenshot_context should be setted + */ +TEST_F(IlmControlTest, ilm_takeAsyncScreenshot_Successfully) +{ + t_ilm_uint lScreenID{10}; + constexpr uint32_t lValidAddress{0xFFFFFFFF}; + // prepare data + ilm_context.wl.wl_shm = lValidAddress; + ilm_context.wl.has_argb8888 = true; + void *lScreenshotRetList[1] = {(void *)lValidAddress}; + int lVersionRetList[1] = {1}; + // mock wayland APIs + SET_RETURN_SEQ(wl_proxy_marshal_flags, lScreenshotRetList, 1); + SET_RETURN_SEQ(wl_proxy_get_version, lVersionRetList, 1); + // call and verify data + ASSERT_EQ(ILM_SUCCESS, ilm_takeAsyncScreenshot(lScreenID, lValidAddress, lValidAddress, lValidAddress)); + ASSERT_EQ(wl_proxy_marshal_flags_fake.call_count, 4); + ASSERT_EQ(wl_proxy_add_listener_fake.call_count, 1); + ASSERT_EQ(wl_display_flush_fake.call_count, 1); + struct screenshot_context *ctx_scrshot = wl_proxy_add_listener_fake.arg2_val; + ASSERT_EQ(ctx_scrshot->callback_done, lValidAddress); + ASSERT_EQ(ctx_scrshot->callback_error, lValidAddress); + ASSERT_EQ(ctx_scrshot->callback_priv, lValidAddress); + // release resource and revert to default data + destroy_shm_buffer(ctx_scrshot->ivi_buffer); + free(ctx_scrshot); + ilm_context.wl.wl_shm = NULL; + ilm_context.wl.has_argb8888 = false; +} + +/** ================================================================================================ + * @test_id ilm_takeSurfaceScreenshot_FileNameNull + * @brief ilm_takeSurfaceScreenshot() is called with file name is NULL + * @test_procedure Steps: + * -# Calling the ilm_takeSurfaceScreenshot() with file name is NULL + * -# Verification point: + * +# ilm_takeSurfaceScreenshot() must return ILM_SUCCESS + */ +TEST_F(IlmControlTest, ilm_takeSurfaceScreenshot_FileNameNull) +{ + t_ilm_uint lSurfaceID{1}; + t_ilm_const_string filename{NULL}; + ASSERT_EQ(ILM_SUCCESS, ilm_takeSurfaceScreenshot(filename, lSurfaceID)); +} + +/** ================================================================================================ + * @test_id ilm_takeSurfaceScreenshot_InvalidSurfaceID + * @brief ilm_takeSurfaceScreenshot() is called with invalid surfaceID + * @test_procedure Steps: + * -# Mocking the wl_proxy_marshal_flags() return an success object + * -# Call ilm_takeSurfaceScreenshot() + * -# Verification point: + * +# ilm_takeSurfaceScreenshot() must return ILM_FAILED + * +# wl_proxy_marshal_flags should be called 1 time + * +# wl_display_roundtrip_queue should be called 1 time + */ +TEST_F(IlmControlTest, ilm_takeSurfaceScreenshot_InvalidSurfaceID) +{ + t_ilm_uint lInvalidSurfaceID{10}; + t_ilm_const_string filename{"name_test"}; + constexpr uint32_t lValidAddress{0xFFFFFFFF}; + // prepare data + struct wl_proxy *lScreenshotRetList[1] = {(struct wl_proxy *)lValidAddress}; + // mock wayland APIs + SET_RETURN_SEQ(wl_proxy_marshal_flags, lScreenshotRetList, 1); + // call and verify data + ASSERT_EQ(ILM_FAILED, ilm_takeSurfaceScreenshot(filename, lInvalidSurfaceID)); + ASSERT_EQ(wl_proxy_marshal_flags_fake.call_count, 1); + ASSERT_EQ(wl_display_roundtrip_queue_fake.call_count, 1); +} + +/** ================================================================================================ + * @test_id ilm_takeSurfaceScreenshot_controllderIsNull + * @brief ilm_takeSurfaceScreenshot() is called when controller is point to NULL + * @test_procedure Steps: + * -# MaKe controller point to NULL + * -# Call ilm_takeSurfaceScreenshot() + * -# Verification point: + * +# ilm_takeSurfaceScreenshot() must return ILM_FAILED + * +# wl_proxy_marshal_flags should not be called + * +# wl_display_roundtrip_queue should not be called + */ + +TEST_F(IlmControlTest, ilm_takeSurfaceScreenshot_controllderIsNull) +{ + t_ilm_uint lSurfaceID{1}; + t_ilm_const_string filename{"name_test"}; + // prepare data + ilm_context.wl.controller = NULL; + // call and verify data + ASSERT_EQ(ILM_FAILED, ilm_takeSurfaceScreenshot(filename, lSurfaceID)); + ASSERT_EQ(wl_proxy_marshal_flags_fake.call_count, 0); + ASSERT_EQ(wl_display_roundtrip_queue_fake.call_count, 0); +} + +/** ================================================================================================ + * @test_id ilm_takeSurfaceScreenshot_wl_display_roundtrip_queue_Failed + * @brief Client wait server process all pending request when ilm_takeSurfaceScreenshot() is called + * @test_procedure Steps: + * -# Mocking the wl_display_roundtrip_queue() return failure object + * -# Call ilm_takeSurfaceScreenshot() + * -# Verification point: + * +# ilm_takeScreenshot() must return ILM_FAILED + * +# wl_proxy_marshal_flags() should be called 1 time + * +# wl_display_roundtrip_queue() should be called 1 time + */ + +TEST_F(IlmControlTest, ilm_takeSurfaceScreenshot_wl_display_roundtrip_queue_Failed) +{ + t_ilm_uint lSurfaceID{1}; + t_ilm_const_string filename{"name_test"}; + // mock wayland APIs + SET_RETURN_SEQ(wl_display_roundtrip_queue, mp_failureResult, 1); + // call and verify data + ASSERT_EQ(ILM_FAILED, ilm_takeSurfaceScreenshot(filename, lSurfaceID)); + ASSERT_EQ(wl_proxy_marshal_flags_fake.call_count, 1); + ASSERT_EQ(wl_display_roundtrip_queue_fake.call_count, 1); +} + +/** ================================================================================================ + * @test_id ilm_takeSurfaceScreenshot_SupportArgb8888AndUnsupportWlshmGlobal + * @brief ilm_takeSurfaceScreenshot() is called when argb8888 is supported and wl_shm global is unsupported + * @test_procedure Steps: + * -# make argb8888 is supported + * -# point wl_shm to NULL + * -# call ilm_takeSurfaceScreenshot() with valid screenID and file name + * -# Verification point: + * +# ilm_takeSurfaceScreenshot() must return ILM_FAILED + * +# wl_proxy_marshal_flags() should be called 1 time + * +# wl_display_roundtrip_queue() should be called 1 time + */ +TEST_F(IlmControlTest, ilm_takeSurfaceScreenshot_SupportArgb8888AndUnsupportWlshmGlobal) +{ + t_ilm_uint lSurfaceID{1}; + t_ilm_const_string filename{"name_test"}; + constexpr uint32_t lValidAddress{0xFFFFFFFF}; + // prepare data + ilm_context.wl.wl_shm = NULL; + ilm_context.wl.has_argb8888 = true; + void *lScreenshotRetList[1] = {(void *)lValidAddress}; + // mock wayland APIs + SET_RETURN_SEQ(wl_proxy_marshal_flags, lScreenshotRetList, 1); + SET_RETURN_SEQ(wl_display_roundtrip_queue, mp_successResult, 1); + // call and verify data + ASSERT_EQ(ILM_FAILED, ilm_takeSurfaceScreenshot(filename, lSurfaceID)); + ASSERT_EQ(wl_proxy_marshal_flags_fake.call_count, 1); + ASSERT_EQ(wl_display_roundtrip_queue_fake.call_count, 1); +} + +/** ================================================================================================ + * @test_id ilm_takeSurfaceScreenshot_SupportWlshmGlobalAndUnsupportArgb8888 + * @brief ilm_takeSurfaceScreenshot() is called when wl_shm global is supported and argb8888 is unsupported + * @test_procedure Steps: + * -# make wl_shm global is supported + * -# call ilm_takeSurfaceScreenshot() with valid screenID and file name + * -# Verification point: + * +# ilm_takeSurfaceScreenshot() must return ILM_FAILED + * +# wl_proxy_marshal_flags() should be called 1 time + * +# wl_display_roundtrip_queue() should be called 1 time + */ +TEST_F(IlmControlTest, ilm_takeSurfaceScreenshot_SupportWlshmGlobalAndUnsupportArgb8888) +{ + t_ilm_uint lSurfaceID{1}; + t_ilm_const_string filename{"name_test"}; + constexpr uint32_t lValidAddress{0xFFFFFFFF}; + // prepare data + ilm_context.wl.wl_shm = lValidAddress; + ilm_context.wl.has_argb8888 = false; + void *lScreenshotRetList[1] = {(void *)lValidAddress}; + // mock wayland APIs + SET_RETURN_SEQ(wl_proxy_marshal_flags, lScreenshotRetList, 1); + SET_RETURN_SEQ(wl_display_roundtrip_queue, mp_successResult, 1); + // call and verify data + ASSERT_EQ(ILM_FAILED, ilm_takeSurfaceScreenshot(filename, lSurfaceID)); + ASSERT_EQ(wl_proxy_marshal_flags_fake.call_count, 1); + ASSERT_EQ(wl_display_roundtrip_queue_fake.call_count, 1); +} + +/** ================================================================================================ + * @test_id ilm_takeSurfaceScreenshot_CreateBufferFailed + * @brief Create buffer in sharemem pool failed when ilm_takeSurfaceScreenshot() is called + * @test_procedure Steps: + * -# make wl_shm global and argb8888 are supported + * -# Mocking the wl_proxy_get_version() to return success object + * -# Mocking the wl_display_dispatch_queue() to return success object + * -# Mocking the wl_proxy_marshal_flags() to return NULL object when wl_shm_pool_create_buffer() + * is called to create buffer in sharemem pool + * -# Call ilm_takeSurfaceScreenshot() + * -# Verification point: + * +# ilm_takeSurfaceScreenshot() must return ILM_FAILED + * +# wl_proxy_marshal_flags() should be called 4 times + * +# wl_display_roundtrip_queue() should be called 1 time + */ +TEST_F(IlmControlTest, ilm_takeSurfaceScreenshot_CreateBufferFailed) +{ + t_ilm_uint lSurfaceID{1}; + t_ilm_const_string filename{"name_test"}; + constexpr uint32_t lValidAddress{0xFFFFFFFF}; + // prepare data + ilm_context.wl.wl_shm = lValidAddress; + ilm_context.wl.has_argb8888 = true; + void *lScreenshotRetList[3] = {(void *)lValidAddress, (void *)lValidAddress, NULL}; + int lVersionRetList[1] = {1}; + // mock wayland APIs + SET_RETURN_SEQ(wl_proxy_marshal_flags, lScreenshotRetList, 3); + SET_RETURN_SEQ(wl_display_dispatch_queue, mp_successResult, 1); + SET_RETURN_SEQ(wl_proxy_get_version, lVersionRetList, 1); + // call and verify data + ASSERT_EQ(ILM_FAILED, ilm_takeSurfaceScreenshot(filename, lSurfaceID)); + ASSERT_EQ(wl_proxy_marshal_flags_fake.call_count, 4); + ASSERT_EQ(wl_display_roundtrip_queue_fake.call_count, 1); +} + +/** ================================================================================================ + * @test_id ilm_takeSurfaceScreenshot_SendSurfaceScreenShotFailed + * @brief Send request take surface screenshot to server failed when ilm_takeSurfaceScreenshot() is called + * @test_procedure Steps: + * -# make wl_shm global and argb8888 are supported + * -# Mocking the wl_proxy_get_version() to return success object + * -# Mocking the wl_display_dispatch_queue() to return success object + * -# Mocking the wl_proxy_marshal_flags() to return NULL object when ivi_wm_surface_screenshot() + * is called to send request to server + * -# Verification point: + * +# ilm_takeSurfaceScreenshot() must return ILM_FAILED + * +# wl_proxy_marshal_flags() should be called 6 times + * +# wl_display_roundtrip_queue() should be called 1 time + * +# wl_proxy_add_listener() should not be called + */ +TEST_F(IlmControlTest, ilm_takeSurfaceScreenshot_SendSurfaceScreenShotFailed) +{ + t_ilm_uint lSurfaceID{1}; + t_ilm_const_string filename{"name_test"}; + constexpr uint32_t lValidAddress{0xFFFFFFFF}; + // prepare data + ilm_context.wl.wl_shm = lValidAddress; + ilm_context.wl.has_argb8888 = true; + void *lScreenshotRetList[4] = {(void *)lValidAddress, (void *)lValidAddress, (void *)lValidAddress, NULL}; + int lVersionRetList[1] = {1}; + // mock wayland APIs + SET_RETURN_SEQ(wl_proxy_marshal_flags, lScreenshotRetList, 4); + SET_RETURN_SEQ(wl_display_dispatch_queue, mp_successResult, 1); + SET_RETURN_SEQ(wl_proxy_get_version, lVersionRetList, 1); + // call and verify data + ASSERT_EQ(ILM_FAILED, ilm_takeSurfaceScreenshot(filename, lSurfaceID)); + ASSERT_EQ(wl_proxy_marshal_flags_fake.call_count, 6); + ASSERT_EQ(wl_display_roundtrip_queue_fake.call_count, 1); + ASSERT_EQ(wl_proxy_add_listener_fake.call_count, 0); +} + +/** ================================================================================================ + * @test_id ilm_takeSurfaceScreenshot_Successfully + * @brief ilm_takeSurfaceScreenshot() is called with all valid data + * @test_procedure Steps: + * -# make wl_shm global and argb8888 are supported + * -# Mocking the wl_proxy_get_version() to return success object + * -# Mocking the wl_proxy_marshal_flags() to return success object + * -# Mocking the wl_display_dispatch_queue() to return failure object + * -# Verification point: + * +# ilm_takeSurfaceScreenshot() must return ILM_FAILED - Attually this function is done + * with successfully status, but need to assert with ILM_FAILED because in unittest + * context, client side does not get event from server, so need to make wl_display_dispatch_queue() + * return failure object to finish ilm_takeSurfaceScreenshot() function. + * +# wl_proxy_marshal_flags should be called 6 times + * +# wl_display_roundtrip_queue should be called 1 time + * +# wl_proxy_add_listener should be called 1 time + * +# wl_display_dispatch_queue should be called 1 time + * +# wl_display_flush should not be called + */ +TEST_F(IlmControlTest, ilm_takeSurfaceScreenshot_Successfully) +{ + t_ilm_uint lSurfaceID{1}; + t_ilm_const_string filename{"name_test"}; + constexpr uint32_t lValidAddress{0xFFFFFFFF}; + // prepare data + ilm_context.wl.wl_shm = lValidAddress; + ilm_context.wl.has_argb8888 = true; + void *lScreenshotRetList[4] = {(void *)lValidAddress, (void *)lValidAddress, (void *)lValidAddress, NULL}; + int lVersionRetList[1] = {1}; + // mock wayland APIs + SET_RETURN_SEQ(wl_proxy_marshal_flags, lScreenshotRetList, 3); + SET_RETURN_SEQ(wl_display_dispatch_queue, mp_failureResult, 1); + SET_RETURN_SEQ(wl_proxy_get_version, lVersionRetList, 1); + // call and verify data + ASSERT_EQ(ILM_FAILED, ilm_takeSurfaceScreenshot(filename, lSurfaceID)); + ASSERT_EQ(wl_proxy_marshal_flags_fake.call_count, 6); + ASSERT_EQ(wl_display_roundtrip_queue_fake.call_count, 1); + ASSERT_EQ(wl_proxy_add_listener_fake.call_count, 1); + ASSERT_EQ(wl_display_flush_fake.call_count, 0); + ASSERT_EQ(wl_display_dispatch_queue_fake.call_count, 1); +} + +/** ================================================================================================ + * @test_id ilm_takeAsyncSurfaceScreenshot_Successfully + * @brief ilm_takeAsyncScreenshot() is called with all valid data + * @test_procedure Steps: + * -# make wl_shm global and argb8888 are supported + * -# Mocking the wl_proxy_get_version() to return success object + * -# Mocking the wl_proxy_marshal_flags() to return success object + * -# Call ilm_takeAsyncScreenshot() with valid screenID, callback_done, callback_error, user_data + * -# Verification point: + * +# ilm_takeAsyncScreenshot() must return ILM_SUCCESS + * +# wl_proxy_marshal_flags should be called 4 times + * +# wl_proxy_add_listener should be called 1 times + * +# wl_display_flush should be called 1 times + * +# All callback of screenshot_context should be setted + */ +TEST_F(IlmControlTest, ilm_takeAsyncSurfaceScreenshot_Successfully) +{ + t_ilm_uint lSurfaceID{1}; + constexpr uint32_t lValidAddress{0xFFFFFFFF}; + // prepare data + ilm_context.wl.wl_shm = lValidAddress; + ilm_context.wl.has_argb8888 = true; + void *lScreenshotRetList[4] = {(void *)lValidAddress, (void *)lValidAddress, (void *)lValidAddress, NULL}; + int lVersionRetList[1] = {1}; + // mock wayland APIs + SET_RETURN_SEQ(wl_proxy_marshal_flags, lScreenshotRetList, 3); + SET_RETURN_SEQ(wl_display_dispatch_queue, mp_failureResult, 1); + SET_RETURN_SEQ(wl_proxy_get_version, lVersionRetList, 1); + // call and verify data + ASSERT_EQ(ILM_SUCCESS, ilm_takeAsyncSurfaceScreenshot(lSurfaceID, lValidAddress, lValidAddress, lValidAddress)); + ASSERT_EQ(wl_proxy_marshal_flags_fake.call_count, 5); + ASSERT_EQ(wl_display_roundtrip_queue_fake.call_count, 1); + ASSERT_EQ(wl_display_flush_fake.call_count, 1); + ASSERT_EQ(wl_proxy_add_listener_fake.call_count, 1); + ASSERT_EQ(wl_display_dispatch_queue_fake.call_count, 0); + struct screenshot_context *ctx_scrshot = wl_proxy_add_listener_fake.arg2_val; + ASSERT_EQ(ctx_scrshot->callback_done, lValidAddress); + ASSERT_EQ(ctx_scrshot->callback_error, lValidAddress); + ASSERT_EQ(ctx_scrshot->callback_priv, lValidAddress); + // release resource and revert to default data + destroy_shm_buffer(ctx_scrshot->ivi_buffer); + free(ctx_scrshot); + ilm_context.wl.wl_shm = NULL; + ilm_context.wl.has_argb8888 = false; +} + +/** ================================================================================================ + * @test_id screenshot_done_UnknownFileFormat + * @brief screenshot_done() process data when file format is not png or bmp + * @test_procedure Steps: + * -# Setup data to make ilm_takeAsyncSurfaceScreenshot() process successfully + * -# Setup file format is .txt format + * -# call screenshot_done() to process + * -# Verification point: + * +# The callback ScreenshotDoneCallbackFunc() should be called + */ +TEST_F(IlmControlTest, screenshot_done_UnknownFileFormat) +{ + t_ilm_uint lSurfaceID{1}; + constexpr uint32_t lValidAddress{0xFFFFFFFF}; + // prepare data + RESET_FAKE(save_as_png); + RESET_FAKE(save_as_bitmap); + screenshot_data_t screenshotData; + screenshotData.fd.store(-1); + ilm_context.wl.wl_shm = lValidAddress; + ilm_context.wl.has_argb8888 = true; + void *lScreenshotRetList[4] = {(void *)lValidAddress, (void *)lValidAddress, (void *)lValidAddress, NULL}; + int lVersionRetList[1] = {1}; + SET_RETURN_SEQ(wl_proxy_marshal_flags, lScreenshotRetList, 3); + SET_RETURN_SEQ(wl_display_dispatch_queue, mp_failureResult, 1); + SET_RETURN_SEQ(wl_proxy_get_version, lVersionRetList, 1); + // setup callback for ilm_context + ASSERT_EQ(ILM_SUCCESS, ilm_takeAsyncSurfaceScreenshot(lSurfaceID, ScreenshotDoneCallbackFunc, ScreenshotErrorCallbackFunc, &screenshotData)); + ASSERT_EQ(wl_proxy_marshal_flags_fake.call_count, 5); + ASSERT_EQ(wl_display_roundtrip_queue_fake.call_count, 1); + ASSERT_EQ(wl_display_flush_fake.call_count, 1); + ASSERT_EQ(wl_proxy_add_listener_fake.call_count, 1); + ASSERT_EQ(wl_display_dispatch_queue_fake.call_count, 0); + struct screenshot_context *ctx_scrshot = wl_proxy_add_listener_fake.arg2_val; + ASSERT_EQ(ctx_scrshot->callback_done, ScreenshotDoneCallbackFunc); + ASSERT_EQ(ctx_scrshot->callback_error, ScreenshotErrorCallbackFunc); + ASSERT_EQ(ctx_scrshot->callback_priv, &screenshotData); + // set file format + ctx_scrshot->filename = "test.txt"; + // call API and verify data + screenshot_done(ctx_scrshot, lValidAddress, 1); + ASSERT_EQ(save_as_png_fake.call_count, 0); + ASSERT_EQ(save_as_bitmap_fake.call_count, 1); + ilm_context.wl.wl_shm = NULL; + ilm_context.wl.has_argb8888 = false; + destroy_shm_buffer(ctx_scrshot->ivi_buffer); + // make sure call back is called + ASSERT_NE(screenshotData.fd.load(), -1); + free(ctx_scrshot); +} + +/** ================================================================================================ + * @test_id screenshot_done_pngFileFormatSaveAsPngPassed + * @brief screenshot_done() process data when file format is png and can save as png file successfully + * @test_procedure Steps: + * -# Setup data to make ilm_takeAsyncSurfaceScreenshot() process successfully + * -# Setup file format is .png format + * -# Mocking save_as_png to return success object + * -# call screenshot_done() to process + * -# Verification point: + * +# The callback ScreenshotDoneCallbackFunc() should be called + * +# The ctx_scrshot->result should be passed + */ +TEST_F(IlmControlTest, screenshot_done_pngFileFormatSaveAsPngPassed) +{ + t_ilm_uint lSurfaceID{1}; + constexpr uint32_t lValidAddress{0xFFFFFFFF}; + // prepare data + RESET_FAKE(save_as_png); + RESET_FAKE(save_as_bitmap); + screenshot_data_t screenshotData; + screenshotData.fd.store(-1); + ilm_context.wl.wl_shm = lValidAddress; + ilm_context.wl.has_argb8888 = true; + void *lScreenshotRetList[4] = {(void *)lValidAddress, (void *)lValidAddress, (void *)lValidAddress, NULL}; + int lVersionRetList[1] = {1}; + SET_RETURN_SEQ(wl_proxy_marshal_flags, lScreenshotRetList, 3); + SET_RETURN_SEQ(wl_display_dispatch_queue, mp_failureResult, 1); + SET_RETURN_SEQ(wl_proxy_get_version, lVersionRetList, 1); + // setup callback for ilm_context + ASSERT_EQ(ILM_SUCCESS, ilm_takeAsyncSurfaceScreenshot(lSurfaceID, ScreenshotDoneCallbackFunc, ScreenshotErrorCallbackFunc, &screenshotData)); + ASSERT_EQ(wl_proxy_marshal_flags_fake.call_count, 5); + ASSERT_EQ(wl_display_roundtrip_queue_fake.call_count, 1); + ASSERT_EQ(wl_display_flush_fake.call_count, 1); + ASSERT_EQ(wl_proxy_add_listener_fake.call_count, 1); + ASSERT_EQ(wl_display_dispatch_queue_fake.call_count, 0); + struct screenshot_context *ctx_scrshot = wl_proxy_add_listener_fake.arg2_val; + ASSERT_EQ(ctx_scrshot->callback_done, ScreenshotDoneCallbackFunc); + ASSERT_EQ(ctx_scrshot->callback_error, ScreenshotErrorCallbackFunc); + ASSERT_EQ(ctx_scrshot->callback_priv, &screenshotData); + // set file format + ctx_scrshot->filename = "test.png"; + // mock save_as_png + int save_as_png_passed[1] = {0}; + SET_RETURN_SEQ(save_as_png, save_as_png_passed, 1); + // call API and verify data + screenshot_done(ctx_scrshot, lValidAddress, 1); + ASSERT_EQ(save_as_png_fake.call_count, 1); + ASSERT_EQ(save_as_bitmap_fake.call_count, 0); + ASSERT_EQ(ctx_scrshot->result, ILM_SUCCESS); + ilm_context.wl.wl_shm = NULL; + ilm_context.wl.has_argb8888 = false; + destroy_shm_buffer(ctx_scrshot->ivi_buffer); + // make sure call back is called + ASSERT_NE(screenshotData.fd.load(), -1); + free(ctx_scrshot); +} + +/** ================================================================================================ + * @test_id screenshot_done_pngFileFormatSaveAsPngFailed + * @brief screenshot_done() process data when file format is png and cannot save as png file + * @test_procedure Steps: + * -# Setup data to make ilm_takeAsyncSurfaceScreenshot() process successfully + * -# Setup file format is .png format + * -# Mocking save_as_png to return failure object + * -# call screenshot_done() to process + * -# Verification point: + * +# The callback ScreenshotDoneCallbackFunc() should be called + * +# The ctx_scrshot->result should be failed + */ +TEST_F(IlmControlTest, screenshot_done_pngFileFormatSaveAsPngFailed) +{ + t_ilm_uint lSurfaceID{1}; + constexpr uint32_t lValidAddress{0xFFFFFFFF}; + // prepare data + RESET_FAKE(save_as_png); + RESET_FAKE(save_as_bitmap); + screenshot_data_t screenshotData; + screenshotData.fd.store(-1); + ilm_context.wl.wl_shm = lValidAddress; + ilm_context.wl.has_argb8888 = true; + void *lScreenshotRetList[4] = {(void *)lValidAddress, (void *)lValidAddress, (void *)lValidAddress, NULL}; + int lVersionRetList[1] = {1}; + SET_RETURN_SEQ(wl_proxy_marshal_flags, lScreenshotRetList, 3); + SET_RETURN_SEQ(wl_display_dispatch_queue, mp_failureResult, 1); + SET_RETURN_SEQ(wl_proxy_get_version, lVersionRetList, 1); + // setup callback for ilm_context + ASSERT_EQ(ILM_SUCCESS, ilm_takeAsyncSurfaceScreenshot(lSurfaceID, ScreenshotDoneCallbackFunc, ScreenshotErrorCallbackFunc, &screenshotData)); + ASSERT_EQ(wl_proxy_marshal_flags_fake.call_count, 5); + ASSERT_EQ(wl_display_roundtrip_queue_fake.call_count, 1); + ASSERT_EQ(wl_display_flush_fake.call_count, 1); + ASSERT_EQ(wl_proxy_add_listener_fake.call_count, 1); + ASSERT_EQ(wl_display_dispatch_queue_fake.call_count, 0); + struct screenshot_context *ctx_scrshot = wl_proxy_add_listener_fake.arg2_val; + ASSERT_EQ(ctx_scrshot->callback_done, ScreenshotDoneCallbackFunc); + ASSERT_EQ(ctx_scrshot->callback_error, ScreenshotErrorCallbackFunc); + ASSERT_EQ(ctx_scrshot->callback_priv, &screenshotData); + // set file format + ctx_scrshot->filename = "test.png"; + // mock save_as_png + int save_as_png_failed[1] = {1}; + SET_RETURN_SEQ(save_as_png, save_as_png_failed, 1); + // call API and verify data + screenshot_done(ctx_scrshot, lValidAddress, 1); + ASSERT_EQ(save_as_png_fake.call_count, 1); + ASSERT_EQ(save_as_bitmap_fake.call_count, 0); + ASSERT_EQ(ctx_scrshot->result, ILM_FAILED); + ilm_context.wl.wl_shm = NULL; + ilm_context.wl.has_argb8888 = false; + destroy_shm_buffer(ctx_scrshot->ivi_buffer); + // make sure call back is called + ASSERT_NE(screenshotData.fd.load(), -1); + free(ctx_scrshot); +} + +/** ================================================================================================ + * @test_id screenshot_done_bitmapFileFormatSaveAsBitmapPassed + * @brief screenshot_done() process data when file format is bmp and can save as bmp file successfully + * @test_procedure Steps: + * -# Setup data to make ilm_takeAsyncSurfaceScreenshot() process successfully + * -# Setup file format is .bmp format + * -# Mocking save_as_bitmap to return success object + * -# call screenshot_done() to process + * -# Verification point: + * +# The callback ScreenshotDoneCallbackFunc() should be called + * +# The ctx_scrshot->result should be passed + */ +TEST_F(IlmControlTest, screenshot_done_bitmapFileFormatSaveAsBitmapPassed) +{ + t_ilm_uint lSurfaceID{1}; + constexpr uint32_t lValidAddress{0xFFFFFFFF}; + // prepare data + RESET_FAKE(save_as_png); + RESET_FAKE(save_as_bitmap); + screenshot_data_t screenshotData; + screenshotData.fd.store(-1); + ilm_context.wl.wl_shm = lValidAddress; + ilm_context.wl.has_argb8888 = true; + void *lScreenshotRetList[4] = {(void *)lValidAddress, (void *)lValidAddress, (void *)lValidAddress, NULL}; + int lVersionRetList[1] = {1}; + SET_RETURN_SEQ(wl_proxy_marshal_flags, lScreenshotRetList, 3); + SET_RETURN_SEQ(wl_display_dispatch_queue, mp_failureResult, 1); + SET_RETURN_SEQ(wl_proxy_get_version, lVersionRetList, 1); + // setup callback for ilm_context + ASSERT_EQ(ILM_SUCCESS, ilm_takeAsyncSurfaceScreenshot(lSurfaceID, ScreenshotDoneCallbackFunc, ScreenshotErrorCallbackFunc, &screenshotData)); + ASSERT_EQ(wl_proxy_marshal_flags_fake.call_count, 5); + ASSERT_EQ(wl_display_roundtrip_queue_fake.call_count, 1); + ASSERT_EQ(wl_display_flush_fake.call_count, 1); + ASSERT_EQ(wl_proxy_add_listener_fake.call_count, 1); + ASSERT_EQ(wl_display_dispatch_queue_fake.call_count, 0); + struct screenshot_context *ctx_scrshot = wl_proxy_add_listener_fake.arg2_val; + ASSERT_EQ(ctx_scrshot->callback_done, ScreenshotDoneCallbackFunc); + ASSERT_EQ(ctx_scrshot->callback_error, ScreenshotErrorCallbackFunc); + ASSERT_EQ(ctx_scrshot->callback_priv, &screenshotData); + // set file format + ctx_scrshot->filename = "test.bmp"; + // mock save_as_bitmap + int save_as_bitmap_passed[1] = {0}; + SET_RETURN_SEQ(save_as_bitmap, save_as_bitmap_passed, 1); + // call API and verify data + screenshot_done(ctx_scrshot, lValidAddress, 1); + ASSERT_EQ(save_as_png_fake.call_count, 0); + ASSERT_EQ(save_as_bitmap_fake.call_count, 1); + ASSERT_EQ(ctx_scrshot->result, ILM_SUCCESS); + ilm_context.wl.wl_shm = NULL; + ilm_context.wl.has_argb8888 = false; + destroy_shm_buffer(ctx_scrshot->ivi_buffer); + // make sure call back is called + ASSERT_NE(screenshotData.fd.load(), -1); + free(ctx_scrshot); +} + +/** ================================================================================================ + * @test_id screenshot_done_bitmapFileFormatSaveAsBitmapFailed + * @brief screenshot_done() process data when file format is bmp and can not save as bmp file + * @test_procedure Steps: + * -# Setup data to make ilm_takeAsyncSurfaceScreenshot() process successfully + * -# Setup file format is .bmp format + * -# Mocking save_as_bitmap to return failure object + * -# call screenshot_done() to process + * -# Verification point: + * +# The callback ScreenshotDoneCallbackFunc() should be called + * +# The ctx_scrshot->result should be failed + */ +TEST_F(IlmControlTest, screenshot_done_bitmapFileFormatSaveAsBitmapFailed) +{ + t_ilm_uint lSurfaceID{1}; + constexpr uint32_t lValidAddress{0xFFFFFFFF}; + // prepare data + RESET_FAKE(save_as_png); + RESET_FAKE(save_as_bitmap); + screenshot_data_t screenshotData; + screenshotData.fd.store(-1); + ilm_context.wl.wl_shm = lValidAddress; + ilm_context.wl.has_argb8888 = true; + void *lScreenshotRetList[4] = {(void *)lValidAddress, (void *)lValidAddress, (void *)lValidAddress, NULL}; + int lVersionRetList[1] = {1}; + SET_RETURN_SEQ(wl_proxy_marshal_flags, lScreenshotRetList, 3); + SET_RETURN_SEQ(wl_display_dispatch_queue, mp_failureResult, 1); + SET_RETURN_SEQ(wl_proxy_get_version, lVersionRetList, 1); + // setup callback for ilm_context + ASSERT_EQ(ILM_SUCCESS, ilm_takeAsyncSurfaceScreenshot(lSurfaceID, ScreenshotDoneCallbackFunc, ScreenshotErrorCallbackFunc, &screenshotData)); + ASSERT_EQ(wl_proxy_marshal_flags_fake.call_count, 5); + ASSERT_EQ(wl_display_roundtrip_queue_fake.call_count, 1); + ASSERT_EQ(wl_display_flush_fake.call_count, 1); + ASSERT_EQ(wl_proxy_add_listener_fake.call_count, 1); + ASSERT_EQ(wl_display_dispatch_queue_fake.call_count, 0); + struct screenshot_context *ctx_scrshot = wl_proxy_add_listener_fake.arg2_val; + ASSERT_EQ(ctx_scrshot->callback_done, ScreenshotDoneCallbackFunc); + ASSERT_EQ(ctx_scrshot->callback_error, ScreenshotErrorCallbackFunc); + ASSERT_EQ(ctx_scrshot->callback_priv, &screenshotData); + // set file format + ctx_scrshot->filename = "test.bmp"; + // mock save_as_bitmap + int save_as_bitmap_failed[1] = {1}; + SET_RETURN_SEQ(save_as_bitmap, save_as_bitmap_failed, 1); + // call API and verify data + screenshot_done(ctx_scrshot, lValidAddress, 1); + ASSERT_EQ(save_as_png_fake.call_count, 0); + ASSERT_EQ(save_as_bitmap_fake.call_count, 1); + ASSERT_EQ(ctx_scrshot->result, ILM_FAILED); + ilm_context.wl.wl_shm = NULL; + ilm_context.wl.has_argb8888 = false; + destroy_shm_buffer(ctx_scrshot->ivi_buffer); + // make sure call back is called + ASSERT_NE(screenshotData.fd.load(), -1); + free(ctx_scrshot); +} + +/** ================================================================================================ + * @test_id screenshot_error_CheckCall + * @brief screenshot_error() should raise our setted callback + * @test_procedure Steps: + * -# Setup data to make ilm_takeAsyncSurfaceScreenshot() process successfully + * -# call screenshot_error() to process + * -# Verification point: + * +# The callback ScreenshotErrorCallbackFunc() should be called + */ +TEST_F(IlmControlTest, screenshot_error_CheckCall) +{ + t_ilm_uint lSurfaceID{1}; + constexpr uint32_t lValidAddress{0xFFFFFFFF}; + // prepare data + RESET_FAKE(save_as_png); + RESET_FAKE(save_as_bitmap); + screenshot_data_t screenshotData; + screenshotData.error.store(-1); + ilm_context.wl.wl_shm = lValidAddress; + ilm_context.wl.has_argb8888 = true; + void *screenshot[4] = {(void *)lValidAddress, (void *)lValidAddress, (void *)lValidAddress, NULL}; + int version[1] = {1}; + SET_RETURN_SEQ(wl_proxy_marshal_flags, screenshot, 3); + SET_RETURN_SEQ(wl_display_dispatch_queue, mp_failureResult, 1); + SET_RETURN_SEQ(wl_proxy_get_version, version, 1); + // setup callback for ilm_context + ASSERT_EQ(ILM_SUCCESS, ilm_takeAsyncSurfaceScreenshot(lSurfaceID, ScreenshotDoneCallbackFunc, ScreenshotErrorCallbackFunc, &screenshotData)); + ASSERT_EQ(wl_proxy_marshal_flags_fake.call_count, 5); + ASSERT_EQ(wl_display_roundtrip_queue_fake.call_count, 1); + ASSERT_EQ(wl_display_flush_fake.call_count, 1); + ASSERT_EQ(wl_proxy_add_listener_fake.call_count, 1); + ASSERT_EQ(wl_display_dispatch_queue_fake.call_count, 0); + struct screenshot_context *ctx_scrshot = wl_proxy_add_listener_fake.arg2_val; + ASSERT_EQ(ctx_scrshot->callback_done, ScreenshotDoneCallbackFunc); + ASSERT_EQ(ctx_scrshot->callback_error, ScreenshotErrorCallbackFunc); + ASSERT_EQ(ctx_scrshot->callback_priv, &screenshotData); + ctx_scrshot->filename = "test.txt"; + screenshot_error(ctx_scrshot, lValidAddress, 1, "Error message"); + ASSERT_EQ(save_as_png_fake.call_count, 0); + ASSERT_EQ(save_as_bitmap_fake.call_count, 0); + ilm_context.wl.wl_shm = NULL; + ilm_context.wl.has_argb8888 = false; + destroy_shm_buffer(ctx_scrshot->ivi_buffer); + // make sure call back is called + ASSERT_NE(screenshotData.error.load(), -1); + free(ctx_scrshot); +} \ No newline at end of file diff --git a/unittest/client/src/ilm_input_uinttests.cpp b/unittest/client/src/ilm_input_uinttests.cpp new file mode 100644 index 00000000..69b1b3aa --- /dev/null +++ b/unittest/client/src/ilm_input_uinttests.cpp @@ -0,0 +1,628 @@ +/*************************************************************************** + * + * Copyright (C) 2023 Advanced Driver Information Technology Joint Venture GmbH + * + * + * 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. + * + ****************************************************************************/ + +#include +#include "wayland-util.h" +#include "ilm_input.h" +#include "ilm_control_platform.h" +#include "client_api_fake.h" + +extern "C"{ + struct ilm_control_context ilm_context; + FAKE_VALUE_FUNC(ilmErrorTypes, impl_sync_and_acquire_instance, struct ilm_control_context *); + FAKE_VOID_FUNC(release_instance); +} + +class IlmInputTest : public ::testing::Test +{ +public: + void SetUp() + { + CLIENT_API_FAKE_LIST(RESET_FAKE); + RESET_FAKE(impl_sync_and_acquire_instance); + RESET_FAKE(release_instance); + + init_ctx_list_content(); + } + + void TearDown() + { + deinit_ctx_list_content(); + } + + void init_ctx_list_content() + { + custom_wl_list_init(&ilm_context.wl.list_surface); + custom_wl_list_init(&ilm_context.wl.list_seat); + for(uint8_t i = 0; i < MAX_NUMBER; i++) + { + //prepare the surfaces + mp_ctxSurface[i].id_surface = mp_ilmSurfaceIds[i]; + mp_ctxSurface[i].ctx = &ilm_context.wl; + mp_ctxSurface[i].prop.focus = ILM_INPUT_DEVICE_KEYBOARD; + custom_wl_list_insert(&ilm_context.wl.list_surface, &mp_ctxSurface[i].link); + custom_wl_list_init(&mp_ctxSurface[i].list_accepted_seats); + //prepare the accepted seat + mp_acceptedSeat[i].seat_name = (char*)mp_seatName[i]; + custom_wl_list_insert(&mp_ctxSurface[i].list_accepted_seats, &mp_acceptedSeat[i].link); + //prepare the seats + mp_ctxSeat[i].capabilities = ILM_INPUT_DEVICE_ALL; + mp_ctxSeat[i].seat_name = (char*)mp_seatName[i]; + custom_wl_list_insert(&ilm_context.wl.list_seat, &mp_ctxSeat[i].link); + } + } + + void deinit_ctx_list_content() + { + struct surface_context *l, *n; + struct accepted_seat *seat, *seat_next; + wl_list_for_each_safe(l, n, &ilm_context.wl.list_surface, link) + { + wl_list_for_each_safe(seat, seat_next, &l->list_accepted_seats, link) + { + custom_wl_list_remove(&seat->link); + } + custom_wl_list_remove(&l->link); + } + } + + static constexpr uint8_t MAX_NUMBER = 5; + const char *SEAT_DEFAULT = "seat_not_found"; + + t_ilm_surface mp_ilmSurfaceIds[MAX_NUMBER] = {1, 2, 3, 4, 5}; + const char *mp_seatName[MAX_NUMBER] = {"seat_1", "seat_2", "seat_3", "seat_4", "seat_5"}; + struct surface_context mp_ctxSurface[MAX_NUMBER] = {}; + struct seat_context mp_ctxSeat[MAX_NUMBER] = {}; + struct accepted_seat mp_acceptedSeat[MAX_NUMBER] = {}; + + ilmErrorTypes mp_ilmErrorType[MAX_NUMBER] = {ILM_FAILED}; + + t_ilm_string *mp_getSeats = nullptr; + t_ilm_uint m_numberSeat = 0; +}; + +/** ================================================================================================ + * @test_id ilm_setInputAcceptanceOn_invalidAgrument + * @brief Test case of ilm_setInputAcceptanceOn() where invalid input seats + * @test_procedure Steps: + * -# Calling the ilm_setInputAcceptanceOn() with input seats is a null pointer + * -# Verification point: + * +# ilm_setInputAcceptanceOn() must return ILM_FAILED + * +# impl_sync_and_acquire_instance() not be called + */ +TEST_F(IlmInputTest, ilm_setInputAcceptanceOn_invalidAgrument) +{ + ASSERT_EQ(ILM_FAILED, ilm_setInputAcceptanceOn(mp_ilmSurfaceIds[0], 1, nullptr)); + + ASSERT_EQ(0, impl_sync_and_acquire_instance_fake.call_count); +} + +/** ================================================================================================ + * @test_id ilm_setInputAcceptanceOn_cannotSyncAcquireInstance + * @brief Test case of ilm_setInputAcceptanceOn() where impl_sync_and_acquire_instance() fails, return ILM_FAILED + * and input seats is SEAT_DEFAULT + * @test_procedure Steps: + * -# Mocking the impl_sync_and_acquire_instance() does return ILM_FAILED + * -# Calling the ilm_setInputAcceptanceOn() with input seats is SEAT_DEFAULT + * -# Verification point: + * +# ilm_setInputAcceptanceOn() must return ILM_FAILED + * +# impl_sync_and_acquire_instance() must be called once time + */ +TEST_F(IlmInputTest, ilm_setInputAcceptanceOn_cannotSyncAcquireInstance) +{ + mp_ilmErrorType[0] = ILM_FAILED; + SET_RETURN_SEQ(impl_sync_and_acquire_instance, mp_ilmErrorType, 1); + + ASSERT_EQ(ILM_FAILED, ilm_setInputAcceptanceOn(mp_ilmSurfaceIds[0], 1, (t_ilm_string*)&SEAT_DEFAULT)); + + ASSERT_EQ(1, impl_sync_and_acquire_instance_fake.call_count); +} + +/** ================================================================================================ + * @test_id ilm_setInputAcceptanceOn_cannotFindSurfaceId + * @brief Test case of ilm_setInputAcceptanceOn() where impl_sync_and_acquire_instance() success, return ILM_SUCCESS + * and invalid input surface id and input seats is SEAT_DEFAULT + * @test_procedure Steps: + * -# Mocking the impl_sync_and_acquire_instance() does return ILM_SUCCESS + * -# Calling the ilm_setInputAcceptanceOn() with input seats is SEAT_DEFAULT + * -# Verification point: + * +# ilm_setInputAcceptanceOn() must return ILM_FAILED + * +# release_instance() must be called once time + */ +TEST_F(IlmInputTest, ilm_setInputAcceptanceOn_cannotFindSurfaceId) +{ + mp_ilmErrorType[0] = ILM_SUCCESS; + SET_RETURN_SEQ(impl_sync_and_acquire_instance, mp_ilmErrorType, 1); + + ASSERT_EQ(ILM_FAILED, ilm_setInputAcceptanceOn(MAX_NUMBER + 1, 1, (t_ilm_string*)&SEAT_DEFAULT)); + + ASSERT_EQ(1, release_instance_fake.call_count); +} + +/** ================================================================================================ + * @test_id ilm_setInputAcceptanceOn_cannotFindSeat + * @brief Test case of ilm_setInputAcceptanceOn() where impl_sync_and_acquire_instance() success, return ILM_SUCCESS + * and valid input surface id and input seats is SEAT_DEFAULT + * @test_procedure Steps: + * -# Mocking the impl_sync_and_acquire_instance() does return ILM_SUCCESS + * -# Calling the ilm_setInputAcceptanceOn() with input seats is SEAT_DEFAULT + * -# Verification point: + * +# ilm_setInputAcceptanceOn() must return ILM_FAILED + * +# release_instance() must be called once time + */ +TEST_F(IlmInputTest, ilm_setInputAcceptanceOn_cannotFindSeat) +{ + mp_ilmErrorType[0] = ILM_SUCCESS; + SET_RETURN_SEQ(impl_sync_and_acquire_instance, mp_ilmErrorType, 1); + + ASSERT_EQ(ILM_FAILED, ilm_setInputAcceptanceOn(mp_ilmSurfaceIds[0], 1, (t_ilm_string*)&SEAT_DEFAULT)); + + ASSERT_EQ(1, release_instance_fake.call_count); +} + +/** ================================================================================================ + * @test_id ilm_setInputAcceptanceOn_addNewOne + * @brief Test case of ilm_setInputAcceptanceOn() where impl_sync_and_acquire_instance() success, return ILM_SUCCESS + * and valid input surface id and input seats is mp_seatName + * @test_procedure Steps: + * -# Mocking the impl_sync_and_acquire_instance() does return ILM_SUCCESS + * -# Calling the ilm_setInputAcceptanceOn() with input seats is mp_seatName + * -# Verification point: + * +# ilm_setInputAcceptanceOn() must return ILM_SUCCESS + * +# wl_proxy_marshal_flags() must be called once time + * +# release_instance() must be called once time + */ +TEST_F(IlmInputTest, ilm_setInputAcceptanceOn_addNewOne) +{ + mp_ilmErrorType[0] = ILM_SUCCESS; + SET_RETURN_SEQ(impl_sync_and_acquire_instance, mp_ilmErrorType, 1); + + ASSERT_EQ(ILM_SUCCESS, ilm_setInputAcceptanceOn(mp_ilmSurfaceIds[0], 2, (t_ilm_string*)&mp_seatName)); + + ASSERT_EQ(1, wl_proxy_marshal_flags_fake.call_count); + ASSERT_EQ(1, release_instance_fake.call_count); +} + +/** ================================================================================================ + * @test_id ilm_setInputAcceptanceOn_removeOne + * @brief Test case of ilm_setInputAcceptanceOn() where impl_sync_and_acquire_instance() success, return ILM_SUCCESS + * and valid input surface id and input seats is mp_seatName[1] + * @test_procedure Steps: + * -# Mocking the impl_sync_and_acquire_instance() does return ILM_SUCCESS + * -# Calling the ilm_setInputAcceptanceOn() with input seats is mp_seatName[1] + * -# Verification point: + * +# ilm_setInputAcceptanceOn() must return ILM_SUCCESS + * +# wl_proxy_marshal_flags() must be called 2 times + * +# release_instance() must be called once time + */ +TEST_F(IlmInputTest, ilm_setInputAcceptanceOn_removeOne) +{ + mp_ilmErrorType[0] = ILM_SUCCESS; + SET_RETURN_SEQ(impl_sync_and_acquire_instance, mp_ilmErrorType, 1); + + ASSERT_EQ(ILM_SUCCESS, ilm_setInputAcceptanceOn(mp_ilmSurfaceIds[0], 1, (t_ilm_string*)&mp_seatName[1])); + + ASSERT_EQ(2, wl_proxy_marshal_flags_fake.call_count); + ASSERT_EQ(1, release_instance_fake.call_count); +} + +/** ================================================================================================ + * @test_id ilm_getInputAcceptanceOn_invalidAgrument + * @brief Test case of ilm_getInputAcceptanceOn() where invalid input num_seats and seats + * @test_procedure Steps: + * -# Calling the ilm_getInputAcceptanceOn() time 1 with num_seats and seats are null pointer + * -# Calling the ilm_getInputAcceptanceOn() time 2 with seats is null pointer + * -# Verification point: + * +# ilm_getInputAcceptanceOn() time 1 and time 2 must return ILM_FAILED + * +# impl_sync_and_acquire_instance() not be called + */ +TEST_F(IlmInputTest, ilm_getInputAcceptanceOn_invalidAgrument) +{ + ASSERT_EQ(ILM_FAILED, ilm_getInputAcceptanceOn(mp_ilmSurfaceIds[0], nullptr, nullptr)); + ASSERT_EQ(ILM_FAILED, ilm_getInputAcceptanceOn(mp_ilmSurfaceIds[0], &m_numberSeat, nullptr)); + + ASSERT_EQ(0, impl_sync_and_acquire_instance_fake.call_count); +} + +/** ================================================================================================ + * @test_id ilm_getInputAcceptanceOn_cannotSyncAcquireInstance + * @brief Test case of ilm_getInputAcceptanceOn() where impl_sync_and_acquire_instance() fails, return ILM_FAILED + * @test_procedure Steps: + * -# Mocking the impl_sync_and_acquire_instance() does return ILM_FAILED + * -# Calling the ilm_getInputAcceptanceOn() + * -# Verification point: + * +# ilm_getInputAcceptanceOn() must return ILM_FAILED + * +# impl_sync_and_acquire_instance() must be called once time and return ILM_FAILED + */ +TEST_F(IlmInputTest, ilm_getInputAcceptanceOn_cannotSyncAcquireInstance) +{ + mp_ilmErrorType[0] = ILM_FAILED; + SET_RETURN_SEQ(impl_sync_and_acquire_instance, mp_ilmErrorType, 1); + + ASSERT_EQ(ILM_FAILED, ilm_getInputAcceptanceOn(mp_ilmSurfaceIds[0], &m_numberSeat, &mp_getSeats)); + + ASSERT_EQ(1, impl_sync_and_acquire_instance_fake.call_count); + ASSERT_EQ(mp_ilmErrorType[0], impl_sync_and_acquire_instance_fake.return_val_history[0]); +} + +/** ================================================================================================ + * @test_id ilm_getInputAcceptanceOn_cannotFindSurfaceId + * @brief Test case of ilm_getInputAcceptanceOn() where impl_sync_and_acquire_instance() success, return ILM_SUCCESS + * and invalid surface id + * @test_procedure Steps: + * -# Mocking the impl_sync_and_acquire_instance() does return ILM_SUCCESS + * -# Calling the ilm_getInputAcceptanceOn() with invalid surface id + * -# Verification point: + * +# ilm_getInputAcceptanceOn() must return ILM_FAILED + * +# impl_sync_and_acquire_instance() must be called once time + * +# release_instance() must be called once time + */ +TEST_F(IlmInputTest, ilm_getInputAcceptanceOn_cannotFindSurfaceId) +{ + mp_ilmErrorType[0] = ILM_SUCCESS; + SET_RETURN_SEQ(impl_sync_and_acquire_instance, mp_ilmErrorType, 1); + + ASSERT_EQ(ILM_FAILED, ilm_getInputAcceptanceOn(MAX_NUMBER + 1, &m_numberSeat, &mp_getSeats)); + + ASSERT_EQ(1, impl_sync_and_acquire_instance_fake.call_count); + ASSERT_EQ(1, release_instance_fake.call_count); +} + +/** ================================================================================================ + * @test_id ilm_getInputAcceptanceOn_success + * @brief Test case of ilm_getInputAcceptanceOn() where impl_sync_and_acquire_instance() success, return ILM_SUCCESS + * and valid surface id + * @test_procedure Steps: + * -# Mocking the impl_sync_and_acquire_instance() does return ILM_SUCCESS + * -# Calling the ilm_getInputAcceptanceOn() with invalid surface id + * -# Verification point: + * +# ilm_getInputAcceptanceOn() must return ILM_SUCCESS + * +# Output should same with prepare data + * +# Free resources are allocated when running the test + */ +TEST_F(IlmInputTest, ilm_getInputAcceptanceOn_success) +{ + wl_list_length_fake.custom_fake = custom_wl_list_length; + mp_ilmErrorType[0] = ILM_SUCCESS; + SET_RETURN_SEQ(impl_sync_and_acquire_instance, mp_ilmErrorType, 1); + + ASSERT_EQ(ILM_SUCCESS, ilm_getInputAcceptanceOn(mp_ilmSurfaceIds[0], &m_numberSeat, &mp_getSeats)); + + EXPECT_EQ(1, m_numberSeat); + EXPECT_EQ(0, strcmp(mp_getSeats[0], "seat_1")); + EXPECT_EQ(1, release_instance_fake.call_count); + + free(mp_getSeats[0]); + free(mp_getSeats); +} + +/** ================================================================================================ + * @test_id ilm_getInputDevices_invalidAgrument + * @brief Test case of ilm_getInputDevices() where invalid input num_seats and seats + * @test_procedure Steps: + * -# Calling the ilm_getInputDevices() time 1 with num_seats and seats are null pointer + * -# Calling the ilm_getInputDevices() time 2 with seats is null pointer + * -# Verification point: + * +# ilm_getInputDevices() time 1 and time 2 must return ILM_FAILED + * +# impl_sync_and_acquire_instance() not be called + */ +TEST_F(IlmInputTest, ilm_getInputDevices_invalidAgrument) +{ + ASSERT_EQ(ILM_FAILED, ilm_getInputDevices(ILM_INPUT_DEVICE_KEYBOARD, nullptr, nullptr)); + ASSERT_EQ(ILM_FAILED, ilm_getInputDevices(ILM_INPUT_DEVICE_KEYBOARD, &m_numberSeat, nullptr)); + + ASSERT_EQ(impl_sync_and_acquire_instance_fake.call_count, 0); +} + +/** ================================================================================================ + * @test_id ilm_getInputDevices_cannotSyncAcquireInstance + * @brief Test case of ilm_getInputDevices() where impl_sync_and_acquire_instance() fails, return ILM_FAILED + * @test_procedure Steps: + * -# Mocking the impl_sync_and_acquire_instance() does return ILM_FAILED + * -# Calling the ilm_getInputDevices() + * -# Verification point: + * +# ilm_getInputDevices() must return ILM_FAILED + * +# impl_sync_and_acquire_instance() must be called once time and return ILM_FAILED + */ +TEST_F(IlmInputTest, ilm_getInputDevices_cannotSyncAcquireInstance) +{ + mp_ilmErrorType[0] = ILM_FAILED; + SET_RETURN_SEQ(impl_sync_and_acquire_instance, mp_ilmErrorType, 1); + + ASSERT_EQ(ILM_FAILED, ilm_getInputDevices(ILM_INPUT_DEVICE_KEYBOARD, &m_numberSeat, &mp_getSeats)); + + ASSERT_EQ(1, impl_sync_and_acquire_instance_fake.call_count); + ASSERT_EQ(mp_ilmErrorType[0], impl_sync_and_acquire_instance_fake.return_val_history[0]); +} + +/** ================================================================================================ + * @test_id ilm_getInputDevices_success + * @brief Test case of ilm_getInputDevices() where impl_sync_and_acquire_instance() success, return ILM_SUCCESS + * and valid bitmask + * @test_procedure Steps: + * -# Mocking the impl_sync_and_acquire_instance() does return ILM_SUCCESS + * -# Calling the ilm_getInputDevices() + * -# Verification point: + * +# ilm_getInputDevices() must return ILM_SUCCESS + * +# release_instance() must be called once time + * +# Output should same with prepare data + * +# Free resources are allocated when running the test + */ +TEST_F(IlmInputTest, ilm_getInputDevices_success) +{ + wl_list_length_fake.custom_fake = custom_wl_list_length; + mp_ilmErrorType[0] = ILM_SUCCESS; + SET_RETURN_SEQ(impl_sync_and_acquire_instance, mp_ilmErrorType, 1); + + ASSERT_EQ(ILM_SUCCESS, ilm_getInputDevices(ILM_INPUT_DEVICE_KEYBOARD, &m_numberSeat, &mp_getSeats)); + + EXPECT_EQ(1, release_instance_fake.call_count); + EXPECT_EQ(5, m_numberSeat); + for(uint8_t i = 0; i < m_numberSeat; i++) + { + EXPECT_EQ(0, strcmp(mp_getSeats[i], mp_seatName[m_numberSeat - i - 1])); + } + + for(uint8_t i = 0; i < m_numberSeat; i++) + { + free(mp_getSeats[i]); + } + free(mp_getSeats); +} + +/** ================================================================================================ + * @test_id ilm_getInputDeviceCapabilities_invalidAgrument + * @brief Test case of ilm_getInputDeviceCapabilities() where invalid input seat_name and bitmask + * @test_procedure Steps: + * -# Calling the ilm_getInputDeviceCapabilities() time 1 with seat_name is null pointer + * -# Calling the ilm_getInputDeviceCapabilities() time 2 with bitmask is null pointer + * -# Verification point: + * +# ilm_getInputDeviceCapabilities() time 1 and time 2 must return ILM_FAILED + * +# impl_sync_and_acquire_instance() not be called + */ +TEST_F(IlmInputTest, ilm_getInputDeviceCapabilities_invalidAgrument) +{ + ilmInputDevice bitmask; + t_ilm_string l_stringSeat = (t_ilm_string)"seat_1"; + ASSERT_EQ(ILM_FAILED, ilm_getInputDeviceCapabilities(nullptr, &bitmask)); + ASSERT_EQ(ILM_FAILED, ilm_getInputDeviceCapabilities(l_stringSeat, nullptr)); + + ASSERT_EQ(impl_sync_and_acquire_instance_fake.call_count, 0); + +} + +/** ================================================================================================ + * @test_id ilm_getInputDeviceCapabilities_cannotSyncAcquireInstance + * @brief Test case of ilm_getInputDeviceCapabilities() where impl_sync_and_acquire_instance() fails, return ILM_FAILED + * @test_procedure Steps: + * -# Mocking the impl_sync_and_acquire_instance() does return ILM_FAILED + * -# Calling the ilm_getInputDeviceCapabilities() + * -# Verification point: + * +# ilm_getInputDeviceCapabilities() must return ILM_FAILED + * +# impl_sync_and_acquire_instance() must be called once time and return ILM_FAILED + */ +TEST_F(IlmInputTest, ilm_getInputDeviceCapabilities_cannotSyncAcquireInstance) +{ + ilmInputDevice bitmask; + t_ilm_string l_stringSeat = (t_ilm_string)"seat_1"; + mp_ilmErrorType[0] = ILM_FAILED; + SET_RETURN_SEQ(impl_sync_and_acquire_instance, mp_ilmErrorType, 1); + + ASSERT_EQ(ILM_FAILED, ilm_getInputDeviceCapabilities(l_stringSeat, &bitmask)); + + ASSERT_EQ(1, impl_sync_and_acquire_instance_fake.call_count); + ASSERT_EQ(mp_ilmErrorType[0], impl_sync_and_acquire_instance_fake.return_val_history[0]); +} + +/** ================================================================================================ + * @test_id ilm_getInputDeviceCapabilities_success + * @brief Test case of ilm_getInputDeviceCapabilities() where impl_sync_and_acquire_instance() success, return ILM_SUCCESS + * and valid bitmask + * @test_procedure Steps: + * -# Mocking the impl_sync_and_acquire_instance() does return ILM_SUCCESS + * -# Calling the ilm_getInputDeviceCapabilities() + * -# Verification point: + * +# ilm_getInputDeviceCapabilities() must return ILM_SUCCESS + * +# Output should same with prepare data + * +# release_instance() must be called once time + */ +TEST_F(IlmInputTest, ilm_getInputDeviceCapabilities_success) +{ + ilmInputDevice bitmask; + t_ilm_string l_stringSeat = (t_ilm_string)"seat_1"; + mp_ilmErrorType[0] = ILM_SUCCESS; + SET_RETURN_SEQ(impl_sync_and_acquire_instance, mp_ilmErrorType, 1); + + ASSERT_EQ(ILM_SUCCESS, ilm_getInputDeviceCapabilities(l_stringSeat, &bitmask)); + + ASSERT_EQ(ILM_INPUT_DEVICE_ALL, bitmask); + ASSERT_EQ(1, release_instance_fake.call_count); +} + +/** ================================================================================================ + * @test_id ilm_setInputFocus_invalidAgrument + * @brief Test case of ilm_setInputFocus() where invalid input seat_name and bitmask + * @test_procedure Steps: + * -# Calling the ilm_setInputFocus() time 1 with surface id is null pointer + * -# Calling the ilm_setInputFocus() time 2 with surface id is not in the list of surface id + * -# Verification point: + * +# ilm_setInputFocus() time 1 and time 2 must return ILM_FAILED + * +# impl_sync_and_acquire_instance() not be called + */ +TEST_F(IlmInputTest, ilm_setInputFocus_invalidAgrument) +{ + t_ilm_surface l_surfaceIDs[] = {MAX_NUMBER + 1, MAX_NUMBER + 2}; + ASSERT_EQ(ILM_FAILED, ilm_setInputFocus(nullptr, 2, ILM_INPUT_DEVICE_POINTER | ILM_INPUT_DEVICE_KEYBOARD, ILM_TRUE)); + ASSERT_EQ(ILM_FAILED, ilm_setInputFocus(l_surfaceIDs, 2, ILM_INPUT_DEVICE_POINTER | ILM_INPUT_DEVICE_KEYBOARD, ILM_TRUE)); + + ASSERT_EQ(impl_sync_and_acquire_instance_fake.call_count, 0); +} + +/** ================================================================================================ + * @test_id ilm_setInputFocus_cannotSyncAcquireInstance + * @brief Test case of ilm_setInputFocus() where impl_sync_and_acquire_instance() fails, return ILM_FAILED + * @test_procedure Steps: + * -# Mocking the impl_sync_and_acquire_instance() does return ILM_FAILED + * -# Calling the ilm_setInputFocus() + * -# Verification point: + * +# ilm_setInputFocus() must return ILM_FAILED + * +# impl_sync_and_acquire_instance() must be called once time and return ILM_FAILED + */ +TEST_F(IlmInputTest, ilm_setInputFocus_cannotSyncAcquireInstance) +{ + mp_ilmErrorType[0] = ILM_FAILED; + SET_RETURN_SEQ(impl_sync_and_acquire_instance, mp_ilmErrorType, 1); + + t_ilm_surface l_surfaceIDs[] = {1, 2}; + ASSERT_EQ(ILM_FAILED, ilm_setInputFocus(l_surfaceIDs, 2, ILM_INPUT_DEVICE_KEYBOARD, ILM_TRUE)); + + ASSERT_EQ(1, impl_sync_and_acquire_instance_fake.call_count); + ASSERT_EQ(mp_ilmErrorType[0], impl_sync_and_acquire_instance_fake.return_val_history[0]); +} + +/** ================================================================================================ + * @test_id ilm_setInputFocus_surfaceNotFound + * @brief Test case of ilm_setInputFocus() where impl_sync_and_acquire_instance() success, return ILM_SUCCESS + * and invalid input surface id + * @test_procedure Steps: + * -# Mocking the impl_sync_and_acquire_instance() does return ILM_SUCCESS + * -# Calling the ilm_setInputFocus() + * -# Verification point: + * +# ilm_setInputFocus() must return ILM_FAILED + * +# impl_sync_and_acquire_instance() must be called once time + * +# release_instance() must be called once time + */ +TEST_F(IlmInputTest, ilm_setInputFocus_surfaceNotFound) +{ + mp_ilmErrorType[0] = ILM_SUCCESS; + SET_RETURN_SEQ(impl_sync_and_acquire_instance, mp_ilmErrorType, 1); + + t_ilm_surface l_surfaceIDs[] = {MAX_NUMBER + 1, MAX_NUMBER + 2}; + ASSERT_EQ(ILM_FAILED, ilm_setInputFocus(l_surfaceIDs, 2, ILM_INPUT_DEVICE_KEYBOARD, ILM_TRUE)); + + ASSERT_EQ(1, impl_sync_and_acquire_instance_fake.call_count); + ASSERT_EQ(1, release_instance_fake.call_count); +} + +/** ================================================================================================ + * @test_id ilm_setInputFocus_success + * @brief Test case of ilm_setInputFocus() where impl_sync_and_acquire_instance() success, return ILM_SUCCESS + * and valid input surface id + * @test_procedure Steps: + * -# Mocking the impl_sync_and_acquire_instance() does return ILM_SUCCESS + * -# Calling the ilm_setInputFocus() + * -# Verification point: + * +# ilm_setInputFocus() must return ILM_SUCCESS + * +# release_instance() must be called once time + * +# impl_sync_and_acquire_instance() must be called once time + */ +TEST_F(IlmInputTest, ilm_setInputFocus_success) +{ + mp_ilmErrorType[0] = ILM_SUCCESS; + SET_RETURN_SEQ(impl_sync_and_acquire_instance, mp_ilmErrorType, 1); + + t_ilm_surface l_surfaceIDs[] = {1}; + ASSERT_EQ(ILM_SUCCESS, ilm_setInputFocus(l_surfaceIDs, 1, ILM_INPUT_DEVICE_POINTER|ILM_INPUT_DEVICE_KEYBOARD, ILM_TRUE)); + + ASSERT_EQ(1, release_instance_fake.call_count); + ASSERT_EQ(1, wl_proxy_marshal_flags_fake.call_count); +} + +/** ================================================================================================ + * @test_id ilm_getInputFocus_invalidAgrument + * @brief Test case of ilm_getInputFocus() where invalid inputs + * @test_procedure Steps: + * -# Calling the ilm_getInputFocus() time 1 with surfaceIDs is null pointer + * -# Calling the ilm_getInputFocus() time 2 with bitmasks is null pointer + * -# Calling the ilm_getInputFocus() time 3 with num_ids is null pointer + * -# Verification point: + * +# ilm_getInputFocus() time 1 and time 2 and time 3 must return ILM_FAILED + * +# impl_sync_and_acquire_instance() not be called + */ +TEST_F(IlmInputTest, ilm_getInputFocus_invalidAgrument) +{ + t_ilm_surface *lp_surfaceIds = nullptr; + ilmInputDevice *lp_bitmasks = nullptr; + t_ilm_uint l_numId = 0; + ASSERT_EQ(ILM_FAILED, ilm_getInputFocus(nullptr, &lp_bitmasks, &l_numId)); + ASSERT_EQ(ILM_FAILED, ilm_getInputFocus(&lp_surfaceIds, nullptr, &l_numId)); + ASSERT_EQ(ILM_FAILED, ilm_getInputFocus(&lp_surfaceIds, &lp_bitmasks, nullptr)); + + ASSERT_EQ(impl_sync_and_acquire_instance_fake.call_count, 0); +} + +/** ================================================================================================ + * @test_id ilm_getInputFocus_cannotSyncAcquireInstance + * @brief Test case of ilm_getInputFocus() where impl_sync_and_acquire_instance() fails, return ILM_FAILED + * @test_procedure Steps: + * -# Mocking the impl_sync_and_acquire_instance() does return ILM_FAILED + * -# Calling the ilm_getInputFocus() + * -# Verification point: + * +# ilm_getInputFocus() must return ILM_FAILED + * +# impl_sync_and_acquire_instance() must be called once time and return ILM_FAILED + */ +TEST_F(IlmInputTest, ilm_getInputFocus_cannotSyncAcquireInstance) +{ + mp_ilmErrorType[0] = ILM_FAILED; + SET_RETURN_SEQ(impl_sync_and_acquire_instance, mp_ilmErrorType, 1); + + t_ilm_surface *lp_surfaceIds = nullptr; + ilmInputDevice *lp_bitmasks = nullptr; + t_ilm_uint l_numId = 0; + ASSERT_EQ(ILM_FAILED, ilm_getInputFocus(&lp_surfaceIds, &lp_bitmasks, &l_numId)); + + ASSERT_EQ(1, impl_sync_and_acquire_instance_fake.call_count); + ASSERT_EQ(mp_ilmErrorType[0], impl_sync_and_acquire_instance_fake.return_val_history[0]); +} + +/** ================================================================================================ + * @test_id ilm_getInputFocus_success + * @brief Test case of ilm_getInputFocus() where impl_sync_and_acquire_instance() success, return ILM_SUCCESS + * and valid inputs + * @test_procedure Steps: + * -# Mocking the impl_sync_and_acquire_instance() does return ILM_SUCCESS + * -# Calling the ilm_getInputFocus() + * -# Verification point: + * +# ilm_getInputFocus() must return ILM_SUCCESS + * +# release_instance() must be called once time + * +# Output should same with prepare data + * +# Free resources are allocated when running the test + */ +TEST_F(IlmInputTest, ilm_getInputFocus_success) +{ + wl_list_length_fake.custom_fake = custom_wl_list_length; + mp_ilmErrorType[0] = ILM_SUCCESS; + SET_RETURN_SEQ(impl_sync_and_acquire_instance, mp_ilmErrorType, 1); + + t_ilm_surface *lp_surfaceIds = nullptr; + ilmInputDevice *lp_bitmasks = nullptr; + t_ilm_uint l_numId = 0; + ASSERT_EQ(ILM_SUCCESS, ilm_getInputFocus(&lp_surfaceIds, &lp_bitmasks, &l_numId)); + + EXPECT_EQ(1, release_instance_fake.call_count); + EXPECT_EQ(5, l_numId); + for(uint8_t i = 0; i < l_numId; i++) + { + EXPECT_EQ(lp_surfaceIds[i], mp_ilmSurfaceIds[l_numId - i -1]); + EXPECT_EQ(lp_bitmasks[i], ILM_INPUT_DEVICE_KEYBOARD); + } + + free(lp_surfaceIds); + free(lp_bitmasks); +} diff --git a/unittest/common/common_fake_api.c b/unittest/common/common_fake_api.c new file mode 100644 index 00000000..fd52b6ed --- /dev/null +++ b/unittest/common/common_fake_api.c @@ -0,0 +1,109 @@ +/*************************************************************************** + * + * Copyright (C) 2023 Advanced Driver Information Technology Joint Venture GmbH + * + * + * 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. + * + ****************************************************************************/ + +#include "common_fake_api.h" +#include +#include + +/* Invalid memory address */ +#define WL_ARRAY_POISON_PTR (void *) 4 + +void custom_wl_list_init(struct wl_list *list) +{ + list->prev = list; + list->next = list; +} + +void custom_wl_list_insert(struct wl_list *list, struct wl_list *elm) +{ + elm->prev = list; + elm->next = list->next; + list->next = elm; + elm->next->prev = elm; +} + +int custom_wl_list_length(const struct wl_list *list) +{ + struct wl_list *e; + int count; + + count = 0; + e = list->next; + while (e != list) { + e = e->next; + count++; + } + + return count; +} + +void custom_wl_list_remove(struct wl_list *elm) +{ + elm->prev->next = elm->next; + elm->next->prev = elm->prev; + elm->next = NULL; + elm->prev = NULL; +} + +int custom_wl_list_empty(const struct wl_list *list) +{ + return list->next == list; +} + +void custom_wl_array_init(struct wl_array *array) +{ + memset(array, 0, sizeof *array); +} + +void custom_wl_array_release(struct wl_array *array) +{ + free(array->data); + array->data = WL_ARRAY_POISON_PTR; +} + +void *custom_wl_array_add(struct wl_array *array, size_t size) +{ + size_t alloc; + void *data, *p; + + if (array->alloc > 0) + alloc = array->alloc; + else + alloc = 16; + + while (alloc < array->size + size) + alloc *= 2; + + if (array->alloc < alloc) { + if (array->alloc > 0) + data = realloc(array->data, alloc); + else + data = malloc(alloc); + + if (data == NULL) + return NULL; + array->data = data; + array->alloc = alloc; + } + + p = (char *)array->data + array->size; + array->size += size; + + return p; +} \ No newline at end of file diff --git a/unittest/common/common_fake_api.h b/unittest/common/common_fake_api.h new file mode 100644 index 00000000..0019aa66 --- /dev/null +++ b/unittest/common/common_fake_api.h @@ -0,0 +1,42 @@ +/*************************************************************************** + * + * Copyright (C) 2023 Advanced Driver Information Technology Joint Venture GmbH + * + * + * 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. + * + ****************************************************************************/ + +#ifndef COMMON_FAKE_API +#define COMMON_FAKE_API + +#include "stdint.h" +#include "wayland-client-protocol.h" + +#ifdef __cplusplus +extern "C" { +#endif + +void custom_wl_list_init(struct wl_list *list); +void custom_wl_list_insert(struct wl_list *list, struct wl_list *elm); +void custom_wl_list_remove(struct wl_list *elm); +int custom_wl_list_empty(const struct wl_list *list); +void custom_wl_array_init(struct wl_array *array); +void custom_wl_array_release(struct wl_array *array); +void *custom_wl_array_add(struct wl_array *array, size_t size); +int custom_wl_list_length(const struct wl_list *list); + +#ifdef __cplusplus +} +#endif +#endif // COMMON_FAKE_API \ No newline at end of file diff --git a/unittest/common/fff.h b/unittest/common/fff.h new file mode 100644 index 00000000..a2eb329a --- /dev/null +++ b/unittest/common/fff.h @@ -0,0 +1,6643 @@ +/* +LICENSE + +The MIT License (MIT) + +Copyright (c) 2010 Michael Long + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +*/ +#ifndef FAKE_FUNCTIONS +#define FAKE_FUNCTIONS + +#include +#include /* For memset and memcpy */ + +#define FFF_MAX_ARGS (20u) +#ifndef FFF_ARG_HISTORY_LEN + #define FFF_ARG_HISTORY_LEN (50u) +#endif +#ifndef FFF_CALL_HISTORY_LEN + #define FFF_CALL_HISTORY_LEN (50u) +#endif +#ifndef FFF_GCC_FUNCTION_ATTRIBUTES + #define FFF_GCC_FUNCTION_ATTRIBUTES +#endif +/* -- INTERNAL HELPER MACROS -- */ +#define SET_RETURN_SEQ(FUNCNAME, ARRAY_POINTER, ARRAY_LEN) \ + FUNCNAME##_fake.return_val_seq = ARRAY_POINTER; \ + FUNCNAME##_fake.return_val_seq_len = ARRAY_LEN; +#define SET_CUSTOM_FAKE_SEQ(FUNCNAME, ARRAY_POINTER, ARRAY_LEN) \ + FUNCNAME##_fake.custom_fake_seq = ARRAY_POINTER; \ + FUNCNAME##_fake.custom_fake_seq_len = ARRAY_LEN; + +/* Defining a function to reset a fake function */ +#define RESET_FAKE(FUNCNAME) { \ + FUNCNAME##_reset(); \ +} \ + + +#define DECLARE_ARG(type, n, FUNCNAME) \ + type arg##n##_val; \ + type arg##n##_history[FFF_ARG_HISTORY_LEN]; + +#define DECLARE_ALL_FUNC_COMMON \ + unsigned int call_count; \ + unsigned int arg_history_len; \ + unsigned int arg_histories_dropped; \ + +#define DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE) \ + RETURN_TYPE return_val_history[FFF_ARG_HISTORY_LEN]; + +#define SAVE_ARG(FUNCNAME, n) \ + memcpy((void*)&FUNCNAME##_fake.arg##n##_val, (void*)&arg##n, sizeof(arg##n)); + +#define ROOM_FOR_MORE_HISTORY(FUNCNAME) \ + FUNCNAME##_fake.call_count < FFF_ARG_HISTORY_LEN + +#define SAVE_RET_HISTORY(FUNCNAME, RETVAL) \ + if ((FUNCNAME##_fake.call_count - 1) < FFF_ARG_HISTORY_LEN) \ + memcpy((void *)&FUNCNAME##_fake.return_val_history[FUNCNAME##_fake.call_count - 1], (const void *) &RETVAL, sizeof(RETVAL)); \ + +#define SAVE_ARG_HISTORY(FUNCNAME, ARGN) \ + memcpy((void*)&FUNCNAME##_fake.arg##ARGN##_history[FUNCNAME##_fake.call_count], (void*)&arg##ARGN, sizeof(arg##ARGN)); + +#define HISTORY_DROPPED(FUNCNAME) \ + FUNCNAME##_fake.arg_histories_dropped++ + +#define DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE) \ + RETURN_TYPE return_val; \ + int return_val_seq_len; \ + int return_val_seq_idx; \ + RETURN_TYPE * return_val_seq; \ + +#define DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + int custom_fake_seq_len; \ + int custom_fake_seq_idx; \ + +#define INCREMENT_CALL_COUNT(FUNCNAME) \ + FUNCNAME##_fake.call_count++ + +#define RETURN_FAKE_RESULT(FUNCNAME) \ + if (FUNCNAME##_fake.return_val_seq_len){ /* then its a sequence */ \ + if(FUNCNAME##_fake.return_val_seq_idx < FUNCNAME##_fake.return_val_seq_len) { \ + SAVE_RET_HISTORY(FUNCNAME, FUNCNAME##_fake.return_val_seq[FUNCNAME##_fake.return_val_seq_idx]) \ + return FUNCNAME##_fake.return_val_seq[FUNCNAME##_fake.return_val_seq_idx++]; \ + } \ + SAVE_RET_HISTORY(FUNCNAME, FUNCNAME##_fake.return_val_seq[FUNCNAME##_fake.return_val_seq_len-1]) \ + return FUNCNAME##_fake.return_val_seq[FUNCNAME##_fake.return_val_seq_len-1]; /* return last element */ \ + } \ + SAVE_RET_HISTORY(FUNCNAME, FUNCNAME##_fake.return_val) \ + return FUNCNAME##_fake.return_val; \ + +#ifdef __cplusplus + #define FFF_EXTERN_C extern "C"{ + #define FFF_END_EXTERN_C } +#else /* ansi c */ + #define FFF_EXTERN_C + #define FFF_END_EXTERN_C +#endif /* cpp/ansi c */ + +#define DEFINE_RESET_FUNCTION(FUNCNAME) \ + void FUNCNAME##_reset(void){ \ + memset(&FUNCNAME##_fake, 0, sizeof(FUNCNAME##_fake)); \ + FUNCNAME##_fake.arg_history_len = FFF_ARG_HISTORY_LEN; \ + } +/* -- END INTERNAL HELPER MACROS -- */ + +typedef void (*fff_function_t)(void); +typedef struct { + fff_function_t call_history[FFF_CALL_HISTORY_LEN]; + unsigned int call_history_idx; +} fff_globals_t; + +FFF_EXTERN_C +extern fff_globals_t fff; +FFF_END_EXTERN_C + +#define DEFINE_FFF_GLOBALS \ + FFF_EXTERN_C \ + fff_globals_t fff; \ + FFF_END_EXTERN_C + +#define FFF_RESET_HISTORY() \ + fff.call_history_idx = 0; \ + memset(fff.call_history, 0, sizeof(fff.call_history)); + +#define REGISTER_CALL(function) \ + if(fff.call_history_idx < FFF_CALL_HISTORY_LEN) \ + fff.call_history[fff.call_history_idx++] = (fff_function_t)function; + +#define DECLARE_FAKE_VOID_FUNC0(FUNCNAME) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + void(*custom_fake)(void); \ + void(**custom_fake_seq)(void); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(void); \ + +#define DEFINE_FAKE_VOID_FUNC0(FUNCNAME) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(void){ \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](); \ + } \ + else{ \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](); \ + } \ + } \ + if (FUNCNAME##_fake.custom_fake){ \ + FUNCNAME##_fake.custom_fake(); \ + } \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VOID_FUNC0(FUNCNAME) \ + DECLARE_FAKE_VOID_FUNC0(FUNCNAME) \ + DEFINE_FAKE_VOID_FUNC0(FUNCNAME) \ + + +#define DECLARE_FAKE_VOID_FUNC1(FUNCNAME, ARG0_TYPE) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + void(*custom_fake)(ARG0_TYPE arg0); \ + void(**custom_fake_seq)(ARG0_TYPE arg0); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0); \ + +#define DEFINE_FAKE_VOID_FUNC1(FUNCNAME, ARG0_TYPE) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0){ \ + SAVE_ARG(FUNCNAME, 0); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0); \ + } \ + else{ \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0); \ + } \ + } \ + if (FUNCNAME##_fake.custom_fake){ \ + FUNCNAME##_fake.custom_fake(arg0); \ + } \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VOID_FUNC1(FUNCNAME, ARG0_TYPE) \ + DECLARE_FAKE_VOID_FUNC1(FUNCNAME, ARG0_TYPE) \ + DEFINE_FAKE_VOID_FUNC1(FUNCNAME, ARG0_TYPE) \ + + +#define DECLARE_FAKE_VOID_FUNC2(FUNCNAME, ARG0_TYPE, ARG1_TYPE) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + void(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1); \ + void(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1); \ + +#define DEFINE_FAKE_VOID_FUNC2(FUNCNAME, ARG0_TYPE, ARG1_TYPE) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1); \ + } \ + else{ \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1); \ + } \ + } \ + if (FUNCNAME##_fake.custom_fake){ \ + FUNCNAME##_fake.custom_fake(arg0, arg1); \ + } \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VOID_FUNC2(FUNCNAME, ARG0_TYPE, ARG1_TYPE) \ + DECLARE_FAKE_VOID_FUNC2(FUNCNAME, ARG0_TYPE, ARG1_TYPE) \ + DEFINE_FAKE_VOID_FUNC2(FUNCNAME, ARG0_TYPE, ARG1_TYPE) \ + + +#define DECLARE_FAKE_VOID_FUNC3(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + void(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2); \ + void(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2); \ + +#define DEFINE_FAKE_VOID_FUNC3(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2); \ + } \ + else{ \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2); \ + } \ + } \ + if (FUNCNAME##_fake.custom_fake){ \ + FUNCNAME##_fake.custom_fake(arg0, arg1, arg2); \ + } \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VOID_FUNC3(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE) \ + DECLARE_FAKE_VOID_FUNC3(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE) \ + DEFINE_FAKE_VOID_FUNC3(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE) \ + + +#define DECLARE_FAKE_VOID_FUNC4(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + void(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3); \ + void(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3); \ + +#define DEFINE_FAKE_VOID_FUNC4(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3); \ + } \ + else{ \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3); \ + } \ + } \ + if (FUNCNAME##_fake.custom_fake){ \ + FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3); \ + } \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VOID_FUNC4(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE) \ + DECLARE_FAKE_VOID_FUNC4(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE) \ + DEFINE_FAKE_VOID_FUNC4(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE) \ + + +#define DECLARE_FAKE_VOID_FUNC5(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + void(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4); \ + void(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4); \ + +#define DEFINE_FAKE_VOID_FUNC5(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4); \ + } \ + else{ \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4); \ + } \ + } \ + if (FUNCNAME##_fake.custom_fake){ \ + FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4); \ + } \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VOID_FUNC5(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE) \ + DECLARE_FAKE_VOID_FUNC5(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE) \ + DEFINE_FAKE_VOID_FUNC5(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE) \ + + +#define DECLARE_FAKE_VOID_FUNC6(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + void(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5); \ + void(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5); \ + +#define DEFINE_FAKE_VOID_FUNC6(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + SAVE_ARG(FUNCNAME, 5); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + SAVE_ARG_HISTORY(FUNCNAME, 5); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5); \ + } \ + else{ \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5); \ + } \ + } \ + if (FUNCNAME##_fake.custom_fake){ \ + FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5); \ + } \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VOID_FUNC6(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE) \ + DECLARE_FAKE_VOID_FUNC6(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE) \ + DEFINE_FAKE_VOID_FUNC6(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE) \ + + +#define DECLARE_FAKE_VOID_FUNC7(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \ + DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + void(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6); \ + void(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6); \ + +#define DEFINE_FAKE_VOID_FUNC7(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + SAVE_ARG(FUNCNAME, 5); \ + SAVE_ARG(FUNCNAME, 6); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + SAVE_ARG_HISTORY(FUNCNAME, 5); \ + SAVE_ARG_HISTORY(FUNCNAME, 6); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6); \ + } \ + else{ \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6); \ + } \ + } \ + if (FUNCNAME##_fake.custom_fake){ \ + FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6); \ + } \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VOID_FUNC7(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE) \ + DECLARE_FAKE_VOID_FUNC7(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE) \ + DEFINE_FAKE_VOID_FUNC7(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE) \ + + +#define DECLARE_FAKE_VOID_FUNC8(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \ + DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \ + DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + void(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7); \ + void(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7); \ + +#define DEFINE_FAKE_VOID_FUNC8(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + SAVE_ARG(FUNCNAME, 5); \ + SAVE_ARG(FUNCNAME, 6); \ + SAVE_ARG(FUNCNAME, 7); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + SAVE_ARG_HISTORY(FUNCNAME, 5); \ + SAVE_ARG_HISTORY(FUNCNAME, 6); \ + SAVE_ARG_HISTORY(FUNCNAME, 7); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7); \ + } \ + else{ \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7); \ + } \ + } \ + if (FUNCNAME##_fake.custom_fake){ \ + FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7); \ + } \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VOID_FUNC8(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE) \ + DECLARE_FAKE_VOID_FUNC8(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE) \ + DEFINE_FAKE_VOID_FUNC8(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE) \ + + +#define DECLARE_FAKE_VOID_FUNC9(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \ + DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \ + DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \ + DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + void(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8); \ + void(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8); \ + +#define DEFINE_FAKE_VOID_FUNC9(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + SAVE_ARG(FUNCNAME, 5); \ + SAVE_ARG(FUNCNAME, 6); \ + SAVE_ARG(FUNCNAME, 7); \ + SAVE_ARG(FUNCNAME, 8); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + SAVE_ARG_HISTORY(FUNCNAME, 5); \ + SAVE_ARG_HISTORY(FUNCNAME, 6); \ + SAVE_ARG_HISTORY(FUNCNAME, 7); \ + SAVE_ARG_HISTORY(FUNCNAME, 8); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); \ + } \ + else{ \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); \ + } \ + } \ + if (FUNCNAME##_fake.custom_fake){ \ + FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); \ + } \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VOID_FUNC9(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE) \ + DECLARE_FAKE_VOID_FUNC9(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE) \ + DEFINE_FAKE_VOID_FUNC9(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE) \ + + +#define DECLARE_FAKE_VOID_FUNC10(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \ + DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \ + DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \ + DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME) \ + DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + void(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9); \ + void(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9); \ + +#define DEFINE_FAKE_VOID_FUNC10(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + SAVE_ARG(FUNCNAME, 5); \ + SAVE_ARG(FUNCNAME, 6); \ + SAVE_ARG(FUNCNAME, 7); \ + SAVE_ARG(FUNCNAME, 8); \ + SAVE_ARG(FUNCNAME, 9); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + SAVE_ARG_HISTORY(FUNCNAME, 5); \ + SAVE_ARG_HISTORY(FUNCNAME, 6); \ + SAVE_ARG_HISTORY(FUNCNAME, 7); \ + SAVE_ARG_HISTORY(FUNCNAME, 8); \ + SAVE_ARG_HISTORY(FUNCNAME, 9); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); \ + } \ + else{ \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); \ + } \ + } \ + if (FUNCNAME##_fake.custom_fake){ \ + FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); \ + } \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VOID_FUNC10(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE) \ + DECLARE_FAKE_VOID_FUNC10(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE) \ + DEFINE_FAKE_VOID_FUNC10(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE) \ + + +#define DECLARE_FAKE_VOID_FUNC11(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \ + DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \ + DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \ + DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME) \ + DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME) \ + DECLARE_ARG(ARG10_TYPE, 10, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + void(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10); \ + void(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10); \ + +#define DEFINE_FAKE_VOID_FUNC11(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + SAVE_ARG(FUNCNAME, 5); \ + SAVE_ARG(FUNCNAME, 6); \ + SAVE_ARG(FUNCNAME, 7); \ + SAVE_ARG(FUNCNAME, 8); \ + SAVE_ARG(FUNCNAME, 9); \ + SAVE_ARG(FUNCNAME, 10); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + SAVE_ARG_HISTORY(FUNCNAME, 5); \ + SAVE_ARG_HISTORY(FUNCNAME, 6); \ + SAVE_ARG_HISTORY(FUNCNAME, 7); \ + SAVE_ARG_HISTORY(FUNCNAME, 8); \ + SAVE_ARG_HISTORY(FUNCNAME, 9); \ + SAVE_ARG_HISTORY(FUNCNAME, 10); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10); \ + } \ + else{ \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10); \ + } \ + } \ + if (FUNCNAME##_fake.custom_fake){ \ + FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10); \ + } \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VOID_FUNC11(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE) \ + DECLARE_FAKE_VOID_FUNC11(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE) \ + DEFINE_FAKE_VOID_FUNC11(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE) \ + + +#define DECLARE_FAKE_VOID_FUNC12(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \ + DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \ + DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \ + DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME) \ + DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME) \ + DECLARE_ARG(ARG10_TYPE, 10, FUNCNAME) \ + DECLARE_ARG(ARG11_TYPE, 11, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + void(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11); \ + void(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11); \ + +#define DEFINE_FAKE_VOID_FUNC12(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + SAVE_ARG(FUNCNAME, 5); \ + SAVE_ARG(FUNCNAME, 6); \ + SAVE_ARG(FUNCNAME, 7); \ + SAVE_ARG(FUNCNAME, 8); \ + SAVE_ARG(FUNCNAME, 9); \ + SAVE_ARG(FUNCNAME, 10); \ + SAVE_ARG(FUNCNAME, 11); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + SAVE_ARG_HISTORY(FUNCNAME, 5); \ + SAVE_ARG_HISTORY(FUNCNAME, 6); \ + SAVE_ARG_HISTORY(FUNCNAME, 7); \ + SAVE_ARG_HISTORY(FUNCNAME, 8); \ + SAVE_ARG_HISTORY(FUNCNAME, 9); \ + SAVE_ARG_HISTORY(FUNCNAME, 10); \ + SAVE_ARG_HISTORY(FUNCNAME, 11); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11); \ + } \ + else{ \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11); \ + } \ + } \ + if (FUNCNAME##_fake.custom_fake){ \ + FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11); \ + } \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VOID_FUNC12(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE) \ + DECLARE_FAKE_VOID_FUNC12(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE) \ + DEFINE_FAKE_VOID_FUNC12(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE) \ + + +#define DECLARE_FAKE_VOID_FUNC13(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \ + DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \ + DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \ + DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME) \ + DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME) \ + DECLARE_ARG(ARG10_TYPE, 10, FUNCNAME) \ + DECLARE_ARG(ARG11_TYPE, 11, FUNCNAME) \ + DECLARE_ARG(ARG12_TYPE, 12, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + void(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12); \ + void(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12); \ + +#define DEFINE_FAKE_VOID_FUNC13(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + SAVE_ARG(FUNCNAME, 5); \ + SAVE_ARG(FUNCNAME, 6); \ + SAVE_ARG(FUNCNAME, 7); \ + SAVE_ARG(FUNCNAME, 8); \ + SAVE_ARG(FUNCNAME, 9); \ + SAVE_ARG(FUNCNAME, 10); \ + SAVE_ARG(FUNCNAME, 11); \ + SAVE_ARG(FUNCNAME, 12); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + SAVE_ARG_HISTORY(FUNCNAME, 5); \ + SAVE_ARG_HISTORY(FUNCNAME, 6); \ + SAVE_ARG_HISTORY(FUNCNAME, 7); \ + SAVE_ARG_HISTORY(FUNCNAME, 8); \ + SAVE_ARG_HISTORY(FUNCNAME, 9); \ + SAVE_ARG_HISTORY(FUNCNAME, 10); \ + SAVE_ARG_HISTORY(FUNCNAME, 11); \ + SAVE_ARG_HISTORY(FUNCNAME, 12); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12); \ + } \ + else{ \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12); \ + } \ + } \ + if (FUNCNAME##_fake.custom_fake){ \ + FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12); \ + } \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VOID_FUNC13(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE) \ + DECLARE_FAKE_VOID_FUNC13(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE) \ + DEFINE_FAKE_VOID_FUNC13(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE) \ + + +#define DECLARE_FAKE_VOID_FUNC14(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \ + DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \ + DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \ + DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME) \ + DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME) \ + DECLARE_ARG(ARG10_TYPE, 10, FUNCNAME) \ + DECLARE_ARG(ARG11_TYPE, 11, FUNCNAME) \ + DECLARE_ARG(ARG12_TYPE, 12, FUNCNAME) \ + DECLARE_ARG(ARG13_TYPE, 13, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + void(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13); \ + void(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13); \ + +#define DEFINE_FAKE_VOID_FUNC14(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + SAVE_ARG(FUNCNAME, 5); \ + SAVE_ARG(FUNCNAME, 6); \ + SAVE_ARG(FUNCNAME, 7); \ + SAVE_ARG(FUNCNAME, 8); \ + SAVE_ARG(FUNCNAME, 9); \ + SAVE_ARG(FUNCNAME, 10); \ + SAVE_ARG(FUNCNAME, 11); \ + SAVE_ARG(FUNCNAME, 12); \ + SAVE_ARG(FUNCNAME, 13); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + SAVE_ARG_HISTORY(FUNCNAME, 5); \ + SAVE_ARG_HISTORY(FUNCNAME, 6); \ + SAVE_ARG_HISTORY(FUNCNAME, 7); \ + SAVE_ARG_HISTORY(FUNCNAME, 8); \ + SAVE_ARG_HISTORY(FUNCNAME, 9); \ + SAVE_ARG_HISTORY(FUNCNAME, 10); \ + SAVE_ARG_HISTORY(FUNCNAME, 11); \ + SAVE_ARG_HISTORY(FUNCNAME, 12); \ + SAVE_ARG_HISTORY(FUNCNAME, 13); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13); \ + } \ + else{ \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13); \ + } \ + } \ + if (FUNCNAME##_fake.custom_fake){ \ + FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13); \ + } \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VOID_FUNC14(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE) \ + DECLARE_FAKE_VOID_FUNC14(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE) \ + DEFINE_FAKE_VOID_FUNC14(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE) \ + + +#define DECLARE_FAKE_VOID_FUNC15(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \ + DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \ + DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \ + DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME) \ + DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME) \ + DECLARE_ARG(ARG10_TYPE, 10, FUNCNAME) \ + DECLARE_ARG(ARG11_TYPE, 11, FUNCNAME) \ + DECLARE_ARG(ARG12_TYPE, 12, FUNCNAME) \ + DECLARE_ARG(ARG13_TYPE, 13, FUNCNAME) \ + DECLARE_ARG(ARG14_TYPE, 14, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + void(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14); \ + void(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14); \ + +#define DEFINE_FAKE_VOID_FUNC15(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + SAVE_ARG(FUNCNAME, 5); \ + SAVE_ARG(FUNCNAME, 6); \ + SAVE_ARG(FUNCNAME, 7); \ + SAVE_ARG(FUNCNAME, 8); \ + SAVE_ARG(FUNCNAME, 9); \ + SAVE_ARG(FUNCNAME, 10); \ + SAVE_ARG(FUNCNAME, 11); \ + SAVE_ARG(FUNCNAME, 12); \ + SAVE_ARG(FUNCNAME, 13); \ + SAVE_ARG(FUNCNAME, 14); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + SAVE_ARG_HISTORY(FUNCNAME, 5); \ + SAVE_ARG_HISTORY(FUNCNAME, 6); \ + SAVE_ARG_HISTORY(FUNCNAME, 7); \ + SAVE_ARG_HISTORY(FUNCNAME, 8); \ + SAVE_ARG_HISTORY(FUNCNAME, 9); \ + SAVE_ARG_HISTORY(FUNCNAME, 10); \ + SAVE_ARG_HISTORY(FUNCNAME, 11); \ + SAVE_ARG_HISTORY(FUNCNAME, 12); \ + SAVE_ARG_HISTORY(FUNCNAME, 13); \ + SAVE_ARG_HISTORY(FUNCNAME, 14); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14); \ + } \ + else{ \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14); \ + } \ + } \ + if (FUNCNAME##_fake.custom_fake){ \ + FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14); \ + } \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VOID_FUNC15(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE) \ + DECLARE_FAKE_VOID_FUNC15(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE) \ + DEFINE_FAKE_VOID_FUNC15(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE) \ + + +#define DECLARE_FAKE_VOID_FUNC16(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \ + DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \ + DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \ + DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME) \ + DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME) \ + DECLARE_ARG(ARG10_TYPE, 10, FUNCNAME) \ + DECLARE_ARG(ARG11_TYPE, 11, FUNCNAME) \ + DECLARE_ARG(ARG12_TYPE, 12, FUNCNAME) \ + DECLARE_ARG(ARG13_TYPE, 13, FUNCNAME) \ + DECLARE_ARG(ARG14_TYPE, 14, FUNCNAME) \ + DECLARE_ARG(ARG15_TYPE, 15, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + void(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15); \ + void(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15); \ + +#define DEFINE_FAKE_VOID_FUNC16(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + SAVE_ARG(FUNCNAME, 5); \ + SAVE_ARG(FUNCNAME, 6); \ + SAVE_ARG(FUNCNAME, 7); \ + SAVE_ARG(FUNCNAME, 8); \ + SAVE_ARG(FUNCNAME, 9); \ + SAVE_ARG(FUNCNAME, 10); \ + SAVE_ARG(FUNCNAME, 11); \ + SAVE_ARG(FUNCNAME, 12); \ + SAVE_ARG(FUNCNAME, 13); \ + SAVE_ARG(FUNCNAME, 14); \ + SAVE_ARG(FUNCNAME, 15); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + SAVE_ARG_HISTORY(FUNCNAME, 5); \ + SAVE_ARG_HISTORY(FUNCNAME, 6); \ + SAVE_ARG_HISTORY(FUNCNAME, 7); \ + SAVE_ARG_HISTORY(FUNCNAME, 8); \ + SAVE_ARG_HISTORY(FUNCNAME, 9); \ + SAVE_ARG_HISTORY(FUNCNAME, 10); \ + SAVE_ARG_HISTORY(FUNCNAME, 11); \ + SAVE_ARG_HISTORY(FUNCNAME, 12); \ + SAVE_ARG_HISTORY(FUNCNAME, 13); \ + SAVE_ARG_HISTORY(FUNCNAME, 14); \ + SAVE_ARG_HISTORY(FUNCNAME, 15); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15); \ + } \ + else{ \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15); \ + } \ + } \ + if (FUNCNAME##_fake.custom_fake){ \ + FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15); \ + } \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VOID_FUNC16(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE) \ + DECLARE_FAKE_VOID_FUNC16(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE) \ + DEFINE_FAKE_VOID_FUNC16(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE) \ + + +#define DECLARE_FAKE_VOID_FUNC17(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \ + DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \ + DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \ + DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME) \ + DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME) \ + DECLARE_ARG(ARG10_TYPE, 10, FUNCNAME) \ + DECLARE_ARG(ARG11_TYPE, 11, FUNCNAME) \ + DECLARE_ARG(ARG12_TYPE, 12, FUNCNAME) \ + DECLARE_ARG(ARG13_TYPE, 13, FUNCNAME) \ + DECLARE_ARG(ARG14_TYPE, 14, FUNCNAME) \ + DECLARE_ARG(ARG15_TYPE, 15, FUNCNAME) \ + DECLARE_ARG(ARG16_TYPE, 16, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + void(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16); \ + void(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16); \ + +#define DEFINE_FAKE_VOID_FUNC17(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + SAVE_ARG(FUNCNAME, 5); \ + SAVE_ARG(FUNCNAME, 6); \ + SAVE_ARG(FUNCNAME, 7); \ + SAVE_ARG(FUNCNAME, 8); \ + SAVE_ARG(FUNCNAME, 9); \ + SAVE_ARG(FUNCNAME, 10); \ + SAVE_ARG(FUNCNAME, 11); \ + SAVE_ARG(FUNCNAME, 12); \ + SAVE_ARG(FUNCNAME, 13); \ + SAVE_ARG(FUNCNAME, 14); \ + SAVE_ARG(FUNCNAME, 15); \ + SAVE_ARG(FUNCNAME, 16); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + SAVE_ARG_HISTORY(FUNCNAME, 5); \ + SAVE_ARG_HISTORY(FUNCNAME, 6); \ + SAVE_ARG_HISTORY(FUNCNAME, 7); \ + SAVE_ARG_HISTORY(FUNCNAME, 8); \ + SAVE_ARG_HISTORY(FUNCNAME, 9); \ + SAVE_ARG_HISTORY(FUNCNAME, 10); \ + SAVE_ARG_HISTORY(FUNCNAME, 11); \ + SAVE_ARG_HISTORY(FUNCNAME, 12); \ + SAVE_ARG_HISTORY(FUNCNAME, 13); \ + SAVE_ARG_HISTORY(FUNCNAME, 14); \ + SAVE_ARG_HISTORY(FUNCNAME, 15); \ + SAVE_ARG_HISTORY(FUNCNAME, 16); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16); \ + } \ + else{ \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16); \ + } \ + } \ + if (FUNCNAME##_fake.custom_fake){ \ + FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16); \ + } \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VOID_FUNC17(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE) \ + DECLARE_FAKE_VOID_FUNC17(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE) \ + DEFINE_FAKE_VOID_FUNC17(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE) \ + + +#define DECLARE_FAKE_VOID_FUNC18(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \ + DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \ + DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \ + DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME) \ + DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME) \ + DECLARE_ARG(ARG10_TYPE, 10, FUNCNAME) \ + DECLARE_ARG(ARG11_TYPE, 11, FUNCNAME) \ + DECLARE_ARG(ARG12_TYPE, 12, FUNCNAME) \ + DECLARE_ARG(ARG13_TYPE, 13, FUNCNAME) \ + DECLARE_ARG(ARG14_TYPE, 14, FUNCNAME) \ + DECLARE_ARG(ARG15_TYPE, 15, FUNCNAME) \ + DECLARE_ARG(ARG16_TYPE, 16, FUNCNAME) \ + DECLARE_ARG(ARG17_TYPE, 17, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + void(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, ARG17_TYPE arg17); \ + void(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, ARG17_TYPE arg17); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, ARG17_TYPE arg17); \ + +#define DEFINE_FAKE_VOID_FUNC18(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, ARG17_TYPE arg17){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + SAVE_ARG(FUNCNAME, 5); \ + SAVE_ARG(FUNCNAME, 6); \ + SAVE_ARG(FUNCNAME, 7); \ + SAVE_ARG(FUNCNAME, 8); \ + SAVE_ARG(FUNCNAME, 9); \ + SAVE_ARG(FUNCNAME, 10); \ + SAVE_ARG(FUNCNAME, 11); \ + SAVE_ARG(FUNCNAME, 12); \ + SAVE_ARG(FUNCNAME, 13); \ + SAVE_ARG(FUNCNAME, 14); \ + SAVE_ARG(FUNCNAME, 15); \ + SAVE_ARG(FUNCNAME, 16); \ + SAVE_ARG(FUNCNAME, 17); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + SAVE_ARG_HISTORY(FUNCNAME, 5); \ + SAVE_ARG_HISTORY(FUNCNAME, 6); \ + SAVE_ARG_HISTORY(FUNCNAME, 7); \ + SAVE_ARG_HISTORY(FUNCNAME, 8); \ + SAVE_ARG_HISTORY(FUNCNAME, 9); \ + SAVE_ARG_HISTORY(FUNCNAME, 10); \ + SAVE_ARG_HISTORY(FUNCNAME, 11); \ + SAVE_ARG_HISTORY(FUNCNAME, 12); \ + SAVE_ARG_HISTORY(FUNCNAME, 13); \ + SAVE_ARG_HISTORY(FUNCNAME, 14); \ + SAVE_ARG_HISTORY(FUNCNAME, 15); \ + SAVE_ARG_HISTORY(FUNCNAME, 16); \ + SAVE_ARG_HISTORY(FUNCNAME, 17); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16, arg17); \ + } \ + else{ \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16, arg17); \ + } \ + } \ + if (FUNCNAME##_fake.custom_fake){ \ + FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16, arg17); \ + } \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VOID_FUNC18(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE) \ + DECLARE_FAKE_VOID_FUNC18(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE) \ + DEFINE_FAKE_VOID_FUNC18(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE) \ + + +#define DECLARE_FAKE_VOID_FUNC19(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ARG18_TYPE) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \ + DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \ + DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \ + DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME) \ + DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME) \ + DECLARE_ARG(ARG10_TYPE, 10, FUNCNAME) \ + DECLARE_ARG(ARG11_TYPE, 11, FUNCNAME) \ + DECLARE_ARG(ARG12_TYPE, 12, FUNCNAME) \ + DECLARE_ARG(ARG13_TYPE, 13, FUNCNAME) \ + DECLARE_ARG(ARG14_TYPE, 14, FUNCNAME) \ + DECLARE_ARG(ARG15_TYPE, 15, FUNCNAME) \ + DECLARE_ARG(ARG16_TYPE, 16, FUNCNAME) \ + DECLARE_ARG(ARG17_TYPE, 17, FUNCNAME) \ + DECLARE_ARG(ARG18_TYPE, 18, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + void(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, ARG17_TYPE arg17, ARG18_TYPE arg18); \ + void(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, ARG17_TYPE arg17, ARG18_TYPE arg18); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, ARG17_TYPE arg17, ARG18_TYPE arg18); \ + +#define DEFINE_FAKE_VOID_FUNC19(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ARG18_TYPE) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, ARG17_TYPE arg17, ARG18_TYPE arg18){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + SAVE_ARG(FUNCNAME, 5); \ + SAVE_ARG(FUNCNAME, 6); \ + SAVE_ARG(FUNCNAME, 7); \ + SAVE_ARG(FUNCNAME, 8); \ + SAVE_ARG(FUNCNAME, 9); \ + SAVE_ARG(FUNCNAME, 10); \ + SAVE_ARG(FUNCNAME, 11); \ + SAVE_ARG(FUNCNAME, 12); \ + SAVE_ARG(FUNCNAME, 13); \ + SAVE_ARG(FUNCNAME, 14); \ + SAVE_ARG(FUNCNAME, 15); \ + SAVE_ARG(FUNCNAME, 16); \ + SAVE_ARG(FUNCNAME, 17); \ + SAVE_ARG(FUNCNAME, 18); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + SAVE_ARG_HISTORY(FUNCNAME, 5); \ + SAVE_ARG_HISTORY(FUNCNAME, 6); \ + SAVE_ARG_HISTORY(FUNCNAME, 7); \ + SAVE_ARG_HISTORY(FUNCNAME, 8); \ + SAVE_ARG_HISTORY(FUNCNAME, 9); \ + SAVE_ARG_HISTORY(FUNCNAME, 10); \ + SAVE_ARG_HISTORY(FUNCNAME, 11); \ + SAVE_ARG_HISTORY(FUNCNAME, 12); \ + SAVE_ARG_HISTORY(FUNCNAME, 13); \ + SAVE_ARG_HISTORY(FUNCNAME, 14); \ + SAVE_ARG_HISTORY(FUNCNAME, 15); \ + SAVE_ARG_HISTORY(FUNCNAME, 16); \ + SAVE_ARG_HISTORY(FUNCNAME, 17); \ + SAVE_ARG_HISTORY(FUNCNAME, 18); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16, arg17, arg18); \ + } \ + else{ \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16, arg17, arg18); \ + } \ + } \ + if (FUNCNAME##_fake.custom_fake){ \ + FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16, arg17, arg18); \ + } \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VOID_FUNC19(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ARG18_TYPE) \ + DECLARE_FAKE_VOID_FUNC19(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ARG18_TYPE) \ + DEFINE_FAKE_VOID_FUNC19(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ARG18_TYPE) \ + + +#define DECLARE_FAKE_VOID_FUNC20(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ARG18_TYPE, ARG19_TYPE) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \ + DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \ + DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \ + DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME) \ + DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME) \ + DECLARE_ARG(ARG10_TYPE, 10, FUNCNAME) \ + DECLARE_ARG(ARG11_TYPE, 11, FUNCNAME) \ + DECLARE_ARG(ARG12_TYPE, 12, FUNCNAME) \ + DECLARE_ARG(ARG13_TYPE, 13, FUNCNAME) \ + DECLARE_ARG(ARG14_TYPE, 14, FUNCNAME) \ + DECLARE_ARG(ARG15_TYPE, 15, FUNCNAME) \ + DECLARE_ARG(ARG16_TYPE, 16, FUNCNAME) \ + DECLARE_ARG(ARG17_TYPE, 17, FUNCNAME) \ + DECLARE_ARG(ARG18_TYPE, 18, FUNCNAME) \ + DECLARE_ARG(ARG19_TYPE, 19, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + void(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, ARG17_TYPE arg17, ARG18_TYPE arg18, ARG19_TYPE arg19); \ + void(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, ARG17_TYPE arg17, ARG18_TYPE arg18, ARG19_TYPE arg19); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, ARG17_TYPE arg17, ARG18_TYPE arg18, ARG19_TYPE arg19); \ + +#define DEFINE_FAKE_VOID_FUNC20(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ARG18_TYPE, ARG19_TYPE) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, ARG17_TYPE arg17, ARG18_TYPE arg18, ARG19_TYPE arg19){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + SAVE_ARG(FUNCNAME, 5); \ + SAVE_ARG(FUNCNAME, 6); \ + SAVE_ARG(FUNCNAME, 7); \ + SAVE_ARG(FUNCNAME, 8); \ + SAVE_ARG(FUNCNAME, 9); \ + SAVE_ARG(FUNCNAME, 10); \ + SAVE_ARG(FUNCNAME, 11); \ + SAVE_ARG(FUNCNAME, 12); \ + SAVE_ARG(FUNCNAME, 13); \ + SAVE_ARG(FUNCNAME, 14); \ + SAVE_ARG(FUNCNAME, 15); \ + SAVE_ARG(FUNCNAME, 16); \ + SAVE_ARG(FUNCNAME, 17); \ + SAVE_ARG(FUNCNAME, 18); \ + SAVE_ARG(FUNCNAME, 19); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + SAVE_ARG_HISTORY(FUNCNAME, 5); \ + SAVE_ARG_HISTORY(FUNCNAME, 6); \ + SAVE_ARG_HISTORY(FUNCNAME, 7); \ + SAVE_ARG_HISTORY(FUNCNAME, 8); \ + SAVE_ARG_HISTORY(FUNCNAME, 9); \ + SAVE_ARG_HISTORY(FUNCNAME, 10); \ + SAVE_ARG_HISTORY(FUNCNAME, 11); \ + SAVE_ARG_HISTORY(FUNCNAME, 12); \ + SAVE_ARG_HISTORY(FUNCNAME, 13); \ + SAVE_ARG_HISTORY(FUNCNAME, 14); \ + SAVE_ARG_HISTORY(FUNCNAME, 15); \ + SAVE_ARG_HISTORY(FUNCNAME, 16); \ + SAVE_ARG_HISTORY(FUNCNAME, 17); \ + SAVE_ARG_HISTORY(FUNCNAME, 18); \ + SAVE_ARG_HISTORY(FUNCNAME, 19); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16, arg17, arg18, arg19); \ + } \ + else{ \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16, arg17, arg18, arg19); \ + } \ + } \ + if (FUNCNAME##_fake.custom_fake){ \ + FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16, arg17, arg18, arg19); \ + } \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VOID_FUNC20(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ARG18_TYPE, ARG19_TYPE) \ + DECLARE_FAKE_VOID_FUNC20(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ARG18_TYPE, ARG19_TYPE) \ + DEFINE_FAKE_VOID_FUNC20(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ARG18_TYPE, ARG19_TYPE) \ + + +#define DECLARE_FAKE_VALUE_FUNC0(RETURN_TYPE, FUNCNAME) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE) \ + DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE) \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + RETURN_TYPE(*custom_fake)(void); \ + RETURN_TYPE(**custom_fake_seq)(void); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(void); \ + +#define DEFINE_FAKE_VALUE_FUNC0(RETURN_TYPE, FUNCNAME) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(void){ \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + } \ + else{ \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + return FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](); \ + } \ + } \ + if (FUNCNAME##_fake.custom_fake){ \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake(); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + return FUNCNAME##_fake.custom_fake(); \ + } \ + RETURN_FAKE_RESULT(FUNCNAME) \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VALUE_FUNC0(RETURN_TYPE, FUNCNAME) \ + DECLARE_FAKE_VALUE_FUNC0(RETURN_TYPE, FUNCNAME) \ + DEFINE_FAKE_VALUE_FUNC0(RETURN_TYPE, FUNCNAME) \ + + +#define DECLARE_FAKE_VALUE_FUNC1(RETURN_TYPE, FUNCNAME, ARG0_TYPE) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE) \ + DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE) \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + RETURN_TYPE(*custom_fake)(ARG0_TYPE arg0); \ + RETURN_TYPE(**custom_fake_seq)(ARG0_TYPE arg0); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0); \ + +#define DEFINE_FAKE_VALUE_FUNC1(RETURN_TYPE, FUNCNAME, ARG0_TYPE) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0){ \ + SAVE_ARG(FUNCNAME, 0); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + } \ + else{ \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + return FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0); \ + } \ + } \ + if (FUNCNAME##_fake.custom_fake){ \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake(arg0); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + return FUNCNAME##_fake.custom_fake(arg0); \ + } \ + RETURN_FAKE_RESULT(FUNCNAME) \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VALUE_FUNC1(RETURN_TYPE, FUNCNAME, ARG0_TYPE) \ + DECLARE_FAKE_VALUE_FUNC1(RETURN_TYPE, FUNCNAME, ARG0_TYPE) \ + DEFINE_FAKE_VALUE_FUNC1(RETURN_TYPE, FUNCNAME, ARG0_TYPE) \ + + +#define DECLARE_FAKE_VALUE_FUNC2(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE) \ + DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE) \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + RETURN_TYPE(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1); \ + RETURN_TYPE(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1); \ + +#define DEFINE_FAKE_VALUE_FUNC2(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + } \ + else{ \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + return FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1); \ + } \ + } \ + if (FUNCNAME##_fake.custom_fake){ \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake(arg0, arg1); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + return FUNCNAME##_fake.custom_fake(arg0, arg1); \ + } \ + RETURN_FAKE_RESULT(FUNCNAME) \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VALUE_FUNC2(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE) \ + DECLARE_FAKE_VALUE_FUNC2(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE) \ + DEFINE_FAKE_VALUE_FUNC2(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE) \ + + +#define DECLARE_FAKE_VALUE_FUNC3(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE) \ + DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE) \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + RETURN_TYPE(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2); \ + RETURN_TYPE(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2); \ + +#define DEFINE_FAKE_VALUE_FUNC3(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + } \ + else{ \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + return FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2); \ + } \ + } \ + if (FUNCNAME##_fake.custom_fake){ \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake(arg0, arg1, arg2); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + return FUNCNAME##_fake.custom_fake(arg0, arg1, arg2); \ + } \ + RETURN_FAKE_RESULT(FUNCNAME) \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VALUE_FUNC3(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE) \ + DECLARE_FAKE_VALUE_FUNC3(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE) \ + DEFINE_FAKE_VALUE_FUNC3(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE) \ + + +#define DECLARE_FAKE_VALUE_FUNC4(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE) \ + DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE) \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + RETURN_TYPE(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3); \ + RETURN_TYPE(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3); \ + +#define DEFINE_FAKE_VALUE_FUNC4(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + } \ + else{ \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + return FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3); \ + } \ + } \ + if (FUNCNAME##_fake.custom_fake){ \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + return FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3); \ + } \ + RETURN_FAKE_RESULT(FUNCNAME) \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VALUE_FUNC4(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE) \ + DECLARE_FAKE_VALUE_FUNC4(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE) \ + DEFINE_FAKE_VALUE_FUNC4(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE) \ + + +#define DECLARE_FAKE_VALUE_FUNC5(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE) \ + DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE) \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + RETURN_TYPE(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4); \ + RETURN_TYPE(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4); \ + +#define DEFINE_FAKE_VALUE_FUNC5(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + } \ + else{ \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + return FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4); \ + } \ + } \ + if (FUNCNAME##_fake.custom_fake){ \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + return FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4); \ + } \ + RETURN_FAKE_RESULT(FUNCNAME) \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VALUE_FUNC5(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE) \ + DECLARE_FAKE_VALUE_FUNC5(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE) \ + DEFINE_FAKE_VALUE_FUNC5(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE) \ + + +#define DECLARE_FAKE_VALUE_FUNC6(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE) \ + DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE) \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + RETURN_TYPE(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5); \ + RETURN_TYPE(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5); \ + +#define DEFINE_FAKE_VALUE_FUNC6(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + SAVE_ARG(FUNCNAME, 5); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + SAVE_ARG_HISTORY(FUNCNAME, 5); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + } \ + else{ \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + return FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5); \ + } \ + } \ + if (FUNCNAME##_fake.custom_fake){ \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + return FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5); \ + } \ + RETURN_FAKE_RESULT(FUNCNAME) \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VALUE_FUNC6(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE) \ + DECLARE_FAKE_VALUE_FUNC6(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE) \ + DEFINE_FAKE_VALUE_FUNC6(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE) \ + + +#define DECLARE_FAKE_VALUE_FUNC7(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \ + DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE) \ + DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE) \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + RETURN_TYPE(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6); \ + RETURN_TYPE(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6); \ + +#define DEFINE_FAKE_VALUE_FUNC7(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + SAVE_ARG(FUNCNAME, 5); \ + SAVE_ARG(FUNCNAME, 6); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + SAVE_ARG_HISTORY(FUNCNAME, 5); \ + SAVE_ARG_HISTORY(FUNCNAME, 6); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + } \ + else{ \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + return FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6); \ + } \ + } \ + if (FUNCNAME##_fake.custom_fake){ \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + return FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6); \ + } \ + RETURN_FAKE_RESULT(FUNCNAME) \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VALUE_FUNC7(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE) \ + DECLARE_FAKE_VALUE_FUNC7(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE) \ + DEFINE_FAKE_VALUE_FUNC7(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE) \ + + +#define DECLARE_FAKE_VALUE_FUNC8(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \ + DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \ + DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE) \ + DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE) \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + RETURN_TYPE(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7); \ + RETURN_TYPE(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7); \ + +#define DEFINE_FAKE_VALUE_FUNC8(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + SAVE_ARG(FUNCNAME, 5); \ + SAVE_ARG(FUNCNAME, 6); \ + SAVE_ARG(FUNCNAME, 7); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + SAVE_ARG_HISTORY(FUNCNAME, 5); \ + SAVE_ARG_HISTORY(FUNCNAME, 6); \ + SAVE_ARG_HISTORY(FUNCNAME, 7); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + } \ + else{ \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + return FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7); \ + } \ + } \ + if (FUNCNAME##_fake.custom_fake){ \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + return FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7); \ + } \ + RETURN_FAKE_RESULT(FUNCNAME) \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VALUE_FUNC8(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE) \ + DECLARE_FAKE_VALUE_FUNC8(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE) \ + DEFINE_FAKE_VALUE_FUNC8(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE) \ + + +#define DECLARE_FAKE_VALUE_FUNC9(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \ + DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \ + DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \ + DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE) \ + DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE) \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + RETURN_TYPE(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8); \ + RETURN_TYPE(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8); \ + +#define DEFINE_FAKE_VALUE_FUNC9(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + SAVE_ARG(FUNCNAME, 5); \ + SAVE_ARG(FUNCNAME, 6); \ + SAVE_ARG(FUNCNAME, 7); \ + SAVE_ARG(FUNCNAME, 8); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + SAVE_ARG_HISTORY(FUNCNAME, 5); \ + SAVE_ARG_HISTORY(FUNCNAME, 6); \ + SAVE_ARG_HISTORY(FUNCNAME, 7); \ + SAVE_ARG_HISTORY(FUNCNAME, 8); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + } \ + else{ \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + return FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); \ + } \ + } \ + if (FUNCNAME##_fake.custom_fake){ \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + return FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); \ + } \ + RETURN_FAKE_RESULT(FUNCNAME) \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VALUE_FUNC9(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE) \ + DECLARE_FAKE_VALUE_FUNC9(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE) \ + DEFINE_FAKE_VALUE_FUNC9(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE) \ + + +#define DECLARE_FAKE_VALUE_FUNC10(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \ + DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \ + DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \ + DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME) \ + DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE) \ + DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE) \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + RETURN_TYPE(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9); \ + RETURN_TYPE(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9); \ + +#define DEFINE_FAKE_VALUE_FUNC10(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + SAVE_ARG(FUNCNAME, 5); \ + SAVE_ARG(FUNCNAME, 6); \ + SAVE_ARG(FUNCNAME, 7); \ + SAVE_ARG(FUNCNAME, 8); \ + SAVE_ARG(FUNCNAME, 9); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + SAVE_ARG_HISTORY(FUNCNAME, 5); \ + SAVE_ARG_HISTORY(FUNCNAME, 6); \ + SAVE_ARG_HISTORY(FUNCNAME, 7); \ + SAVE_ARG_HISTORY(FUNCNAME, 8); \ + SAVE_ARG_HISTORY(FUNCNAME, 9); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + } \ + else{ \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + return FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); \ + } \ + } \ + if (FUNCNAME##_fake.custom_fake){ \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + return FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); \ + } \ + RETURN_FAKE_RESULT(FUNCNAME) \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VALUE_FUNC10(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE) \ + DECLARE_FAKE_VALUE_FUNC10(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE) \ + DEFINE_FAKE_VALUE_FUNC10(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE) \ + + +#define DECLARE_FAKE_VALUE_FUNC11(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \ + DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \ + DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \ + DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME) \ + DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME) \ + DECLARE_ARG(ARG10_TYPE, 10, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE) \ + DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE) \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + RETURN_TYPE(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10); \ + RETURN_TYPE(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10); \ + +#define DEFINE_FAKE_VALUE_FUNC11(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + SAVE_ARG(FUNCNAME, 5); \ + SAVE_ARG(FUNCNAME, 6); \ + SAVE_ARG(FUNCNAME, 7); \ + SAVE_ARG(FUNCNAME, 8); \ + SAVE_ARG(FUNCNAME, 9); \ + SAVE_ARG(FUNCNAME, 10); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + SAVE_ARG_HISTORY(FUNCNAME, 5); \ + SAVE_ARG_HISTORY(FUNCNAME, 6); \ + SAVE_ARG_HISTORY(FUNCNAME, 7); \ + SAVE_ARG_HISTORY(FUNCNAME, 8); \ + SAVE_ARG_HISTORY(FUNCNAME, 9); \ + SAVE_ARG_HISTORY(FUNCNAME, 10); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + } \ + else{ \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + return FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10); \ + } \ + } \ + if (FUNCNAME##_fake.custom_fake){ \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + return FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10); \ + } \ + RETURN_FAKE_RESULT(FUNCNAME) \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VALUE_FUNC11(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE) \ + DECLARE_FAKE_VALUE_FUNC11(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE) \ + DEFINE_FAKE_VALUE_FUNC11(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE) \ + + +#define DECLARE_FAKE_VALUE_FUNC12(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \ + DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \ + DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \ + DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME) \ + DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME) \ + DECLARE_ARG(ARG10_TYPE, 10, FUNCNAME) \ + DECLARE_ARG(ARG11_TYPE, 11, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE) \ + DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE) \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + RETURN_TYPE(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11); \ + RETURN_TYPE(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11); \ + +#define DEFINE_FAKE_VALUE_FUNC12(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + SAVE_ARG(FUNCNAME, 5); \ + SAVE_ARG(FUNCNAME, 6); \ + SAVE_ARG(FUNCNAME, 7); \ + SAVE_ARG(FUNCNAME, 8); \ + SAVE_ARG(FUNCNAME, 9); \ + SAVE_ARG(FUNCNAME, 10); \ + SAVE_ARG(FUNCNAME, 11); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + SAVE_ARG_HISTORY(FUNCNAME, 5); \ + SAVE_ARG_HISTORY(FUNCNAME, 6); \ + SAVE_ARG_HISTORY(FUNCNAME, 7); \ + SAVE_ARG_HISTORY(FUNCNAME, 8); \ + SAVE_ARG_HISTORY(FUNCNAME, 9); \ + SAVE_ARG_HISTORY(FUNCNAME, 10); \ + SAVE_ARG_HISTORY(FUNCNAME, 11); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + } \ + else{ \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + return FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11); \ + } \ + } \ + if (FUNCNAME##_fake.custom_fake){ \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + return FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11); \ + } \ + RETURN_FAKE_RESULT(FUNCNAME) \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VALUE_FUNC12(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE) \ + DECLARE_FAKE_VALUE_FUNC12(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE) \ + DEFINE_FAKE_VALUE_FUNC12(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE) \ + + +#define DECLARE_FAKE_VALUE_FUNC13(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \ + DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \ + DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \ + DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME) \ + DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME) \ + DECLARE_ARG(ARG10_TYPE, 10, FUNCNAME) \ + DECLARE_ARG(ARG11_TYPE, 11, FUNCNAME) \ + DECLARE_ARG(ARG12_TYPE, 12, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE) \ + DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE) \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + RETURN_TYPE(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12); \ + RETURN_TYPE(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12); \ + +#define DEFINE_FAKE_VALUE_FUNC13(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + SAVE_ARG(FUNCNAME, 5); \ + SAVE_ARG(FUNCNAME, 6); \ + SAVE_ARG(FUNCNAME, 7); \ + SAVE_ARG(FUNCNAME, 8); \ + SAVE_ARG(FUNCNAME, 9); \ + SAVE_ARG(FUNCNAME, 10); \ + SAVE_ARG(FUNCNAME, 11); \ + SAVE_ARG(FUNCNAME, 12); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + SAVE_ARG_HISTORY(FUNCNAME, 5); \ + SAVE_ARG_HISTORY(FUNCNAME, 6); \ + SAVE_ARG_HISTORY(FUNCNAME, 7); \ + SAVE_ARG_HISTORY(FUNCNAME, 8); \ + SAVE_ARG_HISTORY(FUNCNAME, 9); \ + SAVE_ARG_HISTORY(FUNCNAME, 10); \ + SAVE_ARG_HISTORY(FUNCNAME, 11); \ + SAVE_ARG_HISTORY(FUNCNAME, 12); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + } \ + else{ \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + return FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12); \ + } \ + } \ + if (FUNCNAME##_fake.custom_fake){ \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + return FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12); \ + } \ + RETURN_FAKE_RESULT(FUNCNAME) \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VALUE_FUNC13(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE) \ + DECLARE_FAKE_VALUE_FUNC13(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE) \ + DEFINE_FAKE_VALUE_FUNC13(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE) \ + + +#define DECLARE_FAKE_VALUE_FUNC14(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \ + DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \ + DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \ + DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME) \ + DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME) \ + DECLARE_ARG(ARG10_TYPE, 10, FUNCNAME) \ + DECLARE_ARG(ARG11_TYPE, 11, FUNCNAME) \ + DECLARE_ARG(ARG12_TYPE, 12, FUNCNAME) \ + DECLARE_ARG(ARG13_TYPE, 13, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE) \ + DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE) \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + RETURN_TYPE(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13); \ + RETURN_TYPE(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13); \ + +#define DEFINE_FAKE_VALUE_FUNC14(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + SAVE_ARG(FUNCNAME, 5); \ + SAVE_ARG(FUNCNAME, 6); \ + SAVE_ARG(FUNCNAME, 7); \ + SAVE_ARG(FUNCNAME, 8); \ + SAVE_ARG(FUNCNAME, 9); \ + SAVE_ARG(FUNCNAME, 10); \ + SAVE_ARG(FUNCNAME, 11); \ + SAVE_ARG(FUNCNAME, 12); \ + SAVE_ARG(FUNCNAME, 13); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + SAVE_ARG_HISTORY(FUNCNAME, 5); \ + SAVE_ARG_HISTORY(FUNCNAME, 6); \ + SAVE_ARG_HISTORY(FUNCNAME, 7); \ + SAVE_ARG_HISTORY(FUNCNAME, 8); \ + SAVE_ARG_HISTORY(FUNCNAME, 9); \ + SAVE_ARG_HISTORY(FUNCNAME, 10); \ + SAVE_ARG_HISTORY(FUNCNAME, 11); \ + SAVE_ARG_HISTORY(FUNCNAME, 12); \ + SAVE_ARG_HISTORY(FUNCNAME, 13); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + } \ + else{ \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + return FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13); \ + } \ + } \ + if (FUNCNAME##_fake.custom_fake){ \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + return FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13); \ + } \ + RETURN_FAKE_RESULT(FUNCNAME) \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VALUE_FUNC14(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE) \ + DECLARE_FAKE_VALUE_FUNC14(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE) \ + DEFINE_FAKE_VALUE_FUNC14(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE) \ + + +#define DECLARE_FAKE_VALUE_FUNC15(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \ + DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \ + DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \ + DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME) \ + DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME) \ + DECLARE_ARG(ARG10_TYPE, 10, FUNCNAME) \ + DECLARE_ARG(ARG11_TYPE, 11, FUNCNAME) \ + DECLARE_ARG(ARG12_TYPE, 12, FUNCNAME) \ + DECLARE_ARG(ARG13_TYPE, 13, FUNCNAME) \ + DECLARE_ARG(ARG14_TYPE, 14, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE) \ + DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE) \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + RETURN_TYPE(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14); \ + RETURN_TYPE(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14); \ + +#define DEFINE_FAKE_VALUE_FUNC15(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + SAVE_ARG(FUNCNAME, 5); \ + SAVE_ARG(FUNCNAME, 6); \ + SAVE_ARG(FUNCNAME, 7); \ + SAVE_ARG(FUNCNAME, 8); \ + SAVE_ARG(FUNCNAME, 9); \ + SAVE_ARG(FUNCNAME, 10); \ + SAVE_ARG(FUNCNAME, 11); \ + SAVE_ARG(FUNCNAME, 12); \ + SAVE_ARG(FUNCNAME, 13); \ + SAVE_ARG(FUNCNAME, 14); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + SAVE_ARG_HISTORY(FUNCNAME, 5); \ + SAVE_ARG_HISTORY(FUNCNAME, 6); \ + SAVE_ARG_HISTORY(FUNCNAME, 7); \ + SAVE_ARG_HISTORY(FUNCNAME, 8); \ + SAVE_ARG_HISTORY(FUNCNAME, 9); \ + SAVE_ARG_HISTORY(FUNCNAME, 10); \ + SAVE_ARG_HISTORY(FUNCNAME, 11); \ + SAVE_ARG_HISTORY(FUNCNAME, 12); \ + SAVE_ARG_HISTORY(FUNCNAME, 13); \ + SAVE_ARG_HISTORY(FUNCNAME, 14); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + } \ + else{ \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + return FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14); \ + } \ + } \ + if (FUNCNAME##_fake.custom_fake){ \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + return FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14); \ + } \ + RETURN_FAKE_RESULT(FUNCNAME) \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VALUE_FUNC15(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE) \ + DECLARE_FAKE_VALUE_FUNC15(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE) \ + DEFINE_FAKE_VALUE_FUNC15(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE) \ + + +#define DECLARE_FAKE_VALUE_FUNC16(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \ + DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \ + DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \ + DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME) \ + DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME) \ + DECLARE_ARG(ARG10_TYPE, 10, FUNCNAME) \ + DECLARE_ARG(ARG11_TYPE, 11, FUNCNAME) \ + DECLARE_ARG(ARG12_TYPE, 12, FUNCNAME) \ + DECLARE_ARG(ARG13_TYPE, 13, FUNCNAME) \ + DECLARE_ARG(ARG14_TYPE, 14, FUNCNAME) \ + DECLARE_ARG(ARG15_TYPE, 15, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE) \ + DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE) \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + RETURN_TYPE(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15); \ + RETURN_TYPE(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15); \ + +#define DEFINE_FAKE_VALUE_FUNC16(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + SAVE_ARG(FUNCNAME, 5); \ + SAVE_ARG(FUNCNAME, 6); \ + SAVE_ARG(FUNCNAME, 7); \ + SAVE_ARG(FUNCNAME, 8); \ + SAVE_ARG(FUNCNAME, 9); \ + SAVE_ARG(FUNCNAME, 10); \ + SAVE_ARG(FUNCNAME, 11); \ + SAVE_ARG(FUNCNAME, 12); \ + SAVE_ARG(FUNCNAME, 13); \ + SAVE_ARG(FUNCNAME, 14); \ + SAVE_ARG(FUNCNAME, 15); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + SAVE_ARG_HISTORY(FUNCNAME, 5); \ + SAVE_ARG_HISTORY(FUNCNAME, 6); \ + SAVE_ARG_HISTORY(FUNCNAME, 7); \ + SAVE_ARG_HISTORY(FUNCNAME, 8); \ + SAVE_ARG_HISTORY(FUNCNAME, 9); \ + SAVE_ARG_HISTORY(FUNCNAME, 10); \ + SAVE_ARG_HISTORY(FUNCNAME, 11); \ + SAVE_ARG_HISTORY(FUNCNAME, 12); \ + SAVE_ARG_HISTORY(FUNCNAME, 13); \ + SAVE_ARG_HISTORY(FUNCNAME, 14); \ + SAVE_ARG_HISTORY(FUNCNAME, 15); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + } \ + else{ \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + return FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15); \ + } \ + } \ + if (FUNCNAME##_fake.custom_fake){ \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + return FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15); \ + } \ + RETURN_FAKE_RESULT(FUNCNAME) \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VALUE_FUNC16(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE) \ + DECLARE_FAKE_VALUE_FUNC16(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE) \ + DEFINE_FAKE_VALUE_FUNC16(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE) \ + + +#define DECLARE_FAKE_VALUE_FUNC17(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \ + DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \ + DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \ + DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME) \ + DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME) \ + DECLARE_ARG(ARG10_TYPE, 10, FUNCNAME) \ + DECLARE_ARG(ARG11_TYPE, 11, FUNCNAME) \ + DECLARE_ARG(ARG12_TYPE, 12, FUNCNAME) \ + DECLARE_ARG(ARG13_TYPE, 13, FUNCNAME) \ + DECLARE_ARG(ARG14_TYPE, 14, FUNCNAME) \ + DECLARE_ARG(ARG15_TYPE, 15, FUNCNAME) \ + DECLARE_ARG(ARG16_TYPE, 16, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE) \ + DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE) \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + RETURN_TYPE(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16); \ + RETURN_TYPE(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16); \ + +#define DEFINE_FAKE_VALUE_FUNC17(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + SAVE_ARG(FUNCNAME, 5); \ + SAVE_ARG(FUNCNAME, 6); \ + SAVE_ARG(FUNCNAME, 7); \ + SAVE_ARG(FUNCNAME, 8); \ + SAVE_ARG(FUNCNAME, 9); \ + SAVE_ARG(FUNCNAME, 10); \ + SAVE_ARG(FUNCNAME, 11); \ + SAVE_ARG(FUNCNAME, 12); \ + SAVE_ARG(FUNCNAME, 13); \ + SAVE_ARG(FUNCNAME, 14); \ + SAVE_ARG(FUNCNAME, 15); \ + SAVE_ARG(FUNCNAME, 16); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + SAVE_ARG_HISTORY(FUNCNAME, 5); \ + SAVE_ARG_HISTORY(FUNCNAME, 6); \ + SAVE_ARG_HISTORY(FUNCNAME, 7); \ + SAVE_ARG_HISTORY(FUNCNAME, 8); \ + SAVE_ARG_HISTORY(FUNCNAME, 9); \ + SAVE_ARG_HISTORY(FUNCNAME, 10); \ + SAVE_ARG_HISTORY(FUNCNAME, 11); \ + SAVE_ARG_HISTORY(FUNCNAME, 12); \ + SAVE_ARG_HISTORY(FUNCNAME, 13); \ + SAVE_ARG_HISTORY(FUNCNAME, 14); \ + SAVE_ARG_HISTORY(FUNCNAME, 15); \ + SAVE_ARG_HISTORY(FUNCNAME, 16); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + } \ + else{ \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + return FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16); \ + } \ + } \ + if (FUNCNAME##_fake.custom_fake){ \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + return FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16); \ + } \ + RETURN_FAKE_RESULT(FUNCNAME) \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VALUE_FUNC17(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE) \ + DECLARE_FAKE_VALUE_FUNC17(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE) \ + DEFINE_FAKE_VALUE_FUNC17(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE) \ + + +#define DECLARE_FAKE_VALUE_FUNC18(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \ + DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \ + DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \ + DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME) \ + DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME) \ + DECLARE_ARG(ARG10_TYPE, 10, FUNCNAME) \ + DECLARE_ARG(ARG11_TYPE, 11, FUNCNAME) \ + DECLARE_ARG(ARG12_TYPE, 12, FUNCNAME) \ + DECLARE_ARG(ARG13_TYPE, 13, FUNCNAME) \ + DECLARE_ARG(ARG14_TYPE, 14, FUNCNAME) \ + DECLARE_ARG(ARG15_TYPE, 15, FUNCNAME) \ + DECLARE_ARG(ARG16_TYPE, 16, FUNCNAME) \ + DECLARE_ARG(ARG17_TYPE, 17, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE) \ + DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE) \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + RETURN_TYPE(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, ARG17_TYPE arg17); \ + RETURN_TYPE(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, ARG17_TYPE arg17); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, ARG17_TYPE arg17); \ + +#define DEFINE_FAKE_VALUE_FUNC18(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, ARG17_TYPE arg17){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + SAVE_ARG(FUNCNAME, 5); \ + SAVE_ARG(FUNCNAME, 6); \ + SAVE_ARG(FUNCNAME, 7); \ + SAVE_ARG(FUNCNAME, 8); \ + SAVE_ARG(FUNCNAME, 9); \ + SAVE_ARG(FUNCNAME, 10); \ + SAVE_ARG(FUNCNAME, 11); \ + SAVE_ARG(FUNCNAME, 12); \ + SAVE_ARG(FUNCNAME, 13); \ + SAVE_ARG(FUNCNAME, 14); \ + SAVE_ARG(FUNCNAME, 15); \ + SAVE_ARG(FUNCNAME, 16); \ + SAVE_ARG(FUNCNAME, 17); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + SAVE_ARG_HISTORY(FUNCNAME, 5); \ + SAVE_ARG_HISTORY(FUNCNAME, 6); \ + SAVE_ARG_HISTORY(FUNCNAME, 7); \ + SAVE_ARG_HISTORY(FUNCNAME, 8); \ + SAVE_ARG_HISTORY(FUNCNAME, 9); \ + SAVE_ARG_HISTORY(FUNCNAME, 10); \ + SAVE_ARG_HISTORY(FUNCNAME, 11); \ + SAVE_ARG_HISTORY(FUNCNAME, 12); \ + SAVE_ARG_HISTORY(FUNCNAME, 13); \ + SAVE_ARG_HISTORY(FUNCNAME, 14); \ + SAVE_ARG_HISTORY(FUNCNAME, 15); \ + SAVE_ARG_HISTORY(FUNCNAME, 16); \ + SAVE_ARG_HISTORY(FUNCNAME, 17); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16, arg17); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + } \ + else{ \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16, arg17); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + return FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16, arg17); \ + } \ + } \ + if (FUNCNAME##_fake.custom_fake){ \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16, arg17); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + return FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16, arg17); \ + } \ + RETURN_FAKE_RESULT(FUNCNAME) \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VALUE_FUNC18(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE) \ + DECLARE_FAKE_VALUE_FUNC18(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE) \ + DEFINE_FAKE_VALUE_FUNC18(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE) \ + + +#define DECLARE_FAKE_VALUE_FUNC19(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ARG18_TYPE) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \ + DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \ + DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \ + DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME) \ + DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME) \ + DECLARE_ARG(ARG10_TYPE, 10, FUNCNAME) \ + DECLARE_ARG(ARG11_TYPE, 11, FUNCNAME) \ + DECLARE_ARG(ARG12_TYPE, 12, FUNCNAME) \ + DECLARE_ARG(ARG13_TYPE, 13, FUNCNAME) \ + DECLARE_ARG(ARG14_TYPE, 14, FUNCNAME) \ + DECLARE_ARG(ARG15_TYPE, 15, FUNCNAME) \ + DECLARE_ARG(ARG16_TYPE, 16, FUNCNAME) \ + DECLARE_ARG(ARG17_TYPE, 17, FUNCNAME) \ + DECLARE_ARG(ARG18_TYPE, 18, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE) \ + DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE) \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + RETURN_TYPE(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, ARG17_TYPE arg17, ARG18_TYPE arg18); \ + RETURN_TYPE(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, ARG17_TYPE arg17, ARG18_TYPE arg18); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, ARG17_TYPE arg17, ARG18_TYPE arg18); \ + +#define DEFINE_FAKE_VALUE_FUNC19(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ARG18_TYPE) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, ARG17_TYPE arg17, ARG18_TYPE arg18){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + SAVE_ARG(FUNCNAME, 5); \ + SAVE_ARG(FUNCNAME, 6); \ + SAVE_ARG(FUNCNAME, 7); \ + SAVE_ARG(FUNCNAME, 8); \ + SAVE_ARG(FUNCNAME, 9); \ + SAVE_ARG(FUNCNAME, 10); \ + SAVE_ARG(FUNCNAME, 11); \ + SAVE_ARG(FUNCNAME, 12); \ + SAVE_ARG(FUNCNAME, 13); \ + SAVE_ARG(FUNCNAME, 14); \ + SAVE_ARG(FUNCNAME, 15); \ + SAVE_ARG(FUNCNAME, 16); \ + SAVE_ARG(FUNCNAME, 17); \ + SAVE_ARG(FUNCNAME, 18); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + SAVE_ARG_HISTORY(FUNCNAME, 5); \ + SAVE_ARG_HISTORY(FUNCNAME, 6); \ + SAVE_ARG_HISTORY(FUNCNAME, 7); \ + SAVE_ARG_HISTORY(FUNCNAME, 8); \ + SAVE_ARG_HISTORY(FUNCNAME, 9); \ + SAVE_ARG_HISTORY(FUNCNAME, 10); \ + SAVE_ARG_HISTORY(FUNCNAME, 11); \ + SAVE_ARG_HISTORY(FUNCNAME, 12); \ + SAVE_ARG_HISTORY(FUNCNAME, 13); \ + SAVE_ARG_HISTORY(FUNCNAME, 14); \ + SAVE_ARG_HISTORY(FUNCNAME, 15); \ + SAVE_ARG_HISTORY(FUNCNAME, 16); \ + SAVE_ARG_HISTORY(FUNCNAME, 17); \ + SAVE_ARG_HISTORY(FUNCNAME, 18); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16, arg17, arg18); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + } \ + else{ \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16, arg17, arg18); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + return FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16, arg17, arg18); \ + } \ + } \ + if (FUNCNAME##_fake.custom_fake){ \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16, arg17, arg18); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + return FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16, arg17, arg18); \ + } \ + RETURN_FAKE_RESULT(FUNCNAME) \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VALUE_FUNC19(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ARG18_TYPE) \ + DECLARE_FAKE_VALUE_FUNC19(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ARG18_TYPE) \ + DEFINE_FAKE_VALUE_FUNC19(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ARG18_TYPE) \ + + +#define DECLARE_FAKE_VALUE_FUNC20(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ARG18_TYPE, ARG19_TYPE) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \ + DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \ + DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \ + DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME) \ + DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME) \ + DECLARE_ARG(ARG10_TYPE, 10, FUNCNAME) \ + DECLARE_ARG(ARG11_TYPE, 11, FUNCNAME) \ + DECLARE_ARG(ARG12_TYPE, 12, FUNCNAME) \ + DECLARE_ARG(ARG13_TYPE, 13, FUNCNAME) \ + DECLARE_ARG(ARG14_TYPE, 14, FUNCNAME) \ + DECLARE_ARG(ARG15_TYPE, 15, FUNCNAME) \ + DECLARE_ARG(ARG16_TYPE, 16, FUNCNAME) \ + DECLARE_ARG(ARG17_TYPE, 17, FUNCNAME) \ + DECLARE_ARG(ARG18_TYPE, 18, FUNCNAME) \ + DECLARE_ARG(ARG19_TYPE, 19, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE) \ + DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE) \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + RETURN_TYPE(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, ARG17_TYPE arg17, ARG18_TYPE arg18, ARG19_TYPE arg19); \ + RETURN_TYPE(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, ARG17_TYPE arg17, ARG18_TYPE arg18, ARG19_TYPE arg19); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, ARG17_TYPE arg17, ARG18_TYPE arg18, ARG19_TYPE arg19); \ + +#define DEFINE_FAKE_VALUE_FUNC20(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ARG18_TYPE, ARG19_TYPE) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, ARG17_TYPE arg17, ARG18_TYPE arg18, ARG19_TYPE arg19){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + SAVE_ARG(FUNCNAME, 5); \ + SAVE_ARG(FUNCNAME, 6); \ + SAVE_ARG(FUNCNAME, 7); \ + SAVE_ARG(FUNCNAME, 8); \ + SAVE_ARG(FUNCNAME, 9); \ + SAVE_ARG(FUNCNAME, 10); \ + SAVE_ARG(FUNCNAME, 11); \ + SAVE_ARG(FUNCNAME, 12); \ + SAVE_ARG(FUNCNAME, 13); \ + SAVE_ARG(FUNCNAME, 14); \ + SAVE_ARG(FUNCNAME, 15); \ + SAVE_ARG(FUNCNAME, 16); \ + SAVE_ARG(FUNCNAME, 17); \ + SAVE_ARG(FUNCNAME, 18); \ + SAVE_ARG(FUNCNAME, 19); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + SAVE_ARG_HISTORY(FUNCNAME, 5); \ + SAVE_ARG_HISTORY(FUNCNAME, 6); \ + SAVE_ARG_HISTORY(FUNCNAME, 7); \ + SAVE_ARG_HISTORY(FUNCNAME, 8); \ + SAVE_ARG_HISTORY(FUNCNAME, 9); \ + SAVE_ARG_HISTORY(FUNCNAME, 10); \ + SAVE_ARG_HISTORY(FUNCNAME, 11); \ + SAVE_ARG_HISTORY(FUNCNAME, 12); \ + SAVE_ARG_HISTORY(FUNCNAME, 13); \ + SAVE_ARG_HISTORY(FUNCNAME, 14); \ + SAVE_ARG_HISTORY(FUNCNAME, 15); \ + SAVE_ARG_HISTORY(FUNCNAME, 16); \ + SAVE_ARG_HISTORY(FUNCNAME, 17); \ + SAVE_ARG_HISTORY(FUNCNAME, 18); \ + SAVE_ARG_HISTORY(FUNCNAME, 19); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16, arg17, arg18, arg19); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + } \ + else{ \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16, arg17, arg18, arg19); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + return FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16, arg17, arg18, arg19); \ + } \ + } \ + if (FUNCNAME##_fake.custom_fake){ \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16, arg17, arg18, arg19); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + return FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16, arg17, arg18, arg19); \ + } \ + RETURN_FAKE_RESULT(FUNCNAME) \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VALUE_FUNC20(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ARG18_TYPE, ARG19_TYPE) \ + DECLARE_FAKE_VALUE_FUNC20(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ARG18_TYPE, ARG19_TYPE) \ + DEFINE_FAKE_VALUE_FUNC20(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ARG18_TYPE, ARG19_TYPE) \ + + +#define DECLARE_FAKE_VOID_FUNC2_VARARG(FUNCNAME, ARG0_TYPE, ...) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + void(*custom_fake)(ARG0_TYPE arg0, va_list ap); \ + void(**custom_fake_seq)(ARG0_TYPE arg0, va_list ap); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ...); \ + +#define DEFINE_FAKE_VOID_FUNC2_VARARG(FUNCNAME, ARG0_TYPE, ...) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ...){ \ + SAVE_ARG(FUNCNAME, 0); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + va_list ap; \ + va_start(ap, arg0); \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, ap); \ + va_end(ap); \ + } \ + else{ \ + va_list ap; \ + va_start(ap, arg0); \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, ap); \ + va_end(ap); \ + } \ + } \ + if(FUNCNAME##_fake.custom_fake){ \ + va_list ap; \ + va_start(ap, arg0); \ + FUNCNAME##_fake.custom_fake(arg0, ap); \ + va_end(ap); \ + } \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VOID_FUNC2_VARARG(FUNCNAME, ARG0_TYPE, ...) \ + DECLARE_FAKE_VOID_FUNC2_VARARG(FUNCNAME, ARG0_TYPE, ...) \ + DEFINE_FAKE_VOID_FUNC2_VARARG(FUNCNAME, ARG0_TYPE, ...) \ + + +#define DECLARE_FAKE_VOID_FUNC3_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ...) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + void(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, va_list ap); \ + void(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, va_list ap); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ...); \ + +#define DEFINE_FAKE_VOID_FUNC3_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ...) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ...){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + va_list ap; \ + va_start(ap, arg1); \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, ap); \ + va_end(ap); \ + } \ + else{ \ + va_list ap; \ + va_start(ap, arg1); \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, ap); \ + va_end(ap); \ + } \ + } \ + if(FUNCNAME##_fake.custom_fake){ \ + va_list ap; \ + va_start(ap, arg1); \ + FUNCNAME##_fake.custom_fake(arg0, arg1, ap); \ + va_end(ap); \ + } \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VOID_FUNC3_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ...) \ + DECLARE_FAKE_VOID_FUNC3_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ...) \ + DEFINE_FAKE_VOID_FUNC3_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ...) \ + + +#define DECLARE_FAKE_VOID_FUNC4_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ...) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + void(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, va_list ap); \ + void(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, va_list ap); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ...); \ + +#define DEFINE_FAKE_VOID_FUNC4_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ...) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ...){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + va_list ap; \ + va_start(ap, arg2); \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, ap); \ + va_end(ap); \ + } \ + else{ \ + va_list ap; \ + va_start(ap, arg2); \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, ap); \ + va_end(ap); \ + } \ + } \ + if(FUNCNAME##_fake.custom_fake){ \ + va_list ap; \ + va_start(ap, arg2); \ + FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, ap); \ + va_end(ap); \ + } \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VOID_FUNC4_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ...) \ + DECLARE_FAKE_VOID_FUNC4_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ...) \ + DEFINE_FAKE_VOID_FUNC4_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ...) \ + + +#define DECLARE_FAKE_VOID_FUNC5_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ...) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + void(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, va_list ap); \ + void(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, va_list ap); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ...); \ + +#define DEFINE_FAKE_VOID_FUNC5_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ...) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ...){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + va_list ap; \ + va_start(ap, arg3); \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, ap); \ + va_end(ap); \ + } \ + else{ \ + va_list ap; \ + va_start(ap, arg3); \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, ap); \ + va_end(ap); \ + } \ + } \ + if(FUNCNAME##_fake.custom_fake){ \ + va_list ap; \ + va_start(ap, arg3); \ + FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, ap); \ + va_end(ap); \ + } \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VOID_FUNC5_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ...) \ + DECLARE_FAKE_VOID_FUNC5_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ...) \ + DEFINE_FAKE_VOID_FUNC5_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ...) \ + + +#define DECLARE_FAKE_VOID_FUNC6_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ...) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + void(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, va_list ap); \ + void(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, va_list ap); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ...); \ + +#define DEFINE_FAKE_VOID_FUNC6_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ...) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ...){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + va_list ap; \ + va_start(ap, arg4); \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, ap); \ + va_end(ap); \ + } \ + else{ \ + va_list ap; \ + va_start(ap, arg4); \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, ap); \ + va_end(ap); \ + } \ + } \ + if(FUNCNAME##_fake.custom_fake){ \ + va_list ap; \ + va_start(ap, arg4); \ + FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, ap); \ + va_end(ap); \ + } \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VOID_FUNC6_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ...) \ + DECLARE_FAKE_VOID_FUNC6_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ...) \ + DEFINE_FAKE_VOID_FUNC6_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ...) \ + + +#define DECLARE_FAKE_VOID_FUNC7_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ...) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + void(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, va_list ap); \ + void(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, va_list ap); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ...); \ + +#define DEFINE_FAKE_VOID_FUNC7_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ...) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ...){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + SAVE_ARG(FUNCNAME, 5); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + SAVE_ARG_HISTORY(FUNCNAME, 5); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + va_list ap; \ + va_start(ap, arg5); \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, ap); \ + va_end(ap); \ + } \ + else{ \ + va_list ap; \ + va_start(ap, arg5); \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, ap); \ + va_end(ap); \ + } \ + } \ + if(FUNCNAME##_fake.custom_fake){ \ + va_list ap; \ + va_start(ap, arg5); \ + FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, ap); \ + va_end(ap); \ + } \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VOID_FUNC7_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ...) \ + DECLARE_FAKE_VOID_FUNC7_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ...) \ + DEFINE_FAKE_VOID_FUNC7_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ...) \ + + +#define DECLARE_FAKE_VOID_FUNC8_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ...) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \ + DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + void(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, va_list ap); \ + void(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, va_list ap); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ...); \ + +#define DEFINE_FAKE_VOID_FUNC8_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ...) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ...){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + SAVE_ARG(FUNCNAME, 5); \ + SAVE_ARG(FUNCNAME, 6); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + SAVE_ARG_HISTORY(FUNCNAME, 5); \ + SAVE_ARG_HISTORY(FUNCNAME, 6); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + va_list ap; \ + va_start(ap, arg6); \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6, ap); \ + va_end(ap); \ + } \ + else{ \ + va_list ap; \ + va_start(ap, arg6); \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, ap); \ + va_end(ap); \ + } \ + } \ + if(FUNCNAME##_fake.custom_fake){ \ + va_list ap; \ + va_start(ap, arg6); \ + FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, ap); \ + va_end(ap); \ + } \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VOID_FUNC8_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ...) \ + DECLARE_FAKE_VOID_FUNC8_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ...) \ + DEFINE_FAKE_VOID_FUNC8_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ...) \ + + +#define DECLARE_FAKE_VOID_FUNC9_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ...) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \ + DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \ + DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + void(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, va_list ap); \ + void(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, va_list ap); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ...); \ + +#define DEFINE_FAKE_VOID_FUNC9_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ...) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ...){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + SAVE_ARG(FUNCNAME, 5); \ + SAVE_ARG(FUNCNAME, 6); \ + SAVE_ARG(FUNCNAME, 7); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + SAVE_ARG_HISTORY(FUNCNAME, 5); \ + SAVE_ARG_HISTORY(FUNCNAME, 6); \ + SAVE_ARG_HISTORY(FUNCNAME, 7); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + va_list ap; \ + va_start(ap, arg7); \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, ap); \ + va_end(ap); \ + } \ + else{ \ + va_list ap; \ + va_start(ap, arg7); \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, ap); \ + va_end(ap); \ + } \ + } \ + if(FUNCNAME##_fake.custom_fake){ \ + va_list ap; \ + va_start(ap, arg7); \ + FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, ap); \ + va_end(ap); \ + } \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VOID_FUNC9_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ...) \ + DECLARE_FAKE_VOID_FUNC9_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ...) \ + DEFINE_FAKE_VOID_FUNC9_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ...) \ + + +#define DECLARE_FAKE_VOID_FUNC10_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ...) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \ + DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \ + DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \ + DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + void(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, va_list ap); \ + void(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, va_list ap); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ...); \ + +#define DEFINE_FAKE_VOID_FUNC10_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ...) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ...){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + SAVE_ARG(FUNCNAME, 5); \ + SAVE_ARG(FUNCNAME, 6); \ + SAVE_ARG(FUNCNAME, 7); \ + SAVE_ARG(FUNCNAME, 8); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + SAVE_ARG_HISTORY(FUNCNAME, 5); \ + SAVE_ARG_HISTORY(FUNCNAME, 6); \ + SAVE_ARG_HISTORY(FUNCNAME, 7); \ + SAVE_ARG_HISTORY(FUNCNAME, 8); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + va_list ap; \ + va_start(ap, arg8); \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, ap); \ + va_end(ap); \ + } \ + else{ \ + va_list ap; \ + va_start(ap, arg8); \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, ap); \ + va_end(ap); \ + } \ + } \ + if(FUNCNAME##_fake.custom_fake){ \ + va_list ap; \ + va_start(ap, arg8); \ + FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, ap); \ + va_end(ap); \ + } \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VOID_FUNC10_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ...) \ + DECLARE_FAKE_VOID_FUNC10_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ...) \ + DEFINE_FAKE_VOID_FUNC10_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ...) \ + + +#define DECLARE_FAKE_VOID_FUNC11_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ...) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \ + DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \ + DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \ + DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME) \ + DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + void(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, va_list ap); \ + void(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, va_list ap); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ...); \ + +#define DEFINE_FAKE_VOID_FUNC11_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ...) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ...){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + SAVE_ARG(FUNCNAME, 5); \ + SAVE_ARG(FUNCNAME, 6); \ + SAVE_ARG(FUNCNAME, 7); \ + SAVE_ARG(FUNCNAME, 8); \ + SAVE_ARG(FUNCNAME, 9); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + SAVE_ARG_HISTORY(FUNCNAME, 5); \ + SAVE_ARG_HISTORY(FUNCNAME, 6); \ + SAVE_ARG_HISTORY(FUNCNAME, 7); \ + SAVE_ARG_HISTORY(FUNCNAME, 8); \ + SAVE_ARG_HISTORY(FUNCNAME, 9); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + va_list ap; \ + va_start(ap, arg9); \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, ap); \ + va_end(ap); \ + } \ + else{ \ + va_list ap; \ + va_start(ap, arg9); \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, ap); \ + va_end(ap); \ + } \ + } \ + if(FUNCNAME##_fake.custom_fake){ \ + va_list ap; \ + va_start(ap, arg9); \ + FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, ap); \ + va_end(ap); \ + } \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VOID_FUNC11_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ...) \ + DECLARE_FAKE_VOID_FUNC11_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ...) \ + DEFINE_FAKE_VOID_FUNC11_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ...) \ + + +#define DECLARE_FAKE_VOID_FUNC12_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ...) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \ + DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \ + DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \ + DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME) \ + DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME) \ + DECLARE_ARG(ARG10_TYPE, 10, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + void(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, va_list ap); \ + void(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, va_list ap); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ...); \ + +#define DEFINE_FAKE_VOID_FUNC12_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ...) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ...){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + SAVE_ARG(FUNCNAME, 5); \ + SAVE_ARG(FUNCNAME, 6); \ + SAVE_ARG(FUNCNAME, 7); \ + SAVE_ARG(FUNCNAME, 8); \ + SAVE_ARG(FUNCNAME, 9); \ + SAVE_ARG(FUNCNAME, 10); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + SAVE_ARG_HISTORY(FUNCNAME, 5); \ + SAVE_ARG_HISTORY(FUNCNAME, 6); \ + SAVE_ARG_HISTORY(FUNCNAME, 7); \ + SAVE_ARG_HISTORY(FUNCNAME, 8); \ + SAVE_ARG_HISTORY(FUNCNAME, 9); \ + SAVE_ARG_HISTORY(FUNCNAME, 10); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + va_list ap; \ + va_start(ap, arg10); \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, ap); \ + va_end(ap); \ + } \ + else{ \ + va_list ap; \ + va_start(ap, arg10); \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, ap); \ + va_end(ap); \ + } \ + } \ + if(FUNCNAME##_fake.custom_fake){ \ + va_list ap; \ + va_start(ap, arg10); \ + FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, ap); \ + va_end(ap); \ + } \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VOID_FUNC12_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ...) \ + DECLARE_FAKE_VOID_FUNC12_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ...) \ + DEFINE_FAKE_VOID_FUNC12_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ...) \ + + +#define DECLARE_FAKE_VOID_FUNC13_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ...) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \ + DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \ + DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \ + DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME) \ + DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME) \ + DECLARE_ARG(ARG10_TYPE, 10, FUNCNAME) \ + DECLARE_ARG(ARG11_TYPE, 11, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + void(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, va_list ap); \ + void(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, va_list ap); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ...); \ + +#define DEFINE_FAKE_VOID_FUNC13_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ...) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ...){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + SAVE_ARG(FUNCNAME, 5); \ + SAVE_ARG(FUNCNAME, 6); \ + SAVE_ARG(FUNCNAME, 7); \ + SAVE_ARG(FUNCNAME, 8); \ + SAVE_ARG(FUNCNAME, 9); \ + SAVE_ARG(FUNCNAME, 10); \ + SAVE_ARG(FUNCNAME, 11); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + SAVE_ARG_HISTORY(FUNCNAME, 5); \ + SAVE_ARG_HISTORY(FUNCNAME, 6); \ + SAVE_ARG_HISTORY(FUNCNAME, 7); \ + SAVE_ARG_HISTORY(FUNCNAME, 8); \ + SAVE_ARG_HISTORY(FUNCNAME, 9); \ + SAVE_ARG_HISTORY(FUNCNAME, 10); \ + SAVE_ARG_HISTORY(FUNCNAME, 11); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + va_list ap; \ + va_start(ap, arg11); \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, ap); \ + va_end(ap); \ + } \ + else{ \ + va_list ap; \ + va_start(ap, arg11); \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, ap); \ + va_end(ap); \ + } \ + } \ + if(FUNCNAME##_fake.custom_fake){ \ + va_list ap; \ + va_start(ap, arg11); \ + FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, ap); \ + va_end(ap); \ + } \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VOID_FUNC13_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ...) \ + DECLARE_FAKE_VOID_FUNC13_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ...) \ + DEFINE_FAKE_VOID_FUNC13_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ...) \ + + +#define DECLARE_FAKE_VOID_FUNC14_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ...) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \ + DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \ + DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \ + DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME) \ + DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME) \ + DECLARE_ARG(ARG10_TYPE, 10, FUNCNAME) \ + DECLARE_ARG(ARG11_TYPE, 11, FUNCNAME) \ + DECLARE_ARG(ARG12_TYPE, 12, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + void(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, va_list ap); \ + void(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, va_list ap); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ...); \ + +#define DEFINE_FAKE_VOID_FUNC14_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ...) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ...){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + SAVE_ARG(FUNCNAME, 5); \ + SAVE_ARG(FUNCNAME, 6); \ + SAVE_ARG(FUNCNAME, 7); \ + SAVE_ARG(FUNCNAME, 8); \ + SAVE_ARG(FUNCNAME, 9); \ + SAVE_ARG(FUNCNAME, 10); \ + SAVE_ARG(FUNCNAME, 11); \ + SAVE_ARG(FUNCNAME, 12); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + SAVE_ARG_HISTORY(FUNCNAME, 5); \ + SAVE_ARG_HISTORY(FUNCNAME, 6); \ + SAVE_ARG_HISTORY(FUNCNAME, 7); \ + SAVE_ARG_HISTORY(FUNCNAME, 8); \ + SAVE_ARG_HISTORY(FUNCNAME, 9); \ + SAVE_ARG_HISTORY(FUNCNAME, 10); \ + SAVE_ARG_HISTORY(FUNCNAME, 11); \ + SAVE_ARG_HISTORY(FUNCNAME, 12); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + va_list ap; \ + va_start(ap, arg12); \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, ap); \ + va_end(ap); \ + } \ + else{ \ + va_list ap; \ + va_start(ap, arg12); \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, ap); \ + va_end(ap); \ + } \ + } \ + if(FUNCNAME##_fake.custom_fake){ \ + va_list ap; \ + va_start(ap, arg12); \ + FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, ap); \ + va_end(ap); \ + } \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VOID_FUNC14_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ...) \ + DECLARE_FAKE_VOID_FUNC14_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ...) \ + DEFINE_FAKE_VOID_FUNC14_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ...) \ + + +#define DECLARE_FAKE_VOID_FUNC15_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ...) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \ + DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \ + DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \ + DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME) \ + DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME) \ + DECLARE_ARG(ARG10_TYPE, 10, FUNCNAME) \ + DECLARE_ARG(ARG11_TYPE, 11, FUNCNAME) \ + DECLARE_ARG(ARG12_TYPE, 12, FUNCNAME) \ + DECLARE_ARG(ARG13_TYPE, 13, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + void(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, va_list ap); \ + void(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, va_list ap); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ...); \ + +#define DEFINE_FAKE_VOID_FUNC15_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ...) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ...){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + SAVE_ARG(FUNCNAME, 5); \ + SAVE_ARG(FUNCNAME, 6); \ + SAVE_ARG(FUNCNAME, 7); \ + SAVE_ARG(FUNCNAME, 8); \ + SAVE_ARG(FUNCNAME, 9); \ + SAVE_ARG(FUNCNAME, 10); \ + SAVE_ARG(FUNCNAME, 11); \ + SAVE_ARG(FUNCNAME, 12); \ + SAVE_ARG(FUNCNAME, 13); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + SAVE_ARG_HISTORY(FUNCNAME, 5); \ + SAVE_ARG_HISTORY(FUNCNAME, 6); \ + SAVE_ARG_HISTORY(FUNCNAME, 7); \ + SAVE_ARG_HISTORY(FUNCNAME, 8); \ + SAVE_ARG_HISTORY(FUNCNAME, 9); \ + SAVE_ARG_HISTORY(FUNCNAME, 10); \ + SAVE_ARG_HISTORY(FUNCNAME, 11); \ + SAVE_ARG_HISTORY(FUNCNAME, 12); \ + SAVE_ARG_HISTORY(FUNCNAME, 13); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + va_list ap; \ + va_start(ap, arg13); \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, ap); \ + va_end(ap); \ + } \ + else{ \ + va_list ap; \ + va_start(ap, arg13); \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, ap); \ + va_end(ap); \ + } \ + } \ + if(FUNCNAME##_fake.custom_fake){ \ + va_list ap; \ + va_start(ap, arg13); \ + FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, ap); \ + va_end(ap); \ + } \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VOID_FUNC15_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ...) \ + DECLARE_FAKE_VOID_FUNC15_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ...) \ + DEFINE_FAKE_VOID_FUNC15_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ...) \ + + +#define DECLARE_FAKE_VOID_FUNC16_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ...) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \ + DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \ + DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \ + DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME) \ + DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME) \ + DECLARE_ARG(ARG10_TYPE, 10, FUNCNAME) \ + DECLARE_ARG(ARG11_TYPE, 11, FUNCNAME) \ + DECLARE_ARG(ARG12_TYPE, 12, FUNCNAME) \ + DECLARE_ARG(ARG13_TYPE, 13, FUNCNAME) \ + DECLARE_ARG(ARG14_TYPE, 14, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + void(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, va_list ap); \ + void(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, va_list ap); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ...); \ + +#define DEFINE_FAKE_VOID_FUNC16_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ...) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ...){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + SAVE_ARG(FUNCNAME, 5); \ + SAVE_ARG(FUNCNAME, 6); \ + SAVE_ARG(FUNCNAME, 7); \ + SAVE_ARG(FUNCNAME, 8); \ + SAVE_ARG(FUNCNAME, 9); \ + SAVE_ARG(FUNCNAME, 10); \ + SAVE_ARG(FUNCNAME, 11); \ + SAVE_ARG(FUNCNAME, 12); \ + SAVE_ARG(FUNCNAME, 13); \ + SAVE_ARG(FUNCNAME, 14); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + SAVE_ARG_HISTORY(FUNCNAME, 5); \ + SAVE_ARG_HISTORY(FUNCNAME, 6); \ + SAVE_ARG_HISTORY(FUNCNAME, 7); \ + SAVE_ARG_HISTORY(FUNCNAME, 8); \ + SAVE_ARG_HISTORY(FUNCNAME, 9); \ + SAVE_ARG_HISTORY(FUNCNAME, 10); \ + SAVE_ARG_HISTORY(FUNCNAME, 11); \ + SAVE_ARG_HISTORY(FUNCNAME, 12); \ + SAVE_ARG_HISTORY(FUNCNAME, 13); \ + SAVE_ARG_HISTORY(FUNCNAME, 14); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + va_list ap; \ + va_start(ap, arg14); \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, ap); \ + va_end(ap); \ + } \ + else{ \ + va_list ap; \ + va_start(ap, arg14); \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, ap); \ + va_end(ap); \ + } \ + } \ + if(FUNCNAME##_fake.custom_fake){ \ + va_list ap; \ + va_start(ap, arg14); \ + FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, ap); \ + va_end(ap); \ + } \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VOID_FUNC16_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ...) \ + DECLARE_FAKE_VOID_FUNC16_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ...) \ + DEFINE_FAKE_VOID_FUNC16_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ...) \ + + +#define DECLARE_FAKE_VOID_FUNC17_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ...) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \ + DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \ + DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \ + DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME) \ + DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME) \ + DECLARE_ARG(ARG10_TYPE, 10, FUNCNAME) \ + DECLARE_ARG(ARG11_TYPE, 11, FUNCNAME) \ + DECLARE_ARG(ARG12_TYPE, 12, FUNCNAME) \ + DECLARE_ARG(ARG13_TYPE, 13, FUNCNAME) \ + DECLARE_ARG(ARG14_TYPE, 14, FUNCNAME) \ + DECLARE_ARG(ARG15_TYPE, 15, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + void(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, va_list ap); \ + void(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, va_list ap); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ...); \ + +#define DEFINE_FAKE_VOID_FUNC17_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ...) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ...){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + SAVE_ARG(FUNCNAME, 5); \ + SAVE_ARG(FUNCNAME, 6); \ + SAVE_ARG(FUNCNAME, 7); \ + SAVE_ARG(FUNCNAME, 8); \ + SAVE_ARG(FUNCNAME, 9); \ + SAVE_ARG(FUNCNAME, 10); \ + SAVE_ARG(FUNCNAME, 11); \ + SAVE_ARG(FUNCNAME, 12); \ + SAVE_ARG(FUNCNAME, 13); \ + SAVE_ARG(FUNCNAME, 14); \ + SAVE_ARG(FUNCNAME, 15); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + SAVE_ARG_HISTORY(FUNCNAME, 5); \ + SAVE_ARG_HISTORY(FUNCNAME, 6); \ + SAVE_ARG_HISTORY(FUNCNAME, 7); \ + SAVE_ARG_HISTORY(FUNCNAME, 8); \ + SAVE_ARG_HISTORY(FUNCNAME, 9); \ + SAVE_ARG_HISTORY(FUNCNAME, 10); \ + SAVE_ARG_HISTORY(FUNCNAME, 11); \ + SAVE_ARG_HISTORY(FUNCNAME, 12); \ + SAVE_ARG_HISTORY(FUNCNAME, 13); \ + SAVE_ARG_HISTORY(FUNCNAME, 14); \ + SAVE_ARG_HISTORY(FUNCNAME, 15); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + va_list ap; \ + va_start(ap, arg15); \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, ap); \ + va_end(ap); \ + } \ + else{ \ + va_list ap; \ + va_start(ap, arg15); \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, ap); \ + va_end(ap); \ + } \ + } \ + if(FUNCNAME##_fake.custom_fake){ \ + va_list ap; \ + va_start(ap, arg15); \ + FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, ap); \ + va_end(ap); \ + } \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VOID_FUNC17_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ...) \ + DECLARE_FAKE_VOID_FUNC17_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ...) \ + DEFINE_FAKE_VOID_FUNC17_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ...) \ + + +#define DECLARE_FAKE_VOID_FUNC18_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ...) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \ + DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \ + DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \ + DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME) \ + DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME) \ + DECLARE_ARG(ARG10_TYPE, 10, FUNCNAME) \ + DECLARE_ARG(ARG11_TYPE, 11, FUNCNAME) \ + DECLARE_ARG(ARG12_TYPE, 12, FUNCNAME) \ + DECLARE_ARG(ARG13_TYPE, 13, FUNCNAME) \ + DECLARE_ARG(ARG14_TYPE, 14, FUNCNAME) \ + DECLARE_ARG(ARG15_TYPE, 15, FUNCNAME) \ + DECLARE_ARG(ARG16_TYPE, 16, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + void(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, va_list ap); \ + void(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, va_list ap); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, ...); \ + +#define DEFINE_FAKE_VOID_FUNC18_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ...) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, ...){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + SAVE_ARG(FUNCNAME, 5); \ + SAVE_ARG(FUNCNAME, 6); \ + SAVE_ARG(FUNCNAME, 7); \ + SAVE_ARG(FUNCNAME, 8); \ + SAVE_ARG(FUNCNAME, 9); \ + SAVE_ARG(FUNCNAME, 10); \ + SAVE_ARG(FUNCNAME, 11); \ + SAVE_ARG(FUNCNAME, 12); \ + SAVE_ARG(FUNCNAME, 13); \ + SAVE_ARG(FUNCNAME, 14); \ + SAVE_ARG(FUNCNAME, 15); \ + SAVE_ARG(FUNCNAME, 16); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + SAVE_ARG_HISTORY(FUNCNAME, 5); \ + SAVE_ARG_HISTORY(FUNCNAME, 6); \ + SAVE_ARG_HISTORY(FUNCNAME, 7); \ + SAVE_ARG_HISTORY(FUNCNAME, 8); \ + SAVE_ARG_HISTORY(FUNCNAME, 9); \ + SAVE_ARG_HISTORY(FUNCNAME, 10); \ + SAVE_ARG_HISTORY(FUNCNAME, 11); \ + SAVE_ARG_HISTORY(FUNCNAME, 12); \ + SAVE_ARG_HISTORY(FUNCNAME, 13); \ + SAVE_ARG_HISTORY(FUNCNAME, 14); \ + SAVE_ARG_HISTORY(FUNCNAME, 15); \ + SAVE_ARG_HISTORY(FUNCNAME, 16); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + va_list ap; \ + va_start(ap, arg16); \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16, ap); \ + va_end(ap); \ + } \ + else{ \ + va_list ap; \ + va_start(ap, arg16); \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16, ap); \ + va_end(ap); \ + } \ + } \ + if(FUNCNAME##_fake.custom_fake){ \ + va_list ap; \ + va_start(ap, arg16); \ + FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16, ap); \ + va_end(ap); \ + } \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VOID_FUNC18_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ...) \ + DECLARE_FAKE_VOID_FUNC18_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ...) \ + DEFINE_FAKE_VOID_FUNC18_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ...) \ + + +#define DECLARE_FAKE_VOID_FUNC19_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ...) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \ + DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \ + DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \ + DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME) \ + DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME) \ + DECLARE_ARG(ARG10_TYPE, 10, FUNCNAME) \ + DECLARE_ARG(ARG11_TYPE, 11, FUNCNAME) \ + DECLARE_ARG(ARG12_TYPE, 12, FUNCNAME) \ + DECLARE_ARG(ARG13_TYPE, 13, FUNCNAME) \ + DECLARE_ARG(ARG14_TYPE, 14, FUNCNAME) \ + DECLARE_ARG(ARG15_TYPE, 15, FUNCNAME) \ + DECLARE_ARG(ARG16_TYPE, 16, FUNCNAME) \ + DECLARE_ARG(ARG17_TYPE, 17, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + void(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, ARG17_TYPE arg17, va_list ap); \ + void(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, ARG17_TYPE arg17, va_list ap); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, ARG17_TYPE arg17, ...); \ + +#define DEFINE_FAKE_VOID_FUNC19_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ...) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, ARG17_TYPE arg17, ...){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + SAVE_ARG(FUNCNAME, 5); \ + SAVE_ARG(FUNCNAME, 6); \ + SAVE_ARG(FUNCNAME, 7); \ + SAVE_ARG(FUNCNAME, 8); \ + SAVE_ARG(FUNCNAME, 9); \ + SAVE_ARG(FUNCNAME, 10); \ + SAVE_ARG(FUNCNAME, 11); \ + SAVE_ARG(FUNCNAME, 12); \ + SAVE_ARG(FUNCNAME, 13); \ + SAVE_ARG(FUNCNAME, 14); \ + SAVE_ARG(FUNCNAME, 15); \ + SAVE_ARG(FUNCNAME, 16); \ + SAVE_ARG(FUNCNAME, 17); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + SAVE_ARG_HISTORY(FUNCNAME, 5); \ + SAVE_ARG_HISTORY(FUNCNAME, 6); \ + SAVE_ARG_HISTORY(FUNCNAME, 7); \ + SAVE_ARG_HISTORY(FUNCNAME, 8); \ + SAVE_ARG_HISTORY(FUNCNAME, 9); \ + SAVE_ARG_HISTORY(FUNCNAME, 10); \ + SAVE_ARG_HISTORY(FUNCNAME, 11); \ + SAVE_ARG_HISTORY(FUNCNAME, 12); \ + SAVE_ARG_HISTORY(FUNCNAME, 13); \ + SAVE_ARG_HISTORY(FUNCNAME, 14); \ + SAVE_ARG_HISTORY(FUNCNAME, 15); \ + SAVE_ARG_HISTORY(FUNCNAME, 16); \ + SAVE_ARG_HISTORY(FUNCNAME, 17); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + va_list ap; \ + va_start(ap, arg17); \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16, arg17, ap); \ + va_end(ap); \ + } \ + else{ \ + va_list ap; \ + va_start(ap, arg17); \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16, arg17, ap); \ + va_end(ap); \ + } \ + } \ + if(FUNCNAME##_fake.custom_fake){ \ + va_list ap; \ + va_start(ap, arg17); \ + FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16, arg17, ap); \ + va_end(ap); \ + } \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VOID_FUNC19_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ...) \ + DECLARE_FAKE_VOID_FUNC19_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ...) \ + DEFINE_FAKE_VOID_FUNC19_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ...) \ + + +#define DECLARE_FAKE_VOID_FUNC20_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ARG18_TYPE, ...) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \ + DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \ + DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \ + DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME) \ + DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME) \ + DECLARE_ARG(ARG10_TYPE, 10, FUNCNAME) \ + DECLARE_ARG(ARG11_TYPE, 11, FUNCNAME) \ + DECLARE_ARG(ARG12_TYPE, 12, FUNCNAME) \ + DECLARE_ARG(ARG13_TYPE, 13, FUNCNAME) \ + DECLARE_ARG(ARG14_TYPE, 14, FUNCNAME) \ + DECLARE_ARG(ARG15_TYPE, 15, FUNCNAME) \ + DECLARE_ARG(ARG16_TYPE, 16, FUNCNAME) \ + DECLARE_ARG(ARG17_TYPE, 17, FUNCNAME) \ + DECLARE_ARG(ARG18_TYPE, 18, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + void(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, ARG17_TYPE arg17, ARG18_TYPE arg18, va_list ap); \ + void(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, ARG17_TYPE arg17, ARG18_TYPE arg18, va_list ap); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, ARG17_TYPE arg17, ARG18_TYPE arg18, ...); \ + +#define DEFINE_FAKE_VOID_FUNC20_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ARG18_TYPE, ...) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, ARG17_TYPE arg17, ARG18_TYPE arg18, ...){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + SAVE_ARG(FUNCNAME, 5); \ + SAVE_ARG(FUNCNAME, 6); \ + SAVE_ARG(FUNCNAME, 7); \ + SAVE_ARG(FUNCNAME, 8); \ + SAVE_ARG(FUNCNAME, 9); \ + SAVE_ARG(FUNCNAME, 10); \ + SAVE_ARG(FUNCNAME, 11); \ + SAVE_ARG(FUNCNAME, 12); \ + SAVE_ARG(FUNCNAME, 13); \ + SAVE_ARG(FUNCNAME, 14); \ + SAVE_ARG(FUNCNAME, 15); \ + SAVE_ARG(FUNCNAME, 16); \ + SAVE_ARG(FUNCNAME, 17); \ + SAVE_ARG(FUNCNAME, 18); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + SAVE_ARG_HISTORY(FUNCNAME, 5); \ + SAVE_ARG_HISTORY(FUNCNAME, 6); \ + SAVE_ARG_HISTORY(FUNCNAME, 7); \ + SAVE_ARG_HISTORY(FUNCNAME, 8); \ + SAVE_ARG_HISTORY(FUNCNAME, 9); \ + SAVE_ARG_HISTORY(FUNCNAME, 10); \ + SAVE_ARG_HISTORY(FUNCNAME, 11); \ + SAVE_ARG_HISTORY(FUNCNAME, 12); \ + SAVE_ARG_HISTORY(FUNCNAME, 13); \ + SAVE_ARG_HISTORY(FUNCNAME, 14); \ + SAVE_ARG_HISTORY(FUNCNAME, 15); \ + SAVE_ARG_HISTORY(FUNCNAME, 16); \ + SAVE_ARG_HISTORY(FUNCNAME, 17); \ + SAVE_ARG_HISTORY(FUNCNAME, 18); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + va_list ap; \ + va_start(ap, arg18); \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16, arg17, arg18, ap); \ + va_end(ap); \ + } \ + else{ \ + va_list ap; \ + va_start(ap, arg18); \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16, arg17, arg18, ap); \ + va_end(ap); \ + } \ + } \ + if(FUNCNAME##_fake.custom_fake){ \ + va_list ap; \ + va_start(ap, arg18); \ + FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16, arg17, arg18, ap); \ + va_end(ap); \ + } \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VOID_FUNC20_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ARG18_TYPE, ...) \ + DECLARE_FAKE_VOID_FUNC20_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ARG18_TYPE, ...) \ + DEFINE_FAKE_VOID_FUNC20_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ARG18_TYPE, ...) \ + + +#define DECLARE_FAKE_VALUE_FUNC2_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ...) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE) \ + DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE) \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + RETURN_TYPE(*custom_fake)(ARG0_TYPE arg0, va_list ap); \ + RETURN_TYPE(**custom_fake_seq)(ARG0_TYPE arg0, va_list ap); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ...); \ + +#define DEFINE_FAKE_VALUE_FUNC2_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ...) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ...){ \ + SAVE_ARG(FUNCNAME, 0); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + va_list ap; \ + va_start(ap, arg0); \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, ap); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + va_end(ap); \ + return ret; \ + } \ + else{ \ + va_list ap; \ + va_start(ap, arg0); \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, ap); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + va_end(ap); \ + return ret; \ + return FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, ap); \ + } \ + } \ + if(FUNCNAME##_fake.custom_fake){ \ + RETURN_TYPE ret; \ + va_list ap; \ + va_start(ap, arg0); \ + ret = FUNCNAME##_fake.custom_fake(arg0, ap); \ + va_end(ap); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + } \ + RETURN_FAKE_RESULT(FUNCNAME) \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VALUE_FUNC2_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ...) \ + DECLARE_FAKE_VALUE_FUNC2_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ...) \ + DEFINE_FAKE_VALUE_FUNC2_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ...) \ + + +#define DECLARE_FAKE_VALUE_FUNC3_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ...) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE) \ + DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE) \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + RETURN_TYPE(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, va_list ap); \ + RETURN_TYPE(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, va_list ap); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ...); \ + +#define DEFINE_FAKE_VALUE_FUNC3_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ...) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ...){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + va_list ap; \ + va_start(ap, arg1); \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, ap); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + va_end(ap); \ + return ret; \ + } \ + else{ \ + va_list ap; \ + va_start(ap, arg1); \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, ap); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + va_end(ap); \ + return ret; \ + return FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, ap); \ + } \ + } \ + if(FUNCNAME##_fake.custom_fake){ \ + RETURN_TYPE ret; \ + va_list ap; \ + va_start(ap, arg1); \ + ret = FUNCNAME##_fake.custom_fake(arg0, arg1, ap); \ + va_end(ap); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + } \ + RETURN_FAKE_RESULT(FUNCNAME) \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VALUE_FUNC3_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ...) \ + DECLARE_FAKE_VALUE_FUNC3_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ...) \ + DEFINE_FAKE_VALUE_FUNC3_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ...) \ + + +#define DECLARE_FAKE_VALUE_FUNC4_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ...) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE) \ + DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE) \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + RETURN_TYPE(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, va_list ap); \ + RETURN_TYPE(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, va_list ap); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ...); \ + +#define DEFINE_FAKE_VALUE_FUNC4_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ...) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ...){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + va_list ap; \ + va_start(ap, arg2); \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, ap); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + va_end(ap); \ + return ret; \ + } \ + else{ \ + va_list ap; \ + va_start(ap, arg2); \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, ap); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + va_end(ap); \ + return ret; \ + return FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, ap); \ + } \ + } \ + if(FUNCNAME##_fake.custom_fake){ \ + RETURN_TYPE ret; \ + va_list ap; \ + va_start(ap, arg2); \ + ret = FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, ap); \ + va_end(ap); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + } \ + RETURN_FAKE_RESULT(FUNCNAME) \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VALUE_FUNC4_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ...) \ + DECLARE_FAKE_VALUE_FUNC4_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ...) \ + DEFINE_FAKE_VALUE_FUNC4_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ...) \ + + +#define DECLARE_FAKE_VALUE_FUNC5_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ...) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE) \ + DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE) \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + RETURN_TYPE(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, va_list ap); \ + RETURN_TYPE(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, va_list ap); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ...); \ + +#define DEFINE_FAKE_VALUE_FUNC5_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ...) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ...){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + va_list ap; \ + va_start(ap, arg3); \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, ap); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + va_end(ap); \ + return ret; \ + } \ + else{ \ + va_list ap; \ + va_start(ap, arg3); \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, ap); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + va_end(ap); \ + return ret; \ + return FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, ap); \ + } \ + } \ + if(FUNCNAME##_fake.custom_fake){ \ + RETURN_TYPE ret; \ + va_list ap; \ + va_start(ap, arg3); \ + ret = FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, ap); \ + va_end(ap); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + } \ + RETURN_FAKE_RESULT(FUNCNAME) \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VALUE_FUNC5_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ...) \ + DECLARE_FAKE_VALUE_FUNC5_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ...) \ + DEFINE_FAKE_VALUE_FUNC5_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ...) \ + + +#define DECLARE_FAKE_VALUE_FUNC6_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ...) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE) \ + DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE) \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + RETURN_TYPE(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, va_list ap); \ + RETURN_TYPE(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, va_list ap); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ...); \ + +#define DEFINE_FAKE_VALUE_FUNC6_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ...) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ...){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + va_list ap; \ + va_start(ap, arg4); \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, ap); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + va_end(ap); \ + return ret; \ + } \ + else{ \ + va_list ap; \ + va_start(ap, arg4); \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, ap); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + va_end(ap); \ + return ret; \ + return FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, ap); \ + } \ + } \ + if(FUNCNAME##_fake.custom_fake){ \ + RETURN_TYPE ret; \ + va_list ap; \ + va_start(ap, arg4); \ + ret = FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, ap); \ + va_end(ap); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + } \ + RETURN_FAKE_RESULT(FUNCNAME) \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VALUE_FUNC6_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ...) \ + DECLARE_FAKE_VALUE_FUNC6_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ...) \ + DEFINE_FAKE_VALUE_FUNC6_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ...) \ + + +#define DECLARE_FAKE_VALUE_FUNC7_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ...) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE) \ + DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE) \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + RETURN_TYPE(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, va_list ap); \ + RETURN_TYPE(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, va_list ap); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ...); \ + +#define DEFINE_FAKE_VALUE_FUNC7_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ...) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ...){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + SAVE_ARG(FUNCNAME, 5); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + SAVE_ARG_HISTORY(FUNCNAME, 5); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + va_list ap; \ + va_start(ap, arg5); \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, ap); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + va_end(ap); \ + return ret; \ + } \ + else{ \ + va_list ap; \ + va_start(ap, arg5); \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, ap); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + va_end(ap); \ + return ret; \ + return FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, ap); \ + } \ + } \ + if(FUNCNAME##_fake.custom_fake){ \ + RETURN_TYPE ret; \ + va_list ap; \ + va_start(ap, arg5); \ + ret = FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, ap); \ + va_end(ap); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + } \ + RETURN_FAKE_RESULT(FUNCNAME) \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VALUE_FUNC7_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ...) \ + DECLARE_FAKE_VALUE_FUNC7_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ...) \ + DEFINE_FAKE_VALUE_FUNC7_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ...) \ + + +#define DECLARE_FAKE_VALUE_FUNC8_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ...) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \ + DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE) \ + DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE) \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + RETURN_TYPE(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, va_list ap); \ + RETURN_TYPE(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, va_list ap); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ...); \ + +#define DEFINE_FAKE_VALUE_FUNC8_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ...) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ...){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + SAVE_ARG(FUNCNAME, 5); \ + SAVE_ARG(FUNCNAME, 6); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + SAVE_ARG_HISTORY(FUNCNAME, 5); \ + SAVE_ARG_HISTORY(FUNCNAME, 6); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + va_list ap; \ + va_start(ap, arg6); \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6, ap); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + va_end(ap); \ + return ret; \ + } \ + else{ \ + va_list ap; \ + va_start(ap, arg6); \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, ap); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + va_end(ap); \ + return ret; \ + return FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, ap); \ + } \ + } \ + if(FUNCNAME##_fake.custom_fake){ \ + RETURN_TYPE ret; \ + va_list ap; \ + va_start(ap, arg6); \ + ret = FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, ap); \ + va_end(ap); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + } \ + RETURN_FAKE_RESULT(FUNCNAME) \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VALUE_FUNC8_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ...) \ + DECLARE_FAKE_VALUE_FUNC8_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ...) \ + DEFINE_FAKE_VALUE_FUNC8_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ...) \ + + +#define DECLARE_FAKE_VALUE_FUNC9_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ...) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \ + DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \ + DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE) \ + DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE) \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + RETURN_TYPE(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, va_list ap); \ + RETURN_TYPE(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, va_list ap); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ...); \ + +#define DEFINE_FAKE_VALUE_FUNC9_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ...) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ...){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + SAVE_ARG(FUNCNAME, 5); \ + SAVE_ARG(FUNCNAME, 6); \ + SAVE_ARG(FUNCNAME, 7); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + SAVE_ARG_HISTORY(FUNCNAME, 5); \ + SAVE_ARG_HISTORY(FUNCNAME, 6); \ + SAVE_ARG_HISTORY(FUNCNAME, 7); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + va_list ap; \ + va_start(ap, arg7); \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, ap); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + va_end(ap); \ + return ret; \ + } \ + else{ \ + va_list ap; \ + va_start(ap, arg7); \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, ap); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + va_end(ap); \ + return ret; \ + return FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, ap); \ + } \ + } \ + if(FUNCNAME##_fake.custom_fake){ \ + RETURN_TYPE ret; \ + va_list ap; \ + va_start(ap, arg7); \ + ret = FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, ap); \ + va_end(ap); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + } \ + RETURN_FAKE_RESULT(FUNCNAME) \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VALUE_FUNC9_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ...) \ + DECLARE_FAKE_VALUE_FUNC9_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ...) \ + DEFINE_FAKE_VALUE_FUNC9_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ...) \ + + +#define DECLARE_FAKE_VALUE_FUNC10_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ...) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \ + DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \ + DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \ + DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE) \ + DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE) \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + RETURN_TYPE(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, va_list ap); \ + RETURN_TYPE(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, va_list ap); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ...); \ + +#define DEFINE_FAKE_VALUE_FUNC10_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ...) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ...){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + SAVE_ARG(FUNCNAME, 5); \ + SAVE_ARG(FUNCNAME, 6); \ + SAVE_ARG(FUNCNAME, 7); \ + SAVE_ARG(FUNCNAME, 8); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + SAVE_ARG_HISTORY(FUNCNAME, 5); \ + SAVE_ARG_HISTORY(FUNCNAME, 6); \ + SAVE_ARG_HISTORY(FUNCNAME, 7); \ + SAVE_ARG_HISTORY(FUNCNAME, 8); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + va_list ap; \ + va_start(ap, arg8); \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, ap); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + va_end(ap); \ + return ret; \ + } \ + else{ \ + va_list ap; \ + va_start(ap, arg8); \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, ap); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + va_end(ap); \ + return ret; \ + return FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, ap); \ + } \ + } \ + if(FUNCNAME##_fake.custom_fake){ \ + RETURN_TYPE ret; \ + va_list ap; \ + va_start(ap, arg8); \ + ret = FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, ap); \ + va_end(ap); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + } \ + RETURN_FAKE_RESULT(FUNCNAME) \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VALUE_FUNC10_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ...) \ + DECLARE_FAKE_VALUE_FUNC10_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ...) \ + DEFINE_FAKE_VALUE_FUNC10_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ...) \ + + +#define DECLARE_FAKE_VALUE_FUNC11_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ...) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \ + DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \ + DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \ + DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME) \ + DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE) \ + DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE) \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + RETURN_TYPE(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, va_list ap); \ + RETURN_TYPE(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, va_list ap); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ...); \ + +#define DEFINE_FAKE_VALUE_FUNC11_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ...) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ...){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + SAVE_ARG(FUNCNAME, 5); \ + SAVE_ARG(FUNCNAME, 6); \ + SAVE_ARG(FUNCNAME, 7); \ + SAVE_ARG(FUNCNAME, 8); \ + SAVE_ARG(FUNCNAME, 9); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + SAVE_ARG_HISTORY(FUNCNAME, 5); \ + SAVE_ARG_HISTORY(FUNCNAME, 6); \ + SAVE_ARG_HISTORY(FUNCNAME, 7); \ + SAVE_ARG_HISTORY(FUNCNAME, 8); \ + SAVE_ARG_HISTORY(FUNCNAME, 9); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + va_list ap; \ + va_start(ap, arg9); \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, ap); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + va_end(ap); \ + return ret; \ + } \ + else{ \ + va_list ap; \ + va_start(ap, arg9); \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, ap); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + va_end(ap); \ + return ret; \ + return FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, ap); \ + } \ + } \ + if(FUNCNAME##_fake.custom_fake){ \ + RETURN_TYPE ret; \ + va_list ap; \ + va_start(ap, arg9); \ + ret = FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, ap); \ + va_end(ap); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + } \ + RETURN_FAKE_RESULT(FUNCNAME) \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VALUE_FUNC11_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ...) \ + DECLARE_FAKE_VALUE_FUNC11_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ...) \ + DEFINE_FAKE_VALUE_FUNC11_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ...) \ + + +#define DECLARE_FAKE_VALUE_FUNC12_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ...) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \ + DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \ + DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \ + DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME) \ + DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME) \ + DECLARE_ARG(ARG10_TYPE, 10, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE) \ + DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE) \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + RETURN_TYPE(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, va_list ap); \ + RETURN_TYPE(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, va_list ap); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ...); \ + +#define DEFINE_FAKE_VALUE_FUNC12_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ...) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ...){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + SAVE_ARG(FUNCNAME, 5); \ + SAVE_ARG(FUNCNAME, 6); \ + SAVE_ARG(FUNCNAME, 7); \ + SAVE_ARG(FUNCNAME, 8); \ + SAVE_ARG(FUNCNAME, 9); \ + SAVE_ARG(FUNCNAME, 10); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + SAVE_ARG_HISTORY(FUNCNAME, 5); \ + SAVE_ARG_HISTORY(FUNCNAME, 6); \ + SAVE_ARG_HISTORY(FUNCNAME, 7); \ + SAVE_ARG_HISTORY(FUNCNAME, 8); \ + SAVE_ARG_HISTORY(FUNCNAME, 9); \ + SAVE_ARG_HISTORY(FUNCNAME, 10); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + va_list ap; \ + va_start(ap, arg10); \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, ap); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + va_end(ap); \ + return ret; \ + } \ + else{ \ + va_list ap; \ + va_start(ap, arg10); \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, ap); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + va_end(ap); \ + return ret; \ + return FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, ap); \ + } \ + } \ + if(FUNCNAME##_fake.custom_fake){ \ + RETURN_TYPE ret; \ + va_list ap; \ + va_start(ap, arg10); \ + ret = FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, ap); \ + va_end(ap); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + } \ + RETURN_FAKE_RESULT(FUNCNAME) \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VALUE_FUNC12_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ...) \ + DECLARE_FAKE_VALUE_FUNC12_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ...) \ + DEFINE_FAKE_VALUE_FUNC12_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ...) \ + + +#define DECLARE_FAKE_VALUE_FUNC13_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ...) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \ + DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \ + DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \ + DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME) \ + DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME) \ + DECLARE_ARG(ARG10_TYPE, 10, FUNCNAME) \ + DECLARE_ARG(ARG11_TYPE, 11, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE) \ + DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE) \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + RETURN_TYPE(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, va_list ap); \ + RETURN_TYPE(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, va_list ap); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ...); \ + +#define DEFINE_FAKE_VALUE_FUNC13_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ...) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ...){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + SAVE_ARG(FUNCNAME, 5); \ + SAVE_ARG(FUNCNAME, 6); \ + SAVE_ARG(FUNCNAME, 7); \ + SAVE_ARG(FUNCNAME, 8); \ + SAVE_ARG(FUNCNAME, 9); \ + SAVE_ARG(FUNCNAME, 10); \ + SAVE_ARG(FUNCNAME, 11); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + SAVE_ARG_HISTORY(FUNCNAME, 5); \ + SAVE_ARG_HISTORY(FUNCNAME, 6); \ + SAVE_ARG_HISTORY(FUNCNAME, 7); \ + SAVE_ARG_HISTORY(FUNCNAME, 8); \ + SAVE_ARG_HISTORY(FUNCNAME, 9); \ + SAVE_ARG_HISTORY(FUNCNAME, 10); \ + SAVE_ARG_HISTORY(FUNCNAME, 11); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + va_list ap; \ + va_start(ap, arg11); \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, ap); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + va_end(ap); \ + return ret; \ + } \ + else{ \ + va_list ap; \ + va_start(ap, arg11); \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, ap); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + va_end(ap); \ + return ret; \ + return FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, ap); \ + } \ + } \ + if(FUNCNAME##_fake.custom_fake){ \ + RETURN_TYPE ret; \ + va_list ap; \ + va_start(ap, arg11); \ + ret = FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, ap); \ + va_end(ap); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + } \ + RETURN_FAKE_RESULT(FUNCNAME) \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VALUE_FUNC13_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ...) \ + DECLARE_FAKE_VALUE_FUNC13_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ...) \ + DEFINE_FAKE_VALUE_FUNC13_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ...) \ + + +#define DECLARE_FAKE_VALUE_FUNC14_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ...) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \ + DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \ + DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \ + DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME) \ + DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME) \ + DECLARE_ARG(ARG10_TYPE, 10, FUNCNAME) \ + DECLARE_ARG(ARG11_TYPE, 11, FUNCNAME) \ + DECLARE_ARG(ARG12_TYPE, 12, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE) \ + DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE) \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + RETURN_TYPE(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, va_list ap); \ + RETURN_TYPE(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, va_list ap); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ...); \ + +#define DEFINE_FAKE_VALUE_FUNC14_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ...) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ...){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + SAVE_ARG(FUNCNAME, 5); \ + SAVE_ARG(FUNCNAME, 6); \ + SAVE_ARG(FUNCNAME, 7); \ + SAVE_ARG(FUNCNAME, 8); \ + SAVE_ARG(FUNCNAME, 9); \ + SAVE_ARG(FUNCNAME, 10); \ + SAVE_ARG(FUNCNAME, 11); \ + SAVE_ARG(FUNCNAME, 12); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + SAVE_ARG_HISTORY(FUNCNAME, 5); \ + SAVE_ARG_HISTORY(FUNCNAME, 6); \ + SAVE_ARG_HISTORY(FUNCNAME, 7); \ + SAVE_ARG_HISTORY(FUNCNAME, 8); \ + SAVE_ARG_HISTORY(FUNCNAME, 9); \ + SAVE_ARG_HISTORY(FUNCNAME, 10); \ + SAVE_ARG_HISTORY(FUNCNAME, 11); \ + SAVE_ARG_HISTORY(FUNCNAME, 12); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + va_list ap; \ + va_start(ap, arg12); \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, ap); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + va_end(ap); \ + return ret; \ + } \ + else{ \ + va_list ap; \ + va_start(ap, arg12); \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, ap); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + va_end(ap); \ + return ret; \ + return FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, ap); \ + } \ + } \ + if(FUNCNAME##_fake.custom_fake){ \ + RETURN_TYPE ret; \ + va_list ap; \ + va_start(ap, arg12); \ + ret = FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, ap); \ + va_end(ap); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + } \ + RETURN_FAKE_RESULT(FUNCNAME) \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VALUE_FUNC14_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ...) \ + DECLARE_FAKE_VALUE_FUNC14_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ...) \ + DEFINE_FAKE_VALUE_FUNC14_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ...) \ + + +#define DECLARE_FAKE_VALUE_FUNC15_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ...) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \ + DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \ + DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \ + DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME) \ + DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME) \ + DECLARE_ARG(ARG10_TYPE, 10, FUNCNAME) \ + DECLARE_ARG(ARG11_TYPE, 11, FUNCNAME) \ + DECLARE_ARG(ARG12_TYPE, 12, FUNCNAME) \ + DECLARE_ARG(ARG13_TYPE, 13, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE) \ + DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE) \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + RETURN_TYPE(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, va_list ap); \ + RETURN_TYPE(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, va_list ap); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ...); \ + +#define DEFINE_FAKE_VALUE_FUNC15_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ...) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ...){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + SAVE_ARG(FUNCNAME, 5); \ + SAVE_ARG(FUNCNAME, 6); \ + SAVE_ARG(FUNCNAME, 7); \ + SAVE_ARG(FUNCNAME, 8); \ + SAVE_ARG(FUNCNAME, 9); \ + SAVE_ARG(FUNCNAME, 10); \ + SAVE_ARG(FUNCNAME, 11); \ + SAVE_ARG(FUNCNAME, 12); \ + SAVE_ARG(FUNCNAME, 13); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + SAVE_ARG_HISTORY(FUNCNAME, 5); \ + SAVE_ARG_HISTORY(FUNCNAME, 6); \ + SAVE_ARG_HISTORY(FUNCNAME, 7); \ + SAVE_ARG_HISTORY(FUNCNAME, 8); \ + SAVE_ARG_HISTORY(FUNCNAME, 9); \ + SAVE_ARG_HISTORY(FUNCNAME, 10); \ + SAVE_ARG_HISTORY(FUNCNAME, 11); \ + SAVE_ARG_HISTORY(FUNCNAME, 12); \ + SAVE_ARG_HISTORY(FUNCNAME, 13); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + va_list ap; \ + va_start(ap, arg13); \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, ap); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + va_end(ap); \ + return ret; \ + } \ + else{ \ + va_list ap; \ + va_start(ap, arg13); \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, ap); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + va_end(ap); \ + return ret; \ + return FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, ap); \ + } \ + } \ + if(FUNCNAME##_fake.custom_fake){ \ + RETURN_TYPE ret; \ + va_list ap; \ + va_start(ap, arg13); \ + ret = FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, ap); \ + va_end(ap); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + } \ + RETURN_FAKE_RESULT(FUNCNAME) \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VALUE_FUNC15_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ...) \ + DECLARE_FAKE_VALUE_FUNC15_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ...) \ + DEFINE_FAKE_VALUE_FUNC15_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ...) \ + + +#define DECLARE_FAKE_VALUE_FUNC16_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ...) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \ + DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \ + DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \ + DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME) \ + DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME) \ + DECLARE_ARG(ARG10_TYPE, 10, FUNCNAME) \ + DECLARE_ARG(ARG11_TYPE, 11, FUNCNAME) \ + DECLARE_ARG(ARG12_TYPE, 12, FUNCNAME) \ + DECLARE_ARG(ARG13_TYPE, 13, FUNCNAME) \ + DECLARE_ARG(ARG14_TYPE, 14, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE) \ + DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE) \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + RETURN_TYPE(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, va_list ap); \ + RETURN_TYPE(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, va_list ap); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ...); \ + +#define DEFINE_FAKE_VALUE_FUNC16_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ...) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ...){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + SAVE_ARG(FUNCNAME, 5); \ + SAVE_ARG(FUNCNAME, 6); \ + SAVE_ARG(FUNCNAME, 7); \ + SAVE_ARG(FUNCNAME, 8); \ + SAVE_ARG(FUNCNAME, 9); \ + SAVE_ARG(FUNCNAME, 10); \ + SAVE_ARG(FUNCNAME, 11); \ + SAVE_ARG(FUNCNAME, 12); \ + SAVE_ARG(FUNCNAME, 13); \ + SAVE_ARG(FUNCNAME, 14); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + SAVE_ARG_HISTORY(FUNCNAME, 5); \ + SAVE_ARG_HISTORY(FUNCNAME, 6); \ + SAVE_ARG_HISTORY(FUNCNAME, 7); \ + SAVE_ARG_HISTORY(FUNCNAME, 8); \ + SAVE_ARG_HISTORY(FUNCNAME, 9); \ + SAVE_ARG_HISTORY(FUNCNAME, 10); \ + SAVE_ARG_HISTORY(FUNCNAME, 11); \ + SAVE_ARG_HISTORY(FUNCNAME, 12); \ + SAVE_ARG_HISTORY(FUNCNAME, 13); \ + SAVE_ARG_HISTORY(FUNCNAME, 14); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + va_list ap; \ + va_start(ap, arg14); \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, ap); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + va_end(ap); \ + return ret; \ + } \ + else{ \ + va_list ap; \ + va_start(ap, arg14); \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, ap); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + va_end(ap); \ + return ret; \ + return FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, ap); \ + } \ + } \ + if(FUNCNAME##_fake.custom_fake){ \ + RETURN_TYPE ret; \ + va_list ap; \ + va_start(ap, arg14); \ + ret = FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, ap); \ + va_end(ap); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + } \ + RETURN_FAKE_RESULT(FUNCNAME) \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VALUE_FUNC16_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ...) \ + DECLARE_FAKE_VALUE_FUNC16_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ...) \ + DEFINE_FAKE_VALUE_FUNC16_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ...) \ + + +#define DECLARE_FAKE_VALUE_FUNC17_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ...) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \ + DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \ + DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \ + DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME) \ + DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME) \ + DECLARE_ARG(ARG10_TYPE, 10, FUNCNAME) \ + DECLARE_ARG(ARG11_TYPE, 11, FUNCNAME) \ + DECLARE_ARG(ARG12_TYPE, 12, FUNCNAME) \ + DECLARE_ARG(ARG13_TYPE, 13, FUNCNAME) \ + DECLARE_ARG(ARG14_TYPE, 14, FUNCNAME) \ + DECLARE_ARG(ARG15_TYPE, 15, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE) \ + DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE) \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + RETURN_TYPE(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, va_list ap); \ + RETURN_TYPE(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, va_list ap); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ...); \ + +#define DEFINE_FAKE_VALUE_FUNC17_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ...) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ...){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + SAVE_ARG(FUNCNAME, 5); \ + SAVE_ARG(FUNCNAME, 6); \ + SAVE_ARG(FUNCNAME, 7); \ + SAVE_ARG(FUNCNAME, 8); \ + SAVE_ARG(FUNCNAME, 9); \ + SAVE_ARG(FUNCNAME, 10); \ + SAVE_ARG(FUNCNAME, 11); \ + SAVE_ARG(FUNCNAME, 12); \ + SAVE_ARG(FUNCNAME, 13); \ + SAVE_ARG(FUNCNAME, 14); \ + SAVE_ARG(FUNCNAME, 15); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + SAVE_ARG_HISTORY(FUNCNAME, 5); \ + SAVE_ARG_HISTORY(FUNCNAME, 6); \ + SAVE_ARG_HISTORY(FUNCNAME, 7); \ + SAVE_ARG_HISTORY(FUNCNAME, 8); \ + SAVE_ARG_HISTORY(FUNCNAME, 9); \ + SAVE_ARG_HISTORY(FUNCNAME, 10); \ + SAVE_ARG_HISTORY(FUNCNAME, 11); \ + SAVE_ARG_HISTORY(FUNCNAME, 12); \ + SAVE_ARG_HISTORY(FUNCNAME, 13); \ + SAVE_ARG_HISTORY(FUNCNAME, 14); \ + SAVE_ARG_HISTORY(FUNCNAME, 15); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + va_list ap; \ + va_start(ap, arg15); \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, ap); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + va_end(ap); \ + return ret; \ + } \ + else{ \ + va_list ap; \ + va_start(ap, arg15); \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, ap); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + va_end(ap); \ + return ret; \ + return FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, ap); \ + } \ + } \ + if(FUNCNAME##_fake.custom_fake){ \ + RETURN_TYPE ret; \ + va_list ap; \ + va_start(ap, arg15); \ + ret = FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, ap); \ + va_end(ap); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + } \ + RETURN_FAKE_RESULT(FUNCNAME) \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VALUE_FUNC17_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ...) \ + DECLARE_FAKE_VALUE_FUNC17_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ...) \ + DEFINE_FAKE_VALUE_FUNC17_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ...) \ + + +#define DECLARE_FAKE_VALUE_FUNC18_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ...) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \ + DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \ + DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \ + DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME) \ + DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME) \ + DECLARE_ARG(ARG10_TYPE, 10, FUNCNAME) \ + DECLARE_ARG(ARG11_TYPE, 11, FUNCNAME) \ + DECLARE_ARG(ARG12_TYPE, 12, FUNCNAME) \ + DECLARE_ARG(ARG13_TYPE, 13, FUNCNAME) \ + DECLARE_ARG(ARG14_TYPE, 14, FUNCNAME) \ + DECLARE_ARG(ARG15_TYPE, 15, FUNCNAME) \ + DECLARE_ARG(ARG16_TYPE, 16, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE) \ + DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE) \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + RETURN_TYPE(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, va_list ap); \ + RETURN_TYPE(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, va_list ap); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, ...); \ + +#define DEFINE_FAKE_VALUE_FUNC18_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ...) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, ...){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + SAVE_ARG(FUNCNAME, 5); \ + SAVE_ARG(FUNCNAME, 6); \ + SAVE_ARG(FUNCNAME, 7); \ + SAVE_ARG(FUNCNAME, 8); \ + SAVE_ARG(FUNCNAME, 9); \ + SAVE_ARG(FUNCNAME, 10); \ + SAVE_ARG(FUNCNAME, 11); \ + SAVE_ARG(FUNCNAME, 12); \ + SAVE_ARG(FUNCNAME, 13); \ + SAVE_ARG(FUNCNAME, 14); \ + SAVE_ARG(FUNCNAME, 15); \ + SAVE_ARG(FUNCNAME, 16); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + SAVE_ARG_HISTORY(FUNCNAME, 5); \ + SAVE_ARG_HISTORY(FUNCNAME, 6); \ + SAVE_ARG_HISTORY(FUNCNAME, 7); \ + SAVE_ARG_HISTORY(FUNCNAME, 8); \ + SAVE_ARG_HISTORY(FUNCNAME, 9); \ + SAVE_ARG_HISTORY(FUNCNAME, 10); \ + SAVE_ARG_HISTORY(FUNCNAME, 11); \ + SAVE_ARG_HISTORY(FUNCNAME, 12); \ + SAVE_ARG_HISTORY(FUNCNAME, 13); \ + SAVE_ARG_HISTORY(FUNCNAME, 14); \ + SAVE_ARG_HISTORY(FUNCNAME, 15); \ + SAVE_ARG_HISTORY(FUNCNAME, 16); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + va_list ap; \ + va_start(ap, arg16); \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16, ap); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + va_end(ap); \ + return ret; \ + } \ + else{ \ + va_list ap; \ + va_start(ap, arg16); \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16, ap); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + va_end(ap); \ + return ret; \ + return FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16, ap); \ + } \ + } \ + if(FUNCNAME##_fake.custom_fake){ \ + RETURN_TYPE ret; \ + va_list ap; \ + va_start(ap, arg16); \ + ret = FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16, ap); \ + va_end(ap); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + } \ + RETURN_FAKE_RESULT(FUNCNAME) \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VALUE_FUNC18_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ...) \ + DECLARE_FAKE_VALUE_FUNC18_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ...) \ + DEFINE_FAKE_VALUE_FUNC18_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ...) \ + + +#define DECLARE_FAKE_VALUE_FUNC19_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ...) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \ + DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \ + DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \ + DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME) \ + DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME) \ + DECLARE_ARG(ARG10_TYPE, 10, FUNCNAME) \ + DECLARE_ARG(ARG11_TYPE, 11, FUNCNAME) \ + DECLARE_ARG(ARG12_TYPE, 12, FUNCNAME) \ + DECLARE_ARG(ARG13_TYPE, 13, FUNCNAME) \ + DECLARE_ARG(ARG14_TYPE, 14, FUNCNAME) \ + DECLARE_ARG(ARG15_TYPE, 15, FUNCNAME) \ + DECLARE_ARG(ARG16_TYPE, 16, FUNCNAME) \ + DECLARE_ARG(ARG17_TYPE, 17, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE) \ + DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE) \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + RETURN_TYPE(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, ARG17_TYPE arg17, va_list ap); \ + RETURN_TYPE(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, ARG17_TYPE arg17, va_list ap); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, ARG17_TYPE arg17, ...); \ + +#define DEFINE_FAKE_VALUE_FUNC19_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ...) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, ARG17_TYPE arg17, ...){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + SAVE_ARG(FUNCNAME, 5); \ + SAVE_ARG(FUNCNAME, 6); \ + SAVE_ARG(FUNCNAME, 7); \ + SAVE_ARG(FUNCNAME, 8); \ + SAVE_ARG(FUNCNAME, 9); \ + SAVE_ARG(FUNCNAME, 10); \ + SAVE_ARG(FUNCNAME, 11); \ + SAVE_ARG(FUNCNAME, 12); \ + SAVE_ARG(FUNCNAME, 13); \ + SAVE_ARG(FUNCNAME, 14); \ + SAVE_ARG(FUNCNAME, 15); \ + SAVE_ARG(FUNCNAME, 16); \ + SAVE_ARG(FUNCNAME, 17); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + SAVE_ARG_HISTORY(FUNCNAME, 5); \ + SAVE_ARG_HISTORY(FUNCNAME, 6); \ + SAVE_ARG_HISTORY(FUNCNAME, 7); \ + SAVE_ARG_HISTORY(FUNCNAME, 8); \ + SAVE_ARG_HISTORY(FUNCNAME, 9); \ + SAVE_ARG_HISTORY(FUNCNAME, 10); \ + SAVE_ARG_HISTORY(FUNCNAME, 11); \ + SAVE_ARG_HISTORY(FUNCNAME, 12); \ + SAVE_ARG_HISTORY(FUNCNAME, 13); \ + SAVE_ARG_HISTORY(FUNCNAME, 14); \ + SAVE_ARG_HISTORY(FUNCNAME, 15); \ + SAVE_ARG_HISTORY(FUNCNAME, 16); \ + SAVE_ARG_HISTORY(FUNCNAME, 17); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + va_list ap; \ + va_start(ap, arg17); \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16, arg17, ap); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + va_end(ap); \ + return ret; \ + } \ + else{ \ + va_list ap; \ + va_start(ap, arg17); \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16, arg17, ap); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + va_end(ap); \ + return ret; \ + return FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16, arg17, ap); \ + } \ + } \ + if(FUNCNAME##_fake.custom_fake){ \ + RETURN_TYPE ret; \ + va_list ap; \ + va_start(ap, arg17); \ + ret = FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16, arg17, ap); \ + va_end(ap); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + } \ + RETURN_FAKE_RESULT(FUNCNAME) \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VALUE_FUNC19_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ...) \ + DECLARE_FAKE_VALUE_FUNC19_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ...) \ + DEFINE_FAKE_VALUE_FUNC19_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ...) \ + + +#define DECLARE_FAKE_VALUE_FUNC20_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ARG18_TYPE, ...) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \ + DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \ + DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \ + DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME) \ + DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME) \ + DECLARE_ARG(ARG10_TYPE, 10, FUNCNAME) \ + DECLARE_ARG(ARG11_TYPE, 11, FUNCNAME) \ + DECLARE_ARG(ARG12_TYPE, 12, FUNCNAME) \ + DECLARE_ARG(ARG13_TYPE, 13, FUNCNAME) \ + DECLARE_ARG(ARG14_TYPE, 14, FUNCNAME) \ + DECLARE_ARG(ARG15_TYPE, 15, FUNCNAME) \ + DECLARE_ARG(ARG16_TYPE, 16, FUNCNAME) \ + DECLARE_ARG(ARG17_TYPE, 17, FUNCNAME) \ + DECLARE_ARG(ARG18_TYPE, 18, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE) \ + DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE) \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + RETURN_TYPE(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, ARG17_TYPE arg17, ARG18_TYPE arg18, va_list ap); \ + RETURN_TYPE(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, ARG17_TYPE arg17, ARG18_TYPE arg18, va_list ap); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, ARG17_TYPE arg17, ARG18_TYPE arg18, ...); \ + +#define DEFINE_FAKE_VALUE_FUNC20_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ARG18_TYPE, ...) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, ARG17_TYPE arg17, ARG18_TYPE arg18, ...){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + SAVE_ARG(FUNCNAME, 5); \ + SAVE_ARG(FUNCNAME, 6); \ + SAVE_ARG(FUNCNAME, 7); \ + SAVE_ARG(FUNCNAME, 8); \ + SAVE_ARG(FUNCNAME, 9); \ + SAVE_ARG(FUNCNAME, 10); \ + SAVE_ARG(FUNCNAME, 11); \ + SAVE_ARG(FUNCNAME, 12); \ + SAVE_ARG(FUNCNAME, 13); \ + SAVE_ARG(FUNCNAME, 14); \ + SAVE_ARG(FUNCNAME, 15); \ + SAVE_ARG(FUNCNAME, 16); \ + SAVE_ARG(FUNCNAME, 17); \ + SAVE_ARG(FUNCNAME, 18); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + SAVE_ARG_HISTORY(FUNCNAME, 5); \ + SAVE_ARG_HISTORY(FUNCNAME, 6); \ + SAVE_ARG_HISTORY(FUNCNAME, 7); \ + SAVE_ARG_HISTORY(FUNCNAME, 8); \ + SAVE_ARG_HISTORY(FUNCNAME, 9); \ + SAVE_ARG_HISTORY(FUNCNAME, 10); \ + SAVE_ARG_HISTORY(FUNCNAME, 11); \ + SAVE_ARG_HISTORY(FUNCNAME, 12); \ + SAVE_ARG_HISTORY(FUNCNAME, 13); \ + SAVE_ARG_HISTORY(FUNCNAME, 14); \ + SAVE_ARG_HISTORY(FUNCNAME, 15); \ + SAVE_ARG_HISTORY(FUNCNAME, 16); \ + SAVE_ARG_HISTORY(FUNCNAME, 17); \ + SAVE_ARG_HISTORY(FUNCNAME, 18); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + va_list ap; \ + va_start(ap, arg18); \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16, arg17, arg18, ap); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + va_end(ap); \ + return ret; \ + } \ + else{ \ + va_list ap; \ + va_start(ap, arg18); \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16, arg17, arg18, ap); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + va_end(ap); \ + return ret; \ + return FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16, arg17, arg18, ap); \ + } \ + } \ + if(FUNCNAME##_fake.custom_fake){ \ + RETURN_TYPE ret; \ + va_list ap; \ + va_start(ap, arg18); \ + ret = FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16, arg17, arg18, ap); \ + va_end(ap); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + } \ + RETURN_FAKE_RESULT(FUNCNAME) \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VALUE_FUNC20_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ARG18_TYPE, ...) \ + DECLARE_FAKE_VALUE_FUNC20_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ARG18_TYPE, ...) \ + DEFINE_FAKE_VALUE_FUNC20_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ARG18_TYPE, ...) \ + +/* MSVC expand macro fix */ +#define EXPAND(x) x + +#define PP_NARG_MINUS2(...) EXPAND(PP_NARG_MINUS2_(__VA_ARGS__, PP_RSEQ_N_MINUS2())) + +#define PP_NARG_MINUS2_(...) EXPAND(PP_ARG_MINUS2_N(__VA_ARGS__)) + +#define PP_ARG_MINUS2_N(returnVal, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, N, ...) N + +#define PP_RSEQ_N_MINUS2() 20,19,18,17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0 + +#define PP_NARG_MINUS1(...) EXPAND(PP_NARG_MINUS1_(__VA_ARGS__, PP_RSEQ_N_MINUS1())) + +#define PP_NARG_MINUS1_(...) EXPAND(PP_ARG_MINUS1_N(__VA_ARGS__)) + +#define PP_ARG_MINUS1_N( _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, N, ...) N + +#define PP_RSEQ_N_MINUS1() 20,19,18,17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0 + + + +/* DECLARE AND DEFINE FAKE FUNCTIONS - PLACE IN TEST FILES */ + +#define FAKE_VALUE_FUNC(...) EXPAND(FUNC_VALUE_(PP_NARG_MINUS2(__VA_ARGS__), __VA_ARGS__)) + +#define FUNC_VALUE_(N,...) EXPAND(FUNC_VALUE_N(N,__VA_ARGS__)) + +#define FUNC_VALUE_N(N,...) EXPAND(FAKE_VALUE_FUNC ## N(__VA_ARGS__)) + + +#define FAKE_VOID_FUNC(...) EXPAND(FUNC_VOID_(PP_NARG_MINUS1(__VA_ARGS__), __VA_ARGS__)) + +#define FUNC_VOID_(N,...) EXPAND(FUNC_VOID_N(N,__VA_ARGS__)) + +#define FUNC_VOID_N(N,...) EXPAND(FAKE_VOID_FUNC ## N(__VA_ARGS__)) + + +#define FAKE_VALUE_FUNC_VARARG(...) EXPAND(FUNC_VALUE_VARARG_(PP_NARG_MINUS2(__VA_ARGS__), __VA_ARGS__)) + +#define FUNC_VALUE_VARARG_(N,...) EXPAND(FUNC_VALUE_VARARG_N(N,__VA_ARGS__)) + +#define FUNC_VALUE_VARARG_N(N,...) EXPAND(FAKE_VALUE_FUNC ## N ## _VARARG(__VA_ARGS__)) + + +#define FAKE_VOID_FUNC_VARARG(...) EXPAND(FUNC_VOID_VARARG_(PP_NARG_MINUS1(__VA_ARGS__), __VA_ARGS__)) + +#define FUNC_VOID_VARARG_(N,...) EXPAND(FUNC_VOID_VARARG_N(N,__VA_ARGS__)) + +#define FUNC_VOID_VARARG_N(N,...) EXPAND(FAKE_VOID_FUNC ## N ## _VARARG(__VA_ARGS__)) + + + +/* DECLARE FAKE FUNCTIONS - PLACE IN HEADER FILES */ + +#define DECLARE_FAKE_VALUE_FUNC(...) EXPAND(DECLARE_FUNC_VALUE_(PP_NARG_MINUS2(__VA_ARGS__), __VA_ARGS__)) + +#define DECLARE_FUNC_VALUE_(N,...) EXPAND(DECLARE_FUNC_VALUE_N(N,__VA_ARGS__)) + +#define DECLARE_FUNC_VALUE_N(N,...) EXPAND(DECLARE_FAKE_VALUE_FUNC ## N(__VA_ARGS__)) + + +#define DECLARE_FAKE_VOID_FUNC(...) EXPAND(DECLARE_FUNC_VOID_(PP_NARG_MINUS1(__VA_ARGS__), __VA_ARGS__)) + +#define DECLARE_FUNC_VOID_(N,...) EXPAND(DECLARE_FUNC_VOID_N(N,__VA_ARGS__)) + +#define DECLARE_FUNC_VOID_N(N,...) EXPAND(DECLARE_FAKE_VOID_FUNC ## N(__VA_ARGS__)) + + +#define DECLARE_FAKE_VALUE_FUNC_VARARG(...) EXPAND(DECLARE_FUNC_VALUE_VARARG_(PP_NARG_MINUS2(__VA_ARGS__), __VA_ARGS__)) + +#define DECLARE_FUNC_VALUE_VARARG_(N,...) EXPAND(DECLARE_FUNC_VALUE_VARARG_N(N,__VA_ARGS__)) + +#define DECLARE_FUNC_VALUE_VARARG_N(N,...) EXPAND(DECLARE_FAKE_VALUE_FUNC ## N ## _VARARG(__VA_ARGS__)) + + +#define DECLARE_FAKE_VOID_FUNC_VARARG(...) EXPAND(DECLARE_FUNC_VOID_VARARG_(PP_NARG_MINUS1(__VA_ARGS__), __VA_ARGS__)) + +#define DECLARE_FUNC_VOID_VARARG_(N,...) EXPAND(DECLARE_FUNC_VOID_VARARG_N(N,__VA_ARGS__)) + +#define DECLARE_FUNC_VOID_VARARG_N(N,...) EXPAND(DECLARE_FAKE_VOID_FUNC ## N ## _VARARG(__VA_ARGS__)) + + + +/* DEFINE FAKE FUNCTIONS - PLACE IN SOURCE FILES */ + +#define DEFINE_FAKE_VALUE_FUNC(...) EXPAND(DEFINE_FUNC_VALUE_(PP_NARG_MINUS2(__VA_ARGS__), __VA_ARGS__)) + +#define DEFINE_FUNC_VALUE_(N,...) EXPAND(DEFINE_FUNC_VALUE_N(N,__VA_ARGS__)) + +#define DEFINE_FUNC_VALUE_N(N,...) EXPAND(DEFINE_FAKE_VALUE_FUNC ## N(__VA_ARGS__)) + + +#define DEFINE_FAKE_VOID_FUNC(...) EXPAND(DEFINE_FUNC_VOID_(PP_NARG_MINUS1(__VA_ARGS__), __VA_ARGS__)) + +#define DEFINE_FUNC_VOID_(N,...) EXPAND(DEFINE_FUNC_VOID_N(N,__VA_ARGS__)) + +#define DEFINE_FUNC_VOID_N(N,...) EXPAND(DEFINE_FAKE_VOID_FUNC ## N(__VA_ARGS__)) + + +#define DEFINE_FAKE_VALUE_FUNC_VARARG(...) EXPAND(DEFINE_FUNC_VALUE_VARARG_(PP_NARG_MINUS2(__VA_ARGS__), __VA_ARGS__)) + +#define DEFINE_FUNC_VALUE_VARARG_(N,...) EXPAND(DEFINE_FUNC_VALUE_VARARG_N(N,__VA_ARGS__)) + +#define DEFINE_FUNC_VALUE_VARARG_N(N,...) EXPAND(DEFINE_FAKE_VALUE_FUNC ## N ## _VARARG(__VA_ARGS__)) + + +#define DEFINE_FAKE_VOID_FUNC_VARARG(...) EXPAND(DEFINE_FUNC_VOID_VARARG_(PP_NARG_MINUS1(__VA_ARGS__), __VA_ARGS__)) + +#define DEFINE_FUNC_VOID_VARARG_(N,...) EXPAND(DEFINE_FUNC_VOID_VARARG_N(N,__VA_ARGS__)) + +#define DEFINE_FUNC_VOID_VARARG_N(N,...) EXPAND(DEFINE_FAKE_VOID_FUNC ## N ## _VARARG(__VA_ARGS__)) + + + + +#endif /* FAKE_FUNCTIONS */ \ No newline at end of file diff --git a/unittest/server/CMakeLists.txt b/unittest/server/CMakeLists.txt new file mode 100644 index 00000000..63b2eed4 --- /dev/null +++ b/unittest/server/CMakeLists.txt @@ -0,0 +1,118 @@ +############################################################################ +# +# Copyright (C) 2023 Advanced Driver Information Technology Joint Venture GmbH +# +# +# 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. +# +############################################################################ + +CMAKE_MINIMUM_REQUIRED(VERSION 2.6) +cmake_policy(SET CMP0046 OLD) + +PROJECT(ilm_server_unittest) + +find_package(PkgConfig REQUIRED) +pkg_check_modules(WAYLAND_SERVER wayland-server REQUIRED) +pkg_check_modules(WESTON weston>=5.0.0 REQUIRED) + +GET_TARGET_PROPERTY(WESTON_IVI ivi-controller INCLUDE_DIRECTORIES) +find_program(WAYLAND_SCANNER_EXECUTABLE NAMES wayland-scanner) + +add_custom_command( + OUTPUT ivi-input-protocol.c + COMMAND ${WAYLAND_SCANNER_EXECUTABLE} code + < ${CMAKE_SOURCE_DIR}/protocol/ivi-input.xml + > ${CMAKE_CURRENT_BINARY_DIR}/ivi-input-protocol.c + DEPENDS ${CMAKE_SOURCE_DIR}/protocol/ivi-input.xml +) + +add_custom_command( + OUTPUT ivi-wm-protocol.c + COMMAND ${WAYLAND_SCANNER_EXECUTABLE} code + < ${CMAKE_SOURCE_DIR}/protocol/ivi-wm.xml + > ${CMAKE_CURRENT_BINARY_DIR}/ivi-wm-protocol.c + DEPENDS ${CMAKE_SOURCE_DIR}/protocol/ivi-wm.xml +) + +INCLUDE_DIRECTORIES( + ${CMAKE_CURRENT_SOURCE_DIR}/../../weston-ivi-shell/src/ + ${CMAKE_CURRENT_SOURCE_DIR}/../../ivi-input-modules/ivi-input-controller/src/ + ${CMAKE_CURRENT_SOURCE_DIR}/../../ivi-id-agent-modules/ivi-id-agent/src/ + ${CMAKE_CURRENT_BINARY_DIR}/../../ivi-input-modules/ivi-input-controller/ + ${CMAKE_CURRENT_BINARY_DIR}/../../weston-ivi-shell/ + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${CMAKE_CURRENT_SOURCE_DIR}/../common + ${CMAKE_CURRENT_SOURCE_DIR}/../../ivi-layermanagement-api/ilmCommon/include/ + ${WAYLAND_SERVER_INCLUDE_DIRS} + ${WESTON_INCLUDE_DIRS} + ${gtest_INCLUDE_DIRS} +) + +LINK_DIRECTORIES( + ${WAYLAND_SERVER_LIBRARY_DIRS} +) + +SET(LIBS + ${gtest_LIBRARIES} +) + +SET(SRC_COMMON_FILES + ${CMAKE_CURRENT_SOURCE_DIR}/src/server_api_fake.c + ${CMAKE_CURRENT_SOURCE_DIR}/src/ivi_layout_interface_fake.c + ${CMAKE_CURRENT_SOURCE_DIR}/../common/common_fake_api.c +) + +SET(SRC_ID_AGENT_FILES + ${CMAKE_CURRENT_SOURCE_DIR}/src/ivi_id_agent_unittests.cpp +) + +SET(SRC_CONTROLLER_FILES + ${CMAKE_CURRENT_SOURCE_DIR}/src/ivi_controller_uinttests.cpp + ivi-wm-protocol.c +) + +SET(SRC_INPUT_CONTROLLER_FILES + ${CMAKE_CURRENT_SOURCE_DIR}/src/ivi_input_controller_uinttests.cpp + ivi-input-protocol.c +) + +SET(GCC_SANITIZER_COMPILE_FLAGS "-fsanitize=address -fsanitize=undefined -fno-sanitize-recover -fstack-protector-all -fpermissive") +IF(BUILD_CODE_COVERAGE) + SET(COVERAGE_COMPILER_FLAGS "-g --coverage") + SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${COVERAGE_COMPILER_FLAGS}") + SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${GCC_SANITIZER_COMPILE_FLAGS} -pthread ${COVERAGE_COMPILER_FLAGS}") + SET(CMAKE_CXX_LINK_FLAGS "${CMAKE_CXX_LINK_FLAGS} -static-libasan -static-libubsan ${COVERAGE_COMPILER_FLAGS}") +ELSE() + SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${GCC_SANITIZER_COMPILE_FLAGS} -pthread") + SET(CMAKE_CXX_LINK_FLAGS "${CMAKE_CXX_LINK_FLAGS} -static-libasan -static-libubsan") +ENDIF() + +ADD_EXECUTABLE(unittest-ivi-controller ${SRC_CONTROLLER_FILES} ${SRC_COMMON_FILES}) +TARGET_LINK_LIBRARIES(unittest-ivi-controller ${LIBS}) +ADD_DEPENDENCIES(unittest-ivi-controller ${LIBS} ivi-controller) +INSTALL(TARGETS unittest-ivi-controller DESTINATION bin) + +ADD_EXECUTABLE(unittest-ivi-input-controller ${SRC_INPUT_CONTROLLER_FILES} ${SRC_COMMON_FILES}) +TARGET_LINK_LIBRARIES(unittest-ivi-input-controller ${LIBS}) +ADD_DEPENDENCIES(unittest-ivi-input-controller ${LIBS} ivi-input-controller) +INSTALL(TARGETS unittest-ivi-input-controller DESTINATION bin) + +ADD_EXECUTABLE(unittest-ivi-id-agent ${SRC_ID_AGENT_FILES} ${SRC_COMMON_FILES}) +TARGET_LINK_LIBRARIES(unittest-ivi-id-agent ${LIBS}) +ADD_DEPENDENCIES(unittest-ivi-id-agent ${LIBS} ivi-id-agent) +INSTALL(TARGETS unittest-ivi-id-agent DESTINATION bin) + +ADD_TEST(Unittest-ivi-controller unittest-ivi-controller) +ADD_TEST(Unittest-ivi-input-controller unittest-ivi-input-controller) +ADD_TEST(Unittest-ivi-id-agent unittest-ivi-id-agent) diff --git a/unittest/server/include/ivi_layout_interface_fake.h b/unittest/server/include/ivi_layout_interface_fake.h new file mode 100644 index 00000000..d5da1e58 --- /dev/null +++ b/unittest/server/include/ivi_layout_interface_fake.h @@ -0,0 +1,139 @@ +/*************************************************************************** + * + * Copyright (C) 2023 Advanced Driver Information Technology Joint Venture GmbH + * + * + * 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. + * + ****************************************************************************/ + +#ifndef IVI_LAYOUT_INTERFACE_FAKE +#define IVI_LAYOUT_INTERFACE_FAKE +#include "ivi-wm-server-protocol.h" +#include "ivi-layout-export.h" +#include +#include "weston.h" +#include "fff.h" + +#ifdef __cplusplus +extern "C" { +#endif + +// create the fake interface +DECLARE_FAKE_VALUE_FUNC(const struct ivi_layout_layer_properties *, get_properties_of_layer, struct ivi_layout_layer *); +DECLARE_FAKE_VALUE_FUNC(const struct ivi_layout_surface_properties *, get_properties_of_surface, struct ivi_layout_surface *); +DECLARE_FAKE_VALUE_FUNC(int32_t, add_listener_configure_desktop_surface, struct wl_listener *); +DECLARE_FAKE_VALUE_FUNC(int32_t, add_listener_configure_surface, struct wl_listener *); +DECLARE_FAKE_VALUE_FUNC(int32_t, add_listener_create_layer, struct wl_listener *); +DECLARE_FAKE_VALUE_FUNC(int32_t, add_listener_create_surface, struct wl_listener *); +DECLARE_FAKE_VALUE_FUNC(int32_t, add_listener_remove_layer, struct wl_listener *); +DECLARE_FAKE_VALUE_FUNC(int32_t, add_listener_remove_surface, struct wl_listener *); +DECLARE_FAKE_VALUE_FUNC(int32_t, commit_changes); +DECLARE_FAKE_VALUE_FUNC(int32_t, get_layers, int32_t *, struct ivi_layout_layer ***); +DECLARE_FAKE_VALUE_FUNC(int32_t, get_layers_on_screen, struct weston_output *, int32_t *, struct ivi_layout_layer ***); +DECLARE_FAKE_VALUE_FUNC(int32_t, get_layers_under_surface, struct ivi_layout_surface *, int32_t *, struct ivi_layout_layer ***); +DECLARE_FAKE_VALUE_FUNC(int32_t, get_screens_under_layer, struct ivi_layout_layer *, int32_t *, struct weston_output ***); +DECLARE_FAKE_VALUE_FUNC(int32_t, get_surfaces, int32_t *, struct ivi_layout_surface ***); +DECLARE_FAKE_VALUE_FUNC(int32_t, get_surfaces_on_layer, struct ivi_layout_layer *, int32_t *, struct ivi_layout_surface ***); +DECLARE_FAKE_VALUE_FUNC(int32_t, layer_add_listener, struct ivi_layout_layer *, struct wl_listener *); +DECLARE_FAKE_VALUE_FUNC(int32_t, layer_add_surface, struct ivi_layout_layer *, struct ivi_layout_surface *); +DECLARE_FAKE_VALUE_FUNC(int32_t, layer_set_destination_rectangle, struct ivi_layout_layer *, int32_t , int32_t , int32_t , int32_t ); +DECLARE_FAKE_VALUE_FUNC(int32_t, layer_set_fade_info, struct ivi_layout_layer* , uint32_t , double , double ); +DECLARE_FAKE_VALUE_FUNC(int32_t, layer_set_opacity, struct ivi_layout_layer *, wl_fixed_t ); +DECLARE_FAKE_VALUE_FUNC(int32_t, layer_set_render_order, struct ivi_layout_layer *, struct ivi_layout_surface **, int32_t ); +DECLARE_FAKE_VALUE_FUNC(int32_t, layer_set_source_rectangle, struct ivi_layout_layer *, int32_t , int32_t , int32_t , int32_t ); +DECLARE_FAKE_VALUE_FUNC(int32_t, layer_set_transition, struct ivi_layout_layer *, enum ivi_layout_transition_type , uint32_t ); +DECLARE_FAKE_VALUE_FUNC(int32_t, layer_set_visibility, struct ivi_layout_layer *, bool ); +DECLARE_FAKE_VALUE_FUNC(int32_t, screen_add_layer, struct weston_output *, struct ivi_layout_layer *); +DECLARE_FAKE_VALUE_FUNC(int32_t, screen_remove_layer, struct weston_output *, struct ivi_layout_layer *); +DECLARE_FAKE_VALUE_FUNC(int32_t, screen_set_render_order, struct weston_output *, struct ivi_layout_layer **, const int32_t ); +DECLARE_FAKE_VALUE_FUNC(int32_t, surface_add_listener, struct ivi_layout_surface *, struct wl_listener *); +DECLARE_FAKE_VALUE_FUNC(int32_t, surface_dump, struct weston_surface *, void *, size_t , int32_t , int32_t , int32_t , int32_t ); +DECLARE_FAKE_VALUE_FUNC(int32_t, surface_get_size, struct ivi_layout_surface *, int32_t *, int32_t *, int32_t *); +DECLARE_FAKE_VALUE_FUNC(int32_t, surface_set_destination_rectangle, struct ivi_layout_surface *, int32_t , int32_t , int32_t , int32_t ); +DECLARE_FAKE_VALUE_FUNC(int32_t, surface_set_id, struct ivi_layout_surface *, uint32_t ); +DECLARE_FAKE_VALUE_FUNC(int32_t, surface_set_opacity, struct ivi_layout_surface *, wl_fixed_t ); +DECLARE_FAKE_VALUE_FUNC(int32_t, surface_set_source_rectangle, struct ivi_layout_surface *, int32_t , int32_t , int32_t , int32_t ); +DECLARE_FAKE_VALUE_FUNC(int32_t, surface_set_transition_duration, struct ivi_layout_surface *, uint32_t ); +DECLARE_FAKE_VALUE_FUNC(int32_t, surface_set_transition, struct ivi_layout_surface *, enum ivi_layout_transition_type , uint32_t ); +DECLARE_FAKE_VALUE_FUNC(int32_t, surface_set_visibility, struct ivi_layout_surface *, bool ); +DECLARE_FAKE_VALUE_FUNC(struct ivi_layout_layer *, get_layer_from_id, uint32_t ); +DECLARE_FAKE_VALUE_FUNC(struct ivi_layout_layer *, layer_create_with_dimension, uint32_t , int32_t , int32_t ); +DECLARE_FAKE_VALUE_FUNC(struct ivi_layout_surface *, get_surface_from_id, uint32_t ); +// DECLARE_FAKE_VALUE_FUNC(struct ivisurface *, get_surface, struct wl_list *, struct ivi_layout_surface *); +DECLARE_FAKE_VALUE_FUNC(struct weston_surface *, surface_get_weston_surface, struct ivi_layout_surface *); +DECLARE_FAKE_VALUE_FUNC(uint32_t, get_id_of_layer, struct ivi_layout_layer *); +DECLARE_FAKE_VALUE_FUNC(uint32_t, get_id_of_surface, struct ivi_layout_surface *); +DECLARE_FAKE_VOID_FUNC(focus, struct weston_pointer_grab *); +DECLARE_FAKE_VOID_FUNC(layer_destroy, struct ivi_layout_layer *); +DECLARE_FAKE_VOID_FUNC(layer_remove_surface, struct ivi_layout_layer *, struct ivi_layout_surface *); +DECLARE_FAKE_VOID_FUNC(transition_move_layer_cancel, struct ivi_layout_layer *); +DECLARE_FAKE_VALUE_FUNC(int32_t, shell_add_destroy_listener_once, struct wl_listener *, wl_notify_func_t); + +#define IVI_LAYOUT_FAKE_LIST(FAKE) \ + FAKE(get_properties_of_layer) \ + FAKE(get_properties_of_surface) \ + FAKE(add_listener_configure_desktop_surface) \ + FAKE(add_listener_configure_surface) \ + FAKE(add_listener_create_layer) \ + FAKE(add_listener_create_surface) \ + FAKE(add_listener_remove_layer) \ + FAKE(add_listener_remove_surface) \ + FAKE(commit_changes) \ + FAKE(get_layers) \ + FAKE(get_layers_on_screen) \ + FAKE(get_layers_under_surface) \ + FAKE(get_screens_under_layer) \ + FAKE(get_surfaces) \ + FAKE(get_surfaces_on_layer) \ + FAKE(layer_add_listener) \ + FAKE(layer_add_surface) \ + FAKE(layer_set_destination_rectangle) \ + FAKE(layer_set_fade_info) \ + FAKE(layer_set_opacity) \ + FAKE(layer_set_render_order) \ + FAKE(layer_set_source_rectangle) \ + FAKE(layer_set_transition) \ + FAKE(layer_set_visibility) \ + FAKE(screen_add_layer) \ + FAKE(screen_remove_layer) \ + FAKE(screen_set_render_order) \ + FAKE(surface_add_listener) \ + FAKE(surface_dump) \ + FAKE(surface_get_size) \ + FAKE(surface_set_destination_rectangle) \ + FAKE(surface_set_id) \ + FAKE(surface_set_opacity) \ + FAKE(surface_set_source_rectangle) \ + FAKE(surface_set_transition_duration) \ + FAKE(surface_set_transition) \ + FAKE(surface_set_visibility) \ + FAKE(get_layer_from_id) \ + FAKE(layer_create_with_dimension) \ + FAKE(get_surface_from_id) \ + FAKE(surface_get_weston_surface) \ + FAKE(get_id_of_layer) \ + FAKE(get_id_of_surface) \ + FAKE(focus) \ + FAKE(layer_destroy) \ + FAKE(layer_remove_surface) \ + FAKE(transition_move_layer_cancel)\ + FAKE(shell_add_destroy_listener_once) + +extern struct ivi_layout_interface g_iviLayoutInterfaceFake; +extern struct weston_pointer_grab_interface g_grabInterfaceFake; + +#ifdef __cplusplus +} +#endif +#endif // IVI_LAYOUT_INTERFACE_FAKE \ No newline at end of file diff --git a/unittest/server/include/ivi_layout_structure.hpp b/unittest/server/include/ivi_layout_structure.hpp new file mode 100644 index 00000000..d6558267 --- /dev/null +++ b/unittest/server/include/ivi_layout_structure.hpp @@ -0,0 +1,132 @@ +/*************************************************************************** + * + * Copyright (C) 2023 Advanced Driver Information Technology Joint Venture GmbH + * + * + * 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. + * + ****************************************************************************/ + +#ifndef IVI_LAYOUT_STRUCTURE +#define IVI_LAYOUT_STRUCTURE + +#include +#include "libweston/libweston.h" +#include "ivi-layout-export.h" +#include + +struct ivi_layout_view { + struct wl_list link; /* ivi_layout::view_list */ + struct wl_list surf_link; /*ivi_layout_surface::view_list */ + struct wl_list pending_link; /* ivi_layout_layer::pending.view_list */ + struct wl_list order_link; /* ivi_layout_layer::order.view_list */ + + struct weston_view *view; + struct weston_transform transform; + + struct ivi_layout_surface *ivisurf; + struct ivi_layout_layer *on_layer; +}; + +struct ivi_layout_surface { + struct wl_list link; /* ivi_layout::surface_list */ + struct wl_signal property_changed; + int32_t update_count; + uint32_t id_surface; + + struct ivi_layout *layout; + struct weston_surface *surface; + struct weston_desktop_surface *weston_desktop_surface; + + struct ivi_layout_view *ivi_view; + + struct ivi_layout_surface_properties prop; + + struct { + struct ivi_layout_surface_properties prop; + } pending; + + struct wl_list view_list; /* ivi_layout_view::surf_link */ +}; + +struct ivi_layout_layer { + struct wl_list link; /* ivi_layout::layer_list */ + struct wl_signal property_changed; + uint32_t id_layer; + + struct ivi_layout *layout; + struct ivi_layout_screen *on_screen; + + struct ivi_layout_layer_properties prop; + + struct { + struct ivi_layout_layer_properties prop; + struct wl_list view_list; /* ivi_layout_view::pending_link */ + struct wl_list link; /* ivi_layout_screen::pending.layer_list */ + } pending; + + struct { + int dirty; + struct wl_list view_list; /* ivi_layout_view::order_link */ + struct wl_list link; /* ivi_layout_screen::order.layer_list */ + } order; + + int32_t ref_count; +}; + +struct ivi_layout { + struct ivi_shell *shell; + + struct wl_list surface_list; /* ivi_layout_surface::link */ + struct wl_list layer_list; /* ivi_layout_layer::link */ + struct wl_list screen_list; /* ivi_layout_screen::link */ + struct wl_list view_list; /* ivi_layout_view::link */ + + struct { + struct wl_signal destroy_signal; + } shell_notification; + + struct { + struct wl_signal created; + struct wl_signal removed; + } layer_notification; + + struct { + struct wl_signal created; + struct wl_signal removed; + struct wl_signal configure_changed; + struct wl_signal configure_desktop_changed; + } surface_notification; + + struct { + struct wl_signal configure_changed; + struct wl_signal show; + struct wl_signal hide; + struct wl_signal update; + } input_panel_notification; + + struct weston_layer layout_layer; + + struct ivi_layout_transition_set *transitions; + struct wl_list pending_transition_list; /* transition_node::link */ + + struct wl_listener output_created; + struct wl_listener output_destroyed; + + struct { + struct ivi_layout_surface *ivisurf; + pixman_box32_t cursor_rectangle; + } text_input; +}; + +#endif // IVI_LAYOUT_STRUCTURE diff --git a/unittest/server/include/server_api_fake.h b/unittest/server/include/server_api_fake.h new file mode 100644 index 00000000..c9a1bb33 --- /dev/null +++ b/unittest/server/include/server_api_fake.h @@ -0,0 +1,233 @@ +/*************************************************************************** + * + * Copyright (C) 2023 Advanced Driver Information Technology Joint Venture GmbH + * + * + * 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. + * + ****************************************************************************/ + +#ifndef SERVER_API_FAKE +#define SERVER_API_FAKE + +#include "fff.h" +#include "ivi-wm-server-protocol.h" +#include "ivi-layout-export.h" +#include +#include "weston.h" +#include "common_fake_api.h" + +#ifdef __cplusplus +extern "C" { +#endif + +DECLARE_FAKE_VALUE_FUNC(struct weston_config_section *, weston_config_get_section, struct weston_config *, const char *, const char *, const char *); +DECLARE_FAKE_VALUE_FUNC(const void *, weston_plugin_api_get, struct weston_compositor *, const char *, size_t ); +DECLARE_FAKE_VALUE_FUNC(void *, weston_load_module, const char *, const char *, const char *); +DECLARE_FAKE_VALUE_FUNC(int, weston_config_section_get_bool, struct weston_config_section *, const char *, bool *, bool ); +DECLARE_FAKE_VALUE_FUNC(int, weston_config_section_get_string, struct weston_config_section *, const char *, char **, const char *); +DECLARE_FAKE_VALUE_FUNC(struct weston_view *, weston_view_create, struct weston_surface *); +DECLARE_FAKE_VALUE_FUNC(struct wl_client *, weston_client_start, struct weston_compositor *, const char *); +DECLARE_FAKE_VALUE_FUNC(int, weston_config_section_get_color, struct weston_config_section *, const char *, uint32_t *, uint32_t); +DECLARE_FAKE_VALUE_FUNC(int, weston_config_next_section, struct weston_config *, struct weston_config_section **, const char **); +DECLARE_FAKE_VALUE_FUNC(int, weston_config_section_get_int, struct weston_config_section *, const char *, int32_t *, int32_t); +DECLARE_FAKE_VALUE_FUNC(struct weston_config *, wet_get_config, struct weston_compositor *); +DECLARE_FAKE_VALUE_FUNC(int, weston_config_section_get_uint, struct weston_config_section *, const char *, uint32_t *, uint32_t); +DECLARE_FAKE_VALUE_FUNC(struct weston_view *, weston_compositor_pick_view, struct weston_compositor *, struct weston_coord_global); +DECLARE_FAKE_VALUE_FUNC(const char *, weston_desktop_surface_get_app_id, struct weston_desktop_surface *); +DECLARE_FAKE_VALUE_FUNC(const char *, weston_desktop_surface_get_title, struct weston_desktop_surface *); +DECLARE_FAKE_VALUE_FUNC(struct weston_desktop_surface *, weston_surface_get_desktop_surface, struct weston_surface *); +DECLARE_FAKE_VALUE_FUNC(struct weston_keyboard *, weston_seat_get_keyboard, struct weston_seat *); +DECLARE_FAKE_VALUE_FUNC(struct weston_pointer *, weston_seat_get_pointer, struct weston_seat *); +DECLARE_FAKE_VALUE_FUNC(struct weston_touch *, weston_seat_get_touch, struct weston_seat *); +DECLARE_FAKE_VALUE_FUNC(struct weston_surface *, weston_surface_get_main_surface, struct weston_surface *); +DECLARE_FAKE_VALUE_FUNC(bool, weston_touch_has_focus_resource, struct weston_touch *); +DECLARE_FAKE_VALUE_FUNC(struct wl_event_loop *, wl_display_get_event_loop, struct wl_display *); +DECLARE_FAKE_VALUE_FUNC(uint32_t, wl_display_next_serial, struct wl_display *); +DECLARE_FAKE_VALUE_FUNC(struct wl_event_source *, wl_event_loop_add_idle, struct wl_event_loop *, wl_event_loop_idle_func_t , void *); +DECLARE_FAKE_VALUE_FUNC(struct wl_global *, wl_global_create, struct wl_display *, const struct wl_interface *, int , void *, wl_global_bind_func_t); +DECLARE_FAKE_VALUE_FUNC(struct wl_resource *, wl_resource_create, struct wl_client *, const struct wl_interface *, int , uint32_t ); +DECLARE_FAKE_VALUE_FUNC(struct wl_resource *, wl_resource_from_link, struct wl_list *); +DECLARE_FAKE_VALUE_FUNC(struct wl_client *, wl_resource_get_client, struct wl_resource *); +DECLARE_FAKE_VALUE_FUNC(struct wl_list *, wl_resource_get_link, struct wl_resource *); +DECLARE_FAKE_VALUE_FUNC(void *, wl_resource_get_user_data, struct wl_resource *); +DECLARE_FAKE_VALUE_FUNC(int, wl_resource_get_version, struct wl_resource *); +DECLARE_FAKE_VOID_FUNC(weston_layer_entry_remove, struct weston_layer_entry *); +DECLARE_FAKE_VOID_FUNC(weston_layer_set_position, struct weston_layer *, enum weston_layer_position ); +DECLARE_FAKE_VOID_FUNC(weston_view_destroy, struct weston_view *); +DECLARE_FAKE_VOID_FUNC(weston_matrix_scale, struct weston_matrix *, float, float, float); +DECLARE_FAKE_VOID_FUNC(weston_matrix_init, struct weston_matrix *); +DECLARE_FAKE_VOID_FUNC(weston_surface_schedule_repaint, struct weston_surface *); +DECLARE_FAKE_VOID_FUNC(weston_surface_set_color, struct weston_surface *, float, float, float , float); +DECLARE_FAKE_VOID_FUNC(weston_compositor_schedule_repaint, struct weston_compositor *); +DECLARE_FAKE_VOID_FUNC(weston_output_damage, struct weston_output *); +DECLARE_FAKE_VOID_FUNC(weston_view_update_transform, struct weston_view *); +DECLARE_FAKE_VOID_FUNC(weston_matrix_translate, struct weston_matrix *, float, float, float); +DECLARE_FAKE_VOID_FUNC(weston_compositor_read_presentation_clock, const struct weston_compositor *, struct timespec *); +DECLARE_FAKE_VOID_FUNC(weston_layer_init, struct weston_layer *, struct weston_compositor *); +DECLARE_FAKE_VOID_FUNC(weston_layer_entry_insert, struct weston_layer_entry *, struct weston_layer_entry *); +DECLARE_FAKE_VOID_FUNC(weston_keyboard_send_keymap, struct weston_keyboard *, struct wl_resource *); +DECLARE_FAKE_VOID_FUNC(weston_keyboard_start_grab, struct weston_keyboard *, struct weston_keyboard_grab *); +DECLARE_FAKE_VOID_FUNC(weston_pointer_clear_focus, struct weston_pointer *); +DECLARE_FAKE_VOID_FUNC(weston_pointer_send_axis, struct weston_pointer *, const struct timespec *, struct weston_pointer_axis_event *); +DECLARE_FAKE_VOID_FUNC(weston_pointer_send_axis_source, struct weston_pointer *, enum wl_pointer_axis_source); +DECLARE_FAKE_VOID_FUNC(weston_pointer_send_button, struct weston_pointer *, const struct timespec *, uint32_t, enum wl_pointer_button_state); +DECLARE_FAKE_VOID_FUNC(weston_pointer_send_frame, struct weston_pointer *); +DECLARE_FAKE_VOID_FUNC(weston_pointer_send_motion, struct weston_pointer *, const struct timespec *, struct weston_pointer_motion_event *); +DECLARE_FAKE_VOID_FUNC(weston_pointer_set_focus, struct weston_pointer *, struct weston_view *); +DECLARE_FAKE_VOID_FUNC(weston_pointer_start_grab, struct weston_pointer *, struct weston_pointer_grab *); +DECLARE_FAKE_VOID_FUNC(weston_touch_send_down, struct weston_touch *, const struct timespec *, int , struct weston_coord_global ); +DECLARE_FAKE_VOID_FUNC(weston_touch_send_frame, struct weston_touch *); +DECLARE_FAKE_VOID_FUNC(weston_touch_send_motion, struct weston_touch *, const struct timespec *, int , struct weston_coord_global); +DECLARE_FAKE_VOID_FUNC(weston_touch_send_up, struct weston_touch *, const struct timespec *, int ); +DECLARE_FAKE_VOID_FUNC(weston_touch_set_focus, struct weston_touch *, struct weston_view *); +DECLARE_FAKE_VOID_FUNC(weston_touch_start_grab, struct weston_touch *, struct weston_touch_grab *); +DECLARE_FAKE_VOID_FUNC(weston_view_from_global_fixed, struct weston_view *, wl_fixed_t, wl_fixed_t, wl_fixed_t *, wl_fixed_t *); +DECLARE_FAKE_VOID_FUNC(wl_client_add_destroy_listener, struct wl_client *, struct wl_listener *); +DECLARE_FAKE_VOID_FUNC(wl_client_destroy, struct wl_client *); +DECLARE_FAKE_VOID_FUNC(wl_client_get_credentials, struct wl_client *, pid_t *, uid_t *, gid_t *); +DECLARE_FAKE_VOID_FUNC(wl_client_post_no_memory, struct wl_client *); +DECLARE_FAKE_VOID_FUNC(wl_resource_destroy, struct wl_resource *); +DECLARE_FAKE_VOID_FUNC(wl_resource_post_no_memory, struct wl_resource *); +DECLARE_FAKE_VOID_FUNC(wl_resource_set_destructor, struct wl_resource *, wl_resource_destroy_func_t ); +DECLARE_FAKE_VOID_FUNC(wl_resource_set_implementation, struct wl_resource *, const void *, void *, wl_resource_destroy_func_t); +DECLARE_FAKE_VALUE_FUNC_VARARG(int, weston_log, const char *, ...); +DECLARE_FAKE_VOID_FUNC_VARARG(wl_resource_post_event, struct wl_resource *, uint32_t, ...); +DECLARE_FAKE_VALUE_FUNC(void *, wl_array_add, struct wl_array *, size_t); +DECLARE_FAKE_VOID_FUNC(wl_list_insert, struct wl_list *, struct wl_list *); +DECLARE_FAKE_VOID_FUNC(wl_array_init, struct wl_array *); +DECLARE_FAKE_VOID_FUNC(wl_array_release, struct wl_array *); +DECLARE_FAKE_VOID_FUNC(wl_list_init, struct wl_list *); +DECLARE_FAKE_VOID_FUNC(wl_list_remove, struct wl_list *); +DECLARE_FAKE_VALUE_FUNC(int, wl_list_empty, const struct wl_list *); +DECLARE_FAKE_VALUE_FUNC(int32_t, wl_shm_buffer_get_stride, struct wl_shm_buffer *); +DECLARE_FAKE_VALUE_FUNC(int32_t, wl_shm_buffer_get_width, struct wl_shm_buffer *); +DECLARE_FAKE_VALUE_FUNC(int32_t, wl_shm_buffer_get_height, struct wl_shm_buffer *); +DECLARE_FAKE_VALUE_FUNC(void *, wl_shm_buffer_get_data, struct wl_shm_buffer *); +DECLARE_FAKE_VALUE_FUNC(int, wl_list_length, const struct wl_list *); +DECLARE_FAKE_VOID_FUNC_VARARG(wl_client_post_implementation_error,struct wl_client *, char const *, ...); +DECLARE_FAKE_VOID_FUNC(weston_keyboard_end_grab, struct weston_keyboard *); +DECLARE_FAKE_VOID_FUNC(weston_pointer_end_grab, struct weston_pointer *); +DECLARE_FAKE_VOID_FUNC(weston_touch_end_grab, struct weston_touch *); +DECLARE_FAKE_VOID_FUNC(weston_output_schedule_repaint, struct weston_output *); +DECLARE_FAKE_VALUE_FUNC(pixman_bool_t, pixman_region32_union, pixman_region32_t *, pixman_region32_t *, pixman_region32_t *); +DECLARE_FAKE_VALUE_FUNC(struct weston_buffer *, weston_buffer_from_resource, struct weston_compositor *, struct wl_resource *); +DECLARE_FAKE_VOID_FUNC(weston_view_geometry_dirty, struct weston_view *); +DECLARE_FAKE_VALUE_FUNC(int, weston_screenshooter_shoot, struct weston_output *, struct weston_buffer *, weston_screenshooter_done_func_t, void *); +DECLARE_FAKE_VOID_FUNC(weston_surface_map, struct weston_surface *); +DECLARE_FAKE_VALUE_FUNC(bool, weston_surface_has_content, struct weston_surface *); +DECLARE_FAKE_VALUE_FUNC(bool, weston_surface_is_mapped, struct weston_surface *); + +#define SERVER_API_FAKE_LIST(FAKE) \ + FAKE(weston_config_get_section) \ + FAKE(weston_plugin_api_get) \ + FAKE(weston_load_module) \ + FAKE(weston_config_section_get_string) \ + FAKE(weston_config_section_get_bool) \ + FAKE(weston_view_create) \ + FAKE(weston_client_start) \ + FAKE(weston_config_section_get_color) \ + FAKE(weston_config_next_section) \ + FAKE(weston_config_section_get_int) \ + FAKE(wet_get_config) \ + FAKE(weston_config_section_get_uint) \ + FAKE(weston_compositor_pick_view) \ + FAKE(weston_desktop_surface_get_app_id) \ + FAKE(weston_desktop_surface_get_title) \ + FAKE(weston_surface_get_desktop_surface) \ + FAKE(weston_seat_get_keyboard) \ + FAKE(weston_seat_get_pointer) \ + FAKE(weston_seat_get_touch) \ + FAKE(weston_surface_get_main_surface) \ + FAKE(weston_touch_has_focus_resource) \ + FAKE(wl_display_get_event_loop) \ + FAKE(wl_display_next_serial) \ + FAKE(wl_event_loop_add_idle) \ + FAKE(wl_global_create) \ + FAKE(wl_resource_create) \ + FAKE(wl_resource_get_client) \ + FAKE(wl_resource_get_user_data) \ + FAKE(wl_resource_get_version) \ + FAKE(weston_layer_entry_remove) \ + FAKE(weston_layer_set_position) \ + FAKE(weston_view_destroy) \ + FAKE(weston_matrix_scale) \ + FAKE(weston_matrix_init) \ + FAKE(weston_surface_schedule_repaint) \ + FAKE(weston_surface_set_color) \ + FAKE(weston_compositor_schedule_repaint) \ + FAKE(weston_output_damage) \ + FAKE(weston_view_update_transform) \ + FAKE(weston_matrix_translate) \ + FAKE(weston_compositor_read_presentation_clock) \ + FAKE(weston_layer_init) \ + FAKE(weston_layer_entry_insert) \ + FAKE(weston_keyboard_send_keymap) \ + FAKE(weston_keyboard_start_grab) \ + FAKE(weston_pointer_clear_focus) \ + FAKE(weston_pointer_send_axis) \ + FAKE(weston_pointer_send_axis_source) \ + FAKE(weston_pointer_send_button) \ + FAKE(weston_pointer_send_frame) \ + FAKE(weston_pointer_send_motion) \ + FAKE(weston_pointer_set_focus) \ + FAKE(weston_pointer_start_grab) \ + FAKE(weston_touch_send_down) \ + FAKE(weston_touch_send_frame) \ + FAKE(weston_touch_send_motion ) \ + FAKE(weston_touch_send_up) \ + FAKE(weston_touch_set_focus) \ + FAKE(weston_touch_start_grab) \ + FAKE(weston_view_from_global_fixed) \ + FAKE(wl_client_add_destroy_listener) \ + FAKE(wl_client_destroy) \ + FAKE(wl_client_get_credentials) \ + FAKE(wl_client_post_no_memory) \ + FAKE(wl_resource_destroy) \ + FAKE(wl_resource_post_no_memory) \ + FAKE(wl_resource_set_destructor) \ + FAKE(wl_resource_set_implementation) \ + FAKE(wl_resource_post_event) \ + FAKE(wl_array_add) \ + FAKE(wl_list_insert) \ + FAKE(wl_array_init) \ + FAKE(wl_array_release) \ + FAKE(wl_list_init) \ + FAKE(wl_list_remove) \ + FAKE(wl_list_empty) \ + FAKE(wl_shm_buffer_get_stride) \ + FAKE(wl_shm_buffer_get_width) \ + FAKE(wl_shm_buffer_get_height) \ + FAKE(wl_shm_buffer_get_data) \ + FAKE(weston_keyboard_end_grab) \ + FAKE(weston_pointer_end_grab) \ + FAKE(weston_touch_end_grab) \ + FAKE(weston_output_schedule_repaint) \ + FAKE(pixman_region32_union) \ + FAKE(weston_buffer_from_resource) \ + FAKE(weston_view_geometry_dirty) \ + FAKE(weston_screenshooter_shoot) \ + FAKE(weston_surface_map) \ + FAKE(weston_surface_has_content) \ + FAKE(weston_surface_is_mapped) \ + FAKE(wl_list_length) \ + FAKE(wl_client_post_implementation_error) \ + FFF_RESET_HISTORY() + // FAKE(weston_log) // make a common custom weston_log to print the log + +int custom_weston_log(const char *format, va_list ap); + +#ifdef __cplusplus +} +#endif +#endif // SERVER_API_FAKE diff --git a/unittest/server/src/ivi_controller_uinttests.cpp b/unittest/server/src/ivi_controller_uinttests.cpp new file mode 100644 index 00000000..eaae0997 --- /dev/null +++ b/unittest/server/src/ivi_controller_uinttests.cpp @@ -0,0 +1,3475 @@ +/*************************************************************************** + * + * Copyright (C) 2023 Advanced Driver Information Technology Joint Venture GmbH + * + * + * 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. + * + ****************************************************************************/ + +#include +#include +#include +#include "server_api_fake.h" +#include "ivi_layout_interface_fake.h" +#include "ivi_layout_structure.hpp" + +enum { + WESTON_BUFFER_SHM, + WESTON_BUFFER_DMABUF, + WESTON_BUFFER_RENDERER_OPAQUE, + WESTON_BUFFER_SOLID, +} type; + +extern "C" +{ +WL_EXPORT const struct wl_interface wl_buffer_interface = { + "wl_buffer", 1, + 0, NULL, + 0, NULL, +}; + +WL_EXPORT const struct wl_interface wl_output_interface = { + "wl_output", 4, + 0, NULL, + 0, NULL, +}; + +struct wl_resource * custom_wl_resource_from_link(struct wl_list *link) +{ + struct wl_resource *resource; + + return wl_container_of(link, resource, link); +} + +struct wl_list * custom_wl_resource_get_link(struct wl_resource *resource) +{ + return &resource->link; +} + +#include "ivi-controller.c" +} + +static constexpr uint8_t MAX_NUMBER = 2; +static uint32_t g_SurfaceCreatedCount = 0; +static uint32_t custom_get_id_of_surface(struct ivi_layout_surface *ivisurf) +{ + return ivisurf->id_surface; +} + +static uint32_t custom_get_id_of_layer(struct ivi_layout_layer *ivilayer) +{ + return ivilayer->id_layer; +} + +static int32_t custom_get_layers_on_screen(struct weston_output *output, int32_t *pLength, + struct ivi_layout_layer ***ppArray) +{ + struct ivi_layout_layer ivilayer; + ivilayer.id_layer = 1; + + *pLength = 1; + *ppArray = (ivi_layout_layer**)malloc(sizeof(struct ivi_layout_layer *)); + (*ppArray)[0] = &ivilayer; + + return 0; +} + +static int32_t custom_get_surfaces_on_layer(struct ivi_layout_layer *ivilayer, int32_t *pLength, + struct ivi_layout_surface ***ppArray) +{ + struct ivi_layout_surface ivisurface; + ivisurface.id_surface = 1; + + *pLength = 1; + *ppArray = (ivi_layout_surface**)malloc(sizeof(struct ivi_layout_surface *)); + (*ppArray)[0] = &ivisurface; + + return 0; +} + +static int32_t custom_surface_get_size(struct ivi_layout_surface *ivisurf, int32_t *width, int32_t *height, + int32_t *stride) +{ + *width = 1; + *height = 1; + *stride = 1; + + return 0; +} + +static int custom_read_pixels(struct weston_output *output, + pixman_format_code_t format, void *pixels, + uint32_t x, uint32_t y, + uint32_t width, uint32_t height) +{ + return x == 0 || y == 0; +} + +static void surface_create_callback(struct wl_listener *listener, void *data) +{ + g_SurfaceCreatedCount++; +} + +class ControllerTests : public ::testing::Test +{ +public: + void SetUp() + { + IVI_LAYOUT_FAKE_LIST(RESET_FAKE); + SERVER_API_FAKE_LIST(RESET_FAKE); + get_id_of_surface_fake.custom_fake = custom_get_id_of_surface; + get_id_of_layer_fake.custom_fake = custom_get_id_of_layer; + get_layers_on_screen_fake.custom_fake = custom_get_layers_on_screen; + get_surfaces_on_layer_fake.custom_fake = custom_get_surfaces_on_layer; + surface_get_size_fake.custom_fake = custom_surface_get_size; + g_SurfaceCreatedCount = 0; + init_controller_content(); + } + + void TearDown() + { + deinit_controller_content(); + } + + void init_controller_content() + { + uint8_t l_fakeResource = 0, l_fakeClient = 0; + mp_iviShell = (struct ivishell *)malloc(sizeof(struct ivishell)); + mp_iviShell->interface = &g_iviLayoutInterfaceFake; + mp_iviShell->compositor = &m_westonCompositor; + mp_iviShell->bkgnd_surface_id = 1; + mp_iviShell->bkgnd_surface = nullptr; + mp_iviShell->bkgnd_view = nullptr; + mp_iviShell->client = nullptr; + mp_iviShell->screen_id_offset = 1000; + custom_wl_array_init(&mp_iviShell->screen_ids); + mp_screenInfo = (struct screen_id_info *)custom_wl_array_add(&mp_iviShell->screen_ids, sizeof(struct screen_id_info)); + mp_screenInfo->screen_name = (char *)"default_screen"; + mp_screenInfo->screen_id = 0; + + custom_wl_list_init(&m_westonCompositor.output_list); + custom_wl_list_init(&mp_iviShell->list_surface); + custom_wl_list_init(&mp_iviShell->list_layer); + custom_wl_list_init(&mp_iviShell->list_screen); + custom_wl_list_init(&mp_iviShell->list_controller); + custom_wl_list_init(&mp_iviShell->ivisurface_created_signal.listener_list); + custom_wl_list_init(&mp_iviShell->ivisurface_removed_signal.listener_list); + + for(uint8_t i = 0; i < MAX_NUMBER; i++) + { + // Prepare layout surfaces prperties + m_layoutSurface[i].id_surface = i + 10; + m_layoutSurfaceProperties[i].opacity = 1000 + i*100; + m_layoutSurfaceProperties[i].source_x = 0; + m_layoutSurfaceProperties[i].source_y = 0; + m_layoutSurfaceProperties[i].source_width = 100 + i*10; + m_layoutSurfaceProperties[i].source_height = 100 + i*10; + m_layoutSurfaceProperties[i].start_x = 0; + m_layoutSurfaceProperties[i].start_y = 0; + m_layoutSurfaceProperties[i].start_width = 50 + i*20; + m_layoutSurfaceProperties[i].start_height = 50 + i*20; + m_layoutSurfaceProperties[i].dest_x = 0; + m_layoutSurfaceProperties[i].dest_y = 0; + m_layoutSurfaceProperties[i].dest_width = 300 + i*5; + m_layoutSurfaceProperties[i].dest_height = 300 + i*5; + m_layoutSurfaceProperties[i].orientation = WL_OUTPUT_TRANSFORM_NORMAL; + m_layoutSurfaceProperties[i].visibility = true; + m_layoutSurfaceProperties[i].transition_type = 1; + m_layoutSurfaceProperties[i].transition_duration = 20; + m_layoutSurfaceProperties[i].event_mask = 0xFFFFFFFF; + + // Prepare the ivi surface + mp_iviSurface[i] = (struct ivisurface*)malloc(sizeof(struct ivisurface)); + mp_iviSurface[i]->shell = mp_iviShell; + mp_iviSurface[i]->layout_surface = &m_layoutSurface[i]; + mp_iviSurface[i]->prop = &m_layoutSurfaceProperties[i]; + mp_iviSurface[i]->type = IVI_WM_SURFACE_TYPE_DESKTOP; + custom_wl_list_insert(&mp_iviShell->list_surface, &mp_iviSurface[i]->link); + + // the client callback, it listen the change from specific ivi surface id + mp_surfaceNotification[i] = (struct notification*)malloc(sizeof(struct notification)); + mp_surfaceNotification[i]->resource = (struct wl_resource*)((uintptr_t)mp_wlResourceDefault + i); + custom_wl_list_init(&mp_iviSurface[i]->notification_list); + custom_wl_list_insert(&mp_iviSurface[i]->notification_list, &mp_surfaceNotification[i]->layout_link); + + // Prepare layout layer properties + m_layoutLayer[i].id_layer = i + 100; + m_layoutLayerProperties[i].opacity = 1000 + i*100; + m_layoutLayerProperties[i].source_x = 0; + m_layoutLayerProperties[i].source_y = 0; + m_layoutLayerProperties[i].source_width = 100 + i*10; + m_layoutLayerProperties[i].source_height = 100 + i*10; + m_layoutLayerProperties[i].dest_x = 0; + m_layoutLayerProperties[i].dest_y = 0; + m_layoutLayerProperties[i].dest_width = 300 + i*5; + m_layoutLayerProperties[i].dest_height = 300 + i*5; + m_layoutLayerProperties[i].orientation = WL_OUTPUT_TRANSFORM_NORMAL; + m_layoutLayerProperties[i].visibility = true; + m_layoutLayerProperties[i].transition_type = 1; + m_layoutLayerProperties[i].transition_duration = 20; + m_layoutLayerProperties[i].start_alpha = 0.1; + m_layoutLayerProperties[i].end_alpha = 10.0; + m_layoutLayerProperties[i].is_fade_in = 1 ; + m_layoutLayerProperties[i].event_mask = 0 ; + + // Prepare the ivi layer + mp_iviLayer[i] = (struct ivilayer *)malloc(sizeof(struct ivilayer)); + mp_iviLayer[i]->shell = mp_iviShell; + mp_iviLayer[i]->layout_layer = &m_layoutLayer[i]; + mp_iviLayer[i]->prop = &m_layoutLayerProperties[i]; + custom_wl_list_insert(&mp_iviShell->list_layer, &mp_iviLayer[i]->link); + + // The client callback, it lusten the change from specific ivi layer id + mp_LayerNotification[i] = (struct notification *)malloc(sizeof(struct notification)); + mp_LayerNotification[i]->resource = (struct wl_resource*)((uintptr_t)mp_wlResourceDefault + i); + custom_wl_list_init(&mp_iviLayer[i]->notification_list); + custom_wl_list_insert(&mp_iviLayer[i]->notification_list, &mp_LayerNotification[i]->layout_link); + + // Prepare the ivi screens + m_westonOutput[i].id = i + 1000; + mp_iviScreen[i] = (struct iviscreen*)malloc(sizeof(struct iviscreen)); + mp_iviScreen[i]->shell = mp_iviShell; + mp_iviScreen[i]->output = &m_westonOutput[i]; + mp_iviScreen[i]->id_screen = m_westonOutput[i].id; + custom_wl_list_init(&mp_iviScreen[i]->resource_list); + custom_wl_list_insert(&mp_iviShell->list_screen, &mp_iviScreen[i]->link); + + // Prepare sample controllers + mp_iviController[i] = (struct ivicontroller*)malloc(sizeof(struct ivicontroller)); + mp_iviController[i]->resource = (struct wl_resource*)&l_fakeResource; + mp_iviController[i]->client = (struct wl_client*)&l_fakeClient; + mp_iviController[i]->shell = mp_iviShell; + mp_iviController[i]->id = i; + custom_wl_list_insert(&mp_iviShell->list_controller, &mp_iviController[i]->link); + + // Prepare handler for new surfaces + m_listenSurface[i].notify = surface_create_callback; + custom_wl_list_insert(mp_iviShell->ivisurface_created_signal.listener_list.prev, &m_listenSurface[i].link); + } + } + + void deinit_controller_content() + { + for(uint8_t i = 0; i < MAX_NUMBER; i++) + { + free(mp_surfaceNotification[i]); + free(mp_iviSurface[i]); + free(mp_LayerNotification[i]); + free(mp_iviLayer[i]); + free(mp_iviScreen[i]); + free(mp_iviController[i]); + } + custom_wl_array_release(&mp_iviShell->screen_ids); + free(mp_iviShell); + } + + void enable_utility_funcs_of_array_list() + { + wl_list_init_fake.custom_fake = custom_wl_list_init; + wl_list_insert_fake.custom_fake = custom_wl_list_insert; + wl_list_remove_fake.custom_fake = custom_wl_list_remove; + wl_list_empty_fake.custom_fake = custom_wl_list_empty; + wl_array_init_fake.custom_fake = custom_wl_array_init; + wl_array_release_fake.custom_fake = custom_wl_array_release; + wl_array_add_fake.custom_fake = custom_wl_array_add; + wl_signal_init(&m_westonCompositor.output_created_signal); + wl_signal_init(&m_westonCompositor.output_destroyed_signal); + wl_signal_init(&m_westonCompositor.output_resized_signal); + wl_signal_init(&m_westonCompositor.destroy_signal); + } + + struct wl_resource *mp_wlResourceDefault = (struct wl_resource *)0xFFFFFF00; + struct weston_buffer *mp_westonBuffer = (struct weston_buffer *)0xFFFFFF00; + + struct wl_listener m_listenSurface[MAX_NUMBER] = {}; + struct ivisurface *mp_iviSurface[MAX_NUMBER] = {nullptr}; + struct ivi_layout_surface m_layoutSurface[MAX_NUMBER] = {}; + struct ivi_layout_surface_properties m_layoutSurfaceProperties[MAX_NUMBER] = {}; + struct notification *mp_surfaceNotification[MAX_NUMBER] = {nullptr}; + + struct ivilayer *mp_iviLayer[MAX_NUMBER] = {nullptr}; + struct ivi_layout_layer m_layoutLayer[MAX_NUMBER] = {}; + struct ivi_layout_layer_properties m_layoutLayerProperties[MAX_NUMBER] = {}; + struct notification *mp_LayerNotification[MAX_NUMBER] = {nullptr}; + + struct iviscreen *mp_iviScreen[MAX_NUMBER] = {nullptr}; + struct weston_output m_westonOutput[MAX_NUMBER] = {}; + + struct ivicontroller *mp_iviController[MAX_NUMBER] = {nullptr}; + + struct ivishell *mp_iviShell = nullptr; + struct weston_compositor m_westonCompositor = {}; + + struct screen_id_info *mp_screenInfo = nullptr; + + struct wl_client *mp_fakeClient = nullptr; + + static int ms_idAgentModuleValue; + static int ms_inputControllerModuleValue; + static uint32_t ms_screenIdOffset; + static uint32_t ms_screenId; + static char *ms_iviClientName; + static char *ms_debugScopes; + static char *ms_screenName; + static int32_t ms_bkgndSurfaceId; + static uint32_t ms_bkgndColor; + static bool ms_enableCursor; + static uint32_t ms_westonConfigNextSection; + + int mp_successResult[1] = {0}; + int mp_failureResult[1] = {-1}; +}; + +int ControllerTests::ms_idAgentModuleValue = 0; +int ControllerTests::ms_inputControllerModuleValue = 0; +uint32_t ControllerTests::ms_screenIdOffset = 0; +uint32_t ControllerTests::ms_screenId = 0; +char *ControllerTests::ms_iviClientName = nullptr; +char *ControllerTests::ms_debugScopes = nullptr; +char *ControllerTests::ms_screenName = nullptr; +int32_t ControllerTests::ms_bkgndSurfaceId = 0; +uint32_t ControllerTests::ms_bkgndColor = 0; +bool ControllerTests::ms_enableCursor = false; +uint32_t ControllerTests::ms_westonConfigNextSection = 0; + +static int custom_id_agent_module_init(struct weston_compositor *compositor, const struct ivi_layout_interface *interface) +{ + return ControllerTests::ms_idAgentModuleValue; +} +static int custom_input_controller_module_init(struct ivishell *shell) +{ + return ControllerTests::ms_inputControllerModuleValue; +} + +static int custom_weston_config_section_get_uint(struct weston_config_section *section, const char *key, uint32_t *value, uint32_t default_value) +{ + if(strcmp(key, "screen-id-offset") == 0) + { + *value = ControllerTests::ms_screenIdOffset; + } + else if(strcmp(key, "screen-id") == 0) + { + *value = ControllerTests::ms_screenId; + } + return 0; +} + +static int custom_weston_config_section_get_string(struct weston_config_section *section, const char *key, char **value, const char *default_value) +{ + if(strcmp(key, "ivi-client-name") == 0) + { + *value = (ControllerTests::ms_iviClientName == nullptr) ? nullptr : strdup(ControllerTests::ms_iviClientName); + } + else if(strcmp(key, "debug-scopes") == 0) + { + *value = (ControllerTests::ms_debugScopes == nullptr) ? nullptr : strdup(ControllerTests::ms_debugScopes); + } + else if(strcmp(key, "screen-name") == 0) + { + *value = (ControllerTests::ms_screenName == nullptr) ? nullptr : strdup(ControllerTests::ms_screenName); + } + return 0; +} + +static int custom_weston_config_section_get_int(struct weston_config_section *section, const char *key, int32_t *value, int32_t default_value) +{ + if(strcmp(key, "bkgnd-surface-id") == 0) + { + *value = ControllerTests::ms_bkgndSurfaceId; + } + return 0; +} + +static int custom_weston_config_section_get_color(struct weston_config_section *section, const char *key, uint32_t *color, uint32_t default_color) +{ + if(strcmp(key, "bkgnd-color") == 0) + { + *color = ControllerTests::ms_bkgndColor; + } + return 0; +} + +static int custom_weston_config_section_get_bool(struct weston_config_section *section, const char *key, bool *value, bool default_value) +{ + if(strcmp(key, "enable-cursor") == 0) + { + *value = ControllerTests::ms_enableCursor; + } + return 0; +} + +static int custom_weston_config_next_section(struct weston_config *config, struct weston_config_section **section, const char **name) +{ + switch (ControllerTests::ms_westonConfigNextSection) + { + case 0: + { + *name = "ivi-screen"; + ControllerTests::ms_westonConfigNextSection ++; + return 1; + } + case 1: + { + *name = nullptr; + } + default: + break; + } + return 0; +} + +/** ================================================================================================ + * @test_id send_surface_prop_noEvents + * @brief Test case of send_surface_prop() where event mask of ivi surface is 0 + * @test_procedure Steps: + * -# Set event mask of ivi surface is 0 + * -# Calling the send_surface_prop() + * -# Verification point: + * +# get_id_of_surface() must be called once time + * +# wl_resource_get_user_data() must be called once time + * +# wl_resource_post_event() not be called + */ +TEST_F(ControllerTests, send_surface_prop_noEvents) +{ + m_layoutSurfaceProperties[0].event_mask = 0; + + send_surface_prop(&mp_iviSurface[0]->property_changed, nullptr); + + ASSERT_EQ(get_id_of_surface_fake.call_count, 1); + ASSERT_EQ(wl_resource_get_user_data_fake.call_count, 1); + ASSERT_EQ(wl_resource_post_event_fake.call_count, 0); +} + +/** ================================================================================================ + * @test_id send_surface_prop_hasEvents + * @brief Test case of send_surface_prop() where event mask of ivi surface is the change of all properties + * @test_procedure Steps: + * -# Set event mask of ivi surface is the change of all properties + * -# Mocking the surface_get_weston_surface() does return an object + * -# Mocking the wl_resource_get_user_data() does return an object + * -# Calling the send_surface_prop() + * -# Verification point: + * +# get_id_of_surface() must be called once time + * +# wl_resource_get_user_data() must be called once time + * +# wl_resource_post_event() must be called 5 times + */ +TEST_F(ControllerTests, send_surface_prop_hasEvents) +{ + m_layoutSurfaceProperties[0].event_mask = IVI_NOTIFICATION_OPACITY | IVI_NOTIFICATION_SOURCE_RECT | + IVI_NOTIFICATION_DEST_RECT | IVI_NOTIFICATION_VISIBILITY| + IVI_NOTIFICATION_CONFIGURE; + + struct weston_surface l_westonSurface; + l_westonSurface.width = 1920; + l_westonSurface.height = 1080; + struct weston_surface *lp_westonSurface = &l_westonSurface; + SET_RETURN_SEQ(surface_get_weston_surface, &lp_westonSurface, 1); + SET_RETURN_SEQ(wl_resource_get_user_data, (void**)mp_iviController, 1); + + send_surface_prop(&mp_iviSurface[0]->property_changed, nullptr); + + ASSERT_EQ(get_id_of_surface_fake.call_count, 1); + ASSERT_EQ(wl_resource_get_user_data_fake.call_count, 1); + ASSERT_EQ(wl_resource_post_event_fake.call_count, 5); +} + +/** ================================================================================================ + * @test_id send_layer_prop_noEvents + * @brief Test case of send_layer_prop() where event mask of ivi layer is 0 + * @test_procedure Steps: + * -# Set event mask of ivi layer is 0 + * -# Calling the send_layer_prop() + * -# Verification point: + * +# get_id_of_layer() must be called once time + * +# wl_resource_get_user_data() must be called once time + * +# wl_resource_post_event() not be called + */ +TEST_F(ControllerTests, send_layer_prop_noEvents) +{ + m_layoutLayerProperties[0].event_mask = 0; + + send_layer_prop(&mp_iviLayer[0]->property_changed, nullptr); + + ASSERT_EQ(get_id_of_layer_fake.call_count, 1); + ASSERT_EQ(wl_resource_get_user_data_fake.call_count, 1); + ASSERT_EQ(wl_resource_post_event_fake.call_count, 0); +} + +/** ================================================================================================ + * @test_id send_layer_prop_hasEvents + * @brief Test case of send_layer_prop() where event mask of ivi layer is the change of all properties + * @test_procedure Steps: + * -# Set event mask of ivi layer is the change of all properties + * -# Mocking the wl_resource_get_user_data() does return an object + * -# Calling the send_layer_prop() + * -# Verification point: + * +# get_id_of_layer() must be called once time + * +# wl_resource_get_user_data() must be called once time + * +# wl_resource_post_event() must be called 4 times + */ +TEST_F(ControllerTests, send_layer_prop_hasEvents) +{ + m_layoutLayerProperties[0].event_mask = IVI_NOTIFICATION_OPACITY | IVI_NOTIFICATION_SOURCE_RECT | + IVI_NOTIFICATION_DEST_RECT | IVI_NOTIFICATION_VISIBILITY; + + SET_RETURN_SEQ(wl_resource_get_user_data, (void**)mp_iviController, 1); + + send_layer_prop(&mp_iviLayer[0]->property_changed, nullptr); + + ASSERT_EQ(get_id_of_layer_fake.call_count, 1); + ASSERT_EQ(wl_resource_get_user_data_fake.call_count, 1); + ASSERT_EQ(wl_resource_post_event_fake.call_count, 4); +} + +/** ================================================================================================ + * @test_id surface_event_create_idDifferentBkgnSurfaceId + * @brief Test case of surface_event_create() where id_surface different bkgnd_surface_id + * @test_procedure Steps: + * -# Set id_surface and bkgnd_surface_id + * -# Mocking the surface_get_weston_surface() does return an object + * -# Calling the surface_event_create() + * -# Verification point: + * +# get_id_of_surface() must be called once time + * +# get_properties_of_surface() must be called once time + * +# wl_list_init() must be called once time + * +# surface_get_weston_surface() must be called once time + * +# wl_list_insert() must be called 2 times + * +# surface_add_listener() must be called once time + * +# wl_resource_post_event() must be called {MAX_NUMBER} times + * +# The result output should same with prepare data + * +# Free resources are allocated when running the test + */ +TEST_F(ControllerTests, surface_event_create_idDifferentBkgnSurfaceId) +{ + struct ivi_layout_surface l_layoutSurface; + l_layoutSurface.id_surface = 2; + mp_iviShell->bkgnd_surface_id = 1; + + struct weston_surface *lp_westonSurface = (struct weston_surface *)malloc(sizeof(struct weston_surface)); + SET_RETURN_SEQ(surface_get_weston_surface, &lp_westonSurface, 1); + + surface_event_create(&mp_iviShell->surface_created, &l_layoutSurface); + + ASSERT_EQ(get_id_of_surface_fake.call_count, 1); + ASSERT_EQ(get_properties_of_surface_fake.call_count, 1); + ASSERT_EQ(wl_list_init_fake.call_count, 1); + ASSERT_EQ(surface_get_weston_surface_fake.call_count, 1); + ASSERT_EQ(wl_list_insert_fake.call_count, 2); + ASSERT_EQ(surface_add_listener_fake.call_count, 1); + ASSERT_EQ(wl_resource_post_event_fake.call_count, MAX_NUMBER); + ASSERT_EQ(MAX_NUMBER, g_SurfaceCreatedCount); + struct ivisurface *lp_iviSurf = (struct ivisurface*)(uintptr_t(wl_list_init_fake.arg0_history[0]) - offsetof(struct ivisurface, notification_list)); + ASSERT_EQ(lp_iviSurf->shell, mp_iviShell); + ASSERT_EQ(lp_iviSurf->layout_surface, &l_layoutSurface); + ASSERT_EQ(mp_iviShell->bkgnd_surface, nullptr); + + free(lp_iviSurf); + free(lp_westonSurface); +} + +/** ================================================================================================ + * @test_id surface_event_create_idSameBkgnSurfaceId + * @brief Test case of surface_event_create() where id_surface same bkgnd_surface_id + * @test_procedure Steps: + * -# Set id_surface and bkgnd_surface_id + * -# Mocking the surface_get_weston_surface() does return an object + * -# Calling the surface_event_create() + * -# Verification point: + * +# get_id_of_surface() must be called once time + * +# get_properties_of_surface() must be called once time + * +# wl_list_init() must be called once time + * +# surface_get_weston_surface() must be called once time + * +# wl_list_insert() must be called once time + * +# surface_add_listener() not be called + * +# wl_resource_post_event() not be called + * +# The result output should same with prepare data + * +# Free resources are allocated when running the test + */ +TEST_F(ControllerTests, surface_event_create_idSameBkgnSurfaceId) +{ + struct ivi_layout_surface l_layoutSurface; + l_layoutSurface.id_surface = 1; + mp_iviShell->bkgnd_surface_id = 1; + + struct weston_surface *lp_westonSurface = (struct weston_surface *)malloc(sizeof(struct weston_surface)); + SET_RETURN_SEQ(surface_get_weston_surface, &lp_westonSurface, 1); + + surface_event_create(&mp_iviShell->surface_created, &l_layoutSurface); + + ASSERT_EQ(get_id_of_surface_fake.call_count, 1); + ASSERT_EQ(get_properties_of_surface_fake.call_count, 1); + ASSERT_EQ(wl_list_init_fake.call_count, 1); + ASSERT_EQ(surface_get_weston_surface_fake.call_count, 1); + ASSERT_EQ(wl_list_insert_fake.call_count, 1); + ASSERT_EQ(surface_add_listener_fake.call_count, 0); + ASSERT_EQ(wl_resource_post_event_fake.call_count, 0); + ASSERT_EQ(0, g_SurfaceCreatedCount); + struct ivisurface *lp_iviSurf = (struct ivisurface*)(uintptr_t(wl_list_init_fake.arg0_history[0]) - offsetof(struct ivisurface, notification_list)); + ASSERT_EQ(lp_iviSurf->shell, mp_iviShell); + ASSERT_EQ(lp_iviSurf->layout_surface, &l_layoutSurface); + ASSERT_EQ(mp_iviShell->bkgnd_surface, lp_iviSurf); + + free(lp_iviSurf); + free(lp_westonSurface); +} + +/** ================================================================================================ + * @test_id layer_event_create + * @brief Test case of layer_event_create() where valid input params + * @test_procedure Steps: + * -# Set id layer of layout layer + * -# Calling the layer_event_create() + * -# Verification point: + * +# get_id_of_layer() must be called once time + * +# wl_list_insert() must be called once time + * +# wl_list_init() must be called once time + * +# get_properties_of_layer() must be called once time + * +# layer_add_listener() must be called once time + * +# wl_resource_post_event() must be called {MAX_NUMBER} times + * +# The result output should same with prepare data + * +# Free resources are allocated when running the test + */ +TEST_F(ControllerTests, layer_event_create) +{ + struct ivi_layout_layer l_layoutLayer; + l_layoutLayer.id_layer = 10; + + layer_event_create(&mp_iviShell->layer_created, &l_layoutLayer); + + ASSERT_EQ(get_id_of_layer_fake.call_count, 1); + ASSERT_EQ(wl_list_insert_fake.call_count, 1); + ASSERT_EQ(wl_list_init_fake.call_count, 1); + ASSERT_EQ(get_properties_of_layer_fake.call_count, 1); + ASSERT_EQ(layer_add_listener_fake.call_count, 1); + ASSERT_EQ(wl_resource_post_event_fake.call_count, MAX_NUMBER); + struct ivilayer *lp_iviLayer = (struct ivilayer*)(uintptr_t(wl_list_init_fake.arg0_history[0]) - offsetof(struct ivilayer, notification_list)); + ASSERT_EQ(lp_iviLayer->shell, mp_iviShell); + ASSERT_EQ(lp_iviLayer->layout_layer, &l_layoutLayer); + + free(lp_iviLayer); +} + +/** ================================================================================================ + * @test_id output_created_event_customScreen + * @brief Test case of output_created_event() where weston output is a custom name + * different screen info default + * @test_procedure Steps: + * -# Set weston output with name is "custom_screen" and id is 1 + * -# Calling the output_created_event() + * -# Verification point: + * +# wl_list_insert() must be called once time + * +# wl_list_init() must be called once time + * +# weston_compositor_schedule_repaint() must be called once time + * +# The result output should same with prepare data + * +# Free resources are allocated when running the test + */ +TEST_F(ControllerTests, output_created_event_customScreen) +{ + struct weston_output l_createdOutput; + l_createdOutput.id = 1; + l_createdOutput.name = (char*)"custom_screen"; + + output_created_event(&mp_iviShell->output_created, &l_createdOutput); + + ASSERT_EQ(wl_list_insert_fake.call_count, 1); + ASSERT_EQ(wl_list_init_fake.call_count, 1); + ASSERT_EQ(weston_compositor_schedule_repaint_fake.call_count, 1); + struct iviscreen *lp_iviScreen = (struct iviscreen*)(uintptr_t(wl_list_init_fake.arg0_history[0]) - offsetof(struct iviscreen, resource_list)); + ASSERT_EQ(lp_iviScreen->shell, mp_iviShell); + ASSERT_EQ(lp_iviScreen->output, &l_createdOutput); + ASSERT_EQ(lp_iviScreen->id_screen, mp_iviShell->screen_id_offset + l_createdOutput.id); + + free(lp_iviScreen); +} + +/** ================================================================================================ + * @test_id output_created_event_defaultConfigScreen + * @brief Test case of output_created_event() where weston output is a default name + * same screen info default + * @test_procedure Steps: + * -# Set weston output with name is default name and id is 1000 + * -# Calling the output_created_event() + * -# Verification point: + * +# wl_list_insert() must be called once time + * +# wl_list_init() must be called once time + * +# weston_compositor_schedule_repaint() must be called once time + * +# The result output should same with prepare data + * +# Free resources are allocated when running the test + */ +TEST_F(ControllerTests, output_created_event_defaultConfigScreen) +{ + struct weston_output l_createdOutput; + l_createdOutput.id = 1000; + l_createdOutput.name = mp_screenInfo->screen_name; + + output_created_event(&mp_iviShell->output_created, &l_createdOutput); + + ASSERT_EQ(wl_list_insert_fake.call_count, 1); + ASSERT_EQ(wl_list_init_fake.call_count, 1); + ASSERT_EQ(weston_compositor_schedule_repaint_fake.call_count, 1); + struct iviscreen *lp_iviScreen = (struct iviscreen*)(uintptr_t(wl_list_init_fake.arg0_history[0]) - offsetof(struct iviscreen, resource_list)); + ASSERT_EQ(lp_iviScreen->shell, mp_iviShell); + ASSERT_EQ(lp_iviScreen->output, &l_createdOutput); + ASSERT_EQ(lp_iviScreen->id_screen, mp_screenInfo->screen_id); + + free(lp_iviScreen); +} + +/** ================================================================================================ + * @test_id bind_ivi_controller_nullResource + * @brief Test case of bind_ivi_controller() where wl_resource_create() fails, return null pointer + * @test_procedure Steps: + * -# Calling the bind_ivi_controller() + * -# Verification point: + * +# wl_resource_create() must be called once time + * +# wl_resource_set_implementation() not be called + */ +TEST_F(ControllerTests, bind_ivi_controller_nullResource) +{ + // update version >= 2 + bind_ivi_controller(mp_fakeClient, mp_iviShell, 2, 1); + + ASSERT_EQ(wl_resource_create_fake.call_count, 1); + ASSERT_EQ(wl_resource_set_implementation_fake.call_count, 0); +} + +/** ================================================================================================ + * @test_id bind_ivi_controller_success + * @brief Test case of bind_ivi_controller() where wl_resource_create() success, return an object + * @test_procedure Steps: + * -# Mocking the wl_resource_create() does return an object + * -# Calling the bind_ivi_controller() + * -# Verification point: + * +# wl_resource_create() must be called once time + * +# wl_resource_set_implementation() must be called once time + * +# wl_list_insert() must be called once time + * +# wl_list_init() must be called 2 times + * +# get_id_of_surface() must be called {MAX_NUMBER} times + * +# get_id_of_layer() must be called {MAX_NUMBER} times + * +# wl_resource_post_event() must be called {MAX_NUMBER*2} times + * +# The result output should same with prepare data + * +# Free resources are allocated when running the test + */ +TEST_F(ControllerTests, bind_ivi_controller_success) +{ + SET_RETURN_SEQ(wl_resource_create, &mp_wlResourceDefault, 1); + + // update version >= 2 + bind_ivi_controller(mp_fakeClient, mp_iviShell, 2, 1); + + ASSERT_EQ(wl_resource_create_fake.call_count, 1); + ASSERT_EQ(wl_resource_set_implementation_fake.call_count, 1); + ASSERT_EQ(wl_list_insert_fake.call_count, 1); + ASSERT_EQ(wl_list_init_fake.call_count, 2); + ASSERT_EQ(get_id_of_surface_fake.call_count, MAX_NUMBER); + ASSERT_EQ(get_id_of_layer_fake.call_count, MAX_NUMBER); + ASSERT_EQ(wl_resource_post_event_fake.call_count, MAX_NUMBER*2); + struct ivicontroller *lp_iviController = (struct ivicontroller*)(uintptr_t(wl_list_init_fake.arg0_history[0]) - offsetof(struct ivicontroller, surface_notifications)); + ASSERT_EQ(lp_iviController->shell, mp_iviShell); + ASSERT_EQ(lp_iviController->client, mp_fakeClient); + ASSERT_EQ(lp_iviController->id, 1); + + free(lp_iviController); +} + +/** ================================================================================================ + * @test_id controller_create_screen_wrongWestonHead + * @brief Test case of controller_create_screen() where wl_resource_get_user_data() fails, return wrong object + * @test_procedure Steps: + * -# Mocking the wl_resource_get_user_data() does return wrong weston head + * -# Calling the controller_create_screen() + * -# Verification point: + * +# wl_resource_create() not be called + * +# wl_resource_set_implementation() not be called + * +# wl_list_insert() not be called + * +# wl_resource_post_event() not be called + */ +TEST_F(ControllerTests, controller_create_screen_wrongWestonHead) +{ + struct weston_head l_westonHead; + struct weston_output *lp_fakeWestonOutput = (struct weston_output*)0xFFFFFFFF; + l_westonHead.output = lp_fakeWestonOutput; + void *lpp_getUserData [] = {&l_westonHead, mp_iviController[0]}; + SET_RETURN_SEQ(wl_resource_get_user_data, lpp_getUserData, 2); + + controller_create_screen(nullptr, nullptr, nullptr, 1); + + ASSERT_EQ(wl_resource_create_fake.call_count, 0); + ASSERT_EQ(wl_resource_set_implementation_fake.call_count, 0); + ASSERT_EQ(wl_list_insert_fake.call_count, 0); + ASSERT_EQ(wl_resource_post_event_fake.call_count, 0); +} + +/** ================================================================================================ + * @test_id controller_create_screen_nullScreenResource + * @brief Test case of controller_create_screen() where wl_resource_get_user_data() success, return an object + * but wl_resource_create() fails, return null object + * @test_procedure Steps: + * -# Mocking the wl_resource_get_user_data() does return valid weston head + * -# Calling the controller_create_screen() + * -# Verification point: + * +# wl_resource_create() must be called once time + * +# wl_resource_post_no_memory() must be called once time + * +# wl_resource_set_implementation() not be called + * +# wl_list_insert() not be called + * +# wl_resource_post_event() not be called + */ +TEST_F(ControllerTests, controller_create_screen_nullScreenResource) +{ + struct weston_head l_westonHead; + l_westonHead.output = &m_westonOutput[0]; + void *lpp_getUserData [] = {&l_westonHead, mp_iviController[0]}; + SET_RETURN_SEQ(wl_resource_get_user_data, lpp_getUserData, 2); + + controller_create_screen(nullptr, nullptr, nullptr, 1); + + ASSERT_EQ(wl_resource_create_fake.call_count, 1); + ASSERT_EQ(wl_resource_post_no_memory_fake.call_count, 1); + ASSERT_EQ(wl_resource_set_implementation_fake.call_count, 0); + ASSERT_EQ(wl_list_insert_fake.call_count, 0); + ASSERT_EQ(wl_resource_post_event_fake.call_count, 0); +} + +/** ================================================================================================ + * @test_id controller_create_screen_correctWestonHead + * @brief Test case of controller_create_screen() where wl_resource_get_user_data() success, return an object + * and wl_resource_create() success, return an object + * @test_procedure Steps: + * -# Mocking the wl_resource_get_user_data() does return valid weston head + * -# Mocking the wl_resource_create() does return an object + * -# Calling the controller_create_screen() + * -# Verification point: + * +# wl_resource_create() must be called once time + * +# wl_resource_set_implementation() must be called once time + * +# wl_list_insert() must be called once time + * +# wl_resource_post_event() must be called 2 times + */ +TEST_F(ControllerTests, controller_create_screen_correctWestonHead) +{ + struct weston_head l_westonHead; + l_westonHead.output = &m_westonOutput[0]; + void *lpp_getUserData [] = {&l_westonHead, mp_iviController[0]}; + SET_RETURN_SEQ(wl_resource_get_user_data, lpp_getUserData, 2); + SET_RETURN_SEQ(wl_resource_create, &mp_wlResourceDefault, 1); + + controller_create_screen(nullptr, nullptr, nullptr, 1); + + ASSERT_EQ(wl_resource_create_fake.call_count, 1); + ASSERT_EQ(wl_resource_set_implementation_fake.call_count, 1); + ASSERT_EQ(wl_list_insert_fake.call_count, 1); + ASSERT_EQ(wl_resource_post_event_fake.call_count, 2); +} + +/** ================================================================================================ + * @test_id wet_module_init_cannotGetIviLayoutInterface + * @brief Test case of wet_module_init() where weston_plugin_api_get() fails, return null object + * @test_procedure Steps: + * -# Calling the wet_module_init() + * -# Verification point: + * +# wet_module_init() must not return 0 + * +# weston_plugin_api_get() must be called once time + * +# wet_get_config() not be called + */ +TEST_F(ControllerTests, wet_module_init_cannotGetIviLayoutInterface) +{ + ASSERT_NE(wet_module_init(&m_westonCompositor, nullptr, nullptr), 0); + + ASSERT_EQ(weston_plugin_api_get_fake.call_count, 1); + ASSERT_EQ(wet_get_config_fake.call_count, 0); +} + +/** ================================================================================================ + * @test_id wet_module_init_cannotCreateGlobalWmIviInterface + * @brief Test case of wet_module_init() where weston_plugin_api_get() success, return an object + * but wl_global_create() fails, return null object + * @test_procedure Steps: + * -# Mocking the weston_plugin_api_get() does return an object + * -# Calling the wet_module_init() + * -# Verification point: + * +# wet_module_init() must not return 0 + * +# weston_plugin_api_get() must be called once time + * +# wl_global_create() must be called once time + * +# weston_load_module() not be called + */ +TEST_F(ControllerTests, wet_module_init_cannotCreateGlobalWmIviInterface) +{ + struct ivi_layout_interface *lp_iviLayoutInterface = &g_iviLayoutInterfaceFake; + SET_RETURN_SEQ(weston_plugin_api_get, (const void**)&lp_iviLayoutInterface, 1); + + ASSERT_NE(wet_module_init(&m_westonCompositor, nullptr, nullptr), 0); + + ASSERT_EQ(weston_plugin_api_get_fake.call_count, 1); + ASSERT_EQ(wl_global_create_fake.call_count, 1); + ASSERT_EQ(weston_load_module_fake.call_count, 0); +} + +/** ================================================================================================ + * @test_id wet_module_init_cannotInitIviInputModule + * @brief Test case of wet_module_init() where weston_plugin_api_get() success, return an object + * and wl_global_create() success, return an object but ms_inputControllerModuleValue is -1 + * @test_procedure Steps: + * -# Set ms_inputControllerModuleValue is -1 + * -# Mocking the weston_plugin_api_get() does return an object + * -# Mocking the wl_global_create() does return an object + * -# Mocking the weston_load_module() does return an object + * -# Calling the wet_module_init() + * -# Verification point: + * +# wet_module_init() must not return 0 + * +# weston_plugin_api_get() must be called once time + * +# wl_global_create() must be called once time + * +# weston_load_module() must be called once time + */ +TEST_F(ControllerTests, wet_module_init_cannotInitIviInputModule) +{ + ControllerTests::ms_inputControllerModuleValue = -1; + + struct ivi_layout_interface *lp_iviLayoutInterface = &g_iviLayoutInterfaceFake; + SET_RETURN_SEQ(weston_plugin_api_get, (const void**)&lp_iviLayoutInterface, 1); + struct wl_global *lp_wlGlobal = (struct wl_global*) 0xFFFFFFFF; + SET_RETURN_SEQ(wl_global_create, &lp_wlGlobal, 1); + void *lp_iviInputInitModule = (void*)custom_input_controller_module_init; + SET_RETURN_SEQ(weston_load_module, &lp_iviInputInitModule, 1); + + ASSERT_NE(wet_module_init(&m_westonCompositor, nullptr, nullptr), 0); + + ASSERT_EQ(weston_plugin_api_get_fake.call_count, 1); + ASSERT_EQ(wl_global_create_fake.call_count, 1); + // this API dont have anymore + ASSERT_EQ(weston_load_module_fake.call_count, 1); +} + +/** ================================================================================================ + * @test_id wet_module_init_cannotGetWestonConfig + * @brief Test case of wet_module_init() where weston_plugin_api_get() success, return an object + * and wl_global_create() success, return an object and ms_inputControllerModuleValue is 0 + * but wet_get_config() return fails, return null pointer + * @test_procedure Steps: + * -# Calling the enable_utility_funcs_of_array_list() to set real function for wl_list, wl_array + * -# Set ms_inputControllerModuleValue is 0 + * -# Set ms_idAgentModuleValue is -1 + * -# Mocking the weston_plugin_api_get() does return an object + * -# Mocking the wl_global_create() does return an object + * -# Mocking the weston_load_module() does return an object + * -# Calling the wet_module_init() + * -# Verification point: + * +# wet_module_init() must return 0 + * +# weston_plugin_api_get() must be called once time + * +# wl_global_create() must be called once time + * +# weston_load_module() must be called 2 times + * +# The result output should same with prepare data + * +# Free resources are allocated when running the test + */ +TEST_F(ControllerTests, wet_module_init_cannotGetWestonConfig) +{ + enable_utility_funcs_of_array_list(); + + ControllerTests::ms_inputControllerModuleValue = 0; + ControllerTests::ms_idAgentModuleValue = -1; + + struct ivi_layout_interface *lp_iviLayoutInterface = &g_iviLayoutInterfaceFake; + SET_RETURN_SEQ(weston_plugin_api_get, (const void**)&lp_iviLayoutInterface, 1); + struct wl_global *lp_wlGlobal = (struct wl_global*) 0xFFFFFFFF; + SET_RETURN_SEQ(wl_global_create, &lp_wlGlobal, 1); + void *lp_iviInputInitModule[] ={(void *)custom_input_controller_module_init, (void *)custom_id_agent_module_init}; + SET_RETURN_SEQ(weston_load_module, lp_iviInputInitModule, 2); + + // this API dont have anymore + ASSERT_EQ(wet_module_init(&m_westonCompositor, nullptr, nullptr), 0); + + ASSERT_EQ(weston_plugin_api_get_fake.call_count, 1); + ASSERT_EQ(wl_global_create_fake.call_count, 1); + ASSERT_EQ(weston_load_module_fake.call_count, 2); + + struct ivishell *lp_iviShell = (struct ivishell*)wl_global_create_fake.arg3_history[0]; + EXPECT_EQ(lp_iviShell->interface, lp_iviLayoutInterface); + EXPECT_EQ(lp_iviShell->screen_id_offset, 0); + EXPECT_EQ(lp_iviShell->ivi_client_name, nullptr); + EXPECT_EQ(lp_iviShell->bkgnd_surface_id, 0); + EXPECT_EQ(lp_iviShell->debug_scopes, nullptr); + EXPECT_EQ(lp_iviShell->bkgnd_color, 0); + EXPECT_EQ(lp_iviShell->enable_cursor, 0); + EXPECT_EQ(lp_iviShell->screen_ids.size, 0); + EXPECT_EQ(custom_wl_list_length(&lp_iviShell->list_surface), 0); + EXPECT_EQ(custom_wl_list_length(&lp_iviShell->list_layer), 0); + EXPECT_EQ(custom_wl_list_length(&lp_iviShell->list_screen), 0); + EXPECT_EQ(custom_wl_list_length(&lp_iviShell->list_controller), 0); + EXPECT_NE(lp_iviShell->layer_created.notify, nullptr); + EXPECT_NE(lp_iviShell->layer_removed.notify, nullptr); + EXPECT_NE(lp_iviShell->surface_created.notify, nullptr); + EXPECT_NE(lp_iviShell->surface_removed.notify, nullptr); + EXPECT_NE(lp_iviShell->surface_configured.notify, nullptr); + EXPECT_NE(lp_iviShell->output_created.notify, nullptr); + EXPECT_NE(lp_iviShell->output_destroyed.notify, nullptr); + EXPECT_NE(lp_iviShell->output_resized.notify, nullptr); + EXPECT_EQ(custom_wl_list_length(&m_westonCompositor.output_created_signal.listener_list), 1); + EXPECT_EQ(custom_wl_list_length(&m_westonCompositor.output_destroyed_signal.listener_list), 1); + EXPECT_EQ(custom_wl_list_length(&m_westonCompositor.output_resized_signal.listener_list), 1); + + free(lp_iviShell); +} + +/** ================================================================================================ + * @test_id wet_module_init_canGetWestonConfig + * @brief Test case of wet_module_init() where weston_plugin_api_get() success, return an object + * and wl_global_create() success, return an object and ms_inputControllerModuleValue is 0 + * and wet_get_config() return success, return an pointer + * @test_procedure Steps: + * -# Calling the enable_utility_funcs_of_array_list() to set real function for wl_list, wl_array + * -# Set ms_inputControllerModuleValue is 0 + * -# Set ms_idAgentModuleValue is -1 + * -# Mocking the weston_plugin_api_get() does return an object + * -# Mocking the wl_global_create() does return an object + * -# Mocking the wet_get_config() does return an object + * -# Mocking the weston_config_get_section() does return an object + * -# Mocking the weston_config_next_section() does return an object + * -# Mocking the weston_load_module() does return an object + * -# Set config data + * -# Calling the wet_module_init() + * -# Verification point: + * +# wet_module_init() must return 0 + * +# weston_plugin_api_get() must be called once time + * +# wl_global_create() must be called once time + * +# weston_load_module() must be called 2 times + * +# wet_get_config() must be called 3 times + * +# weston_config_get_section() must be called 3 times + * +# The result output should same with prepare data + * +# Free resources are allocated when running the test + */ +TEST_F(ControllerTests, wet_module_init_canGetWestonConfig) +{ + enable_utility_funcs_of_array_list(); + + ControllerTests::ms_inputControllerModuleValue = 0; + ControllerTests::ms_idAgentModuleValue = -1; + + struct ivi_layout_interface *lp_iviLayoutInterface = &g_iviLayoutInterfaceFake; + struct wl_global *lp_wlGlobal = (struct wl_global*) 0xFFFFFFFF; + struct weston_config *lp_westonConfig = (struct weston_config*) 0xFFFFFFFF; + struct weston_config_section *lp_westonConfigSection = (struct weston_config_section*) 0xFFFFFFFF; + int lpp_westonConfigNextSection[] = {1, 0}; + void *lp_iviInputInitModule[] ={(void *)custom_input_controller_module_init, (void *)custom_id_agent_module_init}; + SET_RETURN_SEQ(weston_plugin_api_get, (const void**)&lp_iviLayoutInterface, 1); + SET_RETURN_SEQ(wl_global_create, &lp_wlGlobal, 1); + SET_RETURN_SEQ(wet_get_config, &lp_westonConfig, 1); + SET_RETURN_SEQ(weston_config_get_section, &lp_westonConfigSection, 1); + SET_RETURN_SEQ(weston_config_next_section, lpp_westonConfigNextSection, 2); + SET_RETURN_SEQ(weston_load_module, lp_iviInputInitModule, 2); + + ControllerTests::ms_screenIdOffset = 100; + ControllerTests::ms_screenId = 10; + ControllerTests::ms_iviClientName = (char *)"ivi_client_app.elf"; + ControllerTests::ms_debugScopes = (char *)"controller"; + ControllerTests::ms_screenName = (char *)"screen_test"; + ControllerTests::ms_bkgndSurfaceId = 100; + ControllerTests::ms_bkgndColor = 0xAABBCCDD; + ControllerTests::ms_enableCursor = true; + ControllerTests::ms_westonConfigNextSection = 0; + weston_config_section_get_uint_fake.custom_fake = custom_weston_config_section_get_uint; + weston_config_section_get_string_fake.custom_fake = custom_weston_config_section_get_string; + weston_config_section_get_int_fake.custom_fake = custom_weston_config_section_get_int; + weston_config_section_get_color_fake.custom_fake = custom_weston_config_section_get_color; + weston_config_section_get_bool_fake.custom_fake = custom_weston_config_section_get_bool; + weston_config_next_section_fake.custom_fake = custom_weston_config_next_section; + + + // this API dont have anymore + ASSERT_EQ(wet_module_init(&m_westonCompositor, nullptr, nullptr), 0); + + ASSERT_EQ(weston_plugin_api_get_fake.call_count, 1); + ASSERT_EQ(wl_global_create_fake.call_count, 1); + ASSERT_EQ(weston_load_module_fake.call_count, 2); + ASSERT_EQ(wet_get_config_fake.call_count, 3); + ASSERT_EQ(weston_config_get_section_fake.call_count, 3); + + struct ivishell *lp_iviShell = (struct ivishell*)wl_global_create_fake.arg3_history[0]; + EXPECT_EQ(lp_iviShell->interface, lp_iviLayoutInterface); + EXPECT_EQ(lp_iviShell->screen_id_offset, ControllerTests::ms_screenIdOffset); + EXPECT_EQ(strcmp(lp_iviShell->ivi_client_name, ControllerTests::ms_iviClientName), 0); + EXPECT_EQ(lp_iviShell->bkgnd_surface_id, ControllerTests::ms_bkgndSurfaceId); + EXPECT_EQ(strcmp(lp_iviShell->debug_scopes, ControllerTests::ms_debugScopes), 0); + EXPECT_EQ(lp_iviShell->bkgnd_color, ControllerTests::ms_bkgndColor); + EXPECT_EQ(lp_iviShell->enable_cursor, ControllerTests::ms_enableCursor); + EXPECT_EQ(lp_iviShell->screen_ids.size, sizeof(struct screen_id_info)); + EXPECT_EQ(custom_wl_list_length(&lp_iviShell->list_surface), 0); + EXPECT_EQ(custom_wl_list_length(&lp_iviShell->list_layer), 0); + EXPECT_EQ(custom_wl_list_length(&lp_iviShell->list_screen), 0); + EXPECT_EQ(custom_wl_list_length(&lp_iviShell->list_controller), 0); + EXPECT_NE(lp_iviShell->layer_created.notify, nullptr); + EXPECT_NE(lp_iviShell->layer_removed.notify, nullptr); + EXPECT_NE(lp_iviShell->surface_created.notify, nullptr); + EXPECT_NE(lp_iviShell->surface_removed.notify, nullptr); + EXPECT_NE(lp_iviShell->surface_configured.notify, nullptr); + EXPECT_NE(lp_iviShell->output_created.notify, nullptr); + EXPECT_NE(lp_iviShell->output_destroyed.notify, nullptr); + EXPECT_NE(lp_iviShell->output_resized.notify, nullptr); + EXPECT_EQ(custom_wl_list_length(&m_westonCompositor.output_created_signal.listener_list), 1); + EXPECT_EQ(custom_wl_list_length(&m_westonCompositor.output_destroyed_signal.listener_list), 1); + EXPECT_EQ(custom_wl_list_length(&m_westonCompositor.output_resized_signal.listener_list), 1); + + struct screen_id_info *screen_info = NULL; + wl_array_for_each(screen_info, &lp_iviShell->screen_ids) { + free(screen_info->screen_name); + } + wl_array_release(&lp_iviShell->screen_ids); + free(lp_iviShell->ivi_client_name); + free(lp_iviShell->debug_scopes); + free(lp_iviShell); +} + +/** ================================================================================================ + * @test_id controller_screen_destroy_success + * @brief Test case of controller_screen_destroy() where valid input params + * @test_procedure Steps: + * -# Calling the controller_screen_destroy() + * -# Verification point: + * +# wl_resource_destroy() must be called once time + */ +TEST_F(ControllerTests, controller_screen_destroy_success) +{ + controller_screen_destroy(nullptr, nullptr); + ASSERT_EQ(wl_resource_destroy_fake.call_count, 1); +} + +/** ================================================================================================ + * @test_id controller_screen_clear_cannotGetUserData + * @brief Test case of controller_screen_clear() where wl_resource_get_user_data() fails, return null pointer + * @test_procedure Steps: + * -# Calling the controller_screen_clear() + * -# Verification point: + * +# wl_resource_post_event() must be called once time + */ +TEST_F(ControllerTests, controller_screen_clear_cannotGetUserData) +{ + controller_screen_clear(nullptr, nullptr); + ASSERT_EQ(wl_resource_post_event_fake.call_count, 1); +} + +/** ================================================================================================ + * @test_id controller_screen_clear_success + * @brief Test case of controller_screen_clear() where wl_resource_get_user_data() success, return an object + * @test_procedure Steps: + * -# Mocking the wl_resource_get_user_data() does return an object + * -# Calling the controller_screen_clear() + * -# Verification point: + * +# wl_resource_post_event() not be called + * +# screen_set_render_order() must be called once time + */ +TEST_F(ControllerTests, controller_screen_clear_success) +{ + SET_RETURN_SEQ(wl_resource_get_user_data, (void**)mp_iviScreen, 1); + + controller_screen_clear(nullptr, nullptr); + + ASSERT_EQ(wl_resource_post_event_fake.call_count, 0); + ASSERT_EQ(screen_set_render_order_fake.call_count, 1); +} + +/** ================================================================================================ + * @test_id controller_screen_add_layer_nullScreen + * @brief Test case of controller_screen_add_layer() where wl_resource_get_user_data() fails, return null pointer + * @test_procedure Steps: + * -# Calling the controller_screen_add_layer() + * -# Verification point: + * +# wl_resource_post_event() must be called once time + */ +TEST_F(ControllerTests, controller_screen_add_layer_nullScreen) +{ + uint32_t l_layer_id = 10; + controller_screen_add_layer(nullptr, nullptr, l_layer_id); + + ASSERT_EQ(wl_resource_post_event_fake.call_count, 1); +} + +/** ================================================================================================ + * @test_id controller_screen_add_layer_wrongLayerId + * @brief Test case of controller_screen_add_layer() where wl_resource_get_user_data() success, return an object + * but get_layer_from_id() fails, return null pointer + * @test_procedure Steps: + * -# Mocking the wl_resource_get_user_data() does return an object + * -# Calling the controller_screen_add_layer() + * -# Verification point: + * +# wl_resource_post_event() must be called once time + */ +TEST_F(ControllerTests, controller_screen_add_layer_wrongLayerId) +{ + SET_RETURN_SEQ(wl_resource_get_user_data, (void**)mp_iviScreen, 1); + + uint32_t l_layer_id = 10; + controller_screen_add_layer(nullptr, nullptr, l_layer_id); + + ASSERT_EQ(wl_resource_post_event_fake.call_count, 1); + +} + +/** ================================================================================================ + * @test_id controller_screen_add_layer_success + * @brief Test case of controller_screen_add_layer() where wl_resource_get_user_data() success, return an object + * and get_layer_from_id() success, return an object + * @test_procedure Steps: + * -# Mocking the wl_resource_get_user_data() does return an object + * -# Mocking the get_layer_from_id() does return an object + * -# Calling the controller_screen_add_layer() + * -# Verification point: + * +# wl_resource_post_event() not be called + */ +TEST_F(ControllerTests, controller_screen_add_layer_success) +{ + SET_RETURN_SEQ(wl_resource_get_user_data, (void**)mp_iviScreen, 1); + struct ivi_layout_layer *l_layoutLayer[1] = {(struct ivi_layout_layer *)0xFFFFFFFF}; + SET_RETURN_SEQ(get_layer_from_id, l_layoutLayer, 1); + + uint32_t l_layer_id = 10; + controller_screen_add_layer(nullptr, nullptr, l_layer_id); + + ASSERT_EQ(wl_resource_post_event_fake.call_count, 0); +} + +/** ================================================================================================ + * @test_id controller_screen_remove_layer_nullScreen + * @brief Test case of controller_screen_remove_layer() where wl_resource_get_user_data() fails, return null pointer + * @test_procedure Steps: + * -# Calling the controller_screen_remove_layer() + * -# Verification point: + * +# wl_resource_post_event() must be called once time + */ +TEST_F(ControllerTests, controller_screen_remove_layer_nullScreen) +{ + uint32_t l_layer_id = 10; + controller_screen_remove_layer(nullptr, nullptr, l_layer_id); + + ASSERT_EQ(wl_resource_post_event_fake.call_count, 1); +} + +/** ================================================================================================ + * @test_id controller_screen_remove_layer_wrongLayerId + * @brief Test case of controller_screen_remove_layer() where wl_resource_get_user_data() success, return an object + * but get_layer_from_id() fails, return null pointer + * @test_procedure Steps: + * -# Mocking the wl_resource_get_user_data() does return an object + * -# Calling the controller_screen_remove_layer() + * -# Verification point: + * +# wl_resource_post_event() must be called once time + */ +TEST_F(ControllerTests, controller_screen_remove_layer_wrongLayerId) +{ + SET_RETURN_SEQ(wl_resource_get_user_data, (void**)mp_iviScreen, 1); + + uint32_t l_layer_id = 10; + controller_screen_remove_layer(nullptr, nullptr, l_layer_id); + + ASSERT_EQ(wl_resource_post_event_fake.call_count, 1); +} + +/** ================================================================================================ + * @test_id controller_screen_remove_layer_success + * @brief Test case of controller_screen_remove_layer() where wl_resource_get_user_data() success, return an object + * and get_layer_from_id() success, return an object + * @test_procedure Steps: + * -# Mocking the wl_resource_get_user_data() does return an object + * -# Mocking the get_layer_from_id() does return an object + * -# Calling the controller_screen_remove_layer() + * -# Verification point: + * +# wl_resource_post_event() not be called + */ +TEST_F(ControllerTests, controller_screen_remove_layer_success) +{ + SET_RETURN_SEQ(wl_resource_get_user_data, (void**)mp_iviScreen, 1); + struct ivi_layout_layer *l_layoutLayer[1] = {(struct ivi_layout_layer *)0xFFFFFFFF}; + SET_RETURN_SEQ(get_layer_from_id, l_layoutLayer, 1); + + uint32_t l_layer_id = 10; + controller_screen_remove_layer(nullptr, nullptr, l_layer_id); + + ASSERT_EQ(wl_resource_post_event_fake.call_count, 0); +} + +/** ================================================================================================ + * @test_id controller_screen_screenshot_nullScreenShot + * @brief Test case of controller_screen_screenshot() where wl_resource_create() fails, return null pointer + * @test_procedure Steps: + * -# Calling the controller_screen_screenshot() + * -# Verification point: + * +# wl_resource_post_no_memory() must be called once time + */ +TEST_F(ControllerTests, controller_screen_screenshot_nullScreenShot) +{ + uint32_t l_id = 10; + controller_screen_screenshot(nullptr, nullptr, nullptr, l_id); + + ASSERT_EQ(wl_resource_post_no_memory_fake.call_count, 1); + ASSERT_EQ(wl_resource_post_no_memory_fake.arg0_history[0], NULL); + ASSERT_EQ(wl_resource_get_user_data_fake.return_val_history[0], NULL); +} + +/** ================================================================================================ + * @test_id controller_screen_screenshot_nullScreen + * @brief Test case of controller_screen_screenshot() where wl_resource_create() success, return an object + * but wl_resource_get_user_data() fails, return null pointer + * @test_procedure Steps: + * -# Mocking the wl_resource_create() does return an object + * -# Calling the controller_screen_screenshot() + * -# Verification point: + * +# wl_resource_post_event() must be called once time + * +# wl_resource_destroy() must be called once time + */ +TEST_F(ControllerTests, controller_screen_screenshot_nullScreen) +{ + struct wl_resource * screenshot[1] = {(struct wl_resource *)0xFFFFFFFF}; + SET_RETURN_SEQ(wl_resource_create, screenshot, 1); + + uint32_t l_id = 10; + controller_screen_screenshot(nullptr, nullptr, nullptr, l_id); + + ASSERT_EQ(wl_resource_get_user_data_fake.return_val_history[0], NULL); + ASSERT_EQ(wl_resource_post_event_fake.call_count, 1); + ASSERT_EQ(wl_resource_post_event_fake.arg1_history[0], IVI_SCREENSHOT_ERROR); + ASSERT_EQ(wl_resource_destroy_fake.call_count, 1); +} + +/** ================================================================================================ + * @test_id controller_screen_screenshot_nullWestonBuffer + * @brief Test case of controller_screen_screenshot() where wl_resource_create() success, return an object + * but wl_resource_get_user_data() fails, return null pointer + * @test_procedure Steps: + * -# Mocking the wl_resource_create() does return an object + * -# Calling the controller_screen_screenshot() + * -# Verification point: + * +# wl_resource_post_event() must be called once time + */ +TEST_F(ControllerTests, controller_screen_screenshot_nullWestonBuffer) +{ + void * buffer[1] = {nullptr}; + struct wl_resource * screenshot[1] = {(struct wl_resource *)0xFFFFFFFF}; + SET_RETURN_SEQ(wl_resource_create, screenshot, 1); + SET_RETURN_SEQ(wl_resource_get_user_data, (void**)mp_iviScreen, 1); + SET_RETURN_SEQ(weston_buffer_from_resource, buffer, 1); + uint32_t l_id = 10; + controller_screen_screenshot(nullptr, nullptr, nullptr, l_id); + + ASSERT_EQ(wl_resource_post_no_memory_fake.call_count, 0); + ASSERT_EQ(wl_resource_create_fake.call_count, 1); + ASSERT_EQ(weston_buffer_from_resource_fake.call_count, 1); + ASSERT_EQ(wl_resource_post_event_fake.call_count, 1); + ASSERT_EQ(wl_resource_post_event_fake.arg1_history[0], IVI_SCREENSHOT_ERROR); + ASSERT_EQ(wl_shm_buffer_get_data_fake.call_count, 0); +} + +/** ================================================================================================ + * @test_id controller_screen_screenshot_success + * @brief Test case of controller_screen_screenshot() where wl_resource_create() success, return an object + * and wl_resource_get_user_data() success, return an object + * @test_procedure Steps: + * -# Mocking the wl_resource_create() does return an object + * -# Mocking the wl_resource_get_user_data() does return an object + * -# Calling the controller_screen_screenshot() + * -# Verification point: + * +# wl_resource_set_implementation() must be called once time + * +# wl_list_insert() must be called 2 times + * +# Free resources are allocated when running the test + */ +TEST_F(ControllerTests, controller_screen_screenshot_success) +{ + struct wl_resource * screenshot[1] = {(struct wl_resource *)0xFFFFFFFF}; + SET_RETURN_SEQ(wl_resource_create, screenshot, 1); + SET_RETURN_SEQ(wl_resource_get_user_data, (void**)mp_iviScreen, 1); + SET_RETURN_SEQ(weston_buffer_from_resource, &mp_westonBuffer, 1); + + uint32_t l_id = 10; + controller_screen_screenshot(nullptr, nullptr, nullptr, l_id); + + ASSERT_EQ(wl_resource_post_no_memory_fake.call_count, 0); + ASSERT_EQ(wl_resource_create_fake.call_count, 1); + ASSERT_EQ(weston_buffer_from_resource_fake.call_count, 1); + ASSERT_EQ(wl_resource_destroy_fake.call_count, 0); + + struct screenshot_frame_listener *lp_l = (struct screenshot_frame_listener*)wl_resource_set_implementation_fake.arg2_history[0]; + free(lp_l); +} + +/** ================================================================================================ + * @test_id controller_screen_get_nullScreen + * @brief Test case of controller_screen_get() where wl_resource_get_user_data() fails, return null pointer + * @test_procedure Steps: + * -# Calling the controller_screen_get() + * -# Verification point: + * +# wl_resource_post_event() must be called once time + */ +TEST_F(ControllerTests, controller_screen_get_nullScreen) +{ + uint32_t l_param = 1; + controller_screen_get(nullptr, nullptr, l_param); + + ASSERT_EQ(wl_resource_post_event_fake.call_count, 1); +} + +/** ================================================================================================ + * @test_id controller_screen_get_wrongParam + * @brief Test case of controller_screen_get() where wl_resource_get_user_data() success, return an object + * but invalid input param + * @test_procedure Steps: + * -# Mocking the wl_resource_get_user_data() does return an object + * -# Calling the controller_screen_get() + * -# Verification point: + * +# get_layers_on_screen() not be called + * +# wl_resource_post_event() not be called + */ +TEST_F(ControllerTests, controller_screen_get_wrongParam) +{ + SET_RETURN_SEQ(wl_resource_get_user_data, (void**)mp_iviScreen, 1); + + uint32_t l_param = 0; + controller_screen_get(nullptr, nullptr, l_param); + + ASSERT_EQ(get_layers_on_screen_fake.call_count, 0); + ASSERT_EQ(wl_resource_post_event_fake.call_count, 0); +} + +/** ================================================================================================ + * @test_id controller_screen_get_success + * @brief Test case of controller_screen_get() where wl_resource_get_user_data() success, return an object + * but valid input param + * @test_procedure Steps: + * -# Mocking the wl_resource_get_user_data() does return an object + * -# Calling the controller_screen_get() + * -# Verification point: + * +# get_layers_on_screen() must be called once time + * +# wl_resource_post_event() must be called + */ +TEST_F(ControllerTests, controller_screen_get_success) +{ + SET_RETURN_SEQ(wl_resource_get_user_data, (void**)mp_iviScreen, 1); + + uint32_t l_param = 10; + controller_screen_get(nullptr, nullptr, l_param); + + ASSERT_EQ(get_layers_on_screen_fake.call_count, 1); + ASSERT_NE(wl_resource_post_event_fake.call_count, 0); +} + +/** ================================================================================================ + * @test_id controller_commit_changes_failed + * @brief Test case of controller_commit_changes() where commit_changes() fails, return -1 + * and wl_resource_get_user_data() success, return an object + * @test_procedure Steps: + * -# Mocking the commit_changes() does return -1 + * -# Mocking the wl_resource_get_user_data() does return an object + * -# Calling the controller_commit_changes() + * -# Verification point: + * +# commit_changes() must be called once time + */ +TEST_F(ControllerTests, controller_commit_changes_failed) +{ + SET_RETURN_SEQ(commit_changes, mp_failureResult, 1); + SET_RETURN_SEQ(wl_resource_get_user_data, (void**)mp_iviController, 1); + + controller_commit_changes(nullptr, nullptr); + + ASSERT_EQ(commit_changes_fake.call_count, 1); +} + +/** ================================================================================================ + * @test_id controller_commit_changes_success + * @brief Test case of controller_commit_changes() where commit_changes() success, return 0 + * and wl_resource_get_user_data() success, return an object + * @test_procedure Steps: + * -# Mocking the commit_changes() does return 0 + * -# Mocking the wl_resource_get_user_data() does return an object + * -# Calling the controller_commit_changes() + * -# Verification point: + * +# commit_changes() must be called once time + */ +TEST_F(ControllerTests, controller_commit_changes_success) +{ + SET_RETURN_SEQ(commit_changes, mp_successResult, 1); + SET_RETURN_SEQ(wl_resource_get_user_data, (void**)mp_iviController, 1); + + controller_commit_changes(nullptr, nullptr); + + ASSERT_EQ(commit_changes_fake.call_count, 1); +} + +/** ================================================================================================ + * @test_id controller_set_surface_visibility_wrongLayoutSurface + * @brief Test case of controller_set_surface_visibility() where get_surface_from_id() fails, return null pointer + * @test_procedure Steps: + * -# Mocking the wl_resource_get_user_data() does return an object + * -# Calling the controller_set_surface_visibility() + * -# Verification point: + * +# wl_resource_post_event() must be called once time + */ +TEST_F(ControllerTests, controller_set_surface_visibility_wrongLayoutSurface) +{ + SET_RETURN_SEQ(wl_resource_get_user_data, (void**)mp_iviController, 1); + + controller_set_surface_visibility(nullptr, nullptr, 1, 1); + + ASSERT_EQ(wl_resource_post_event_fake.call_count, 1); +} + +/** ================================================================================================ + * @test_id controller_set_surface_visibility_success + * @brief Test case of controller_set_surface_visibility() where get_surface_from_id() success, return an object + * @test_procedure Steps: + * -# Mocking the wl_resource_get_user_data() does return an object + * -# Mocking the get_surface_from_id() does return an object + * -# Calling the controller_set_surface_visibility() + * -# Verification point: + * +# surface_set_visibility() must be called once time + */ +TEST_F(ControllerTests, controller_set_surface_visibility_success) +{ + SET_RETURN_SEQ(wl_resource_get_user_data, (void**)mp_iviController, 1); + struct ivi_layout_surface *l_layout_surface[1] = {(struct ivi_layout_surface *)0xFFFFFFFF}; + SET_RETURN_SEQ(get_surface_from_id, l_layout_surface, 1); + + controller_set_surface_visibility(nullptr, nullptr, 1, 1); + + ASSERT_EQ(surface_set_visibility_fake.call_count, 1); +} + +/** ================================================================================================ + * @test_id controller_set_layer_visibility_wrongLayoutLayer + * @brief Test case of controller_set_layer_visibility() where get_layer_from_id() fails, return null pointer + * @test_procedure Steps: + * -# Mocking the wl_resource_get_user_data() does return an object + * -# Calling the controller_set_layer_visibility() + * -# Verification point: + * +# wl_resource_post_event() must be called once time + */ +TEST_F(ControllerTests, controller_set_layer_visibility_wrongLayoutLayer) +{ + SET_RETURN_SEQ(wl_resource_get_user_data, (void**)mp_iviController, 1); + + controller_set_layer_visibility(nullptr, nullptr, 1, 1); + + ASSERT_EQ(wl_resource_post_event_fake.call_count, 1); +} + +/** ================================================================================================ + * @test_id controller_set_layer_visibility_success + * @brief Test case of controller_set_layer_visibility() where get_layer_from_id() success, return an object + * @test_procedure Steps: + * -# Mocking the wl_resource_get_user_data() does return an object + * -# Mocking the get_layer_from_id() does return an object + * -# Calling the controller_set_layer_visibility() + * -# Verification point: + * +# layer_set_visibility() must be called once time + */ +TEST_F(ControllerTests, controller_set_layer_visibility_success) +{ + SET_RETURN_SEQ(wl_resource_get_user_data, (void**)mp_iviController, 1); + struct ivi_layout_layer *l_layout_layer[1] = {(struct ivi_layout_layer *)0xFFFFFFFF}; + SET_RETURN_SEQ(get_layer_from_id, l_layout_layer, 1); + + controller_set_layer_visibility(nullptr, nullptr, 1, 1); + + ASSERT_EQ(layer_set_visibility_fake.call_count, 1); +} + +/** ================================================================================================ + * @test_id controller_set_surface_opacity_wrongLayoutSurface + * @brief Test case of controller_set_surface_opacity() where get_surface_from_id() fails, return null pointer + * @test_procedure Steps: + * -# Mocking the wl_resource_get_user_data() does return an object + * -# Calling the controller_set_surface_opacity() + * -# Verification point: + * +# wl_resource_post_event() must be called once time + */ +TEST_F(ControllerTests, controller_set_surface_opacity_wrongLayoutSurface) +{ + SET_RETURN_SEQ(wl_resource_get_user_data, (void**)mp_iviController, 1); + + controller_set_surface_opacity(nullptr, nullptr, 1, 1); + + ASSERT_EQ(wl_resource_post_event_fake.call_count, 1); +} + +/** ================================================================================================ + * @test_id controller_set_surface_opacity_success + * @brief Test case of controller_set_surface_opacity() where get_surface_from_id() success, return an object + * @test_procedure Steps: + * -# Mocking the wl_resource_get_user_data() does return an object + * -# Mocking the get_surface_from_id() does return an object + * -# Calling the controller_set_surface_opacity() + * -# Verification point: + * +# surface_set_opacity() must be called once time + */ +TEST_F(ControllerTests, controller_set_surface_opacity_success) +{ + SET_RETURN_SEQ(wl_resource_get_user_data, (void**)mp_iviController, 1); + struct ivi_layout_surface *l_layout_surface[1] = {(struct ivi_layout_surface *)0xFFFFFFFF}; + SET_RETURN_SEQ(get_surface_from_id, l_layout_surface, 1); + + controller_set_surface_opacity(nullptr, nullptr, 1, 1); + + ASSERT_EQ(surface_set_opacity_fake.call_count, 1); +} + +/** ================================================================================================ + * @test_id controller_set_layer_opacity_wrongLayoutLayer + * @brief Test case of controller_set_layer_opacity() where get_layer_from_id() fails, return null pointer + * @test_procedure Steps: + * -# Mocking the wl_resource_get_user_data() does return an object + * -# Calling the controller_set_layer_opacity() + * -# Verification point: + * +# wl_resource_post_event() must be called once time + */ +TEST_F(ControllerTests, controller_set_layer_opacity_wrongLayoutLayer) +{ + SET_RETURN_SEQ(wl_resource_get_user_data, (void**)mp_iviController, 1); + + controller_set_layer_opacity(nullptr, nullptr, 1, 1); + + ASSERT_EQ(wl_resource_post_event_fake.call_count, 1); +} + +/** ================================================================================================ + * @test_id controller_set_layer_opacity_success + * @brief Test case of controller_set_layer_opacity() where get_layer_from_id() success, return an object + * @test_procedure Steps: + * -# Mocking the wl_resource_get_user_data() does return an object + * -# Mocking the get_layer_from_id() does return an object + * -# Calling the controller_set_layer_opacity() + * -# Verification point: + * +# layer_set_opacity() must be called once time + */ +TEST_F(ControllerTests, controller_set_layer_opacity_success) +{ + SET_RETURN_SEQ(wl_resource_get_user_data, (void**)mp_iviController, 1); + struct ivi_layout_layer *l_layout_layer[1] = {(struct ivi_layout_layer *)0xFFFFFFFF}; + SET_RETURN_SEQ(get_layer_from_id, l_layout_layer, 1); + + controller_set_layer_opacity(nullptr, nullptr, 1, 1); + + ASSERT_EQ(layer_set_opacity_fake.call_count, 1); +} + +/** ================================================================================================ + * @test_id controller_set_surface_source_rectangle_wrongLayoutSurface + * @brief Test case of controller_set_surface_source_rectangle() where get_surface_from_id() fails, return null pointer + * @test_procedure Steps: + * -# Mocking the wl_resource_get_user_data() does return an object + * -# Calling the controller_set_surface_source_rectangle() + * -# Verification point: + * +# wl_resource_post_event() must be called once time + */ +TEST_F(ControllerTests, controller_set_surface_source_rectangle_wrongLayoutSurface) +{ + SET_RETURN_SEQ(wl_resource_get_user_data, (void**)mp_iviController, 1); + + controller_set_surface_source_rectangle(nullptr, nullptr, 1, 1, 1, 1, 1); + + ASSERT_EQ(wl_resource_post_event_fake.call_count, 1); +} + +/** ================================================================================================ + * @test_id controller_set_surface_source_rectangle_successWithPositiveValues + * @brief Test case of controller_set_surface_source_rectangle() where get_surface_from_id() success, return an object + * and input x, y, width, height are positive values + * @test_procedure Steps: + * -# Mocking the wl_resource_get_user_data() does return an object + * -# Mocking the get_surface_from_id() does return an object + * -# Calling the controller_set_surface_source_rectangle() + * -# Verification point: + * +# surface_set_source_rectangle() must be called once time + * +# Input data of surface_set_source_rectangle() must same input data of controller_set_surface_source_rectangle() + */ +TEST_F(ControllerTests, controller_set_surface_source_rectangle_successWithPositiveValues) +{ + SET_RETURN_SEQ(wl_resource_get_user_data, (void**)mp_iviController, 1); + struct ivi_layout_surface *l_layout_surface[1] = {(struct ivi_layout_surface *)0xFFFFFFFF}; + SET_RETURN_SEQ(get_surface_from_id, l_layout_surface, 1); + + controller_set_surface_source_rectangle(nullptr, nullptr, 1, 1, 1, 1, 1); + + ASSERT_EQ(surface_set_source_rectangle_fake.call_count, 1); + ASSERT_EQ(surface_set_source_rectangle_fake.arg1_val, 1); + ASSERT_EQ(surface_set_source_rectangle_fake.arg2_val, 1); + ASSERT_EQ(surface_set_source_rectangle_fake.arg3_val, 1); + ASSERT_EQ(surface_set_source_rectangle_fake.arg4_val, 1); +} + +/** ================================================================================================ + * @test_id controller_set_surface_source_rectangle_successWithNegativeValues + * @brief Test case of controller_set_surface_source_rectangle() where get_surface_from_id() success, return an object + * and input x, y, width, height are negative values + * @test_procedure Steps: + * -# Set data of ivi_layout_surface_properties to default value {0} + * -# Mocking the get_properties_of_surface() does return an object + * -# Mocking the wl_resource_get_user_data() does return an object + * -# Mocking the get_surface_from_id() does return an object + * -# Calling the controller_set_surface_source_rectangle() + * -# Verification point: + * +# surface_set_source_rectangle() must be called once time + * +# Input data of surface_set_source_rectangle() must same default value of ivi_layout_surface_properties + */ +TEST_F(ControllerTests, controller_set_surface_source_rectangle_successWithNegativeValues) +{ + const struct ivi_layout_surface_properties l_prop = { + .opacity = 0, + .source_x = 0, + .source_y = 0, + .source_width = 0, + .source_height = 0, + .start_x = 0, + .start_y = 0, + .start_width = 0, + .start_height = 0, + .dest_x = 0, + .dest_y = 0, + .dest_width = 0, + .dest_height = 0, + .orientation = WL_OUTPUT_TRANSFORM_NORMAL, + .visibility = true, + .transition_type = 0, + .transition_duration = 0, + .event_mask = 0, + }; + const struct ivi_layout_surface_properties *prop[1] = {&l_prop}; + + SET_RETURN_SEQ(get_properties_of_surface, prop, 1); + SET_RETURN_SEQ(wl_resource_get_user_data, (void**)mp_iviController, 1); + struct ivi_layout_surface *l_layout_surface[1] = {(struct ivi_layout_surface *)0xFFFFFFFF}; + SET_RETURN_SEQ(get_surface_from_id, l_layout_surface, 1); + + controller_set_surface_source_rectangle(nullptr, nullptr, 1, -1, -1, -1, -1); + + ASSERT_EQ(surface_set_source_rectangle_fake.call_count, 1); + ASSERT_EQ(surface_set_source_rectangle_fake.arg1_val, 0); + ASSERT_EQ(surface_set_source_rectangle_fake.arg2_val, 0); + ASSERT_EQ(surface_set_source_rectangle_fake.arg3_val, 0); + ASSERT_EQ(surface_set_source_rectangle_fake.arg4_val, 0); +} + +/** ================================================================================================ + * @test_id controller_set_layer_source_rectangle_wrongLayoutLayer + * @brief Test case of controller_set_layer_source_rectangle() where get_layer_from_id() fails, return null pointer + * @test_procedure Steps: + * -# Mocking the wl_resource_get_user_data() does return an object + * -# Calling the controller_set_layer_source_rectangle() + * -# Verification point: + * +# wl_resource_post_event() must be called once time + */ +TEST_F(ControllerTests, controller_set_layer_source_rectangle_wrongLayoutLayer) +{ + SET_RETURN_SEQ(wl_resource_get_user_data, (void**)mp_iviController, 1); + + controller_set_layer_source_rectangle(nullptr, nullptr, 1, 1, 1, 1, 1); + + ASSERT_EQ(wl_resource_post_event_fake.call_count, 1); +} + +/** ================================================================================================ + * @test_id controller_set_layer_source_rectangle_successWithPositiveValues + * @brief Test case of controller_set_layer_source_rectangle() where get_layer_from_id() success, return an object + * and input x, y, width, height are positive values + * @test_procedure Steps: + * -# Mocking the wl_resource_get_user_data() does return an object + * -# Mocking the get_layer_from_id() does return an object + * -# Calling the controller_set_layer_source_rectangle() + * -# Verification point: + * +# layer_set_source_rectangle() must be called once time + * +# Input data of layer_set_source_rectangle() must same input data of controller_set_layer_source_rectangle() + */ +TEST_F(ControllerTests, controller_set_layer_source_rectangle_successWithPositiveValues) +{ + SET_RETURN_SEQ(wl_resource_get_user_data, (void**)mp_iviController, 1); + struct ivi_layout_layer *l_layout_layer[1] = {(struct ivi_layout_layer *)0xFFFFFFFF}; + SET_RETURN_SEQ(get_layer_from_id, l_layout_layer, 1); + + controller_set_layer_source_rectangle(nullptr, nullptr, 1, 1, 1, 1, 1); + + ASSERT_EQ(layer_set_source_rectangle_fake.call_count, 1); + ASSERT_EQ(layer_set_source_rectangle_fake.arg1_val, 1); + ASSERT_EQ(layer_set_source_rectangle_fake.arg2_val, 1); + ASSERT_EQ(layer_set_source_rectangle_fake.arg3_val, 1); + ASSERT_EQ(layer_set_source_rectangle_fake.arg4_val, 1); +} + +/** ================================================================================================ + * @test_id controller_set_layer_source_rectangle_successWithNegativeValues + * @brief Test case of controller_set_layer_source_rectangle() where get_layer_from_id() success, return an object + * and input x, y, width, height are negative values + * @test_procedure Steps: + * -# Set data of ivi_layout_layer_properties to default value {0} + * -# Mocking the get_properties_of_layer() does return an object + * -# Mocking the wl_resource_get_user_data() does return an object + * -# Mocking the get_layer_from_id() does return an object + * -# Calling the controller_set_layer_source_rectangle() + * -# Verification point: + * +# layer_set_source_rectangle() must be called once time + * +# Input data of layer_set_source_rectangle() must same default value of ivi_layout_layer_properties + */ +TEST_F(ControllerTests, controller_set_layer_source_rectangle_successWithNegativeValues) +{ + const struct ivi_layout_layer_properties l_prop = { + .opacity = 0, + .source_x = 0, + .source_y = 0, + .source_width = 0, + .source_height = 0, + .dest_x = 0, + .dest_y = 0, + .dest_width = 0, + .dest_height = 0, + .orientation = WL_OUTPUT_TRANSFORM_NORMAL, + .visibility = true, + .transition_type = 0, + .transition_duration = 0, + .start_alpha = 0, + .end_alpha = 0, + .is_fade_in = 0, + .event_mask = 0, + }; + const struct ivi_layout_layer_properties *prop[1] = {&l_prop}; + + SET_RETURN_SEQ(get_properties_of_layer, prop, 1); + SET_RETURN_SEQ(wl_resource_get_user_data, (void**)mp_iviController, 1); + struct ivi_layout_layer *l_layout_layer[1] = {(struct ivi_layout_layer *)0xFFFFFFFF}; + SET_RETURN_SEQ(get_layer_from_id, l_layout_layer, 1); + + controller_set_layer_source_rectangle(nullptr, nullptr, 1, -1, -1, -1, -1); + + ASSERT_EQ(layer_set_source_rectangle_fake.call_count, 1); + ASSERT_EQ(layer_set_source_rectangle_fake.arg1_val, 0); + ASSERT_EQ(layer_set_source_rectangle_fake.arg2_val, 0); + ASSERT_EQ(layer_set_source_rectangle_fake.arg3_val, 0); + ASSERT_EQ(layer_set_source_rectangle_fake.arg4_val, 0); +} + +/** ================================================================================================ + * @test_id controller_set_surface_destination_rectangle_wrongLayoutSurface + * @brief Test case of controller_set_surface_destination_rectangle() where get_surface_from_id() fails, return null pointer + * @test_procedure Steps: + * -# Mocking the wl_resource_get_user_data() does return an object + * -# Calling the controller_set_surface_destination_rectangle() + * -# Verification point: + * +# wl_resource_post_event() must be called once time + */ +TEST_F(ControllerTests, controller_set_surface_destination_rectangle_wrongLayoutSurface) +{ + SET_RETURN_SEQ(wl_resource_get_user_data, (void**)mp_iviController, 1); + + controller_set_surface_destination_rectangle(nullptr, nullptr, 1, 1, 1, 1, 1); + + ASSERT_EQ(wl_resource_post_event_fake.call_count, 1); +} + +/** ================================================================================================ + * @test_id controller_set_surface_destination_rectangle_successWithPositiveValues + * @brief Test case of controller_set_surface_destination_rectangle() where get_surface_from_id() success, return an object + * and input x, y, width, height are positive values + * @test_procedure Steps: + * -# Mocking the wl_resource_get_user_data() does return an object + * -# Mocking the get_surface_from_id() does return an object + * -# Calling the controller_set_surface_destination_rectangle() + * -# Verification point: + * +# surface_set_destination_rectangle() must be called once time + * +# Input data of surface_set_destination_rectangle() must same input data of controller_set_surface_destination_rectangle() + */ +TEST_F(ControllerTests, controller_set_surface_destination_rectangle_successWithPositiveValues) +{ + SET_RETURN_SEQ(wl_resource_get_user_data, (void**)mp_iviController, 1); + struct ivi_layout_surface *l_layout_surface[1] = {(struct ivi_layout_surface *)0xFFFFFFFF}; + SET_RETURN_SEQ(get_surface_from_id, l_layout_surface, 1); + + controller_set_surface_destination_rectangle(nullptr, nullptr, 1, 1, 1, 1, 1); + + ASSERT_EQ(surface_set_destination_rectangle_fake.call_count, 1); + ASSERT_EQ(surface_set_destination_rectangle_fake.arg1_val, 1); + ASSERT_EQ(surface_set_destination_rectangle_fake.arg2_val, 1); + ASSERT_EQ(surface_set_destination_rectangle_fake.arg3_val, 1); + ASSERT_EQ(surface_set_destination_rectangle_fake.arg4_val, 1); +} + +/** ================================================================================================ + * @test_id controller_set_surface_destination_rectangle_successWithNegativeValues + * @brief Test case of controller_set_surface_destination_rectangle() where get_surface_from_id() success, return an object + * and input x, y, width, height are negative values + * @test_procedure Steps: + * -# Set data of ivi_layout_surface_properties to default value {0} + * -# Mocking the get_properties_of_surface() does return an object + * -# Mocking the wl_resource_get_user_data() does return an object + * -# Mocking the get_surface_from_id() does return an object + * -# Calling the controller_set_surface_destination_rectangle() + * -# Verification point: + * +# surface_set_destination_rectangle() must be called once time + * +# Input data of surface_set_destination_rectangle() must same default value of ivi_layout_surface_properties + */ +TEST_F(ControllerTests, controller_set_surface_destination_rectangle_successWithNegativeValues) +{ + const struct ivi_layout_surface_properties l_prop = { + .opacity = 0, + .source_x = 0, + .source_y = 0, + .source_width = 0, + .source_height = 0, + .start_x = 0, + .start_y = 0, + .start_width = 0, + .start_height = 0, + .dest_x = 0, + .dest_y = 0, + .dest_width = 0, + .dest_height = 0, + .orientation = WL_OUTPUT_TRANSFORM_NORMAL, + .visibility = true, + .transition_type = 0, + .transition_duration = 0, + .event_mask = 0, + }; + const struct ivi_layout_surface_properties *prop[1] = {&l_prop}; + + SET_RETURN_SEQ(get_properties_of_surface, prop, 1); + SET_RETURN_SEQ(wl_resource_get_user_data, (void**)mp_iviController, 1); + struct ivi_layout_surface *l_layout_surface[1] = {(struct ivi_layout_surface *)0xFFFFFFFF}; + SET_RETURN_SEQ(get_surface_from_id, l_layout_surface, 1); + + controller_set_surface_destination_rectangle(nullptr, nullptr, 1, -1, -1, -1, -1); + + ASSERT_EQ(surface_set_destination_rectangle_fake.call_count, 1); + ASSERT_EQ(surface_set_destination_rectangle_fake.arg1_val, 0); + ASSERT_EQ(surface_set_destination_rectangle_fake.arg2_val, 0); + ASSERT_EQ(surface_set_destination_rectangle_fake.arg3_val, 0); + ASSERT_EQ(surface_set_destination_rectangle_fake.arg4_val, 0); +} + +/** ================================================================================================ + * @test_id controller_set_layer_destination_rectangle_wrongLayoutLayer + * @brief Test case of controller_set_layer_destination_rectangle() where get_layer_from_id() fails, return null pointer + * @test_procedure Steps: + * -# Mocking the wl_resource_get_user_data() does return an object + * -# Calling the controller_set_layer_destination_rectangle() + * -# Verification point: + * +# wl_resource_post_event() must be called once time + */ +TEST_F(ControllerTests, controller_set_layer_destination_rectangle_wrongLayoutLayer) +{ + SET_RETURN_SEQ(wl_resource_get_user_data, (void**)mp_iviController, 1); + + controller_set_layer_destination_rectangle(nullptr, nullptr, 1, 1, 1, 1, 1); + + ASSERT_EQ(wl_resource_post_event_fake.call_count, 1); +} + +/** ================================================================================================ + * @test_id controller_set_layer_destination_rectangle_successWithPositiveValues + * @brief Test case of controller_set_layer_destination_rectangle() where get_layer_from_id() success, return an object + * and input x, y, width, height are positive values + * @test_procedure Steps: + * -# Mocking the wl_resource_get_user_data() does return an object + * -# Mocking the get_layer_from_id() does return an object + * -# Calling the controller_set_layer_destination_rectangle() + * -# Verification point: + * +# layer_set_destination_rectangle() must be called once time + * +# Input data of layer_set_destination_rectangle() must same input data of controller_set_layer_destination_rectangle() + */ +TEST_F(ControllerTests, controller_set_layer_destination_rectangle_successWithPositiveValues) +{ + SET_RETURN_SEQ(wl_resource_get_user_data, (void**)mp_iviController, 1); + struct ivi_layout_layer *l_layout_layer[1] = {(struct ivi_layout_layer *)0xFFFFFFFF}; + SET_RETURN_SEQ(get_layer_from_id, l_layout_layer, 1); + + controller_set_layer_destination_rectangle(nullptr, nullptr, 1, 1, 1, 1, 1); + + ASSERT_EQ(layer_set_destination_rectangle_fake.call_count, 1); + ASSERT_EQ(layer_set_destination_rectangle_fake.arg1_val, 1); + ASSERT_EQ(layer_set_destination_rectangle_fake.arg2_val, 1); + ASSERT_EQ(layer_set_destination_rectangle_fake.arg3_val, 1); + ASSERT_EQ(layer_set_destination_rectangle_fake.arg4_val, 1); +} + +/** ================================================================================================ + * @test_id controller_set_layer_destination_rectangle_successWithNegativeValues + * @brief Test case of controller_set_layer_destination_rectangle() where get_layer_from_id() success, return an object + * and input x, y, width, height are negative values + * @test_procedure Steps: + * -# Set data of ivi_layout_layer_properties to default value {0} + * -# Mocking the get_properties_of_layer() does return an object + * -# Mocking the wl_resource_get_user_data() does return an object + * -# Mocking the get_layer_from_id() does return an object + * -# Calling the controller_set_layer_destination_rectangle() + * -# Verification point: + * +# layer_set_destination_rectangle() must be called once time + * +# Input data of layer_set_destination_rectangle() must same default value of ivi_layout_layer_properties + */ +TEST_F(ControllerTests, controller_set_layer_destination_rectangle_successWithNegativeValues) +{ + const struct ivi_layout_layer_properties l_prop = { + .opacity = 0, + .source_x = 0, + .source_y = 0, + .source_width = 0, + .source_height = 0, + .dest_x = 0, + .dest_y = 0, + .dest_width = 0, + .dest_height = 0, + .orientation = WL_OUTPUT_TRANSFORM_NORMAL, + .visibility = true, + .transition_type = 0, + .transition_duration = 0, + .start_alpha = 0, + .end_alpha = 0, + .is_fade_in = 0, + .event_mask = 0, + }; + const struct ivi_layout_layer_properties *prop[1] = {&l_prop}; + + SET_RETURN_SEQ(get_properties_of_layer, prop, 1); + SET_RETURN_SEQ(wl_resource_get_user_data, (void**)mp_iviController, 1); + struct ivi_layout_layer *l_layout_layer[1] = {(struct ivi_layout_layer *)0xFFFFFFFF}; + SET_RETURN_SEQ(get_layer_from_id, l_layout_layer, 1); + + controller_set_layer_destination_rectangle(nullptr, nullptr, 1, -1, -1, -1, -1); + + ASSERT_EQ(layer_set_destination_rectangle_fake.call_count, 1); + ASSERT_EQ(layer_set_destination_rectangle_fake.arg1_val, 0); + ASSERT_EQ(layer_set_destination_rectangle_fake.arg2_val, 0); + ASSERT_EQ(layer_set_destination_rectangle_fake.arg3_val, 0); + ASSERT_EQ(layer_set_destination_rectangle_fake.arg4_val, 0); +} + +/** ================================================================================================ + * @test_id controller_surface_sync_wrongLayoutSurface + * @brief Test case of controller_surface_sync() where get_surface_from_id() fails, return null pointer + * @test_procedure Steps: + * -# Mocking the wl_resource_get_user_data() does return an object + * -# Calling the controller_surface_sync() + * -# Verification point: + * +# wl_resource_post_event() must be called once time + */ +TEST_F(ControllerTests, controller_surface_sync_wrongLayoutSurface) +{ + SET_RETURN_SEQ(wl_resource_get_user_data, (void**)mp_iviController, 1); + + controller_surface_sync(nullptr, nullptr, 1, 1); + + ASSERT_EQ(wl_resource_post_event_fake.call_count, 1); +} + +/** ================================================================================================ + * @test_id controller_surface_sync_add + * @brief Test case of controller_surface_sync() where get_surface_from_id() success, return an object + * and input sync_state is IVI_WM_SYNC_ADD {0} + * @test_procedure Steps: + * -# Mocking the wl_resource_get_user_data() does return an object + * -# Mocking the get_surface_from_id() does return an object + * -# Calling the controller_surface_sync() + * -# Verification point: + * +# wl_list_insert() must be called 2 times + * +# Free resources are allocated when running the test + */ +TEST_F(ControllerTests, controller_surface_sync_add) +{ + SET_RETURN_SEQ(wl_resource_get_user_data, (void**)mp_iviController, 1); + struct ivi_layout_surface *l_layout_surface[1] = {&m_layoutSurface[0]}; + SET_RETURN_SEQ(get_surface_from_id, l_layout_surface, 1); + + controller_surface_sync(nullptr, mp_surfaceNotification[0]->resource, 1, 0); + + ASSERT_EQ(wl_list_insert_fake.call_count, 2); + + struct notification *l_not = (struct notification*)(uintptr_t(wl_list_insert_fake.arg1_history[0]) - offsetof(struct notification, link)); + free(l_not); +} + +/** ================================================================================================ + * @test_id controller_surface_sync_remove + * @brief Test case of controller_surface_sync() where get_surface_from_id() success, return an object + * and input sync_state is IVI_WM_SYNC_REMOVE {1} + * @test_procedure Steps: + * -# Mocking the wl_resource_get_user_data() does return an object + * -# Mocking the get_surface_from_id() does return an object + * -# Calling the controller_surface_sync() + * -# Verification point: + * +# wl_list_remove() must be called 2 times + * +# Allocate memory for resources are freed when running the test + */ +TEST_F(ControllerTests, controller_surface_sync_remove) +{ + SET_RETURN_SEQ(wl_resource_get_user_data, (void**)mp_iviController, 1); + struct ivi_layout_surface *l_layout_surface[1] = {&m_layoutSurface[0]}; + SET_RETURN_SEQ(get_surface_from_id, l_layout_surface, 1); + + controller_surface_sync(nullptr, mp_surfaceNotification[0]->resource, 1, 1); + + ASSERT_EQ(wl_list_remove_fake.call_count, 2); + + mp_surfaceNotification[0] = (struct notification*)malloc(sizeof(struct notification)); +} + +/** ================================================================================================ + * @test_id controller_surface_sync_default + * @brief Test case of controller_surface_sync() where get_surface_from_id() success, return an object + * and input sync_state is default value (not add/remove) + * @test_procedure Steps: + * -# Mocking the wl_resource_get_user_data() does return an object + * -# Mocking the get_surface_from_id() does return an object + * -# Calling the controller_surface_sync() + * -# Verification point: + * +# wl_resource_post_event() must be called once time + */ +TEST_F(ControllerTests, controller_surface_sync_default) +{ + SET_RETURN_SEQ(wl_resource_get_user_data, (void**)mp_iviController, 1); + struct ivi_layout_surface *l_layout_surface[1] = {(struct ivi_layout_surface *)0xFFFFFFFF}; + SET_RETURN_SEQ(get_surface_from_id, l_layout_surface, 1); + + controller_surface_sync(nullptr, nullptr, 1, 2); + + ASSERT_EQ(wl_resource_post_event_fake.call_count, 1); +} + +/** ================================================================================================ + * @test_id controller_layer_sync_wrongLayoutLayer + * @brief Test case of controller_layer_sync() where get_layer_from_id() fails, return null pointer + * @test_procedure Steps: + * -# Mocking the wl_resource_get_user_data() does return an object + * -# Calling the controller_layer_sync() + * -# Verification point: + * +# wl_resource_post_event() must be called once time + */ +TEST_F(ControllerTests, controller_layer_sync_wrongLayoutLayer) +{ + SET_RETURN_SEQ(wl_resource_get_user_data, (void**)mp_iviController, 1); + + controller_layer_sync(nullptr, nullptr, 1, 1); + + ASSERT_EQ(wl_resource_post_event_fake.call_count, 1); +} + +/** ================================================================================================ + * @test_id controller_layer_sync_add + * @brief Test case of controller_layer_sync() where get_layer_from_id() success, return an object + * and input sync_state is IVI_WM_SYNC_ADD {0} + * @test_procedure Steps: + * -# Mocking the wl_resource_get_user_data() does return an object + * -# Mocking the get_layer_from_id() does return an object + * -# Calling the controller_layer_sync() + * -# Verification point: + * +# wl_list_insert() must be called 2 times + * +# Free resources are allocated when running the test + */ +TEST_F(ControllerTests, controller_layer_sync_add) +{ + SET_RETURN_SEQ(wl_resource_get_user_data, (void**)mp_iviController, 1); + struct ivi_layout_layer *l_layout_layer[1] = {&m_layoutLayer[0]}; + SET_RETURN_SEQ(get_layer_from_id, l_layout_layer, 1); + + controller_layer_sync(nullptr, mp_LayerNotification[0]->resource, 1, 0); + + ASSERT_EQ(wl_list_insert_fake.call_count, 2); + + struct notification *l_not = (struct notification*)(uintptr_t(wl_list_insert_fake.arg1_history[0]) - offsetof(struct notification, link)); + free(l_not); +} + +/** ================================================================================================ + * @test_id controller_layer_sync_remove + * @brief Test case of controller_layer_sync() where get_layer_from_id() success, return an object + * and input sync_state is IVI_WM_SYNC_REMOVE {1} + * @test_procedure Steps: + * -# Mocking the wl_resource_get_user_data() does return an object + * -# Mocking the get_layer_from_id() does return an object + * -# Calling the controller_layer_sync() + * -# Verification point: + * +# wl_list_remove() must be called 2 times + * +# Allocate memory for resources are freed when running the test + */ +TEST_F(ControllerTests, controller_layer_sync_remove) +{ + SET_RETURN_SEQ(wl_resource_get_user_data, (void**)mp_iviController, 1); + struct ivi_layout_layer *l_layout_layer[1] = {&m_layoutLayer[0]}; + SET_RETURN_SEQ(get_layer_from_id, l_layout_layer, 1); + + controller_layer_sync(nullptr, mp_LayerNotification[0]->resource, 1, 1); + + ASSERT_EQ(wl_list_remove_fake.call_count, 2); + + mp_LayerNotification[0] = (struct notification*)malloc(sizeof(struct notification)); +} + +/** ================================================================================================ + * @test_id controller_layer_sync_default + * @brief Test case of controller_layer_sync() where get_layer_from_id() success, return an object + * and input sync_state is default value (not add/remove) + * @test_procedure Steps: + * -# Mocking the wl_resource_get_user_data() does return an object + * -# Mocking the get_layer_from_id() does return an object + * -# Calling the controller_layer_sync() + * -# Verification point: + * +# wl_resource_post_event() must be called once time + */ +TEST_F(ControllerTests, controller_layer_sync_default) +{ + SET_RETURN_SEQ(wl_resource_get_user_data, (void**)mp_iviController, 1); + struct ivi_layout_layer *l_layout_layer[1] = {(struct ivi_layout_layer *)0xFFFFFFFF}; + SET_RETURN_SEQ(get_layer_from_id, l_layout_layer, 1); + + controller_layer_sync(nullptr, nullptr, 1, 2); + + ASSERT_EQ(wl_resource_post_event_fake.call_count, 1); +} + +/** ================================================================================================ + * @test_id controller_surface_get_wrongLayoutSurface + * @brief Test case of controller_surface_get() where get_surface_from_id() fails, return null pointer + * @test_procedure Steps: + * -# Mocking the wl_resource_get_user_data() does return an object + * -# Calling the controller_surface_get() + * -# Verification point: + * +# wl_resource_post_event() must be called once time + */ +TEST_F(ControllerTests, controller_surface_get_wrongLayoutSurface) +{ + SET_RETURN_SEQ(wl_resource_get_user_data, (void**)mp_iviController, 1); + + controller_surface_get(nullptr, nullptr, 1, 1); + + ASSERT_EQ(wl_resource_post_event_fake.call_count, 1); +} + +/** ================================================================================================ + * @test_id controller_surface_get_success + * @brief Test case of controller_surface_get() where get_surface_from_id() success, return an object + * @test_procedure Steps: + * -# Mocking the wl_resource_get_user_data() does return an object + * -# Mocking the get_surface_from_id() does return an object + * -# Mocking the surface_get_weston_surface() does return an object + * -# Calling the controller_surface_get() + * -# Verification point: + * +# get_properties_of_surface() must be called once time + * +# Free resources are allocated when running the test + */ +TEST_F(ControllerTests, controller_surface_get_success) +{ + SET_RETURN_SEQ(wl_resource_get_user_data, (void**)mp_iviController, 1); + struct ivi_layout_surface *l_layout_surface[1] = {&m_layoutSurface[0]}; + SET_RETURN_SEQ(get_surface_from_id, l_layout_surface, 1); + struct weston_surface *l_surface[1] = {(struct weston_surface *)malloc(sizeof(struct weston_surface))}; + SET_RETURN_SEQ(surface_get_weston_surface, l_surface, 1); + + controller_surface_get(nullptr, nullptr, 1, 0); + + ASSERT_EQ(get_properties_of_surface_fake.call_count, 1); + + free(l_surface[0]); +} + +/** ================================================================================================ + * @test_id controller_layer_get_wrongLayoutLayer + * @brief Test case of controller_layer_get() where get_layer_from_id() fails, return null pointer + * @test_procedure Steps: + * -# Mocking the wl_resource_get_user_data() does return an object + * -# Calling the controller_layer_get() + * -# Verification point: + * +# wl_resource_post_event() must be called once time + */ +TEST_F(ControllerTests, controller_layer_get_wrongLayoutLayer) +{ + SET_RETURN_SEQ(wl_resource_get_user_data, (void**)mp_iviController, 1); + + controller_layer_get(nullptr, nullptr, 1, 1); + + ASSERT_EQ(wl_resource_post_event_fake.call_count, 1); +} + +/** ================================================================================================ + * @test_id controller_layer_get_wrongParam + * @brief Test case of controller_layer_get() where get_layer_from_id() success, return an object + * and invalid input param + * @test_procedure Steps: + * -# Mocking the wl_resource_get_user_data() does return an object + * -# Mocking the get_layer_from_id() does return an object + * -# Calling the controller_layer_get() + * -# Verification point: + * +# wl_resource_post_event() not be called + * +# get_surfaces_on_layer() not be called + */ +TEST_F(ControllerTests, controller_layer_get_wrongParam) +{ + SET_RETURN_SEQ(wl_resource_get_user_data, (void**)mp_iviController, 1); + struct ivi_layout_layer *l_layout_layer[1] = {(struct ivi_layout_layer *)0xFFFFFFFF}; + SET_RETURN_SEQ(get_layer_from_id, l_layout_layer, 1); + + controller_layer_get(nullptr, nullptr, 1, 0); + + ASSERT_EQ(wl_resource_post_event_fake.call_count, 0); + ASSERT_EQ(get_surfaces_on_layer_fake.call_count, 0); +} + +/** ================================================================================================ + * @test_id controller_layer_get_success + * @brief Test case of controller_layer_get() where get_layer_from_id() success, return an object + * and valid input param + * @test_procedure Steps: + * -# Mocking the wl_resource_get_user_data() does return an object + * -# Mocking the get_layer_from_id() does return an object + * -# Mocking the get_properties_of_layer() does return an object + * -# Calling the controller_layer_get() + * -# Verification point: + * +# wl_resource_post_event() must be called once time + * +# get_surfaces_on_layer() must be called once time + */ +TEST_F(ControllerTests, controller_layer_get_success) +{ + SET_RETURN_SEQ(wl_resource_get_user_data, (void**)mp_iviController, 1); + struct ivi_layout_layer *l_layout_layer[1] = {&m_layoutLayer[0]}; + SET_RETURN_SEQ(get_layer_from_id, l_layout_layer, 1); + const struct ivi_layout_layer_properties *l_prop[1] = {&m_layoutLayerProperties[0]}; + SET_RETURN_SEQ(get_properties_of_layer, l_prop, 1); + + controller_layer_get(nullptr, nullptr, 1, 8); + + ASSERT_EQ(wl_resource_post_event_fake.call_count, 1); + ASSERT_EQ(get_surfaces_on_layer_fake.call_count, 1); +} + +/** ================================================================================================ + * @test_id controller_surface_screenshot_nullScreenShot + * @brief Test case of controller_surface_screenshot() where wl_resource_create() fails, return null pointer + * @test_procedure Steps: + * -# Mocking the wl_resource_get_user_data() does return an object + * -# Calling the controller_surface_screenshot() + * -# Verification point:` + * +# wl_client_post_no_memory() must be called once time + */ +TEST_F(ControllerTests, controller_surface_screenshot_nullScreenShot) +{ + struct wl_client * lClient; + struct wl_resource * lResource; + struct wl_resource * lBufferResource; + uint32_t lScreenshotId{1}; + uint32_t lSurfaceId{1}; + + struct wl_resource * lScreenshotRetList[1] = {NULL}; + SET_RETURN_SEQ(wl_resource_get_user_data,(void**)mp_iviController, 1); + SET_RETURN_SEQ(wl_resource_create, (void**)lScreenshotRetList, 1); + + controller_surface_screenshot(lClient, lResource, lBufferResource, lScreenshotId, lSurfaceId); + + ASSERT_EQ(wl_client_post_no_memory_fake.call_count, 1); + ASSERT_EQ(get_surface_from_id_fake.call_count, 0); +} + +/** ================================================================================================ + * @test_id controller_surface_screenshot_GetLayoutSurfaceFailed + * @brief Test case of controller_surface_screenshot() where get_surface_from_id() fails, return null pointer + * @test_procedure Steps: + * -# Mocking the wl_resource_get_user_data() does return an object + * -# Mocking the wl_resource_create() does return an object + * -# Calling the controller_surface_screenshot() + * -# Verification point: + * +# get_surface_from_id() must be called once time + * +# wl_resource_destroy() must be called once time + * +# wl_resource_post_event() must be called once time and opcode should be IVI_SCREENSHOT_ERROR + * +# surface_get_size() should not be called + */ +TEST_F(ControllerTests, controller_surface_screenshot_GetLayoutSurfaceFailed) +{ + struct wl_client * lClient; + struct wl_resource * lResource; + struct wl_resource * lBufferResource; + uint32_t lScreenshotId{1}; + uint32_t lSurfaceId{1}; + + SET_RETURN_SEQ(wl_resource_get_user_data, (void**)mp_iviController, 1); + struct wl_resource * lScreenshotRetList[1] = {(struct wl_resource *)0xFFFFFFFF}; + SET_RETURN_SEQ(wl_resource_create, lScreenshotRetList, 1); + + controller_surface_screenshot(lClient, lResource, lBufferResource, lScreenshotId, lSurfaceId); + + ASSERT_EQ(get_surface_from_id_fake.call_count, 1); + ASSERT_EQ(wl_resource_destroy_fake.call_count, 1); + ASSERT_EQ(wl_resource_post_event_fake.call_count, 1); + ASSERT_EQ(wl_resource_post_event_fake.arg1_val, IVI_SCREENSHOT_ERROR); + ASSERT_EQ(surface_get_size_fake.call_count, 0); +} + +/** ================================================================================================ + * @test_id controller_surface_screenshot_ContentOfSurfaceInvalid + * @brief Test case of controller_surface_screenshot() where the content of surface are invalid + * @test_procedure Steps: + * -# Mocking the wl_resource_get_user_data() does return an success object + * -# Mocking the wl_resource_create() does return an success object + * -# Mocking the get_surface_from_id() does return an success object + * -# Calling the controller_surface_screenshot() + * -# Verification point: + * +# get_surface_from_id() must be called once time + * +# wl_resource_destroy() must be called once time + * +# wl_resource_post_event() must be called once time and opcode should be IVI_SCREENSHOT_ERROR + * +# surface_get_size() should not be called + * +# weston_buffer_from_resource() should not be called + */ +TEST_F(ControllerTests, controller_surface_screenshot_ContentOfSurfaceInvalid) +{ + struct wl_client * lClient; + struct wl_resource * lResource; + struct wl_resource * lBufferResource; + uint32_t lScreenshotId{1}; + uint32_t lSurfaceId{1}; + + SET_RETURN_SEQ(wl_resource_get_user_data, (void**)mp_iviController, 1); + struct wl_resource *lScreenshotRetList[1] = {(struct wl_resource *)0xFFFFFFFF}; + SET_RETURN_SEQ(wl_resource_create, lScreenshotRetList, 1); + struct ivi_layout_surface *lLayoutSurfaceRetList[1] = {(struct ivi_layout_surface *)0xFFFFFFFF}; + SET_RETURN_SEQ(get_surface_from_id, lLayoutSurfaceRetList, 1); + + surface_get_size_fake.custom_fake = nullptr; + + controller_surface_screenshot(lClient, lResource, lBufferResource, lScreenshotId, lSurfaceId); + + ASSERT_EQ(get_surface_from_id_fake.call_count, 1); + ASSERT_EQ(wl_resource_destroy_fake.call_count, 1); + ASSERT_EQ(wl_resource_post_event_fake.call_count, 1); + ASSERT_EQ(wl_resource_post_event_fake.arg1_val, IVI_SCREENSHOT_ERROR); + ASSERT_EQ(surface_get_size_fake.call_count, 1); + ASSERT_EQ(weston_buffer_from_resource_fake.call_count, 0); +} + +/** ================================================================================================ + * @test_id controller_surface_screenshot_WhenGetWestonBuffer + * @brief Test case of controller_surface_screenshot() where cannot get weston buffer from buffer resource + * @test_procedure Steps: + * -# Mocking the wl_resource_get_user_data() does return an success object + * -# Mocking the wl_resource_create() does return an success object + * -# Mocking the get_surface_from_id() does return an success object + * -# Mocking the weston_buffer_from_resource() does return an null pointer + * -# Calling the controller_surface_screenshot() + * -# Verification point: + * +# get_surface_from_id() must be called once time + * +# wl_resource_destroy() must be called once time + * +# wl_resource_post_event() must be called once time and opcode should be IVI_SCREENSHOT_ERROR + * +# surface_get_size() must be called once time + * +# weston_buffer_from_resource() must be called once time and return a NULL pointer + * +# wl_shm_buffer_get_data() should not be called + */ +TEST_F(ControllerTests, controller_surface_screenshot_WhenGetWestonBuffer) +{ + struct wl_client * lClient; + struct wl_resource * lResource; + struct wl_resource * lBufferResource; + uint32_t lScreenshotId{1}; + uint32_t lSurfaceId{1}; + + SET_RETURN_SEQ(wl_resource_get_user_data, (void**)mp_iviController, 1); + struct wl_resource *lScreenshotRetList[1] = {(struct wl_resource *)0xFFFFFFFF}; + SET_RETURN_SEQ(wl_resource_create, lScreenshotRetList, 1); + struct ivi_layout_surface *lLayoutSurfaceRetList[1] = {(struct ivi_layout_surface *)0xFFFFFFFF}; + SET_RETURN_SEQ(get_surface_from_id, lLayoutSurfaceRetList, 1); + surface_get_size_fake.custom_fake = custom_surface_get_size; + struct weston_buffer * lWestonBufferRetList[1] = {NULL}; + SET_RETURN_SEQ(weston_buffer_from_resource, (struct weston_buffer **)lWestonBufferRetList, 1); + + controller_surface_screenshot(lClient, lResource, lBufferResource, lScreenshotId, lSurfaceId); + + ASSERT_EQ(get_surface_from_id_fake.call_count, 1); + ASSERT_EQ(surface_get_size_fake.call_count, 1); + ASSERT_EQ(weston_buffer_from_resource_fake.call_count, 1); + ASSERT_EQ(weston_buffer_from_resource_fake.return_val, NULL); + ASSERT_EQ(wl_resource_post_event_fake.call_count, 1); + ASSERT_EQ(wl_resource_post_event_fake.arg1_val, IVI_SCREENSHOT_ERROR); + ASSERT_EQ(wl_shm_buffer_get_data_fake.call_count, 0); + ASSERT_EQ(wl_resource_destroy_fake.call_count, 1); +} + +/** ================================================================================================ + * @test_id controller_surface_screenshot_SurfaceDumpDataFailed + * @brief controller_surface_screenshot() is called when surface dump data to buffer failed + * @test_procedure Steps: + * -# Mocking the wl_resource_get_user_data() does return an success object + * -# Mocking the wl_resource_create() does return an success object + * -# Mocking the get_surface_from_id() does return an success object + * -# Mocking the weston_buffer_from_resource() does return an success object + * -# Mocking the wl_shm_buffer_get_stride() does return an success object + * -# Mocking the wl_shm_buffer_get_width() does return an success object + * -# Mocking the wl_shm_buffer_get_height() does return an success object + * -# Mocking the surface_dump() does return an failure object + * -# Calling the controller_surface_screenshot() + * -# Verification point: + * +# get_surface_from_id() must be called once time + * +# wl_resource_destroy() must be called once time + * +# wl_resource_post_event() must be called once time and opcode should be IVI_SCREENSHOT_ERROR + * +# surface_get_size() must be called once time + * +# weston_buffer_from_resource() must be called once time + * +# wl_shm_buffer_get_data() must be called once time + * +# surface_dump() must be called once time + */ +TEST_F(ControllerTests, controller_surface_screenshot_SurfaceDumpDataFailed) +{ + struct wl_client * lClient; + struct wl_resource * lResource; + struct wl_resource * lBufferResource; + uint32_t lScreenshotId{1}; + uint32_t lSurfaceId{1}; + + SET_RETURN_SEQ(wl_resource_get_user_data, (void**)mp_iviController, 1); + struct wl_resource *lScreenshotRetList[1] = {(struct wl_resource *)0xFFFFFFFF}; + SET_RETURN_SEQ(wl_resource_create, lScreenshotRetList, 1); + struct ivi_layout_surface *lLayoutSurfaceRetList[1] = {(struct ivi_layout_surface *)0xFFFFFFFF}; + SET_RETURN_SEQ(get_surface_from_id, lLayoutSurfaceRetList, 1); + surface_get_size_fake.custom_fake = custom_surface_get_size; + struct weston_buffer * westonBuffer = (struct weston_buffer*)malloc(sizeof(weston_buffer)); + westonBuffer->type = 0; // WESTON_BUFFER_SHM + struct weston_buffer * lWestonBufferRetList[1] = {westonBuffer}; + SET_RETURN_SEQ(weston_buffer_from_resource, (struct weston_buffer **)lWestonBufferRetList, 1); + int validStride[1] = {4}; + int validWidth[1] = {1}; + int validheight[1] = {1}; + SET_RETURN_SEQ(wl_shm_buffer_get_stride, validStride, 1); + SET_RETURN_SEQ(wl_shm_buffer_get_width, validWidth, 1); + SET_RETURN_SEQ(wl_shm_buffer_get_height, validheight, 1); + SET_RETURN_SEQ(surface_dump, &mp_failureResult[0], 1); + + controller_surface_screenshot(lClient, lResource, lBufferResource, lScreenshotId, lSurfaceId); + + ASSERT_EQ(get_surface_from_id_fake.call_count, 1); + ASSERT_EQ(wl_resource_destroy_fake.call_count, 1); + ASSERT_EQ(surface_get_size_fake.call_count, 1); + ASSERT_EQ(weston_buffer_from_resource_fake.call_count, 1); + ASSERT_EQ(wl_shm_buffer_get_data_fake.call_count, 1); + ASSERT_EQ(surface_dump_fake.call_count, 1); + ASSERT_EQ(wl_resource_post_event_fake.call_count, 1); + ASSERT_EQ(wl_resource_post_event_fake.arg1_val, IVI_SCREENSHOT_ERROR); + free(westonBuffer); +} + +/** ================================================================================================ + * @test_id controller_surface_screenshot_success + * @brief controller_surface_screenshot() is called successfully + * @test_procedure Steps: + * -# Mocking the wl_resource_get_user_data() does return an success object + * -# Mocking the wl_resource_create() does return an success object + * -# Mocking the get_surface_from_id() does return an success object + * -# Mocking the weston_buffer_from_resource() does return an success object + * -# Mocking the wl_shm_buffer_get_stride() does return an success object + * -# Mocking the wl_shm_buffer_get_width() does return an success object + * -# Mocking the wl_shm_buffer_get_height() does return an success object + * -# Mocking the surface_dump() does return an success object + * -# Calling the controller_surface_screenshot() + * -# Verification point: + * +# get_surface_from_id() must be called once time + * +# wl_resource_destroy() must be called once time + * +# wl_resource_post_event() must be called once time and opcode should be IVI_SCREENSHOT_DONE + * +# surface_get_size() must be called once time + * +# weston_buffer_from_resource() must be called once time + * +# wl_shm_buffer_get_data() must be called once time + * +# surface_dump() must be called once time + */ +TEST_F(ControllerTests, controller_surface_screenshot_success) +{ + struct wl_client * lClient; + struct wl_resource * lResource; + struct wl_resource * lBufferResource; + uint32_t lScreenshotId{1}; + uint32_t lSurfaceId{1}; + + SET_RETURN_SEQ(wl_resource_get_user_data, (void**)mp_iviController, 1); + struct wl_resource *lScreenshotRetList[1] = {(struct wl_resource *)0xFFFFFFFF}; + SET_RETURN_SEQ(wl_resource_create, lScreenshotRetList, 1); + struct ivi_layout_surface *lLayoutSurfaceRetList[1] = {(struct ivi_layout_surface *)0xFFFFFFFF}; + SET_RETURN_SEQ(get_surface_from_id, lLayoutSurfaceRetList, 1); + surface_get_size_fake.custom_fake = custom_surface_get_size; + struct weston_buffer * westonBuffer = (struct weston_buffer*)malloc(sizeof(weston_buffer)); + westonBuffer->type = 0; // WESTON_BUFFER_SHM + struct weston_buffer * lWestonBufferRetList[1] = {westonBuffer}; + SET_RETURN_SEQ(weston_buffer_from_resource, (struct weston_buffer **)lWestonBufferRetList, 1); + int validStride[1] = {4}; + int validWidth[1] = {1}; + int validheight[1] = {1}; + SET_RETURN_SEQ(wl_shm_buffer_get_stride, validStride, 1); + SET_RETURN_SEQ(wl_shm_buffer_get_width, validWidth, 1); + SET_RETURN_SEQ(wl_shm_buffer_get_height, validheight, 1); + + controller_surface_screenshot(lClient, lResource, lBufferResource, lScreenshotId, lSurfaceId); + + ASSERT_EQ(get_surface_from_id_fake.call_count, 1); + ASSERT_EQ(wl_resource_destroy_fake.call_count, 1); + ASSERT_EQ(surface_get_size_fake.call_count, 1); + ASSERT_EQ(weston_buffer_from_resource_fake.call_count, 1); + ASSERT_EQ(wl_shm_buffer_get_data_fake.call_count, 1); + ASSERT_EQ(surface_dump_fake.call_count, 1); + ASSERT_EQ(wl_resource_post_event_fake.call_count, 1); + ASSERT_EQ(wl_resource_post_event_fake.arg1_val, IVI_SCREENSHOT_DONE); + free(westonBuffer); +} + +/** ================================================================================================ + * @test_id controller_screenshooter_done_WESTON_SCREENSHOOTER_SUCCESS_option + * @brief Test case of controller_screenshooter_done() when process WESTON_SCREENSHOOTER_SUCCESS option + * @test_procedure Steps: + * -# Call controller_screenshooter_done() with arg is WESTON_SCREENSHOOTER_SUCCESS option + * -# Verification point: + * +# wl_resource_post_event() must be called once time with opcode is IVI_SCREENSHOT_DONE + */ +TEST_F(ControllerTests, controller_screenshooter_done_WESTON_SCREENSHOOTER_SUCCESS_option) +{ + struct ivi_screenshooter *screenshooter = (struct ivi_screenshooter *)malloc(sizeof(struct ivi_screenshooter)); + screenshooter->output = &m_westonOutput[0]; + weston_screenshooter_outcome outcome = WESTON_SCREENSHOOTER_SUCCESS; + controller_screenshooter_done(screenshooter, outcome); + ASSERT_EQ(wl_resource_post_event_fake.call_count, 1); + ASSERT_EQ(wl_resource_post_event_fake.arg1_val, IVI_SCREENSHOT_DONE); + free(screenshooter); +} + +/** ================================================================================================ + * @test_id controller_screenshooter_done_WESTON_SCREENSHOOTER_NO_MEMORY_option + * @brief Test case of controller_screenshooter_done() when process WESTON_SCREENSHOOTER_NO_MEMORY option + * @test_procedure Steps: + * -# Call controller_screenshooter_done() with arg is WESTON_SCREENSHOOTER_NO_MEMORY option + * -# Verification point: + * +# wl_resource_post_event() must be called once time with opcode is IVI_SCREENSHOT_ERROR + */ +TEST_F(ControllerTests, controller_screenshooter_done_WESTON_SCREENSHOOTER_NO_MEMORY_option) +{ + struct ivi_screenshooter *screenshooter = (struct ivi_screenshooter *)malloc(sizeof(struct ivi_screenshooter)); + screenshooter->output = &m_westonOutput[0]; + weston_screenshooter_outcome outcome = WESTON_SCREENSHOOTER_NO_MEMORY; + controller_screenshooter_done(screenshooter, outcome); + ASSERT_EQ(wl_resource_post_event_fake.call_count, 1); + ASSERT_EQ(wl_resource_post_event_fake.arg1_val, IVI_SCREENSHOT_ERROR); + free(screenshooter); +} + +/** ================================================================================================ + * @test_id controller_screenshooter_done_WESTON_SCREENSHOOTER_BAD_BUFFER_option + * @brief Test case of controller_screenshooter_done() when process WESTON_SCREENSHOOTER_BAD_BUFFER option + * @test_procedure Steps: + * -# Call controller_screenshooter_done() with arg is WESTON_SCREENSHOOTER_BAD_BUFFER option + * -# Verification point: + * +# wl_resource_post_event() must be called once time with opcode is IVI_SCREENSHOT_ERROR + */ +TEST_F(ControllerTests, controller_screenshooter_done_WESTON_SCREENSHOOTER_BAD_BUFFER_option) +{ + struct ivi_screenshooter *screenshooter = (struct ivi_screenshooter *)malloc(sizeof(struct ivi_screenshooter)); + screenshooter->output = &m_westonOutput[0]; + weston_screenshooter_outcome outcome = WESTON_SCREENSHOOTER_BAD_BUFFER; + controller_screenshooter_done(screenshooter, outcome); + ASSERT_EQ(wl_resource_post_event_fake.call_count, 1); + ASSERT_EQ(wl_resource_post_event_fake.arg1_val, IVI_SCREENSHOT_ERROR); + free(screenshooter); +} + +/** ================================================================================================ + * @test_id controller_screenshooter_done_InvalidArg + * @brief Test case of controller_screenshooter_done() when process invalid option + * @test_procedure Steps: + * -# Call controller_screenshooter_done() with invalid option + * -# Verification point: + * +# wl_resource_post_event() should not be called + */ +TEST_F(ControllerTests, controller_screenshooter_done_InvalidArg) +{ + struct ivi_screenshooter *screenshooter = (struct ivi_screenshooter *)malloc(sizeof(struct ivi_screenshooter)); + screenshooter->output = &m_westonOutput[0]; + weston_screenshooter_outcome outcome = (weston_screenshooter_outcome)10; + controller_screenshooter_done(screenshooter, outcome); + ASSERT_EQ(wl_resource_post_event_fake.call_count, 0); + free(screenshooter); +} + +/** ================================================================================================ + * @test_id controller_screenshoot_destroy_call + * @brief Check behavior of controller_screenshoot_destroy() + * @test_procedure Steps: + * -# Mocking wl_resource_get_user_data() to return an success object + * -# Call controller_screenshoot_destroy() with invalid option + * -# Verification point: + * +# wl_resource_get_user_data() should be called 1 time + */ +TEST_F(ControllerTests, controller_screenshoot_destroy_call) +{ + struct wl_resource *lResource; + struct ivi_screenshooter * screenshooter = (struct ivi_screenshooter *)malloc(sizeof(struct ivi_screenshooter)); + screenshooter->output = &m_westonOutput[0]; + struct ivi_screenshooter * screenshooterRet[1] = {screenshooter}; + SET_RETURN_SEQ(wl_resource_get_user_data, (struct ivi_screenshooter **)screenshooterRet, 1); + controller_screenshoot_destroy(lResource); + ASSERT_EQ(wl_resource_get_user_data_fake.call_count, 1); +} + +/** ================================================================================================ + * @test_id controller_set_surface_type_wrongLayoutSurface + * @brief Test case of controller_set_surface_type() where get_surface_from_id() fails, return null pointer + * @test_procedure Steps: + * -# Mocking the wl_resource_get_user_data() does return an object + * -# Calling the controller_set_surface_type() + * -# Verification point: + * +# wl_resource_post_event() must be called once time + */ +TEST_F(ControllerTests, controller_set_surface_type_wrongLayoutSurface) +{ + SET_RETURN_SEQ(wl_resource_get_user_data, (void**)mp_iviController, 1); + + controller_set_surface_type(nullptr, nullptr, 1, 1); + + ASSERT_EQ(wl_resource_post_event_fake.call_count, 1); +} + +/** ================================================================================================ + * @test_id controller_set_surface_type_success + * @brief Test case of controller_set_surface_type() where get_surface_from_id() success, return an object + * @test_procedure Steps: + * -# Mocking the wl_resource_get_user_data() does return an object + * -# Mocking the get_surface_from_id() does return an object + * -# Calling the controller_set_surface_type() + * -# Verification point: + * +# wl_resource_post_event() not be called + */ +TEST_F(ControllerTests, controller_set_surface_type_success) +{ + SET_RETURN_SEQ(wl_resource_get_user_data, (void**)mp_iviController, 1); + struct ivi_layout_surface *l_layout_surface[1] = {&m_layoutSurface[0]}; + SET_RETURN_SEQ(get_surface_from_id, l_layout_surface, 1); + + controller_set_surface_type(nullptr, nullptr, 1, 1); + + ASSERT_EQ(wl_resource_post_event_fake.call_count, 0); +} + +/** ================================================================================================ + * @test_id controller_layer_clear_wrongLayoutLayer + * @brief Test case of controller_layer_clear() where get_layer_from_id() fails, return null pointer + * @test_procedure Steps: + * -# Mocking the wl_resource_get_user_data() does return an object + * -# Calling the controller_layer_clear() + * -# Verification point: + * +# wl_resource_post_event() must be called once time + */ +TEST_F(ControllerTests, controller_layer_clear_wrongLayoutLayer) +{ + SET_RETURN_SEQ(wl_resource_get_user_data, (void**)mp_iviController, 1); + + controller_layer_clear(nullptr, nullptr, 1); + + ASSERT_EQ(wl_resource_post_event_fake.call_count, 1); +} + +/** ================================================================================================ + * @test_id controller_layer_clear_success + * @brief Test case of controller_layer_clear() where get_layer_from_id() success, return an object + * @test_procedure Steps: + * -# Mocking the wl_resource_get_user_data() does return an object + * -# Mocking the get_layer_from_id() does return an object + * -# Calling the controller_layer_clear() + * -# Verification point: + * +# layer_set_render_order() must be called once time + */ +TEST_F(ControllerTests, controller_layer_clear_success) +{ + SET_RETURN_SEQ(wl_resource_get_user_data, (void**)mp_iviController, 1); + struct ivi_layout_layer *l_layoutLayer[1] = {(struct ivi_layout_layer *)0xFFFFFFFF}; + SET_RETURN_SEQ(get_layer_from_id, l_layoutLayer, 1); + + controller_layer_clear(nullptr, nullptr, 1); + + ASSERT_EQ(layer_set_render_order_fake.call_count, 1); +} + +/** ================================================================================================ + * @test_id controller_layer_add_surface_wrongLayoutLayer + * @brief Test case of controller_layer_add_surface() where get_layer_from_id() fails, return null pointer + * @test_procedure Steps: + * -# Mocking the wl_resource_get_user_data() does return an object + * -# Calling the controller_layer_add_surface() + * -# Verification point: + * +# wl_resource_post_event() must be called once time + */ +TEST_F(ControllerTests, controller_layer_add_surface_wrongLayoutLayer) +{ + SET_RETURN_SEQ(wl_resource_get_user_data, (void**)mp_iviController, 1); + + controller_layer_add_surface(nullptr, nullptr, 1, 1); + + ASSERT_EQ(wl_resource_post_event_fake.call_count, 1); +} + +/** ================================================================================================ + * @test_id controller_layer_add_surface_wrongLayoutSurface + * @brief Test case of controller_layer_add_surface() where get_layer_from_id() success, return an object + * but get_surface_from_id() fails, return null pointer + * @test_procedure Steps: + * -# Mocking the wl_resource_get_user_data() does return an object + * -# Mocking the get_layer_from_id() does return an object + * -# Calling the controller_layer_add_surface() + * -# Verification point: + * +# wl_resource_post_event() must be called once time + */ +TEST_F(ControllerTests, controller_layer_add_surface_wrongLayoutSurface) +{ + SET_RETURN_SEQ(wl_resource_get_user_data, (void**)mp_iviController, 1); + struct ivi_layout_layer *l_layoutLayer[1] = {(struct ivi_layout_layer *)0xFFFFFFFF}; + SET_RETURN_SEQ(get_layer_from_id, l_layoutLayer, 1); + + controller_layer_add_surface(nullptr, nullptr, 1, 1); + + ASSERT_EQ(wl_resource_post_event_fake.call_count, 1); +} + +/** ================================================================================================ + * @test_id controller_layer_add_surface_success + * @brief Test case of controller_layer_add_surface() where get_layer_from_id() success, return an object + * and get_surface_from_id() success, return an object + * @test_procedure Steps: + * -# Mocking the wl_resource_get_user_data() does return an object + * -# Mocking the get_layer_from_id() does return an object + * -# Mocking the get_surface_from_id() does return an object + * -# Calling the controller_layer_add_surface() + * -# Verification point: + * +# layer_add_surface() must be called once time + */ +TEST_F(ControllerTests, controller_layer_add_surface_success) +{ + SET_RETURN_SEQ(wl_resource_get_user_data, (void**)mp_iviController, 1); + struct ivi_layout_layer *l_layoutLayer[1] = {(struct ivi_layout_layer *)0xFFFFFFFF}; + SET_RETURN_SEQ(get_layer_from_id, l_layoutLayer, 1); + struct ivi_layout_surface *l_layout_surface[1] = {(struct ivi_layout_surface *)0xFFFFFFFF}; + SET_RETURN_SEQ(get_surface_from_id, l_layout_surface, 1); + + controller_layer_add_surface(nullptr, nullptr, 1, 1); + + ASSERT_EQ(layer_add_surface_fake.call_count, 1); +} + +/** ================================================================================================ + * @test_id controller_layer_remove_surface_wrongLayoutLayer + * @brief Test case of controller_layer_remove_surface() where get_layer_from_id() fails, return null pointer + * @test_procedure Steps: + * -# Mocking the wl_resource_get_user_data() does return an object + * -# Calling the controller_layer_remove_surface() + * -# Verification point: + * +# wl_resource_post_event() must be called once time + */ +TEST_F(ControllerTests, controller_layer_remove_surface_wrongLayoutLayer) +{ + SET_RETURN_SEQ(wl_resource_get_user_data, (void**)mp_iviController, 1); + + controller_layer_remove_surface(nullptr, nullptr, 1, 1); + + ASSERT_EQ(wl_resource_post_event_fake.call_count, 1); +} + +/** ================================================================================================ + * @test_id controller_layer_remove_surface_wrongLayoutSurface + * @brief Test case of controller_layer_remove_surface() where get_layer_from_id() success, return an object + * and get_surface_from_id() fails, return null pointer + * @test_procedure Steps: + * -# Mocking the wl_resource_get_user_data() does return an object + * -# Mocking the get_layer_from_id() does return an object + * -# Calling the controller_layer_remove_surface() + * -# Verification point: + * +# wl_resource_post_event() must be called once time + */ +TEST_F(ControllerTests, controller_layer_remove_surface_wrongLayoutSurface) +{ + SET_RETURN_SEQ(wl_resource_get_user_data, (void**)mp_iviController, 1); + struct ivi_layout_layer *l_layoutLayer[1] = {(struct ivi_layout_layer *)0xFFFFFFFF}; + SET_RETURN_SEQ(get_layer_from_id, l_layoutLayer, 1); + + controller_layer_remove_surface(nullptr, nullptr, 1, 1); + + ASSERT_EQ(wl_resource_post_event_fake.call_count, 1); +} + +/** ================================================================================================ + * @test_id controller_layer_remove_surface_success + * @brief Test case of controller_layer_remove_surface() where get_layer_from_id() success, return an object + * and get_surface_from_id() success, return an object + * @test_procedure Steps: + * -# Mocking the wl_resource_get_user_data() does return an object + * -# Mocking the get_layer_from_id() does return an object + * -# Mocking the get_surface_from_id() does return an object + * -# Calling the controller_layer_remove_surface() + * -# Verification point: + * +# layer_remove_surface() must be called once time + */ +TEST_F(ControllerTests, controller_layer_remove_surface_success) +{ + SET_RETURN_SEQ(wl_resource_get_user_data, (void**)mp_iviController, 1); + struct ivi_layout_layer *l_layoutLayer[1] = {(struct ivi_layout_layer *)0xFFFFFFFF}; + SET_RETURN_SEQ(get_layer_from_id, l_layoutLayer, 1); + struct ivi_layout_surface *l_layout_surface[1] = {(struct ivi_layout_surface *)0xFFFFFFFF}; + SET_RETURN_SEQ(get_surface_from_id, l_layout_surface, 1); + + controller_layer_remove_surface(nullptr, nullptr, 1, 1); + + ASSERT_EQ(layer_remove_surface_fake.call_count, 1); +} + +/** ================================================================================================ + * @test_id controller_create_layout_layer_error + * @brief Test case of controller_create_layout_layer() where layer_create_with_dimension() fails, return null pointer + * @test_procedure Steps: + * -# Mocking the wl_resource_get_user_data() does return an object + * -# Calling the controller_create_layout_layer() + * -# Verification point: + * +# wl_resource_post_no_memory() must be called once time + */ +TEST_F(ControllerTests, controller_create_layout_layer_error) +{ + SET_RETURN_SEQ(wl_resource_get_user_data, (void**)mp_iviController, 1); + + controller_create_layout_layer(nullptr, nullptr, 1, 1, 1); + + ASSERT_EQ(wl_resource_post_no_memory_fake.call_count, 1); +} + +/** ================================================================================================ + * @test_id controller_create_layout_layer_success + * @brief Test case of controller_create_layout_layer() where layer_create_with_dimension() success, return an object + * @test_procedure Steps: + * -# Mocking the wl_resource_get_user_data() does return an object + * -# Mocking the layer_create_with_dimension() does return an object + * -# Calling the controller_create_layout_layer() + * -# Verification point: + * +# wl_resource_post_no_memory() not be called + */ +TEST_F(ControllerTests, controller_create_layout_layer_success) +{ + SET_RETURN_SEQ(wl_resource_get_user_data, (void**)mp_iviController, 1); + struct ivi_layout_layer *l_layoutLayer[1] = {(struct ivi_layout_layer *)0xFFFFFFFF}; + SET_RETURN_SEQ(layer_create_with_dimension, l_layoutLayer, 1); + + controller_create_layout_layer(nullptr, nullptr, 1, 1, 1); + + ASSERT_EQ(wl_resource_post_no_memory_fake.call_count, 0); +} + +/** ================================================================================================ + * @test_id controller_destroy_layout_layer_error + * @brief Test case of controller_destroy_layout_layer() where get_layer_from_id() fails, return null pointer + * @test_procedure Steps: + * -# Mocking the wl_resource_get_user_data() does return an object + * -# Calling the controller_destroy_layout_layer() + * -# Verification point: + * +# wl_resource_post_event() must be called once time + */ +TEST_F(ControllerTests, controller_destroy_layout_layer_error) +{ + SET_RETURN_SEQ(wl_resource_get_user_data, (void**)mp_iviController, 1); + + controller_destroy_layout_layer(nullptr, nullptr, 1); + + ASSERT_EQ(wl_resource_post_event_fake.call_count, 1); +} + +/** ================================================================================================ + * @test_id controller_destroy_layout_layer_success + * @brief Test case of controller_destroy_layout_layer() where get_layer_from_id() success, return an object + * @test_procedure Steps: + * -# Mocking the wl_resource_get_user_data() does return an object + * -# Mocking the get_layer_from_id() does return an object + * -# Calling the controller_destroy_layout_layer() + * -# Verification point: + * +# layer_destroy() must be called once time + */ +TEST_F(ControllerTests, controller_destroy_layout_layer_success) +{ + SET_RETURN_SEQ(wl_resource_get_user_data, (void**)mp_iviController, 1); + struct ivi_layout_layer *l_layoutLayer[1] = {(struct ivi_layout_layer *)0xFFFFFFFF}; + SET_RETURN_SEQ(get_layer_from_id, l_layoutLayer, 1); + + controller_destroy_layout_layer(nullptr, nullptr, 1); + + ASSERT_EQ(layer_destroy_fake.call_count, 1); +} + +/** ================================================================================================ + * @test_id destroy_ivicontroller_screen_success + * @brief Test case of destroy_ivicontroller_screen() where valid input param + * @test_procedure Steps: + * -# Calling the destroy_ivicontroller_screen() + * -# Verification point: + * +# wl_list_remove() must be called once time + */ +TEST_F(ControllerTests, destroy_ivicontroller_screen_success) +{ + destroy_ivicontroller_screen(nullptr); + ASSERT_EQ(wl_list_remove_fake.call_count, 1); +} + +/** ================================================================================================ + * @test_id output_destroyed_event_invalidOutput + * @brief Test case of output_destroyed_event() where invalid ivi shell + * @test_procedure Steps: + * -# Calling the output_destroyed_event() + * -# Verification point: + * +# weston_compositor_schedule_repaint() must be called once time + * +# wl_list_remove() not be called + */ +TEST_F(ControllerTests, output_destroyed_event_invalidOutput) +{ + output_destroyed_event(&mp_iviShell->output_destroyed, nullptr); + + ASSERT_EQ(weston_compositor_schedule_repaint_fake.call_count, 1); + ASSERT_EQ(wl_list_remove_fake.call_count, 0); +} + +/** ================================================================================================ + * @test_id output_destroyed_event_success + * @brief Test case of output_destroyed_event() where valid ivi shell + * @test_procedure Steps: + * -# Set data input for ivi shell + * -# Calling the output_destroyed_event() + * -# Verification point: + * +# wl_list_remove() must be called 2 times + * +# wl_list_insert() must be called once time + * +# Free resources are allocated when running the test + * +# Allocate memory for resources are freed when running the test + */ +TEST_F(ControllerTests, output_destroyed_event_success) +{ + wl_resource_from_link_fake.custom_fake = custom_wl_resource_from_link; + wl_resource_get_link_fake.custom_fake = custom_wl_resource_get_link; + mp_iviShell->bkgnd_view = (struct weston_view*)malloc(sizeof(struct weston_view)); + mp_iviShell->bkgnd_view->surface = (struct weston_surface*)malloc(sizeof(struct weston_surface)); + mp_iviShell->bkgnd_view->surface->width = 1; + mp_iviShell->bkgnd_view->surface->height = 1; + mp_iviShell->bkgnd_view->surface->compositor = (struct weston_compositor*)malloc(sizeof(weston_compositor)); + custom_wl_list_init(&mp_iviShell->compositor->output_list); + struct weston_output *l_output = (struct weston_output *)malloc(sizeof(struct weston_output)); + l_output->name = (char*)"default"; + l_output->id = 1; + l_output->x = 1; + l_output->y = 1; + l_output->width = 1; + l_output->height = 1; + custom_wl_list_insert(&mp_iviShell->compositor->output_list, &l_output->link); + custom_wl_list_init(&mp_iviShell->bkgnd_view->surface->compositor->output_list); + struct weston_output *l_output2 = (struct weston_output *)malloc(sizeof(struct weston_output)); + l_output2->name = (char*)"default"; + l_output2->id = 1; + l_output2->x = 1; + l_output2->y = 1; + l_output2->width = 1; + l_output2->height = 1; + custom_wl_list_insert(&mp_iviShell->bkgnd_view->surface->compositor->output_list, &l_output2->link); + mp_iviShell->client = (struct wl_client*)&mp_fakeClient; + + output_destroyed_event(&mp_iviShell->output_destroyed, mp_iviScreen[0]->output); + + ASSERT_EQ(wl_list_remove_fake.call_count, 2); + ASSERT_EQ(wl_list_insert_fake.call_count, 1); + + free(l_output); + free(l_output2); + free(mp_iviShell->bkgnd_view->surface->compositor); + free(mp_iviShell->bkgnd_view->surface); + free(mp_iviShell->bkgnd_view); + + mp_iviScreen[0] = (struct iviscreen*)malloc(sizeof(struct iviscreen)); +} + +/** ================================================================================================ + * @test_id output_resized_event_nullBkgndView + * @brief Test case of output_resized_event() where ivi shell bkgnd_view is null pointer + * @test_procedure Steps: + * -# Set data for ivi shell with bkgnd_view is null pointer + * -# Calling the output_resized_event() + * -# Verification point: + * +# wl_list_remove() not be called + */ +TEST_F(ControllerTests, output_resized_event_nullBkgndView) +{ + mp_iviShell->bkgnd_view = nullptr; + mp_iviShell->client = (struct wl_client*)&mp_fakeClient; + + output_resized_event(&mp_iviShell->output_resized, nullptr); + + ASSERT_EQ(wl_list_remove_fake.call_count, 0); +} + +/** ================================================================================================ + * @test_id output_resized_event_nullClient + * @brief Test case of output_resized_event() where ivi shell client is null pointer + * @test_procedure Steps: + * -# Set data for ivi shell with client is null pointer + * -# Calling the output_resized_event() + * -# Verification point: + * +# wl_list_remove() not be called + * +# Free resources are allocated when running the test + */ +TEST_F(ControllerTests, output_resized_event_nullClient) +{ + mp_iviShell->bkgnd_view = (struct weston_view*)malloc(sizeof(struct weston_view)); + mp_iviShell->client = nullptr; + + output_resized_event(&mp_iviShell->output_resized, nullptr); + + ASSERT_EQ(wl_list_remove_fake.call_count, 0); + + free(mp_iviShell->bkgnd_view); +} + +/** ================================================================================================ + * @test_id output_resized_event_success + * @brief Test case of output_resized_event() where valid ivi shell bkgnd_view and client + * @test_procedure Steps: + * -# Set data for ivi shell with valid bkgnd_view and client + * -# Calling the output_resized_event() + * -# Verification point: + * +# wl_list_remove() must be called once time + * +# wl_list_insert() must be called once time + * +# Free resources are allocated when running the test + */ +TEST_F(ControllerTests, output_resized_event_success) +{ + mp_iviShell->bkgnd_view = (struct weston_view*)malloc(sizeof(struct weston_view)); + mp_iviShell->bkgnd_view->surface = (struct weston_surface*)malloc(sizeof(struct weston_surface)); + mp_iviShell->bkgnd_view->surface->width = 1; + mp_iviShell->bkgnd_view->surface->height = 1; + mp_iviShell->bkgnd_view->surface->compositor = (struct weston_compositor*)malloc(sizeof(weston_compositor)); + custom_wl_list_init(&mp_iviShell->bkgnd_view->surface->compositor->output_list); + struct weston_output *l_output = (struct weston_output *)malloc(sizeof(struct weston_output)); + l_output->name = (char*)"default"; + l_output->id = 1; + l_output->x = 1; + l_output->y = 1; + l_output->width = 1; + l_output->height = 1; + custom_wl_list_insert(&mp_iviShell->compositor->output_list, &l_output->link); + mp_iviShell->client = (struct wl_client*)&mp_fakeClient; + + output_resized_event(&mp_iviShell->output_resized, nullptr); + + ASSERT_EQ(wl_list_remove_fake.call_count, 1); + ASSERT_EQ(wl_list_insert_fake.call_count, 1); + + free(l_output); + free(mp_iviShell->bkgnd_view->surface->compositor); + free(mp_iviShell->bkgnd_view->surface); + free(mp_iviShell->bkgnd_view); +} + +/** ================================================================================================ + * @test_id surface_committed_success + * @brief Test case of surface_committed() where valid input params + * @test_procedure Steps: + * -# Set ivi surface frame_count to 0 + * -# Calling the surface_committed() + * -# Verification point: + * +# frame_count must be increased by 1 + */ +TEST_F(ControllerTests, surface_committed_success) +{ + mp_iviSurface[0]->frame_count = 0; + surface_committed(&mp_iviSurface[0]->committed, nullptr); + + ASSERT_EQ(mp_iviSurface[0]->frame_count, 1); +} + +/** ================================================================================================ + * @test_id layer_event_remove_wrongIviLayer + * @brief Test case of layer_event_remove() where input ivi layout layer is null pointer + * @test_procedure Steps: + * -# Calling the layer_event_remove() + * -# Verification point: + * +# wl_list_remove() not be called + */ +TEST_F(ControllerTests, layer_event_remove_wrongIviLayer) +{ + layer_event_remove(&mp_iviShell->layer_removed, nullptr); + ASSERT_EQ(wl_list_remove_fake.call_count, 0); +} + +/** ================================================================================================ + * @test_id layer_event_remove_success + * @brief Test case of layer_event_remove() where valid input ivi layout layer + * @test_procedure Steps: + * -# Calling the layer_event_remove() + * -# Verification point: + * +# wl_list_remove() must be called 4 times + * +# Allocate memory for resources are freed when running the test + */ +TEST_F(ControllerTests, layer_event_remove_success) +{ + layer_event_remove(&mp_iviShell->layer_removed, m_layoutLayer); + + ASSERT_EQ(wl_list_remove_fake.call_count, 4); + + mp_LayerNotification[0] = (struct notification *)malloc(sizeof(struct notification)); + mp_iviLayer[0] = (struct ivilayer *)malloc(sizeof(struct ivilayer)); +} + +/** ================================================================================================ + * @test_id surface_event_remove_wrongIdSurface + * @brief Test case of surface_event_remove() where valid input ivi layout surfacey + * but ivi shell bkgnd_surface_id is null pointer + * @test_procedure Steps: + * -# Calling the surface_event_remove() + * -# Verification point: + * +# wl_list_remove() must be called 5 times + * +# Allocate memory for resources are freed when running the test + */ +TEST_F(ControllerTests, surface_event_remove_wrongIdSurface) +{ + surface_event_remove(&mp_iviShell->surface_removed, m_layoutSurface); + + ASSERT_EQ(wl_list_remove_fake.call_count, 5); + + mp_surfaceNotification[0] = (struct notification *)malloc(sizeof(struct notification)); + mp_iviSurface[0] = (struct ivisurface*)malloc(sizeof(struct ivisurface)); +} + +/** ================================================================================================ + * @test_id surface_event_remove_success + * @brief Test case of surface_event_remove() where valid input ivi layout surfacey + * and valid ivi shell bkgnd_surface_id + * @test_procedure Steps: + * -# Set data for ivi shell with valid bkgnd_surface_id + * -# Calling the surface_event_remove() + * -# Verification point: + * +# wl_list_remove() must be called 5 times + * +# weston_layer_entry_remove() not be called + * +# weston_view_destroy() not be called + * +# Free resources are allocated when running the test + * +# Allocate memory for resources are freed when running the test + */ +TEST_F(ControllerTests, surface_event_remove_success) +{ + mp_iviShell->bkgnd_surface_id = 10; + mp_iviShell->bkgnd_surface = mp_iviSurface[0]; + mp_iviShell->bkgnd_view = (struct weston_view*)malloc(sizeof(struct weston_view)); + + surface_event_remove(&mp_iviShell->surface_removed, m_layoutSurface); + + ASSERT_EQ(wl_list_remove_fake.call_count, 5); + ASSERT_EQ(weston_layer_entry_remove_fake.call_count, 0); + ASSERT_EQ(weston_view_destroy_fake.call_count, 0); + + free(mp_iviShell->bkgnd_view); + + mp_surfaceNotification[0] = (struct notification*)malloc(sizeof(struct notification)); + mp_iviSurface[0] = (struct ivisurface*)malloc(sizeof(struct ivisurface)); +} + +/** ================================================================================================ + * @test_id surface_event_configure_wrongSurfaceId + * @brief Test case of surface_event_configure() where invalid ivi shell bkgnd_surface_id + * @test_procedure Steps: + * -# Mocking the wl_resource_get_user_data() does return an object + * -# Calling the surface_event_configure() + * -# Verification point: + * +# wl_resource_get_user_data() must be called once time + */ +TEST_F(ControllerTests, surface_event_configure_wrongSurfaceId) +{ + m_layoutSurface[0].surface = (struct weston_surface*)malloc(sizeof(struct weston_surface)); + m_layoutSurface[0].surface->width = 1; + m_layoutSurface[0].surface->height = 1; + struct weston_surface* tmp[1] = {m_layoutSurface[0].surface}; + SET_RETURN_SEQ(surface_get_weston_surface, (struct weston_surface**)(tmp), 1); + SET_RETURN_SEQ(wl_resource_get_user_data, (void**)mp_iviController, 1); + + mp_iviShell->bkgnd_surface_id = 0; + surface_event_configure(&mp_iviShell->surface_configured, &m_layoutSurface[0]); + ASSERT_EQ(wl_resource_get_user_data_fake.call_count, 1); + free(m_layoutSurface[0].surface); +} + +/** ================================================================================================ + * @test_id surface_event_configure_validBkgndView + * @brief Test case of surface_event_configure() where valid ivi shell bkgnd_surface_id + * and valid bkgnd_view + * @test_procedure Steps: + * -# Set data for ivi shell + * -# Mocking the wl_resource_get_user_data() does return an object + * -# Calling the surface_event_configure() + * -# Verification point: + * +# wl_resource_get_user_data() not be called + * +# wl_list_remove() must be called once time + * +# Free resources are allocated when running the test + */ +TEST_F(ControllerTests, surface_event_configure_validBkgndView) +{ + mp_iviShell->bkgnd_surface_id = 10; + mp_iviShell->bkgnd_view = (struct weston_view*)malloc(sizeof(struct weston_view)); + mp_iviShell->bkgnd_view->surface = (struct weston_surface*)malloc(sizeof(struct weston_surface)); + mp_iviShell->bkgnd_view->surface->width = 1; + mp_iviShell->bkgnd_view->surface->height = 1; + mp_iviShell->bkgnd_view->surface->compositor = (struct weston_compositor*)malloc(sizeof(weston_compositor)); + custom_wl_list_init(&mp_iviShell->bkgnd_view->surface->compositor->output_list); + uint32_t tmp[1] = {m_layoutSurface[0].id_surface}; + SET_RETURN_SEQ(get_id_of_surface, (uint32_t *)tmp, 1); + SET_RETURN_SEQ(wl_resource_get_user_data, (void**)mp_iviController, 1); + + surface_event_configure(&mp_iviShell->surface_configured, m_layoutSurface); + + ASSERT_EQ(wl_resource_get_user_data_fake.call_count, 0); + ASSERT_EQ(wl_list_remove_fake.call_count, 1); + ASSERT_EQ(surface_get_weston_surface_fake.call_count, 1); + ASSERT_EQ(get_id_of_surface_fake.call_count, 1); + ASSERT_EQ(weston_matrix_init_fake.call_count, 1); + + free(mp_iviShell->bkgnd_view->surface->compositor); + free(mp_iviShell->bkgnd_view->surface); + free(mp_iviShell->bkgnd_view); +} + +/** ================================================================================================ + * @test_id surface_event_configure_nullBkgndView + * @brief Test case of surface_event_configure() where valid ivi shell bkgnd_surface_id + * and invalid bkgnd_view + * @test_procedure Steps: + * -# Set data for ivi shell with bkgnd_view is null pointer + * -# Mocking the weston_view_create() does return an object + * -# Calling the surface_event_configure() + * -# Verification point: + * +# wl_resource_get_user_data() not be called + * +# wl_list_remove() must be called once time + * +# weston_view_create() must be called once time + * +# Free resources are allocated when running the test + */ +TEST_F(ControllerTests, surface_event_configure_nullBkgndView) +{ + mp_iviShell->bkgnd_surface_id = 10; + mp_iviShell->bkgnd_view = nullptr; + struct weston_view *l_bkgnd_view[1]; + l_bkgnd_view[0] = (struct weston_view*)malloc(sizeof(struct weston_view)); + l_bkgnd_view[0]->surface = (struct weston_surface*)malloc(sizeof(struct weston_surface)); + l_bkgnd_view[0]->surface->width = 1; + l_bkgnd_view[0]->surface->height = 1; + l_bkgnd_view[0]->surface->compositor = (struct weston_compositor*)malloc(sizeof(weston_compositor)); + custom_wl_list_init(&l_bkgnd_view[0]->surface->compositor->output_list); + + uint32_t tmp[1] = {m_layoutSurface[0].id_surface}; + SET_RETURN_SEQ(get_id_of_surface, (uint32_t *)tmp, 1); + SET_RETURN_SEQ(weston_view_create, l_bkgnd_view, 1); + + surface_event_configure(&mp_iviShell->surface_configured, m_layoutSurface); + + ASSERT_EQ(wl_resource_get_user_data_fake.call_count, 0); + ASSERT_EQ(wl_list_remove_fake.call_count, 1); + ASSERT_EQ(wl_list_init_fake.call_count, 1); + ASSERT_EQ(weston_view_create_fake.call_count, 1); + ASSERT_EQ(weston_layer_entry_insert_fake.call_count, 1); + ASSERT_EQ(weston_surface_map_fake.call_count, 1); + + free(l_bkgnd_view[0]->surface->compositor); + free(l_bkgnd_view[0]->surface); + free(l_bkgnd_view[0]); +} + +/** ================================================================================================ + * @test_id ivi_shell_destroy_nullClient + * @brief Test case of ivi_shell_destroy() where ivi shell client is null pointer + * @test_procedure Steps: + * -# Set data for ivi shell with client is null pointer + * -# Calling the ivi_shell_destroy() + * -# Verification point: + * +# wl_list_remove() must be called 16 times + * +# Allocate memory for resources are freed when running the test + * +# Free resources are allocated when running the test + */ +TEST_F(ControllerTests, ivi_shell_destroy_nullClient) +{ + wl_resource_from_link_fake.custom_fake = custom_wl_resource_from_link; + wl_resource_get_link_fake.custom_fake = custom_wl_resource_get_link; + mp_iviShell->client = nullptr; + mp_screenInfo->screen_name = (char *)malloc(30); + + ivi_shell_destroy(&mp_iviShell->destroy_listener, nullptr); + + ASSERT_EQ(wl_list_remove_fake.call_count, 16); + ASSERT_EQ(wl_client_destroy_fake.call_count, 0); + + for(uint8_t i = 0; i < MAX_NUMBER; i++) + { + mp_iviSurface[i] = (struct ivisurface*)malloc(sizeof(struct ivisurface)); + mp_iviLayer[i] = (struct ivilayer *)malloc(sizeof(struct ivilayer)); + mp_iviScreen[i] = (struct iviscreen*)malloc(sizeof(struct iviscreen)); + } + mp_iviShell = (struct ivishell *)malloc(sizeof(struct ivishell)); + custom_wl_array_init(&mp_iviShell->screen_ids); + + free(mp_screenInfo); +} + +/** ================================================================================================ + * @test_id ivi_shell_destroy_success + * @brief Test case of ivi_shell_destroy() where ivi shell client and screen name are valid values + * @test_procedure Steps: + * -# Set data for ivi shell with client is valid value + * -# Calling the ivi_shell_destroy() + * -# Verification point: + * +# wl_list_remove() must be called 17 times + * +# Allocate memory for resources are freed when running the test + * +# Free resources are allocated when running the test + */ +TEST_F(ControllerTests, ivi_shell_destroy_success) +{ + mp_iviShell->client = (struct wl_client *)0xFFFFFFFF; + mp_screenInfo->screen_name = (char *)malloc(30); + + ivi_shell_destroy(&mp_iviShell->destroy_listener, nullptr); + + ASSERT_EQ(wl_list_remove_fake.call_count, 17); + + for(uint8_t i = 0; i < MAX_NUMBER; i++) + { + mp_iviSurface[i] = (struct ivisurface*)malloc(sizeof(struct ivisurface)); + mp_iviLayer[i] = (struct ivilayer *)malloc(sizeof(struct ivilayer)); + mp_iviScreen[i] = (struct iviscreen*)malloc(sizeof(struct iviscreen)); + } + mp_iviShell = (struct ivishell *)malloc(sizeof(struct ivishell)); + custom_wl_array_init(&mp_iviShell->screen_ids); + + free(mp_screenInfo); +} + +/** ================================================================================================ + * @test_id launch_client_process_success + * @brief Test case of launch_client_process() where valid input params + * @test_procedure Steps: + * -# Calling the launch_client_process() + * -# Verification point: + * +# weston_client_start() must be called once time + * +# wl_client_add_destroy_listener() must be called once time + */ +TEST_F(ControllerTests, launch_client_process_success) +{ + launch_client_process(&mp_iviShell); + + ASSERT_EQ(weston_client_start_fake.call_count, 1); + ASSERT_EQ(wl_client_add_destroy_listener_fake.call_count, 1); +} + +/** ================================================================================================ + * @test_id unbind_resource_controller_success + * @brief Test case of unbind_resource_controller() where wl_resource_get_user_data() success, return an object + * @test_procedure Steps: + * -# Set data for layer_notifications and surface_notifications + * -# Mocking the wl_resource_get_user_data() does return an object + * -# Calling the unbind_resource_controller() + * -# Verification point: + * +# wl_list_remove() must be called 3 times + * +# Allocate memory for resources are freed when running the test + */ +TEST_F(ControllerTests, unbind_resource_controller_success) +{ + struct notification *l_not = (struct notification *)malloc(sizeof(struct notification)); + custom_wl_list_init(&mp_iviController[0]->layer_notifications); + custom_wl_list_insert(&mp_iviController[0]->layer_notifications, &l_not->link); + custom_wl_list_init(&mp_iviController[0]->surface_notifications); + + SET_RETURN_SEQ(wl_resource_get_user_data, (void**)mp_iviController, 1); + + unbind_resource_controller(nullptr); + + ASSERT_EQ(wl_list_remove_fake.call_count, 3); + + mp_iviController[0] = (struct ivicontroller*)malloc(sizeof(struct ivicontroller)); +} diff --git a/unittest/server/src/ivi_id_agent_unittests.cpp b/unittest/server/src/ivi_id_agent_unittests.cpp new file mode 100644 index 00000000..6a89bd3e --- /dev/null +++ b/unittest/server/src/ivi_id_agent_unittests.cpp @@ -0,0 +1,578 @@ +/*************************************************************************** + * + * Copyright (C) 2023 Advanced Driver Information Technology Joint Venture GmbH + * + * + * 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. + * + ****************************************************************************/ + +#include +#include +#include "server_api_fake.h" +#include "ivi_layout_interface_fake.h" + +extern "C" +{ +#include "ivi-id-agent.c" +} + +#define INVALID_ID 0xFFFFFFFF +static constexpr uint8_t MAX_NUMBER = 2; + +class IdAgentTest: public ::testing::Test +{ +public: + void SetUp() + { + // ASSERT_EQ(initBaseModule(), true); + IVI_LAYOUT_FAKE_LIST(RESET_FAKE); + SERVER_API_FAKE_LIST(RESET_FAKE); + init_controller_content(); + } + + void TearDown() + { + deinit_controller_content(); + } + + void init_controller_content() + { + m_iviShell.interface = &g_iviLayoutInterfaceFake; + m_iviShell.compositor = &m_westonCompositor; + custom_wl_list_init(&m_westonCompositor.seat_list); + custom_wl_list_init(&m_iviShell.list_surface); + custom_wl_list_init(&m_westonCompositor.seat_list); + wl_signal_init(&m_iviShell.id_allocation_request_signal); + wl_signal_init(&m_iviShell.ivisurface_created_signal); + wl_signal_init(&m_iviShell.ivisurface_removed_signal); + mp_iviIdAgent = (struct ivi_id_agent*)malloc(sizeof(struct ivi_id_agent)); + mp_iviIdAgent->compositor = &m_westonCompositor; + mp_iviIdAgent->interface = &g_iviLayoutInterfaceFake; + mp_iviIdAgent->default_surface_id = 100; + mp_iviIdAgent->default_surface_id_max = 200; + mp_iviIdAgent->default_behavior_set = 0; + + custom_wl_list_init(&mp_iviIdAgent->app_list); + custom_wl_list_init(&mp_iviIdAgent->id_allocation_listener.link); + custom_wl_list_init(&mp_iviIdAgent->surface_removed.link); + custom_wl_list_init(&mp_iviIdAgent->destroy_listener.link); + custom_wl_list_init(&m_westonCompositor.destroy_signal.listener_list); + + for(uint8_t i = 0; i < MAX_NUMBER; i++) + { + // prepare for desktop apps + mp_dbElem[i] = (struct db_elem*)malloc(sizeof(struct db_elem)); + mp_dbElem[i]->surface_id = 10 + i; + mp_dbElem[i]->cfg_app_id = (char*)malloc(5); + mp_dbElem[i]->cfg_title = (char*)malloc(10); + snprintf(mp_dbElem[i]->cfg_app_id, 5, "%d", i); + snprintf(mp_dbElem[i]->cfg_title, 10, "idtest%d", i); + custom_wl_list_insert(&mp_iviIdAgent->app_list, &mp_dbElem[i]->link); + } + } + + void deinit_controller_content() + { + for(uint8_t i = 0; i < MAX_NUMBER; i++) + { + if(mp_dbElem[i] != nullptr) + { + free(mp_dbElem[i]->cfg_app_id); + free(mp_dbElem[i]->cfg_title); + free(mp_dbElem[i]); + } + } + if(mp_iviIdAgent != nullptr) + { + free(mp_iviIdAgent); + } + } + + struct ivishell m_iviShell = {}; + struct ivi_id_agent *mp_iviIdAgent = nullptr; + struct weston_compositor m_westonCompositor = {}; + + struct db_elem *mp_dbElem[MAX_NUMBER] = {nullptr}; + void *mp_fakePointer = (void*)0xFFFFFFFF; + void *mp_nullPointer = nullptr; + + static uint32_t ms_surfaceId; + static uint32_t ms_defaultSurfaceId; + static uint32_t ms_defaultSurfaceIdMax; + static char *ms_appId; + static char *ms_appTitle; +}; + +char *IdAgentTest::ms_appId = (char*)"0"; +char *IdAgentTest::ms_appTitle = (char*)"app_1"; +uint32_t IdAgentTest::ms_surfaceId = 10; +uint32_t IdAgentTest::ms_defaultSurfaceId = 100; +uint32_t IdAgentTest::ms_defaultSurfaceIdMax = 200; + +static int custom_weston_config_next_section_1(struct weston_config *config, struct weston_config_section **section, const char **name) +{ + *name = "desktop-app"; + return 1; +} + +static int custom_weston_config_next_section_2(struct weston_config *config, struct weston_config_section **section, const char **name) +{ + return 0; +} + +static int custom_weston_config_section_get_uint(struct weston_config_section *section, const char *key, uint32_t *value, uint32_t default_value) +{ + if(strcmp(key, "surface-id") == 0) + { + *value = IdAgentTest::ms_surfaceId; + } + else if(strcmp(key, "default-surface-id") == 0) + { + *value = IdAgentTest::ms_defaultSurfaceId; + } + else if(strcmp(key, "default-surface-id-max") == 0) + { + *value = IdAgentTest::ms_defaultSurfaceIdMax; + } + return 0; +} + +static int custom_weston_config_section_get_string(struct weston_config_section *section, const char *key, char **value, const char *default_value) +{ + if(strcmp(key, "app-id") == 0) + { + *value = (IdAgentTest::ms_appId != nullptr) ? strdup(IdAgentTest::ms_appId) : nullptr; + } + else if(strcmp(key, "app-title") == 0) + { + *value = (IdAgentTest::ms_appTitle != nullptr) ? strdup(IdAgentTest::ms_appId) : nullptr; + } + return 0; +} + +/** ================================================================================================ + * @test_id surface_event_remove + * @brief Test case of surface_event_remove() where valid input params + * @test_procedure Steps: + * -# Set the layout surface for db elem, to check function + * -# Calling the surface_event_remove() + * -# Verification point: + * +# If the db elem have the layout surface is mp_fakePointer, it should reset to null pointer + * +# If not, keep the right pointer + */ +TEST_F(IdAgentTest, surface_event_remove) +{ + mp_dbElem[0]->layout_surface = (struct ivi_layout_surface *)mp_fakePointer; + mp_dbElem[1]->layout_surface = (struct ivi_layout_surface *)0xFFFFFF00; + + surface_event_remove(&mp_iviIdAgent->surface_removed, mp_fakePointer); + + ASSERT_EQ(mp_dbElem[0]->layout_surface, nullptr); + ASSERT_EQ(mp_dbElem[1]->layout_surface, (struct ivi_layout_surface *)0xFFFFFF00); +} + +/** ================================================================================================ + * @test_id id_agent_module_deinit + * @brief Test case of id_agent_module_deinit() where valid input params + * @test_procedure Steps: + * -# Calling the id_agent_module_deinit() + * -# Verification point: + * +# wl_list_remove() must be called 5 times + * +# Free resources are allocated when running the test + */ +TEST_F(IdAgentTest, id_agent_module_deinit) +{ + id_agent_module_deinit(&mp_iviIdAgent->destroy_listener, nullptr); + + ASSERT_EQ(wl_list_remove_fake.call_count, 5); + + for(uint8_t i = 0; i < MAX_NUMBER; i++) + { + mp_dbElem[i] = nullptr; + } + mp_iviIdAgent = nullptr; +} + +/** ================================================================================================ + * @test_id id_agent_module_init_cannotGetwestonConfig + * @brief Test case of id_agent_module_init() where wet_get_config() does not mock, return null pointer + * @test_procedure Steps: + * -# Prepare mock for wl_list_init(), to init real list + * -# Prepare mock for wl_list_insert(), to insert real object + * -# Prepare mock for wl_list_empty(), to empty real list + * -# Calling the id_agent_module_init() + * -# Verification point: + * +# id_agent_module_init() must return IVI_FAILED + * +# wet_get_config() must be called once time + * +# weston_config_get_section() not be called + */ +TEST_F(IdAgentTest, id_agent_module_init_cannotGetwestonConfig) +{ + wl_list_init_fake.custom_fake = custom_wl_list_init; + wl_list_empty_fake.custom_fake = custom_wl_list_empty; + + ASSERT_EQ(id_agent_module_init(&m_iviShell), IVI_FAILED); + + ASSERT_EQ(wet_get_config_fake.call_count, 1); + ASSERT_EQ(weston_config_get_section_fake.call_count, 0); +} + +/** ================================================================================================ + * @test_id id_agent_module_init_noDefaultBehaviorNoDesktopApp + * @brief Test case of id_agent_module_init() where weston_config_get_section() does not mock, return null pointer + * @test_procedure Steps: + * -# Prepare mock for wl_list_init(), to init real list + * -# Prepare mock for wl_list_insert(), to insert real object + * -# Prepare mock for wl_list_empty(), to empty real list + * -# Mocking the wet_get_config() to return an object + * -# Calling the id_agent_module_init() + * -# Verification point: + * +# id_agent_module_init() must return IVI_FAILED + * +# wet_get_config() must be called once time + * +# weston_config_get_section() must be called once time + * +# weston_config_next_section() must be called once time + * +# weston_config_section_get_uint() not be called + * +# weston_config_section_get_string() not be called + * +# wl_list_empty() must return 0 + */ +TEST_F(IdAgentTest, id_agent_module_init_noDefaultBehaviorNoDesktopApp) +{ + wl_list_init_fake.custom_fake = custom_wl_list_init; + wl_list_empty_fake.custom_fake = custom_wl_list_empty; + + SET_RETURN_SEQ(wet_get_config, (struct weston_config **)&mp_fakePointer, 1); + + ASSERT_EQ(id_agent_module_init(&m_iviShell), IVI_FAILED); + + ASSERT_EQ(wet_get_config_fake.call_count, 1); + ASSERT_EQ(weston_config_get_section_fake.call_count, 1); + ASSERT_EQ(weston_config_next_section_fake.call_count, 1); + ASSERT_EQ(weston_config_section_get_uint_fake.call_count, 0); + ASSERT_EQ(weston_config_section_get_string_fake.call_count, 0); + ASSERT_NE(wl_list_empty_fake.return_val_history[0], 0); +} + +/** ================================================================================================ + * @test_id id_agent_module_init_hasDefaultBehaviorNoDesktopApp + * @brief Test case of id_agent_module_init() where weston_config_get_section() does mock, return an object + * and default surface id and default surface id max are INVALID_ID + * @test_procedure Steps: + * -# Prepare mock for wl_list_init(), to init real list + * -# Prepare mock for wl_list_insert(), to insert real object + * -# Prepare mock for wl_list_empty(), to empty real list + * -# Mocking the wet_get_config() to return an object + * -# Mocking the weston_config_get_section() to return an object + * -# Set the default surface id and default surface id max to INVALID_ID + * -# Prepare mock for weston_config_section_get_uint(), to set the input value + * -# Calling the id_agent_module_init() time 1 + * -# Set the default surface id to valid value and default surface id max to INVALID_ID + * -# Calling the id_agent_module_init() time 2 + * -# Verification point: + * +# id_agent_module_init() time 1 and time 2 must return IVI_FAILED + * +# wet_get_config() must be called 2 times + * +# weston_config_get_section() must be called 2 times + * +# weston_config_section_get_uint() must be called 4 times + * +# weston_config_section_get_string() not be called + */ +TEST_F(IdAgentTest, id_agent_module_init_hasDefaultBehaviorNoDesktopApp) +{ + wl_list_init_fake.custom_fake = custom_wl_list_init; + wl_list_empty_fake.custom_fake = custom_wl_list_empty; + + SET_RETURN_SEQ(wet_get_config, (struct weston_config **)&mp_fakePointer, 1); + SET_RETURN_SEQ(weston_config_get_section, (struct weston_config_section **)&mp_fakePointer, 1); + + IdAgentTest::ms_defaultSurfaceId = INVALID_ID; + IdAgentTest::ms_defaultSurfaceIdMax = INVALID_ID; + weston_config_section_get_uint_fake.custom_fake = custom_weston_config_section_get_uint; + + EXPECT_EQ(id_agent_module_init(&m_iviShell), IVI_FAILED); + + IdAgentTest::ms_defaultSurfaceId = 100; + IdAgentTest::ms_defaultSurfaceIdMax = INVALID_ID; + EXPECT_EQ(id_agent_module_init(&m_iviShell), IVI_FAILED); + + ASSERT_EQ(wet_get_config_fake.call_count, 2); + ASSERT_EQ(weston_config_get_section_fake.call_count, 2); + ASSERT_EQ(weston_config_section_get_uint_fake.call_count, 4); + ASSERT_EQ(weston_config_section_get_string_fake.call_count, 0); +} + +/** ================================================================================================ + * @test_id id_agent_module_init_noDefaultBehaviorHasDesktopAppWithInvalidSurfaceId + * @brief Test case of id_agent_module_init() where weston_config_next_section() does mock, return an object + * and no set default behavior and invalid surface id + * @test_procedure Steps: + * -# Prepare mock for wl_list_init(), to init real list + * -# Prepare mock for wl_list_insert(), to insert real object + * -# Prepare mock for wl_list_empty(), to empty real list + * -# Mocking the wet_get_config() to return an object + * -# Mocking the weston_config_next_section() to return an object + * -# Set the surface id to INVALID_ID + * -# Prepare mock for weston_config_section_get_uint(), to set the input value + * -# Calling the id_agent_module_init() + * -# Verification point: + * +# id_agent_module_init() must return IVI_FAILED + * +# wet_get_config() must be called once time + * +# weston_config_next_section() must be called once time + * +# weston_config_section_get_uint() must be called once time + * +# weston_config_section_get_string() not be called + */ +TEST_F(IdAgentTest, id_agent_module_init_noDefaultBehaviorHasDesktopAppWithInvalidSurfaceId) +{ + wl_list_init_fake.custom_fake = custom_wl_list_init; + wl_list_empty_fake.custom_fake = custom_wl_list_empty; + + int (*weston_config_next_section_fakes[])(struct weston_config *, struct weston_config_section **, const char **) = { + custom_weston_config_next_section_1, + custom_weston_config_next_section_2 + }; + SET_RETURN_SEQ(wet_get_config, (struct weston_config **)&mp_fakePointer, 1); + SET_CUSTOM_FAKE_SEQ(weston_config_next_section, weston_config_next_section_fakes, 2); + + IdAgentTest::ms_surfaceId = INVALID_ID; + weston_config_section_get_uint_fake.custom_fake = custom_weston_config_section_get_uint; + + ASSERT_EQ(id_agent_module_init(&m_iviShell), IVI_FAILED); + + ASSERT_EQ(wet_get_config_fake.call_count, 1); + ASSERT_EQ(weston_config_next_section_fake.call_count, 1); + ASSERT_EQ(weston_config_section_get_uint_fake.call_count, 1); + ASSERT_EQ(weston_config_section_get_string_fake.call_count, 0); + + struct db_elem *db_elem = (struct db_elem *)((uintptr_t)weston_config_section_get_uint_fake.arg2_history[0] - offsetof(struct db_elem, surface_id)); + free(db_elem); +} + +/** ================================================================================================ + * @test_id id_agent_module_init_noDefaultBehaviorHasDesktopAppWithNullOfAppIdAndAppTitle + * @brief Test case of id_agent_module_init() where weston_config_next_section() does mock, return an object + * and no set default behavior and valid surface id and invalid appTitle, appId + * @test_procedure Steps: + * -# Prepare mock for wl_list_init(), to init real list + * -# Prepare mock for wl_list_insert(), to insert real object + * -# Prepare mock for wl_list_empty(), to empty real list + * -# Mocking the wet_get_config() to return an object + * -# Mocking the weston_config_next_section() to return an object + * -# Set the surface id to a valid value + * -# Set the appTitle and appId to null pointer + * -# Prepare mock for weston_config_section_get_uint(), to set the input value + * -# Prepare mock for weston_config_section_get_string(), to set the input value + * -# Calling the id_agent_module_init() + * -# Verification point: + * +# id_agent_module_init() must return IVI_FAILED + * +# wet_get_config() must be called once time + * +# weston_config_next_section() must be called once time + * +# weston_config_section_get_uint() must be called once time + * +# weston_config_section_get_string() must be called 2 times + */ +TEST_F(IdAgentTest, id_agent_module_init_noDefaultBehaviorHasDesktopAppWithNullOfAppIdAndAppTitle) +{ + wl_list_init_fake.custom_fake = custom_wl_list_init; + wl_list_empty_fake.custom_fake = custom_wl_list_empty; + + int (*weston_config_next_section_fakes[])(struct weston_config *, struct weston_config_section **, const char **) = { + custom_weston_config_next_section_1, + custom_weston_config_next_section_2 + }; + SET_RETURN_SEQ(wet_get_config, (struct weston_config **)&mp_fakePointer, 1); + SET_CUSTOM_FAKE_SEQ(weston_config_next_section, weston_config_next_section_fakes, 2); + + IdAgentTest::ms_surfaceId = 10; + IdAgentTest::ms_appId = nullptr; + IdAgentTest::ms_appTitle = nullptr; + weston_config_section_get_uint_fake.custom_fake = custom_weston_config_section_get_uint; + weston_config_section_get_string_fake.custom_fake = custom_weston_config_section_get_string; + + ASSERT_EQ(id_agent_module_init(&m_iviShell), IVI_FAILED); + + ASSERT_EQ(wet_get_config_fake.call_count, 1); + ASSERT_EQ(weston_config_next_section_fake.call_count, 1); + ASSERT_EQ(weston_config_section_get_uint_fake.call_count, 1); + ASSERT_EQ(weston_config_section_get_string_fake.call_count, 2); + + struct db_elem *db_elem = (struct db_elem *)((uintptr_t)weston_config_section_get_uint_fake.arg2_history[0] - offsetof(struct db_elem, surface_id)); + free(db_elem); +} + +/** ================================================================================================ + * @test_id id_agent_module_init_noDefaultBehaviorHasDesktopAppWithRightConfig + * @brief Test case of id_agent_module_init() where weston_config_next_section() does mock, return an object + * and no set default behavior and valid surface id, appTitle, appId + * @test_procedure Steps: + * -# Prepare mock for wl_list_init(), to init real list + * -# Prepare mock for wl_list_insert(), to insert real object + * -# Prepare mock for wl_list_empty(), to empty real list + * -# Mocking the wet_get_config() to return an object + * -# Mocking the weston_config_next_section() to return an object + * -# Set the surface id to a valid value + * -# Set the appTitle and appId to a valid value + * -# Prepare mock for weston_config_section_get_uint(), to set the input value + * -# Prepare mock for weston_config_section_get_string(), to set the input value + * -# Calling the id_agent_module_init() + * -# Verification point: + * +# id_agent_module_init() must return IVI_FAILED + * +# wet_get_config() must be called once time + * +# weston_config_next_section() must be called once time + * +# weston_config_section_get_uint() must be called once time + * +# weston_config_section_get_string() must be called 2 times + * @todo Maybe have a logic issue here, do we must have the default-app-default section? + * only that section configured the default id and default max id + */ +TEST_F(IdAgentTest, id_agent_module_init_noDefaultBehaviorHasDesktopAppWithRightConfig) +{ + wl_list_init_fake.custom_fake = custom_wl_list_init; + wl_list_empty_fake.custom_fake = custom_wl_list_empty; + + int (*weston_config_next_section_fakes[])(struct weston_config *, struct weston_config_section **, const char **) = { + custom_weston_config_next_section_1, + custom_weston_config_next_section_2 + }; + SET_RETURN_SEQ(wet_get_config, (struct weston_config **)&mp_fakePointer, 1); + SET_CUSTOM_FAKE_SEQ(weston_config_next_section, weston_config_next_section_fakes, 2); + + IdAgentTest::ms_surfaceId = 0; + IdAgentTest::ms_appId = (char*)"0"; + IdAgentTest::ms_appTitle = (char*)"app_0"; + weston_config_section_get_uint_fake.custom_fake = custom_weston_config_section_get_uint; + weston_config_section_get_string_fake.custom_fake = custom_weston_config_section_get_string; + + ASSERT_EQ(id_agent_module_init(&m_iviShell), IVI_FAILED); + + ASSERT_EQ(wet_get_config_fake.call_count, 1); + ASSERT_EQ(weston_config_next_section_fake.call_count, 1); + ASSERT_EQ(weston_config_section_get_uint_fake.call_count, 1); + ASSERT_EQ(weston_config_section_get_string_fake.call_count, 2); + + struct db_elem *db_elem = (struct db_elem *)((uintptr_t)weston_config_section_get_uint_fake.arg2_history[0] - offsetof(struct db_elem, surface_id)); + free(db_elem->cfg_app_id); + free(db_elem->cfg_title); + free(db_elem); +} + +/** ================================================================================================ + * @test_id id_agent_module_init_hasDefaultBehaviorHasDesktopAppWithRightConfig + * @brief Test case of id_agent_module_init() where weston_config_next_section() does mock, return an object + * and set default behavior and valid surface id, appTitle, appId but surface id exceeds the default value + * @test_procedure Steps: + * -# Prepare mock for wl_list_init(), to init real list + * -# Prepare mock for wl_list_insert(), to insert real object + * -# Prepare mock for wl_list_empty(), to empty real list + * -# Mocking the wet_get_config() to return an object + * -# Mocking the weston_config_get_section() to return an object + * -# Mocking the weston_config_next_section() to return an object + * -# Set the default surface id and default surface id max + * -# Set the surface id to a valid value but it exceeds the default value + * -# Set the appTitle and appId to a valid value + * -# Prepare mock for weston_config_section_get_uint(), to set the input value + * -# Prepare mock for weston_config_section_get_string(), to set the input value + * -# Calling the id_agent_module_init() + * -# Verification point: + * +# id_agent_module_init() must return IVI_FAILED + * +# wet_get_config() must be called once time + * +# weston_config_get_section() must be called once time + * +# weston_config_next_section() must be called once time + * +# weston_config_section_get_uint() must be called 3 times + * +# weston_config_section_get_string() must be called 2 times + * @todo Maybe have a logic issue here, range of surface id in check_config functions + * enable free resoure, if there is a change in the lib + */ +TEST_F(IdAgentTest, id_agent_module_init_hasDefaultBehaviorHasDesktopAppWithRightConfig) +{ + wl_list_init_fake.custom_fake = custom_wl_list_init; + wl_list_empty_fake.custom_fake = custom_wl_list_empty; + + int (*weston_config_next_section_fakes[])(struct weston_config *, struct weston_config_section **, const char **) = { + custom_weston_config_next_section_1, + custom_weston_config_next_section_2 + }; + SET_RETURN_SEQ(wet_get_config, (struct weston_config **)&mp_fakePointer, 1); + SET_RETURN_SEQ(weston_config_get_section, (struct weston_config_section **)&mp_fakePointer, 1); + SET_CUSTOM_FAKE_SEQ(weston_config_next_section, weston_config_next_section_fakes, 2); + + IdAgentTest::ms_defaultSurfaceId = 100; + IdAgentTest::ms_defaultSurfaceIdMax = 200; + IdAgentTest::ms_surfaceId = IdAgentTest::ms_defaultSurfaceId + 1; + IdAgentTest::ms_appId = (char*)"0"; + IdAgentTest::ms_appTitle = (char*)"app_0"; + weston_config_section_get_uint_fake.custom_fake = custom_weston_config_section_get_uint; + weston_config_section_get_string_fake.custom_fake = custom_weston_config_section_get_string; + + ASSERT_EQ(id_agent_module_init(&m_iviShell), IVI_FAILED); + + ASSERT_EQ(wet_get_config_fake.call_count, 1); + ASSERT_EQ(weston_config_get_section_fake.call_count, 1); + ASSERT_EQ(weston_config_next_section_fake.call_count, 1); + ASSERT_EQ(weston_config_section_get_uint_fake.call_count, 3); + ASSERT_EQ(weston_config_section_get_string_fake.call_count, 2); + struct db_elem *db_elem = (struct db_elem *)((uintptr_t)weston_config_section_get_uint_fake.arg2_history[2] - offsetof(struct db_elem, surface_id)); + free(db_elem->cfg_app_id); + free(db_elem->cfg_title); + free(db_elem); +} + +/** ================================================================================================ + * @test_id id_agent_module_init_success + * @brief Test case of id_agent_module_init() where weston_config_next_section() does mock, return an object + * and set default behavior and valid surface id, appTitle, appId (surface id is in the range of the default value) + * @test_procedure Steps: + * -# Prepare mock for wl_list_init(), to init real list + * -# Prepare mock for wl_list_insert(), to insert real object + * -# Prepare mock for wl_list_empty(), to empty real list + * -# Mocking the wet_get_config() to return an object + * -# Mocking the weston_config_get_section() to return an object + * -# Mocking the weston_config_next_section() to return an object + * -# Set the default surface id and default surface id max + * -# Set the surface id to a valid value that is in the range of the default value + * -# Set the appTitle and appId to a valid value + * -# Prepare mock for weston_config_section_get_uint(), to set the input value + * -# Prepare mock for weston_config_section_get_string(), to set the input value + * -# Calling the id_agent_module_init() + * -# Verification point: + * +# id_agent_module_init() must return IVI_SUCCEEDED + * +# wet_get_config() must be called once time + * +# weston_config_get_section() must be called once time + * +# weston_config_next_section() must be called 2 times + * +# weston_config_section_get_uint() must be called 3 times + * +# weston_config_section_get_string() must be called 2 times + */ +TEST_F(IdAgentTest, id_agent_module_init_success) +{ + wl_list_init_fake.custom_fake = custom_wl_list_init; + wl_list_empty_fake.custom_fake = custom_wl_list_empty; + + int (*weston_config_next_section_fakes[])(struct weston_config *, struct weston_config_section **, const char **) = { + custom_weston_config_next_section_1, + custom_weston_config_next_section_2 + }; + SET_RETURN_SEQ(wet_get_config, (struct weston_config **)&mp_fakePointer, 1); + SET_RETURN_SEQ(weston_config_get_section, (struct weston_config_section **)&mp_fakePointer, 1); + SET_CUSTOM_FAKE_SEQ(weston_config_next_section, weston_config_next_section_fakes, 2); + + IdAgentTest::ms_defaultSurfaceId = 100; + IdAgentTest::ms_defaultSurfaceIdMax = 200; + IdAgentTest::ms_surfaceId = IdAgentTest::ms_defaultSurfaceId - 1; + IdAgentTest::ms_appId = (char*)"0"; + IdAgentTest::ms_appTitle = (char*)"app_0"; + weston_config_section_get_uint_fake.custom_fake = custom_weston_config_section_get_uint; + weston_config_section_get_string_fake.custom_fake = custom_weston_config_section_get_string; + + ASSERT_EQ(id_agent_module_init(&m_iviShell), IVI_SUCCEEDED); + + ASSERT_EQ(wet_get_config_fake.call_count, 1); + ASSERT_EQ(weston_config_get_section_fake.call_count, 1); + ASSERT_EQ(weston_config_next_section_fake.call_count, 2); + ASSERT_EQ(weston_config_section_get_uint_fake.call_count, 3); + ASSERT_EQ(weston_config_section_get_string_fake.call_count, 2); +} diff --git a/unittest/server/src/ivi_input_controller_uinttests.cpp b/unittest/server/src/ivi_input_controller_uinttests.cpp new file mode 100644 index 00000000..7afdf678 --- /dev/null +++ b/unittest/server/src/ivi_input_controller_uinttests.cpp @@ -0,0 +1,1714 @@ +/*************************************************************************** + * + * Copyright (C) 2023 Advanced Driver Information Technology Joint Venture GmbH + * + * + * 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. + * + ****************************************************************************/ + + +#include +#include "ivi-controller.h" +#include "ivi-input-server-protocol.h" +#include "ivi_layout_structure.hpp" +#include "server_api_fake.h" +#include "ivi_layout_interface_fake.h" +#include "ilm_types.h" + +static constexpr uint8_t MAX_NUMBER = 2; +static constexpr uint8_t DEFAULT_SEAT = 0; +static constexpr uint8_t CUSTOM_SEAT = 1; + +extern "C" +{ +FAKE_VALUE_FUNC(struct ivi_layout_surface *, get_surface, struct weston_surface *); + +struct wl_resource * custom_wl_resource_from_link(struct wl_list *link) +{ + struct wl_resource *resource; + + return wl_container_of(link, resource, link); +} + +struct wl_list * custom_wl_resource_get_link(struct wl_resource *resource) +{ + return &resource->link; +} + +} + +extern "C" +{ +#include "ivi-input-controller.c" +} + +class InputControllerTest: public ::testing::Test +{ +public: + void SetUp() + { + IVI_LAYOUT_FAKE_LIST(RESET_FAKE); + SERVER_API_FAKE_LIST(RESET_FAKE); + init_input_controller_content(); + } + + void TearDown() + { + deinit_input_controller_content(); + } + + void init_input_controller_content() + { + // Prepare sample for ivi shell + m_iviShell.interface = &g_iviLayoutInterfaceFake; + m_iviShell.compositor = &m_westonCompositor; + custom_wl_list_init(&m_iviShell.list_surface); + custom_wl_list_init(&m_westonCompositor.seat_list); + // Prepare the input context + mp_ctxInput = (struct input_context*)calloc(1, sizeof(struct input_context)); + mp_ctxInput->ivishell = &m_iviShell; + custom_wl_list_init(&mp_ctxInput->seat_list); + custom_wl_list_init(&mp_ctxInput->resource_list); + + for(uint8_t i = 0; i < MAX_NUMBER; i++) + { + //Prepare for weston seats + mp_westonSeat[i].seat_name = (char*)mp_seatName[i]; + custom_wl_list_init(&mp_westonSeat[i].destroy_signal.listener_list); + custom_wl_list_init(&mp_westonSeat[i].updated_caps_signal.listener_list); + //Prepare for seat context + mpp_ctxSeat[i] = (struct seat_ctx*)calloc(1, sizeof(struct seat_ctx)); + mpp_ctxSeat[i]->input_ctx = mp_ctxInput; + mpp_ctxSeat[i]->west_seat = &mp_westonSeat[i]; + mpp_ctxSeat[i]->pointer_grab.interface = &g_grabInterfaceFake; + custom_wl_list_insert(&mp_ctxInput->seat_list, &mpp_ctxSeat[i]->seat_node); + //Prepare for resource + mp_wlResource[i].object.id = i + 1; + custom_wl_list_insert(&mp_ctxInput->resource_list, &mp_wlResource[i].link); + //Prepare for surface + mp_layoutSurface[i].id_surface = i + 10; + mp_iviSurface[i].shell = &m_iviShell; + mp_iviSurface[i].layout_surface = &mp_layoutSurface[i]; + custom_wl_list_init(&mp_iviSurface[i].accepted_seat_list); + custom_wl_list_insert(&m_iviShell.list_surface, &mp_iviSurface[i].link); + // Prepare for accepted + mpp_seatFocus[i] = (struct seat_focus*)calloc(1, sizeof(struct seat_focus)); + mpp_seatFocus[i]->seat_ctx = mpp_ctxSeat[i]; + custom_wl_list_insert(&mp_iviSurface[i].accepted_seat_list, &mpp_seatFocus[i]->link); + } + } + + void enable_utility_funcs_of_array_list() + { + wl_list_init_fake.custom_fake = custom_wl_list_init; + wl_list_insert_fake.custom_fake = custom_wl_list_insert; + wl_list_remove_fake.custom_fake = custom_wl_list_remove; + wl_list_empty_fake.custom_fake = custom_wl_list_empty; + wl_array_init_fake.custom_fake = custom_wl_array_init; + wl_array_release_fake.custom_fake = custom_wl_array_release; + wl_array_add_fake.custom_fake = custom_wl_array_add; + wl_signal_init(&m_iviShell.ivisurface_created_signal); + wl_signal_init(&m_iviShell.ivisurface_removed_signal); + wl_signal_init(&m_iviShell.compositor->destroy_signal); + wl_signal_init(&m_iviShell.compositor->seat_created_signal); + } + + void deinit_input_controller_content() + { + if(mp_ctxInput != nullptr) + { + free(mp_ctxInput); + } + + for(uint8_t i = 0; i< MAX_NUMBER; i++) + { + if(mpp_ctxSeat[i] != nullptr) + { + free(mpp_ctxSeat[i]); + } + if(mpp_seatFocus[i] != nullptr) + { + free(mpp_seatFocus[i]); + } + } + } + + struct input_context *mp_ctxInput = nullptr; + struct wl_resource mp_wlResource[MAX_NUMBER]; + + struct seat_ctx *mpp_ctxSeat[MAX_NUMBER] = {nullptr}; + struct weston_seat mp_westonSeat[MAX_NUMBER]; + const char* mp_seatName[MAX_NUMBER] = {"default", "weston_seat_1"}; + + struct seat_focus *mpp_seatFocus[MAX_NUMBER] = {nullptr}; + struct ivisurface mp_iviSurface[MAX_NUMBER]; + struct ivi_layout_surface mp_layoutSurface[MAX_NUMBER]; + + struct weston_compositor m_westonCompositor = {}; + struct ivishell m_iviShell = {}; +}; + +/** ================================================================================================ + * @test_id handle_seat_create_customSeat + * @brief Test case of handle_seat_create() where valid input params with seat name is a custom seat + * @test_procedure Steps: + * -# Calling the handle_seat_create() + * -# Verification point: + * +# wl_list_insert() must be called 5 times + * +# wl_resource_post_event() must be called 6 times + * +# Free resources are allocated when running the test + */ +TEST_F(InputControllerTest, handle_seat_create_customSeat) +{ + enable_utility_funcs_of_array_list(); + wl_resource_from_link_fake.custom_fake = custom_wl_resource_from_link; + wl_resource_get_link_fake.custom_fake = custom_wl_resource_get_link; + mp_ctxInput->seat_default_name = (char*)mp_seatName[CUSTOM_SEAT]; + handle_seat_create(&mp_ctxInput->seat_create_listener, &mp_westonSeat[CUSTOM_SEAT]); + ASSERT_EQ(wl_list_insert_fake.call_count, 5); + ASSERT_EQ(wl_resource_post_event_fake.call_count, 6); + + struct seat_ctx *lp_ctxSeat = (struct seat_ctx *)((uintptr_t)wl_list_insert_fake.arg1_history[0] - offsetof(struct seat_ctx, seat_node)); + for(uint8_t i = 0; i < MAX_NUMBER; i++) + { + struct seat_focus *lp_seatFocus = (struct seat_focus *)((uintptr_t)wl_list_insert_fake.arg1_history[i+3] - offsetof(struct seat_focus, link)); + free(lp_seatFocus); + } + free(lp_ctxSeat); +} + +/** ================================================================================================ + * @test_id handle_seat_create_defaultSeat + * @brief Test case of handle_seat_create() where valid input params with seat name is default seat + * @test_procedure Steps: + * -# Calling the handle_seat_create() + * -# Verification point: + * +# wl_list_insert() must be called 5 times + * +# wl_resource_post_event() must be called {MAX_NUMBER + MAX_NUMBER*MAX_NUMBER} times + * +# Free resources are allocated when running the test + */ +TEST_F(InputControllerTest, handle_seat_create_defaultSeat) +{ + enable_utility_funcs_of_array_list(); + wl_resource_from_link_fake.custom_fake = custom_wl_resource_from_link; + wl_resource_get_link_fake.custom_fake = custom_wl_resource_get_link; + mp_ctxInput->seat_default_name = (char*)mp_seatName[DEFAULT_SEAT]; + handle_seat_create(&mp_ctxInput->seat_create_listener, &mp_westonSeat[DEFAULT_SEAT]); + + ASSERT_EQ(wl_list_insert_fake.call_count, 5); + ASSERT_EQ(MAX_NUMBER + MAX_NUMBER*MAX_NUMBER, wl_resource_post_event_fake.call_count); + + struct seat_ctx *lp_ctxSeat = (struct seat_ctx *)((uintptr_t)wl_list_insert_fake.arg1_history[0] - offsetof(struct seat_ctx, seat_node)); + for(uint8_t i = 0; i < MAX_NUMBER; i++) + { + struct seat_focus *lp_seatFocus = (struct seat_focus *)((uintptr_t)wl_list_insert_fake.arg1_history[i+3] - offsetof(struct seat_focus, link)); + free(lp_seatFocus); + } + free(lp_ctxSeat); +} + +/** ================================================================================================ + * @test_id handle_seat_updated_caps_allAvailableWithSameAdrr + * @brief Test case of handle_seat_updated_caps() where object address of mocked functions + * is same as input address + * @test_procedure Steps: + * -# Mocking the weston_seat_get_keyboard() does return an object with address 0xFFFFFFFF + * -# Mocking the weston_seat_get_pointer() does return an object with address 0xFFFFFFFF + * -# Mocking the weston_seat_get_touch() does return an object with address 0xFFFFFFFF + * -# Set input param keyboard_grab.keyboard to an object with address 0xFFFFFFFF + * -# Set input param pointer_grab.pointer to an object with address 0xFFFFFFFF + * -# Set input param touch_grab.touch to an object with address 0xFFFFFFFF + * -# Calling the handle_seat_updated_caps() + * -# Verification point: + * +# weston_keyboard_start_grab() not be called + * +# weston_pointer_start_grab() not be called + * +# weston_touch_start_grab() not be called + * +# wl_resource_post_event() must be called {MAX_NUMBER} times + */ +TEST_F(InputControllerTest, handle_seat_updated_caps_allAvailableWithSameAdrr) +{ + struct weston_keyboard *lpp_keyboard [] = {(struct weston_keyboard *)0xFFFFFFFF}; + struct weston_pointer *lpp_pointer [] = {(struct weston_pointer *)0xFFFFFFFF}; + struct weston_touch *lpp_touch [] = {(struct weston_touch *)0xFFFFFFFF}; + SET_RETURN_SEQ(weston_seat_get_keyboard, lpp_keyboard, 1); + SET_RETURN_SEQ(weston_seat_get_pointer, lpp_pointer, 1); + SET_RETURN_SEQ(weston_seat_get_touch, lpp_touch, 1); + + mpp_ctxSeat[CUSTOM_SEAT]->keyboard_grab.keyboard = {(struct weston_keyboard *)0xFFFFFFFF}; + mpp_ctxSeat[CUSTOM_SEAT]->pointer_grab.pointer = {(struct weston_pointer *)0xFFFFFFFF}; + mpp_ctxSeat[CUSTOM_SEAT]->touch_grab.touch = {(struct weston_touch *)0xFFFFFFFF}; + + handle_seat_updated_caps(&mpp_ctxSeat[CUSTOM_SEAT]->updated_caps_listener, &mp_westonSeat[CUSTOM_SEAT]); + + ASSERT_EQ(0, weston_keyboard_start_grab_fake.call_count); + ASSERT_EQ(0, weston_pointer_start_grab_fake.call_count); + ASSERT_EQ(0, weston_touch_start_grab_fake.call_count); + ASSERT_EQ(MAX_NUMBER, wl_resource_post_event_fake.call_count); +} + +/** ================================================================================================ + * @test_id handle_seat_updated_caps_allAvailableWithNotSameAdrr + * @brief Test case of handle_seat_updated_caps() where object address of mocked functions + * is different from input address + * @test_procedure Steps: + * -# Mocking the weston_seat_get_keyboard() does return an object with address 0xFFFFFFFF + * -# Mocking the weston_seat_get_pointer() does return an object with address 0xFFFFFFFF + * -# Mocking the weston_seat_get_touch() does return an object with address 0xFFFFFFFF + * -# Set input param keyboard_grab.keyboard to null pointer + * -# Set input param pointer_grab.pointer to null pointer + * -# Set input param touch_grab.touch to null pointer + * -# Calling the handle_seat_updated_caps() + * -# Verification point: + * +# weston_keyboard_start_grab() must be called once time + * +# weston_pointer_start_grab() must be called once time + * +# weston_touch_start_grab() must be called once time + * +# wl_resource_post_event() must be called {MAX_NUMBER} times + */ +TEST_F(InputControllerTest, handle_seat_updated_caps_allAvailableWithNotSameAdrr) +{ + struct weston_keyboard *lpp_keyboard [] = {(struct weston_keyboard *)0xFFFFFFFF}; + struct weston_pointer *lpp_pointer [] = {(struct weston_pointer *)0xFFFFFFFF}; + struct weston_touch *lpp_touch [] = {(struct weston_touch *)0xFFFFFFFF}; + SET_RETURN_SEQ(weston_seat_get_keyboard, lpp_keyboard, 1); + SET_RETURN_SEQ(weston_seat_get_pointer, lpp_pointer, 1); + SET_RETURN_SEQ(weston_seat_get_touch, lpp_touch, 1); + + mpp_ctxSeat[CUSTOM_SEAT]->keyboard_grab.keyboard = nullptr; + mpp_ctxSeat[CUSTOM_SEAT]->pointer_grab.pointer = nullptr; + mpp_ctxSeat[CUSTOM_SEAT]->touch_grab.touch = nullptr; + + handle_seat_updated_caps(&mpp_ctxSeat[CUSTOM_SEAT]->updated_caps_listener, &mp_westonSeat[CUSTOM_SEAT]); + + ASSERT_EQ(1, weston_keyboard_start_grab_fake.call_count); + ASSERT_EQ(1, weston_pointer_start_grab_fake.call_count); + ASSERT_EQ(1, weston_touch_start_grab_fake.call_count); + ASSERT_EQ(MAX_NUMBER, wl_resource_post_event_fake.call_count); +} + +/** ================================================================================================ + * @test_id handle_seat_updated_caps_notAvailable + * @brief Test case of handle_seat_updated_caps() where weston_seat_get_keyboard() and weston_seat_get_pointer() + * and weston_seat_get_touch() are not mocked + * @test_procedure Steps: + * -# Calling the handle_seat_updated_caps() time 1 + * -# Set input param keyboard_grab.keyboard to an object with address 0xFFFFFFFF + * -# Set input param pointer_grab.pointer to an object with address 0xFFFFFFFF + * -# Set input param touch_grab.touch to an object with address 0xFFFFFFFF + * -# Calling the handle_seat_updated_caps() time 2 + * -# Verification point: + * +# weston_keyboard_start_grab() not be called + * +# weston_pointer_start_grab() not be called + * +# weston_touch_start_grab() not be called + * +# keyboard_grab.keyboard set to null pointer + * +# pointer_grab.pointer set to null pointer + * +# touch_grab.touch set to null pointer + * +# wl_resource_post_event() must be called {2*MAX_NUMBER} times + */ +TEST_F(InputControllerTest, handle_seat_updated_caps_notAvailable) +{ + handle_seat_updated_caps(&mpp_ctxSeat[CUSTOM_SEAT]->updated_caps_listener, &mp_westonSeat[CUSTOM_SEAT]); + + mpp_ctxSeat[CUSTOM_SEAT]->keyboard_grab.keyboard = (struct weston_keyboard *)0xFFFFFFFF; + mpp_ctxSeat[CUSTOM_SEAT]->pointer_grab.pointer = (struct weston_pointer *)0xFFFFFFFF; + mpp_ctxSeat[CUSTOM_SEAT]->touch_grab.touch = (struct weston_touch *)0xFFFFFFFF; + + handle_seat_updated_caps(&mpp_ctxSeat[CUSTOM_SEAT]->updated_caps_listener, &mp_westonSeat[CUSTOM_SEAT]); + + ASSERT_EQ(0, weston_keyboard_start_grab_fake.call_count); + ASSERT_EQ(0, weston_pointer_start_grab_fake.call_count); + ASSERT_EQ(0, weston_touch_start_grab_fake.call_count); + ASSERT_EQ(nullptr, mpp_ctxSeat[CUSTOM_SEAT]->keyboard_grab.keyboard); + ASSERT_EQ(nullptr, mpp_ctxSeat[CUSTOM_SEAT]->pointer_grab.pointer); + ASSERT_EQ(nullptr, mpp_ctxSeat[CUSTOM_SEAT]->touch_grab.touch); + ASSERT_EQ(2*MAX_NUMBER, wl_resource_post_event_fake.call_count); +} + +/** ================================================================================================ + * @test_id handle_seat_destroy_notSurfaceAccepted + * @brief Test case of handle_seat_destroy() where seat_list is null list + * @test_procedure Steps: + * -# Prepare the data input, the seat_ctx object + * -# Calling the handle_seat_destroy() + * -# Verification point: + * +# wl_resource_post_event() must be called {MAX_NUMBER} times + * +# wl_list_remove() must be called 3 times + */ +TEST_F(InputControllerTest, handle_seat_destroy_notSurfaceAccepted) +{ + struct seat_ctx* lp_ctxSeat = (struct seat_ctx*)calloc(1, sizeof(struct seat_ctx)); + lp_ctxSeat->input_ctx = mp_ctxInput; + lp_ctxSeat->west_seat = &mp_westonSeat[CUSTOM_SEAT]; + + handle_seat_destroy(&lp_ctxSeat->destroy_listener, &mp_westonSeat[CUSTOM_SEAT]); + + ASSERT_EQ(MAX_NUMBER, wl_resource_post_event_fake.call_count); + ASSERT_EQ(3, wl_list_remove_fake.call_count); +} + +/** ================================================================================================ + * @test_id handle_seat_destroy_withSurfaceAccepted + * @brief Test case of handle_seat_destroy() where exist elements in seat_list + * @test_procedure Steps: + * -# Calling the handle_seat_destroy() + * -# Verification point: + * +# wl_resource_post_event() must be called {MAX_NUMBER} times + * +# wl_list_remove() must be called 4 times + * +# Free resources are allocated when running the test + */ +TEST_F(InputControllerTest, handle_seat_destroy_withSurfaceAccepted) +{ + handle_seat_destroy(&mpp_ctxSeat[CUSTOM_SEAT]->destroy_listener, &mp_westonSeat[CUSTOM_SEAT]); + + ASSERT_EQ(MAX_NUMBER, wl_resource_post_event_fake.call_count); + ASSERT_EQ(4, wl_list_remove_fake.call_count); + + mpp_ctxSeat[CUSTOM_SEAT] = nullptr; + mpp_seatFocus[CUSTOM_SEAT] = nullptr; +} + +/** ================================================================================================ + * @test_id input_controller_module_init_WrongInput + * @brief Test case of input_controller_module_init() where interface in ivishell object is a null pointer + * @test_procedure Steps: + * -# Calling the input_controller_module_init() + * -# Verification point: + * +# input_controller_module_init() must not return 0 + */ +TEST_F(InputControllerTest, input_controller_module_init_WrongInput) +{ + m_iviShell.interface = nullptr; + ASSERT_NE(input_controller_module_init(&m_iviShell), 0); +} + +/** ================================================================================================ + * @test_id input_controller_module_init_cannotCreateIviInput + * @brief Test case of input_controller_module_init() where wl_global_create() is not mocked, returns null pointer + * @test_procedure Steps: + * -# Calling the enable_utility_funcs_of_array_list() to set real function for wl_list, wl_array + * -# Calling the input_controller_module_init() + * -# Verification point: + * +# input_controller_module_init() must return 0 + * +# wl_global_create() must be called once time + * +# Free resources are allocated when running the test + */ +TEST_F(InputControllerTest, input_controller_module_init_cannotCreateIviInput) +{ + enable_utility_funcs_of_array_list(); + wl_resource_from_link_fake.custom_fake = custom_wl_resource_from_link; + wl_resource_get_link_fake.custom_fake = custom_wl_resource_get_link; + struct wl_global *lp_wlGlobal = (struct wl_global*) 0xFFFFFFFF; + SET_RETURN_SEQ(wl_global_create, &lp_wlGlobal, 1); + ASSERT_EQ(input_controller_module_init(&m_iviShell), 0); + + EXPECT_EQ(wl_global_create_fake.call_count, 1); + + struct input_context * tmp = wl_global_create_fake.arg3_val; + free(tmp->seat_default_name); + free(tmp); +} + +/** ================================================================================================ + * @test_id input_controller_module_init_canInitSuccess + * @brief Test case of input_controller_module_init() where wl_global_create() is mocked, returns an object + * @test_procedure Steps: + * -# Calling the enable_utility_funcs_of_array_list() to set real function for wl_list, wl_array + * -# Mocking the wl_global_create() does return an object + * -# Calling the input_controller_module_init() + * -# Verification point: + * +# input_controller_module_init() must return 0 + * +# wl_global_create() must be called once time + * +# Input controller module member must same the prepared data + * +# Free resources are allocated when running the test + */ +TEST_F(InputControllerTest, input_controller_module_init_canInitSuccess) +{ + enable_utility_funcs_of_array_list(); + struct wl_global *lp_wlGlobal = (struct wl_global*) 0xFFFFFFFF; + SET_RETURN_SEQ(wl_global_create, &lp_wlGlobal, 1); + + ASSERT_EQ(input_controller_module_init(&m_iviShell), 0); + + ASSERT_EQ(wl_global_create_fake.call_count, 1); + + struct input_context *lp_ctxInput = (struct input_context *)((uintptr_t)wl_list_init_fake.arg0_history[4] - offsetof(struct input_context, resource_list)); + EXPECT_EQ(lp_ctxInput->ivishell, &m_iviShell); + EXPECT_NE(lp_ctxInput->surface_created.notify, nullptr); + EXPECT_NE(lp_ctxInput->surface_destroyed.notify, nullptr); + EXPECT_NE(lp_ctxInput->seat_create_listener.notify, nullptr); + EXPECT_EQ(lp_ctxInput->successful_init_stage, 1); + + free(lp_ctxInput->seat_default_name); + free(lp_ctxInput); +} + +/** ================================================================================================ + * @test_id keyboard_grab_key_success + * @brief Test case of keyboard_grab_key() where surface_get_weston_surface() success, return an object + * and valid input params + * @test_procedure Steps: + * -# Set seat focus to enable {1} + * -# Set input timespec to TIME_UTC + * -# Set input ctxSeat + * -# Mocking the surface_get_weston_surface() does return an object + * -# Calling the keyboard_grab_key() + * -# Verification point: + * +# wl_display_next_serial() must be called once time + * +# surface_get_weston_surface() must be called once time + * +# Free resources are allocated when running the test + */ +TEST_F(InputControllerTest, keyboard_grab_key_success) +{ + mpp_seatFocus[0]->focus = 1; + + struct timespec l_time; + timespec_get(&l_time, TIME_UTC); + + mpp_ctxSeat[0]->keyboard_grab.keyboard = (struct weston_keyboard *)malloc(sizeof(struct weston_keyboard)); + mpp_ctxSeat[0]->keyboard_grab.keyboard->seat = (struct weston_seat *)malloc(sizeof(struct weston_seat)); + mpp_ctxSeat[0]->keyboard_grab.keyboard->seat->compositor = (struct weston_compositor *)malloc(sizeof(struct weston_compositor)); + mpp_ctxSeat[0]->keyboard_grab.keyboard->seat->compositor->wl_display = (struct wl_display *)0xFFFFFFFF; + custom_wl_list_init(&mpp_ctxSeat[0]->keyboard_grab.keyboard->focus_resource_list); + custom_wl_list_insert(&mpp_ctxSeat[0]->keyboard_grab.keyboard->focus_resource_list, &mp_wlResource[0].link); + custom_wl_list_init(&mpp_ctxSeat[0]->keyboard_grab.keyboard->resource_list); + custom_wl_list_insert(&mpp_ctxSeat[0]->keyboard_grab.keyboard->resource_list, &mp_wlResource[1].link); + + struct weston_surface *l_surf[1] = {(struct weston_surface *)malloc(sizeof(struct weston_surface))}; + l_surf[0]->resource = (struct wl_resource *)malloc(sizeof(struct wl_resource)); + SET_RETURN_SEQ(surface_get_weston_surface, l_surf, 1); + + keyboard_grab_key(&mpp_ctxSeat[0]->keyboard_grab, &l_time, 1, 1); + + ASSERT_EQ(wl_display_next_serial_fake.call_count, 1); + ASSERT_EQ(surface_get_weston_surface_fake.call_count, 1); + + free(l_surf[0]->resource); + free(l_surf[0]); + free(mpp_ctxSeat[0]->keyboard_grab.keyboard->seat->compositor); + free(mpp_ctxSeat[0]->keyboard_grab.keyboard->seat); + free(mpp_ctxSeat[0]->keyboard_grab.keyboard); +} + +/** ================================================================================================ + * @test_id keyboard_grab_modifiers_success + * @brief Test case of keyboard_grab_modifiers() where surface_get_weston_surface() success, return an object + * and valid input params + * @test_procedure Steps: + * -# Set seat focus to enable {1} + * -# Set input ctxSeat + * -# Mocking the surface_get_weston_surface() does return an object + * -# Calling the keyboard_grab_modifiers() + * -# Verification point: + * +# wl_resource_get_client() must be called 3 times + * +# Free resources are allocated when running the test + */ +TEST_F(InputControllerTest, keyboard_grab_modifiers_success) +{ + mpp_seatFocus[0]->focus = 1; + + mpp_ctxSeat[0]->keyboard_grab.keyboard = (struct weston_keyboard *)malloc(sizeof(struct weston_keyboard)); + custom_wl_list_init(&mpp_ctxSeat[0]->keyboard_grab.keyboard->focus_resource_list); + custom_wl_list_insert(&mpp_ctxSeat[0]->keyboard_grab.keyboard->focus_resource_list, &mp_wlResource[0].link); + custom_wl_list_init(&mpp_ctxSeat[0]->keyboard_grab.keyboard->resource_list); + custom_wl_list_insert(&mpp_ctxSeat[0]->keyboard_grab.keyboard->resource_list, &mp_wlResource[1].link); + + struct weston_surface *l_surf[1] = {(struct weston_surface *)malloc(sizeof(struct weston_surface))}; + l_surf[0]->resource = (struct wl_resource *)malloc(sizeof(struct wl_resource)); + SET_RETURN_SEQ(surface_get_weston_surface, l_surf, 1); + + keyboard_grab_modifiers(&mpp_ctxSeat[0]->keyboard_grab, 1, 1, 1, 1, 1); + + ASSERT_EQ(wl_resource_get_client_fake.call_count, 3); + + free(l_surf[0]->resource); + free(l_surf[0]); + free(mpp_ctxSeat[0]->keyboard_grab.keyboard); +} + +/** ================================================================================================ + * @test_id keyboard_grab_cancel_success + * @brief Test case of keyboard_grab_cancel() where surface_get_weston_surface() success, return an object + * and valid input params + * @test_procedure Steps: + * -# Set seat focus to enable {1} + * -# Mocking the surface_get_weston_surface() does return an object + * -# Set input ctxSeat + * -# Calling the keyboard_grab_cancel() + * -# Verification point: + * +# surface_get_weston_surface() must be called 2 times + * +# Free resources are allocated when running the test + */ +TEST_F(InputControllerTest, keyboard_grab_cancel_success) +{ + mpp_seatFocus[0]->focus = 1; + + struct weston_surface *l_surf[1] = {(struct weston_surface *)malloc(sizeof(struct weston_surface))}; + l_surf[0]->resource = (struct wl_resource *)malloc(sizeof(struct wl_resource)); + SET_RETURN_SEQ(surface_get_weston_surface, l_surf, 1); + + struct wl_resource l_wlResource; + mpp_ctxSeat[0]->keyboard_grab.keyboard = (struct weston_keyboard *)malloc(sizeof(struct weston_keyboard)); + custom_wl_list_init(&mpp_ctxSeat[0]->keyboard_grab.keyboard->focus_resource_list); + custom_wl_list_insert(&mpp_ctxSeat[0]->keyboard_grab.keyboard->focus_resource_list, &l_wlResource.link); + custom_wl_list_init(&mpp_ctxSeat[0]->keyboard_grab.keyboard->resource_list); + + keyboard_grab_cancel(&mpp_ctxSeat[0]->keyboard_grab); + + ASSERT_EQ(surface_get_weston_surface_fake.call_count, 2); + + free(l_surf[0]->resource); + free(l_surf[0]); + free(mpp_ctxSeat[0]->keyboard_grab.keyboard); +} + +/** ================================================================================================ + * @test_id pointer_grab_focus_wrongButtonCount + * @brief Test case of pointer_grab_focus() where input ctxSeat button_count is enable {1} + * @test_procedure Steps: + * -# Set input ctxSeat + * -# Calling the pointer_grab_focus() + * -# Verification point: + * +# surface_get_weston_surface() not be called + * +# Free resources are allocated when running the test + */ +TEST_F(InputControllerTest, pointer_grab_focus_wrongButtonCount) +{ + mpp_ctxSeat[0]->pointer_grab.pointer = (struct weston_pointer *)malloc(sizeof(struct weston_pointer)); + mpp_ctxSeat[0]->pointer_grab.pointer->button_count = 1; + + pointer_grab_focus(&mpp_ctxSeat[0]->pointer_grab); + + ASSERT_EQ(surface_get_weston_surface_fake.call_count, 0); + + free(mpp_ctxSeat[0]->pointer_grab.pointer); +} + +/** ================================================================================================ + * @test_id pointer_grab_focus_nullForcedPtr + * @brief Test case of pointer_grab_focus() where input ctxSeat button_count is disable {0} + * and forced_ptr_focus_surf is null pointer + * @test_procedure Steps: + * -# Set input ctxSeat (Do not set forced_ptr_focus_surf) + * -# Calling the pointer_grab_focus() + * -# Verification point: + * +# surface_get_weston_surface() not be called + * +# Free resources are allocated when running the test + */ +TEST_F(InputControllerTest, pointer_grab_focus_nullForcedPtr) +{ + mpp_ctxSeat[0]->pointer_grab.pointer = (struct weston_pointer *)malloc(sizeof(struct weston_pointer)); + mpp_ctxSeat[0]->pointer_grab.pointer->button_count = 0; + mpp_ctxSeat[0]->pointer_grab.pointer->seat = (struct weston_seat *)malloc(sizeof(struct weston_seat)); + mpp_ctxSeat[0]->pointer_grab.pointer->seat->compositor = (struct weston_compositor *)0xFFFFFFFF; + mpp_ctxSeat[0]->pointer_grab.pointer->focus = (struct weston_view *)malloc(sizeof(struct weston_view)); + mpp_ctxSeat[0]->pointer_grab.pointer->focus->surface = (struct weston_surface *)0xFFFFFFFF; + + pointer_grab_focus(&mpp_ctxSeat[0]->pointer_grab); + + ASSERT_EQ(surface_get_weston_surface_fake.call_count, 0); + + free(mpp_ctxSeat[0]->pointer_grab.pointer->seat); + free(mpp_ctxSeat[0]->pointer_grab.pointer->focus); + free(mpp_ctxSeat[0]->pointer_grab.pointer); +} + +/** ================================================================================================ + * @test_id pointer_grab_focus_surfNotEnabledAndNullFocus + * @brief Test case of pointer_grab_focus() where input ctxSeat button_count, forced_surf_enabled is disable {0} + * and forced_ptr_focus_surf is an object and pointer focus is null pointer + * @test_procedure Steps: + * -# Set input ctxSeat + * -# Mocking the surface_get_weston_surface() does return an object + * -# Calling the pointer_grab_focus() + * -# Verification point: + * +# surface_get_weston_surface() must be called once time + * +# weston_pointer_clear_focus() not be called + * +# Free resources are allocated when running the test + */ +TEST_F(InputControllerTest, pointer_grab_focus_surfNotEnabledAndNullFocus) +{ + mpp_ctxSeat[0]->pointer_grab.pointer = (struct weston_pointer *)malloc(sizeof(struct weston_pointer)); + mpp_ctxSeat[0]->pointer_grab.pointer->button_count = 0; + mpp_ctxSeat[0]->pointer_grab.pointer->focus = (struct weston_view *)0xFFFFFFFF; + mpp_ctxSeat[0]->forced_surf_enabled = ILM_FALSE; + struct ivisurface l_ivi_surf; + l_ivi_surf.layout_surface = (struct ivi_layout_surface *)0xFFFFFFFF; + mpp_ctxSeat[0]->forced_ptr_focus_surf = &l_ivi_surf; + mpp_ctxSeat[0]->pointer_grab.pointer->focus = {nullptr}; + + struct weston_surface *l_surf[1] = {(struct weston_surface *)0xFFFFFFFF}; + SET_RETURN_SEQ(surface_get_weston_surface, l_surf, 1); + + pointer_grab_focus(&mpp_ctxSeat[0]->pointer_grab); + + ASSERT_EQ(surface_get_weston_surface_fake.call_count, 1); + ASSERT_EQ(weston_pointer_clear_focus_fake.call_count, 0); + + free(mpp_ctxSeat[0]->pointer_grab.pointer); +} + +/** ================================================================================================ + * @test_id pointer_grab_focus_surfNotEnabled + * @brief Test case of pointer_grab_focus() where input ctxSeat button_count, forced_surf_enabled is disable {0} + * and forced_ptr_focus_surf, pointer focus is an object + * @test_procedure Steps: + * -# Set input ctxSeat + * -# Mocking the surface_get_weston_surface() does return an object + * -# Calling the pointer_grab_focus() + * -# Verification point: + * +# surface_get_weston_surface() must be called once time + * +# weston_pointer_clear_focus() must be called once time + * +# Free resources are allocated when running the test + */ +TEST_F(InputControllerTest, pointer_grab_focus_surfNotEnabled) +{ + mpp_ctxSeat[0]->pointer_grab.pointer = (struct weston_pointer *)malloc(sizeof(struct weston_pointer)); + mpp_ctxSeat[0]->pointer_grab.pointer->button_count = 0; + mpp_ctxSeat[0]->pointer_grab.pointer->focus = (struct weston_view *)0xFFFFFFFF; + mpp_ctxSeat[0]->forced_surf_enabled = ILM_FALSE; + struct ivisurface l_ivi_surf; + l_ivi_surf.layout_surface = (struct ivi_layout_surface *)0xFFFFFFFF; + mpp_ctxSeat[0]->forced_ptr_focus_surf = &l_ivi_surf; + mpp_ctxSeat[0]->pointer_grab.pointer->focus = (struct weston_view *)malloc(sizeof(struct weston_view)); + mpp_ctxSeat[0]->pointer_grab.pointer->focus->surface = (struct weston_surface *)0xFFFFFFFF; + + struct weston_surface *l_surf[1] = {(struct weston_surface *)0xFFFFFFFF}; + SET_RETURN_SEQ(surface_get_weston_surface, l_surf, 1); + + pointer_grab_focus(&mpp_ctxSeat[0]->pointer_grab); + + ASSERT_EQ(surface_get_weston_surface_fake.call_count, 1); + ASSERT_EQ(weston_pointer_clear_focus_fake.call_count, 1); + + free(mpp_ctxSeat[0]->pointer_grab.pointer->focus); + free(mpp_ctxSeat[0]->pointer_grab.pointer); +} + +/** ================================================================================================ + * @test_id pointer_grab_focus_nullSurfCtx + * @brief Test case of pointer_grab_focus() where input ctxSeat button_count is disable {0} + * and forced_surf_enabled is enable {1} and forced_ptr_focus_surf, pointer focus is an object + * @test_procedure Steps: + * -# Set input ctxSeat + * -# Mocking the surface_get_weston_surface() does return an object + * -# Calling the pointer_grab_focus() + * -# Verification point: + * +# surface_get_weston_surface() must be called once time + * +# weston_pointer_set_focus() must be called once time + * +# weston_pointer_clear_focus() not be called + * +# Free resources are allocated when running the test + */ +TEST_F(InputControllerTest, pointer_grab_focus_nullSurfCtx) +{ + mpp_ctxSeat[0]->pointer_grab.pointer = (struct weston_pointer *)malloc(sizeof(struct weston_pointer)); + mpp_ctxSeat[0]->pointer_grab.pointer->button_count = 0; + mpp_ctxSeat[0]->pointer_grab.pointer->focus = (struct weston_view *)0xFFFFFFFF; + mpp_ctxSeat[0]->forced_surf_enabled = ILM_TRUE; + struct ivisurface l_ivi_surf; + l_ivi_surf.layout_surface = (struct ivi_layout_surface *)0xFFFFFFFF; + mpp_ctxSeat[0]->forced_ptr_focus_surf = &l_ivi_surf; + mpp_ctxSeat[0]->pointer_grab.pointer->focus = (struct weston_view *)malloc(sizeof(struct weston_view)); + mpp_ctxSeat[0]->pointer_grab.pointer->focus->surface = (struct weston_surface *)0xFFFFFFFF; + + struct weston_surface *l_surf[1] = {(struct weston_surface *)malloc(sizeof(struct weston_surface))}; + custom_wl_list_init(&l_surf[0]->views); + SET_RETURN_SEQ(surface_get_weston_surface, l_surf, 1); + + pointer_grab_focus(&mpp_ctxSeat[0]->pointer_grab); + + ASSERT_EQ(surface_get_weston_surface_fake.call_count, 1); + ASSERT_EQ(weston_pointer_set_focus_fake.call_count, 1); + ASSERT_EQ(weston_pointer_clear_focus_fake.call_count, 0); + + free(l_surf[0]); + free(mpp_ctxSeat[0]->pointer_grab.pointer->focus); + free(mpp_ctxSeat[0]->pointer_grab.pointer); +} + +/** ================================================================================================ + * @test_id pointer_grab_focus_success + * @brief Test case of pointer_grab_focus() where input ctxSeat button_count is disable {0} + * and forced_surf_enabled is enable {1} and forced_ptr_focus_surf, pointer focus is an object + * and get_surface(), weston_surface_get_main_surface() are mocked to return an object + * @test_procedure Steps: + * -# Set input ctxSeat + * -# Mocking the get_surface() does return an object + * -# Mocking the surface_get_weston_surface() does return an object + * -# Mocking the weston_surface_get_main_surface() does return an object + * -# Calling the pointer_grab_focus() + * -# Verification point: + * +# surface_get_weston_surface() must be called once time + * +# weston_pointer_clear_focus() not be called + * +# Free resources are allocated when running the test + */ +TEST_F(InputControllerTest, pointer_grab_focus_success) +{ + wl_list_empty_fake.custom_fake = custom_wl_list_empty; + mpp_ctxSeat[0]->pointer_grab.pointer = (struct weston_pointer *)malloc(sizeof(struct weston_pointer)); + mpp_ctxSeat[0]->pointer_grab.pointer->button_count = 0; + mpp_ctxSeat[0]->pointer_grab.pointer->focus = (struct weston_view *)0xFFFFFFFF; + mpp_ctxSeat[0]->forced_surf_enabled = ILM_TRUE; + struct ivisurface l_ivi_surf; + l_ivi_surf.layout_surface = (struct ivi_layout_surface *)0xFFFFFFFF; + mpp_ctxSeat[0]->forced_ptr_focus_surf = &l_ivi_surf; + mpp_ctxSeat[0]->pointer_grab.pointer->focus = (struct weston_view *)malloc(sizeof(struct weston_view)); + mpp_ctxSeat[0]->pointer_grab.pointer->focus->surface = (struct weston_surface *)0xFFFFFFFF; + + struct ivi_layout_surface *l_layout_surf[1] = {mp_layoutSurface}; + SET_RETURN_SEQ(get_surface, l_layout_surf, 1); + + struct weston_surface *l_surf[1] = {(struct weston_surface *)malloc(sizeof(struct weston_surface))}; + custom_wl_list_init(&l_surf[0]->views); + SET_RETURN_SEQ(surface_get_weston_surface, l_surf, 1); + SET_RETURN_SEQ(weston_surface_get_main_surface, l_surf, 1); + + pointer_grab_focus(&mpp_ctxSeat[0]->pointer_grab); + + ASSERT_EQ(surface_get_weston_surface_fake.call_count, 1); + ASSERT_EQ(weston_pointer_clear_focus_fake.call_count, 0); + + free(l_surf[0]); + free(mpp_ctxSeat[0]->pointer_grab.pointer->focus); + free(mpp_ctxSeat[0]->pointer_grab.pointer); +} + +/** ================================================================================================ + * @test_id pointer_grab_motion_success + * @brief Test case of pointer_grab_motion() where valid input params + * @test_procedure Steps: + * -# Calling the pointer_grab_motion() with valid input params + * -# Verification point: + * +# weston_pointer_send_motion() must be called once time + */ +TEST_F(InputControllerTest, pointer_grab_motion_success) +{ + pointer_grab_motion(&mpp_ctxSeat[0]->pointer_grab, nullptr, nullptr); + ASSERT_EQ(weston_pointer_send_motion_fake.call_count, 1); +} + +/** ================================================================================================ + * @test_id pointer_grab_button_error + * @brief Test case of pointer_grab_button() where input ctxSeat button_count and state are enable {1} + * @test_procedure Steps: + * -# Set input ctxSeat with button_count is enable {1} + * -# Calling the pointer_grab_button() time 1 with state is 0 + * -# Set input ctxSeat with button_count is disable {0} + * -# Calling the pointer_grab_button() time 2 with state is 1 + * -# Verification point: + * +# focus() not be called + * +# weston_pointer_send_button() must be called + * +# Free resources are allocated when running the test + */ +TEST_F(InputControllerTest, pointer_grab_button_error) +{ + mpp_ctxSeat[0]->pointer_grab.pointer = (struct weston_pointer *)malloc(sizeof(struct weston_pointer)); + mpp_ctxSeat[0]->pointer_grab.pointer->button_count = 1; + + pointer_grab_button(&mpp_ctxSeat[0]->pointer_grab, nullptr, 0, 0); + + ASSERT_EQ(weston_pointer_send_button_fake.call_count, 1); + ASSERT_EQ(focus_fake.call_count, 0); + + mpp_ctxSeat[0]->pointer_grab.pointer->button_count = 0; + + pointer_grab_button(&mpp_ctxSeat[0]->pointer_grab, nullptr, 0, 1); + + ASSERT_EQ(weston_pointer_send_button_fake.call_count, 2); + ASSERT_EQ(focus_fake.call_count, 0); + + free(mpp_ctxSeat[0]->pointer_grab.pointer); +} + +/** ================================================================================================ + * @test_id pointer_grab_button_success + * @brief Test case of pointer_grab_button() where input ctxSeat button_count and state are disable {0} + * @test_procedure Steps: + * -# Set input ctxSeat with button_count is disable {0} + * -# Calling the pointer_grab_button() with state is 0 + * -# Verification point: + * +# weston_pointer_send_button() must be called once time + * +# focus() must be called once time + * +# Free resources are allocated when running the test + */ +TEST_F(InputControllerTest, pointer_grab_button_success) +{ + mpp_ctxSeat[0]->pointer_grab.pointer = (struct weston_pointer *)malloc(sizeof(struct weston_pointer)); + mpp_ctxSeat[0]->pointer_grab.pointer->button_count = 0; + + pointer_grab_button(&mpp_ctxSeat[0]->pointer_grab, nullptr, 0, 0); + + ASSERT_EQ(weston_pointer_send_button_fake.call_count, 1); + ASSERT_EQ(focus_fake.call_count, 1); + + free(mpp_ctxSeat[0]->pointer_grab.pointer); +} + +/** ================================================================================================ + * @test_id pointer_grab_axis_success + * @brief Test case of pointer_grab_axis() where input ctxSeat button_count is disable {0} + * @test_procedure Steps: + * -# Set input ctxSeat with button_count is disable {0} + * -# Calling the pointer_grab_axis() + * -# Verification point: + * +# weston_pointer_send_axis() must be called once time + * +# Free resources are allocated when running the test + */ +TEST_F(InputControllerTest, pointer_grab_axis_success) +{ + mpp_ctxSeat[0]->pointer_grab.pointer = (struct weston_pointer *)malloc(sizeof(struct weston_pointer)); + mpp_ctxSeat[0]->pointer_grab.pointer->button_count = 0; + + pointer_grab_axis(&mpp_ctxSeat[0]->pointer_grab, nullptr, nullptr); + + ASSERT_EQ(weston_pointer_send_axis_fake.call_count, 1); + + free(mpp_ctxSeat[0]->pointer_grab.pointer); +} + +/** ================================================================================================ + * @test_id pointer_grab_axis_source_success + * @brief Test case of pointer_grab_axis_source() where input ctxSeat button_count is disable {0} + * @test_procedure Steps: + * -# Set input ctxSeat with button_count is disable {0} + * -# Calling the pointer_grab_axis_source() + * -# Verification point: + * +# weston_pointer_send_axis_source() must be called once time + * +# Free resources are allocated when running the test + */ +TEST_F(InputControllerTest, pointer_grab_axis_source_success) +{ + mpp_ctxSeat[0]->pointer_grab.pointer = (struct weston_pointer *)malloc(sizeof(struct weston_pointer)); + mpp_ctxSeat[0]->pointer_grab.pointer->button_count = 0; + + pointer_grab_axis_source(&mpp_ctxSeat[0]->pointer_grab, 0); + + ASSERT_EQ(weston_pointer_send_axis_source_fake.call_count, 1); + + free(mpp_ctxSeat[0]->pointer_grab.pointer); +} + +/** ================================================================================================ + * @test_id pointer_grab_frame_success + * @brief Test case of pointer_grab_frame() where input ctxSeat button_count is disable {0} + * @test_procedure Steps: + * -# Set input ctxSeat with button_count is disable {0} + * -# Calling the pointer_grab_frame() + * -# Verification point: + * +# weston_pointer_send_frame() must be called once time + * +# Free resources are allocated when running the test + */ +TEST_F(InputControllerTest, pointer_grab_frame_success) +{ + mpp_ctxSeat[0]->pointer_grab.pointer = (struct weston_pointer *)malloc(sizeof(struct weston_pointer)); + mpp_ctxSeat[0]->pointer_grab.pointer->button_count = 0; + + pointer_grab_frame(&mpp_ctxSeat[0]->pointer_grab); + + ASSERT_EQ(weston_pointer_send_frame_fake.call_count, 1); + + free(mpp_ctxSeat[0]->pointer_grab.pointer); +} + +/** ================================================================================================ + * @test_id pointer_grab_cancel_success + * @brief Test case of pointer_grab_cancel() where input ctxSeat button_count is disable {0} + * @test_procedure Steps: + * -# Set input ctxSeat with button_count is disable {0} + * -# Calling the pointer_grab_cancel() + * -# Verification point: + * +# weston_pointer_clear_focus() must be called once time + * +# Free resources are allocated when running the test + */ +TEST_F(InputControllerTest, pointer_grab_cancel_success) +{ + mpp_ctxSeat[0]->pointer_grab.pointer = (struct weston_pointer *)malloc(sizeof(struct weston_pointer)); + mpp_ctxSeat[0]->pointer_grab.pointer->button_count = 0; + mpp_ctxSeat[0]->pointer_grab.pointer->focus = (struct weston_view *)malloc(sizeof(struct weston_view)); + mpp_ctxSeat[0]->pointer_grab.pointer->focus->surface = (struct weston_surface *)0xFFFFFFFF; + + pointer_grab_cancel(&mpp_ctxSeat[0]->pointer_grab); + + ASSERT_EQ(weston_pointer_clear_focus_fake.call_count, 1); + + free(mpp_ctxSeat[0]->pointer_grab.pointer->focus); + free(mpp_ctxSeat[0]->pointer_grab.pointer); +} + +/** ================================================================================================ + * @test_id touch_grab_down_nullFocus + * @brief Test case of touch_grab_down() where input ctxSeat focus is null pointer + * @test_procedure Steps: + * -# Set input ctxSeat with focus is null pointer + * -# Calling the touch_grab_down() + * -# Verification point: + * +# weston_surface_get_main_surface() not be called + * +# Free resources are allocated when running the test + */ +TEST_F(InputControllerTest, touch_grab_down_nullFocus) +{ + mpp_ctxSeat[0]->touch_grab.touch = (struct weston_touch *)malloc(sizeof(struct weston_touch)); + mpp_ctxSeat[0]->touch_grab.touch->focus = nullptr; + + touch_grab_down(&mpp_ctxSeat[0]->touch_grab, nullptr, 0, 0, 0); + + ASSERT_EQ(weston_surface_get_main_surface_fake.call_count, 0); + + free(mpp_ctxSeat[0]->touch_grab.touch); +} + +/** ================================================================================================ + * @test_id touch_grab_down_nullSurfCtx + * @brief Test case of touch_grab_down() where weston_surface_get_main_surface() fails, return null object + * @test_procedure Steps: + * -# Set input ctxSeat + * -# Calling the touch_grab_down() + * -# Verification point: + * +# weston_surface_get_main_surface() must be called once time + * +# weston_touch_send_down() must be called once time + * +# Free resources are allocated when running the test + */ +TEST_F(InputControllerTest, touch_grab_down_nullSurfCtx) +{ + mpp_ctxSeat[0]->touch_grab.touch = (struct weston_touch *)malloc(sizeof(struct weston_touch)); + mpp_ctxSeat[0]->touch_grab.touch->focus = (struct weston_view *)malloc(sizeof(struct weston_view)); + mpp_ctxSeat[0]->touch_grab.touch->focus->surface = (struct weston_surface *)0xFFFFFFFF; + + touch_grab_down(&mpp_ctxSeat[0]->touch_grab, nullptr, 0, 0, 0); + + ASSERT_EQ(weston_surface_get_main_surface_fake.call_count, 1); + ASSERT_EQ(weston_touch_send_down_fake.call_count, 1); + + free(mpp_ctxSeat[0]->touch_grab.touch->focus); + free(mpp_ctxSeat[0]->touch_grab.touch); +} + +/** ================================================================================================ + * @test_id touch_grab_down_wrongNumTp + * @brief Test case of touch_grab_down() where weston_surface_get_main_surface() success, return an object + * and input ctxSeat num_tp is disable {0} + * @test_procedure Steps: + * -# Mocking the get_surface() does return an object + * -# Mocking the weston_surface_get_main_surface() does return an object + * -# Set input ctxSeat + * -# Calling the touch_grab_down() + * -# Verification point: + * +# weston_surface_get_main_surface() must be called once time + * +# weston_touch_send_down() must be called once time + * +# get_id_of_surface() not be called + * +# Free resources are allocated when running the test + */ +TEST_F(InputControllerTest, touch_grab_down_wrongNumTp) +{ + g_iviLayoutInterfaceFake.get_surface = get_surface; + struct ivi_layout_surface *l_layout_surf[1] = {mp_layoutSurface}; + SET_RETURN_SEQ(get_surface, l_layout_surf, 1); + + struct weston_surface *l_surf[1] = {(struct weston_surface *)malloc(sizeof(struct weston_surface))}; + SET_RETURN_SEQ(weston_surface_get_main_surface, l_surf, 1); + + mpp_ctxSeat[0]->touch_grab.touch = (struct weston_touch *)malloc(sizeof(struct weston_touch)); + mpp_ctxSeat[0]->touch_grab.touch->focus = (struct weston_view *)malloc(sizeof(struct weston_view)); + mpp_ctxSeat[0]->touch_grab.touch->focus->surface = (struct weston_surface *)0xFFFFFFFF; + mpp_ctxSeat[0]->touch_grab.touch->num_tp = 0; + + touch_grab_down(&mpp_ctxSeat[0]->touch_grab, nullptr, 0, 0, 0); + + ASSERT_EQ(weston_surface_get_main_surface_fake.call_count, 1); + ASSERT_EQ(weston_touch_send_down_fake.call_count, 1); + ASSERT_EQ(get_id_of_surface_fake.call_count, 0); + + free(l_surf[0]); + free(mpp_ctxSeat[0]->touch_grab.touch->focus); + free(mpp_ctxSeat[0]->touch_grab.touch); +} + +/** ================================================================================================ + * @test_id touch_grab_down_success + * @brief Test case of touch_grab_down() where weston_surface_get_main_surface() success, return an object + * and input ctxSeat num_tp is enable {1} + * @test_procedure Steps: + * -# Mocking the get_surface() does return an object + * -# Mocking the weston_surface_get_main_surface() does return an object + * -# Set input ctxSeat + * -# Calling the touch_grab_down() + * -# Verification point: + * +# weston_surface_get_main_surface() must be called once time + * +# weston_touch_send_down() must be called once time + * +# get_id_of_surface() not be called + * +# Free resources are allocated when running the test + */ +TEST_F(InputControllerTest, touch_grab_down_success) +{ + g_iviLayoutInterfaceFake.get_surface = get_surface; + struct ivi_layout_surface *l_layout_surf[1] = {mp_layoutSurface}; + SET_RETURN_SEQ(get_surface, l_layout_surf, 1); + + struct weston_surface *l_surf[1] = {(struct weston_surface *)malloc(sizeof(struct weston_surface))}; + SET_RETURN_SEQ(weston_surface_get_main_surface, l_surf, 1); + + mpp_ctxSeat[0]->touch_grab.touch = (struct weston_touch *)malloc(sizeof(struct weston_touch)); + mpp_ctxSeat[0]->touch_grab.touch->focus = (struct weston_view *)malloc(sizeof(struct weston_view)); + mpp_ctxSeat[0]->touch_grab.touch->focus->surface = (struct weston_surface *)0xFFFFFFFF; + mpp_ctxSeat[0]->touch_grab.touch->num_tp = 1; + + touch_grab_down(&mpp_ctxSeat[0]->touch_grab, nullptr, 0, 0, 0); + + ASSERT_EQ(weston_surface_get_main_surface_fake.call_count, 1); + ASSERT_EQ(weston_touch_send_down_fake.call_count, 1); + ASSERT_EQ(get_id_of_surface_fake.call_count, 1); + + free(l_surf[0]); + free(mpp_ctxSeat[0]->touch_grab.touch->focus); + free(mpp_ctxSeat[0]->touch_grab.touch); +} + +/** ================================================================================================ + * @test_id touch_grab_up_nullFocus + * @brief Test case of touch_grab_up() where input ctxSeat focus is null pointer + * @test_procedure Steps: + * -# Set input ctxSeat with focus is null pointer + * -# Calling the touch_grab_up() + * -# Verification point: + * +# weston_touch_send_up() not be called + * +# Free resources are allocated when running the test + */ +TEST_F(InputControllerTest, touch_grab_up_nullFocus) +{ + mpp_ctxSeat[0]->touch_grab.touch = (struct weston_touch *)malloc(sizeof(struct weston_touch)); + mpp_ctxSeat[0]->touch_grab.touch->focus = nullptr; + + touch_grab_up(&mpp_ctxSeat[0]->touch_grab, nullptr, 0); + + ASSERT_EQ(weston_touch_send_up_fake.call_count, 0); + + free(mpp_ctxSeat[0]->touch_grab.touch); +} + +/** ================================================================================================ + * @test_id touch_grab_up_wrongNumTp + * @brief Test case of touch_grab_up() where input ctxSeat num_tp is enable {1} + * @test_procedure Steps: + * -# Set input ctxSeat + * -# Calling the touch_grab_up() + * -# Verification point: + * +# weston_touch_send_up() must be called once time + * +# get_id_of_surface() not be called + * +# Free resources are allocated when running the test + */ +TEST_F(InputControllerTest, touch_grab_up_wrongNumTp) +{ + mpp_ctxSeat[0]->touch_grab.touch = (struct weston_touch *)malloc(sizeof(struct weston_touch)); + mpp_ctxSeat[0]->touch_grab.touch->focus = (struct weston_view *)0xFFFFFFFF; + mpp_ctxSeat[0]->touch_grab.touch->num_tp = 1; + + touch_grab_up(&mpp_ctxSeat[0]->touch_grab, nullptr, 0); + + ASSERT_EQ(weston_touch_send_up_fake.call_count, 1); + ASSERT_EQ(get_id_of_surface_fake.call_count, 0); + + free(mpp_ctxSeat[0]->touch_grab.touch); +} + +/** ================================================================================================ + * @test_id touch_grab_up_success + * @brief Test case of touch_grab_up() where weston_surface_get_main_surface() success, return an object + * and input ctxSeat num_tp is disable {0} + * @test_procedure Steps: + * -# Set input ctxSeat + * -# Mocking the get_surface() does return an object + * -# Mocking the weston_surface_get_main_surface() does return an object + * -# Calling the touch_grab_up() + * -# Verification point: + * +# weston_touch_send_up() must be called once time + * +# get_id_of_surface() must be called once time + * +# Free resources are allocated when running the test + */ +TEST_F(InputControllerTest, touch_grab_up_success) +{ + mpp_ctxSeat[0]->touch_grab.touch = (struct weston_touch *)malloc(sizeof(struct weston_touch)); + mpp_ctxSeat[0]->touch_grab.touch->focus = (struct weston_view *)malloc(sizeof(struct weston_view)); + mpp_ctxSeat[0]->touch_grab.touch->focus->surface = (struct weston_surface *)0xFFFFFFFF; + mpp_ctxSeat[0]->touch_grab.touch->num_tp = 0; + + struct ivi_layout_surface *l_layout_surf[1] = {mp_layoutSurface}; + SET_RETURN_SEQ(get_surface, l_layout_surf, 1); + + struct weston_surface *l_surf[1] = {(struct weston_surface *)malloc(sizeof(struct weston_surface))}; + SET_RETURN_SEQ(weston_surface_get_main_surface, l_surf, 1); + + touch_grab_up(&mpp_ctxSeat[0]->touch_grab, nullptr, 0); + + ASSERT_EQ(weston_touch_send_up_fake.call_count, 1); + ASSERT_EQ(get_id_of_surface_fake.call_count, 1); + + free(l_surf[0]); + free(mpp_ctxSeat[0]->touch_grab.touch->focus); + free(mpp_ctxSeat[0]->touch_grab.touch); +} + +/** ================================================================================================ + * @test_id touch_grab_motion_success + * @brief Test case of touch_grab_motion() where valid input params + * @test_procedure Steps: + * -# Calling the touch_grab_motion() + * -# Verification point: + * +# weston_touch_send_motion() must be called once time + */ +TEST_F(InputControllerTest, touch_grab_motion_success) +{ + touch_grab_motion(&mpp_ctxSeat[0]->touch_grab, nullptr, 0, 0, 0); + ASSERT_EQ(weston_touch_send_motion_fake.call_count, 1); +} + +/** ================================================================================================ + * @test_id touch_grab_frame_success + * @brief Test case of touch_grab_frame() where valid input params + * @test_procedure Steps: + * -# Calling the touch_grab_frame() + * -# Verification point: + * +# weston_touch_send_frame() must be called once time + */ +TEST_F(InputControllerTest, touch_grab_frame_success) +{ + touch_grab_frame(&mpp_ctxSeat[0]->touch_grab); + ASSERT_EQ(weston_touch_send_frame_fake.call_count, 1); +} + +/** ================================================================================================ + * @test_id touch_grab_cancel_success + * @brief Test case of touch_grab_cancel() where valid input params + * @test_procedure Steps: + * -# Set input ctxSeat + * -# Calling the touch_grab_cancel() + * -# Verification point: + * +# weston_touch_set_focus() must be called once time + * +# Free resources are allocated when running the test + */ +TEST_F(InputControllerTest, touch_grab_cancel_success) +{ + mpp_ctxSeat[0]->touch_grab.touch = (struct weston_touch *)malloc(sizeof(struct weston_touch)); + mpp_ctxSeat[0]->touch_grab.touch->focus = (struct weston_view *)malloc(sizeof(struct weston_view)); + mpp_ctxSeat[0]->touch_grab.touch->focus->surface = (struct weston_surface *)0xFFFFFFFF; + custom_wl_list_init(&mpp_ctxSeat[0]->touch_grab.touch->focus_resource_list); + + touch_grab_cancel(&mpp_ctxSeat[0]->touch_grab); + + ASSERT_EQ(weston_touch_set_focus_fake.call_count, 1); + + free(mpp_ctxSeat[0]->touch_grab.touch->focus); + free(mpp_ctxSeat[0]->touch_grab.touch); +} + +/** ================================================================================================ + * @test_id input_set_input_focus_nullSurface + * @brief Test case of setup_input_focus() where get_surface_from_id() fails, return null object + * @test_procedure Steps: + * -# Mocking the wl_resource_get_user_data() does return an object + * -# Calling the setup_input_focus() + * -# Verification point: + * +# get_surface_from_id() must be called once time + */ +TEST_F(InputControllerTest, input_set_input_focus_nullSurface) +{ + struct input_context *l_input[1] = {mp_ctxInput}; + SET_RETURN_SEQ(wl_resource_get_user_data, (void**)l_input, 1); + + setup_input_focus(mp_ctxInput, 10, 1, ILM_TRUE); + + ASSERT_EQ(get_surface_from_id_fake.call_count, 1); +} + +/** ================================================================================================ + * @test_id input_set_input_focus_wrongDevice + * @brief Test case of setup_input_focus() where get_surface_from_id() success, return an object + * and input device not focus anything + * @test_procedure Steps: + * -# Mocking the wl_resource_get_user_data() does return an object + * -# Mocking the get_surface_from_id() does return an object + * -# Calling the setup_input_focus() with input device is 0 + * -# Verification point: + * +# get_surface_from_id() must be called once time + */ +TEST_F(InputControllerTest, input_set_input_focus_wrongDevice) +{ + struct input_context *l_input[1] = {mp_ctxInput}; + SET_RETURN_SEQ(wl_resource_get_user_data, (void**)l_input, 1); + + struct ivi_layout_surface *l_surface[1] = {mp_layoutSurface}; + SET_RETURN_SEQ(get_surface_from_id, l_surface, 1); + + setup_input_focus(mp_ctxInput, 10, 0, 1); + + ASSERT_EQ(get_surface_from_id_fake.call_count, 1); +} + +/** ================================================================================================ + * @test_id input_set_input_focus_toKeyBoardWithNullKeyBoard + * @brief Test case of setup_input_focus() where weston_seat_get_keyboard() fails, return null pointer + * and input device focus to keyboard + * @test_procedure Steps: + * -# Mocking the wl_resource_get_user_data() does return an object + * -# Mocking the get_surface_from_id() does return an object + * -# Calling the setup_input_focus() with input device is 1 + * -# Verification point: + * +# get_surface_from_id() must be called once time + * +# weston_seat_get_keyboard() must be called once time + */ +TEST_F(InputControllerTest, input_set_input_focus_toKeyBoardWithNullKeyBoard) +{ + struct input_context *l_input[1] = {mp_ctxInput}; + SET_RETURN_SEQ(wl_resource_get_user_data, (void**)l_input, 1); + + struct ivi_layout_surface *l_surface[1] = {mp_layoutSurface}; + SET_RETURN_SEQ(get_surface_from_id, l_surface, 1); + + setup_input_focus(mp_ctxInput, 10, 1, 1); + + ASSERT_EQ(get_surface_from_id_fake.call_count, 1); + ASSERT_EQ(weston_seat_get_keyboard_fake.call_count, 1); +} + +/** ================================================================================================ + * @test_id input_set_input_focus_toKeyBoardWithOneKeyBoardAndNotEnabled + * @brief Test case of setup_input_focus() where weston_seat_get_keyboard() success, return an pointer + * and input device focus to keyboard and input enabled is disable {0} + * @test_procedure Steps: + * -# Mocking the wl_resource_get_user_data() does return an object + * -# Mocking the get_surface_from_id() does return an object + * -# Mocking the weston_seat_get_keyboard() does return an object + * -# Calling the setup_input_focus() with input enabled is 0 + * -# Verification point: + * +# get_surface_from_id() must be called once time + * +# weston_seat_get_keyboard() must be called once time + */ +TEST_F(InputControllerTest, input_set_input_focus_toKeyBoardWithOneKeyBoardAndNotEnabled) +{ + struct input_context *l_input[1] = {mp_ctxInput}; + SET_RETURN_SEQ(wl_resource_get_user_data, (void**)l_input, 1); + + struct ivi_layout_surface *l_surface[1] = {mp_layoutSurface}; + SET_RETURN_SEQ(get_surface_from_id, l_surface, 1); + + struct weston_keyboard *l_keyboard[1] = {(struct weston_keyboard *)0xFFFFFFFF}; + SET_RETURN_SEQ(weston_seat_get_keyboard, l_keyboard, 1); + + setup_input_focus(mp_ctxInput, 10, 1, 0); + + ASSERT_EQ(get_surface_from_id_fake.call_count, 1); + ASSERT_EQ(weston_seat_get_keyboard_fake.call_count, 1); +} + +/** ================================================================================================ + * @test_id input_set_input_focus_toKeyBoardWithOneKeyBoardAndEnabled + * @brief Test case of setup_input_focus() where weston_seat_get_keyboard() success, return an pointer + * and input device focus to keyboard and input enabled is enable {1} + * @test_procedure Steps: + * -# Set input ctxSeat + * -# Mocking the wl_resource_get_user_data() does return an object + * -# Mocking the get_surface_from_id() does return an object + * -# Mocking the weston_seat_get_keyboard() does return an object + * -# Mocking the surface_get_weston_surface() does return an object + * -# Mocking the wl_resource_get_version() does return an object + * -# Calling the setup_input_focus() with input enabled is 1 + * -# Verification point: + * +# get_surface_from_id() must be called once time + * +# weston_seat_get_keyboard() must be called once time + * +# Free resources are allocated when running the test + */ +TEST_F(InputControllerTest, input_set_input_focus_toKeyBoardWithOneKeyBoardAndEnabled) +{ + struct wl_resource l_wlResource; + mpp_ctxSeat[0]->keyboard_grab.keyboard = (struct weston_keyboard *)malloc(sizeof(struct weston_keyboard)); + mpp_ctxSeat[0]->keyboard_grab.keyboard->seat = (struct weston_seat *)malloc(sizeof(struct weston_seat)); + mp_westonSeat[0].compositor = (struct weston_compositor *)malloc(sizeof(struct weston_compositor)); + mp_westonSeat[0].compositor->kb_repeat_rate = 0; + mp_westonSeat[0].compositor->kb_repeat_delay = 0; + custom_wl_list_init(&mpp_ctxSeat[0]->keyboard_grab.keyboard->focus_resource_list); + custom_wl_list_insert(&mpp_ctxSeat[0]->keyboard_grab.keyboard->focus_resource_list, &l_wlResource.link); + custom_wl_list_init(&mpp_ctxSeat[0]->keyboard_grab.keyboard->resource_list); + + struct input_context *l_input[1] = {mp_ctxInput}; + SET_RETURN_SEQ(wl_resource_get_user_data, (void**)l_input, 1); + + struct ivi_layout_surface *l_surface[1] = {mp_layoutSurface}; + SET_RETURN_SEQ(get_surface_from_id, l_surface, 1); + + struct weston_keyboard *l_keyboard[1] = {(struct weston_keyboard *)0xFFFFFFFF}; + SET_RETURN_SEQ(weston_seat_get_keyboard, l_keyboard, 1); + + struct weston_surface *l_weston_surfaces[1] = {(struct weston_surface *)malloc(sizeof(struct weston_surface))}; + SET_RETURN_SEQ(surface_get_weston_surface, l_weston_surfaces, 1); + + int l_num[1] = {WL_KEYBOARD_REPEAT_INFO_SINCE_VERSION}; + SET_RETURN_SEQ(wl_resource_get_version, l_num, 1); + + setup_input_focus(mp_ctxInput, 10, 1, 1); + + ASSERT_EQ(get_surface_from_id_fake.call_count, 1); + ASSERT_EQ(weston_seat_get_keyboard_fake.call_count, 1); + + free(l_weston_surfaces[0]); + free(mp_westonSeat[0].compositor); + free(mpp_ctxSeat[0]->keyboard_grab.keyboard->seat); + free(mpp_ctxSeat[0]->keyboard_grab.keyboard); +} + +/** ================================================================================================ + * @test_id input_set_input_focus_toPointerWithNullPointer + * @brief Test case of setup_input_focus() where weston_seat_get_pointer() fails, return null pointer + * and input device focus to pointer + * @test_procedure Steps: + * -# Mocking the wl_resource_get_user_data() does return an object + * -# Mocking the get_surface_from_id() does return an object + * -# Calling the setup_input_focus() with input enabled is 1 + * -# Verification point: + * +# get_surface_from_id() must be called once time + * +# weston_seat_get_pointer() must be called once time + */ +TEST_F(InputControllerTest, input_set_input_focus_toPointerWithNullPointer) +{ + struct input_context *l_input[1] = {mp_ctxInput}; + SET_RETURN_SEQ(wl_resource_get_user_data, (void**)l_input, 1); + + struct ivi_layout_surface *l_surface[1] = {mp_layoutSurface}; + SET_RETURN_SEQ(get_surface_from_id, l_surface, 1); + + setup_input_focus(mp_ctxInput, 10, 2, 1); + + ASSERT_EQ(get_surface_from_id_fake.call_count, 1); + ASSERT_EQ(weston_seat_get_pointer_fake.call_count, 1); +} + +/** ================================================================================================ + * @test_id input_set_input_focus_toPointerWithOnePointerAndNotEnabled + * @brief Test case of setup_input_focus() where weston_seat_get_pointer() success, return an pointer + * and input device focus to pointer and input enabled is disable {0} + * @test_procedure Steps: + * -# Mocking the wl_resource_get_user_data() does return an object + * -# Mocking the get_surface_from_id() does return an object + * -# Mocking the weston_seat_get_pointer() does return an object + * -# Calling the setup_input_focus() with input enabled is 0 + * -# Verification point: + * +# get_surface_from_id() must be called once time + * +# weston_seat_get_pointer() must be called once time + */ +TEST_F(InputControllerTest, input_set_input_focus_toPointerWithOnePointerAndNotEnabled) +{ + struct input_context *l_input[1] = {mp_ctxInput}; + SET_RETURN_SEQ(wl_resource_get_user_data, (void**)l_input, 1); + + struct ivi_layout_surface *l_surface[1] = {mp_layoutSurface}; + SET_RETURN_SEQ(get_surface_from_id, l_surface, 1); + + struct weston_pointer *l_ptr[1] = {(struct weston_pointer *)0xFFFFFFFF}; + SET_RETURN_SEQ(weston_seat_get_pointer, l_ptr, 1); + + setup_input_focus(mp_ctxInput, 10, 2, 0); + + ASSERT_EQ(get_surface_from_id_fake.call_count, 1); + ASSERT_EQ(weston_seat_get_pointer_fake.call_count, 1); +} + +/** ================================================================================================ + * @test_id input_set_input_focus_toPointerWithOnePointerAndEnabled + * @brief Test case of setup_input_focus() where weston_seat_get_pointer() success, return an pointer + * and input device focus to pointer and input enabled is enable {1} + * @test_procedure Steps: + * -# Mocking the wl_resource_get_user_data() does return an object + * -# Mocking the get_surface_from_id() does return an object + * -# Mocking the weston_seat_get_pointer() does return an object + * -# Calling the setup_input_focus() with input enabled is 1 + * -# Verification point: + * +# get_surface_from_id() must be called once time + * +# weston_seat_get_pointer() must be called once time + */ +TEST_F(InputControllerTest, input_set_input_focus_toPointerWithOnePointerAndEnabled) +{ + struct input_context *l_input[1] = {mp_ctxInput}; + SET_RETURN_SEQ(wl_resource_get_user_data, (void**)l_input, 1); + + struct ivi_layout_surface *l_surface[1] = {mp_layoutSurface}; + SET_RETURN_SEQ(get_surface_from_id, l_surface, 1); + + struct weston_pointer *l_ptr[1] = {(struct weston_pointer *)0xFFFFFFFF}; + SET_RETURN_SEQ(weston_seat_get_pointer, l_ptr, 1); + + setup_input_focus(mp_ctxInput, 10, 2, 1); + + ASSERT_EQ(get_surface_from_id_fake.call_count, 1); + ASSERT_EQ(weston_seat_get_pointer_fake.call_count, 1); +} + +/** ================================================================================================ + * @test_id input_set_input_focus_toTouch + * @brief Test case of setup_input_focus() where input device focus to touch + * and input enabled is enable {1} + * @test_procedure Steps: + * -# Mocking the wl_resource_get_user_data() does return an object + * -# Mocking the get_surface_from_id() does return an object + * -# Calling the setup_input_focus() with input enabled is 1 + * -# Verification point: + * +# get_surface_from_id() must be called once time + * +# wl_resource_post_event() must be called 2 times + */ +TEST_F(InputControllerTest, input_set_input_focus_toTouch) +{ + struct input_context *l_input[1] = {mp_ctxInput}; + SET_RETURN_SEQ(wl_resource_get_user_data, (void**)l_input, 1); + + struct ivi_layout_surface *l_surface[1] = {mp_layoutSurface}; + SET_RETURN_SEQ(get_surface_from_id, l_surface, 1); + + setup_input_focus(mp_ctxInput, 10, 4, 1); + + ASSERT_EQ(get_surface_from_id_fake.call_count, 1); + ASSERT_EQ(wl_resource_post_event_fake.call_count, 2); +} + +/** ================================================================================================ + * @test_id input_set_input_acceptance_wrongSeatName + * @brief Test case of setup_input_acceptance() where input seat name is null + * @test_procedure Steps: + * -# Mocking the wl_resource_get_user_data() does return an object + * -# Calling the setup_input_acceptance() + * -# Verification point: + * +# get_surface_from_id() not be called + */ +TEST_F(InputControllerTest, input_set_input_acceptance_wrongSeatName) +{ + struct input_context *l_input[1] = {mp_ctxInput}; + SET_RETURN_SEQ(wl_resource_get_user_data, (void**)l_input, 1); + + setup_input_acceptance(mp_ctxInput, 10, "", 1); + + ASSERT_EQ(get_surface_from_id_fake.call_count, 0); +} + +/** ================================================================================================ + * @test_id input_set_input_acceptance_nullSurface + * @brief Test case of setup_input_acceptance() where get_surface_from_id() fails, return null pointer + * @test_procedure Steps: + * -# Mocking the wl_resource_get_user_data() does return an object + * -# Calling the setup_input_acceptance() with valid seat name + * -# Verification point: + * +# wl_resource_get_user_data() must be called once time + * +# get_surface_from_id() must be called once time + * +# weston_seat_get_pointer() not be called + * +# wl_resource_post_event() not be called + */ +TEST_F(InputControllerTest, input_set_input_acceptance_nullSurface) +{ + struct input_context *l_input[1] = {mp_ctxInput}; + SET_RETURN_SEQ(wl_resource_get_user_data, (void**)l_input, 1); + + setup_input_acceptance(mp_ctxInput, 10, "default", 1); + + ASSERT_EQ(get_surface_from_id_fake.call_count, 1); + ASSERT_EQ(weston_seat_get_pointer_fake.call_count, 0); + ASSERT_EQ(wl_resource_post_event_fake.call_count, 0); +} + +/** ================================================================================================ + * @test_id input_set_input_acceptance_withValidPointerAndUnapccepted + * @brief Test case of setup_input_acceptance() where valid ctxSeat pointer + * and input accepted is disable {0} + * @test_procedure Steps: + * -# Set input ctxSeat + * -# Mocking the weston_seat_get_keyboard() does return an object + * -# Mocking the weston_seat_get_pointer() does return an object + * -# Mocking the weston_seat_get_touch() does return an object + * -# Mocking the wl_resource_get_user_data() does return an object + * -# Mocking the get_surface_from_id() does return an object + * -# Calling the setup_input_acceptance() with input accepted is 0 + * -# Verification point: + * +# get_surface_from_id() must be called once time + * +# weston_seat_get_pointer() must be called once time + * +# surface_get_weston_surface() must be called once time + * +# Free resources are allocated when running the test + * +# Allocate memory for resources are freed when running the test + */ +TEST_F(InputControllerTest, input_set_input_acceptance_withValidPointerAndUnapccepted) +{ + mpp_ctxSeat[0]->pointer_grab.pointer = (struct weston_pointer *)malloc(sizeof(struct weston_pointer)); + mpp_ctxSeat[0]->pointer_grab.pointer->focus = (struct weston_view *)malloc(sizeof(struct weston_view)); + + struct weston_keyboard *lpp_keyboard [] = {(struct weston_keyboard *)0xFFFFFFFF}; + struct weston_pointer *lpp_pointer [] = {(struct weston_pointer *)0xFFFFFFFF}; + struct weston_touch *lpp_touch [] = {(struct weston_touch *)0xFFFFFFFF}; + SET_RETURN_SEQ(weston_seat_get_keyboard, lpp_keyboard, 1); + SET_RETURN_SEQ(weston_seat_get_pointer, lpp_pointer, 1); + SET_RETURN_SEQ(weston_seat_get_touch, lpp_touch, 1); + + struct input_context *l_input[1] = {mp_ctxInput}; + SET_RETURN_SEQ(wl_resource_get_user_data, (void**)l_input, 1); + + struct ivi_layout_surface *l_surface[1] = {mp_layoutSurface}; + SET_RETURN_SEQ(get_surface_from_id, l_surface, 1); + + setup_input_acceptance(mp_ctxInput, 10, "default", 0); + + ASSERT_EQ(get_surface_from_id_fake.call_count, 1); + ASSERT_EQ(weston_seat_get_pointer_fake.call_count, 1); + ASSERT_EQ(surface_get_weston_surface_fake.call_count, 1); + + free(mpp_ctxSeat[0]->pointer_grab.pointer->focus); + free(mpp_ctxSeat[0]->pointer_grab.pointer); + + mpp_seatFocus[0] = (struct seat_focus*)calloc(1, sizeof(struct seat_focus)); +} + +/** ================================================================================================ + * @test_id input_set_input_acceptance_withValidPointerAndApccepted + * @brief Test case of setup_input_acceptance() where valid ctxSeat pointer + * and input accepted is enable {1} + * @test_procedure Steps: + * -# Set input ctxSeat + * -# Mocking the wl_resource_get_user_data() does return an object + * -# Mocking the get_surface_from_id() does return an object + * -# Mocking the weston_seat_get_pointer() does return an object + * -# Calling the setup_input_acceptance() with input accepted is 1 + * -# Verification point: + * +# get_surface_from_id() must be called once time + * +# weston_seat_get_pointer() must be called once time + * +# Free resources are allocated when running the test + */ +TEST_F(InputControllerTest, input_set_input_acceptance_withValidPointerAndApccepted) +{ + mpp_ctxSeat[0]->pointer_grab.pointer = (struct weston_pointer *)malloc(sizeof(struct weston_pointer)); + mpp_ctxSeat[0]->pointer_grab.pointer->focus = (struct weston_view *)malloc(sizeof(struct weston_view)); + + struct input_context *l_input[1] = {mp_ctxInput}; + SET_RETURN_SEQ(wl_resource_get_user_data, (void**)l_input, 1); + + struct ivi_layout_surface *l_surface[1] = {mp_layoutSurface}; + SET_RETURN_SEQ(get_surface_from_id, l_surface, 1); + + struct weston_pointer *l_ptr[1] = {(struct weston_pointer *)0xFFFFFFFF}; + SET_RETURN_SEQ(weston_seat_get_pointer, l_ptr, 1); + + setup_input_acceptance(mp_ctxInput, 10, "default", 1); + + ASSERT_EQ(get_surface_from_id_fake.call_count, 1); + ASSERT_EQ(weston_seat_get_pointer_fake.call_count, 1); + + free(mpp_ctxSeat[0]->pointer_grab.pointer->focus); + free(mpp_ctxSeat[0]->pointer_grab.pointer); +} + +/** ================================================================================================ + * @test_id handle_surface_destroy_nullSurface + * @brief Test case of handle_surface_destroy() where valid input params + * @test_procedure Steps: + * -# Calling the handle_surface_destroy() + * -# Verification point: + * +# wl_list_remove() not be called + */ +TEST_F(InputControllerTest, handle_surface_destroy_nullSurface) +{ + handle_surface_destroy(&mp_ctxInput->surface_destroyed, nullptr); + ASSERT_EQ(wl_list_remove_fake.call_count, 0); +} + +/** ================================================================================================ + * @test_id handle_surface_destroy_success + * @brief Test case of handle_surface_destroy() where valid input params + * @test_procedure Steps: + * -# Calling the handle_surface_destroy() + * -# Verification point: + * +# wl_list_remove() must be called once time + * +# Allocate memory for resources are freed when running the test + */ +TEST_F(InputControllerTest, handle_surface_destroy_success) +{ + handle_surface_destroy(&mp_ctxInput->surface_destroyed, &mp_iviSurface[0]); + + ASSERT_EQ(wl_list_remove_fake.call_count, 1); + + mpp_seatFocus[0] = (struct seat_focus*)calloc(1, sizeof(struct seat_focus)); +} + +/** ================================================================================================ + * @test_id handle_surface_create_nullSeatCtx + * @brief Test case of handle_surface_create() where invalid input params + * @test_procedure Steps: + * -# Create input context and set seat_list for input context + * -# Calling the handle_surface_create() with input surface is null pointer + * -# Verification point: + * +# wl_resource_post_event() not be called + */ +TEST_F(InputControllerTest, handle_surface_create_nullSeatCtx) +{ + struct input_context l_input_ctx; + custom_wl_list_init(&l_input_ctx.seat_list); + l_input_ctx.ivishell = &m_iviShell; + l_input_ctx.seat_default_name = (char*)mp_seatName[0]; + + handle_surface_create(&l_input_ctx.surface_created, &mp_iviSurface[0]); + ASSERT_EQ(wl_resource_post_event_fake.call_count, 0); +} + +/** ================================================================================================ + * @test_id handle_surface_create_success + * @brief Test case of handle_surface_create() where valid input params + * @test_procedure Steps: + * -# Calling the handle_surface_create() with valid input context and input surface + * -# Verification point: + * +# wl_resource_post_event() must be called 2 times + */ +TEST_F(InputControllerTest, handle_surface_create_success) +{ + mp_ctxInput->seat_default_name = (char*)mp_seatName[0]; + handle_surface_create(&mp_ctxInput->surface_created, &mp_iviSurface[0]); + ASSERT_EQ(wl_resource_post_event_fake.call_count, 2); +} + +/** ================================================================================================ + * @test_id unbind_resource_controller_success + * @brief Test case of unbind_resource_controller() where valid input params + * @test_procedure Steps: + * -# Calling the unbind_resource_controller() + * -# Verification point: + * +# wl_list_remove() must be called once time + */ +TEST_F(InputControllerTest, unbind_resource_controller_success) +{ + enable_utility_funcs_of_array_list(); + wl_resource_from_link_fake.custom_fake = custom_wl_resource_from_link; + wl_resource_get_link_fake.custom_fake = custom_wl_resource_get_link; + unbind_resource_controller(&(mp_wlResource[0])); + ASSERT_EQ(wl_list_remove_fake.call_count, 1); +} + +/** ================================================================================================ + * @test_id input_controller_destroy_nullListener + * @brief Test case of input_controller_destroy() where input context is null pointer + * @test_procedure Steps: + * -# Calling the input_controller_destroy() + */ +TEST_F(InputControllerTest, input_controller_destroy_nullListener) +{ + input_controller_destroy(nullptr, nullptr); +} + +/** ================================================================================================ + * @test_id input_controller_destroy_success + * @brief Test case of input_controller_destroy() where valid input params + * @test_procedure Steps: + * -# Set ctx input successful_init_stage is -1 + * -# Calling the input_controller_destroy() + */ +TEST_F(InputControllerTest, input_controller_destroy_success) +{ + mp_ctxInput->successful_init_stage = -1; + input_controller_destroy(&mp_ctxInput->shell_destroy_listener, nullptr); +} diff --git a/unittest/server/src/ivi_layout_interface_fake.c b/unittest/server/src/ivi_layout_interface_fake.c new file mode 100644 index 00000000..18211885 --- /dev/null +++ b/unittest/server/src/ivi_layout_interface_fake.c @@ -0,0 +1,125 @@ +/*************************************************************************** + * + * Copyright (C) 2023 Advanced Driver Information Technology Joint Venture GmbH + * + * + * 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. + * + ****************************************************************************/ + +#include "ivi_layout_interface_fake.h" + +DEFINE_FAKE_VALUE_FUNC(const struct ivi_layout_layer_properties *, get_properties_of_layer, struct ivi_layout_layer *); +DEFINE_FAKE_VALUE_FUNC(const struct ivi_layout_surface_properties *, get_properties_of_surface, struct ivi_layout_surface *); +DEFINE_FAKE_VALUE_FUNC(int32_t, add_listener_configure_desktop_surface, struct wl_listener *); +DEFINE_FAKE_VALUE_FUNC(int32_t, add_listener_configure_surface, struct wl_listener *); +DEFINE_FAKE_VALUE_FUNC(int32_t, add_listener_create_layer, struct wl_listener *); +DEFINE_FAKE_VALUE_FUNC(int32_t, add_listener_create_surface, struct wl_listener *); +DEFINE_FAKE_VALUE_FUNC(int32_t, add_listener_remove_layer, struct wl_listener *); +DEFINE_FAKE_VALUE_FUNC(int32_t, add_listener_remove_surface, struct wl_listener *); +DEFINE_FAKE_VALUE_FUNC(int32_t, commit_changes); +DEFINE_FAKE_VALUE_FUNC(int32_t, get_layers, int32_t *, struct ivi_layout_layer ***); +DEFINE_FAKE_VALUE_FUNC(int32_t, get_layers_on_screen, struct weston_output *, int32_t *, struct ivi_layout_layer ***); +DEFINE_FAKE_VALUE_FUNC(int32_t, get_layers_under_surface, struct ivi_layout_surface *, int32_t *, struct ivi_layout_layer ***); +DEFINE_FAKE_VALUE_FUNC(int32_t, get_screens_under_layer, struct ivi_layout_layer *, int32_t *, struct weston_output ***); +DEFINE_FAKE_VALUE_FUNC(int32_t, get_surfaces, int32_t *, struct ivi_layout_surface ***); +DEFINE_FAKE_VALUE_FUNC(int32_t, get_surfaces_on_layer, struct ivi_layout_layer *, int32_t *, struct ivi_layout_surface ***); +DEFINE_FAKE_VALUE_FUNC(int32_t, layer_add_listener, struct ivi_layout_layer *, struct wl_listener *); +DEFINE_FAKE_VALUE_FUNC(int32_t, layer_add_surface, struct ivi_layout_layer *, struct ivi_layout_surface *); +DEFINE_FAKE_VALUE_FUNC(int32_t, layer_set_destination_rectangle, struct ivi_layout_layer *, int32_t , int32_t , int32_t , int32_t ); +DEFINE_FAKE_VALUE_FUNC(int32_t, layer_set_fade_info, struct ivi_layout_layer* , uint32_t , double , double ); +DEFINE_FAKE_VALUE_FUNC(int32_t, layer_set_opacity, struct ivi_layout_layer *, wl_fixed_t ); +DEFINE_FAKE_VALUE_FUNC(int32_t, layer_set_render_order, struct ivi_layout_layer *, struct ivi_layout_surface **, int32_t ); +DEFINE_FAKE_VALUE_FUNC(int32_t, layer_set_source_rectangle, struct ivi_layout_layer *, int32_t , int32_t , int32_t , int32_t ); +DEFINE_FAKE_VALUE_FUNC(int32_t, layer_set_transition, struct ivi_layout_layer *, enum ivi_layout_transition_type , uint32_t ); +DEFINE_FAKE_VALUE_FUNC(int32_t, layer_set_visibility, struct ivi_layout_layer *, bool ); +DEFINE_FAKE_VALUE_FUNC(int32_t, screen_add_layer, struct weston_output *, struct ivi_layout_layer *); +DEFINE_FAKE_VALUE_FUNC(int32_t, screen_remove_layer, struct weston_output *, struct ivi_layout_layer *); +DEFINE_FAKE_VALUE_FUNC(int32_t, screen_set_render_order, struct weston_output *, struct ivi_layout_layer **, const int32_t ); +DEFINE_FAKE_VALUE_FUNC(int32_t, surface_add_listener, struct ivi_layout_surface *, struct wl_listener *); +DEFINE_FAKE_VALUE_FUNC(int32_t, surface_dump, struct weston_surface *, void *, size_t , int32_t , int32_t , int32_t , int32_t ); +DEFINE_FAKE_VALUE_FUNC(int32_t, surface_get_size, struct ivi_layout_surface *, int32_t *, int32_t *, int32_t *); +DEFINE_FAKE_VALUE_FUNC(int32_t, surface_set_destination_rectangle, struct ivi_layout_surface *, int32_t , int32_t , int32_t , int32_t ); +DEFINE_FAKE_VALUE_FUNC(int32_t, surface_set_id, struct ivi_layout_surface *, uint32_t ); +DEFINE_FAKE_VALUE_FUNC(int32_t, surface_set_opacity, struct ivi_layout_surface *, wl_fixed_t ); +DEFINE_FAKE_VALUE_FUNC(int32_t, surface_set_source_rectangle, struct ivi_layout_surface *, int32_t , int32_t , int32_t , int32_t ); +DEFINE_FAKE_VALUE_FUNC(int32_t, surface_set_transition_duration, struct ivi_layout_surface *, uint32_t ); +DEFINE_FAKE_VALUE_FUNC(int32_t, surface_set_transition, struct ivi_layout_surface *, enum ivi_layout_transition_type , uint32_t ); +DEFINE_FAKE_VALUE_FUNC(int32_t, surface_set_visibility, struct ivi_layout_surface *, bool ); +DEFINE_FAKE_VALUE_FUNC(struct ivi_layout_layer *, get_layer_from_id, uint32_t ); +DEFINE_FAKE_VALUE_FUNC(struct ivi_layout_layer *, layer_create_with_dimension, uint32_t , int32_t , int32_t ); +DEFINE_FAKE_VALUE_FUNC(struct ivi_layout_surface *, get_surface_from_id, uint32_t ); +// DEFINE_FAKE_VALUE_FUNC(struct ivisurface *, get_surface, struct wl_list *, struct ivi_layout_surface *); // have another get_surface() in ivi-controller.c +DEFINE_FAKE_VALUE_FUNC(struct weston_surface *, surface_get_weston_surface, struct ivi_layout_surface *); +DEFINE_FAKE_VALUE_FUNC(uint32_t, get_id_of_layer, struct ivi_layout_layer *); +DEFINE_FAKE_VALUE_FUNC(uint32_t, get_id_of_surface, struct ivi_layout_surface *); +DEFINE_FAKE_VOID_FUNC(focus, struct weston_pointer_grab *); +DEFINE_FAKE_VOID_FUNC(layer_destroy, struct ivi_layout_layer *); +DEFINE_FAKE_VOID_FUNC(layer_remove_surface, struct ivi_layout_layer *, struct ivi_layout_surface *); +DEFINE_FAKE_VOID_FUNC(transition_move_layer_cancel, struct ivi_layout_layer *); +DEFINE_FAKE_VALUE_FUNC(int32_t, shell_add_destroy_listener_once, struct wl_listener *, wl_notify_func_t); + +struct ivi_layout_interface g_iviLayoutInterfaceFake = { + .commit_changes = commit_changes, + .add_listener_create_surface = add_listener_create_surface, + .add_listener_remove_surface = add_listener_remove_surface, + .add_listener_configure_surface = add_listener_configure_surface, + .add_listener_configure_desktop_surface = add_listener_configure_desktop_surface, + .get_surfaces = get_surfaces, + .get_id_of_surface = get_id_of_surface, + .get_surface_from_id = get_surface_from_id, + .get_properties_of_surface = get_properties_of_surface, + .get_surfaces_on_layer = get_surfaces_on_layer, + .surface_set_visibility = surface_set_visibility, + .surface_set_opacity = surface_set_opacity, + .surface_set_source_rectangle = surface_set_source_rectangle, + .surface_set_destination_rectangle = surface_set_destination_rectangle, + .surface_add_listener = surface_add_listener, + .surface_get_weston_surface = surface_get_weston_surface, + .surface_set_transition = surface_set_transition, + .surface_set_transition_duration = surface_set_transition_duration, + .surface_set_id = surface_set_id, + .add_listener_create_layer = add_listener_create_layer, + .add_listener_remove_layer = add_listener_remove_layer, + .layer_create_with_dimension = layer_create_with_dimension, + .layer_destroy = layer_destroy, + .get_layers = get_layers, + .get_id_of_layer = get_id_of_layer, + .get_layer_from_id = get_layer_from_id, + .get_properties_of_layer = get_properties_of_layer, + .get_layers_under_surface = get_layers_under_surface, + .get_layers_on_screen = get_layers_on_screen, + .layer_set_visibility = layer_set_visibility, + .layer_set_opacity = layer_set_opacity, + .layer_set_source_rectangle = layer_set_source_rectangle, + .layer_set_destination_rectangle = layer_set_destination_rectangle, + .layer_add_surface = layer_add_surface, + .layer_remove_surface = layer_remove_surface, + .layer_set_render_order = layer_set_render_order, + .layer_add_listener = layer_add_listener, + .layer_set_transition = layer_set_transition, + .get_screens_under_layer = get_screens_under_layer, + .screen_add_layer = screen_add_layer, + .screen_set_render_order = screen_set_render_order, + .transition_move_layer_cancel = transition_move_layer_cancel, + .layer_set_fade_info = layer_set_fade_info, + .surface_get_size = surface_get_size, + .surface_dump = surface_dump, + // .get_surface = get_surface, + .screen_remove_layer = screen_remove_layer, + .shell_add_destroy_listener_once = shell_add_destroy_listener_once, +}; + +struct weston_pointer_grab_interface g_grabInterfaceFake = { + .focus = focus, +}; diff --git a/unittest/server/src/server_api_fake.c b/unittest/server/src/server_api_fake.c new file mode 100644 index 00000000..d27c0f8e --- /dev/null +++ b/unittest/server/src/server_api_fake.c @@ -0,0 +1,127 @@ +/*************************************************************************** + * + * Copyright (C) 2023 Advanced Driver Information Technology Joint Venture GmbH + * + * + * 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. + * + ****************************************************************************/ + +#include "server_api_fake.h" +DEFINE_FFF_GLOBALS; + +DEFINE_FAKE_VALUE_FUNC(struct weston_config_section *, weston_config_get_section, struct weston_config *, const char *, const char *, const char *); +DEFINE_FAKE_VALUE_FUNC(const void *, weston_plugin_api_get, struct weston_compositor *, const char *, size_t ); +DEFINE_FAKE_VALUE_FUNC(void *, weston_load_module, const char *, const char *, const char *); +DEFINE_FAKE_VALUE_FUNC(int, weston_config_section_get_bool, struct weston_config_section *, const char *, bool *, bool ); +DEFINE_FAKE_VALUE_FUNC(int, weston_config_section_get_string, struct weston_config_section *, const char *, char **, const char *); +DEFINE_FAKE_VALUE_FUNC(struct weston_view *, weston_view_create, struct weston_surface *); +DEFINE_FAKE_VALUE_FUNC(struct wl_client *, weston_client_start, struct weston_compositor *, const char *); +DEFINE_FAKE_VALUE_FUNC(int, weston_config_section_get_color, struct weston_config_section *, const char *, uint32_t *, uint32_t); +DEFINE_FAKE_VALUE_FUNC(int, weston_config_next_section, struct weston_config *, struct weston_config_section **, const char **); +DEFINE_FAKE_VALUE_FUNC(int, weston_config_section_get_int, struct weston_config_section *, const char *, int32_t *, int32_t); +DEFINE_FAKE_VALUE_FUNC(struct weston_config *, wet_get_config, struct weston_compositor *); +DEFINE_FAKE_VALUE_FUNC(int, weston_config_section_get_uint, struct weston_config_section *, const char *, uint32_t *, uint32_t); +DEFINE_FAKE_VALUE_FUNC(struct weston_view *, weston_compositor_pick_view, struct weston_compositor *, struct weston_coord_global); +DEFINE_FAKE_VALUE_FUNC(const char *, weston_desktop_surface_get_app_id, struct weston_desktop_surface *); +DEFINE_FAKE_VALUE_FUNC(const char *, weston_desktop_surface_get_title, struct weston_desktop_surface *); +DEFINE_FAKE_VALUE_FUNC(struct weston_desktop_surface *, weston_surface_get_desktop_surface, struct weston_surface *); +DEFINE_FAKE_VALUE_FUNC(struct weston_keyboard *, weston_seat_get_keyboard, struct weston_seat *); +DEFINE_FAKE_VALUE_FUNC(struct weston_pointer *, weston_seat_get_pointer, struct weston_seat *); +DEFINE_FAKE_VALUE_FUNC(struct weston_touch *, weston_seat_get_touch, struct weston_seat *); +DEFINE_FAKE_VALUE_FUNC(struct weston_surface *, weston_surface_get_main_surface, struct weston_surface *); +DEFINE_FAKE_VALUE_FUNC(bool, weston_touch_has_focus_resource, struct weston_touch *); +DEFINE_FAKE_VALUE_FUNC(struct wl_event_loop *, wl_display_get_event_loop, struct wl_display *); +DEFINE_FAKE_VALUE_FUNC(uint32_t, wl_display_next_serial, struct wl_display *); +DEFINE_FAKE_VALUE_FUNC(struct wl_event_source *, wl_event_loop_add_idle, struct wl_event_loop *, wl_event_loop_idle_func_t , void *); +DEFINE_FAKE_VALUE_FUNC(struct wl_global *, wl_global_create, struct wl_display *, const struct wl_interface *, int , void *, wl_global_bind_func_t); +DEFINE_FAKE_VALUE_FUNC(struct wl_resource *, wl_resource_create, struct wl_client *, const struct wl_interface *, int , uint32_t ); +DEFINE_FAKE_VALUE_FUNC(struct wl_resource *, wl_resource_from_link, struct wl_list *); +DEFINE_FAKE_VALUE_FUNC(struct wl_client *, wl_resource_get_client, struct wl_resource *); +DEFINE_FAKE_VALUE_FUNC(struct wl_list *, wl_resource_get_link, struct wl_resource *); +DEFINE_FAKE_VALUE_FUNC(void *, wl_resource_get_user_data, struct wl_resource *); +DEFINE_FAKE_VALUE_FUNC(int, wl_resource_get_version, struct wl_resource *); +DEFINE_FAKE_VOID_FUNC(weston_layer_entry_remove, struct weston_layer_entry *); +DEFINE_FAKE_VOID_FUNC(weston_layer_set_position, struct weston_layer *, enum weston_layer_position ); +DEFINE_FAKE_VOID_FUNC(weston_view_destroy, struct weston_view *); +DEFINE_FAKE_VOID_FUNC(weston_matrix_scale, struct weston_matrix *, float, float, float); +DEFINE_FAKE_VOID_FUNC(weston_matrix_init, struct weston_matrix *); +DEFINE_FAKE_VOID_FUNC(weston_surface_schedule_repaint, struct weston_surface *); +DEFINE_FAKE_VOID_FUNC(weston_surface_set_color, struct weston_surface *, float, float, float , float); +DEFINE_FAKE_VOID_FUNC(weston_compositor_schedule_repaint, struct weston_compositor *); +DEFINE_FAKE_VOID_FUNC(weston_output_damage, struct weston_output *); +DEFINE_FAKE_VOID_FUNC(weston_view_update_transform, struct weston_view *); +DEFINE_FAKE_VOID_FUNC(weston_matrix_translate, struct weston_matrix *, float, float, float); +DEFINE_FAKE_VOID_FUNC(weston_compositor_read_presentation_clock, const struct weston_compositor *, struct timespec *); +DEFINE_FAKE_VOID_FUNC(weston_layer_init, struct weston_layer *, struct weston_compositor *); +DEFINE_FAKE_VOID_FUNC(weston_layer_entry_insert, struct weston_layer_entry *, struct weston_layer_entry *); +DEFINE_FAKE_VOID_FUNC(weston_keyboard_send_keymap, struct weston_keyboard *, struct wl_resource *); +DEFINE_FAKE_VOID_FUNC(weston_keyboard_start_grab, struct weston_keyboard *, struct weston_keyboard_grab *); +DEFINE_FAKE_VOID_FUNC(weston_pointer_clear_focus, struct weston_pointer *); +DEFINE_FAKE_VOID_FUNC(weston_pointer_send_axis, struct weston_pointer *, const struct timespec *, struct weston_pointer_axis_event *); +DEFINE_FAKE_VOID_FUNC(weston_pointer_send_axis_source, struct weston_pointer *, enum wl_pointer_axis_source); +DEFINE_FAKE_VOID_FUNC(weston_pointer_send_button, struct weston_pointer *, const struct timespec *, uint32_t, enum wl_pointer_button_state); +DEFINE_FAKE_VOID_FUNC(weston_pointer_send_frame, struct weston_pointer *); +DEFINE_FAKE_VOID_FUNC(weston_pointer_send_motion, struct weston_pointer *, const struct timespec *, struct weston_pointer_motion_event *); +DEFINE_FAKE_VOID_FUNC(weston_pointer_set_focus, struct weston_pointer *, struct weston_view *); +DEFINE_FAKE_VOID_FUNC(weston_pointer_start_grab, struct weston_pointer *, struct weston_pointer_grab *); +DEFINE_FAKE_VOID_FUNC(weston_touch_send_down, struct weston_touch *, const struct timespec *, int , struct weston_coord_global); +DEFINE_FAKE_VOID_FUNC(weston_touch_send_frame, struct weston_touch *); +DEFINE_FAKE_VOID_FUNC(weston_touch_send_motion, struct weston_touch *, const struct timespec *, int , struct weston_coord_global); +DEFINE_FAKE_VOID_FUNC(weston_touch_send_up, struct weston_touch *, const struct timespec *, int ); +DEFINE_FAKE_VOID_FUNC(weston_touch_set_focus, struct weston_touch *, struct weston_view *); +DEFINE_FAKE_VOID_FUNC(weston_touch_start_grab, struct weston_touch *, struct weston_touch_grab *); +DEFINE_FAKE_VOID_FUNC(weston_view_from_global_fixed, struct weston_view *, wl_fixed_t, wl_fixed_t, wl_fixed_t *, wl_fixed_t *); +DEFINE_FAKE_VOID_FUNC(wl_client_add_destroy_listener, struct wl_client *, struct wl_listener *); +DEFINE_FAKE_VOID_FUNC(wl_client_destroy, struct wl_client *); +DEFINE_FAKE_VOID_FUNC(wl_client_get_credentials, struct wl_client *, pid_t *, uid_t *, gid_t *); +DEFINE_FAKE_VOID_FUNC(wl_client_post_no_memory, struct wl_client *); +DEFINE_FAKE_VOID_FUNC(wl_resource_destroy, struct wl_resource *); +DEFINE_FAKE_VOID_FUNC(wl_resource_post_no_memory, struct wl_resource *); +DEFINE_FAKE_VOID_FUNC(wl_resource_set_destructor, struct wl_resource *, wl_resource_destroy_func_t ); +DEFINE_FAKE_VOID_FUNC(wl_resource_set_implementation, struct wl_resource *, const void *, void *, wl_resource_destroy_func_t); +DEFINE_FAKE_VALUE_FUNC_VARARG(int, weston_log, const char *, ...); +DEFINE_FAKE_VOID_FUNC_VARARG(wl_resource_post_event, struct wl_resource *, uint32_t, ...); +DEFINE_FAKE_VOID_FUNC(wl_list_insert, struct wl_list *, struct wl_list *); +DEFINE_FAKE_VALUE_FUNC(void *, wl_array_add, struct wl_array *, size_t); +DEFINE_FAKE_VOID_FUNC(wl_list_init, struct wl_list *); +DEFINE_FAKE_VOID_FUNC(wl_list_remove, struct wl_list *); +DEFINE_FAKE_VOID_FUNC(wl_array_init, struct wl_array *); +DEFINE_FAKE_VOID_FUNC(wl_array_release, struct wl_array *); +DEFINE_FAKE_VALUE_FUNC(int, wl_list_empty, const struct wl_list *); + +DEFINE_FAKE_VALUE_FUNC(int32_t, wl_shm_buffer_get_stride, struct wl_shm_buffer *); +DEFINE_FAKE_VALUE_FUNC(int32_t, wl_shm_buffer_get_width, struct wl_shm_buffer *); +DEFINE_FAKE_VALUE_FUNC(int32_t, wl_shm_buffer_get_height, struct wl_shm_buffer *); +DEFINE_FAKE_VALUE_FUNC(void *, wl_shm_buffer_get_data, struct wl_shm_buffer *); +DEFINE_FAKE_VOID_FUNC_VARARG(wl_client_post_implementation_error,struct wl_client *, char const *, ...); + +DEFINE_FAKE_VOID_FUNC(weston_keyboard_end_grab, struct weston_keyboard *); +DEFINE_FAKE_VOID_FUNC(weston_pointer_end_grab, struct weston_pointer *); +DEFINE_FAKE_VOID_FUNC(weston_touch_end_grab, struct weston_touch *); +DEFINE_FAKE_VOID_FUNC(weston_output_schedule_repaint, struct weston_output *); +DEFINE_FAKE_VALUE_FUNC(pixman_bool_t, pixman_region32_union, pixman_region32_t *, pixman_region32_t *, pixman_region32_t *); + +DEFINE_FAKE_VALUE_FUNC(struct weston_buffer *, weston_buffer_from_resource, struct weston_compositor *, struct wl_resource *); +DEFINE_FAKE_VOID_FUNC(weston_view_geometry_dirty, struct weston_view *); +DEFINE_FAKE_VALUE_FUNC(int, weston_screenshooter_shoot, struct weston_output *, struct weston_buffer *, weston_screenshooter_done_func_t, void *); +DEFINE_FAKE_VOID_FUNC(weston_surface_map, struct weston_surface *); +DEFINE_FAKE_VALUE_FUNC(bool, weston_surface_has_content, struct weston_surface *); +DEFINE_FAKE_VALUE_FUNC(bool, weston_surface_is_mapped, struct weston_surface *); +DEFINE_FAKE_VALUE_FUNC(int, wl_list_length, const struct wl_list *); + +int custom_weston_log(const char *format, va_list ap) +{ + vfprintf(stderr, format, ap); + return 1; +} \ No newline at end of file