From e21c716d348d8d71bf109f95f40b9c54a5411644 Mon Sep 17 00:00:00 2001 From: Falk Werner Date: Sat, 22 Feb 2020 16:46:21 +0100 Subject: [PATCH] refactored fake adapter server into ws server; added test for client protocol getattr --- cmake/unit_tests.cmake | 2 +- test/webfuse/fakes/fake_adapter_server.hpp | 24 ------ .../tests/provider/test_client_protocol.cc | 65 ++++++++++++++- .../ws_server.cc} | 83 ++++++++++++++----- test/webfuse/utils/ws_server.hpp | 27 ++++++ 5 files changed, 153 insertions(+), 48 deletions(-) delete mode 100644 test/webfuse/fakes/fake_adapter_server.hpp rename test/webfuse/{fakes/fake_adapter_server.cc => utils/ws_server.cc} (68%) create mode 100644 test/webfuse/utils/ws_server.hpp diff --git a/cmake/unit_tests.cmake b/cmake/unit_tests.cmake index dfc804e..3e445ed 100644 --- a/cmake/unit_tests.cmake +++ b/cmake/unit_tests.cmake @@ -14,7 +14,7 @@ add_executable(alltests test/webfuse/utils/timeout_watcher.cc test/webfuse/utils/path.c test/webfuse/utils/static_filesystem.c - test/webfuse/fakes/fake_adapter_server.cc + test/webfuse/utils/ws_server.cc test/webfuse/mocks/mock_authenticator.cc test/webfuse/mocks/mock_request.cc test/webfuse/tests/core/test_container_of.cc diff --git a/test/webfuse/fakes/fake_adapter_server.hpp b/test/webfuse/fakes/fake_adapter_server.hpp deleted file mode 100644 index 9cc51f0..0000000 --- a/test/webfuse/fakes/fake_adapter_server.hpp +++ /dev/null @@ -1,24 +0,0 @@ -#ifndef WF_TEST_FAKE_SERVER_HPP -#define WF_TEST_FAKE_SERVER_HPP - -#include - -namespace webfuse_test -{ - -class FakeAdapterServer -{ - FakeAdapterServer(FakeAdapterServer const &) = delete; - FakeAdapterServer & operator=(FakeAdapterServer const &) = delete; -public: - explicit FakeAdapterServer(int port); - ~FakeAdapterServer(); - void waitForConnection(); -private: - class Private; - Private * d; -}; - -} - -#endif diff --git a/test/webfuse/tests/provider/test_client_protocol.cc b/test/webfuse/tests/provider/test_client_protocol.cc index 4faba4f..5212f45 100644 --- a/test/webfuse/tests/provider/test_client_protocol.cc +++ b/test/webfuse/tests/provider/test_client_protocol.cc @@ -3,13 +3,13 @@ #include #include -#include "webfuse/fakes/fake_adapter_server.hpp" +#include "webfuse/utils/ws_server.hpp" #include #include #include -using webfuse_test::FakeAdapterServer; +using webfuse_test::WebsocketServer; using testing::_; namespace @@ -20,7 +20,7 @@ class ClientProtocolTest: public ::testing::Test protected: void SetUp() { - server = new FakeAdapterServer(54321); + server = new WebsocketServer(54321); config = wfp_client_config_create(); protocol = wfp_client_protocol_create(config); @@ -57,7 +57,40 @@ protected: delete server; } - FakeAdapterServer * server; + void awaitAddFilesystem(std::string& filesystemName) + { + json_t * addFilesystemRequest = server->receiveMessage(); + ASSERT_NE(nullptr, addFilesystemRequest); + ASSERT_TRUE(json_is_object(addFilesystemRequest)); + + json_t * method = json_object_get(addFilesystemRequest, "method"); + ASSERT_TRUE(json_is_string(method)); + ASSERT_STREQ("add_filesystem", json_string_value(method)); + + json_t * params = json_object_get(addFilesystemRequest, "params"); + ASSERT_TRUE(json_is_array(params)); + ASSERT_EQ(1, json_array_size(params)); + + json_t * filesystem = json_array_get(params, 0); + ASSERT_TRUE(json_is_string(filesystem)); + filesystemName = json_string_value(filesystem); + + json_t * id = json_object_get(addFilesystemRequest, "id"); + ASSERT_TRUE(json_is_integer(id)); + + json_t * response = json_object(); + json_t * result = json_object(); + json_object_set(result, "id", filesystem); + json_object_set_new(response, "result", result); + json_object_set(response, "id", id); + + server->sendMessage(response); + + json_decref(addFilesystemRequest); + + } + + WebsocketServer * server; private: static void run(ClientProtocolTest * self) @@ -77,10 +110,34 @@ private: }; + } TEST_F(ClientProtocolTest, connect) { server->waitForConnection(); +} + +TEST_F(ClientProtocolTest, getattr) +{ + server->waitForConnection(); + + std::string filesystem; + awaitAddFilesystem(filesystem); + if (HasFatalFailure()) { return; } + + json_t * params = json_array(); + json_array_append_new(params, json_string(filesystem.c_str())); + json_array_append_new(params, json_integer(1)); + json_t * request = json_object(); + json_object_set_new(request, "method", json_string("getattr")); + json_object_set_new(request, "params", params); + json_object_set_new(request, "id", json_integer(42)); + + server->sendMessage(request); + json_t * response = server->receiveMessage(); + ASSERT_TRUE(json_is_object(response)); + + json_decref(response); } \ No newline at end of file diff --git a/test/webfuse/fakes/fake_adapter_server.cc b/test/webfuse/utils/ws_server.cc similarity index 68% rename from test/webfuse/fakes/fake_adapter_server.cc rename to test/webfuse/utils/ws_server.cc index bebd3d9..995d0b8 100644 --- a/test/webfuse/fakes/fake_adapter_server.cc +++ b/test/webfuse/utils/ws_server.cc @@ -1,4 +1,4 @@ -#include "webfuse/fakes/fake_adapter_server.hpp" +#include "webfuse/utils/ws_server.hpp" #include "webfuse/utils/timeout_watcher.hpp" #include "webfuse/core/util.h" @@ -30,7 +30,7 @@ public: extern "C" { -static int wf_test_fake_adapter_server_callback( +static int wf_test_utils_ws_server_callback( struct lws * wsi, enum lws_callback_reasons reason, void * WF_UNUSED_PARAM(user), @@ -65,7 +65,6 @@ static int wf_test_fake_adapter_server_callback( break; } - return 0; } @@ -74,16 +73,15 @@ static int wf_test_fake_adapter_server_callback( namespace webfuse_test { -class FakeAdapterServer::Private: public IServer +class WebsocketServer::Private: public IServer { public: explicit Private(int port) : client_wsi(nullptr) - , message_received(false) { memset(ws_protocols, 0, sizeof(struct lws_protocols) * 2); ws_protocols[0].name = "fs"; - ws_protocols[0].callback = &wf_test_fake_adapter_server_callback; + ws_protocols[0].callback = &wf_test_utils_ws_server_callback; ws_protocols[0].per_session_data_size = 0; ws_protocols[0].user = reinterpret_cast(this); @@ -114,6 +112,44 @@ public: } } + void sendMessage(json_t * message) + { + char* message_text = json_dumps(message, JSON_COMPACT); + writeQueue.push(message_text); + json_decref(message); + free(message_text); + + if (nullptr != client_wsi) + { + lws_callback_on_writable(client_wsi); + + TimeoutWatcher watcher(DEFAULT_TIMEOUT); + while (!writeQueue.empty()) + { + watcher.check(); + lws_service(context, 100); + } + } + + } + + json_t * receiveMessage() + { + TimeoutWatcher watcher(DEFAULT_TIMEOUT); + + while (recvQueue.empty()) + { + watcher.check(); + lws_service(context, 100); + } + + std::string const & message_text = recvQueue.front(); + json_t * message = json_loads(message_text.c_str(), JSON_DECODE_ANY, nullptr); + recvQueue.pop(); + + return message; + } + void onConnectionEstablished(struct lws * wsi) override { client_wsi = wsi; @@ -131,24 +167,23 @@ public: { if (wsi == client_wsi) { - last_message.assign(length, *data); - message_received = true; + recvQueue.push(std::string(data, length)); } } void onWritable(struct lws * wsi) override { - if (!queue.empty()) + if (!writeQueue.empty()) { - std::string const & message = queue.front(); + std::string const & message = writeQueue.front(); unsigned char * data = new unsigned char[LWS_PRE + message.size()]; memcpy(&data[LWS_PRE], message.c_str(), message.size()); lws_write(wsi, &data[LWS_PRE], message.size(), LWS_WRITE_TEXT); delete[] data; - queue.pop(); - if (!queue.empty()) + writeQueue.pop(); + if (!writeQueue.empty()) { lws_callback_on_writable(wsi); } @@ -161,36 +196,46 @@ private: { if (nullptr != client_wsi) { - queue.push(message); + writeQueue.push(message); lws_callback_on_writable(client_wsi); } } struct lws * client_wsi; - bool message_received; struct lws_protocols ws_protocols[2]; struct lws_context_creation_info info; struct lws_context * context; - std::vector last_message; - std::queue queue; + std::queue writeQueue; + std::queue recvQueue; }; -FakeAdapterServer::FakeAdapterServer(int port) +WebsocketServer::WebsocketServer(int port) : d(new Private(port)) { } -FakeAdapterServer::~FakeAdapterServer() +WebsocketServer::~WebsocketServer() { delete d; } -void FakeAdapterServer::waitForConnection() +void WebsocketServer::waitForConnection() { d->waitForConnection(); } +void WebsocketServer::sendMessage(json_t * message) +{ + d->sendMessage(message); +} + +json_t * WebsocketServer::receiveMessage() +{ + return d->receiveMessage(); +} + + } \ No newline at end of file diff --git a/test/webfuse/utils/ws_server.hpp b/test/webfuse/utils/ws_server.hpp new file mode 100644 index 0000000..bacab51 --- /dev/null +++ b/test/webfuse/utils/ws_server.hpp @@ -0,0 +1,27 @@ +#ifndef WF_TEST_UTILS_WS_SERVER_HPP +#define WF_TEST_UTILS_WS_SERVER_HPP + +#include +#include + +namespace webfuse_test +{ + +class WebsocketServer +{ + WebsocketServer(WebsocketServer const &) = delete; + WebsocketServer & operator=(WebsocketServer const &) = delete; +public: + explicit WebsocketServer(int port); + ~WebsocketServer(); + void waitForConnection(); + void sendMessage(json_t * message); + json_t * receiveMessage(); +private: + class Private; + Private * d; +}; + +} + +#endif