mirror of
https://github.com/falk-werner/webfuse
synced 2024-10-27 20:34:10 +00:00
added test for server_protocol
This commit is contained in:
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");
|
||||
|
117
test/webfuse/test_server_protocol.cc
Normal file
117
test/webfuse/test_server_protocol.cc
Normal file
@ -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);
|
||||
}
|
41
test/webfuse/test_util/mountpoint_factory.cc
Normal file
41
test/webfuse/test_util/mountpoint_factory.cc
Normal file
@ -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;
|
||||
}
|
||||
|
||||
|
||||
}
|
17
test/webfuse/test_util/mountpoint_factory.hpp
Normal file
17
test/webfuse/test_util/mountpoint_factory.hpp
Normal file
@ -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 "webfuse/test_util/mountpoint_factory.hpp"
|
||||
#include "webfuse/test_util/tempdir.hpp"
|
||||
#include "webfuse/impl/server.h"
|
||||
#include "webfuse/webfuse.h"
|
||||
|
||||
#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/tempdir.hpp"
|
||||
|
||||
#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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
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");
|
||||
|
133
test/webfuse/test_util/server_protocol.cc
Normal file
133
test/webfuse/test_util/server_protocol.cc
Normal file
@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
22
test/webfuse/test_util/server_protocol.hpp
Normal file
22
test/webfuse/test_util/server_protocol.hpp
Normal file
@ -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…
Reference in New Issue
Block a user