129 lines
3.7 KiB
C++
129 lines
3.7 KiB
C++
#include <gtest/gtest.h>
|
|
|
|
#include <eedb/db/RawSql.hpp>
|
|
#include <eedb/db/config.hpp>
|
|
#include <eedb/db/connection.hpp>
|
|
#include <sqlpp11/postgresql/exception.h>
|
|
|
|
#include <boost/process.hpp>
|
|
#include <nlohmann/json.hpp>
|
|
|
|
#include <thread>
|
|
|
|
class DockerRunner {
|
|
enum class Status { Running, Exited, Missing };
|
|
|
|
public:
|
|
DockerRunner(std::string name) : _name{std::move(name)} {
|
|
using namespace boost::process;
|
|
|
|
auto getStatus = [this]() {
|
|
ipstream is; // reading pipe-stream
|
|
auto status = system(search_path("docker"), "inspect", _name, std_out > is);
|
|
|
|
if(!status) {
|
|
std::string statusBuf, line;
|
|
statusBuf.reserve(10240);
|
|
|
|
while(std::getline(is, line) && !line.empty())
|
|
statusBuf.append(line);
|
|
|
|
auto status = nlohmann::json::parse(std::move(statusBuf))[0]["State"]["Status"];
|
|
|
|
if(status == "running") {
|
|
return Status::Running;
|
|
} else if(status == "exited") {
|
|
return Status::Exited;
|
|
}
|
|
}
|
|
return Status::Missing;
|
|
};
|
|
|
|
auto status = getStatus();
|
|
if(status == Status::Exited) {
|
|
system(search_path("docker"), "start", _name);
|
|
} else if(status == Status::Missing) {
|
|
system(search_path("docker"),
|
|
"run --detach",
|
|
"--name",
|
|
_name,
|
|
"-p 5432:5432",
|
|
"-e POSTGRES_PASSWORD=postgres",
|
|
"-e POSTGRES_DB=eedb",
|
|
"postgres:9.5-alpine");
|
|
}
|
|
}
|
|
|
|
~DockerRunner() {
|
|
// using namespace boost::process;
|
|
// auto p = search_path("docker");
|
|
// system(p, "stop", _name);
|
|
// system(p, "rm", "-v", _name);
|
|
}
|
|
|
|
private:
|
|
std::string _name;
|
|
};
|
|
|
|
class PgTestDatabasePrepare {
|
|
public:
|
|
PgTestDatabasePrepare() {
|
|
_docker = std::make_unique< DockerRunner >("eedb_test_database");
|
|
|
|
auto dbConfig = std::make_shared< eedb::db::PgConfig >();
|
|
dbConfig->host = "localhost";
|
|
dbConfig->port = 5432;
|
|
dbConfig->password = "postgres";
|
|
dbConfig->user = "postgres";
|
|
dbConfig->dbname = "eedb";
|
|
dbConfig->debug = false;
|
|
|
|
bool conOk{false};
|
|
int faild_attempts_count{0};
|
|
do {
|
|
try {
|
|
_db = std::make_unique< eedb::db::PgConnection >(dbConfig);
|
|
conOk = true;
|
|
} catch(sqlpp::postgresql::broken_connection &) {
|
|
std::this_thread::sleep_for(std::chrono::milliseconds(500));
|
|
faild_attempts_count++;
|
|
}
|
|
} while(!conOk && faild_attempts_count < 30);
|
|
|
|
if(faild_attempts_count >= 30)
|
|
std::terminate();
|
|
}
|
|
eedb::db::PgConnection & db() {
|
|
if(!_db)
|
|
throw std::runtime_error("db not initialized");
|
|
return *_db;
|
|
}
|
|
|
|
private:
|
|
std::unique_ptr< DockerRunner > _docker;
|
|
std::unique_ptr< eedb::db::PgConnection > _db;
|
|
};
|
|
|
|
template < typename T >
|
|
class DbTestBase : public testing::Test {
|
|
public:
|
|
static void SetUpTestCase() {
|
|
_test_db = std::make_unique< PgTestDatabasePrepare >();
|
|
_test_db->db().native()->start_transaction();
|
|
_test_db->db().native()->execute("SET synchronous_commit=off;");
|
|
eedb::db::exec_file(_test_db->db(), "/home/bwieczor/src/eedb/sql/schema.sql");
|
|
_test_db->db().native()->commit_transaction();
|
|
}
|
|
|
|
static void TearDownTestCase() {
|
|
_test_db.reset();
|
|
}
|
|
|
|
eedb::db::PgConnection & db() {
|
|
return _test_db->db();
|
|
}
|
|
|
|
protected:
|
|
static std::unique_ptr< PgTestDatabasePrepare > _test_db;
|
|
};
|