summaryrefslogtreecommitdiffhomepage
path: root/tests
diff options
context:
space:
mode:
Diffstat (limited to 'tests')
-rw-r--r--tests/test-whiteboard.cpp120
1 files changed, 119 insertions, 1 deletions
diff --git a/tests/test-whiteboard.cpp b/tests/test-whiteboard.cpp
index 46c4bae..b183021 100644
--- a/tests/test-whiteboard.cpp
+++ b/tests/test-whiteboard.cpp
@@ -1,21 +1,39 @@
#include <gtest/gtest.h>
+#include <cstring>
#include <filesystem>
#include <memory>
#include <string>
#include <system_error>
+#include <boost/process/child.hpp>
+#include <boost/algorithm/string.hpp>
+#include <boost/beast/core.hpp>
+#include <boost/beast/http.hpp>
+#include <boost/beast/websocket.hpp>
+#include <boost/asio/buffer.hpp>
+#include <boost/asio/buffers_iterator.hpp>
+#include <boost/asio/connect.hpp>
+#include <boost/asio/ip/tcp.hpp>
+#include <boost/asio/local/stream_protocol.hpp>
+
+#include <unistd.h>
+
#include "libreichwein/file.h"
+#include "libreichwein/process.h"
#include "config.h"
#include "storage.h"
#include "whiteboard.h"
+namespace bp = boost::process;
namespace fs = std::filesystem;
using namespace Reichwein;
+using namespace std::string_literals;
namespace {
const fs::path webserverConfigFilename{"./webserver.conf"};
+
const fs::path testConfigFilename{"./whiteboard.conf"};
const fs::path testDbFilename{"./whiteboard.db3"};
}
@@ -25,20 +43,55 @@ class Webserver
public:
Webserver()
{
+ File::setFile(webserverConfigFilename, R"CONFIG(
+<webserver>
+ <user>www-data</user>
+ <group>www-data</group>
+ <threads>10</threads>
+ <statisticspath>stats.db</statisticspath>
+ <plugin-directory>../plugins</plugin-directory>
+ <sites>
+ <site>
+ <host>[::1]</host>
+ <path requested="/">
+ <plugin>websocket</plugin>
+ <target>::1:9876</target>
+ </path>
+ </site>
+ </sites>
+ <sockets>
+ <socket>
+ <address>::1</address>
+ <port>8080</port>
+ <protocol>http</protocol>
+ <site>localhost</site>
+ </socket>
+ </sockets>
+</webserver>
+)CONFIG");
+ start();
}
~Webserver()
{
stop();
+ fs::remove(webserverConfigFilename);
}
- void runInBackground()
+ void start()
{
+ m_child = bp::child("/usr/bin/webserver"s, "-c"s, webserverConfigFilename.generic_string());
+ Process::wait_for_pid_listening_on(m_child.id(), 8080);
+ std::this_thread::sleep_for(std::chrono::milliseconds(20));
}
void stop()
{
+ m_child.terminate();
}
+
+private:
+ bp::child m_child;
};
class WhiteboardTest: public ::testing::Test
@@ -54,27 +107,92 @@ protected:
{
File::setFile(testConfigFilename, R"CONFIG(
<config>
+ <port>::1:9876</port>
<datapath>.</datapath>
<maxage>2592000</maxage>
+ <threads>4</threads>
</config>
)CONFIG");
std::error_code ec;
fs::remove(testDbFilename, ec);
m_config = std::make_shared<Config>(testConfigFilename);
+
+ //m_webserver = std::make_shared<Webserver>(webserverConfigFilename);
+
+ m_pid = fork();
+ if (m_pid == -1) {
+ throw std::runtime_error("Error on fork(): "s + strerror(errno));
+ } else if (m_pid == 0) { // child
+ Whiteboard whiteboard;
+ std::vector<std::string> argvv{{"whiteboard", "-c", testConfigFilename.generic_string()}};
+ char* argv[] = {argvv[0].data(), argvv[1].data(), argvv[2].data(), nullptr};
+ whiteboard.run(argvv.size(), argv);
+ exit(0);
+ }
+ Process::wait_for_pid_listening_on(m_pid, 9876);
+ std::this_thread::sleep_for(std::chrono::milliseconds(20));
}
void TearDown() override
{
+ if (m_pid == 0)
+ throw std::runtime_error("Whiteboard not running on requesting SIGTERM");
+
+ if (kill(m_pid, SIGTERM) != 0)
+ throw std::runtime_error("Unable to SIGTERM Whiteboard");
+
+ if (int result = waitpid(m_pid, NULL, 0); result != m_pid)
+ throw std::runtime_error("waitpid returned "s + std::to_string(result));
+
std::error_code ec;
fs::remove(testDbFilename, ec);
fs::remove(testConfigFilename, ec);
}
std::shared_ptr<Config> m_config;
+ //std::shared_ptr<Webserver> m_webserver;
+ pid_t m_pid{};
};
TEST_F(WhiteboardTest, connection)
{
+ std::string host = "::1";
+ auto const port = "9876" ;
+
+ // The io_context is required for all I/O
+ boost::asio::io_context ioc;
+
+ // These objects perform our I/O
+ boost::asio::ip::tcp::resolver resolver{ioc};
+ boost::beast::websocket::stream<boost::asio::ip::tcp::socket> ws{ioc};
+
+ // Look up the domain name
+ auto const results = resolver.resolve(host, port);
+
+ // Make the connection on the IP address we get from a lookup
+ auto ep = boost::asio::connect(boost::beast::get_lowest_layer(ws), results);
+
+ // Update the host_ string. This will provide the value of the
+ // Host HTTP header during the WebSocket handshake.
+ // See https://tools.ietf.org/html/rfc7230#section-5.4
+ if (host == "::1")
+ host = "[" + host + "]";
+ host += ':' + std::to_string(ep.port());
+
+ // Set a decorator to change the User-Agent of the handshake
+ ws.set_option(boost::beast::websocket::stream_base::decorator(
+ [](boost::beast::websocket::request_type& req)
+ {
+ req.set(boost::beast::http::field::user_agent,
+ std::string("Reichwein.IT Test Websocket Client"));
+ }));
+
+ // Perform the websocket handshake
+ ws.handshake(host, "/");
+}
+
+TEST_F(WhiteboardTest, getfile)
+{
}