put wf_client into a separate thread for testing

pull/2/head
Falk Werner 4 years ago
parent 4713ec3e93
commit 51cb628410

@ -211,6 +211,7 @@ alltests = executable('alltests',
'test/webfuse/utils/static_filesystem.c',
'test/webfuse/utils/ws_server.cc',
'test/webfuse/utils/ws_server2.cc',
'test/webfuse/utils/adapter_client.cc',
'test/webfuse/utils/jansson_test_environment.cc',
'test/webfuse/mocks/fake_invokation_context.cc',
'test/webfuse/mocks/mock_authenticator.cc',

@ -1,8 +1,8 @@
#include <gtest/gtest.h>
#include <gmock/gmock.h>
#include "webfuse/adapter/client.h"
#include "webfuse/adapter/credentials.h"
#include "webfuse/utils/adapter_client.hpp"
#include "webfuse/adapter/credentials.h"
#include "webfuse/core/protocol_names.h"
#include "webfuse/utils/ws_server2.hpp"
@ -10,6 +10,7 @@
#include "webfuse/mocks/mock_invokation_handler.hpp"
#include "webfuse/utils/timeout_watcher.hpp"
using webfuse_test::AdapterClient;
using webfuse_test::WsServer2;
using webfuse_test::MockInvokationHander;
using webfuse_test::MockAdapterClientCallback;
@ -34,79 +35,6 @@ void GetCredentials(wf_client *, int, void * arg)
wf_credentials_add(creds, "password", "secret");
}
enum class connection_state
{
disconnected,
connected,
connecting
};
struct context
{
connection_state state;
};
void callback(
wf_client * client,
int reason,
void * args)
{
auto * ctx = reinterpret_cast<context*>(wf_client_get_userdata(client));
switch (reason)
{
case WF_CLIENT_CREATED:
ctx->state = connection_state::connecting;
wf_client_connect(client, "ws://dummy-server/");
break;
case WF_CLIENT_CONNECTED:
ctx->state = connection_state::connected;
wf_client_authenticate(client);
break;
case WF_CLIENT_AUTHENTICATED:
wf_client_add_filesystem(client, ".", "test");
break;
case WF_CLIENT_AUTHENTICATION_FAILED:
wf_client_disconnect(client);
break;
case WF_CLIENT_AUTHENTICATE_GET_CREDENTIALS:
{
auto * credentials = reinterpret_cast<wf_credentials*>(args);
wf_credentials_set_type(credentials, "username");
wf_credentials_add(credentials, "user", "bob");
wf_credentials_add(credentials, "password", "secret");
}
break;
case WF_CLIENT_FILESYSTEM_ADDED:
// operational
break;
case WF_CLIENT_FILESYSTEM_ADD_FAILED:
wf_client_disconnect(client);
break;
case WF_CLIENT_DISCONNECTED:
ctx->state = connection_state::disconnected;
break;
default:
break;
}
}
}
TEST(AdapterClient, GeneralUsage)
{
context ctx;
ctx.state = connection_state::connecting;
wf_client * client = wf_client_create(
&callback, reinterpret_cast<void*>(&ctx));
while (ctx.state != connection_state::disconnected)
{
wf_client_service(client);
}
wf_client_dispose(client);
}
TEST(AdapterClient, CreateAndDispose)
@ -141,25 +69,19 @@ TEST(AdapterClient, Connect)
EXPECT_CALL(callback, Invoke(_, WF_CLIENT_CONNECTED, nullptr)).Times(1);
EXPECT_CALL(callback, Invoke(_, WF_CLIENT_DISCONNECTED, nullptr)).Times(1);
AdapterClient client(callback.GetCallbackFn(), callback.GetUserData(), server.GetUrl());
wf_client * client = wf_client_create(
callback.GetCallbackFn(), callback.GetUserData());
wf_client_connect(client, server.GetUrl().c_str());
client.Connect();
while (!server.IsConnected())
{
watcher.check();
wf_client_service(client);
}
wf_client_disconnect(client);
client.Disconnect();
while (server.IsConnected())
{
watcher.check();
wf_client_service(client);
}
wf_client_dispose(client);
}
TEST(AdapterClient, Authenticate)
@ -181,31 +103,24 @@ TEST(AdapterClient, Authenticate)
called = true;
}));
wf_client * client = wf_client_create(
callback.GetCallbackFn(), callback.GetUserData());
AdapterClient client(callback.GetCallbackFn(), callback.GetUserData(), server.GetUrl());
wf_client_connect(client, server.GetUrl().c_str());
client.Connect();
while (!server.IsConnected())
{
watcher.check();
wf_client_service(client);
}
wf_client_authenticate(client);
client.Authenticate();
while (!called) {
watcher.check();
wf_client_service(client);
}
wf_client_disconnect(client);
client.Disconnect();
while (server.IsConnected())
{
watcher.check();
wf_client_service(client);
}
wf_client_dispose(client);
}
TEST(AdapterClient, AuthenticateFailedWithoutConnect)
@ -222,17 +137,12 @@ TEST(AdapterClient, AuthenticateFailedWithoutConnect)
called = true;
}));
wf_client * client = wf_client_create(
callback.GetCallbackFn(), callback.GetUserData());
AdapterClient client(callback.GetCallbackFn(), callback.GetUserData(), "");
wf_client_authenticate(client);
client.Authenticate();
while (!called) {
watcher.check();
wf_client_service(client);
}
wf_client_dispose(client);
}
TEST(AdapterClient, AuthenticationFailed)
@ -254,29 +164,22 @@ TEST(AdapterClient, AuthenticationFailed)
called = true;
}));
wf_client * client = wf_client_create(
callback.GetCallbackFn(), callback.GetUserData());
AdapterClient client(callback.GetCallbackFn(), callback.GetUserData(), server.GetUrl());
wf_client_connect(client, server.GetUrl().c_str());
client.Connect();
while (!server.IsConnected())
{
watcher.check();
wf_client_service(client);
}
wf_client_authenticate(client);
client.Authenticate();
while (!called) {
watcher.check();
wf_client_service(client);
}
wf_client_disconnect(client);
client.Disconnect();
while (server.IsConnected())
{
watcher.check();
wf_client_service(client);
}
wf_client_dispose(client);
}
}

@ -0,0 +1,136 @@
#include "webfuse/utils/adapter_client.hpp"
#include <thread>
#include <mutex>
#include <queue>
namespace
{
enum class Command
{
run,
shutdown,
connect,
disconnect,
authenticate,
add_filesystem
};
}
namespace webfuse_test
{
class AdapterClient::Private
{
public:
Private(
wf_client_callback_fn * callback,
void * user_data,
std::string const & url)
: client(wf_client_create(callback, user_data))
, url_(url)
, command(Command::run)
{
thread = std::thread(&Run, this);
}
~Private()
{
ApplyCommand(Command::shutdown);
thread.join();
wf_client_dispose(client);
}
void ApplyCommand(Command actual_command)
{
{
std::unique_lock<std::mutex> lock(mutex);
command = actual_command;
}
wf_client_interrupt(client);
}
private:
static void Run(Private * self)
{
bool is_running = true;
while (is_running)
{
Command actual_command;
{
std::unique_lock<std::mutex> lock(self->mutex);
actual_command = self->command;
self->command = Command::run;
}
switch (actual_command)
{
case Command::run:
wf_client_service(self->client);
break;
case Command::connect:
wf_client_connect(self->client, self->url_.c_str());
break;
case Command::disconnect:
wf_client_disconnect(self->client);
break;
case Command::authenticate:
wf_client_authenticate(self->client);
break;
case Command::add_filesystem:
wf_client_add_filesystem(self->client, "/tmp", "test");
break;
case Command::shutdown:
// fall-through
default:
is_running = false;
break;
}
}
}
wf_client * client;
std::string url_;
Command command;
std::thread thread;
std::mutex mutex;
};
AdapterClient::AdapterClient(
wf_client_callback_fn * callback,
void * user_data,
std::string const & url)
: d(new Private(callback, user_data, url))
{
}
AdapterClient::~AdapterClient()
{
delete d;
}
void AdapterClient::Connect()
{
d->ApplyCommand(Command::connect);
}
void AdapterClient::Disconnect()
{
d->ApplyCommand(Command::disconnect);
}
void AdapterClient::Authenticate()
{
d->ApplyCommand(Command::authenticate);
}
void AdapterClient::AddFileSystem()
{
d->ApplyCommand(Command::add_filesystem);
}
}

@ -0,0 +1,31 @@
#ifndef WF_UTILS_ADAPTER_CLIENT_HPP
#define WF_UTILS_APAPTER_CLIENT_HPP
#include "webfuse/adapter/client.h"
#include <string>
namespace webfuse_test
{
class AdapterClient
{
AdapterClient(AdapterClient const &) = delete;
AdapterClient& operator=(AdapterClient const &) = delete;
public:
AdapterClient(
wf_client_callback_fn * callback,
void * user_data,
std::string const & url);
~AdapterClient();
void Connect();
void Disconnect();
void Authenticate();
void AddFileSystem();
private:
class Private;
Private * d;
};
}
#endif
Loading…
Cancel
Save