mirror of
https://github.com/falk-werner/webfuse
synced 2024-10-27 20:34:10 +00:00
added websockets client and server wrapper
This commit is contained in:
parent
cdb36eaea1
commit
6db99b0634
@ -126,9 +126,12 @@ alltests = executable('alltests',
|
||||
'test/webfuse/timer/test_timer.cc',
|
||||
'test/webfuse/test_util/tempdir.cc',
|
||||
'test/webfuse/test_util/file_utils.cc',
|
||||
'test/webfuse/test_util/server.cc',
|
||||
'test/webfuse/test_util/ws_server.cc',
|
||||
'test/webfuse/test_util/ws_client.cc',
|
||||
'test/webfuse/test_util/adapter_client.cc',
|
||||
'test/webfuse/test_util/jansson_test_environment.cc',
|
||||
'test/webfuse/test_util/lws_test_environment.cc',
|
||||
'test/webfuse/mocks/mock_authenticator.cc',
|
||||
'test/webfuse/mocks/mock_fuse.cc',
|
||||
'test/webfuse/mocks/mock_operation_context.cc',
|
||||
|
@ -2,7 +2,7 @@
|
||||
#define WF_MOCK_INVOKATION_HANDLER_HPP
|
||||
|
||||
#include "webfuse/test_util/invokation_handler.hpp"
|
||||
#include <gtest/gtest.h>
|
||||
#include <gmock/gmock.h>
|
||||
|
||||
namespace webfuse_test
|
||||
{
|
||||
|
@ -4,9 +4,20 @@
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
#include <chrono>
|
||||
|
||||
#include "webfuse/server.h"
|
||||
#include "webfuse/server_config.h"
|
||||
#include "webfuse/test_util/server.hpp"
|
||||
#include "webfuse/test_util/ws_client.hpp"
|
||||
#include "webfuse/mocks/mock_invokation_handler.hpp"
|
||||
#include "webfuse/protocol_names.h"
|
||||
|
||||
using webfuse_test::MockInvokationHander;
|
||||
using webfuse_test::WsClient;
|
||||
using webfuse_test::Server;
|
||||
|
||||
#define TIMEOUT (std::chrono::seconds(10))
|
||||
|
||||
namespace
|
||||
{
|
||||
@ -37,3 +48,14 @@ TEST(server, create_dispose)
|
||||
|
||||
rmdir("test");
|
||||
}
|
||||
|
||||
TEST(server, connect)
|
||||
{
|
||||
Server server;
|
||||
MockInvokationHander handler;
|
||||
WsClient client(handler, WF_PROTOCOL_NAME_PROVIDER_CLIENT);
|
||||
|
||||
auto future = client.Connect(server.GetPort(), WF_PROTOCOL_NAME_ADAPTER_SERVER);
|
||||
ASSERT_EQ(std::future_status::ready, future.wait_for(TIMEOUT));
|
||||
// future.get();
|
||||
}
|
16
test/webfuse/test_util/lws_test_environment.cc
Normal file
16
test/webfuse/test_util/lws_test_environment.cc
Normal file
@ -0,0 +1,16 @@
|
||||
#include <gtest/gtest.h>
|
||||
#include "webfuse/impl/util/lws_log.h"
|
||||
|
||||
namespace webfuse_test
|
||||
{
|
||||
|
||||
class LwsTestEnvironment: public testing::Environment
|
||||
{
|
||||
public:
|
||||
void SetUp()
|
||||
{
|
||||
wf_impl_lwslog_disable();
|
||||
}
|
||||
};
|
||||
|
||||
}
|
@ -1,13 +1,15 @@
|
||||
#include "webfuse/tests/integration/server.hpp"
|
||||
#include "webfuse/test_util/server.hpp"
|
||||
#include <thread>
|
||||
#include <mutex>
|
||||
#include <sstream>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include <unistd.h>
|
||||
#include <sys/stat.h>
|
||||
#include <string>
|
||||
|
||||
#include "webfuse/webfuse.h"
|
||||
#include "webfuse/impl/server.h"
|
||||
#include "webfuse/test_util/tempdir.hpp"
|
||||
|
||||
#define WF_PATH_MAX (100)
|
||||
|
||||
@ -50,20 +52,13 @@ class Server::Private
|
||||
public:
|
||||
Private()
|
||||
: is_shutdown_requested(false)
|
||||
, tempdir("webfuse_test_integration")
|
||||
{
|
||||
snprintf(base_dir, WF_PATH_MAX, "%s", "/tmp/webfuse_test_integration_XXXXXX");
|
||||
char const * result = mkdtemp(base_dir);
|
||||
if (NULL == result)
|
||||
{
|
||||
throw std::runtime_error("unable to create temp dir");
|
||||
}
|
||||
|
||||
|
||||
config = wf_server_config_create();
|
||||
wf_server_config_set_port(config, 0);
|
||||
wf_server_config_set_mountpoint_factory(config,
|
||||
&webfuse_test_server_create_mountpoint,
|
||||
reinterpret_cast<void*>(base_dir));
|
||||
reinterpret_cast<void*>(const_cast<char*>(tempdir.path())));
|
||||
wf_server_config_set_keypath(config, "server-key.pem");
|
||||
wf_server_config_set_certpath(config, "server-cert.pem");
|
||||
|
||||
@ -82,26 +77,35 @@ public:
|
||||
{
|
||||
RequestShutdown();
|
||||
thread.join();
|
||||
rmdir(base_dir);
|
||||
wf_server_dispose(server);
|
||||
wf_server_config_dispose(config);
|
||||
}
|
||||
|
||||
char const * GetBaseDir()
|
||||
{
|
||||
return tempdir.path();
|
||||
}
|
||||
|
||||
int GetPort(void) const
|
||||
{
|
||||
return wf_server_get_port(server);
|
||||
}
|
||||
|
||||
private:
|
||||
static void Run(Private * context)
|
||||
{
|
||||
while (!context->IsShutdownRequested())
|
||||
{
|
||||
wf_server_service(context->server);
|
||||
}
|
||||
}
|
||||
|
||||
bool IsShutdownRequested()
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(shutdown_lock);
|
||||
return is_shutdown_requested;
|
||||
}
|
||||
|
||||
std::string GetUrl(void) const
|
||||
{
|
||||
int const port = wf_server_get_port(server);
|
||||
std::ostringstream stream;
|
||||
stream << "wss://localhost:" << port << "/";
|
||||
return stream.str();
|
||||
}
|
||||
|
||||
private:
|
||||
void RequestShutdown()
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(shutdown_lock);
|
||||
@ -109,22 +113,10 @@ private:
|
||||
wf_server_interrupt(server);
|
||||
}
|
||||
|
||||
static void Run(Server::Private * context)
|
||||
{
|
||||
while (!context->IsShutdownRequested())
|
||||
{
|
||||
wf_server_service(context->server);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
std::mutex shutdown_lock;
|
||||
std::thread thread;
|
||||
bool is_shutdown_requested;
|
||||
|
||||
|
||||
public:
|
||||
char base_dir[WF_PATH_MAX];
|
||||
TempDir tempdir;
|
||||
wf_server_config * config;
|
||||
wf_server * server;
|
||||
};
|
||||
@ -142,12 +134,12 @@ Server::~Server()
|
||||
|
||||
char const * Server::GetBaseDir(void) const
|
||||
{
|
||||
return d->base_dir;
|
||||
return d->GetBaseDir();
|
||||
}
|
||||
|
||||
std::string Server::GetUrl(void) const
|
||||
int Server::GetPort(void) const
|
||||
{
|
||||
return d->GetUrl();
|
||||
return d->GetPort();
|
||||
}
|
||||
|
||||
|
@ -1,8 +1,6 @@
|
||||
#ifndef WF_TEST_INTEGRATION_SERVER_HPP
|
||||
#define WF_TEST_INTEGRATION_SERVER_HPP
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace webfuse_test
|
||||
{
|
||||
|
||||
@ -11,10 +9,8 @@ class Server
|
||||
public:
|
||||
Server();
|
||||
~Server();
|
||||
void Start(void);
|
||||
void Stop(void);
|
||||
char const * GetBaseDir(void) const;
|
||||
std::string GetUrl(void) const;
|
||||
int GetPort(void) const;
|
||||
private:
|
||||
class Private;
|
||||
Private * d;
|
197
test/webfuse/test_util/ws_client.cc
Normal file
197
test/webfuse/test_util/ws_client.cc
Normal file
@ -0,0 +1,197 @@
|
||||
#include "webfuse/test_util/ws_client.hpp"
|
||||
#include "webfuse/test_util/invokation_handler.hpp"
|
||||
|
||||
#include <libwebsockets.h>
|
||||
|
||||
#include <cstring>
|
||||
#include <thread>
|
||||
#include <mutex>
|
||||
#include <queue>
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
class IServer
|
||||
{
|
||||
public:
|
||||
virtual ~IServer() = default;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
extern "C"
|
||||
{
|
||||
|
||||
static int webfuse_test_WsClient_callback(
|
||||
lws * wsi,
|
||||
lws_callback_reasons reason,
|
||||
void * user,
|
||||
void * in,
|
||||
size_t len)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
namespace webfuse_test
|
||||
{
|
||||
|
||||
class WsClient::Private: public IServer
|
||||
{
|
||||
public:
|
||||
Private(
|
||||
InvokationHandler & handler,
|
||||
std::string const & protocol)
|
||||
: handler_(handler)
|
||||
, protocol_(protocol)
|
||||
, remote_port(0)
|
||||
, remote_use_tls(false)
|
||||
{
|
||||
IServer * self = this;
|
||||
|
||||
memset(protocols, 0, sizeof(lws_protocols) * 2);
|
||||
protocols[0].name = protocol_.c_str();
|
||||
protocols[0].callback = &webfuse_test_WsClient_callback;
|
||||
protocols[0].per_session_data_size = 0;
|
||||
protocols[0].user = self;
|
||||
|
||||
memset(&info, 0, sizeof(lws_context_creation_info));
|
||||
info.port = CONTEXT_PORT_NO_LISTEN;
|
||||
info.protocols = protocols;
|
||||
info.uid = -1;
|
||||
info.gid = -1;
|
||||
info.options = LWS_SERVER_OPTION_EXPLICIT_VHOSTS;
|
||||
|
||||
context = lws_create_context(&info);
|
||||
|
||||
lws_vhost * vhost = lws_create_vhost(context, & info);
|
||||
info.options |= LWS_SERVER_OPTION_DO_SSL_GLOBAL_INIT;
|
||||
info.client_ssl_cert_filepath = "client-cert.pem";
|
||||
info.client_ssl_private_key_filepath = "client-key.pem";
|
||||
info.client_ssl_ca_filepath = "server-cert.pem";
|
||||
lws_init_vhost_client_ssl(&info, vhost);
|
||||
|
||||
thread = std::thread(&Run, this);
|
||||
}
|
||||
|
||||
~Private()
|
||||
{
|
||||
Invoke(command::shutdown);
|
||||
lws_cancel_service(context);
|
||||
|
||||
thread.join();
|
||||
lws_context_destroy(context);
|
||||
}
|
||||
|
||||
std::future<void> Connect(int port, std::string const & protocol, bool use_tls)
|
||||
{
|
||||
{
|
||||
std::unique_lock<std::mutex> lock(mutex);
|
||||
remote_port = port;
|
||||
remote_protocol = protocol;
|
||||
remote_use_tls = use_tls;
|
||||
commands.push(command::connect);
|
||||
}
|
||||
|
||||
std::promise<void> p;
|
||||
p.set_exception(std::make_exception_ptr(std::runtime_error("not implemented")));
|
||||
return p.get_future();
|
||||
}
|
||||
|
||||
std::future<std::string> Invoke(std::string const & message)
|
||||
{
|
||||
std::promise<std::string> p;
|
||||
p.set_exception(std::make_exception_ptr(std::runtime_error("not implemented")));
|
||||
return p.get_future();
|
||||
}
|
||||
|
||||
private:
|
||||
enum class command
|
||||
{
|
||||
run,
|
||||
shutdown,
|
||||
connect
|
||||
};
|
||||
|
||||
static void Run(Private * self)
|
||||
{
|
||||
bool is_running = true;
|
||||
|
||||
while (is_running)
|
||||
{
|
||||
switch (self->GetCommand())
|
||||
{
|
||||
case command::run:
|
||||
lws_service(self->context, 0);
|
||||
break;
|
||||
case command::shutdown:
|
||||
is_running = false;
|
||||
break;
|
||||
case command::connect:
|
||||
// ToDo: connect
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
command GetCommand()
|
||||
{
|
||||
std::unique_lock<std::mutex> lock(mutex);
|
||||
|
||||
command command = command::run;
|
||||
if (!commands.empty())
|
||||
{
|
||||
command = commands.front();
|
||||
commands.pop();
|
||||
}
|
||||
|
||||
return command;
|
||||
}
|
||||
|
||||
void Invoke(command command)
|
||||
{
|
||||
std::unique_lock<std::mutex> lock(mutex);
|
||||
commands.push(command);
|
||||
}
|
||||
|
||||
InvokationHandler & handler_;
|
||||
std::string protocol_;
|
||||
lws_context_creation_info info;
|
||||
lws_protocols protocols[2];
|
||||
lws_context * context;
|
||||
std::thread thread;
|
||||
std::mutex mutex;
|
||||
std::queue<command> commands;
|
||||
int remote_port;
|
||||
std::string remote_protocol;
|
||||
bool remote_use_tls;
|
||||
};
|
||||
|
||||
WsClient::WsClient(
|
||||
InvokationHandler& handler,
|
||||
std::string const & protocol)
|
||||
: d(new Private(handler, protocol))
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
WsClient::~WsClient()
|
||||
{
|
||||
delete d;
|
||||
}
|
||||
|
||||
std::future<void> WsClient::Connect(int port, std::string const & protocol, bool use_tls)
|
||||
{
|
||||
return d->Connect(port, protocol, use_tls);
|
||||
}
|
||||
|
||||
std::future<std::string> WsClient::Invoke(std::string const & message)
|
||||
{
|
||||
return d->Invoke(message);
|
||||
}
|
||||
|
||||
|
||||
}
|
30
test/webfuse/test_util/ws_client.hpp
Normal file
30
test/webfuse/test_util/ws_client.hpp
Normal file
@ -0,0 +1,30 @@
|
||||
#ifndef WF_TEST_UTIL_WS_CLIENT_HPP
|
||||
#define WF_TEST_UTIL_WS_CLIENT_HPP
|
||||
|
||||
#include <string>
|
||||
#include <future>
|
||||
|
||||
namespace webfuse_test
|
||||
{
|
||||
|
||||
class InvokationHandler;
|
||||
|
||||
class WsClient
|
||||
{
|
||||
WsClient(WsClient const &) = delete;
|
||||
WsClient & operator=(WsClient const &) = delete;
|
||||
public:
|
||||
WsClient(
|
||||
InvokationHandler& handler,
|
||||
std::string const & protocol);
|
||||
virtual ~WsClient();
|
||||
std::future<void> Connect(int port, std::string const & protocol, bool use_tls = true);
|
||||
std::future<std::string> Invoke(std::string const & message);
|
||||
private:
|
||||
class Private;
|
||||
Private *d;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
@ -143,7 +143,6 @@ WsServer::Private::Private(
|
||||
, is_shutdown_requested(false)
|
||||
, wsi_(nullptr)
|
||||
{
|
||||
wf_impl_lwslog_disable();
|
||||
IServer * server = this;
|
||||
memset(ws_protocols, 0, sizeof(struct lws_protocols) * 2 );
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user