From 1d4db34ecb2921a32c4cedb5b0d9923d5e9f0588 Mon Sep 17 00:00:00 2001 From: Falk Werner Date: Sun, 22 Mar 2020 20:09:40 +0100 Subject: [PATCH] increased test coverage --- cmake/unit_tests.cmake | 13 +++- lib/wf/jsonrpc/test/wf/jsonrpc/mock_timer.cc | 31 ++++++++ lib/wf/jsonrpc/test/wf/jsonrpc/mock_timer.hpp | 47 ++++++++++++ .../test/wf/jsonrpc/mock_timer_callback.cc | 41 ++++++++++ .../test/wf/jsonrpc/mock_timer_callback.hpp | 23 ++++++ lib/wf/jsonrpc/test/wf/jsonrpc/test_proxy.cc | 49 +++++++++++- lib/wf/jsonrpc/test/wf/jsonrpc/wrap.hpp | 74 +++++++++++++++++++ 7 files changed, 276 insertions(+), 2 deletions(-) create mode 100644 lib/wf/jsonrpc/test/wf/jsonrpc/mock_timer.cc create mode 100644 lib/wf/jsonrpc/test/wf/jsonrpc/mock_timer.hpp create mode 100644 lib/wf/jsonrpc/test/wf/jsonrpc/mock_timer_callback.cc create mode 100644 lib/wf/jsonrpc/test/wf/jsonrpc/mock_timer_callback.hpp create mode 100644 lib/wf/jsonrpc/test/wf/jsonrpc/wrap.hpp diff --git a/cmake/unit_tests.cmake b/cmake/unit_tests.cmake index aaf5381..1722301 100644 --- a/cmake/unit_tests.cmake +++ b/cmake/unit_tests.cmake @@ -7,6 +7,8 @@ include(GoogleTest) pkg_check_modules(GMOCK gmock) add_executable(alltests + lib/wf/jsonrpc/test/wf/jsonrpc/mock_timer_callback.cc + lib/wf/jsonrpc/test/wf/jsonrpc/mock_timer.cc lib/wf/jsonrpc/test/wf/jsonrpc/test_is_request.cc lib/wf/jsonrpc/test/wf/jsonrpc/test_request.cc lib/wf/jsonrpc/test/wf/jsonrpc/test_is_response.cc @@ -51,6 +53,7 @@ add_executable(alltests target_include_directories(alltests PRIVATE lib/wf/jsonrpc/include lib/wf/jsonrpc/src + lib/wf/jsonrpc/test lib/wf/timer/include lib/wf/timer/src ${FUSE3_INCLUDE_DIRS} @@ -60,7 +63,15 @@ target_compile_options(alltests PUBLIC ${FUSE3_CFLAGS_OTHER} ) -target_link_libraries(alltests PUBLIC +target_link_libraries(alltests PUBLIC + -Wl,--wrap=wf_timer_manager_create + -Wl,--wrap=wf_timer_manager_dispose + -Wl,--wrap=wf_timer_manager_check + -Wl,--wrap=wf_timer_create + -Wl,--wrap=wf_timer_dispose + -Wl,--wrap=wf_timer_start + -Wl,--wrap=wf_timer_cancel + webfuse-adapter-static webfuse-provider-static webfuse-core diff --git a/lib/wf/jsonrpc/test/wf/jsonrpc/mock_timer.cc b/lib/wf/jsonrpc/test/wf/jsonrpc/mock_timer.cc new file mode 100644 index 0000000..bdfde2b --- /dev/null +++ b/lib/wf/jsonrpc/test/wf/jsonrpc/mock_timer.cc @@ -0,0 +1,31 @@ +#include "wf/jsonrpc/mock_timer.hpp" +#include "wf/jsonrpc/wrap.hpp" + +extern "C" +{ +static wf_jsonrpc_test::ITimer * wf_jsonrpc_MockTimer = nullptr; + +WF_WRAP_FUNC0(wf_jsonrpc_MockTimer, wf_timer_manager *, wf_timer_manager_create); +WF_WRAP_FUNC1(wf_jsonrpc_MockTimer, void, wf_timer_manager_dispose, wf_timer_manager *); +WF_WRAP_FUNC1(wf_jsonrpc_MockTimer, void, wf_timer_manager_check, wf_timer_manager *); + +WF_WRAP_FUNC3(wf_jsonrpc_MockTimer, wf_timer *, wf_timer_create, wf_timer_manager *, wf_timer_on_timer_fn *, void *); +WF_WRAP_FUNC1(wf_jsonrpc_MockTimer, void, wf_timer_dispose, wf_timer *); +WF_WRAP_FUNC2(wf_jsonrpc_MockTimer, void, wf_timer_start, wf_timer *, int); +WF_WRAP_FUNC1(wf_jsonrpc_MockTimer, void, wf_timer_cancel, wf_timer *); + +} + +namespace wf_jsonrpc_test +{ +MockTimer::MockTimer() +{ + wf_jsonrpc_MockTimer = this; +} + +MockTimer::~MockTimer() +{ + wf_jsonrpc_MockTimer = nullptr; +} + +} \ No newline at end of file diff --git a/lib/wf/jsonrpc/test/wf/jsonrpc/mock_timer.hpp b/lib/wf/jsonrpc/test/wf/jsonrpc/mock_timer.hpp new file mode 100644 index 0000000..3fde45e --- /dev/null +++ b/lib/wf/jsonrpc/test/wf/jsonrpc/mock_timer.hpp @@ -0,0 +1,47 @@ +#ifndef WF_JSONRPC_MOCK_TIMERMANAGER_HPP +#define WF_JSONRPC_MOCK_TIMERMANAGER_HPP + +#include +#include + +namespace wf_jsonrpc_test +{ + +class ITimer +{ +public: + virtual ~ITimer() = default; + virtual wf_timer_manager * wf_timer_manager_create() = 0; + virtual void wf_timer_manager_dispose(wf_timer_manager * manager) = 0; + virtual void wf_timer_manager_check(wf_timer_manager * manager) = 0; + virtual wf_timer * wf_timer_create( + wf_timer_manager * manager, + wf_timer_on_timer_fn * on_timer, + void * user_data) = 0; + virtual void wf_timer_dispose(wf_timer * timer) = 0; + virtual void wf_timer_start(wf_timer * timer, int timeout_ms) = 0; + virtual void wf_timer_cancel(wf_timer * timer) = 0; +}; + +class MockTimer: public ITimer +{ +public: + MockTimer(); + ~MockTimer() override; + MOCK_METHOD0(wf_timer_manager_create, wf_timer_manager * ()); + MOCK_METHOD1(wf_timer_manager_dispose, void(wf_timer_manager * manager)); + MOCK_METHOD1(wf_timer_manager_check, void (wf_timer_manager * manager)); + MOCK_METHOD3(wf_timer_create, wf_timer *( + wf_timer_manager * manager, + wf_timer_on_timer_fn * on_timer, + void * user_data)); + MOCK_METHOD1(wf_timer_dispose, void (wf_timer * timer)); + MOCK_METHOD2(wf_timer_start, void (wf_timer * timer, int timeout_ms)); + MOCK_METHOD1(wf_timer_cancel, void (wf_timer * timer)); + +}; + + +} + +#endif diff --git a/lib/wf/jsonrpc/test/wf/jsonrpc/mock_timer_callback.cc b/lib/wf/jsonrpc/test/wf/jsonrpc/mock_timer_callback.cc new file mode 100644 index 0000000..dd3cc3b --- /dev/null +++ b/lib/wf/jsonrpc/test/wf/jsonrpc/mock_timer_callback.cc @@ -0,0 +1,41 @@ +#include "wf/jsonrpc/mock_timer_callback.hpp" + +extern "C" +{ +using wf_jsonrpc_test::MockTimerCallback; + +static void wf_jsonrpc_test_MockTimerCallback_on_timer( + wf_timer * timer, + void * user_data) +{ + auto * self = reinterpret_cast(user_data); + self->on_timer(timer, user_data); +} + +} + +namespace wf_jsonrpc_test +{ + +MockTimerCallback::MockTimerCallback() +{ + +} + +MockTimerCallback::~MockTimerCallback() +{ + +} + +wf_timer_on_timer_fn * MockTimerCallback::on_timer_fn() +{ + return &wf_jsonrpc_test_MockTimerCallback_on_timer; +} + +void * MockTimerCallback::user_data() +{ + return reinterpret_cast(this); +} + + +} \ No newline at end of file diff --git a/lib/wf/jsonrpc/test/wf/jsonrpc/mock_timer_callback.hpp b/lib/wf/jsonrpc/test/wf/jsonrpc/mock_timer_callback.hpp new file mode 100644 index 0000000..cdbf2d6 --- /dev/null +++ b/lib/wf/jsonrpc/test/wf/jsonrpc/mock_timer_callback.hpp @@ -0,0 +1,23 @@ +#ifndef WF_JSONRPC_MOCK_TIMERCALLBACK_HPP +#define WF_JSONRPC_MOCK_TIMERCALLBACK_HPP + +#include "wf/timer.h" +#include + +namespace wf_jsonrpc_test +{ +class MockTimerCallback +{ +public: + MockTimerCallback(); + virtual ~MockTimerCallback(); + wf_timer_on_timer_fn * on_timer_fn(); + void * user_data(); + + MOCK_METHOD2(on_timer, void (wf_timer * timer, void * user_data)); + +}; + +} + +#endif diff --git a/lib/wf/jsonrpc/test/wf/jsonrpc/test_proxy.cc b/lib/wf/jsonrpc/test/wf/jsonrpc/test_proxy.cc index 66eafa9..763fa51 100644 --- a/lib/wf/jsonrpc/test/wf/jsonrpc/test_proxy.cc +++ b/lib/wf/jsonrpc/test/wf/jsonrpc/test_proxy.cc @@ -3,11 +3,17 @@ #include "wf/jsonrpc/status.h" #include "wf/timer/manager.h" +#include "wf/jsonrpc/mock_timer.hpp" + #include #include using namespace std::chrono_literals; - +using wf_jsonrpc_test::MockTimer; +using testing::Return; +using testing::_; +using testing::DoAll; +using testing::SaveArg; #define WF_DEFAULT_TIMEOUT (10 * 1000) @@ -380,3 +386,44 @@ TEST(wf_jsonrpc_proxy, notify_dont_send_invalid_request) wf_jsonrpc_proxy_dispose(proxy); wf_timer_manager_dispose(timer_manager); } + +TEST(wf_jsonrpc_proxy, swallow_timeout_if_no_request_pending) +{ + MockTimer timer_api; + + wf_timer_on_timer_fn * on_timer = nullptr; + void * timer_context = nullptr; + EXPECT_CALL(timer_api, wf_timer_create(_, _, _)) + .Times(1) + .WillOnce(DoAll(SaveArg<1>(&on_timer), SaveArg<2>(&timer_context), Return(nullptr))); + + SendContext send_context; + void * send_data = reinterpret_cast(&send_context); + struct wf_jsonrpc_proxy * proxy = wf_jsonrpc_proxy_create(nullptr, 1, &jsonrpc_send, send_data); + + on_timer(nullptr, timer_context); + ASSERT_FALSE(send_context.is_called); + + + wf_jsonrpc_proxy_dispose(proxy); +} + +TEST(wf_jsonrpc_proxy, on_result_swallow_if_no_request_pending) +{ + struct wf_timer_manager * timer_manager = wf_timer_manager_create(); + + SendContext send_context; + void * send_data = reinterpret_cast(&send_context); + struct wf_jsonrpc_proxy * proxy = wf_jsonrpc_proxy_create(timer_manager, WF_DEFAULT_TIMEOUT, &jsonrpc_send, send_data); + + json_t * response = json_object(); + json_object_set_new(response, "result", json_string("okay")); + json_object_set_new(response, "id", json_integer(42)); + + wf_jsonrpc_proxy_onresult(proxy, response); + json_decref(response); + + wf_jsonrpc_proxy_dispose(proxy); + wf_timer_manager_dispose(timer_manager); +} + diff --git a/lib/wf/jsonrpc/test/wf/jsonrpc/wrap.hpp b/lib/wf/jsonrpc/test/wf/jsonrpc/wrap.hpp new file mode 100644 index 0000000..9d062d8 --- /dev/null +++ b/lib/wf/jsonrpc/test/wf/jsonrpc/wrap.hpp @@ -0,0 +1,74 @@ +#ifndef WF_WRAP_HPP +#define WF_WRAP_HPP + +#define WF_WRAP_FUNC0( GLOBAL_VAR, RETURN_TYPE, FUNC_NAME ) \ + extern RETURN_TYPE __real_ ## FUNC_NAME (); \ + RETURN_TYPE __wrap_ ## FUNC_NAME () \ + { \ + if (nullptr == GLOBAL_VAR ) \ + { \ + return __real_ ## FUNC_NAME (); \ + } \ + else \ + { \ + return GLOBAL_VAR -> FUNC_NAME(); \ + } \ + } + +#define WF_WRAP_FUNC1( GLOBAL_VAR, RETURN_TYPE, FUNC_NAME, ARG1_TYPE ) \ + extern RETURN_TYPE __real_ ## FUNC_NAME (ARG1_TYPE); \ + RETURN_TYPE __wrap_ ## FUNC_NAME (ARG1_TYPE arg1) \ + { \ + if (nullptr == GLOBAL_VAR ) \ + { \ + return __real_ ## FUNC_NAME (arg1); \ + } \ + else \ + { \ + return GLOBAL_VAR -> FUNC_NAME(arg1); \ + } \ + } + +#define WF_WRAP_FUNC2( GLOBAL_VAR, RETURN_TYPE, FUNC_NAME, ARG1_TYPE, ARG2_TYPE ) \ + extern RETURN_TYPE __real_ ## FUNC_NAME (ARG1_TYPE, ARG2_TYPE); \ + RETURN_TYPE __wrap_ ## FUNC_NAME (ARG1_TYPE arg1, ARG2_TYPE arg2) \ + { \ + if (nullptr == GLOBAL_VAR ) \ + { \ + return __real_ ## FUNC_NAME (arg1, arg2); \ + } \ + else \ + { \ + return GLOBAL_VAR -> FUNC_NAME(arg1, arg2); \ + } \ + } + +#define WF_WRAP_FUNC3( GLOBAL_VAR, RETURN_TYPE, FUNC_NAME, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE ) \ + extern RETURN_TYPE __real_ ## FUNC_NAME (ARG1_TYPE, ARG2_TYPE, ARG3_TYPE); \ + RETURN_TYPE __wrap_ ## FUNC_NAME (ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3) \ + { \ + if (nullptr == GLOBAL_VAR ) \ + { \ + return __real_ ## FUNC_NAME (arg1, arg2, arg3); \ + } \ + else \ + { \ + return GLOBAL_VAR -> FUNC_NAME(arg1, arg2, arg3); \ + } \ + } + +#define WF_WRAP_FUNC4( GLOBAL_VAR, RETURN_TYPE, FUNC_NAME, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE ) \ + extern RETURN_TYPE __real_ ## FUNC_NAME (ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE); \ + RETURN_TYPE __wrap_ ## FUNC_NAME (ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4) \ + { \ + if (nullptr == GLOBAL_VAR ) \ + { \ + return __real_ ## FUNC_NAME (arg1, arg2, arg3, arg4); \ + } \ + else \ + { \ + return GLOBAL_VAR -> FUNC_NAME(arg1, arg2, arg3, arg4); \ + } \ + } + +#endif