diff --git a/cmake/unit_tests.cmake b/cmake/unit_tests.cmake index 06d510d..4934a05 100644 --- a/cmake/unit_tests.cmake +++ b/cmake/unit_tests.cmake @@ -31,6 +31,8 @@ add_executable(alltests test/webfuse/mocks/mock_provider_client.cc test/webfuse/mocks/mock_provider.cc test/webfuse/mocks/mock_fuse.cc + test/webfuse/mocks/mock_operations_context.cc + test/webfuse/mocks/mock_jsonrpc_proxy.cc test/webfuse//tests/core/test_util.cc test/webfuse/tests/core/test_container_of.cc test/webfuse/tests/core/test_string.cc @@ -69,6 +71,8 @@ target_link_libraries(alltests PUBLIC -Wl,--wrap=wf_timer_dispose -Wl,--wrap=wf_timer_start -Wl,--wrap=wf_timer_cancel + -Wl,--wrap=wf_impl_operations_context_get_proxy + -Wl,--wrap=wf_jsonrpc_proxy_vinvoke -Wl,--wrap=fuse_req_userdata -Wl,--wrap=fuse_reply_open -Wl,--wrap=fuse_reply_err diff --git a/cmake/webfuse_core.cmake b/cmake/webfuse_core.cmake index fb25b75..3dfa958 100644 --- a/cmake/webfuse_core.cmake +++ b/cmake/webfuse_core.cmake @@ -13,6 +13,7 @@ add_library(webfuse-core STATIC lib/webfuse/core/timer/timepoint.c lib/webfuse/core/timer/timer.c lib/webfuse/core/jsonrpc/proxy.c + lib/webfuse/core/jsonrpc/proxy_invoke.c lib/webfuse/core/jsonrpc/server.c lib/webfuse/core/jsonrpc/method.c lib/webfuse/core/jsonrpc/request.c diff --git a/lib/webfuse/adapter/impl/filesystem.c b/lib/webfuse/adapter/impl/filesystem.c index b7966a1..67fef92 100644 --- a/lib/webfuse/adapter/impl/filesystem.c +++ b/lib/webfuse/adapter/impl/filesystem.c @@ -1,5 +1,6 @@ #include "webfuse/adapter/impl/filesystem.h" #include "webfuse/adapter/impl/operations.h" +#include "webfuse/adapter/impl/operation/open.h" #include "webfuse/adapter/impl/session.h" #include "webfuse/adapter/impl/mountpoint.h" diff --git a/lib/webfuse/adapter/impl/operation/open.c b/lib/webfuse/adapter/impl/operation/open.c index 07d8ea9..630e9c8 100644 --- a/lib/webfuse/adapter/impl/operation/open.c +++ b/lib/webfuse/adapter/impl/operation/open.c @@ -1,15 +1,15 @@ +#include "webfuse/adapter/impl/operation/open.h" #include "webfuse/adapter/impl/operations.h" -#include -#include -#include - #include "webfuse/core/jsonrpc/proxy.h" #include "webfuse/core/util.h" #include "webfuse/core/status.h" #include "webfuse/core/json_util.h" -static void wf_impl_operation_open_finished( +#include +#include + +void wf_impl_operation_open_finished( void * user_data, json_t const * result, json_t const * error) diff --git a/lib/webfuse/adapter/impl/operation/open.h b/lib/webfuse/adapter/impl/operation/open.h new file mode 100644 index 0000000..eb40490 --- /dev/null +++ b/lib/webfuse/adapter/impl/operation/open.h @@ -0,0 +1,26 @@ +#ifndef WF_ADAPTER_IMPL_OPERATION_OPEN_H +#define WF_ADAPTER_IMPL_OPERATION_OPEN_H + +#include "webfuse/adapter/impl/fuse_wrapper.h" +#include + +#ifdef __cplusplus +extern "C" +{ +#endif + +extern void wf_impl_operation_open( + fuse_req_t request, + fuse_ino_t inode, + struct fuse_file_info * file_info); + +extern void wf_impl_operation_open_finished( + void * user_data, + json_t const * result, + json_t const * error); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/lib/webfuse/adapter/impl/operations.h b/lib/webfuse/adapter/impl/operations.h index 4d23db2..162ee15 100644 --- a/lib/webfuse/adapter/impl/operations.h +++ b/lib/webfuse/adapter/impl/operations.h @@ -34,11 +34,6 @@ extern void wf_impl_operation_readdir ( off_t offset, struct fuse_file_info *file_info); -extern void wf_impl_operation_open( - fuse_req_t request, - fuse_ino_t inode, - struct fuse_file_info * file_info); - extern void wf_impl_operation_close( fuse_req_t request, fuse_ino_t inode, diff --git a/lib/webfuse/core/jsonrpc/proxy.c b/lib/webfuse/core/jsonrpc/proxy.c index 67fd6d8..90a9d56 100644 --- a/lib/webfuse/core/jsonrpc/proxy.c +++ b/lib/webfuse/core/jsonrpc/proxy.c @@ -133,14 +133,13 @@ void wf_jsonrpc_proxy_cleanup( wf_timer_dispose(proxy->request.timer); } -void wf_jsonrpc_proxy_invoke( +void wf_jsonrpc_proxy_vinvoke( struct wf_jsonrpc_proxy * proxy, wf_jsonrpc_proxy_finished_fn * finished, void * user_data, char const * method_name, char const * param_info, - ... -) + va_list args) { if (!proxy->request.is_pending) { @@ -150,10 +149,7 @@ void wf_jsonrpc_proxy_invoke( proxy->request.id = 42; wf_timer_start(proxy->request.timer, proxy->timeout); - va_list args; - va_start(args, param_info); json_t * request = wf_jsonrpc_request_create(method_name, proxy->request.id, param_info, args); - va_end(args); bool const is_send = ((NULL != request) && (proxy->send(request, proxy->user_data))); if (!is_send) diff --git a/lib/webfuse/core/jsonrpc/proxy_intern.h b/lib/webfuse/core/jsonrpc/proxy_intern.h index 3186e14..920bd56 100644 --- a/lib/webfuse/core/jsonrpc/proxy_intern.h +++ b/lib/webfuse/core/jsonrpc/proxy_intern.h @@ -41,6 +41,14 @@ extern void wf_jsonrpc_proxy_cleanup( struct wf_jsonrpc_proxy * proxy); +extern void wf_jsonrpc_proxy_vinvoke( + struct wf_jsonrpc_proxy * proxy, + wf_jsonrpc_proxy_finished_fn * finished, + void * user_data, + char const * method_name, + char const * param_info, + va_list args); + #ifdef __cplusplus } #endif diff --git a/lib/webfuse/core/jsonrpc/proxy_invoke.c b/lib/webfuse/core/jsonrpc/proxy_invoke.c new file mode 100644 index 0000000..ada6b9e --- /dev/null +++ b/lib/webfuse/core/jsonrpc/proxy_invoke.c @@ -0,0 +1,15 @@ +#include "webfuse/core/jsonrpc/proxy_intern.h" + +void wf_jsonrpc_proxy_invoke( + struct wf_jsonrpc_proxy * proxy, + wf_jsonrpc_proxy_finished_fn * finished, + void * user_data, + char const * method_name, + char const * param_info, + ...) +{ + va_list args; + va_start(args, param_info); + wf_jsonrpc_proxy_vinvoke(proxy, finished, user_data, method_name, param_info, args); + va_end(args); +} diff --git a/test/webfuse/mocks/mock_fuse.hpp b/test/webfuse/mocks/mock_fuse.hpp index ed6e6ff..07bcb60 100644 --- a/test/webfuse/mocks/mock_fuse.hpp +++ b/test/webfuse/mocks/mock_fuse.hpp @@ -1,3 +1,6 @@ +#ifndef MOCK_FUSE_HPP +#define MOCK_FUSE_HPP + #include "webfuse/adapter/impl/fuse_wrapper.h" #include @@ -15,5 +18,6 @@ public: MOCK_METHOD2(fuse_reply_err, int (fuse_req_t req, int err)); }; +} -} \ No newline at end of file +#endif diff --git a/test/webfuse/mocks/mock_jsonrpc_proxy.cc b/test/webfuse/mocks/mock_jsonrpc_proxy.cc new file mode 100644 index 0000000..569dfa8 --- /dev/null +++ b/test/webfuse/mocks/mock_jsonrpc_proxy.cc @@ -0,0 +1,30 @@ +#include "webfuse/mocks/mock_jsonrpc_proxy.hpp" +#include "webfuse/utils/wrap.hpp" + +extern "C" +{ +static webfuse_test::MockJsonRpcProxy * webfuse_test_MockJsonRpcProxy = nullptr; + +WF_WRAP_FUNC6(webfuse_test_MockJsonRpcProxy, void, wf_jsonrpc_proxy_vinvoke, + struct wf_jsonrpc_proxy *, + wf_jsonrpc_proxy_finished_fn *, + void *, + char const *, + char const *, + va_list); +} + +namespace webfuse_test +{ + +MockJsonRpcProxy::MockJsonRpcProxy() +{ + webfuse_test_MockJsonRpcProxy = this; +} + +MockJsonRpcProxy::~MockJsonRpcProxy() +{ + webfuse_test_MockJsonRpcProxy = nullptr; +} + +} \ No newline at end of file diff --git a/test/webfuse/mocks/mock_jsonrpc_proxy.hpp b/test/webfuse/mocks/mock_jsonrpc_proxy.hpp new file mode 100644 index 0000000..97a1b1b --- /dev/null +++ b/test/webfuse/mocks/mock_jsonrpc_proxy.hpp @@ -0,0 +1,27 @@ +#ifndef MOCK_JSONRPC_PROXY_HPP +#define MOCK_JSONRPC_PROXY_HPP + +#include "webfuse/core/jsonrpc/proxy_intern.h" +#include + +namespace webfuse_test +{ + +class MockJsonRpcProxy +{ +public: + MockJsonRpcProxy(); + virtual ~MockJsonRpcProxy(); + MOCK_METHOD6(wf_jsonrpc_proxy_vinvoke, void ( + struct wf_jsonrpc_proxy * proxy, + wf_jsonrpc_proxy_finished_fn * finished, + void * user_data, + char const * method_name, + char const * param_info, + va_list args)); + +}; + +} + +#endif diff --git a/test/webfuse/mocks/mock_operations_context.cc b/test/webfuse/mocks/mock_operations_context.cc new file mode 100644 index 0000000..89498f7 --- /dev/null +++ b/test/webfuse/mocks/mock_operations_context.cc @@ -0,0 +1,27 @@ +#include "webfuse/mocks/mock_operations_context.hpp" +#include "webfuse/utils/wrap.hpp" + +extern "C" +{ +static webfuse_test::MockOperationsContext * webfuse_test_MockOperationsContext = nullptr; + +WF_WRAP_FUNC1(webfuse_test_MockOperationsContext, + struct wf_jsonrpc_proxy *, wf_impl_operations_context_get_proxy, + struct wf_impl_operations_context *); + +} + +namespace webfuse_test +{ + +MockOperationsContext::MockOperationsContext() +{ + webfuse_test_MockOperationsContext = this; +} + +MockOperationsContext::~MockOperationsContext() +{ + webfuse_test_MockOperationsContext = nullptr; +} + +} \ No newline at end of file diff --git a/test/webfuse/mocks/mock_operations_context.hpp b/test/webfuse/mocks/mock_operations_context.hpp new file mode 100644 index 0000000..a12aa7b --- /dev/null +++ b/test/webfuse/mocks/mock_operations_context.hpp @@ -0,0 +1,22 @@ +#ifndef MOCK_OPERATIONS_CONTEXT_HPP +#define MOCK_OPERATIONS_CONTEXT_HPP + +#include "webfuse/adapter/impl/operations.h" +#include + +namespace webfuse_test +{ + +class MockOperationsContext +{ +public: + MockOperationsContext(); + virtual ~MockOperationsContext(); + MOCK_METHOD1(wf_impl_operations_context_get_proxy, wf_jsonrpc_proxy * ( + struct wf_impl_operations_context * context)); + +}; + +} + +#endif diff --git a/test/webfuse/tests/adapter/operation/test_open.cc b/test/webfuse/tests/adapter/operation/test_open.cc index d1b5960..e7e5ca4 100644 --- a/test/webfuse/tests/adapter/operation/test_open.cc +++ b/test/webfuse/tests/adapter/operation/test_open.cc @@ -1,28 +1,101 @@ +#include "webfuse/adapter/impl/operation/open.h" #include "webfuse/adapter/impl/operations.h" + +#include "webfuse/core/status.h" + #include "webfuse/mocks/mock_fuse.hpp" -#include "webfuse/adapter/impl/session.h" +#include "webfuse/mocks/mock_operations_context.hpp" +#include "webfuse/mocks/mock_jsonrpc_proxy.hpp" #include +using webfuse_test::MockJsonRpcProxy; +using webfuse_test::MockOperationsContext; using webfuse_test::FuseMock; using testing::_; using testing::Return; +using testing::StrEq; + +TEST(wf_impl_operation_open, invoke_proxy) +{ + MockJsonRpcProxy proxy; + EXPECT_CALL(proxy, wf_jsonrpc_proxy_vinvoke(_,_,_,StrEq("open"),StrEq("sii"),_)).Times(1); + + MockOperationsContext context; + EXPECT_CALL(context, wf_impl_operations_context_get_proxy(_)).Times(1) + .WillOnce(Return(reinterpret_cast(&proxy))); + + wf_impl_operations_context op_context; + op_context.name = nullptr; + FuseMock fuse; + EXPECT_CALL(fuse, fuse_req_userdata(_)).Times(1).WillOnce(Return(&op_context)); + + + fuse_req_t request = nullptr; + fuse_ino_t inode = 1; + fuse_file_info file_info; + file_info.flags = 0; + wf_impl_operation_open(request, inode, &file_info); +} TEST(wf_impl_operation_open, fail_rpc_null) { - wf_impl_session session; - memset(&session, 0, sizeof(session)); - wf_impl_operations_context context = - {&session, 1.0f, nullptr }; + MockOperationsContext context; + EXPECT_CALL(context, wf_impl_operations_context_get_proxy(_)).Times(1) + .WillOnce(Return(nullptr)); FuseMock fuse; - EXPECT_CALL(fuse, fuse_req_userdata(_)).Times(1) - .WillOnce(Return(reinterpret_cast(&context))); - EXPECT_CALL(fuse, fuse_reply_err(_, ENOENT)).Times(1) - .WillOnce(Return(0)); + EXPECT_CALL(fuse, fuse_req_userdata(_)).Times(1).WillOnce(Return(nullptr)); + EXPECT_CALL(fuse, fuse_reply_err(_, ENOENT)).Times(1).WillOnce(Return(0)); fuse_req_t request = nullptr; fuse_ino_t inode = 1; fuse_file_info * file_info = nullptr; wf_impl_operation_open(request, inode, file_info); -} \ No newline at end of file +} + +TEST(wf_impl_operation_open, finished) +{ + FuseMock fuse; + EXPECT_CALL(fuse, fuse_reply_open(_,_)).Times(1).WillOnce(Return(0)); + + json_t * result = json_object(); + json_object_set_new(result, "handle", json_integer(42)); + wf_impl_operation_open_finished(nullptr, result, nullptr); + json_decref(result); +} + +TEST(wf_impl_operation_open, finished_fail_error) +{ + FuseMock fuse; + EXPECT_CALL(fuse, fuse_reply_open(_,_)).Times(0); + EXPECT_CALL(fuse, fuse_reply_err(_, ENOENT)).Times(1).WillOnce(Return(0)); + + json_t * error = json_object(); + json_object_set_new(error, "code", json_integer(WF_BAD)); + wf_impl_operation_open_finished(nullptr, nullptr, error); + json_decref(error); +} + +TEST(wf_impl_operation_open, finished_fail_no_handle) +{ + FuseMock fuse; + EXPECT_CALL(fuse, fuse_reply_open(_,_)).Times(0); + EXPECT_CALL(fuse, fuse_reply_err(_, ENOENT)).Times(1).WillOnce(Return(0)); + + json_t * result = json_object(); + wf_impl_operation_open_finished(nullptr, result, nullptr); + json_decref(result); +} + +TEST(wf_impl_operation_open, finished_fail_invalid_handle_type) +{ + FuseMock fuse; + EXPECT_CALL(fuse, fuse_reply_open(_,_)).Times(0); + EXPECT_CALL(fuse, fuse_reply_err(_, ENOENT)).Times(1).WillOnce(Return(0)); + + json_t * result = json_object(); + json_object_set_new(result, "handle", json_string("42")); + wf_impl_operation_open_finished(nullptr, result, nullptr); + json_decref(result); +} diff --git a/test/webfuse/utils/wrap.hpp b/test/webfuse/utils/wrap.hpp index 9d062d8..4402598 100644 --- a/test/webfuse/utils/wrap.hpp +++ b/test/webfuse/utils/wrap.hpp @@ -71,4 +71,32 @@ } \ } +#define WF_WRAP_FUNC5( GLOBAL_VAR, RETURN_TYPE, FUNC_NAME, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE ) \ + extern RETURN_TYPE __real_ ## FUNC_NAME (ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE); \ + RETURN_TYPE __wrap_ ## FUNC_NAME (ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5) \ + { \ + if (nullptr == GLOBAL_VAR ) \ + { \ + return __real_ ## FUNC_NAME (arg1, arg2, arg3, arg4, arg5); \ + } \ + else \ + { \ + return GLOBAL_VAR -> FUNC_NAME(arg1, arg2, arg3, arg4, arg5); \ + } \ + } + +#define WF_WRAP_FUNC6( GLOBAL_VAR, RETURN_TYPE, FUNC_NAME, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE ) \ + extern RETURN_TYPE __real_ ## FUNC_NAME (ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE); \ + RETURN_TYPE __wrap_ ## FUNC_NAME (ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6) \ + { \ + if (nullptr == GLOBAL_VAR ) \ + { \ + return __real_ ## FUNC_NAME (arg1, arg2, arg3, arg4, arg5, arg6); \ + } \ + else \ + { \ + return GLOBAL_VAR -> FUNC_NAME(arg1, arg2, arg3, arg4, arg5, arg6); \ + } \ + } + #endif