1
0
mirror of https://github.com/falk-werner/webfuse-provider synced 2024-10-27 20:44:10 +00:00

refactored fake adapter server into ws server; added test for client protocol getattr

This commit is contained in:
Falk Werner 2020-02-22 16:46:21 +01:00
parent 1a1367eae7
commit e21c716d34
5 changed files with 153 additions and 48 deletions

View File

@ -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

View File

@ -1,24 +0,0 @@
#ifndef WF_TEST_FAKE_SERVER_HPP
#define WF_TEST_FAKE_SERVER_HPP
#include <libwebsockets.h>
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

View File

@ -3,13 +3,13 @@
#include <webfuse/provider/client_protocol.h>
#include <webfuse/provider/client_config.h>
#include "webfuse/fakes/fake_adapter_server.hpp"
#include "webfuse/utils/ws_server.hpp"
#include <cstring>
#include <thread>
#include <atomic>
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,6 +110,7 @@ private:
};
}
@ -84,3 +118,26 @@ 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);
}

View File

@ -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<void*>(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<char> last_message;
std::queue<std::string> queue;
std::queue<std::string> writeQueue;
std::queue<std::string> 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();
}
}

View File

@ -0,0 +1,27 @@
#ifndef WF_TEST_UTILS_WS_SERVER_HPP
#define WF_TEST_UTILS_WS_SERVER_HPP
#include <libwebsockets.h>
#include <jansson.h>
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