summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--p2pvr/daemon/unittests/mockDatasource.cpp64
-rw-r--r--p2pvr/daemon/unittests/mockDatasource.h29
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
+