summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorRoland Reichwein <mail@reichwein.it>2023-01-28 17:06:57 +0100
committerRoland Reichwein <mail@reichwein.it>2023-01-28 17:06:57 +0100
commit4247b81e7756ce1ff01e097e634a9dcbc0912787 (patch)
treeaf14dd7aedf6b06826b5c15e3994431ed86f84a7
parenta61c702d91d7444ce0bb094ddccc70f72416500b (diff)
Added tests
-rw-r--r--connectionregistry.h12
-rw-r--r--diff.cpp4
-rw-r--r--tests/Makefile1
-rw-r--r--tests/test-connectionregistry.cpp144
-rw-r--r--tests/test-diff.cpp110
-rw-r--r--tests/test-whiteboard.cpp68
6 files changed, 272 insertions, 67 deletions
diff --git a/connectionregistry.h b/connectionregistry.h
index cdd30d9..155ab31 100644
--- a/connectionregistry.h
+++ b/connectionregistry.h
@@ -22,16 +22,18 @@ public:
void addConnection(connection c);
void delConnection(connection c);
- // map connection to id
- std::unordered_map<connection, std::string> m_connections;
- // map id to list of related connections, used for iteration over connections to notify about changes
- std::unordered_map<std::string, std::unordered_set<connection>> m_ids;
-
std::unordered_set<connection>::iterator begin(const std::string& id);
std::unordered_set<connection>::iterator end(const std::string& id);
void dump() const;
+private:
+ // map connection to id
+ std::unordered_map<connection, std::string> m_connections;
+ // map id to list of related connections, used for iteration over connections to notify about changes
+ std::unordered_map<std::string, std::unordered_set<connection>> m_ids;
+
+public:
class RegistryGuard
{
public:
diff --git a/diff.cpp b/diff.cpp
index ee17fad..99a2f14 100644
--- a/diff.cpp
+++ b/diff.cpp
@@ -115,6 +115,10 @@ void Diff::create(const std::string& xml)
m_pos0 = tree.get<int>("diff.start");
m_pos1 = tree.get<int>("diff.end");
+
+ if (m_pos0 > m_pos1)
+ throw std::runtime_error("Bad range in diff");
+
m_data = tree.get<std::string>("diff.data");
}
diff --git a/tests/Makefile b/tests/Makefile
index 0347210..f3ec6c8 100644
--- a/tests/Makefile
+++ b/tests/Makefile
@@ -15,6 +15,7 @@ UNITS=storage.cpp config.cpp compiledsql.cpp qrcode.cpp whiteboard.cpp connectio
UNITTESTS=test-config.cpp \
test-storage.cpp \
+ test-connectionregistry.cpp \
test-compiledsql.cpp \
test-qrcode.cpp \
test-whiteboard.cpp \
diff --git a/tests/test-connectionregistry.cpp b/tests/test-connectionregistry.cpp
new file mode 100644
index 0000000..1f68dd9
--- /dev/null
+++ b/tests/test-connectionregistry.cpp
@@ -0,0 +1,144 @@
+#include <gtest/gtest.h>
+
+#include <filesystem>
+#include <string>
+#include <system_error>
+
+#include <boost/beast/core.hpp>
+#include <boost/beast/http.hpp>
+
+#include "libreichwein/file.h"
+
+#include "connectionregistry.h"
+
+namespace fs = std::filesystem;
+using namespace Reichwein;
+
+class ConnectionRegistryTest: public ::testing::Test
+{
+protected:
+ ConnectionRegistryTest(){
+ }
+
+ ~ConnectionRegistryTest(){
+ }
+};
+
+TEST_F(ConnectionRegistryTest, constructor)
+{
+ ConnectionRegistry cr{};
+}
+
+TEST_F(ConnectionRegistryTest, test_addConnection)
+{
+ boost::asio::io_context ioc{1};
+
+ boost::asio::ip::tcp::socket ts0{ioc};
+ ConnectionRegistry::connection c0 {std::make_shared<ConnectionRegistry::connection::element_type>(std::move(ts0))};
+
+ boost::asio::ip::tcp::socket ts1{ioc};
+ ConnectionRegistry::connection c1 {std::make_shared<ConnectionRegistry::connection::element_type>(std::move(ts1))};
+
+ ConnectionRegistry cr{};
+
+ cr.addConnection(c0);
+ EXPECT_THROW(cr.addConnection(c0), std::exception);
+ cr.addConnection(c1);
+ EXPECT_THROW(cr.addConnection(c0), std::exception);
+ EXPECT_THROW(cr.addConnection(c1), std::exception);
+}
+
+TEST_F(ConnectionRegistryTest, test_delConnection)
+{
+ boost::asio::io_context ioc{1};
+
+ boost::asio::ip::tcp::socket ts0{ioc};
+ ConnectionRegistry::connection c0 {std::make_shared<ConnectionRegistry::connection::element_type>(std::move(ts0))};
+
+ boost::asio::ip::tcp::socket ts1{ioc};
+ ConnectionRegistry::connection c1 {std::make_shared<ConnectionRegistry::connection::element_type>(std::move(ts1))};
+
+ ConnectionRegistry cr{};
+
+ EXPECT_THROW(cr.delConnection(c0), std::exception);
+
+ cr.addConnection(c0);
+ cr.delConnection(c0);
+
+ cr.addConnection(c0);
+ cr.addConnection(c1);
+ cr.delConnection(c0);
+ EXPECT_THROW(cr.delConnection(c0), std::exception);
+ cr.delConnection(c1);
+ EXPECT_THROW(cr.delConnection(c1), std::exception);
+}
+
+TEST_F(ConnectionRegistryTest, test_setId)
+{
+ boost::asio::io_context ioc{1};
+ boost::asio::ip::tcp::socket ts{ioc};
+
+ ConnectionRegistry::connection c {std::make_shared<ConnectionRegistry::connection::element_type>(std::move(ts))};
+
+ ConnectionRegistry cr{};
+
+ EXPECT_THROW(cr.setId(c, "id1"), std::exception);
+ cr.addConnection(c);
+ cr.setId(c, "id2");
+}
+
+TEST_F(ConnectionRegistryTest, test_dump)
+{
+ boost::asio::io_context ioc{1};
+ boost::asio::ip::tcp::socket ts{ioc};
+
+ ConnectionRegistry::connection c {std::make_shared<ConnectionRegistry::connection::element_type>(std::move(ts))};
+
+ ConnectionRegistry cr{};
+
+ cr.addConnection(c);
+ cr.dump();
+
+ cr.setId(c, "id1");
+ cr.dump();
+}
+
+TEST_F(ConnectionRegistryTest, test_iterators)
+{
+ boost::asio::io_context ioc{1};
+ boost::asio::ip::tcp::socket ts{ioc};
+
+ ConnectionRegistry::connection c {std::make_shared<ConnectionRegistry::connection::element_type>(std::move(ts))};
+
+ ConnectionRegistry cr{};
+
+ EXPECT_THROW(cr.begin(""), std::exception);
+ EXPECT_THROW(cr.end(""), std::exception);
+
+ cr.addConnection(c);
+ EXPECT_THROW(cr.begin(""), std::exception);
+ EXPECT_THROW(cr.end(""), std::exception);
+
+ cr.setId(c, "id1");
+
+ EXPECT_EQ(std::distance(cr.begin("id1"), cr.end("id1")), 1);
+}
+
+TEST_F(ConnectionRegistryTest, test_guard)
+{
+ boost::asio::io_context ioc{1};
+ boost::asio::ip::tcp::socket ts{ioc};
+
+ ConnectionRegistry::connection c {std::make_shared<ConnectionRegistry::connection::element_type>(std::move(ts))};
+
+ ConnectionRegistry cr{};
+
+ {
+ ConnectionRegistry::RegistryGuard rg{cr, c};
+
+ EXPECT_THROW(cr.addConnection(c), std::exception);
+ }
+
+ EXPECT_THROW(cr.delConnection(c), std::exception);
+}
+
diff --git a/tests/test-diff.cpp b/tests/test-diff.cpp
index b6b703a..7061ef0 100644
--- a/tests/test-diff.cpp
+++ b/tests/test-diff.cpp
@@ -4,6 +4,8 @@
#include <string>
#include <system_error>
+#include <stdlib.h>
+
#include "libreichwein/file.h"
#include "diff.h"
@@ -23,6 +25,112 @@ protected:
TEST_F(DiffTest, constructor)
{
- Diff diff{};
+ // empty constructor
+ {
+ Diff d{};
+ EXPECT_EQ(d.get_xml(), "<diff><start>0</start><end>0</end><data/></diff>");
+ }
+
+ // constructor via xml diff
+ {
+ EXPECT_THROW(Diff d{""}, std::exception);
+ }
+ {
+ EXPECT_THROW(Diff d{"<diff><begin></begin></diff>"}, std::exception);
+ EXPECT_THROW(Diff d{"<diff><end>0</end><data>abc</data></diff>"}, std::exception);
+ EXPECT_THROW(Diff d{"<diff><start>0</start><data>abc</data></diff>"}, std::exception);
+ EXPECT_THROW(Diff d{"<diff><start>0</start><end>0</end></diff>"}, std::exception);
+ EXPECT_THROW(Diff d{"<diff><start>5</start><end>0</end><data>abc</data></diff>"}, std::exception);
+ EXPECT_THROW(Diff d{"<diff><start></start><end>0</end><data>abc</data></diff>"}, std::exception);
+ }
+
+ {
+ Diff d{"<diff><start>0</start><end>0</end><data>abc</data></diff>"};
+ EXPECT_EQ(d.get_xml(), "<diff><start>0</start><end>0</end><data>abc</data></diff>");
+ }
+
+ {
+ Diff d{"<diff><start>5</start><end>5</end><data>abc</data></diff>"};
+ EXPECT_EQ(d.get_xml(), "<diff><start>5</start><end>5</end><data>abc</data></diff>");
+ }
+
+ {
+ Diff d{"<diff><start>5</start><end>50</end><data>abc</data></diff>"};
+ EXPECT_EQ(d.get_xml(), "<diff><start>5</start><end>50</end><data>abc</data></diff>");
+ }
+
+ // constructor via versions
+ {
+ Diff d{"", ""};
+ EXPECT_EQ(d.get_xml(), "<diff><start>0</start><end>0</end><data/></diff>");
+ }
+ {
+ Diff d{"a", "a"};
+ EXPECT_EQ(d.get_xml(), "<diff><start>0</start><end>0</end><data/></diff>");
+ }
+ {
+ Diff d{"a", "b"};
+ EXPECT_EQ(d.get_xml(), "<diff><start>0</start><end>1</end><data>b</data></diff>");
+ }
+ {
+ Diff d{"0a1", "0b1"};
+ EXPECT_EQ(d.get_xml(), "<diff><start>1</start><end>2</end><data>b</data></diff>");
+ }
+ {
+ Diff d{"0abc1", "00b01"};
+ EXPECT_EQ(d.get_xml(), "<diff><start>1</start><end>4</end><data>0b0</data></diff>");
+ }
+ {
+ Diff d{"0ab1", "00b01"};
+ EXPECT_EQ(d.get_xml(), "<diff><start>1</start><end>3</end><data>0b0</data></diff>");
+ }
+ {
+ Diff d{"0abc1", "00b1"};
+ EXPECT_EQ(d.get_xml(), "<diff><start>1</start><end>4</end><data>0b</data></diff>");
+ }
+ {
+ Diff d{"0abc1", ""};
+ EXPECT_EQ(d.get_xml(), "<diff><start>0</start><end>5</end><data/></diff>");
+ }
+ {
+ Diff d{"bc1", "0abc1"};
+ EXPECT_EQ(d.get_xml(), "<diff><start>0</start><end>0</end><data>0a</data></diff>");
+ }
+ {
+ Diff d{"0abc1", "0ab"};
+ EXPECT_EQ(d.get_xml(), "<diff><start>3</start><end>5</end><data/></diff>");
+ }
+ {
+ Diff d{"0abc1", "0abc123"};
+ EXPECT_EQ(d.get_xml(), "<diff><start>5</start><end>5</end><data>23</data></diff>");
+ }
+ {
+ Diff d{"0abc1", "010abc1"};
+ EXPECT_EQ(d.get_xml(), "<diff><start>0</start><end>0</end><data>01</data></diff>");
+ }
+ {
+ Diff d{"0abc1", "0ac1"};
+ EXPECT_EQ(d.get_xml(), "<diff><start>2</start><end>3</end><data/></diff>");
+ }
+ {
+ Diff d{"0abc1", "0abxc1"};
+ EXPECT_EQ(d.get_xml(), "<diff><start>3</start><end>3</end><data>x</data></diff>");
+ }
+}
+
+TEST_F(DiffTest, diff_create)
+{
+ const char* result {diff_create("0abc1", "0ab")};
+
+ EXPECT_EQ(std::string(result), "<diff><start>3</start><end>5</end><data/></diff>");
+ free((void*)result); // this will be done by javascript side in real scenario
+}
+
+TEST_F(DiffTest, diff_apply)
+{
+ const char* result {diff_apply("0abc1", "<diff><start>3</start><end>5</end><data/></diff>")};
+
+ EXPECT_EQ(std::string(result), "0ab");
+ free((void*)result); // this will be done by javascript side in real scenario
}
diff --git a/tests/test-whiteboard.cpp b/tests/test-whiteboard.cpp
index a472d64..9e6b7fb 100644
--- a/tests/test-whiteboard.cpp
+++ b/tests/test-whiteboard.cpp
@@ -3,6 +3,7 @@
#include <cstring>
#include <filesystem>
#include <memory>
+#include <regex>
#include <string>
#include <system_error>
@@ -38,62 +39,6 @@ namespace {
const fs::path testDbFilename{"./whiteboard.db3"};
}
-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 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
{
protected:
@@ -118,8 +63,6 @@ protected:
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));
@@ -151,7 +94,6 @@ protected:
}
std::shared_ptr<Config> m_config;
- //std::shared_ptr<Webserver> m_webserver;
pid_t m_pid{};
};
@@ -223,12 +165,16 @@ private:
boost::asio::ip::tcp::endpoint ep_;
};
-TEST_F(WhiteboardTest, connection)
+//
+// tests via websocket server in separate process (hides coverage)
+//
+
+TEST_F(WhiteboardTest, websocket_server_connection)
{
WebsocketClient wc;
}
-TEST_F(WhiteboardTest, generate_id)
+TEST_F(WhiteboardTest, websocket_server_generate_id)
{
WebsocketClient wc;