126 lines
2.9 KiB
C++
126 lines
2.9 KiB
C++
|
|
#include "PgTestEnvironment.h"
|
||
|
|
|
||
|
|
#include <QCoreApplication>
|
||
|
|
#include <QFile>
|
||
|
|
#include <QUrl>
|
||
|
|
#include <iostream>
|
||
|
|
#include <stdexcept>
|
||
|
|
|
||
|
|
#include "Pgsql_Connection.h"
|
||
|
|
#include "Pgsql_Result.h"
|
||
|
|
|
||
|
|
namespace pgtest {
|
||
|
|
|
||
|
|
namespace {
|
||
|
|
|
||
|
|
bool g_available = false;
|
||
|
|
int g_versionNum = 0;
|
||
|
|
|
||
|
|
} // namespace
|
||
|
|
|
||
|
|
std::optional<QString> baseUrl()
|
||
|
|
{
|
||
|
|
QByteArray v = qgetenv("TEST_DATABASE_URL");
|
||
|
|
if (v.isEmpty())
|
||
|
|
return std::nullopt;
|
||
|
|
return QString::fromUtf8(v);
|
||
|
|
}
|
||
|
|
|
||
|
|
QString urlForDb(const QString &db)
|
||
|
|
{
|
||
|
|
auto base = baseUrl();
|
||
|
|
if (!base)
|
||
|
|
throw std::runtime_error("TEST_DATABASE_URL is not set");
|
||
|
|
QUrl url(*base);
|
||
|
|
url.setPath("/" + db);
|
||
|
|
return url.toString();
|
||
|
|
}
|
||
|
|
|
||
|
|
bool available()
|
||
|
|
{
|
||
|
|
return g_available;
|
||
|
|
}
|
||
|
|
|
||
|
|
int serverVersionNum()
|
||
|
|
{
|
||
|
|
return g_versionNum;
|
||
|
|
}
|
||
|
|
|
||
|
|
qint64 processId()
|
||
|
|
{
|
||
|
|
return QCoreApplication::applicationPid();
|
||
|
|
}
|
||
|
|
|
||
|
|
QString templateDbName()
|
||
|
|
{
|
||
|
|
return QString("tmpl_%1").arg(processId());
|
||
|
|
}
|
||
|
|
|
||
|
|
QString quoteIdent(const QString &name)
|
||
|
|
{
|
||
|
|
QString r = name;
|
||
|
|
r.replace('"', "\"\"");
|
||
|
|
return "\"" + r + "\"";
|
||
|
|
}
|
||
|
|
|
||
|
|
void PgEnv::SetUp()
|
||
|
|
{
|
||
|
|
auto base = baseUrl();
|
||
|
|
if (!base) {
|
||
|
|
std::cerr << "TEST_DATABASE_URL not set, integration tests will be skipped\n";
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
const QString tmpl = templateDbName();
|
||
|
|
try {
|
||
|
|
{
|
||
|
|
Pgsql::Connection admin;
|
||
|
|
admin.connect(*base);
|
||
|
|
Pgsql::Result r = admin.query("SHOW server_version_num");
|
||
|
|
if (!r || r.rows() != 1)
|
||
|
|
throw std::runtime_error("could not query server_version_num");
|
||
|
|
g_versionNum = QString::fromUtf8(r.val(0, 0)).toInt();
|
||
|
|
admin.query(QString("DROP DATABASE IF EXISTS %1 WITH (FORCE)").arg(quoteIdent(tmpl)));
|
||
|
|
admin.query(QString("CREATE DATABASE %1").arg(quoteIdent(tmpl)));
|
||
|
|
}
|
||
|
|
{
|
||
|
|
QFile f(fixtureDir_ + "/schema.sql");
|
||
|
|
if (!f.open(QIODevice::ReadOnly))
|
||
|
|
throw std::runtime_error("cannot open " + f.fileName().toStdString());
|
||
|
|
QByteArray sql = f.readAll();
|
||
|
|
|
||
|
|
Pgsql::Connection c;
|
||
|
|
c.connect(urlForDb(tmpl));
|
||
|
|
c.query(sql.constData());
|
||
|
|
}
|
||
|
|
g_available = true;
|
||
|
|
}
|
||
|
|
catch (const std::exception &e) {
|
||
|
|
ADD_FAILURE() << "Setting up template database failed: " << e.what();
|
||
|
|
try {
|
||
|
|
Pgsql::Connection admin;
|
||
|
|
admin.connect(*base);
|
||
|
|
admin.query(QString("DROP DATABASE IF EXISTS %1 WITH (FORCE)").arg(quoteIdent(tmpl)));
|
||
|
|
}
|
||
|
|
catch (const std::exception &) {
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
void PgEnv::TearDown()
|
||
|
|
{
|
||
|
|
if (!g_available)
|
||
|
|
return;
|
||
|
|
try {
|
||
|
|
Pgsql::Connection admin;
|
||
|
|
admin.connect(*baseUrl());
|
||
|
|
admin.query(QString("DROP DATABASE IF EXISTS %1 WITH (FORCE)").arg(quoteIdent(templateDbName())));
|
||
|
|
}
|
||
|
|
catch (const std::exception &e) {
|
||
|
|
ADD_FAILURE() << "Dropping template database failed: " << e.what();
|
||
|
|
}
|
||
|
|
g_available = false;
|
||
|
|
}
|
||
|
|
|
||
|
|
} // namespace pgtest
|