added test for server_protocol

pull/79/head
Falk Werner 4 years ago
parent 4f8d438e45
commit 05d2947aa6

@ -124,8 +124,10 @@ alltests = executable('alltests',
'test/webfuse/jsonrpc/test_response_parser.cc',
'test/webfuse/timer/test_timepoint.cc',
'test/webfuse/timer/test_timer.cc',
'test/webfuse/test_util/mountpoint_factory.cc',
'test/webfuse/test_util/tempdir.cc',
'test/webfuse/test_util/server.cc',
'test/webfuse/test_util/server_protocol.cc',
'test/webfuse/test_util/ws_server.cc',
'test/webfuse/test_util/ws_client.cc',
'test/webfuse/test_util/adapter_client.cc',
@ -146,6 +148,7 @@ alltests = executable('alltests',
'test/webfuse/test_message.cc',
'test/webfuse/test_message_queue.cc',
'test/webfuse/test_server.cc',
'test/webfuse/test_server_protocol.cc',
'test/webfuse/test_server_config.cc',
'test/webfuse/test_credentials.cc',
'test/webfuse/test_authenticator.cc',

@ -28,8 +28,6 @@ using testing::AnyNumber;
using testing::AtMost;
using testing::Return;
#define TIMEOUT (std::chrono::seconds(10))
namespace
{
struct wf_mountpoint *
@ -78,7 +76,7 @@ TEST(server, add_filesystem)
Server server;
MockInvokationHander handler;
EXPECT_CALL(handler, Invoke(StrEq("lookup"), _)).Times(AnyNumber());
EXPECT_CALL(handler, Invoke(StrEq("getattr"), GetAttr(1))).Times(1)
EXPECT_CALL(handler, Invoke(StrEq("getattr"), GetAttr(1))).Times(AnyNumber())
.WillOnce(Return("{\"mode\": 420, \"type\": \"dir\"}"));
WsClient client(handler, WF_PROTOCOL_NAME_PROVIDER_CLIENT);
@ -95,6 +93,7 @@ TEST(server, add_filesystem)
json_decref(response);
std::string base_dir = server.GetBaseDir();
ASSERT_TRUE(File(base_dir).isDirectory());
File file(base_dir + "/test");
ASSERT_TRUE(file.isDirectory());
@ -155,7 +154,7 @@ TEST(server, add_filesystem_fail_invalid_name)
auto connected = client.Connect(server.GetPort(), WF_PROTOCOL_NAME_ADAPTER_SERVER);
ASSERT_TRUE(connected);
std::string response_text = client.Invoke("{\"method\": \"add_filesystem\", \"params\": [\"invalid/name\"], \"id\": 42}");
std::string response_text = client.Invoke("{\"method\": \"add_filesystem\", \"params\": [\"invalid_1/name\"], \"id\": 42}");
json_t * response = json_loads(response_text.c_str(), 0, nullptr);
ASSERT_TRUE(json_is_object(response));
json_t * error = json_object_get(response, "error");

@ -0,0 +1,117 @@
#include "webfuse/test_util/server_protocol.hpp"
#include "webfuse/test_util/ws_client.hpp"
#include "webfuse/test_util/file.hpp"
#include "webfuse/mocks/mock_invokation_handler.hpp"
#include "webfuse/mocks/getattr_matcher.hpp"
#include "webfuse/protocol_names.h"
#include <gtest/gtest.h>
#include <gmock/gmock.h>
using webfuse_test::MockInvokationHander;
using webfuse_test::WsClient;
using webfuse_test::ServerProtocol;
using webfuse_test::File;
using webfuse_test::GetAttr;
using testing::_;
using testing::AnyNumber;
using testing::StrEq;
using testing::Return;
TEST(server_protocol, add_filesystem)
{
ServerProtocol server;
MockInvokationHander handler;
EXPECT_CALL(handler, Invoke(StrEq("lookup"), _)).Times(AnyNumber());
EXPECT_CALL(handler, Invoke(StrEq("getattr"), GetAttr(1))).Times(AnyNumber())
.WillOnce(Return("{\"mode\": 420, \"type\": \"dir\"}"));
WsClient client(handler, WF_PROTOCOL_NAME_PROVIDER_CLIENT);
auto connected = client.Connect(server.GetPort(), WF_PROTOCOL_NAME_ADAPTER_SERVER, false);
ASSERT_TRUE(connected);
{
std::string response_text = client.Invoke("{\"method\": \"authenticate\", \"params\": [\"username\", {\"username\": \"bob\", \"password\": \"secret\"}], \"id\": 23}");
json_t * response = json_loads(response_text.c_str(), 0, nullptr);
ASSERT_TRUE(json_is_object(response));
json_t * result = json_object_get(response, "result");
ASSERT_TRUE(json_is_object(result));
json_t * id = json_object_get(response, "id");
ASSERT_EQ(23, json_integer_value(id));
json_decref(response);
}
{
std::string response_text = client.Invoke("{\"method\": \"add_filesystem\", \"params\": [\"test\"], \"id\": 42}");
json_t * response = json_loads(response_text.c_str(), 0, nullptr);
ASSERT_TRUE(json_is_object(response));
json_t * result = json_object_get(response, "result");
ASSERT_TRUE(json_is_object(result));
json_t * id = json_object_get(response, "id");
ASSERT_EQ(42, json_integer_value(id));
json_decref(response);
}
std::string base_dir = server.GetBaseDir();
ASSERT_TRUE(File(base_dir).isDirectory());
File file(base_dir + "/test");
ASSERT_TRUE(file.isDirectory());
auto disconnected = client.Disconnect();
ASSERT_TRUE(disconnected);
}
TEST(server_protocol, add_filesystem_fail_without_authentication)
{
ServerProtocol server;
MockInvokationHander handler;
EXPECT_CALL(handler, Invoke(StrEq("lookup"), _)).Times(AnyNumber());
EXPECT_CALL(handler, Invoke(StrEq("getattr"), GetAttr(1))).Times(AnyNumber())
.WillOnce(Return("{\"mode\": 420, \"type\": \"dir\"}"));
WsClient client(handler, WF_PROTOCOL_NAME_PROVIDER_CLIENT);
auto connected = client.Connect(server.GetPort(), WF_PROTOCOL_NAME_ADAPTER_SERVER, false);
ASSERT_TRUE(connected);
{
std::string response_text = client.Invoke("{\"method\": \"add_filesystem\", \"params\": [\"test\"], \"id\": 42}");
json_t * response = json_loads(response_text.c_str(), 0, nullptr);
ASSERT_TRUE(json_is_object(response));
json_t * error = json_object_get(response, "error");
ASSERT_TRUE(json_is_object(error));
json_t * id = json_object_get(response, "id");
ASSERT_EQ(42, json_integer_value(id));
json_decref(response);
}
auto disconnected = client.Disconnect();
ASSERT_TRUE(disconnected);
}
TEST(server_protocol, authenticate_fail_wrong_credentials)
{
ServerProtocol server;
MockInvokationHander handler;
EXPECT_CALL(handler, Invoke(StrEq("lookup"), _)).Times(AnyNumber());
EXPECT_CALL(handler, Invoke(StrEq("getattr"), GetAttr(1))).Times(AnyNumber())
.WillOnce(Return("{\"mode\": 420, \"type\": \"dir\"}"));
WsClient client(handler, WF_PROTOCOL_NAME_PROVIDER_CLIENT);
auto connected = client.Connect(server.GetPort(), WF_PROTOCOL_NAME_ADAPTER_SERVER, false);
ASSERT_TRUE(connected);
{
std::string response_text = client.Invoke("{\"method\": \"authenticate\", \"params\": [\"username\", {\"username\": \"alice\", \"password\": \"cheshire\"}], \"id\": 23}");
json_t * response = json_loads(response_text.c_str(), 0, nullptr);
ASSERT_TRUE(json_is_object(response));
json_t * error = json_object_get(response, "error");
ASSERT_TRUE(json_is_object(error));
json_t * id = json_object_get(response, "id");
ASSERT_EQ(23, json_integer_value(id));
json_decref(response);
}
auto disconnected = client.Disconnect();
ASSERT_TRUE(disconnected);
}

@ -0,0 +1,41 @@
#include "webfuse/test_util/mountpoint_factory.hpp"
#include "webfuse/mountpoint.h"
#include <cstdio>
#include <cstdlib>
#include <unistd.h>
#include <sys/stat.h>
#include <string>
extern "C"
{
static void
webfuse_test_cleanup_mountpoint(
void * user_data)
{
char * path = reinterpret_cast<char*>(user_data);
rmdir(path);
free(path);
}
struct wf_mountpoint *
webfuse_test_create_mountpoint(
char const * filesystem,
void * user_data)
{
char const * base_dir = reinterpret_cast<char const*>(user_data);
char * path;
asprintf(&path, "%s/%s", base_dir, filesystem);
mkdir(path, 0755);
struct wf_mountpoint * mountpoint = wf_mountpoint_create(path);
wf_mountpoint_set_userdata(
mountpoint,
reinterpret_cast<void*>(path),
&webfuse_test_cleanup_mountpoint);
return mountpoint;
}
}

@ -0,0 +1,17 @@
#ifndef WF_TEST_UTIL_MOUNTPOINT_FACTORY_HPP
#define WF_TEST_UTIL_MOUNTPOINT_FACTORY_HPP
extern "C"
{
struct wf_mountpoint;
extern wf_mountpoint *
webfuse_test_create_mountpoint(
char const * filesystem,
void * user_data);
}
#endif

@ -1,48 +1,12 @@
#include "webfuse/test_util/server.hpp"
#include <thread>
#include <mutex>
#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/mountpoint_factory.hpp"
#include "webfuse/test_util/tempdir.hpp"
#include "webfuse/impl/server.h"
#include "webfuse/webfuse.h"
#define WF_PATH_MAX (100)
extern "C"
{
static void webfuse_test_server_cleanup_mountpoint(
void * user_data)
{
char * path = reinterpret_cast<char*>(user_data);
rmdir(path);
free(path);
}
static struct wf_mountpoint *
webfuse_test_server_create_mountpoint(
char const * filesystem,
void * user_data)
{
char const * base_dir = reinterpret_cast<char const*>(user_data);
char path[WF_PATH_MAX];
snprintf(path, WF_PATH_MAX, "%s/%s", base_dir, filesystem);
mkdir(path, 0755);
struct wf_mountpoint * mountpoint = wf_mountpoint_create(path);
wf_mountpoint_set_userdata(
mountpoint,
reinterpret_cast<void*>(strdup(path)),
&webfuse_test_server_cleanup_mountpoint);
return mountpoint;
}
}
#include <thread>
#include <mutex>
namespace webfuse_test
{
@ -52,12 +16,12 @@ class Server::Private
public:
Private()
: is_shutdown_requested(false)
, tempdir("webfuse_test_integration")
, tempdir("webfuse_test_server")
{
config = wf_server_config_create();
wf_server_config_set_port(config, 0);
wf_server_config_set_mountpoint_factory(config,
&webfuse_test_server_create_mountpoint,
&webfuse_test_create_mountpoint,
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");

@ -0,0 +1,133 @@
#include "webfuse/test_util/server_protocol.hpp"
#include "webfuse/test_util/mountpoint_factory.hpp"
#include "webfuse/test_util/tempdir.hpp"
#include "webfuse/server_protocol.h"
#include "webfuse/credentials.h"
#include <libwebsockets.h>
#include <cstring>
#include <thread>
#include <mutex>
namespace webfuse_test
{
extern "C" bool webfuse_test_server_protocol_authenticate(
wf_credentials const * credentials,
void *)
{
char const * username = wf_credentials_get(credentials, "username");
char const * password = wf_credentials_get(credentials, "password");
return ((nullptr != username) && (nullptr != password) &&
(0 == strcmp("bob", username)) &&
(0 == strcmp("secret", password)));
}
class ServerProtocol::Private
{
public:
Private();
~Private();
char const * GetBaseDir();
int GetPort() const;
private:
static void Run(Private * self);
bool is_shutdown_requested;
TempDir tempdir;
int port;
wf_server_protocol * protocol;
lws_context * context;
lws_context_creation_info info;
lws_protocols protocols[2];
std::thread thread;
std::mutex mutex;
};
ServerProtocol::ServerProtocol()
: d(new Private())
{
}
ServerProtocol::~ServerProtocol()
{
delete d;
}
char const * ServerProtocol::GetBaseDir() const
{
return d->GetBaseDir();
}
int ServerProtocol::GetPort() const
{
return d->GetPort();
}
ServerProtocol::Private::Private()
: is_shutdown_requested(false)
, tempdir("webfuse_test_server_protocol")
{
protocol = wf_server_protocol_create(
&webfuse_test_create_mountpoint,
reinterpret_cast<void*>(const_cast<char*>(tempdir.path())));
wf_server_protocol_add_authenticator(protocol, "username",
&webfuse_test_server_protocol_authenticate, nullptr);
memset(protocols, 0, 2 * sizeof(lws_protocols));
wf_server_protocol_init_lws(protocol, &protocols[0]);
memset(&info, 0, sizeof(lws_context_creation_info));
info.port = 0;
info.protocols = protocols;
info.vhost_name = "localhost";
info.ws_ping_pong_interval = 10;
info.options = LWS_SERVER_OPTION_HTTP_HEADERS_SECURITY_BEST_PRACTICES_ENFORCE;
info.options |= LWS_SERVER_OPTION_EXPLICIT_VHOSTS;
context = lws_create_context(&info);
struct lws_vhost * const vhost = lws_create_vhost(context, &info);
port = lws_get_vhost_port(vhost);
thread = std::thread(&Run, this);
}
ServerProtocol::Private::~Private()
{
std::unique_lock<std::mutex> lock(mutex);
is_shutdown_requested = true;
lock.unlock();
lws_cancel_service(context);
thread.join();
lws_context_destroy(context);
wf_server_protocol_dispose(protocol);
}
char const * ServerProtocol::Private::GetBaseDir()
{
return tempdir.path();
}
int ServerProtocol::Private::GetPort() const
{
return port;
}
void ServerProtocol::Private::Run(Private * self)
{
std::unique_lock<std::mutex> lock(self->mutex);
while(!self->is_shutdown_requested)
{
lock.unlock();
lws_service(self->context, 0);
lock.lock();
}
}
}

@ -0,0 +1,22 @@
#ifndef WF_TEST_UTIL_SERVER_PROTOCOL_HPP
#define WF_TEST_UTIL_SERVER_PROTOCOL_HPP
namespace webfuse_test
{
class ServerProtocol
{
public:
ServerProtocol();
~ServerProtocol();
char const * GetBaseDir() const;
int GetPort() const;
private:
class Private;
Private * d;
};
}
#endif
Loading…
Cancel
Save