remove unused tests

pull/2/head
Falk Werner 4 years ago
parent 797ee2bd15
commit fdd93149fe

@ -117,9 +117,7 @@ alltests = executable('alltests',
'test/webfuse_provider/utils/file_utils.cc',
'test/webfuse_provider/utils/timeout_watcher.cc',
'test/webfuse_provider/utils/path.c',
'test/webfuse_provider/utils/static_filesystem.c',
'test/webfuse_provider/utils/ws_server.cc',
'test/webfuse_provider/utils/ws_server2.cc',
'test/webfuse_provider/utils/jansson_test_environment.cc',
'test/webfuse_provider/mocks/fake_invokation_context.cc',
'test/webfuse_provider/mocks/mock_request.cc',

@ -1,85 +0,0 @@
#include "webfuse_provider/tests/integration/file.hpp"
#include <cstdio>
#include <sstream>
namespace
{
bool invoke(std::string const & command)
{
int exit_code = -1;
FILE * file = ::popen(command.c_str(), "r");
if (nullptr != file)
{
exit_code = ::pclose(file);
}
return (0 == exit_code);
}
}
namespace webfuse_test
{
File::File(std::string const& path)
: path_(path)
{
}
File::~File()
{
}
bool File::isFile()
{
std::stringstream command;
command << "./fs_check -c is_file -f " << path_;
return invoke(command.str());
}
bool File::isDirectory()
{
std::stringstream command;
command << "./fs_check -c is_dir -f " << path_;
return invoke(command.str());
}
bool File::hasAccessRights(int accessRights)
{
std::stringstream command;
command << "./fs_check -c has_mode -f " << path_ << " -a " << accessRights;
return invoke(command.str());
}
bool File::hasSize(size_t size)
{
std::stringstream command;
command << "./fs_check -c has_size -f " << path_ << " -a " << size;
return invoke(command.str());
}
bool File::hasSubdirectory(std::string const & subdir)
{
std::stringstream command;
command << "./fs_check -c has_subdir -f " << path_ << " -a " << subdir;
return invoke(command.str());
}
bool File::hasContents(std::string const & contents)
{
std::stringstream command;
command << "./fs_check -c has_contents -f " << path_ << " -a " << contents;
return invoke(command.str());
}
}

@ -1,26 +0,0 @@
#ifndef WFP_TEST_INTEGRATION_FILE_HPP
#define WFP_TEST_INTEGRATION_FILE_HPP
#include <string>
namespace webfuse_test
{
class File final
{
public:
explicit File(std::string const& path);
~File();
bool isFile();
bool isDirectory();
bool hasAccessRights(int accessRights);
bool hasSize(size_t size);
bool hasSubdirectory(std::string const & subdir);
bool hasContents(std::string const & contents);
private:
std::string path_;
};
}
#endif

@ -1,148 +0,0 @@
#include "webfuse_provider/tests/integration/provider.hpp"
#include "webfuse_provider.h"
#include "webfuse_provider/impl/client.h"
#include <thread>
#include <mutex>
#include <chrono>
#include <string>
#include "webfuse/utils/static_filesystem.h"
using namespace std::chrono_literals;
namespace
{
enum class ConnectionState
{
disconnected,
connected,
connecting
};
}
extern "C"
{
void
webfuse_test_provider_onconnected(
void * user_data)
{
auto * fs = reinterpret_cast<wfp_static_filesystem*>(user_data);
auto * connection_state = reinterpret_cast<ConnectionState*>(wfp_static_filesystem_get_user_data(fs));
*connection_state = ConnectionState::connected;
}
void
webfuse_test_provider_ondisconnected(
void * user_data)
{
auto * fs = reinterpret_cast<wfp_static_filesystem*>(user_data);
auto * connection_state = reinterpret_cast<ConnectionState*>(wfp_static_filesystem_get_user_data(fs));
*connection_state = ConnectionState::disconnected;
}
}
namespace webfuse_test
{
class Provider::Private
{
public:
explicit Private(char const * url)
: is_shutdown_requested(false)
, connection_state(ConnectionState::connecting)
{
config = wfp_client_config_create();
wfp_client_config_set_certpath(config, "client-cert.pem");
wfp_client_config_set_keypath(config, "client-key.pem");
wfp_client_config_set_ca_filepath(config, "server-cert.pem");
wfp_client_config_set_onconnected(config, &webfuse_test_provider_onconnected);
wfp_client_config_set_ondisconnected(config, &webfuse_test_provider_ondisconnected);
fs = wfp_static_filesystem_create(config);
wfp_static_filesystem_set_user_data(fs, reinterpret_cast<void*>(&connection_state));
wfp_static_filesystem_add_text(fs, "hello.txt", 0444, "Hello, World");
client = wfp_client_create(config);
wfp_client_connect(client, url);
while (ConnectionState::connecting == connection_state)
{
wfp_client_service(client);
}
if (ConnectionState::connected == connection_state)
{
thread = std::thread(Run, this);
std::this_thread::sleep_for(200ms);
}
else
{
wfp_client_dispose(client);
wfp_static_filesystem_dispose(fs);
wfp_client_config_dispose(config);
throw std::runtime_error("unable to connect");
}
}
~Private()
{
RequestShutdown();
thread.join();
wfp_client_disconnect(client);
while (ConnectionState::disconnected != connection_state)
{
wfp_client_service(client);
}
wfp_client_dispose(client);
wfp_static_filesystem_dispose(fs);
wfp_client_config_dispose(config);
}
bool IsShutdownRequested()
{
std::lock_guard<std::mutex> lock(shutdown_lock);
return is_shutdown_requested;
}
private:
void RequestShutdown()
{
std::lock_guard<std::mutex> lock(shutdown_lock);
is_shutdown_requested = true;
wfp_client_interrupt(client);
}
static void Run(Provider::Private * context)
{
while (!context->IsShutdownRequested())
{
wfp_client_service(context->client);
}
}
std::mutex shutdown_lock;
std::thread thread;
bool is_shutdown_requested;
ConnectionState connection_state;
wfp_client_config * config;
wfp_static_filesystem * fs;
public:
wfp_client * client;
};
Provider::Provider(char const * url)
: d(new Provider::Private(url))
{
}
Provider::~Provider()
{
delete d;
}
}

@ -1,19 +0,0 @@
#ifndef WFP_TEST_INTEGRATION_PROVIDER
#define WFP_TEST_INTEGRATION_PROVIDER
namespace webfuse_test
{
class Provider
{
public:
explicit Provider(char const * url);
~Provider();
private:
class Private;
Private * d;
};
}
#endif

@ -1,154 +0,0 @@
#include "webfuse_provider/tests/integration/server.hpp"
#include <thread>
#include <mutex>
#include <sstream>
#include <cstdlib>
#include <cstring>
#include <unistd.h>
#include <sys/stat.h>
#include "webfuse_adapter.h"
#include "webfuse/adapter/impl/server.h"
#define WFP_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 wfp_mountpoint *
webfuse_test_server_create_mountpoint(
char const * filesystem,
void * user_data)
{
char const * base_dir = reinterpret_cast<char const*>(user_data);
char path[WFP_PATH_MAX];
snprintf(path, WFP_PATH_MAX, "%s/%s", base_dir, filesystem);
mkdir(path, 0755);
struct wfp_mountpoint * mountpoint = wfp_mountpoint_create(path);
wfp_mountpoint_set_userdata(
mountpoint,
reinterpret_cast<void*>(strdup(path)),
&webfuse_test_server_cleanup_mountpoint);
return mountpoint;
}
}
namespace webfuse_test
{
class Server::Private
{
public:
Private()
: is_shutdown_requested(false)
{
snprintf(base_dir, WFP_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 = wfp_server_config_create();
wfp_server_config_set_port(config, 0);
wfp_server_config_set_mountpoint_factory(config,
&webfuse_test_server_create_mountpoint,
reinterpret_cast<void*>(base_dir));
wfp_server_config_set_keypath(config, "server-key.pem");
wfp_server_config_set_certpath(config, "server-cert.pem");
server = wfp_server_create(config);
while (!wfp_impl_server_is_operational(server))
{
wfp_server_service(server);
}
thread = std::thread(Run, this);
}
~Private()
{
RequestShutdown();
thread.join();
rmdir(base_dir);
wfp_server_dispose(server);
wfp_server_config_dispose(config);
}
bool IsShutdownRequested()
{
std::lock_guard<std::mutex> lock(shutdown_lock);
return is_shutdown_requested;
}
std::string GetUrl(void) const
{
int const port = wfp_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);
is_shutdown_requested = true;
wfp_server_interrupt(server);
}
static void Run(Server::Private * context)
{
while (!context->IsShutdownRequested())
{
wfp_server_service(context->server);
}
}
std::mutex shutdown_lock;
std::thread thread;
bool is_shutdown_requested;
public:
char base_dir[WFP_PATH_MAX];
wfp_server_config * config;
wfp_server * server;
};
Server::Server()
: d(new Server::Private())
{
}
Server::~Server()
{
delete d;
}
char const * Server::GetBaseDir(void) const
{
return d->base_dir;
}
std::string Server::GetUrl(void) const
{
return d->GetUrl();
}
}

@ -1,25 +0,0 @@
#ifndef WFP_TEST_INTEGRATION_SERVER_HPP
#define WFP_TEST_INTEGRATION_SERVER_HPP
#include <string>
namespace webfuse_test
{
class Server
{
public:
Server();
~Server();
void Start(void);
void Stop(void);
char const * GetBaseDir(void) const;
std::string GetUrl(void) const;
private:
class Private;
Private * d;
};
}
#endif

@ -1,97 +0,0 @@
#include <gtest/gtest.h>
#include "webfuse_provider/tests/integration/server.hpp"
#include "webfuse_provider/tests/integration/provider.hpp"
#include "webfuse_provider/tests/integration/file.hpp"
#include <cstdio>
#include <csignal>
#include <cstring>
#include <string>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <dirent.h>
#include <jansson.h>
#include "webfuse_provider/impl/lws_log.h"
using webfuse_test::Server;
using webfuse_test::Provider;
using webfuse_test::File;
namespace
{
class IntegrationTest: public ::testing::Test
{
public:
IntegrationTest()
: server(nullptr)
, provider(nullptr)
{
json_object_seed(0);
wfp_impl_lwslog_disable();
}
protected:
void SetUp()
{
server = new Server();
provider = new Provider(server->GetUrl().c_str());
}
void TearDown()
{
delete provider;
delete server;
}
char const * GetBaseDir() const
{
return server->GetBaseDir();
}
private:
Server * server;
Provider * provider;
};
}
TEST_F(IntegrationTest, HasMountpoint)
{
struct stat buffer;
int rc = stat(GetBaseDir(), &buffer);
ASSERT_EQ(0, rc);
ASSERT_TRUE(S_ISDIR(buffer.st_mode));
}
TEST_F(IntegrationTest, ProvidesTextFile)
{
std::string file_name = std::string(GetBaseDir()) + "/cprovider/hello.txt";
File file(file_name);
ASSERT_TRUE(file.isFile());
ASSERT_TRUE(file.hasAccessRights(0444));
ASSERT_TRUE(file.hasSize(12));
}
TEST_F(IntegrationTest, ReadTextFile)
{
std::string file_name = std::string(GetBaseDir()) + "/cprovider/hello.txt";
File file(file_name);
ASSERT_TRUE(file.hasContents("Hello, World"));
}
TEST_F(IntegrationTest, ReadDir)
{
std::string dir_name = std::string(GetBaseDir()) + "/cprovider";
File dir(dir_name);
ASSERT_TRUE(dir.isDirectory());
ASSERT_TRUE(dir.hasSubdirectory("."));
ASSERT_TRUE(dir.hasSubdirectory(".."));
ASSERT_TRUE(dir.hasSubdirectory("hello.txt"));
ASSERT_FALSE(dir.hasSubdirectory("other"));
}

@ -1,112 +0,0 @@
#include "webfuse_adapter.h"
#include "webfuse_provider.h"
#include <libwebsockets.h>
#include "webfuse/utils/tempdir.hpp"
#include <gtest/gtest.h>
using ::webfuse_test::TempDir;
extern "C"
{
wfp_mountpoint *
wfp_test_integration_lowlevel_create_mountpoint(
char const *, void * user_data)
{
auto * tempDir = reinterpret_cast<TempDir*>(user_data);
return wfp_mountpoint_create(tempDir->path());
}
void
wfp_test_integration_lowlevel_on_connected(
void * user_data)
{
int * state = reinterpret_cast<int*>(user_data);
*state = 1;
}
void
wfp_test_integration_lowlevel_on_disconnected(
void * user_data)
{
int * state = reinterpret_cast<int*>(user_data);
*state = -1;
}
bool
wfp_test_integration_lowlevel_authenticate(
struct wfp_credentials const * credentials,
void * )
{
char const * username = wfp_credentials_get(credentials, "username");
char const * password = wfp_credentials_get(credentials, "password");
return ((0 == strcmp(username, "bob")) && (0 == strcmp(password, "secret")));
}
void
wfp_test_integration_lowlevel_get_credentials(
struct wfp_credentials * credentials,
void * )
{
wfp_credentials_set_type(credentials, "username");
wfp_credentials_add(credentials, "username", "bob");
wfp_credentials_add(credentials, "password", "secret");
}
}
TEST(integration, lowlevel)
{
TempDir dir("wfp_test");
wfp_server_protocol * server_protocol = wfp_server_protocol_create(
&wfp_test_integration_lowlevel_create_mountpoint,
reinterpret_cast<void*>(&dir));
ASSERT_NE(nullptr, server_protocol);
wfp_server_protocol_add_authenticator(server_protocol, "username",
&wfp_test_integration_lowlevel_authenticate, nullptr);
int state = 0;
wfp_client_config * client_config = wfp_client_config_create();
ASSERT_NE(nullptr, client_config);
wfp_client_config_set_userdata(client_config, reinterpret_cast<void*>(&state));
wfp_client_config_set_onconnected(client_config, &wfp_test_integration_lowlevel_on_connected);
wfp_client_config_set_ondisconnected(client_config, &wfp_test_integration_lowlevel_on_disconnected);
wfp_client_config_enable_authentication(client_config, &wfp_test_integration_lowlevel_get_credentials);
wfp_client_protocol * client_protocol = wfp_client_protocol_create(client_config);
ASSERT_NE(nullptr, client_protocol);
lws_protocols protocols[3];
memset(protocols, 0, 3 * sizeof(lws_protocols));
wfp_server_protocol_init_lws(server_protocol, &protocols[0]);
wfp_client_protocol_init_lws(client_protocol, &protocols[1]);
lws_context_creation_info info;
memset(&info, 0, sizeof(info));
info.port = 8080;
info.protocols = protocols;
info.vhost_name = "localhost";
info.ws_ping_pong_interval = 10;
info.options = LWS_SERVER_OPTION_HTTP_HEADERS_SECURITY_BEST_PRACTICES_ENFORCE;
struct lws_context * context = lws_create_context(&info);
ASSERT_NE(nullptr, context);
wfp_client_protocol_connect(client_protocol, context, "ws://localhost:8080/");
while (0 == state)
{
lws_service(context, 0);
}
EXPECT_EQ(1, state);
lws_context_destroy(context);
wfp_client_protocol_dispose(client_protocol);
wfp_client_config_dispose(client_config);
wfp_server_protocol_dispose(server_protocol);
}

@ -1,149 +0,0 @@
#include "webfuse/utils/adapter_client.hpp"
#include "webfuse/utils/tempdir.hpp"
#include <thread>
#include <mutex>
namespace
{
enum class Command
{
run,
shutdown,
connect,
disconnect,
authenticate,
add_filesystem
};
}
namespace webfuse_test
{
class AdapterClient::Private
{
public:
Private(
wfp_client_callback_fn * callback,
void * user_data,
std::string const & url)
: client(wfp_client_create(callback, user_data))
, url_(url)
, command(Command::run)
, tempdir("webfuse_adpter_client")
{
thread = std::thread(&Run, this);
}
~Private()
{
ApplyCommand(Command::shutdown);
thread.join();
wfp_client_dispose(client);
}
void ApplyCommand(Command actual_command)
{
{
std::unique_lock<std::mutex> lock(mutex);
command = actual_command;
}
wfp_client_interrupt(client);
}
std::string GetDir()
{
return tempdir.path();
}
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:
wfp_client_service(self->client);
break;
case Command::connect:
wfp_client_connect(self->client, self->url_.c_str());
break;
case Command::disconnect:
wfp_client_disconnect(self->client);
break;
case Command::authenticate:
wfp_client_authenticate(self->client);
break;
case Command::add_filesystem:
wfp_client_add_filesystem(self->client, self->tempdir.path(), "test");
break;
case Command::shutdown:
// fall-through
default:
is_running = false;
break;
}
}
}
wfp_client * client;
std::string url_;
Command command;
TempDir tempdir;
std::thread thread;
std::mutex mutex;
};
AdapterClient::AdapterClient(
wfp_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);
}
std::string AdapterClient::GetDir() const
{
return d->GetDir();
}
}

@ -1,32 +0,0 @@
#ifndef WFP_UTILS_ADAPTER_CLIENT_HPP
#define WFP_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(
wfp_client_callback_fn * callback,
void * user_data,
std::string const & url);
~AdapterClient();
void Connect();
void Disconnect();
void Authenticate();
void AddFileSystem();
std::string GetDir() const;
private:
class Private;
Private * d;
};
}
#endif

@ -1,421 +0,0 @@
#include "webfuse_provider/utils/static_filesystem.h"
#include "webfuse_provider/client_config.h"
#include "webfuse_provider/dirbuffer.h"
#include "webfuse_provider/operation/error.h"
#include "webfuse_provider/utils/path.h"
#include "webfuse_provider/impl/util.h"
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#define WFP_STATIC_FILESYSTEM_DEFAULT_CAPACITY (16)
#define WFP_STATIC_FILSYSTEM_INODE_ROOT (1)
#define WFP_STATIC_FILESYSTEM_MAX_READ_SIZE (4 * 1024)
struct wfp_static_filesystem_entry
{
size_t inode;
size_t parent;
char * name;
bool is_file;
int mode;
size_t size;
char * content;
wfp_static_filesystem_read_fn * read;
wfp_static_filesystem_get_info_fn * get_info;
void * user_data;
};
struct wfp_static_filesystem
{
struct wfp_static_filesystem_entry * entries;
size_t size;
size_t capacity;
void * user_data;
};
static struct wfp_static_filesystem_entry *
wfp_static_filesystem_get_entry(
struct wfp_static_filesystem * filesystem,
size_t inode)
{
struct wfp_static_filesystem_entry * entry = NULL;
if ((0 < inode) && (inode <= filesystem->size))
{
entry = &filesystem->entries[inode - 1];
}
return entry;
}
static struct wfp_static_filesystem_entry *
wfp_static_filesystem_get_entry_by_name(
struct wfp_static_filesystem * filesystem,
size_t parent,
char const * name)
{
struct wfp_static_filesystem_entry * entry = NULL;
for(size_t i = 0; i < filesystem->size; i++)
{
struct wfp_static_filesystem_entry * current = &filesystem->entries[i];
if ((parent == current->parent) && (0 == strcmp(name, current->name)))
{
entry = current;
break;
}
}
return entry;
}
static struct wfp_static_filesystem_entry *
wfp_static_filesystem_add_entry(
struct wfp_static_filesystem * filesystem)
{
struct wfp_static_filesystem_entry * entry = NULL;
if (filesystem->size >= filesystem->capacity)
{
struct wfp_static_filesystem_entry * entries;
size_t new_capacity = 2 * filesystem->capacity;
size_t new_size = new_capacity * sizeof(struct wfp_static_filesystem_entry);
entries = realloc(filesystem->entries, new_size);
if (NULL != entries)
{
filesystem->entries = entries;
filesystem->capacity = new_capacity;
}
}
if (filesystem->size < filesystem->capacity)
{
entry = &filesystem->entries[filesystem->size];
entry->inode = filesystem->size + 1;
filesystem->size++;
}
return entry;
}
static size_t
wfp_static_filesystem_entry_read(
size_t offset,
char * buffer,
size_t buffer_size,
void * user_data)
{
size_t result = 0;
struct wfp_static_filesystem_entry * entry = user_data;
if (offset < entry->size)
{
size_t remaining = (entry->size - offset);
result = (buffer_size < remaining) ? buffer_size : remaining;
memcpy(buffer, entry->content, result);
}
return result;
}
static void
wfp_static_filesystem_entry_get_info(
void * user_data,
int * result_mode,
size_t * result_size)
{
struct wfp_static_filesystem_entry * entry = user_data;
*result_mode = entry->mode;
*result_size = entry->size;
}
static size_t
wfp_static_filesystem_add_dir(
struct wfp_static_filesystem * filesystem,
size_t parent,
char const * name
)
{
struct wfp_static_filesystem_entry * entry = wfp_static_filesystem_get_entry_by_name(filesystem, parent, name);
if (NULL == entry)
{
entry = wfp_static_filesystem_add_entry(filesystem);
entry->parent = parent;
entry->is_file = false;
entry->mode = 0555;
entry->name = strdup(name);
entry->user_data = entry;
entry->read = &wfp_static_filesystem_entry_read;
entry->get_info = &wfp_static_filesystem_entry_get_info;
entry->size = 0;
entry->content = NULL;
}
return entry->inode;
}
static size_t
wfp_static_filesystem_make_parent(
struct wfp_static_filesystem * filesystem,
struct wfp_path * path)
{
size_t result = WFP_STATIC_FILSYSTEM_INODE_ROOT;
size_t count = wfp_path_element_count(path);
if (0 < count)
{
for(size_t i = 0; i < (count - 1); i++)
{
char const * name = wfp_path_get_element(path, i);
result = wfp_static_filesystem_add_dir(filesystem, result, name);
}
}
return result;
}
static void
wfp_static_filesystem_stat(
struct wfp_static_filesystem_entry * entry,
struct stat * stat
)
{
memset(stat, 0, sizeof(struct stat));
int mode;
size_t size;
entry->get_info(entry->user_data, &mode, &size);
stat->st_ino = entry->inode;
stat->st_size = entry->size;
stat->st_mode = entry->mode & 0777;
stat->st_mode |= (entry->is_file) ? S_IFREG: S_IFDIR;
}
static void wfp_static_filesystem_lookup(
struct wfp_request * request,
ino_t parent,
char const * name,
void * user_data)
{
struct wfp_static_filesystem * filesystem = user_data;
struct wfp_static_filesystem_entry * entry = wfp_static_filesystem_get_entry_by_name(filesystem, parent, name);
if (NULL != entry)
{
struct stat stat;
wfp_static_filesystem_stat(entry, &stat);
wfp_respond_lookup(request, &stat);
}
else
{
wfp_respond_error(request, WFP_BAD_NOENTRY);
}
}
static void wfp_static_filesystem_getattr(
struct wfp_request * request,
ino_t inode,
void * user_data)
{
struct wfp_static_filesystem * filesystem = user_data;
struct wfp_static_filesystem_entry * entry = wfp_static_filesystem_get_entry(filesystem, inode);
if (NULL != entry)
{
struct stat stat;
wfp_static_filesystem_stat(entry, &stat);
wfp_respond_getattr(request, &stat);
}
else
{
wfp_respond_error(request, WFP_BAD_NOENTRY);
}
}
static void wfp_static_filesystem_readdir(
struct wfp_request * request,
ino_t directory,
void * user_data)
{
struct wfp_static_filesystem * filesystem = user_data;
struct wfp_static_filesystem_entry * dir = wfp_static_filesystem_get_entry(filesystem, directory);
if ((NULL != dir) && (!dir->is_file))
{
struct wfp_dirbuffer * buffer = wfp_dirbuffer_create();
wfp_dirbuffer_add(buffer, ".", dir->inode);
wfp_dirbuffer_add(buffer, "..", dir->inode);
for(size_t i = 0; i < filesystem->size; i++)
{
struct wfp_static_filesystem_entry const * entry = &filesystem->entries[i];
if (directory == entry->parent)
{
wfp_dirbuffer_add(buffer, entry->name, entry->inode);
}
}
wfp_respond_readdir(request, buffer);
wfp_dirbuffer_dispose(buffer);
}
else
{
wfp_respond_error(request, WFP_BAD_NOENTRY);
}
}
static void wfp_static_filesystem_open(
struct wfp_request * request,
ino_t inode,
int flags,
void * user_data)
{
struct wfp_static_filesystem * filesystem = user_data;
struct wfp_static_filesystem_entry * entry = wfp_static_filesystem_get_entry(filesystem, inode);
if ((NULL != entry) && (entry->is_file))
{
if (O_RDONLY == (flags & O_ACCMODE))
{
wfp_respond_open(request, 0U);
}
else
{
wfp_respond_error(request, WFP_BAD_ACCESS_DENIED);
}
}
else
{
wfp_respond_error(request, WFP_BAD_NOENTRY);
}
}
static void wfp_static_filesystem_read(
struct wfp_request * request,
ino_t inode,
uint32_t WFP_UNUSED_PARAM(handle),
size_t offset,
size_t length,
void * user_data)
{
struct wfp_static_filesystem * filesystem = user_data;
struct wfp_static_filesystem_entry * entry = wfp_static_filesystem_get_entry(filesystem, inode);
if ((NULL != entry) && (entry->is_file))
{
char buffer[WFP_STATIC_FILESYSTEM_MAX_READ_SIZE];
size_t max_size = (length < WFP_STATIC_FILESYSTEM_MAX_READ_SIZE) ? length : WFP_STATIC_FILESYSTEM_MAX_READ_SIZE;
size_t count = entry->read(offset, buffer, max_size, entry->user_data);
wfp_respond_read(request, buffer, count);
}
else
{
wfp_respond_error(request, WFP_BAD_NOENTRY);
}
}
struct wfp_static_filesystem *
wfp_static_filesystem_create(
struct wfp_client_config * config)
{
(void) config;
struct wfp_static_filesystem * filesystem = malloc(sizeof(struct wfp_static_filesystem));
filesystem->entries = malloc(sizeof(struct wfp_static_filesystem_entry) * WFP_STATIC_FILESYSTEM_DEFAULT_CAPACITY);
filesystem->size = 0;
filesystem->capacity = WFP_STATIC_FILESYSTEM_DEFAULT_CAPACITY;
filesystem->user_data = NULL;
wfp_static_filesystem_add_dir(filesystem, 0, "<root>");
wfp_client_config_set_userdata(config, filesystem);
wfp_client_config_set_onlookup(config, &wfp_static_filesystem_lookup);
wfp_client_config_set_ongetattr(config, &wfp_static_filesystem_getattr);
wfp_client_config_set_onreaddir(config, &wfp_static_filesystem_readdir);
wfp_client_config_set_onopen(config, &wfp_static_filesystem_open);
wfp_client_config_set_onread(config, &wfp_static_filesystem_read);
return filesystem;
}
void
wfp_static_filesystem_dispose(
struct wfp_static_filesystem * filesystem)
{
for(size_t i = 0; i < filesystem->size; i++)
{
struct wfp_static_filesystem_entry * entry = &filesystem->entries[i];
free(entry->name);
free(entry->content);
}
free(filesystem->entries);
free(filesystem);
}
void
wfp_static_filesystem_add(
struct wfp_static_filesystem * filesystem,
char const * path,
int mode,
char const * content,
size_t length)
{
struct wfp_path * path_ = wfp_path_create(path);
if (NULL != path_)
{
size_t parent = wfp_static_filesystem_make_parent(filesystem, path_);
struct wfp_static_filesystem_entry * entry = wfp_static_filesystem_add_entry(filesystem);
entry->parent = parent;
entry->is_file = true;
entry->name = strdup(wfp_path_get_filename(path_));
entry->mode = mode;
entry->size = length;
entry->get_info = &wfp_static_filesystem_entry_get_info;
entry->read = &wfp_static_filesystem_entry_read;
entry->user_data = entry;
entry->content = malloc(length);
memcpy(entry->content, content, length);
wfp_path_dispose(path_);
}
}
void
wfp_static_filesystem_add_text(
struct wfp_static_filesystem * filesystem,
char const * path,
int mode,
char const * content)
{
size_t length = strlen(content);
wfp_static_filesystem_add(filesystem, path, mode, content, length);
}
void
wfp_static_filesystem_set_user_data(
struct wfp_static_filesystem * filesystem,
void * user_data)
{
filesystem->user_data = user_data;
}
void *
wfp_static_filesystem_get_user_data(
struct wfp_static_filesystem * filesystem)
{
return filesystem->user_data;
}

@ -1,72 +0,0 @@
#ifndef WFP_STATIC_FILESYSTEM_H
#define WFP_STATIC_FILESYSTEM_H
#ifndef __cplusplus
#include <stddef.h>
#else
#include <cstddef>
using ::std::size_t;
#endif
#include <webfuse_provider/api.h>
#ifdef __cplusplus
extern "C"
{
#endif
struct wfp_client_config;
struct wfp_static_filesystem;
typedef size_t
wfp_static_filesystem_read_fn(
size_t offset,
char * buffer,
size_t buffer_size,
void * user_data);
typedef void
wfp_static_filesystem_get_info_fn(
void * user_data,
int * result_mode,
size_t * result_size);
extern WFP_API struct wfp_static_filesystem *
wfp_static_filesystem_create(
struct wfp_client_config * config);
extern WFP_API void
wfp_static_filesystem_dispose(
struct wfp_static_filesystem * filesystem);
extern WFP_API void
wfp_static_filesystem_add(
struct wfp_static_filesystem * filesystem,
char const * path,
int mode,
char const * content,
size_t length);
extern WFP_API void
wfp_static_filesystem_add_text(
struct wfp_static_filesystem * filesystem,
char const * path,
int mode,
char const * content);
extern void
wfp_static_filesystem_set_user_data(
struct wfp_static_filesystem * filesystem,
void * user_data);
extern void *
wfp_static_filesystem_get_user_data(
struct wfp_static_filesystem * filesystem);
#ifdef __cplusplus
}
#endif
#endif

@ -1,331 +0,0 @@
#include "webfuse_provider/utils/ws_server2.hpp"
#include "webfuse_provider/impl/lws_log.h"
#include <libwebsockets.h>
#include <thread>
#include <mutex>
#include <chrono>
#include <sstream>
#include <queue>
namespace
{
class IServer
{
public:
virtual ~IServer() = default;
virtual void OnConnected(lws * wsi) = 0;
virtual void OnConnectionClosed(lws * wsi) = 0;
virtual void OnMessageReceived(struct lws * wsi, char const * data, size_t length) = 0;
virtual void OnWritable(struct lws * wsi) = 0;
};
}
extern "C"
{
static int wfp_test_utils_ws_server_callback(
struct lws * wsi,
enum lws_callback_reasons reason,
void * user,
void * in,
size_t len)
{
int result = 0;
struct lws_protocols const * ws_protocol = lws_get_protocol(wsi);
auto * server = reinterpret_cast<IServer*>(nullptr != ws_protocol ? ws_protocol->user : nullptr);
if (nullptr != server)
{
switch (reason)
{
case LWS_CALLBACK_ESTABLISHED:
server->OnConnected(wsi);
break;
case LWS_CALLBACK_CLOSED:
server->OnConnectionClosed(wsi);
break;
case LWS_CALLBACK_RECEIVE:
{
auto * data = reinterpret_cast<char const *>(in);
server->OnMessageReceived(wsi, data, len);
}
break;
case LWS_CALLBACK_SERVER_WRITEABLE:
server->OnWritable(wsi);
break;
default:
break;
}
}
return result;
}
}
namespace webfuse_test
{
class WsServer2::Private : public IServer
{
Private(Private const &) = delete;
Private & operator=(Private const &) = delete;
public:
Private(IIvokationHandler & handler, std::string const & protocol, int port, bool enable_tls);
~Private();
bool IsConnected();
std::string const & GetUrl() const;
void OnConnected(lws * wsi) override;
void OnConnectionClosed(lws * wsi) override;
void OnMessageReceived(struct lws * wsi, char const * data, size_t length) override;
void OnWritable(struct lws * wsi) override;
void SendMessage(char const * message);
void SendMessage(json_t * message);
private:
static void Run(Private * self);
IIvokationHandler & handler_;
std::string protocol_;
bool is_connected;
bool is_shutdown_requested;
lws * wsi_;
lws_context * ws_context;
lws_protocols ws_protocols[2];
lws_context_creation_info info;
std::string url;
std::thread context;
std::mutex mutex;
std::queue<std::string> writeQueue;
};
WsServer2::WsServer2(
IIvokationHandler& handler,
std::string const & protocol,
int port,
bool enable_tls)
: d(new WsServer2::Private(handler, protocol, port, enable_tls))
{
}
WsServer2::~WsServer2()
{
delete d;
}
bool WsServer2::IsConnected()
{
return d->IsConnected();
}
std::string const & WsServer2::GetUrl() const
{
return d->GetUrl();
}
void WsServer2::SendMessage(char const * message)
{
d->SendMessage(message);
}
void WsServer2::SendMessage(json_t * message)
{
d->SendMessage(message);
}
WsServer2::Private::Private(
IIvokationHandler & handler,
std::string const & protocol,
int port,
bool enable_tls)
: handler_(handler)
, protocol_(protocol)
, is_connected(false)
, is_shutdown_requested(false)
, wsi_(nullptr)
{
wfp_impl_lwslog_disable();
IServer * server = this;
memset(ws_protocols, 0, sizeof(struct lws_protocols) * 2 );
ws_protocols[0].name = protocol_.c_str();
ws_protocols[0].callback = &wfp_test_utils_ws_server_callback;
ws_protocols[0].per_session_data_size = 0;
ws_protocols[0].user = reinterpret_cast<void*>(server);
memset(&info, 0, sizeof(struct lws_context_creation_info));
info.port = port;
info.mounts = NULL;
info.protocols =ws_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;
if (enable_tls)
{
info.options |= LWS_SERVER_OPTION_DO_SSL_GLOBAL_INIT;
info.ssl_cert_filepath = "server-cert.pem";
info.ssl_private_key_filepath = "server-key.pem";
}
ws_context = lws_create_context(&info);
std::ostringstream stream;
struct lws_vhost * vhost = lws_create_vhost(ws_context, &info);
stream << (enable_tls ? "wss://" : "ws://")
<< "localhost:" << lws_get_vhost_port(vhost) << "/";
url = stream.str();
context = std::thread(&Run, this);
}
WsServer2::Private::~Private()
{
{
std::unique_lock<std::mutex> lock(mutex);
is_shutdown_requested = true;
}
lws_cancel_service(ws_context);
context.join();
lws_context_destroy(ws_context);
}
void WsServer2::Private::Run(Private * self)
{
bool is_running = true;
while (is_running)
{
lws_service(self->ws_context, 0);
{
std::unique_lock<std::mutex> lock(self->mutex);
is_running = !self->is_shutdown_requested;
}
}
}
bool WsServer2::Private::IsConnected()
{
std::unique_lock<std::mutex> lock(mutex);
return is_connected;
}
void WsServer2::Private::OnConnected(lws * wsi)
{
std::unique_lock<std::mutex> lock(mutex);
is_connected = true;
wsi_ = wsi;
}
void WsServer2::Private::OnConnectionClosed(lws * wsi)
{
std::unique_lock<std::mutex> lock(mutex);
if (wsi == wsi_)
{
is_connected = false;
wsi_ = nullptr;
}
}
void WsServer2::Private::OnWritable(struct lws * wsi)
{
bool notify = false;
{
std::unique_lock<std::mutex> lock(mutex);
if (!writeQueue.empty())
{
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;
writeQueue.pop();
notify = !writeQueue.empty();
}
}
if (notify)
{
lws_callback_on_writable(wsi);
}
}
void WsServer2::Private::SendMessage(char const * message)
{
lws * wsi = nullptr;
{
std::unique_lock<std::mutex> lock(mutex);
if (nullptr != wsi_)
{
writeQueue.push(message);
wsi = wsi_;
}
}
if (nullptr != wsi)
{
lws_callback_on_writable(wsi_);
}
}
void WsServer2::Private::SendMessage(json_t * message)
{
char* message_text = json_dumps(message, JSON_COMPACT);
SendMessage(message_text);
json_decref(message);
free(message_text);
}
void WsServer2::Private::OnMessageReceived(struct lws * wsi, char const * data, size_t length)
{
(void) wsi;
json_t * request = json_loadb(data, length, JSON_DECODE_ANY, nullptr);
json_t * method = json_object_get(request, "method");
json_t * params = json_object_get(request, "params");
json_t * id = json_object_get(request, "id");
if (json_is_string(method) && json_is_array(params) && json_is_integer(id))
{
json_t * response = json_object();
try
{
std::string result_text = handler_.Invoke(json_string_value(method), params);
json_t * result = json_loads(result_text.c_str(), JSON_DECODE_ANY, nullptr);
json_object_set_new(response, "result", result);
}
catch (...)
{
json_t * error = json_object();
json_object_set_new(error, "code", json_integer(1));
json_object_set_new(response, "error", error);
}
json_object_set(response, "id", id);
SendMessage(response);
}
json_decref(request);
}
std::string const & WsServer2::Private::GetUrl() const
{
return url;
}
}

@ -1,39 +0,0 @@
#ifndef WFP_TEST_UTILS_WS_SERVER2_HPP
#define WFP_TEST_UTILS_WS_SERVER2_HPP
#include <jansson.h>
#include <string>
namespace webfuse_test
{
class IIvokationHandler
{
public:
virtual ~IIvokationHandler() = default;
virtual std::string Invoke(char const * method, json_t * params) = 0;
};
class WsServer2
{
WsServer2(WsServer2 const &) = delete;
WsServer2 & operator=(WsServer2 const & ) = delete;
public:
WsServer2(
IIvokationHandler& handler,
std::string const & protocol,
int port = 0,
bool enable_tls = false);
virtual ~WsServer2();
bool IsConnected();
std::string const & GetUrl() const;
void SendMessage(char const * message);
void SendMessage(json_t * message);
private:
class Private;
Private * d;
};
}
#endif
Loading…
Cancel
Save