summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDan Goodliffe <dan@randomdan.homeip.net>2015-05-02 18:11:51 +0100
committerDan Goodliffe <dan@randomdan.homeip.net>2015-05-02 18:11:51 +0100
commit53075e2b911dc62619b3843985b6aab0ac32c436 (patch)
tree29f612c52f7169d6f312c1f5051d8a93f8e3e303
parentAdd MySQL mocking and test cases (diff)
downloadproject2-53075e2b911dc62619b3843985b6aab0ac32c436.tar.bz2
project2-53075e2b911dc62619b3843985b6aab0ac32c436.tar.xz
project2-53075e2b911dc62619b3843985b6aab0ac32c436.zip
Centralize the mocking code
-rw-r--r--project2/sql/mockDatabase.cpp76
-rw-r--r--project2/sql/mockDatabase.h37
-rw-r--r--project2/sql/sql-modMySQL.cpp56
-rw-r--r--project2/sql/sql-modMySQL.h13
-rw-r--r--project2/sql/sql-modPQ.cpp40
-rw-r--r--project2/sql/sql-modPQ.h12
-rw-r--r--project2/sql/sql-modSQLite.cpp30
-rw-r--r--project2/sql/sql-modSQLite.h12
8 files changed, 144 insertions, 132 deletions
diff --git a/project2/sql/mockDatabase.cpp b/project2/sql/mockDatabase.cpp
new file mode 100644
index 0000000..259dfd6
--- /dev/null
+++ b/project2/sql/mockDatabase.cpp
@@ -0,0 +1,76 @@
+#include "mockDatabase.h"
+#include "mockDatasource.h"
+#include <misc.h>
+#include <logger.h>
+#include <fstream>
+#include <boost/bind.hpp>
+
+MockDatabase::MockDatabase(const std::string & name) :
+ mockName(name)
+{
+}
+
+MockDatabase::~MockDatabase()
+{
+}
+
+void
+MockDatabase::PlaySchemaScripts(const std::vector<boost::filesystem::path> & ss) const
+{
+ DB::Connection * conn = openConnection();
+ try {
+ for (auto s : ss) {
+ conn->beginTx();
+ Logger()->messagebf(LOG_DEBUG, "%s << %s", mockName, s);
+ std::ifstream f;
+ f.open(s.string());
+ while (!f.eof()) {
+ char buf[BUFSIZ];
+ f.getline(buf, BUFSIZ, ';');
+ if (!f.eof())
+ conn->execute(buf);
+ }
+ f.close();
+ conn->commitTx();
+ }
+ delete conn;
+ Logger()->messagebf(LOG_DEBUG, "%s initialized", mockName);
+ MockConnectionLoader::mocks[mockName] = boost::bind(&MockDatabase::openConnection, this);
+ }
+ catch (...) {
+ if (conn->inTx()) {
+ conn->rollbackTx();
+ }
+ delete conn;
+ DropDatabase();
+ throw;
+ }
+
+}
+
+MockServerDatabase::MockServerDatabase(const std::string & masterdb, const std::string & name, const std::string & type) :
+ MockDatabase(name),
+ master(InstanceMap<ConnectionLoader, std::string>::Get<std::invalid_argument>(type)->create(masterdb)),
+ testDbName(stringbf("test_%d_%d", getpid(), ++MockConnectionLoader::mocked))
+{
+}
+
+MockServerDatabase::~MockServerDatabase()
+{
+}
+
+void
+MockServerDatabase::CreateNewDatabase() const
+{
+ DropDatabase();
+ Logger()->messagebf(LOG_INFO, "Creating new database %s", testDbName);
+ master->execute("CREATE DATABASE " + testDbName);
+}
+
+void
+MockServerDatabase::DropDatabase() const
+{
+ Logger()->messagebf(LOG_INFO, "Creating new database %s", testDbName);
+ master->execute("DROP DATABASE IF EXISTS " + testDbName);
+}
+
diff --git a/project2/sql/mockDatabase.h b/project2/sql/mockDatabase.h
new file mode 100644
index 0000000..49e49a8
--- /dev/null
+++ b/project2/sql/mockDatabase.h
@@ -0,0 +1,37 @@
+#ifndef MOCKDATABASE_H
+#define MOCKDATABASE_H
+
+#include <string>
+#include <vector>
+#include <boost/filesystem/path.hpp>
+#include <connection.h>
+
+class MockDatabase {
+ public:
+ MockDatabase(const std::string & mockName);
+ virtual ~MockDatabase();
+
+ protected:
+ virtual void CreateNewDatabase() const = 0;
+ virtual void PlaySchemaScripts(const std::vector<boost::filesystem::path> & ss) const;
+ virtual void DropDatabase() const = 0;
+ virtual DB::Connection * openConnection() const = 0;
+
+ const std::string mockName;
+};
+
+class MockServerDatabase : public MockDatabase {
+ public:
+ MockServerDatabase(const std::string & masterdb, const std::string & name, const std::string & type);
+ virtual ~MockServerDatabase();
+
+ protected:
+ virtual void CreateNewDatabase() const override;
+ virtual void DropDatabase() const override;
+
+ DB::Connection * master;
+ const std::string testDbName;
+};
+
+#endif
+
diff --git a/project2/sql/sql-modMySQL.cpp b/project2/sql/sql-modMySQL.cpp
index 24172ce..0466cbc 100644
--- a/project2/sql/sql-modMySQL.cpp
+++ b/project2/sql/sql-modMySQL.cpp
@@ -10,67 +10,21 @@ typedef MySQL::Connection MySQLConnection;
DECLARE_GENERIC_LOADER("mysql", ConnectionLoader, MySQLConnection)
MockMySQLDatabase::MockMySQLDatabase(const std::string & name, const std::vector<boost::filesystem::path> & ss) :
- master(InstanceMap<ConnectionLoader, std::string>::Get<std::invalid_argument>("mysql")->create("options=p2testmysql")),
- testDbName(stringbf("test_%d_%d", getpid(), ++MockConnectionLoader::mocked)),
- mockName(name)
+ MockServerDatabase("options=p2testmysql", name, "mysql")
{
- Logger()->messagebf(LOG_DEBUG, "Setting up new mocked database %s", testDbName);
- DropDatabase();
CreateNewDatabase();
- DB::Connection * conn = openConnection(stringbf("options=p2testmysql;database=%s", testDbName));
- try {
- for (auto s : ss) {
- conn->beginTx();
- Logger()->messagebf(LOG_DEBUG, "%s << %s", testDbName, s);
- std::ifstream f;
- f.open(s.string());
- while (!f.eof()) {
- char buf[BUFSIZ];
- f.getline(buf, BUFSIZ, ';');
- if (!f.eof())
- conn->execute(buf);
- }
- f.close();
- conn->commitTx();
- }
- Logger()->messagebf(LOG_DEBUG, "%s initialized", testDbName);
- MockConnectionLoader::mocks[name] = boost::bind(MockMySQLDatabase::openConnection, stringbf("options=p2testmysql;database=%s", testDbName));
- }
- catch (...) {
- if (conn->inTx()) {
- conn->rollbackTx();
- }
- delete conn;
- DropDatabase();
- throw;
- }
+ PlaySchemaScripts(ss);
}
DB::Connection *
-MockMySQLDatabase::openConnection(const std::string & connStr)
+MockMySQLDatabase::openConnection() const
{
- return InstanceMap<ConnectionLoader, std::string>::Get<std::invalid_argument>("mysql")->create(connStr);
+ return InstanceMap<ConnectionLoader, std::string>::Get<std::invalid_argument>("mysql")->create(
+ stringbf("options=p2testmysql;database=%s", testDbName));
}
MockMySQLDatabase::~MockMySQLDatabase()
{
- Logger()->messagebf(LOG_DEBUG, "Tearing down mocked database %s", testDbName);
DropDatabase();
- delete master;
- MockConnectionLoader::mocks.erase(mockName);
- Logger()->messagebf(LOG_DEBUG, "%s torn down", testDbName);
-}
-
-void MockMySQLDatabase::DropDatabase() const
-{
- Logger()->messagebf(LOG_INFO, "Dropping (if exists) old database %s", testDbName);
- master->execute("DROP DATABASE IF EXISTS " + testDbName);
}
-void MockMySQLDatabase::CreateNewDatabase() const
-{
- Logger()->messagebf(LOG_INFO, "Creating new database %s", testDbName);
- master->execute("CREATE DATABASE " + testDbName);
-}
-
-
diff --git a/project2/sql/sql-modMySQL.h b/project2/sql/sql-modMySQL.h
index 628bfdb..b303e71 100644
--- a/project2/sql/sql-modMySQL.h
+++ b/project2/sql/sql-modMySQL.h
@@ -1,23 +1,16 @@
#ifndef MOCKMYSQLDATASOURCE_H
#define MOCKMYSQLDATASOURCE_H
-#include "mockDatasource.h"
+#include "mockDatabase.h"
#include <boost/filesystem/path.hpp>
-class MockMySQLDatabase {
+class MockMySQLDatabase : public MockServerDatabase {
public:
MockMySQLDatabase(const std::string & name, const std::vector<boost::filesystem::path> & ss);
~MockMySQLDatabase();
- protected:
- void DropDatabase() const;
- void CreateNewDatabase() const;
-
private:
- static DB::Connection * openConnection(const std::string & connStr);
- const DB::Connection * master;
- const std::string testDbName;
- const std::string mockName;
+ DB::Connection * openConnection() const override;
};
#endif
diff --git a/project2/sql/sql-modPQ.cpp b/project2/sql/sql-modPQ.cpp
index 5267f28..ec2fcf3 100644
--- a/project2/sql/sql-modPQ.cpp
+++ b/project2/sql/sql-modPQ.cpp
@@ -9,56 +9,28 @@ typedef PQ::Connection PQConnection;
DECLARE_GENERIC_LOADER("postgresql", ConnectionLoader, PQConnection)
MockPqDatabase::MockPqDatabase(const std::string & masterdb, const std::string & name, const std::vector<boost::filesystem::path> & ss) :
- master(InstanceMap<ConnectionLoader, std::string>::Get<std::invalid_argument>("postgresql")->create(masterdb)),
- testDbName(stringbf("test_%d_%d", getpid(), ++MockConnectionLoader::mocked)),
- mockName(name)
+ MockServerDatabase(masterdb, name, "postgresql")
{
- 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);
- if (system(("psql -v ON_ERROR_STOP=1 -q -1 -U postgres " + testDbName + " -f " + s.string()).c_str())) {
- throw std::runtime_error("Failed to execute " + s.string());
- }
- }
- Logger()->messagebf(LOG_DEBUG, "%s initialized", testDbName);
- MockConnectionLoader::mocks[name] = boost::bind(MockPqDatabase::openConnection, stringbf("user=postgres dbname=%s", testDbName));
- }
- catch (...) {
- DropDatabase();
- throw;
- }
+ PlaySchemaScripts(ss);
}
DB::Connection *
-MockPqDatabase::openConnection(const std::string & connStr)
+MockPqDatabase::openConnection() const
{
- return InstanceMap<ConnectionLoader, std::string>::Get<std::invalid_argument>("postgresql")->create(connStr);
+ return InstanceMap<ConnectionLoader, std::string>::Get<std::invalid_argument>("postgresql")->create(
+ stringbf("user=postgres dbname=%s", testDbName));
}
MockPqDatabase::~MockPqDatabase()
{
- Logger()->messagebf(LOG_DEBUG, "Tearing down mocked database %s", testDbName);
DropDatabase();
- delete master;
- MockConnectionLoader::mocks.erase(mockName);
- Logger()->messagebf(LOG_DEBUG, "%s torn down", testDbName);
}
void MockPqDatabase::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);
+ MockServerDatabase::DropDatabase();
}
-void MockPqDatabase::CreateNewDatabase() const
-{
- Logger()->messagebf(LOG_INFO, "Creating new database %s", testDbName);
- master->execute("CREATE DATABASE " + testDbName);
-}
-
-
diff --git a/project2/sql/sql-modPQ.h b/project2/sql/sql-modPQ.h
index f71b5ab..43ef1ee 100644
--- a/project2/sql/sql-modPQ.h
+++ b/project2/sql/sql-modPQ.h
@@ -1,23 +1,19 @@
#ifndef MOCKPQDATASOURCE_H
#define MOCKPQDATASOURCE_H
-#include "mockDatasource.h"
+#include "mockDatabase.h"
#include <boost/filesystem/path.hpp>
-class MockPqDatabase {
+class MockPqDatabase : public MockServerDatabase {
public:
MockPqDatabase(const std::string & master, const std::string & name, const std::vector<boost::filesystem::path> & ss);
~MockPqDatabase();
protected:
- void DropDatabase() const;
- void CreateNewDatabase() const;
+ void DropDatabase() const override;
private:
- static DB::Connection * openConnection(const std::string & connStr);
- const DB::Connection * master;
- const std::string testDbName;
- const std::string mockName;
+ DB::Connection * openConnection() const override;
};
#endif
diff --git a/project2/sql/sql-modSQLite.cpp b/project2/sql/sql-modSQLite.cpp
index 6b4cb85..ef8e133 100644
--- a/project2/sql/sql-modSQLite.cpp
+++ b/project2/sql/sql-modSQLite.cpp
@@ -5,45 +5,28 @@
#include <scripts.h>
#include <logger.h>
#include <boost/filesystem/operations.hpp>
+#include "mockDatasource.h"
typedef SQLite::Connection SQLiteConnection;
DECLARE_GENERIC_LOADER("sqlite", ConnectionLoader, SQLiteConnection)
MockSQLiteDatabase::MockSQLiteDatabase(const std::string & name, const std::vector<boost::filesystem::path> & ss) :
- testDbPath(boost::filesystem::path("/tmp") / "sqliteut" / stringbf("%d", getpid()) / stringbf("%d", ++MockConnectionLoader::mocked)),
- mockName(name)
+ MockDatabase(name),
+ testDbPath(boost::filesystem::path("/tmp") / "sqliteut" / stringbf("%d", getpid()) / stringbf("%d", ++MockConnectionLoader::mocked))
{
- Logger()->messagebf(LOG_DEBUG, "Setting up new mocked database at %s", testDbPath);
- DropDatabase();
CreateNewDatabase();
- try {
- for (auto s : ss) {
- Logger()->messagebf(LOG_DEBUG, "%s << %s", testDbPath, s);
- if (system(("sqlite3 -bail " + testDbPath.string() + " < " + s.string()).c_str())) {
- throw std::runtime_error("Failed to execute " + s.string());
- }
- }
- Logger()->messagebf(LOG_DEBUG, "%s initialized", testDbPath);
- MockConnectionLoader::mocks[name] = boost::bind(MockSQLiteDatabase::openConnection, testDbPath.string());
- }
- catch (...) {
- DropDatabase();
- throw;
- }
+ PlaySchemaScripts(ss);
}
DB::Connection *
-MockSQLiteDatabase::openConnection(const std::string & connStr)
+MockSQLiteDatabase::openConnection() const
{
- return InstanceMap<ConnectionLoader, std::string>::Get<std::invalid_argument>("sqlite")->create(connStr);
+ return InstanceMap<ConnectionLoader, std::string>::Get<std::invalid_argument>("sqlite")->create(testDbPath.string());
}
MockSQLiteDatabase::~MockSQLiteDatabase()
{
- Logger()->messagebf(LOG_DEBUG, "Tearing down mocked database %s", testDbPath);
DropDatabase();
- MockConnectionLoader::mocks.erase(mockName);
- Logger()->messagebf(LOG_DEBUG, "%s torn down", testDbPath);
}
void MockSQLiteDatabase::DropDatabase() const
@@ -56,6 +39,7 @@ void MockSQLiteDatabase::CreateNewDatabase() const
{
Logger()->messagebf(LOG_INFO, "Creating new database at %s", testDbPath);
boost::filesystem::create_directories(testDbPath.parent_path());
+ delete openConnection();
}
diff --git a/project2/sql/sql-modSQLite.h b/project2/sql/sql-modSQLite.h
index 267ba0b..36bca22 100644
--- a/project2/sql/sql-modSQLite.h
+++ b/project2/sql/sql-modSQLite.h
@@ -1,22 +1,22 @@
#ifndef MOCKSQLITEDATASOURCE_H
#define MOCKSQLITEDATASOURCE_H
-#include "mockDatasource.h"
+#include "mockDatabase.h"
#include <boost/filesystem/path.hpp>
-class MockSQLiteDatabase {
+class MockSQLiteDatabase : public MockDatabase {
public:
MockSQLiteDatabase(const std::string & name, const std::vector<boost::filesystem::path> & ss);
~MockSQLiteDatabase();
protected:
- void DropDatabase() const;
- void CreateNewDatabase() const;
+ void DropDatabase() const override;
+ void CreateNewDatabase() const override;
+
+ DB::Connection * openConnection() const override;
private:
- static DB::Connection * openConnection(const std::string & connStr);
const boost::filesystem::path testDbPath;
- const std::string mockName;
};
#endif