Fix and improve read-header unit tests, as well as backup tests

This commit is contained in:
Sébastien Rombauts 2020-01-04 19:10:23 +01:00
parent 55de873f66
commit ddb4929ddb
2 changed files with 104 additions and 77 deletions

View File

@ -24,14 +24,16 @@
TEST(Backup, initException) TEST(Backup, initException)
{ {
remove("backup_test.db3"); remove("backup_test.db3");
SQLite::Database srcDB("backup_test.db3", SQLite::OPEN_READWRITE|SQLite::OPEN_CREATE); {
srcDB.exec("CREATE TABLE backup_test (id INTEGER PRIMARY KEY, value TEXT)"); SQLite::Database srcDB("backup_test.db3", SQLite::OPEN_READWRITE|SQLite::OPEN_CREATE);
ASSERT_EQ(1, srcDB.exec("INSERT INTO backup_test VALUES (1, \"first\")")); srcDB.exec("CREATE TABLE backup_test (id INTEGER PRIMARY KEY, value TEXT)");
ASSERT_EQ(1, srcDB.exec("INSERT INTO backup_test VALUES (2, \"second\")")); ASSERT_EQ(1, srcDB.exec("INSERT INTO backup_test VALUES (1, \"first\")"));
EXPECT_THROW(SQLite::Backup backup(srcDB, srcDB), SQLite::Exception); ASSERT_EQ(1, srcDB.exec("INSERT INTO backup_test VALUES (2, \"second\")"));
EXPECT_THROW(SQLite::Backup backup(srcDB, "main", srcDB, "main"), SQLite::Exception); EXPECT_THROW(SQLite::Backup backup(srcDB, srcDB), SQLite::Exception);
const std::string name("main"); EXPECT_THROW(SQLite::Backup backup(srcDB, "main", srcDB, "main"), SQLite::Exception);
EXPECT_THROW(SQLite::Backup backup(srcDB, name, srcDB, name), SQLite::Exception); const std::string name("main");
EXPECT_THROW(SQLite::Backup backup(srcDB, name, srcDB, name), SQLite::Exception);
}
remove("backup_test.db3"); remove("backup_test.db3");
} }
@ -39,31 +41,33 @@ TEST(Backup, executeStepOne)
{ {
remove("backup_test.db3"); remove("backup_test.db3");
remove("backup_test.db3.backup"); remove("backup_test.db3.backup");
SQLite::Database srcDB("backup_test.db3", SQLite::OPEN_READWRITE|SQLite::OPEN_CREATE); {
srcDB.exec("CREATE TABLE backup_test (id INTEGER PRIMARY KEY, value TEXT)"); SQLite::Database srcDB("backup_test.db3", SQLite::OPEN_READWRITE|SQLite::OPEN_CREATE);
ASSERT_EQ(1, srcDB.exec("INSERT INTO backup_test VALUES (1, \"first\")")); srcDB.exec("CREATE TABLE backup_test (id INTEGER PRIMARY KEY, value TEXT)");
ASSERT_EQ(1, srcDB.exec("INSERT INTO backup_test VALUES (2, \"second\")")); ASSERT_EQ(1, srcDB.exec("INSERT INTO backup_test VALUES (1, \"first\")"));
ASSERT_EQ(1, srcDB.exec("INSERT INTO backup_test VALUES (2, \"second\")"));
SQLite::Database destDB("backup_test.db3.backup", SQLite::OPEN_READWRITE|SQLite::OPEN_CREATE); SQLite::Database destDB("backup_test.db3.backup", SQLite::OPEN_READWRITE|SQLite::OPEN_CREATE);
SQLite::Backup backup(destDB, "main", srcDB, "main"); SQLite::Backup backup(destDB, "main", srcDB, "main");
int res = backup.executeStep(1); // backup only one page at a time int res = backup.executeStep(1); // backup only one page at a time
ASSERT_EQ(SQLite::OK, res); ASSERT_EQ(SQLite::OK, res);
const int total = backup.getTotalPageCount(); const int total = backup.getTotalPageCount();
ASSERT_EQ(2, total); ASSERT_EQ(2, total);
int remaining = backup.getRemainingPageCount(); int remaining = backup.getRemainingPageCount();
ASSERT_EQ(1, remaining); ASSERT_EQ(1, remaining);
res = backup.executeStep(1); // backup the second and last page res = backup.executeStep(1); // backup the second and last page
ASSERT_EQ(SQLITE_DONE, res); ASSERT_EQ(SQLITE_DONE, res);
remaining = backup.getRemainingPageCount(); remaining = backup.getRemainingPageCount();
ASSERT_EQ(0, remaining); ASSERT_EQ(0, remaining);
SQLite::Statement query(destDB, "SELECT * FROM backup_test ORDER BY id ASC"); SQLite::Statement query(destDB, "SELECT * FROM backup_test ORDER BY id ASC");
ASSERT_TRUE(query.executeStep()); ASSERT_TRUE(query.executeStep());
EXPECT_EQ(1, query.getColumn(0).getInt()); EXPECT_EQ(1, query.getColumn(0).getInt());
EXPECT_STREQ("first", query.getColumn(1)); EXPECT_STREQ("first", query.getColumn(1));
ASSERT_TRUE(query.executeStep()); ASSERT_TRUE(query.executeStep());
EXPECT_EQ(2, query.getColumn(0).getInt()); EXPECT_EQ(2, query.getColumn(0).getInt());
EXPECT_STREQ("second", query.getColumn(1)); EXPECT_STREQ("second", query.getColumn(1));
}
remove("backup_test.db3"); remove("backup_test.db3");
remove("backup_test.db3.backup"); remove("backup_test.db3.backup");
} }
@ -72,27 +76,29 @@ TEST(Backup, executeStepAll)
{ {
remove("backup_test.db3"); remove("backup_test.db3");
remove("backup_test.db3.backup"); remove("backup_test.db3.backup");
SQLite::Database srcDB("backup_test.db3", SQLite::OPEN_READWRITE|SQLite::OPEN_CREATE); {
srcDB.exec("CREATE TABLE backup_test (id INTEGER PRIMARY KEY, value TEXT)"); SQLite::Database srcDB("backup_test.db3", SQLite::OPEN_READWRITE|SQLite::OPEN_CREATE);
ASSERT_EQ(1, srcDB.exec("INSERT INTO backup_test VALUES (1, \"first\")")); srcDB.exec("CREATE TABLE backup_test (id INTEGER PRIMARY KEY, value TEXT)");
ASSERT_EQ(1, srcDB.exec("INSERT INTO backup_test VALUES (2, \"second\")")); ASSERT_EQ(1, srcDB.exec("INSERT INTO backup_test VALUES (1, \"first\")"));
ASSERT_EQ(1, srcDB.exec("INSERT INTO backup_test VALUES (2, \"second\")"));
SQLite::Database destDB("backup_test.db3.backup", SQLite::OPEN_READWRITE|SQLite::OPEN_CREATE); SQLite::Database destDB("backup_test.db3.backup", SQLite::OPEN_READWRITE|SQLite::OPEN_CREATE);
SQLite::Backup backup(destDB, srcDB); SQLite::Backup backup(destDB, srcDB);
const int res = backup.executeStep(); // uses default argument "-1" => execute all steps at once const int res = backup.executeStep(); // uses default argument "-1" => execute all steps at once
ASSERT_EQ(res, SQLITE_DONE); ASSERT_EQ(res, SQLITE_DONE);
const int total = backup.getTotalPageCount(); const int total = backup.getTotalPageCount();
ASSERT_EQ(2, total); ASSERT_EQ(2, total);
const int remaining = backup.getRemainingPageCount(); const int remaining = backup.getRemainingPageCount();
ASSERT_EQ(0, remaining); ASSERT_EQ(0, remaining);
SQLite::Statement query(destDB, "SELECT * FROM backup_test ORDER BY id ASC"); SQLite::Statement query(destDB, "SELECT * FROM backup_test ORDER BY id ASC");
ASSERT_TRUE(query.executeStep()); ASSERT_TRUE(query.executeStep());
EXPECT_EQ(1, query.getColumn(0).getInt()); EXPECT_EQ(1, query.getColumn(0).getInt());
EXPECT_STREQ("first", query.getColumn(1)); EXPECT_STREQ("first", query.getColumn(1));
ASSERT_TRUE(query.executeStep()); ASSERT_TRUE(query.executeStep());
EXPECT_EQ(2, query.getColumn(0).getInt()); EXPECT_EQ(2, query.getColumn(0).getInt());
EXPECT_STREQ("second", query.getColumn(1)); EXPECT_STREQ("second", query.getColumn(1));
}
remove("backup_test.db3"); remove("backup_test.db3");
remove("backup_test.db3.backup"); remove("backup_test.db3.backup");
} }
@ -101,18 +107,20 @@ TEST(Backup, executeStepException)
{ {
remove("backup_test.db3"); remove("backup_test.db3");
remove("backup_test.db3.backup"); remove("backup_test.db3.backup");
SQLite::Database srcDB("backup_test.db3", SQLite::OPEN_READWRITE|SQLite::OPEN_CREATE);
srcDB.exec("CREATE TABLE backup_test (id INTEGER PRIMARY KEY, value TEXT)");
ASSERT_EQ(1, srcDB.exec("INSERT INTO backup_test VALUES (1, \"first\")"));
ASSERT_EQ(1, srcDB.exec("INSERT INTO backup_test VALUES (2, \"second\")"));
{ {
SQLite::Database destDB("backup_test.db3.backup", SQLite::OPEN_READWRITE|SQLite::OPEN_CREATE); SQLite::Database srcDB("backup_test.db3", SQLite::OPEN_READWRITE|SQLite::OPEN_CREATE);
(void)destDB; srcDB.exec("CREATE TABLE backup_test (id INTEGER PRIMARY KEY, value TEXT)");
} ASSERT_EQ(1, srcDB.exec("INSERT INTO backup_test VALUES (1, \"first\")"));
{ ASSERT_EQ(1, srcDB.exec("INSERT INTO backup_test VALUES (2, \"second\")"));
SQLite::Database destDB("backup_test.db3.backup", SQLite::OPEN_READONLY); {
SQLite::Backup backup(destDB, srcDB); SQLite::Database destDB("backup_test.db3.backup", SQLite::OPEN_READWRITE|SQLite::OPEN_CREATE);
EXPECT_THROW(backup.executeStep(), SQLite::Exception); (void)destDB;
}
{
SQLite::Database destDB("backup_test.db3.backup", SQLite::OPEN_READONLY);
SQLite::Backup backup(destDB, srcDB);
EXPECT_THROW(backup.executeStep(), SQLite::Exception);
}
} }
remove("backup_test.db3"); remove("backup_test.db3");
remove("backup_test.db3.backup"); remove("backup_test.db3.backup");

View File

@ -140,15 +140,16 @@ TEST(Database, backup)
EXPECT_TRUE(db.tableExists("test")); EXPECT_TRUE(db.tableExists("test"));
// Export the data into a file // Export the data into a file
remove("backup"); remove("backup.db3");
EXPECT_NO_THROW(db.backup("backup", SQLite::Database::Save)); EXPECT_NO_THROW(db.backup("backup.db3", SQLite::Database::Save));
// Trash the table // Trash the table
db.exec("DROP TABLE test;"); db.exec("DROP TABLE test;");
EXPECT_FALSE(db.tableExists("test")); EXPECT_FALSE(db.tableExists("test"));
// Import the data back from the file // Import the data back from the file
EXPECT_NO_THROW(db.backup("backup", SQLite::Database::Load)); EXPECT_NO_THROW(db.backup("backup.db3", SQLite::Database::Load));
remove("backup.db3");
EXPECT_TRUE(db.tableExists("test")); EXPECT_TRUE(db.tableExists("test"));
} }
@ -359,28 +360,46 @@ TEST(Database, getHeaderInfo)
{ {
remove("test.db3"); remove("test.db3");
{ {
//Call without passing a database file name // Call without passing a database file name
EXPECT_THROW(SQLite::Database::getHeaderInfo(""),SQLite::Exception); EXPECT_THROW(SQLite::Database::getHeaderInfo(""),SQLite::Exception);
//Call with a non existant database // Call with a non-existent database
EXPECT_THROW(SQLite::Database::getHeaderInfo("test.db3"), SQLite::Exception); EXPECT_THROW(SQLite::Database::getHeaderInfo("test.db3"), SQLite::Exception);
//Simulate a corrupt header by writing garbage to a file // Simulate an incomplete header by writing garbage to a file
unsigned char badData[100]; {
char* pBadData = reinterpret_cast<char*>(&badData[0]); const unsigned char badData[] = "garbage...";
const char* pBadData = reinterpret_cast<const char*>(&badData[0]);
std::ofstream corruptDb; remove("short.db3");
corruptDb.open("corrupt.db3", std::ios::app | std::ios::binary); std::ofstream corruptDb;
corruptDb.write(pBadData, 100); corruptDb.open("short.db3", std::ios::app | std::ios::binary);
corruptDb.write(pBadData, sizeof(badData));
corruptDb.close();
EXPECT_THROW(SQLite::Database::getHeaderInfo("corrupt.db3"), SQLite::Exception); EXPECT_THROW(SQLite::Database::getHeaderInfo("short.db3"), SQLite::Exception);
remove("short.db3");
remove("corrupt.db3"); }
// Simulate a corrupt header by writing garbage to a file
{
const unsigned char badData[100] = "garbage...";
const char* pBadData = reinterpret_cast<const char*>(&badData[0]);
remove("corrupt.db3");
std::ofstream corruptDb;
corruptDb.open("corrupt.db3", std::ios::app | std::ios::binary);
corruptDb.write(pBadData, sizeof(badData));
corruptDb.close();
EXPECT_THROW(SQLite::Database::getHeaderInfo("corrupt.db3"), SQLite::Exception);
remove("corrupt.db3");
}
// Create a new database // Create a new database
SQLite::Database db("test.db3", SQLite::OPEN_READWRITE | SQLite::OPEN_CREATE); SQLite::Database db("test.db3", SQLite::OPEN_READWRITE | SQLite::OPEN_CREATE);
db.exec("CREATE TABLE test (id INTEGER PRIMARY KEY, value TEXT)"); db.exec("CREATE TABLE test (id INTEGER PRIMARY KEY, value TEXT)");
// Set assorted SQLite header values using associated PRAGMA // Set assorted SQLite header values using associated PRAGMA
db.exec("PRAGMA main.user_version = 12345"); db.exec("PRAGMA main.user_version = 12345");
db.exec("PRAGMA main.application_id = 2468"); db.exec("PRAGMA main.application_id = 2468");
@ -388,7 +407,7 @@ TEST(Database, getHeaderInfo)
// Parse header fields from test database // Parse header fields from test database
SQLite::Header h = SQLite::Database::getHeaderInfo("test.db3"); SQLite::Header h = SQLite::Database::getHeaderInfo("test.db3");
//Test header values expliticly set via PRAGMA statements //Test header values explicitly set via PRAGMA statements
EXPECT_EQ(h.userVersion, 12345); EXPECT_EQ(h.userVersion, 12345);
EXPECT_EQ(h.applicationId, 2468); EXPECT_EQ(h.applicationId, 2468);