diff options
| -rw-r--r-- | config.cpp | 11 | ||||
| -rw-r--r-- | config.h | 3 | ||||
| -rw-r--r-- | debian/webserver.conf | 1 | ||||
| -rw-r--r-- | server.cpp | 2 | ||||
| -rw-r--r-- | statistics.cpp | 13 | ||||
| -rw-r--r-- | statistics.h | 4 | ||||
| -rw-r--r-- | tests/test-config.cpp | 1 | ||||
| -rw-r--r-- | tests/test-statistics.cpp | 69 | ||||
| -rw-r--r-- | tests/test-webserver.cpp | 1 | ||||
| -rw-r--r-- | webserver.conf | 1 | 
10 files changed, 98 insertions, 8 deletions
@@ -45,6 +45,8 @@ void Config::readConfigfile(const std::filesystem::path& filename)   m_threads = tree.get<int>("webserver.threads"); + m_statistics_path = tree.get<std::string>("webserver.statisticspath", "/var/lib/webserver/stats.db"); +   // optional entries   auto elements = tree.get_child_optional("webserver");   if (elements) { @@ -226,6 +228,11 @@ int Config::Threads() const   return m_threads;  } +fs::path Config::statistics_path() const +{ + return m_statistics_path; +} +  const std::vector<std::string>& Config::PluginDirectories() const  {   return m_plugin_directories; @@ -245,10 +252,12 @@ void Config::dump() const  {   std::cout << "=== Configuration ===========================" << std::endl;   std::cout << "User: " << m_user << std::endl; - std::cout << "Group: " << m_user << std::endl; + std::cout << "Group: " << m_group << std::endl;   std::cout << "Threads: " << m_threads << std::endl; + std::cout << "Statistics Path: " << statistics_path() << std::endl; +   std::cout << "Plugin Directories:";   for (const auto& dir: m_plugin_directories)    std::cout << " " << dir; @@ -52,6 +52,7 @@ class Config   std::string m_user;   std::string m_group;   int m_threads; + std::filesystem::path m_statistics_path;   std::vector<std::string> m_plugin_directories;   std::unordered_map<std::string, Site> m_sites;   std::vector<Socket> m_sockets; @@ -65,6 +66,8 @@ class Config    int Threads() const; +  std::filesystem::path statistics_path() const; +    const std::vector<std::string>& PluginDirectories() const;    const std::unordered_map<std::string, Site>& Sites() const;    const std::vector<Socket>& Sockets() const; diff --git a/debian/webserver.conf b/debian/webserver.conf index f40e793..4a9e3af 100644 --- a/debian/webserver.conf +++ b/debian/webserver.conf @@ -1,6 +1,7 @@  <webserver>   <user>www-data</user>   <group>www-data</group> + <statisticspath>/var/lib/webserver/stats.db</statisticspath>   <threads>10</threads>   <plugin-directory>/usr/lib/webserver/plugins</plugin-directory>   <sites> @@ -59,7 +59,7 @@ Server::~Server()  int run_server(Config& config, plugins_container_type& plugins)  { - Statistics stats; + Statistics stats(config.statistics_path());   auto const threads = std::max<int>(1, config.Threads()); diff --git a/statistics.cpp b/statistics.cpp index 1d67bfd..fb7148b 100644 --- a/statistics.cpp +++ b/statistics.cpp @@ -8,14 +8,14 @@ namespace fs = std::filesystem;  using namespace std::string_literals;  namespace { - const fs::path statsfilepath{ "/var/lib/webserver/stats.db" }; + const fs::path default_statsfilepath{ "stats.db" };  } // anonymous namespace  void Statistics::load()  {   std::lock_guard<std::mutex> lock(mMutex);   std::cout << "Loading statistics..." << std::endl; - std::ifstream file{statsfilepath, std::ios::in | std::ios::binary}; + std::ifstream file{mPath, std::ios::in | std::ios::binary};   if (file.is_open()) {    Reichwein::Serialization::IArchive archive{file}; @@ -32,7 +32,7 @@ void Statistics::save()   if (mChanged) {    std::lock_guard<std::mutex> lock(mMutex);    std::cout << "Saving statistics..." << std::endl; -  std::ofstream file{statsfilepath, std::ios::out | std::ios::binary | std::ios::trunc}; +  std::ofstream file{mPath, std::ios::out | std::ios::binary | std::ios::trunc};    if (file.is_open()) {     Reichwein::Serialization::OArchive archive{file}; @@ -45,7 +45,12 @@ void Statistics::save()   }  } -Statistics::Statistics() +Statistics::Statistics(): mPath{default_statsfilepath} +{ + load(); +} + +Statistics::Statistics(const fs::path& path): mPath{path.empty() ? default_statsfilepath : path}  {   load();  } diff --git a/statistics.h b/statistics.h index a8b4854..f2ebcd3 100644 --- a/statistics.h +++ b/statistics.h @@ -1,5 +1,7 @@  #pragma once +#include "config.h" +  #include "libreichwein/archive.h"  #include <cstdint> @@ -63,12 +65,14 @@ private:   bool mChanged{};   std::deque<Bin> mBins;   std::mutex mMutex; + std::filesystem::path mPath;   void load();   void limit();  public:   Statistics(); + Statistics(const std::filesystem::path& path);   ~Statistics();   void count(size_t bytes_in, size_t bytes_out, bool error, bool ipv6, bool https); diff --git a/tests/test-config.cpp b/tests/test-config.cpp index c16c519..fe482f8 100644 --- a/tests/test-config.cpp +++ b/tests/test-config.cpp @@ -41,6 +41,7 @@ BOOST_FIXTURE_TEST_CASE(config, ConfigFixture)   <user>user1</user>   <group>www-data</group>   <threads>10</threads> + <statisticspath>stats.db</statisticspath>   <!--   <plugin-directory>/usr/lib/webserver/plugins</plugin-directory>   <plugin-directory>/usr/local/lib/webserver/plugins</plugin-directory> diff --git a/tests/test-statistics.cpp b/tests/test-statistics.cpp index 9ed7d06..fbc8cfb 100644 --- a/tests/test-statistics.cpp +++ b/tests/test-statistics.cpp @@ -6,23 +6,88 @@  #include <boost/property_tree/ptree.hpp>  #include <boost/property_tree/xml_parser.hpp> +#include <filesystem>  #include <sstream>  #include <string>  #include "statistics.h" +#include "config.h" +  using namespace std::string_literals; +namespace fs = std::filesystem;  class StatisticsFixture  {  public:   StatisticsFixture(){}   ~StatisticsFixture(){} - void setup(){} - void teardown(){} + void setup() + { +  std::error_code ec; +  fs::remove("stats.db", ec); + } + void teardown() + { +  std::error_code ec; +  fs::remove("stats.db", ec); + }  };  BOOST_FIXTURE_TEST_CASE(statistics, StatisticsFixture)  { + { +  Statistics stats; + +  BOOST_CHECK_EQUAL(stats.getValues(), ""); +   +  stats.count(10, 1000, false, true, true); + +  auto v{stats.getValues()}; +  BOOST_CHECK_GT(v.size(), 0); + +  auto pos{v.find(",")}; +  BOOST_CHECK(pos != std::string::npos); +  BOOST_CHECK_GT(pos, 0); + +  std::string v2{v.substr(pos)}; + +  BOOST_CHECK_EQUAL(v2, ",1,0,10,1000,1,0,10,1000,1,0,10,1000\n"); +   +  stats.save(); + +  BOOST_CHECK_EQUAL(v2, ",1,0,10,1000,1,0,10,1000,1,0,10,1000\n"); + } + + { +  Statistics stats("stats.db"); +  auto v{stats.getValues()}; +  BOOST_CHECK_GT(v.size(), 0); + +  auto pos{v.find(",")}; +  BOOST_CHECK(pos != std::string::npos); +  BOOST_CHECK_GT(pos, 0); + +  std::string v2{v.substr(pos)}; + +  BOOST_CHECK_EQUAL(v2, ",1,0,10,1000,1,0,10,1000,1,0,10,1000\n"); + +  stats.count(10, 1000, false, true, true); +  BOOST_CHECK_EQUAL(stats.getValues().substr(pos), ",2,0,20,2000,2,0,20,2000,2,0,20,2000\n"); +  stats.count(10, 1000, true, true, true); +  BOOST_CHECK_EQUAL(stats.getValues().substr(pos), ",3,1,30,3000,3,1,30,3000,3,1,30,3000\n"); +  stats.count(10, 1000, false, false, false); +  BOOST_CHECK_EQUAL(stats.getValues().substr(pos), ",4,1,40,4000,3,1,30,3000,3,1,30,3000\n"); +  stats.count(10, 1000, false, true, false); +  BOOST_CHECK_EQUAL(stats.getValues().substr(pos), ",5,1,50,5000,4,1,40,4000,3,1,30,3000\n"); +  stats.count(10, 1000, false, false, true); +  BOOST_CHECK_EQUAL(stats.getValues().substr(pos), ",6,1,60,6000,4,1,40,4000,4,1,40,4000\n"); + } +} + +BOOST_FIXTURE_TEST_CASE(statistics_non_existing, StatisticsFixture) +{ + Statistics stats("nonexistingpath/stats.db"); + BOOST_CHECK_EQUAL(stats.getValues(), "");  } diff --git a/tests/test-webserver.cpp b/tests/test-webserver.cpp index 53aa9cc..ef3b15f 100644 --- a/tests/test-webserver.cpp +++ b/tests/test-webserver.cpp @@ -65,6 +65,7 @@ public:   <user>www-data</user>   <group>www-data</group>   <threads>10</threads> + <statisticspath>stats.db</sttaisticspath>   <plugin-directory>../plugins</plugin-directory>   <sites>    <site> diff --git a/webserver.conf b/webserver.conf index e1c7902..53b48ce 100644 --- a/webserver.conf +++ b/webserver.conf @@ -2,6 +2,7 @@   <user>www-data</user>   <group>www-data</group>   <threads>10</threads> + <statisticspath>stats.db</statisticspath>   <!--   <plugin-directory>/usr/lib/webserver/plugins</plugin-directory>   <plugin-directory>/usr/local/lib/webserver/plugins</plugin-directory>  | 
