
22 changed files with 248807 additions and 61 deletions
@ -0,0 +1,48 @@ |
|||
#include "ListManagerDummy.hh" |
|||
//#include "status_to_string.hh"
|
|||
|
|||
#include "pEpLog.hh" |
|||
|
|||
namespace pEp { |
|||
|
|||
void ListManagerDummy::create( |
|||
pEp_identity *group_identity, |
|||
pEp_identity *manager, |
|||
identity_list *memberlist) |
|||
{ |
|||
pEpLog("called"); |
|||
} |
|||
|
|||
void ListManagerDummy::dissolve(pEp_identity *group_identity) |
|||
{ |
|||
pEpLog("called"); |
|||
} |
|||
|
|||
void ListManagerDummy::join(pEp_identity *group_identity, pEp_identity *as_member) |
|||
{ |
|||
pEpLog("called"); |
|||
} |
|||
|
|||
void ListManagerDummy::remove_member(pEp_identity *group_identity, pEp_identity *group_member) |
|||
{ |
|||
pEpLog("called"); |
|||
} |
|||
|
|||
identity_list *ListManagerDummy::groups() |
|||
{ |
|||
pEpLog("called"); |
|||
return NULL; |
|||
} |
|||
|
|||
pEp_identity *ListManagerDummy::manager(const pEp_identity *const group) |
|||
{ |
|||
pEpLog("called"); |
|||
return NULL; |
|||
} |
|||
|
|||
identity_list *ListManagerDummy::members(const pEp_identity *const group) |
|||
{ |
|||
pEpLog("called"); |
|||
return NULL; |
|||
} |
|||
} // namespace pEp
|
@ -0,0 +1,29 @@ |
|||
// This file is under GNU General Public License 3.0
|
|||
// see LICENSE.txt
|
|||
#ifndef LIBPEPADAPTER_LISTMANAGERDUMMY_HH |
|||
#define LIBPEPADAPTER_LISTMANAGERDUMMY_HH |
|||
|
|||
#include "ListManagerInterface.hh" |
|||
|
|||
namespace pEp { |
|||
class ListManagerDummy : public ListManagerInterface { |
|||
public: |
|||
// update functions
|
|||
// Group create/destroy
|
|||
void create(pEp_identity *group_identity, pEp_identity *manager, identity_list *memberlist) override; |
|||
void dissolve(pEp_identity *group_identity) override; |
|||
|
|||
// Members create/destroy
|
|||
void join(pEp_identity *group_identity, pEp_identity *as_member) override; |
|||
void remove_member(pEp_identity *group_identity, pEp_identity *group_member) override; |
|||
|
|||
// query functions
|
|||
identity_list *groups() override; |
|||
pEp_identity *manager(const pEp_identity *const group) override; |
|||
identity_list *members(const pEp_identity *const group) override; |
|||
|
|||
private: |
|||
}; |
|||
} // namespace pEp
|
|||
|
|||
#endif // LIBPEPADAPTER_LISTMANAGERDUMMY_HH
|
@ -0,0 +1,33 @@ |
|||
// This file is under GNU General Public License 3.0
|
|||
// see LICENSE.txt
|
|||
|
|||
#ifndef LIBPEPADAPTER_LISTMANAGERINTERFACE_HH |
|||
#define LIBPEPADAPTER_LISTMANAGERINTERFACE_HH |
|||
|
|||
#include <pEp/message_api.h> |
|||
|
|||
namespace pEp { |
|||
class ListManagerInterface { |
|||
public: |
|||
// update functions
|
|||
// Group create/destroy
|
|||
virtual void create( |
|||
pEp_identity *group_identity, |
|||
pEp_identity *manager, |
|||
identity_list *memberlist) = 0; |
|||
virtual void dissolve(pEp_identity *group_identity) = 0; |
|||
|
|||
// Members create/destroy
|
|||
virtual void join(pEp_identity *group_identity, pEp_identity *as_member) = 0; |
|||
virtual void remove_member(pEp_identity *group_identity, pEp_identity *group_member) = 0; |
|||
|
|||
// query functions
|
|||
virtual identity_list *groups() = 0; |
|||
virtual pEp_identity *manager(const pEp_identity *const group) = 0; |
|||
virtual identity_list *members(const pEp_identity *const group) = 0; |
|||
|
|||
private: |
|||
}; |
|||
} // namespace pEp
|
|||
|
|||
#endif // LIBPEPADAPTER_LISTMANAGERINTERFACE_HH
|
File diff suppressed because it is too large
@ -0,0 +1,354 @@ |
|||
#include "listmanager_dummy.hh" |
|||
#include "pEpSQLite.hh" |
|||
#include <exception> |
|||
|
|||
using namespace std; |
|||
|
|||
namespace pEp { |
|||
bool ListManagerDummy::log_enabled = false; |
|||
|
|||
// public
|
|||
ListManagerDummy::ListManagerDummy(const string& db_path) : db(pEpSQLite(db_path)) |
|||
{ |
|||
pEpLogClass("called"); |
|||
} |
|||
|
|||
// private
|
|||
void ListManagerDummy::ensure_db_initialized() |
|||
{ |
|||
if (!db.is_open()) { |
|||
is_db_initialized = false; |
|||
try { |
|||
db.create_or_open_db(); |
|||
} catch (...) { |
|||
db.close_db(); |
|||
DBException e{ "ListManagerDummy - error opening db" }; |
|||
throw_with_nested(e); |
|||
} |
|||
} |
|||
if (!is_db_initialized) { |
|||
try { |
|||
db_config(); |
|||
create_tables(); |
|||
} catch (...) { |
|||
db.close_db(); |
|||
DBException e{ "ListManagerDummy - db init failed" }; |
|||
throw_with_nested(e); |
|||
} |
|||
is_db_initialized = true; |
|||
} |
|||
} |
|||
|
|||
// private
|
|||
void ListManagerDummy::db_config() |
|||
{ |
|||
try { |
|||
string sql; |
|||
sql = "PRAGMA foreign_keys=ON"; |
|||
db.execute(sql); |
|||
} catch (...) { |
|||
DBException e{ "ListManagerDummy - db config failed" }; |
|||
throw_with_nested(e); |
|||
} |
|||
} |
|||
|
|||
// private
|
|||
void ListManagerDummy::create_tables() |
|||
{ |
|||
try { |
|||
string sql; |
|||
|
|||
sql = "CREATE TABLE IF NOT EXISTS lists(" |
|||
"address TEXT NOT NULL," |
|||
"moderator_address TEXT NOT NULL," |
|||
"PRIMARY KEY(address));"; |
|||
db.execute(sql); |
|||
|
|||
sql = "CREATE TABLE IF NOT EXISTS member_of(" |
|||
"address TEXT NOT NULL," |
|||
"list_address TEXT NOT NULL," |
|||
"PRIMARY KEY (address, list_address)," |
|||
"FOREIGN KEY(list_address) REFERENCES lists(address) ON DELETE CASCADE);"; |
|||
db.execute(sql); |
|||
} catch (...) { |
|||
DBException e("ListManagerDummy - create tables failed"); |
|||
throw_with_nested(e); |
|||
} |
|||
} |
|||
|
|||
// public
|
|||
void ListManagerDummy::close_db() |
|||
{ |
|||
pEpLogClass("called"); |
|||
db.close_db(); |
|||
} |
|||
|
|||
// public
|
|||
void ListManagerDummy::delete_db() |
|||
{ |
|||
pEpLogClass("called"); |
|||
try { |
|||
db.delete_db(); |
|||
} catch (...) { |
|||
DBException e{ "ListManagerDummy: delete_db() failed" }; |
|||
throw_with_nested(e); |
|||
} |
|||
} |
|||
|
|||
// public
|
|||
void ListManagerDummy::list_add(const std::string& addr_list, const std::string& addr_mgr) |
|||
{ |
|||
pEpLogClass("list_add(addr_list: \"" + addr_list + "\", addr_mgr: \"" + addr_mgr + "\")"); |
|||
if (list_exists(addr_list)) { |
|||
AlreadyExistsException e{ "list_add(addr_list: \"" + addr_list + "\", addr_mgr: \"" + |
|||
addr_mgr + "\") - List already exists" }; |
|||
throw e; |
|||
} |
|||
|
|||
try { |
|||
string sql = "INSERT INTO lists(address, moderator_address) VALUES ('" + addr_list + |
|||
"','" + addr_mgr + "');"; |
|||
|
|||
db.execute(sql); |
|||
} catch (...) { |
|||
DBException e{ "ListManagerDummy: list_add(addr_list: \"" + addr_list + |
|||
"\"\taddr_mgr: \"" + addr_mgr + "\") - failed with exception" }; |
|||
throw_with_nested(e); |
|||
} |
|||
} |
|||
|
|||
// public
|
|||
void ListManagerDummy::list_delete(const std::string& addr_list) |
|||
{ |
|||
pEpLogClass("list_delete(addr_list: \"" + addr_list + "\")"); |
|||
if (!list_exists(addr_list)) { |
|||
DoesNotExistException e{ "list_delete(addr_list: \"" + addr_list + |
|||
"\") - List does not exist" }; |
|||
throw e; |
|||
} |
|||
|
|||
try { |
|||
string sql; |
|||
sql = "DELETE FROM lists WHERE lists.address = '" + addr_list + "';"; |
|||
db.execute(sql); |
|||
} catch (...) { |
|||
DBException e{ "ListManagerDummy: list_delete(addr_list: \"" + addr_list + |
|||
"\") - failed with exception" }; |
|||
throw_with_nested(e); |
|||
} |
|||
} |
|||
|
|||
// public
|
|||
void ListManagerDummy::member_add(const std::string& addr_list, const std::string& addr_member) |
|||
{ |
|||
pEpLogClass( |
|||
"member_add(addr_list: \"" + addr_list + "\", addr_member: \"" + addr_member + "\")"); |
|||
if (member_exists(addr_list, addr_member)) { |
|||
AlreadyExistsException e{ "member_add(addr_list: \"" + addr_list + "\", addr_member: \"" + |
|||
addr_member + "\") - member already exists" }; |
|||
throw e; |
|||
} |
|||
|
|||
try { |
|||
string sql = "INSERT INTO member_of(address, list_address) VALUES ('" + addr_member + |
|||
"', '" + addr_list + "');"; |
|||
db.execute(sql); |
|||
} catch (...) { |
|||
DBException e{ "ListManagerDummy: member_add(addr_list: \"" + addr_list + |
|||
"\", addr_member: \"" + addr_member + "\") - failed with exception" }; |
|||
throw_with_nested(e); |
|||
} |
|||
} |
|||
|
|||
// public
|
|||
void ListManagerDummy::member_remove(const std::string& addr_list, const std::string& addr_member) |
|||
{ |
|||
pEpLogClass( |
|||
"member_remove(addr_list: \"" + addr_list + "\", addr_member: '\"" + addr_member + "\")"); |
|||
if (!member_exists(addr_list, addr_member)) { |
|||
DoesNotExistException e{ "member_remove(addr_list: \"" + addr_list + |
|||
"\", addr_member: '\"" + addr_member + |
|||
"\") - member does not exist" }; |
|||
throw e; |
|||
} |
|||
|
|||
try { |
|||
string sql; |
|||
sql = "DELETE FROM member_of WHERE (member_of.address = '" + addr_member + |
|||
"') AND (member_of.list_address = '" + addr_list + "');"; |
|||
db.execute(sql); |
|||
} catch (...) { |
|||
DBException e{ "ListManagerDummy: member_remove(" + addr_list + ", " + addr_member + |
|||
") - failed with exception" }; |
|||
throw_with_nested(e); |
|||
} |
|||
} |
|||
|
|||
// public
|
|||
std::vector<std::string> ListManagerDummy::lists() |
|||
{ |
|||
pEpLogClass("called"); |
|||
ensure_db_initialized(); |
|||
vector<string> ret; |
|||
ResultSet rs; |
|||
|
|||
try { |
|||
string sql; |
|||
sql = "SELECT address FROM lists"; |
|||
rs = db.execute(sql); |
|||
} catch (...) { |
|||
DBException e{ "ListManagerDummy: lists() failed" }; |
|||
throw_with_nested(e); |
|||
} |
|||
|
|||
for (const RSRecord& rec : rs) { |
|||
ret.push_back(rec.at("address")); |
|||
} |
|||
|
|||
return ret; |
|||
} |
|||
|
|||
// public
|
|||
std::string ListManagerDummy::moderator(const std::string& addr_list) |
|||
{ |
|||
pEpLogClass("moderator(list_address:\"" + addr_list + "\")"); |
|||
if (!list_exists(addr_list)) { |
|||
DoesNotExistException e{ "moderator(list_address:\"" + addr_list + |
|||
"\") - List does not exist" }; |
|||
throw e; |
|||
} |
|||
|
|||
string ret; |
|||
ResultSet rs; |
|||
|
|||
try { |
|||
string sql; |
|||
sql = "SELECT moderator_address FROM lists " |
|||
"WHERE lists.address = '" + |
|||
addr_list + "';"; |
|||
rs = db.execute(sql); |
|||
} catch (...) { |
|||
DBException e{ "ListManagerDummy: moderator(list_address:\"" + addr_list + |
|||
"\") - failed" }; |
|||
throw_with_nested(e); |
|||
} |
|||
|
|||
if (!rs.empty()) { |
|||
for (const RSRecord& rec : rs) { |
|||
ret = rec.at("moderator_address"); |
|||
} |
|||
} |
|||
|
|||
return ret; |
|||
} |
|||
|
|||
// public
|
|||
std::vector<std::string> ListManagerDummy::members(const std::string& addr_list) |
|||
{ |
|||
pEpLogClass("members(list_address:\"" + addr_list + "\")"); |
|||
if (!list_exists(addr_list)) { |
|||
DoesNotExistException e{ "members(list_address:\"" + addr_list + |
|||
"\") - List does not exist" }; |
|||
throw e; |
|||
} |
|||
|
|||
vector<string> ret; |
|||
ResultSet rs; |
|||
|
|||
try { |
|||
string sql; |
|||
sql = "SELECT address FROM member_of " |
|||
"WHERE list_address = '" + |
|||
addr_list + "'"; |
|||
rs = db.execute(sql); |
|||
} catch (...) { |
|||
DBException e{ "ListManagerDummy: members(list_address:\"" + addr_list + "\")" }; |
|||
throw_with_nested(e); |
|||
} |
|||
|
|||
if (!rs.empty()) { |
|||
for (const RSRecord& rec : rs) { |
|||
ret.push_back(rec.at("address")); |
|||
} |
|||
} |
|||
|
|||
return ret; |
|||
} |
|||
|
|||
bool ListManagerDummy::list_exists(const std::string& addr_list) |
|||
{ |
|||
pEpLogClass("list_exists(addr_list:\"" + addr_list + "\")"); |
|||
bool ret{ false }; |
|||
ensure_db_initialized(); |
|||
|
|||
ResultSet rs; |
|||
int rescount = 0; |
|||
try { |
|||
string sql; |
|||
sql = "SELECT COUNT(address) AS rescount " |
|||
"FROM lists " |
|||
"WHERE address = '" + |
|||
addr_list + "';"; |
|||
rs = db.execute(sql); |
|||
rescount = pEpSQLite::eval_sql_count(rs, "rescount"); |
|||
} catch (...) { |
|||
DBException e{ "ListManagerDummy: list_exists(addr_list:\"" + addr_list + "\")" }; |
|||
throw_with_nested(e); |
|||
} |
|||
// Check FATAL inconsistency
|
|||
if (rescount > 1) { |
|||
DBException e{ "ListManagerDummy: list_exists(addr_list:\"" + addr_list + |
|||
"\") - FATAL DB CONSTRAINT ERROR: list exists more than once" }; |
|||
throw_with_nested(e); |
|||
} |
|||
|
|||
if (rescount == 1) { |
|||
ret = true; |
|||
} |
|||
return ret; |
|||
} |
|||
|
|||
bool ListManagerDummy::member_exists(const std::string& addr_list, const std::string& addr_member) |
|||
{ |
|||
pEpLogClass( |
|||
"member_exists(addr_list:\"" + addr_list + "\", addr_member:\"" + addr_member + "\")"); |
|||
bool ret{ false }; |
|||
ensure_db_initialized(); |
|||
|
|||
ResultSet rs; |
|||
int rescount = 0; |
|||
try { |
|||
string sql; |
|||
sql = "SELECT COUNT(address) AS rescount " |
|||
"FROM member_of " |
|||
"WHERE (address = '" + |
|||
addr_member + "' AND list_address = '" + addr_list + "');"; |
|||
rs = db.execute(sql); |
|||
rescount = pEpSQLite::eval_sql_count(rs, "rescount"); |
|||
} catch (...) { |
|||
DBException e{ "member_exists(addr_list:\"" + addr_list + "\", addr_member:\"" + |
|||
addr_member + "\")" }; |
|||
throw_with_nested(e); |
|||
} |
|||
// Check FATAL inconsistency
|
|||
if (rescount > 1) { |
|||
DBException e{ "member_exists(addr_list:\"" + addr_list + "\", addr_member:\"" + |
|||
addr_member + |
|||
"\") - FATAL DB CONSTRAINT ERROR: list exists more than once" }; |
|||
throw_with_nested(e); |
|||
} |
|||
|
|||
if (rescount == 1) { |
|||
ret = true; |
|||
} |
|||
return ret; |
|||
} |
|||
|
|||
|
|||
// public
|
|||
ListManagerDummy::~ListManagerDummy() |
|||
{ |
|||
pEpLogClass("called"); |
|||
db.close_db(); |
|||
} |
|||
} // namespace pEp
|
@ -0,0 +1,59 @@ |
|||
// This file is under GNU General Public License 3.0
|
|||
// see LICENSE.txt
|
|||
|
|||
#ifndef LIBPEPADAPTER_LISTMANAGER_DUMMY_HH |
|||
#define LIBPEPADAPTER_LISTMANAGER_DUMMY_HH |
|||
|
|||
#include "pEpSQLite.hh" |
|||
#include "pEpLog.hh" |
|||
#include <vector> |
|||
#include <string> |
|||
|
|||
namespace pEp { |
|||
class ListManagerDummy { |
|||
public: |
|||
ListManagerDummy() = delete; |
|||
explicit ListManagerDummy(const std::string& db_path); |
|||
// Update
|
|||
void list_add(const std::string& addr_list, const std::string& addr_mgr); |
|||
void list_delete(const std::string& addr_list); |
|||
void member_add(const std::string& addr_list, const std::string& addr_member); |
|||
void member_remove(const std::string& addr_list, const std::string& addr_member); |
|||
// Query
|
|||
std::vector<std::string> lists(); |
|||
std::string moderator(const std::string& addr_list); |
|||
std::vector<std::string> members(const std::string& addr_list); |
|||
bool list_exists(const std::string& addr_list); |
|||
bool member_exists(const std::string& addr_list, const std::string& addr_member); |
|||
// db
|
|||
void close_db(); |
|||
void delete_db(); |
|||
// Logging
|
|||
static bool log_enabled; |
|||
Adapter::pEpLog::pEpLogger logger{ "ListManagerDummy", log_enabled }; |
|||
~ListManagerDummy(); |
|||
|
|||
private: |
|||
pEpSQLite db; |
|||
bool is_db_initialized{ false }; |
|||
void ensure_db_initialized(); |
|||
void db_config(); |
|||
void create_tables(); |
|||
Adapter::pEpLog::pEpLogger& m4gic_logger_n4ame = logger; |
|||
}; |
|||
|
|||
class DBException : public std::runtime_error { |
|||
public: |
|||
DBException(const std::string& string) : runtime_error(string) {} |
|||
}; |
|||
class DoesNotExistException : public std::runtime_error { |
|||
public: |
|||
DoesNotExistException(const std::string& string) : runtime_error(string) {} |
|||
}; |
|||
class AlreadyExistsException : public std::runtime_error { |
|||
public: |
|||
AlreadyExistsException(const std::string& string) : runtime_error(string) {} |
|||
}; |
|||
} // namespace pEp
|
|||
|
|||
#endif // LIBPEPADAPTER_LISTMANAGER_DUMMY_HH
|
@ -0,0 +1,166 @@ |
|||
#include "pEpSQLite.hh" |
|||
#include "pEpLog.hh" |
|||
#include <iostream> |
|||
#include <cstdio> |
|||
#include <stdexcept> |
|||
#include <string> |
|||
|
|||
using namespace std; |
|||
|
|||
namespace pEp { |
|||
bool pEpSQLite::log_enabled = false; |
|||
|
|||
pEpSQLite::pEpSQLite(const std::string &db_path) : db_path(db_path) |
|||
{ |
|||
pEpLogClass("called with db_path: " + db_path + ""); |
|||
} |
|||
|
|||
void pEpSQLite::create_or_open_db() |
|||
{ |
|||
pEpLogClass("called"); |
|||
int rc{ ::sqlite3_open(db_path.c_str(), &db) }; |
|||
|
|||
if (rc) { |
|||
runtime_error e{ "pEpSQLite: create_or_open_db(\"" + db_path + |
|||
"\") - failed with sqlite3 error: " + std::to_string(rc) + " - " + |
|||
::sqlite3_errmsg(db) }; |
|||
close_db(); |
|||
throw(e); |
|||
} |
|||
} |
|||
|
|||
string pEpSQLite::get_db_path() const |
|||
{ |
|||
pEpLogClass("called"); |
|||
return db_path; |
|||
} |
|||
|
|||
void pEpSQLite::close_db() |
|||
{ |
|||
pEpLogClass("called"); |
|||
if (db != nullptr) { |
|||
::sqlite3_close(db); |
|||
db = nullptr; |
|||
} |
|||
} |
|||
|
|||
bool pEpSQLite::is_open() const |
|||
{ |
|||
if (db == nullptr) { |
|||
return false; |
|||
} else { |
|||
return true; |
|||
} |
|||
} |
|||
|
|||
|
|||
void pEpSQLite::delete_db() |
|||
{ |
|||
pEpLogClass("called"); |
|||
close_db(); |
|||
int status = remove(db_path.c_str()); |
|||
if (status) { |
|||
runtime_error e{ "pEpSQLite: delete_db(\"" + db_path + "\"): failed with error: " + |
|||
std::to_string(status) + " - " + strerror(errno) }; |
|||
throw(e); |
|||
} |
|||
} |
|||
|
|||
int pEpSQLite::callback(void *obj, int argc, char **argv, char **azColName) |
|||
{ |
|||
RSRecord record; |
|||
for (int col = 0; col < argc; col++) { |
|||
const string key = string{ azColName[col] }; |
|||
// TODO: NULL is not correct, could be a valid value
|
|||
const string val = string{ argv[col] ? argv[col] : "NULL" }; |
|||
record.insert({ key, val }); |
|||
} |
|||
(static_cast<pEpSQLite *>(obj))->resultset.push_back(record); |
|||
return 0; |
|||
} |
|||
|
|||
ResultSet pEpSQLite::execute(const string &stmt) |
|||
{ |
|||
if (!is_open()) { |
|||
DBNotOpenException e{ "pEpSQLite: execute() failed - db is not open:" }; |
|||
throw(e); |
|||
} else { |
|||
pEpLogClass("called"); |
|||
this->resultset.clear(); |
|||
char *zErrMsg = nullptr; |
|||
int rc = ::sqlite3_exec( |
|||
db, |
|||
stmt.c_str(), |
|||
(int (*)(void *, int, char **, char **)) & callback, |
|||
this, |
|||
&zErrMsg); |
|||
if (rc != SQLITE_OK) { |
|||
if (rc == SQLITE_CONSTRAINT) { |
|||
ConstraintException e{ "pEpSQLite: execute() failed with sqlite error: " + |
|||
std::to_string(rc) + " - " + string(zErrMsg) }; |
|||
::sqlite3_free(zErrMsg); |
|||
throw(e); |
|||
} |
|||
runtime_error e{ "pEpSQLite: execute() failed with sqlite error: " + |
|||
std::to_string(rc) + " - " + string(zErrMsg) }; |
|||
::sqlite3_free(zErrMsg); |
|||
throw(e); |
|||
} |
|||
} |
|||
return resultset; |
|||
} |
|||
|
|||
// Utils
|
|||
string pEpSQLite::to_string(const RSRecord &rec) |
|||
{ |
|||
stringstream ss; |
|||
for (const auto &col : rec) { |
|||
ss << "[\"" << col.first << "\"] = \"" << col.second << "\"" << endl; |
|||
} |
|||
return ss.str(); |
|||
} |
|||
|
|||
string pEpSQLite::to_string(const ResultSet &rs) |
|||
{ |
|||
stringstream ss; |
|||
ss << "ROWCOUNT: " << rs.size() << endl; |
|||
int i = 0; |
|||
for (const RSRecord &rec : rs) { |
|||
ss << "ROW[" << i << "]" << endl << to_string(rec); |
|||
i++; |
|||
} |
|||
return ss.str(); |
|||
} |
|||
|
|||
//Helper
|
|||
int pEpSQLite::eval_sql_count(const ResultSet& rs, const string& countfieldname) |
|||
{ |
|||
int rescount = 0; |
|||
// Get row
|
|||
RSRecord rec{}; |
|||
if (rs.size() != 1) { |
|||
runtime_error e{ "ListManagerDummy: eval_sql_count() - row count != 1" }; |
|||
throw_with_nested(e); |
|||
} |
|||
try { |
|||
rec = rs.at(0); |
|||
} catch (...) { |
|||
runtime_error e{ "ListManagerDummy: eval_sql_count() - cant get row nr 0" }; |
|||
throw_with_nested(e); |
|||
} |
|||
// Get field
|
|||
try { |
|||
rescount = stoi(rec.at(countfieldname)); |
|||
} catch (...) { |
|||
runtime_error e{ "ListManagerDummy: eval_sql_count() - field not existing" }; |
|||
throw_with_nested(e); |
|||
} |
|||
return rescount; |
|||
} |
|||
|
|||
pEpSQLite::~pEpSQLite() |
|||
{ |
|||
pEpLogClass("called"); |
|||
close_db(); |
|||
} |
|||
} // namespace pEp
|
@ -0,0 +1,64 @@ |
|||
// This file is under GNU General Public License 3.0
|
|||
// see LICENSE.txt
|
|||
#ifndef LIBPEPADAPTER_PEPSQLITE_HH |
|||
#define LIBPEPADAPTER_PEPSQLITE_HH |
|||
|
|||
#include "internal/sqlite3.h" |
|||
#include "pEpLog.hh" |
|||
#include <iostream> |
|||
#include <vector> |
|||
#include <map> |
|||
|
|||
|
|||
using ResultSet = std::vector<std::map<std::string, std::string>>; |
|||
using RSRecord = std::map<std::string, std::string>; |
|||
|
|||
namespace pEp { |
|||
class pEpSQLite { |
|||
public: |
|||
pEpSQLite() = delete; |
|||
|
|||
// The database file as a constant for the obj lifetime
|
|||
explicit pEpSQLite(const std::string& db_path); |
|||
std::string get_db_path() const; |
|||
|
|||
// Creates the database file not existsing
|
|||
// Will not create any dirs
|
|||
void create_or_open_db(); |
|||
void close_db(); |
|||
bool is_open() const; |
|||
|
|||
// Delete the database file
|
|||
void delete_db(); |
|||
ResultSet execute(const std::string& stmt); |
|||
|
|||
// Utils
|
|||
static std::string to_string(const RSRecord& rec); |
|||
static std::string to_string(const ResultSet& rs); |
|||
static int eval_sql_count(const ResultSet& rs, const std::string& countfieldname); |
|||
|
|||
// Logging
|
|||
static bool log_enabled; |
|||
Adapter::pEpLog::pEpLogger logger{ "pEpSQLite", log_enabled }; |
|||
~pEpSQLite(); |
|||
|
|||
private: |
|||
::sqlite3* db = nullptr; |
|||
std::string db_path; |
|||
ResultSet resultset; |
|||
Adapter::pEpLog::pEpLogger& m4gic_logger_n4ame = logger; |
|||
static int callback(void* obj, int argc, char** argv, char** azColName); |
|||
}; |
|||
|
|||
class DBNotOpenException : public std::runtime_error { |
|||
public: |
|||
DBNotOpenException(const std::string& string) : runtime_error(string) {} |
|||
}; |
|||
|
|||
class ConstraintException : public std::runtime_error { |
|||
public: |
|||
ConstraintException(const std::string& string) : runtime_error(string) {} |
|||
}; |
|||
} // namespace pEp
|
|||
|
|||
#endif // LIBPEPADAPTER_PEPSQLITE_HH
|
File diff suppressed because it is too large
@ -0,0 +1,24 @@ |
|||
// This file is under GNU General Public License 3.0
|
|||
// see LICENSE.txt
|
|||
|
|||
#ifndef LIBPEPADAPTER_UTILS_HXX |
|||
#define LIBPEPADAPTER_UTILS_HXX |
|||
|
|||
#include <sstream> |
|||
|
|||
namespace pEp { |
|||
namespace Test { |
|||
namespace Utils { |
|||
template<typename T> |
|||
std::string to_string(std::vector<T> v) |
|||
{ |
|||
std::stringstream ss; |
|||
for (const T& elem : v) { |
|||
ss << elem << std::endl; |
|||
} |
|||
return ss.str(); |
|||
} |
|||
} |
|||
} // namespace Test
|
|||
} // namespace pEp
|
|||
#endif // LIBPEPADAPTER_UTILS_HXX
|
@ -0,0 +1,276 @@ |
|||
#include "../src/listmanager_dummy.hh" |
|||
#include "framework/utils.hh" |
|||
#include <iostream> |
|||
#include <exception> |
|||
#include <map> |
|||
|
|||
#ifndef ASSERT_EXCEPT |
|||
#define ASSERT_EXCEPT(func) \ |
|||
do { \ |
|||
try { \ |
|||
(func); \ |
|||
assert(false); \ |
|||
} catch (const exception& e) { \ |
|||
Test::Utils::print_exception(e); \ |
|||
} \ |
|||
} while (0) |
|||
#endif |
|||
|
|||
using namespace std; |
|||
using namespace pEp; |
|||
using namespace Test::Log; |
|||
using namespace Test::Utils; |
|||
|
|||
struct lm_list { |
|||
string addr; |
|||
string mod; |
|||
vector<string> members; |
|||
}; |
|||
|
|||
struct model_test_lmd { |
|||
string alice; |
|||
string bob; |
|||
string carol; |
|||
string joe; |
|||
string db_path; |
|||
vector<lm_list> lists; |
|||
vector<string> lists_addr() const |
|||
{ |
|||
vector<string> ret; |
|||
for (const lm_list& l : this->lists) { |
|||
ret.push_back(l.addr); |
|||
} |
|||
return ret; |
|||
} |
|||
}; |
|||
|
|||
void apply_model(ListManagerDummy& lmd, const model_test_lmd& model) |
|||
{ |
|||
cout << "apply_model()" << endl; |
|||
for (const lm_list& l : model.lists) { |
|||
lmd.list_add(l.addr, l.mod); |
|||
for (const string& m : l.members) { |
|||
lmd.member_add(l.addr, m); |
|||
} |
|||
} |
|||
} |
|||
|
|||
void verify_model(ListManagerDummy& lmd, const model_test_lmd& model) |
|||
{ |
|||
cout << "verify_model()" << endl; |
|||
assert((model.lists_addr()) == lmd.lists()); |
|||
for (const lm_list& l : model.lists) { |
|||
assert(l.members == lmd.members(l.addr)); |
|||
} |
|||
for (const lm_list& l : model.lists) { |
|||
assert(l.mod == lmd.moderator(l.addr)); |
|||
} |
|||
} |
|||
|
|||
void recreate_apply_and_verify_model(ListManagerDummy& lmd, const model_test_lmd& model) |
|||
{ |
|||
try { |
|||
lmd.delete_db(); |
|||
} catch (const exception& e) { |
|||
} |
|||
assert(!file_exists(model.db_path)); |
|||
apply_model(lmd, model); |
|||
verify_model(lmd, model); |
|||
} |
|||
|
|||
model_test_lmd create_default_model() |
|||
{ |
|||
model_test_lmd model; |
|||
model.db_path = "test_lmd.db"; |
|||
model.alice = "alice@peptest.org"; |
|||
model.bob = "bob@peptest.org"; |
|||
model.carol = "carol@peptest.org"; |
|||
model.joe = "joe@peptest.org"; |
|||
|
|||
lm_list l1; |
|||
l1.addr = "list1@peptest.org"; |
|||
l1.mod = model.alice; |
|||
l1.members.push_back(model.bob); |
|||
l1.members.push_back(model.carol); |
|||
|
|||
lm_list l2; |
|||
l2.addr = "list2@peptest.org"; |
|||
l2.mod = model.alice; |
|||
l2.members.push_back(model.bob); |
|||
l2.members.push_back(model.carol); |
|||
l2.members.push_back(model.joe); |
|||
|
|||
lm_list l3; |
|||
l3.addr = "list3@peptest.org"; |
|||
l3.mod = model.bob; |
|||
l3.members.push_back(model.carol); |
|||
l3.members.push_back(model.joe); |
|||
|
|||
model.lists.push_back(l1); |
|||
model.lists.push_back(l2); |
|||
model.lists.push_back(l3); |
|||
return model; |
|||
} |
|||
|
|||
model_test_lmd create_model_bad_path() |
|||
{ |
|||
model_test_lmd model = create_default_model(); |
|||
model.db_path = "/wont_create_dirs/bad.db"; |
|||
return model; |
|||
} |
|||
|
|||
int main(int argc, char* argv[]) |
|||
{ |
|||
// pEpSQLite::log_enabled = true;
|
|||
ListManagerDummy::log_enabled = false; |
|||
|
|||
logH1("Testing SUCCESS conditions"); |
|||
{ |
|||
logH2("Test create new db"); |
|||
model_test_lmd model = create_default_model(); |
|||
ListManagerDummy lmd(model.db_path); |
|||
recreate_apply_and_verify_model(lmd, model); |
|||
} |
|||
{ |
|||
logH2("Test re-open db"); |
|||
model_test_lmd model = create_default_model(); |
|||
assert(file_exists(model.db_path)); |
|||
ListManagerDummy lmd(model.db_path); |
|||
verify_model(lmd, model); |
|||
|
|||
logH2("Test list_delete"); |
|||
lmd.list_delete(model.lists.at(2).addr); |
|||
model.lists.pop_back(); |
|||
verify_model(lmd, model); |
|||
|
|||
logH2("Test auto reopen after close()"); |
|||
lmd.close_db(); |
|||
|
|||
logH2("Test member_remove"); |
|||
lmd.member_remove(model.lists.at(0).addr, model.lists.at(0).members.at(1)); |
|||
model.lists.at(0).members.pop_back(); |
|||
verify_model(lmd, model); |
|||
|
|||
logH2("Test list_exists() - true"); |
|||
assert(lmd.list_exists(model.lists.at(0).addr)); |
|||
|
|||
logH2("Test list_exists() - false"); |
|||
assert(!lmd.list_exists("does_not_exist_for_sure")); |
|||
|
|||
logH2("Test member_exists() - true"); |
|||
assert(lmd.member_exists(model.lists.at(0).addr, model.lists.at(0).members.at(0))); |
|||
|
|||
logH2("Test member_exists() - false"); |
|||
assert(!lmd.member_exists(model.lists.at(0).addr, "does_not_exist_for_sure")); |
|||
|
|||
logH2("Test delete_db"); |
|||
lmd.delete_db(); |
|||
assert(!file_exists(model.db_path)); |
|||
} |
|||
|
|||
logH1("Testing ERROR conditions"); |
|||
{ |
|||
logH2("Testing success on close_db() on model_bad_path"); |
|||
model_test_lmd model = create_model_bad_path(); |
|||
ListManagerDummy lmd(model.db_path); |
|||
lmd.close_db(); |
|||
} |
|||
{ |
|||
logH2("Testing exception on delete_db() on model_bad_path"); |
|||
model_test_lmd model = create_model_bad_path(); |
|||
ListManagerDummy lmd(model.db_path); |
|||
ASSERT_EXCEPT(lmd.delete_db()); |
|||
} |
|||
{ |
|||
logH2("Testing exception on lists() on: on model_bad_path"); |
|||
model_test_lmd model = create_default_model(); |
|||
model.db_path = "/wont_create_dirs/bad.db"; |
|||
ListManagerDummy lmd(model.db_path); |
|||
ASSERT_EXCEPT(lmd.lists()); |
|||
} |
|||
{ |
|||
logH2("Testing list_add() AlreadyExistsException"); |
|||
model_test_lmd model = create_default_model(); |
|||
ListManagerDummy lmd(model.db_path); |
|||
recreate_apply_and_verify_model(lmd, model); |
|||
try { |
|||
lmd.list_add(model.lists.at(0).addr, "any"); |
|||
assert(false); |
|||
} catch (const AlreadyExistsException& e) { |
|||
print_exception(e); |
|||
} catch (...) { |
|||
cout << "NEVER SEEEE" << endl; |
|||
assert(false); |
|||
} |
|||
} |
|||
{ |
|||
logH2("Testing list_delete() DoesNotExistException"); |
|||
model_test_lmd model = create_default_model(); |
|||
ListManagerDummy lmd(model.db_path); |
|||
recreate_apply_and_verify_model(lmd, model); |
|||
try { |
|||
lmd.list_delete("does_not_exist_for_sure"); |
|||
assert(false); |
|||
} catch (const DoesNotExistException& e) { |
|||
print_exception(e); |
|||
} catch (...) { |
|||
assert(false); |
|||
} |
|||
} |
|||
{ |
|||
logH2("Testing member_add() AlreadyExistsException"); |
|||
model_test_lmd model = create_default_model(); |
|||
ListManagerDummy lmd(model.db_path); |
|||
recreate_apply_and_verify_model(lmd, model); |
|||
try { |
|||
lmd.member_add(model.lists.at(0).addr, model.lists.at(0).members.at(0)); |
|||
assert(false); |
|||
} catch (const AlreadyExistsException& e) { |
|||
print_exception(e); |
|||
} catch (...) { |
|||
assert(false); |
|||
} |
|||
} |
|||
{ |
|||
logH2("Testing member_remove() DoesNotExistException"); |
|||
model_test_lmd model = create_default_model(); |
|||
ListManagerDummy lmd(model.db_path); |
|||
recreate_apply_and_verify_model(lmd, model); |
|||
try { |
|||
lmd.member_remove(model.lists.at(0).addr, "does_not_exist_for_sure"); |
|||
assert(false); |
|||
} catch (const DoesNotExistException& e) { |
|||
print_exception(e); |
|||
} catch (...) { |
|||
assert(false); |
|||
} |
|||
} |
|||
{ |
|||
logH2("Testing moderator() DoesNotExistException"); |
|||
model_test_lmd model = create_default_model(); |
|||
ListManagerDummy lmd(model.db_path); |
|||
recreate_apply_and_verify_model(lmd, model); |
|||
try { |
|||
lmd.moderator("does_not_exist_for_sure"); |
|||
assert(false); |
|||
} catch (const DoesNotExistException& e) { |
|||
print_exception(e); |
|||
} catch (...) { |
|||
assert(false); |
|||
} |
|||
} |
|||
{ |
|||
logH2("Testing members() DoesNotExistException"); |
|||
model_test_lmd model = create_default_model(); |
|||
ListManagerDummy lmd(model.db_path); |
|||
recreate_apply_and_verify_model(lmd, model); |
|||
try { |
|||
lmd.members("does_not_exist_for_sure"); |
|||
assert(false); |
|||
} catch (const DoesNotExistException& e) { |
|||
print_exception(e); |
|||
} catch (...) { |
|||
assert(false); |
|||
} |
|||
} |
|||
} |
@ -0,0 +1,162 @@ |
|||
// This file is under GNU General Public License 3.0
|
|||
// see LICENSE.txt
|
|||
|
|||
#include "framework/framework.hh" |
|||
#include "framework/utils.hh" |
|||
|
|||
#include <iostream> |
|||
|
|||
#include "../src/Adapter.hh" |
|||
#include "../src/status_to_string.hh" |
|||
#include "../src/ListManagerDummy.hh" |
|||
|
|||
using namespace std; |
|||
using namespace pEp; |
|||
using namespace pEp::Test::Log; |
|||
|
|||
bool debug_info_full = true; |
|||
::pEp_identity* alice = nullptr; |
|||
::pEp_identity* bob = nullptr; |
|||
::pEp_identity* carol = nullptr; |
|||
::pEp_identity* grp_ident = nullptr; |
|||
::PEP_STATUS status; |
|||
|
|||
ListManagerInterface* lm_backend; |
|||
|
|||
/*
|
|||
* Test Units |
|||
*/ |
|||
|
|||
void test_create_alice_me() |
|||
{ |
|||
logH2("test_create_alice_me"); |
|||
alice = ::new_identity("alice@peptest.ch", NULL, "23", "Alice"); |
|||
assert(alice); |
|||
alice->lang[0] = 'e'; |
|||
alice->lang[1] = 'n'; |
|||
status = ::myself(Adapter::session(), alice); |
|||
cout << "STATUS: " << status_to_string(status) << endl; |
|||
assert(!status); |
|||
cout << "Alice:" << Test::Utils::to_string(alice, debug_info_full) << endl; |
|||
} |
|||
|
|||
void test_create_bob_partner() |
|||
{ |
|||
logH2("test_create_bob_partner"); |
|||
bob = ::new_identity("bob@peptest.ch", NULL, PEP_OWN_USERID, "Bob"); |
|||
assert(bob); |
|||
bob->lang[0] = 'c'; |
|||
bob->lang[1] = 'r'; |
|||
status = ::update_identity(Adapter::session(), bob); |
|||
cout << "STATUS: " << status_to_string(status) << endl; |
|||
assert(!status); |
|||
cout << "Bob:" << Test::Utils::to_string(bob, debug_info_full) << endl; |
|||
} |
|||
|
|||
void test_create_carol_partner() |
|||
{ |
|||
logH2("test_create_carol_partner"); |
|||
carol = ::new_identity("carol@peptest.ch", NULL, PEP_OWN_USERID, "Carol"); |
|||
assert(carol); |
|||
carol->lang[0] = 'f'; |
|||
carol->lang[1] = 'n'; |
|||
status = ::update_identity(Adapter::session(), carol); |
|||
cout << "STATUS: " << status_to_string(status) << endl; |
|||
assert(!status); |
|||
cout << "Carol:" << Test::Utils::to_string(carol, debug_info_full) << endl; |
|||
} |
|||
|
|||
|
|||
void test_group_create(::identity_list* idl) |
|||
{ |
|||
logH2("test_group_create"); |
|||
cout << "IDL: " << Test::Utils::to_string(idl, debug_info_full) << endl; |
|||
|
|||
cout << "create group identity" << endl; |
|||
grp_ident = ::new_identity("group1@peptest.ch", NULL, "432", "group1"); |
|||
assert(grp_ident); |
|||
status = ::myself(Adapter::session(), grp_ident); |
|||
cout << "STATUS: " << status_to_string(status) << endl; |
|||
assert(!status); |
|||
cout << "grp_ident:" << Test::Utils::to_string(grp_ident, debug_info_full) << endl; |
|||
|
|||
lm_backend->create(grp_ident, alice, idl); |
|||
} |
|||
|
|||
void test_group_join(::pEp_identity* ident) |
|||
{ |
|||
logH2("test_group_join"); |
|||
lm_backend->join(grp_ident, ident); |
|||
} |
|||
|
|||
void test_group_remove_member(::pEp_identity* ident) |
|||
{ |
|||
logH2("test_group_remove_member"); |
|||
lm_backend->remove_member(grp_ident, ident); |
|||
} |
|||
|
|||
void test_group_dissolve() |
|||
{ |
|||
logH2("test_group_dissolve"); |
|||
lm_backend->dissolve(grp_ident); |
|||
} |
|||
|
|||
|
|||
/*
|
|||
* Update functions |
|||
* ---------------- |
|||
* Test procedure: |
|||
* 1. Create group |
|||
* - group_create(Alice) |
|||
* 2. Add Bob |
|||
* - group_join(Bob) |
|||
* 3. Add Carol |
|||
* - group_join(Carol) |
|||
* 4. Remove Carol |
|||
* - group_remove_member(Carol) |
|||
* 6. Dissolve |
|||
* - group_dissolve() |
|||
* |
|||
* Query functions |
|||
* --------------- |
|||
* Always test all the query functions for correctness between every step above. |
|||
* group_query_groups() |
|||
* group_query_manager() |
|||
* group_query_members |
|||
*/ |
|||
int main(int argc, char** argv) |
|||
{ |
|||
Test::setup(argc, argv); |
|||
Adapter::pEpLog::set_enabled(true); |
|||
debug_info_full = false; |
|||
|
|||
// Setup Test Context
|
|||
test_create_alice_me(); |
|||
test_create_bob_partner(); |
|||
test_create_carol_partner(); |
|||
|
|||
// Setup list manager backend
|
|||
ListManagerDummy lm_dummy{}; |
|||
lm_backend = &lm_dummy; |
|||
|
|||
logH1("1. Create group"); |
|||
::identity_list* initial_memberlist = nullptr; |
|||
initial_memberlist = new_identity_list(bob); |
|||
::identity_list_add(initial_memberlist, carol); |
|||
test_group_create(initial_memberlist); |
|||
|
|||
logH1("2. Add Bob"); |
|||
test_group_join(bob); // Fails
|
|||
|
|||
logH1("3. Add Carol"); |
|||
test_group_join(carol); |
|||
|
|||
logH1("4. Remove Carol"); |
|||
test_group_remove_member(carol); |
|||
|
|||
logH1("6. Dissolve"); |
|||
test_group_dissolve(); |
|||
|
|||
Adapter::shutdown(); |
|||
return 0; |
|||
} |
@ -0,0 +1,703 @@ |
|||
#include "test_pEpSQLite.hh" |
|||
#include "../src/pEpSQLite.hh" |
|||
#include "../src/pEpLog.hh" |
|||
#include "framework/utils.hh" |
|||
|
|||
#include <fstream> |
|||
|
|||
using namespace std; |
|||
using namespace pEp; |
|||
using namespace pEp::Test; |
|||
using namespace pEp::Test::Log; |
|||
using namespace pEp::Test::Utils; |
|||
|
|||
namespace pEp { |
|||
namespace Test { |
|||
// --------------------------------- FIXTURES ---------------------------------
|
|||
// filenames
|
|||
string fixture_db_filename_new() |
|||
{ |
|||
// pEpLog("called");
|
|||
string path = "new.db"; |
|||
return path; |
|||
} |
|||
|
|||
string fixture_db_filename_bad() |
|||
{ |
|||
// pEpLog("called");
|
|||
string db_path_bad = "/will_not_create_dirs/bad.db"; |
|||
return db_path_bad; |
|||
} |
|||
|
|||
string fixture_db_filename_existing_and_verified() |
|||
{ |
|||
// pEpLog("called");
|
|||
string path = "new.db"; |
|||
return path; |
|||
} |
|||
|
|||
string fixture_db_filename_corrupt() |
|||
{ |
|||
// pEpLog("called");
|
|||
string path = "corrupt.db"; |
|||
return path; |
|||
} |
|||
|
|||
// prepared db's
|
|||
string fixture_init_db_new() |
|||
{ |
|||
// pEpLog("called");
|
|||
string path = fixture_db_filename_new(); |
|||
// cout << "fixture: \"" << path << "\" not existing" << endl;
|
|||
file_ensure_not_existing(path); |
|||
return path; |
|||
} |
|||
|
|||
string fixture_init_db_existing_and_verified() |
|||
{ |
|||
// pEpLog("called");
|
|||
string path = "existing.db"; |
|||
// cout << "fixture: \"" << path << "\" not existing" << endl;
|
|||
file_ensure_not_existing(path); |
|||
return path; |
|||
} |
|||
|
|||
string fixture_init_db_corrupt() |
|||
{ |
|||
// pEpLog("called");
|
|||
// cout << "creating corrupt db" << endl;
|
|||
string path = fixture_db_filename_corrupt(); |
|||
file_ensure_not_existing(path); |
|||
ofstream db_corrupt = file_create(path); |
|||
db_corrupt << "G4rbage" << endl; |
|||
db_corrupt.close(); |
|||
return path; |
|||
} |
|||
|
|||
// instance
|
|||
pEpSQLite fixture_instance_of_new() |
|||
{ |
|||
// pEpLog("called");
|
|||
return test_create_instance_on_new(); |
|||
} |
|||
|
|||
pEpSQLite fixture_instance_of_existing_and_verified() |
|||
{ |
|||
// pEpLog("called");
|
|||
return test_create_instance_on_existing(); |
|||
} |
|||
|
|||
pEpSQLite fixture_instance_of_bad() |
|||
{ |
|||
// pEpLog("called");
|
|||
return test_create_instance_on_path_bad(); |
|||
} |
|||
|
|||
pEpSQLite fixture_instance_of_corrupt() |
|||
{ |
|||
// pEpLog("called");
|
|||
return test_create_instance_on_path_corrupt(); |
|||
} |
|||
|
|||
// open
|
|||
pEpSQLite fixture_db_open_of_new() |
|||
{ |
|||
// pEpLog("called");
|
|||
return test_createopen_db_new(); |
|||
} |
|||
|
|||
pEpSQLite fixture_db_open_of_existing_and_verified() |
|||
{ |
|||
// pEpLog("called");
|
|||
return test_db_verify_content_after_insert_on_tables_exist(); |
|||
} |
|||
|
|||
pEpSQLite fixture_db_open_of_bad() |
|||
{ |
|||
// pEpLog("called");
|
|||
return test_createopen_db_bad(); |
|||
} |
|||
|
|||
pEpSQLite fixture_db_open_of_corrupt() |
|||
{ |
|||
// pEpLog("called");
|
|||
return test_createopen_db_corrupt(); |
|||
} |
|||
|
|||
pEpSQLite fixture_db_open_after_close() |
|||
{ |
|||
// pEpLog("called");
|
|||
return test_close_after_open(); |
|||
} |
|||
|
|||
// tables
|
|||
pEpSQLite fixture_db_open_with_tables_of_new() |
|||
{ |
|||
// pEpLog("called");
|
|||
return test_db_create_tables_on_open_new(); |
|||
} |
|||
|
|||
pEpSQLite fixture_db_open_with_tables_of_corrupt() |
|||
{ |
|||
// pEpLog("called");
|
|||
return test_db_create_tables_on_open_corrupt(); |
|||
} |
|||
|
|||
// content
|
|||
pEpSQLite fixture_db_open_with_tables_and_content() |
|||
{ |
|||
// pEpLog("called");
|
|||
return test_db_insert_on_tables_exist(); |
|||
} |
|||
|
|||
// delete
|
|||
pEpSQLite fixture_db_open_after_delete() |
|||
{ |
|||
// pEpLog("called");
|
|||
return test_delete_file_gone_after_open_existing(); |
|||
} |
|||
|
|||
pEpSQLite fixture_db_open_after_close_after_delete() |
|||
{ |
|||
// pEpLog("called");
|
|||
return test_delete_file_gone_after_close_new(); |
|||
} |
|||
|
|||
// --------------------------------- TESTS ---------------------------------
|
|||
|
|||
// instance creation
|
|||
// OK
|
|||
pEpSQLite test_create_instance_on_new() |
|||
{ |
|||
pEpLog("called"); |
|||
pEpSQLite db(fixture_init_db_new()); |
|||
return db; |
|||
} |
|||
|
|||
// OK
|
|||
pEpSQLite test_create_instance_on_existing() |
|||
{ |
|||
pEpLog("called"); |
|||
pEpSQLite db(fixture_init_db_existing_and_verified()); |
|||
return db; |
|||
} |
|||
|
|||
// OK
|
|||
pEpSQLite test_create_instance_on_path_bad() |
|||
{ |
|||
pEpLog("called"); |
|||
pEpSQLite db(fixture_db_filename_bad()); |
|||
return db; |
|||
} |
|||
|
|||
// OK
|
|||
pEpSQLite test_create_instance_on_path_corrupt() |
|||
{ |
|||
pEpLog("called"); |
|||
pEpSQLite db(fixture_init_db_corrupt()); |
|||
return db; |
|||
} |
|||
|
|||
// db create_open (create_or_open())
|
|||
// OK, new db
|
|||
pEpSQLite test_createopen_db_new() |
|||
{ |
|||
pEpLog("called"); |
|||
pEpSQLite db = fixture_instance_of_new(); |
|||
assert(!file_exists(fixture_db_filename_new())); |
|||
db.create_or_open_db(); |
|||
assert(file_exists(fixture_db_filename_new())); |
|||
return db; |
|||
} |
|||
|
|||
// OK, open db
|
|||
pEpSQLite test_createopen_db_existing() |
|||
{ |
|||
pEpLog("called"); |
|||
pEpSQLite db = fixture_instance_of_existing_and_verified(); |
|||
assert(file_exists(fixture_db_filename_existing_and_verified())); |
|||
db.create_or_open_db(); |
|||
return db; |
|||
} |
|||
|
|||
// ERR, cant create
|
|||
pEpSQLite test_createopen_db_bad() |
|||
{ |
|||
pEpLog("called"); |
|||
assert(!file_exists(fixture_db_filename_bad())); |
|||
pEpSQLite db = fixture_instance_of_bad(); |
|||
assert(!file_exists(fixture_db_filename_bad())); |
|||
try { |
|||
db.create_or_open_db(); |
|||
assert(false); |
|||
} catch (const exception& e) { |
|||
pEp::Test::Utils::print_exception(e); |
|||
} |
|||
assert(!file_exists(fixture_db_filename_bad())); |
|||
return db; |
|||
} |
|||
|
|||
// OK(cant detect corruption)
|
|||
pEpSQLite test_createopen_db_corrupt() |
|||
{ |
|||
pEpLog("called"); |
|||
pEpSQLite db = fixture_instance_of_corrupt(); |
|||
assert(file_exists(fixture_db_filename_corrupt())); |
|||
db.create_or_open_db(); |
|||
assert(file_exists(fixture_db_filename_corrupt())); |
|||
return db; |
|||
} |
|||
|
|||
// close()
|
|||
// OK
|
|||
pEpSQLite test_close_before_open() |
|||
{ |
|||
pEpLog("called"); |
|||
pEpSQLite db = fixture_instance_of_new(); |
|||
db.close_db(); |
|||
return db; |
|||
} |
|||
|
|||
// OK
|
|||
pEpSQLite test_close_after_open() |
|||
{ |
|||
pEpLog("called"); |
|||
pEpSQLite db = fixture_db_open_of_new(); |
|||
db.close_db(); |
|||
return db; |
|||
} |
|||
|
|||
// OK
|
|||
pEpSQLite test_close_idempotent() |
|||
{ |
|||
pEpLog("called"); |
|||
pEpSQLite db = fixture_db_open_of_new(); |
|||
db.close_db(); |
|||
db.close_db(); |
|||
db.close_db(); |
|||
db.close_db(); |
|||
return db; |
|||
} |
|||
|
|||
// create tables (execute())
|
|||
// OK
|
|||
pEpSQLite test_db_create_tables_on_open_new() |
|||
{ |
|||
pEpLog("called"); |
|||
pEpSQLite db = fixture_db_open_of_new(); |
|||
db.execute("CREATE TABLE test(i,i_squared);"); |
|||
return db; |
|||
} |
|||
|
|||
// ERR, Tables already exist
|
|||
pEpSQLite test_db_create_tables_open_existing() |
|||
{ |
|||
pEpLog("called"); |
|||
pEpSQLite db = fixture_db_open_of_existing_and_verified(); |
|||
try { |
|||
db.execute("CREATE TABLE test(i,i_squared);"); |
|||
assert(false); |
|||
} catch (const exception& e) { |
|||
pEp::Test::Utils::print_exception(e); |
|||
} |
|||
return db; |
|||
} |
|||
|
|||
// ERR, db closed
|
|||
pEpSQLite test_db_create_tables_on_open_bad() |
|||
{ |
|||
pEpLog("called"); |
|||
pEpSQLite db = fixture_db_open_of_bad(); |
|||
try { |
|||
db.execute("CREATE TABLE test(i,i_squared);"); |
|||
assert(false); |
|||
} catch (const exception& e) { |
|||
pEp::Test::Utils::print_exception(e); |
|||
} |
|||
return db; |
|||
} |
|||
|
|||
// ERR, db corrupt
|
|||
pEpSQLite test_db_create_tables_on_open_corrupt() |
|||
{ |
|||
pEpLog("called"); |
|||
pEpSQLite db = fixture_db_open_of_corrupt(); |
|||
try { |
|||
db.execute("CREATE TABLE test(i,i_squared);"); |
|||
assert(false); |
|||
} catch (const exception& e) { |
|||
pEp::Test::Utils::print_exception(e); |
|||
} |
|||
return db; |
|||
} |
|||
|
|||
|
|||
// insert (execute())
|
|||
void insert_operation(pEpSQLite& db) |
|||
{ |
|||
pEpLog("called"); |
|||
for (int i = 0; i < 9; i = (i + 2)) { |
|||
db.execute( |
|||
"INSERT INTO test(i,i_squared) VALUES ('" + to_string(i) + "', '" + |
|||
to_string(i * i) + "');"); |
|||
} |
|||
} |
|||
|
|||
// OK
|
|||
pEpSQLite test_db_insert_on_tables_exist() |
|||
{ |
|||
pEpLog("called"); |
|||
pEpSQLite db = fixture_db_open_with_tables_of_new(); |
|||
insert_operation(db); |
|||
return db; |
|||
} |
|||
|
|||
// ERR, Tables missing
|
|||
pEpSQLite test_db_insert_on_tables_dont_exist() |
|||
{ |
|||
pEpSQLite db = fixture_db_open_of_new(); |
|||
try { |
|||
insert_operation(db); |
|||
assert(false); |
|||
} catch (const exception& e) { |
|||
pEp::Test::Utils::print_exception(e); |
|||
} |
|||
return db; |
|||
} |
|||
|
|||
// ERR, Tables missing
|
|||
pEpSQLite test_db_insert_before_open() |
|||
{ |
|||
pEpLog("called"); |
|||
pEpSQLite db = fixture_instance_of_new(); |
|||
try { |
|||
insert_operation(db); |
|||
assert(false); |
|||
} catch (const exception& e) { |
|||
pEp::Test::Utils::print_exception(e); |
|||
} |
|||
return db; |
|||
} |
|||
|
|||
// ERR, Tables missing
|
|||
pEpSQLite test_db_insert_after_close() |
|||
{ |
|||
pEpLog("called"); |
|||
pEpSQLite db = fixture_db_open_after_close(); |
|||
try { |
|||
insert_operation(db); |
|||
assert(false); |
|||
} catch (const exception& e) { |
|||
pEp::Test::Utils::print_exception(e); |
|||
} |
|||
return db; |
|||
} |
|||
|
|||
// verify contents (execute())
|
|||
void verify_operation(pEpSQLite& db) |
|||
{ |
|||
pEpLog("called"); |
|||
for (int i = 0; i < 9; i++) { |
|||
ResultSet rs = db.execute( |
|||
"SELECT i, i_squared FROM test " |
|||
"WHERE (test.i == '" + |
|||
to_string(i) + "');"); |
|||
// cout << "RESULT: " << endl << pEpSQLite::to_string(rs) << endl;
|
|||
if (i % 2) { |
|||
if (!rs.empty()) { |
|||
runtime_error e{ "Exception verifying database content" }; |
|||
throw(e); |
|||
} |
|||
} else { |
|||
if(rs.size() != 1) { |
|||
runtime_error e{ "Exception verifying database content" }; |
|||
throw(e); |
|||
} |
|||
for (const RSRecord& r : rs) { |
|||
const int x = stoi(r.at("i")); |
|||
const int x_squared = stoi(r.at("i_squared")); |
|||
if((x * x) != x_squared) { |
|||
runtime_error e{ "Exception verifying database content" }; |
|||
throw(e); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
|
|||
// OK
|
|||
pEpSQLite test_db_verify_content_existing_open_db() |
|||
{ |
|||
pEpLog("called"); |
|||
pEpSQLite db = fixture_db_open_of_existing_and_verified(); |
|||
verify_operation(db); |
|||
return db; |
|||
} |
|||
|
|||
// OK
|
|||
pEpSQLite test_db_verify_content_after_insert_on_tables_exist() |
|||
{ |
|||
pEpLog("called"); |
|||
pEpSQLite db = fixture_db_open_with_tables_and_content(); |
|||
verify_operation(db); |
|||
return db; |
|||
} |
|||
|
|||
// ERR - no tables
|
|||
pEpSQLite test_db_verify_content_no_tables() |
|||
{ |
|||
pEpLog("called"); |
|||
pEpSQLite db = fixture_db_open_of_new(); |
|||
try { |
|||
verify_operation(db); |
|||
assert(false); |
|||
} catch (const exception& e) { |
|||
pEp::Test::Utils::print_exception(e); |
|||
} |
|||
return db; |
|||
} |
|||
|
|||
// ERR - err no data
|
|||
pEpSQLite test_db_verify_content_after_create_tables() |
|||
{ |
|||
pEpLog("called"); |
|||
pEpSQLite db = fixture_db_open_with_tables_of_new(); |
|||
try { |
|||
verify_operation(db); |
|||
assert(false); |
|||
} catch (const exception& e) { |
|||
pEp::Test::Utils::print_exception(e); |
|||
} |
|||
return db; |
|||
} |
|||
|
|||
|
|||
// get_path()
|
|||
// OK
|
|||
pEpSQLite test_get_path_on_instance_good() |
|||
{ |
|||
pEpLog("called"); |
|||
pEpSQLite db = fixture_instance_of_new(); |
|||
assert(db.get_db_path() == fixture_db_filename_new()); |
|||
return db; |
|||
} |
|||
|
|||
// OK
|
|||
pEpSQLite test_get_path_on_instance_bad() |
|||
{ |
|||
pEpLog("called"); |
|||
pEpSQLite db = fixture_instance_of_bad(); |
|||
assert(db.get_db_path() == fixture_db_filename_bad()); |
|||
return db; |
|||
} |
|||
|
|||
// delete_db()
|
|||
// ERR, file not found
|
|||
pEpSQLite test_delete_file_gone_before_open_new() |
|||
{ |
|||
pEpLog("called"); |
|||
pEpSQLite db = fixture_instance_of_new(); |
|||
try { |
|||
db.delete_db(); |
|||
assert(false); |
|||
} catch (const exception& e) { |
|||
pEp::Test::Utils::print_exception(e); |
|||
} |
|||
assert(!file_exists(fixture_db_filename_new())); |
|||
return db; |
|||
} |
|||
|
|||
// ERR, file not found
|
|||
pEpSQLite test_delete_file_gone_before_open_existing() |
|||
{ |
|||
pEpLog("called"); |
|||
pEpSQLite db = fixture_instance_of_existing_and_verified(); |
|||
try { |
|||
db.delete_db(); |
|||
assert(false); |
|||
} catch (const exception& e) { |
|||
pEp::Test::Utils::print_exception(e); |
|||
} |
|||
assert(!file_exists(fixture_db_filename_existing_and_verified())); |
|||
return db; |
|||
} |
|||
|
|||
// OK
|
|||
pEpSQLite test_delete_file_gone_after_close_new() |
|||
{ |
|||
pEpLog("called"); |
|||
pEpSQLite db = fixture_db_open_after_close(); |
|||
db.delete_db(); |
|||
assert(!file_exists(fixture_db_filename_new())); |
|||
return db; |
|||
} |
|||
|
|||
// OK
|
|||
pEpSQLite test_delete_file_gone_after_open_existing() |
|||
{ |
|||
pEpLog("called"); |
|||
pEpSQLite db = fixture_db_open_of_existing_and_verified(); |
|||
db.delete_db(); |
|||
assert(!file_exists(fixture_db_filename_existing_and_verified())); |
|||
return db; |
|||
} |
|||
|
|||
// OK
|
|||
pEpSQLite test_delete_file_gone_after_open_corrupt() |
|||
{ |
|||
pEpLog("called"); |
|||
pEpSQLite db = fixture_db_open_of_corrupt(); |
|||
db.delete_db(); |
|||
assert(!file_exists(fixture_db_filename_corrupt())); |
|||
return db; |
|||
} |
|||
|
|||
// ERR
|
|||
pEpSQLite test_delete_file_gone_after_open_bad() |
|||
{ |
|||
pEpLog("called"); |
|||
pEpSQLite db = fixture_db_open_of_bad(); |
|||
try { |
|||
db.delete_db(); |
|||
assert(false); |
|||
} catch (const exception& e) { |
|||
pEp::Test::Utils::print_exception(e); |
|||
} |
|||
assert(!file_exists(fixture_db_filename_bad())); |
|||
return db; |
|||
} |
|||
|
|||
// is_open()
|
|||
// false
|
|||
pEpSQLite test_is_open_before_open_new() |
|||
{ |
|||
pEpLog("called"); |
|||
pEpSQLite db = fixture_instance_of_new(); |
|||
assert(!db.is_open()); |
|||
return db; |
|||
} |
|||
|
|||
// true
|
|||
pEpSQLite test_is_open_after_open_new() |
|||
{ |
|||
pEpLog("called"); |
|||
pEpSQLite db = fixture_db_open_of_new(); |
|||
assert(db.is_open()); |
|||
return db; |
|||
} |
|||
|
|||
// true
|
|||
pEpSQLite test_is_open_after_open_existing() |
|||
{ |
|||
pEpLog("called"); |
|||
pEpSQLite db = fixture_db_open_of_existing_and_verified(); |
|||
assert(db.is_open()); |
|||
return db; |
|||
} |
|||
|
|||
// false
|
|||
pEpSQLite test_is_open_after_open_bad() |
|||
{ |
|||
pEpLog("called"); |
|||
pEpSQLite db = fixture_db_open_of_bad(); |
|||
assert(!db.is_open()); |
|||
return db; |
|||
} |
|||
|
|||
// true (cant detect corruption)
|
|||
pEpSQLite test_is_open_after_open_corrupt() |
|||
{ |
|||
pEpLog("called"); |
|||
pEpSQLite db = fixture_db_open_of_corrupt(); |
|||
assert(db.is_open()); |
|||
return db; |
|||
} |
|||
|
|||
// false
|
|||
pEpSQLite test_is_open_after_close() |
|||
{ |
|||
pEpLog("called"); |
|||
pEpSQLite db = fixture_db_open_after_close(); |
|||
assert(!db.is_open()); |
|||
return db; |
|||
} |
|||
|
|||
// false
|
|||
pEpSQLite test_is_open_after_delete_on_open() |
|||
{ |
|||
pEpLog("called"); |
|||
pEpSQLite db = fixture_db_open_after_delete(); |
|||
assert(!db.is_open()); |
|||
return db; |
|||
} |
|||
|
|||
// false
|
|||
pEpSQLite test_is_open_after_delete_on_closed() |
|||
{ |
|||
pEpLog("called"); |
|||
pEpSQLite db = fixture_db_open_after_close_after_delete(); |
|||
assert(!db.is_open()); |
|||
return db; |
|||
} |
|||
} // namespace Test
|
|||
} // namespace pEp
|
|||
|
|||
int main(int argc, char* argv[]) |
|||
{ |
|||
// Enable logging for all instances of pEpSQLite
|
|||
pEpSQLite::log_enabled = true; |
|||
Adapter::pEpLog::set_enabled(true); |
|||
// instance creation
|
|||
test_create_instance_on_new(); |
|||
test_create_instance_on_existing(); |
|||
test_create_instance_on_path_bad(); |
|||
test_create_instance_on_path_corrupt(); |
|||
// db create_open (create_or_open())
|
|||
test_createopen_db_new(); |
|||
test_createopen_db_existing(); |
|||
test_createopen_db_bad(); |
|||
test_createopen_db_corrupt(); |
|||
// close()
|
|||
test_close_before_open(); |
|||
test_close_after_open(); |
|||
test_close_idempotent(); |
|||
// create tables (execute())
|
|||
test_db_create_tables_on_open_new(); |
|||
test_db_create_tables_open_existing(); |
|||
test_db_create_tables_on_open_bad(); |
|||
test_db_create_tables_on_open_corrupt(); |
|||
// insert (execute())
|
|||
test_db_insert_on_tables_exist(); |
|||
test_db_insert_on_tables_dont_exist(); |
|||
test_db_insert_before_open(); |
|||
test_db_insert_after_close(); |
|||
// verify contents (execute())
|
|||
test_db_verify_content_existing_open_db(); |
|||
test_db_verify_content_after_insert_on_tables_exist(); |
|||
test_db_verify_content_no_tables(); |
|||
test_db_verify_content_after_create_tables(); |
|||
// get_path()
|
|||
test_get_path_on_instance_good(); |
|||
test_get_path_on_instance_bad(); |
|||
// delete_db()
|
|||
test_delete_file_gone_before_open_new(); |
|||
test_delete_file_gone_before_open_existing(); |
|||
test_delete_file_gone_after_close_new(); |
|||
test_delete_file_gone_after_open_existing(); |
|||
test_delete_file_gone_after_open_corrupt(); |
|||
test_delete_file_gone_after_open_bad(); |
|||
// is_open()
|
|||
test_is_open_before_open_new(); |
|||
test_is_open_after_open_new(); |
|||
test_is_open_after_open_existing(); |
|||
test_is_open_after_open_bad(); |
|||
test_is_open_after_open_corrupt(); |
|||
test_is_open_after_close(); |
|||
test_is_open_after_delete_on_open(); |
|||
test_is_open_after_delete_on_closed(); |
|||
|
|||
file_ensure_not_existing(fixture_db_filename_new()); |
|||
file_ensure_not_existing(fixture_db_filename_corrupt()); |
|||
file_ensure_not_existing(fixture_db_filename_existing_and_verified()); |
|||
return 0; |
|||
} |
@ -0,0 +1,115 @@ |
|||
// This file is under GNU General Public License 3.0
|
|||
// see LICENSE.txt
|
|||
|
|||
#ifndef LIBPEPADAPTER_TEST_PEPSQLITE_HH |
|||
#define LIBPEPADAPTER_TEST_PEPSQLITE_HH |
|||
|
|||
#include <string> |
|||
#include "../src/pEpSQLite.hh" |
|||
|
|||
// ATTENTION ATTENTION ATTENTION ATTENTION ATTENTION ATTENTION ATTENTION
|
|||
//
|
|||
// THIS IS TERRIBLE, JUST TERRIBLE, THIS IS A ANTI-PATTERN
|
|||
// Thats the single most stupid way of writing unit test ever!!!
|
|||
// DONT EVER DO THIS!
|
|||
//
|
|||
// The idea is as follows:
|
|||
// * Tests start simple and become increasingly complex
|
|||
// * There are fixtures and tests, as usual
|
|||
// * You start with basic fixtures to write the first test
|
|||
// * A test becomes a fixture, if the operation is needed for another test
|
|||
// * You systematically cover all the states possible in which a test can be executed
|
|||
//
|
|||
// THATS JUST TERRIBLE!!!
|
|||
// I WILL NEVER DO THAT AGAIN!
|
|||
//
|
|||
// ATTENTION ATTENTION ATTENTION ATTENTION ATTENTION ATTENTION ATTENTION
|
|||
|
|||
namespace pEp { |
|||
namespace Test { |
|||
// FIXTURES
|
|||
// --------
|
|||
// filenames
|
|||
std::string fixture_db_filename_new(); |
|||
std::string fixture_db_filename_existing_and_verified(); |
|||
std::string fixture_db_filename_bad(); |
|||
std::string fixture_db_filename_corrupt(); |
|||
// prepared db's
|
|||
std::string fixture_init_db_new(); |
|||
std::string fixture_init_db_existing_and_verified(); |
|||
std::string fixture_init_db_corrupt(); |
|||
// instance
|
|||
pEpSQLite fixture_instance_of_new(); |
|||
pEpSQLite fixture_instance_of_existing_and_verified(); |
|||
pEpSQLite fixture_instance_of_bad(); |
|||
pEpSQLite fixture_instance_of_corrupt(); |
|||
// open
|
|||
pEpSQLite fixture_db_open_of_new(); |
|||
pEpSQLite fixture_db_open_of_existing_and_verified(); |
|||
pEpSQLite fixture_db_open_of_bad(); |
|||
pEpSQLite fixture_db_open_of_corrupt(); |
|||
pEpSQLite fixture_db_open_after_close(); |
|||
// tables
|
|||
pEpSQLite fixture_db_open_with_tables_of_new(); |
|||
// content
|
|||
pEpSQLite fixture_db_open_with_tables_and_content(); |
|||
// delete
|
|||
pEpSQLite fixture_db_open_after_delete(); |
|||
pEpSQLite fixture_db_open_after_close_after_delete(); |
|||
|
|||
|
|||
// TESTS
|
|||
// -----
|
|||
// instance creation
|
|||
pEpSQLite test_create_instance_on_new(); // OK
|
|||
pEpSQLite test_create_instance_on_existing(); // OK
|
|||
pEpSQLite test_create_instance_on_path_bad(); // OK
|
|||
pEpSQLite test_create_instance_on_path_corrupt(); // OK
|
|||
// db create_open (create_or_open())
|
|||
pEpSQLite test_createopen_db_new(); // OK, new db
|
|||
pEpSQLite test_createopen_db_existing(); // OK, open db
|
|||
pEpSQLite test_createopen_db_bad(); // ERR, cant create
|
|||
pEpSQLite test_createopen_db_corrupt(); // OK (cant detect corruption)
|
|||
// close()
|
|||
pEpSQLite test_close_before_open(); // OK
|
|||
pEpSQLite test_close_after_open(); // OK
|
|||
pEpSQLite test_close_idempotent(); // OK
|
|||
// create tables (execute())
|
|||
pEpSQLite test_db_create_tables_on_open_new(); // OK
|
|||
pEpSQLite test_db_create_tables_open_existing(); // ERR, Tables already exist
|
|||
pEpSQLite test_db_create_tables_on_open_bad(); // ERR, db closed
|
|||
pEpSQLite test_db_create_tables_on_open_corrupt(); // ERR, db corrupt
|
|||
// insert (execute())
|
|||
pEpSQLite test_db_insert_on_tables_exist(); // OK
|
|||
pEpSQLite test_db_insert_on_tables_dont_exist(); // ERR, Tables missing
|
|||
pEpSQLite test_db_insert_before_open(); // ERR, Tables missing
|
|||
pEpSQLite test_db_insert_after_close(); // ERR, Tables missing
|
|||
// verify contents (execute())
|
|||
pEpSQLite test_db_verify_content_existing_open_db(); // OK
|
|||
pEpSQLite test_db_verify_content_after_insert_on_tables_exist(); // OK
|
|||
pEpSQLite test_db_verify_content_no_tables(); // ERR - no tables
|
|||
pEpSQLite test_db_verify_content_after_create_tables(); // ERR - err no data
|
|||
// get_path()
|
|||
pEpSQLite test_get_path_on_instance_good(); // OK
|
|||
pEpSQLite test_get_path_on_instance_bad(); // OK
|
|||
// delete_db()
|
|||
pEpSQLite test_delete_file_gone_before_open_new(); // OK?
|
|||
pEpSQLite test_delete_file_gone_before_open_existing(); // OK
|
|||
pEpSQLite test_delete_file_gone_after_close_new(); // OK
|
|||
pEpSQLite test_delete_file_gone_after_open_existing(); // OK
|
|||
pEpSQLite test_delete_file_gone_after_open_corrupt(); // OK
|
|||
pEpSQLite test_delete_file_gone_after_open_bad(); // ERR
|
|||
// is_open()
|
|||
pEpSQLite test_is_open_before_open_new(); // false
|
|||
pEpSQLite test_is_open_after_open_new(); // true
|
|||
pEpSQLite test_is_open_after_open_existing(); // true
|
|||
pEpSQLite test_is_open_after_open_bad(); // false
|
|||
pEpSQLite test_is_open_after_open_corrupt(); // true (cant detect corruption)
|
|||
pEpSQLite test_is_open_after_close(); // false
|
|||
pEpSQLite test_is_open_after_delete_on_open(); // false
|
|||
pEpSQLite test_is_open_after_delete_on_closed(); // false
|
|||
|
|||
} // namespace Test
|
|||
} // end of namespace pEp
|
|||
|
|||
#endif // LIBPEPADAPTER_TEST_PEPSQLITE_HH
|
Loading…
Reference in new issue