From 61ab1549fdd5328c81133efdd01f2a4245607211 Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Wed, 21 Jan 2015 12:15:47 +0000 Subject: Add sandboxed database support to unit tests and lots of sample data --- p2pvr/daemon/unittests/mockDatasource.cpp | 64 +++++++++++++++++++++++++++++++ p2pvr/daemon/unittests/mockDatasource.h | 29 ++++++++++++++ 2 files changed, 93 insertions(+) create mode 100644 p2pvr/daemon/unittests/mockDatasource.cpp create mode 100644 p2pvr/daemon/unittests/mockDatasource.h diff --git a/p2pvr/daemon/unittests/mockDatasource.cpp b/p2pvr/daemon/unittests/mockDatasource.cpp new file mode 100644 index 0000000..da4e3c6 --- /dev/null +++ b/p2pvr/daemon/unittests/mockDatasource.cpp @@ -0,0 +1,64 @@ +#include "mockDatasource.h" +#include +#include +#include +#include +#include +#include + +typedef MockDatabase::MockConnectionLoader MDMCL; +DECLARE_CUSTOM_COMPONENT_LOADER("mock", T, MDMCL, ConnectionLoader); + +std::map MockDatabase::mocks; +unsigned int MockDatabase::mocked = 0; + +DB::Connection * +MockDatabase::MockConnectionLoader::create(const std::string & n) const +{ + auto m = MockDatabase::mocks.find(n); + return InstanceMap::Get("postgresql")->create(m->second); +} + +MockDatabase::MockDatabase(const std::string & masterdb, const std::string & name, const std::vector & ss) : + master(InstanceMap::Get("postgresql")->create(masterdb)), + testDbName(stringbf("test_%d_%d", getpid(), ++mocked)) +{ + Logger()->messagebf(LOG_DEBUG, "Setting up new mocked database %s", testDbName); + DropDatabase(); + CreateNewDatabase(); + try { + for (auto s : ss) { + Logger()->messagebf(LOG_DEBUG, "%s << %s", testDbName, s); + system(("psql -q -1 -U postgres " + testDbName + " -f " + (RootDir / s).string()).c_str()); + } + Logger()->messagebf(LOG_DEBUG, "%s initialized", testDbName); + mocks[name] = stringbf("user=postgres dbname=%s", testDbName); + } + catch (...) { + DropDatabase(); + throw; + } +} + +MockDatabase::~MockDatabase() +{ + Logger()->messagebf(LOG_DEBUG, "Tearing down mocked database %s", testDbName); + DropDatabase(); + delete master; + Logger()->messagebf(LOG_DEBUG, "%s torn down", testDbName); +} + +void MockDatabase::DropDatabase() const +{ + Logger()->messagebf(LOG_INFO, "Killing any active connections to database %s", testDbName); + master->execute("SELECT pg_terminate_backend(pid) FROM pg_stat_activity WHERE datname = '" + testDbName + "'"); + Logger()->messagebf(LOG_INFO, "Dropping (if exists) old database %s", testDbName); + master->execute("DROP DATABASE IF EXISTS " + testDbName); +} + +void MockDatabase::CreateNewDatabase() const +{ + Logger()->messagebf(LOG_INFO, "Creating new database %s", testDbName); + master->execute("CREATE DATABASE " + testDbName); +} + diff --git a/p2pvr/daemon/unittests/mockDatasource.h b/p2pvr/daemon/unittests/mockDatasource.h new file mode 100644 index 0000000..c39e560 --- /dev/null +++ b/p2pvr/daemon/unittests/mockDatasource.h @@ -0,0 +1,29 @@ +#ifndef TESTDATASOURCE_H +#define TESTDATASOURCE_H + +#include + +class MockDatabase { + public: + class MockConnectionLoader : public ConnectionLoader { + public: + DB::Connection * create(const std::string &) const; + }; + + MockDatabase(const std::string & master, const std::string & name, const std::vector & ss); + ~MockDatabase(); + + protected: + void DropDatabase() const; + void CreateNewDatabase() const; + + private: + const DB::Connection * master; + const std::string testDbName; + + static unsigned int mocked; + static std::map mocks; +}; + +#endif + -- cgit v1.2.3