From af1c4ee4d74ff7afc997372802d851d11daad418 Mon Sep 17 00:00:00 2001 From: Roland Reichwein Date: Fri, 30 Dec 2022 15:07:39 +0100 Subject: Added tests, added sqlite-backed storage (WIP!) --- Makefile | 57 ++++---------------------------- common.mk | 49 ++++++++++++++++++++++++++++ config.cpp | 5 ++- config.h | 8 +++-- debian/changelog | 7 ++++ debian/control | 2 +- storage.cpp | 17 ++++++++++ storage.h | 16 +++++++++ tests/Makefile | 26 +++++++++++++++ tests/unittests.cpp | 94 +++++++++++++++++++++++++++++++++++++++++++++++++++++ whiteboard.cpp | 4 +++ 11 files changed, 229 insertions(+), 56 deletions(-) create mode 100644 common.mk create mode 100644 storage.cpp create mode 100644 storage.h create mode 100644 tests/Makefile create mode 100644 tests/unittests.cpp diff --git a/Makefile b/Makefile index 5a1b1d2..a35cb9d 100755 --- a/Makefile +++ b/Makefile @@ -4,64 +4,17 @@ # Environment: Debian # +include common.mk + DISTROS=base debian11 ubuntu2204 VERSION=$(shell dpkg-parsechangelog --show-field Version) -CXX=clang++-13 - -ifeq ($(shell which $(CXX)),) -CXX=clang++-10 -endif - -ifeq ($(shell which $(CXX)),) -CXX=clang++ -endif - -ifeq ($(shell which $(CXX)),) -CXX=g++-9 -endif - -ifeq ($(shell which $(CXX)),) -CXX=g++ -endif - -LIBS=-lfcgi -lboost_filesystem INCLUDES=-I. -HEADERS=file.h config.h qrcode.h +HEADERS=file.h config.h qrcode.h storage.h SOURCES=$(HEADERS:.h=.cpp) OBJECTS=$(HEADERS:.h=.o) TARGETS=whiteboard.fcgi -ifeq ($(CXXFLAGS),) -CXXFLAGS=-g -O2 -endif - -CXXFLAGS+=-Wall -fPIE -Wpedantic -gdwarf-4 -LDFLAGS+=-pie - -ifeq ($(CXX),g++-9) -CXXFLAGS+=-std=c++17 -else -CXXFLAGS+=-std=c++20 -endif - -ifeq ($(CXX),clang++-10) -LIBS+= \ --fuse-ld=lld-10 \ --lstdc++ -#-lc++ \ -#-lc++abi -#-lc++fs -#-lstdc++fs -else -LIBS+= \ --lstdc++ \ --lstdc++fs -endif - -CXXFLAGS+=$(shell pkg-config --cflags qrcodegencpp Magick++ fmt) -LIBS+=$(shell pkg-config --libs qrcodegencpp Magick++ fmt) - build: $(TARGETS) all: build @@ -97,8 +50,12 @@ whiteboard.fcgi: $(OBJECTS) %.o: %.cpp $(CXX) $(CXXFLAGS) $(INCLUDES) -c $< -o $@ +test: + $(MAKE) -C tests + clean: -rm -f *.o *.fcgi + $(MAKE) -C tests clean deb: dpkg-buildpackage diff --git a/common.mk b/common.mk new file mode 100644 index 0000000..7f34a96 --- /dev/null +++ b/common.mk @@ -0,0 +1,49 @@ +CXX=clang++-13 + +ifeq ($(shell which $(CXX)),) +CXX=clang++-10 +endif + +ifeq ($(shell which $(CXX)),) +CXX=clang++ +endif + +ifeq ($(shell which $(CXX)),) +CXX=g++-9 +endif + +ifeq ($(shell which $(CXX)),) +CXX=g++ +endif + +ifeq ($(CXXFLAGS),) +CXXFLAGS=-g -O2 +endif + +CXXFLAGS+=-Wall -fPIE -Wpedantic -gdwarf-4 +LDFLAGS+=-pie + +ifeq ($(CXX),g++-9) +CXXFLAGS+=-std=c++17 +else +CXXFLAGS+=-std=c++20 +endif + +ifeq ($(CXX),clang++-10) +LIBS+= \ +-fuse-ld=lld-10 \ +-lstdc++ +#-lc++ \ +#-lc++abi +#-lc++fs +#-lstdc++fs +else +LIBS+= \ +-lstdc++ \ +-lstdc++fs +endif + +CXXFLAGS+=$(shell pkg-config --cflags qrcodegencpp Magick++ fmt sqlite3) +LIBS+=-lfcgi -lboost_filesystem +LIBS+=$(shell pkg-config --libs qrcodegencpp Magick++ fmt sqlite3) -lSQLiteCpp + diff --git a/config.cpp b/config.cpp index e3ef68f..0255023 100644 --- a/config.cpp +++ b/config.cpp @@ -9,10 +9,9 @@ namespace pt = boost::property_tree; namespace { const std::string default_datapath {"/var/lib/whiteboard"}; - const std::string config_filename{"/etc/webserver.conf"}; } -Config::Config(): m_dataPath{default_datapath} +Config::Config(const std::string& config_filename): m_dataPath{default_datapath} { try { @@ -26,7 +25,7 @@ Config::Config(): m_dataPath{default_datapath} } } -std::string Config::getDataPath() +std::string Config::getDataPath() const { return m_dataPath; } diff --git a/config.h b/config.h index 523b54d..ab95dd5 100644 --- a/config.h +++ b/config.h @@ -1,11 +1,15 @@ +#pragma once + #include +const std::string default_config_filename{"/etc/whiteboard.conf"}; + class Config { private: std::string m_dataPath; public: - Config(); - std::string getDataPath(); + Config(const std::string& config_filename = default_config_filename); + std::string getDataPath() const; }; diff --git a/debian/changelog b/debian/changelog index e9507ef..ad9fd1e 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,10 @@ +whiteboard (1.4) unstable; urgency=medium + + * Move from filesystem based documents to sqlite + * Add tests + + -- Roland Reichwein Fri, 30 Dec 2022 13:08:49 +0100 + whiteboard (1.3) unstable; urgency=medium * Page design (center) diff --git a/debian/control b/debian/control index ec9b915..4b38950 100644 --- a/debian/control +++ b/debian/control @@ -2,7 +2,7 @@ Source: whiteboard Section: web Priority: optional Maintainer: Roland Reichwein -Build-Depends: debhelper (>= 12), libboost-all-dev | libboost1.71-all-dev, clang | g++-9, uglifyjs, python3-pkg-resources, htmlmin, cleancss, libfcgi-dev, libqrcodegencpp-dev, libmagick++-dev, pkg-config, libfmt-dev +Build-Depends: debhelper (>= 12), libboost-all-dev | libboost1.71-all-dev, clang | g++-9, uglifyjs, python3-pkg-resources, htmlmin, cleancss, libfcgi-dev, libqrcodegencpp-dev, libmagick++-dev, pkg-config, libfmt-dev, libsqlitecpp-dev, googletest Standards-Version: 4.5.0 Homepage: http://www.reichwein.it/whiteboard/ diff --git a/storage.cpp b/storage.cpp new file mode 100644 index 0000000..9dc7615 --- /dev/null +++ b/storage.cpp @@ -0,0 +1,17 @@ +#include "storage.h" + +#include "config.h" + +#include + +Storage::Storage(const Config& config): m_config(config) +{ + SQLite::Database db(m_config.getDataPath() + "/whiteboard.db3", SQLite::OPEN_READWRITE|SQLite::OPEN_CREATE); + + db.exec("CREATE TABLE IF NOT EXISTS documents (id INTEGER PRIMARY KEY, value TEXT)"); +} + +std::string Storage::getDocument() +{ + return ""; +} diff --git a/storage.h b/storage.h new file mode 100644 index 0000000..068fad0 --- /dev/null +++ b/storage.h @@ -0,0 +1,16 @@ +#pragma once + +#include + +#include "config.h" + +class Storage +{ +public: + Storage(const Config& config); + std::string getDocument(); + +private: + const Config& m_config; +}; + diff --git a/tests/Makefile b/tests/Makefile new file mode 100644 index 0000000..78097ce --- /dev/null +++ b/tests/Makefile @@ -0,0 +1,26 @@ +include ../common.mk + +CXXFLAGS+=\ + -I/usr/src/googletest/googletest/include \ + -I/usr/src/googletest/googlemock/include \ + -I/usr/src/googletest/googletest \ + -I/usr/src/googletest/googlemock \ + -I.. + +test: unittests + ./unittests + +unittests: libgmock.a unittests.o ../config.o ../file.o ../storage.o + $(CXX) $(LDFLAGS) $^ $(LDLIBS) $(LIBS) -o $@ + +unittests.o: unittests.cpp + $(CXX) $(CXXFLAGS) -o $@ -c unittests.cpp + +libgmock.a: + $(CXX) $(CXXFLAGS) -c /usr/src/googletest/googletest/src/gtest-all.cc + $(CXX) $(CXXFLAGS) -c /usr/src/googletest/googlemock/src/gmock-all.cc + $(CXX) $(CXXFLAGS) -c /usr/src/googletest/googlemock/src/gmock_main.cc + ar -rv libgmock.a gmock-all.o gtest-all.o gmock_main.o + +clean: + -rm -f *.o *.a unittests diff --git a/tests/unittests.cpp b/tests/unittests.cpp new file mode 100644 index 0000000..3b24f83 --- /dev/null +++ b/tests/unittests.cpp @@ -0,0 +1,94 @@ +#include + +#include +#include +#include + +#include "config.h" +#include "file.h" +#include "storage.h" + +namespace fs = std::filesystem; + +namespace { + const std::string testConfigFilename{"./test.conf"}; + const std::string testDbFilename{"./whiteboard.db3"}; +} + +class ConfigTest: public ::testing::Test +{ +protected: + ConfigTest(){ + } + + ~ConfigTest(){ + } +}; + +TEST_F(ConfigTest, defaultData) +{ + std::string filename{testConfigFilename + "doesntexist"}; + std::error_code ec; + fs::remove(filename, ec); + ASSERT_TRUE(!fs::exists(filename)); + { + Config config{filename}; + EXPECT_EQ(config.getDataPath(), "/var/lib/whiteboard"); + ASSERT_TRUE(!fs::exists(filename)); + } + + ASSERT_TRUE(!fs::exists(filename)); +} + +TEST_F(ConfigTest, testData) +{ + File::setFile(testConfigFilename, R"CONFIG( + + /some/other/location + 2592000 + +)CONFIG"); + + { + Config config{testConfigFilename}; + EXPECT_EQ(config.getDataPath(), "/some/other/location"); + } + + std::error_code ec; + fs::remove(testConfigFilename, ec); +} + +class StorageTest: public ::testing::Test +{ +protected: + StorageTest(){ + File::setFile(testConfigFilename, R"CONFIG( + + . + 2592000 + +)CONFIG"); + std::error_code ec; + fs::remove(testDbFilename, ec); + } + + ~StorageTest(){ + std::error_code ec; + fs::remove(testDbFilename, ec); + fs::remove(testConfigFilename, ec); + } +}; + +TEST_F(StorageTest, create) +{ + ASSERT_TRUE(!fs::exists(testDbFilename)); + + { + Config config(testConfigFilename); + ASSERT_EQ(config.getDataPath(), "."); + Storage storage(config); + } + + ASSERT_TRUE(fs::exists(testDbFilename)); +} + diff --git a/whiteboard.cpp b/whiteboard.cpp index dd5f1a8..45434df 100644 --- a/whiteboard.cpp +++ b/whiteboard.cpp @@ -4,6 +4,7 @@ #include #include #include + #include #include @@ -23,6 +24,7 @@ #include "config.h" #include "file.h" #include "qrcode.h" +#include "storage.h" namespace pt = boost::property_tree; using namespace std::string_literals; @@ -98,6 +100,8 @@ int main(void) Config config; data_path = config.getDataPath(); + Storage storage(config); + Magick::InitializeMagick(NULL); // for qrcode.cpp int result = FCGX_Init(); -- cgit v1.2.3