diff options
-rw-r--r-- | p2pvr/daemon/unittests/mockDatasource.cpp | 64 | ||||
-rw-r--r-- | p2pvr/daemon/unittests/mockDatasource.h | 29 |
2 files changed, 93 insertions, 0 deletions
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 <misc.h> +#include <scripts.h> +#include <connection.h> +#include <logger.h> +#include <boost/filesystem/operations.hpp> +#include <definedDirs.h> + +typedef MockDatabase::MockConnectionLoader MDMCL; +DECLARE_CUSTOM_COMPONENT_LOADER("mock", T, MDMCL, ConnectionLoader); + +std::map<std::string, std::string> 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<ConnectionLoader, std::string>::Get<std::invalid_argument>("postgresql")->create(m->second); +} + +MockDatabase::MockDatabase(const std::string & masterdb, const std::string & name, const std::vector<std::string> & ss) : + master(InstanceMap<ConnectionLoader, std::string>::Get<std::invalid_argument>("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 <rdbmsDataSource.h> + +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<std::string> & 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<std::string, std::string> mocks; +}; + +#endif + |