2014-03-09 14:58:06 -04:00
|
|
|
/*
|
|
|
|
* Copyright 2014 (c) Anna Schumaker.
|
|
|
|
* Test a Database
|
|
|
|
*/
|
2014-06-05 10:19:22 -04:00
|
|
|
#include <core/database.h>
|
2015-01-26 09:40:48 -05:00
|
|
|
#include <core/string.h>
|
2014-06-14 10:50:18 -04:00
|
|
|
#include <tests/test.h>
|
2014-03-09 14:58:06 -04:00
|
|
|
|
2015-01-04 16:36:19 -05:00
|
|
|
#include <vector>
|
2014-03-09 14:58:06 -04:00
|
|
|
|
|
|
|
|
2015-01-04 16:36:19 -05:00
|
|
|
/*
|
|
|
|
* Derive a DatabaseEntry for storing integerss
|
2014-04-27 17:04:33 -04:00
|
|
|
*/
|
2014-03-09 14:58:06 -04:00
|
|
|
class IntEntry : public DatabaseEntry {
|
|
|
|
public:
|
|
|
|
unsigned int val;
|
|
|
|
|
2015-01-04 16:36:19 -05:00
|
|
|
IntEntry() : val(0) {};
|
|
|
|
IntEntry(unsigned int v) : val(v) {};
|
2014-04-27 17:04:33 -04:00
|
|
|
|
2015-01-04 16:36:19 -05:00
|
|
|
const std::string primary_key() const
|
|
|
|
{
|
2015-01-26 09:40:48 -05:00
|
|
|
return string :: utos(val);
|
2015-01-04 16:36:19 -05:00
|
|
|
}
|
2014-04-27 17:04:33 -04:00
|
|
|
|
2015-01-04 16:36:19 -05:00
|
|
|
void write(File &f) { f << val; }
|
|
|
|
void read(File &f) { f >> val; }
|
2014-04-27 17:04:33 -04:00
|
|
|
};
|
|
|
|
|
2014-03-09 14:58:06 -04:00
|
|
|
|
2015-01-04 16:36:19 -05:00
|
|
|
static unsigned int N = 0;
|
|
|
|
static bool AUTOSAVE = false;
|
|
|
|
static Database<IntEntry> *DB = NULL;
|
2015-01-04 17:56:54 -05:00
|
|
|
static Database<IntEntry>::iterator IT;
|
|
|
|
static std::vector<IntEntry *> *POINTERS;
|
2014-03-09 14:58:06 -04:00
|
|
|
|
|
|
|
|
2015-01-04 17:56:54 -05:00
|
|
|
static unsigned int _test_insertion_check(unsigned int i)
|
2014-04-27 17:04:33 -04:00
|
|
|
{
|
2015-01-04 17:56:54 -05:00
|
|
|
IntEntry *it = DB->insert(IntEntry(i));
|
|
|
|
if ((it == NULL) || (it->index() != i) || (it->val != i))
|
|
|
|
return LOOP_FAILED;
|
|
|
|
POINTERS->push_back(it);
|
2014-04-27 17:04:33 -04:00
|
|
|
|
2015-01-04 17:56:54 -05:00
|
|
|
return (DB->insert(IntEntry(i)) == NULL) ? LOOP_PASSED : LOOP_FAILED;
|
|
|
|
}
|
2014-03-25 10:57:09 -04:00
|
|
|
|
2015-01-04 17:56:54 -05:00
|
|
|
static unsigned int _test_insertion_pointer_check(unsigned int i)
|
|
|
|
{
|
|
|
|
return (POINTERS->at(i) == DB->at(i)) ? LOOP_PASSED : LOOP_FAILED;
|
|
|
|
}
|
2014-03-09 14:58:06 -04:00
|
|
|
|
2015-01-04 17:56:54 -05:00
|
|
|
static void test_insertion()
|
|
|
|
{
|
|
|
|
/* Check initial sizes. */
|
|
|
|
test_equal(DB->size(), (unsigned)0);
|
|
|
|
test_equal(DB->actual_size(), (unsigned)0);
|
2014-03-09 14:58:06 -04:00
|
|
|
|
2015-01-04 17:56:54 -05:00
|
|
|
test_for_each(0, N, 1, _test_insertion_check);
|
2015-01-04 16:36:19 -05:00
|
|
|
test_equal(DB->size(), N);
|
|
|
|
test_equal(DB->actual_size(), N);
|
2014-03-09 14:58:06 -04:00
|
|
|
|
2015-01-04 17:56:54 -05:00
|
|
|
/* Pointers should still be valid. */
|
|
|
|
test_for_each(0, N, 1, _test_insertion_pointer_check);
|
2014-04-27 17:04:33 -04:00
|
|
|
}
|
2014-03-09 14:58:06 -04:00
|
|
|
|
2015-01-04 17:56:54 -05:00
|
|
|
|
2015-01-04 16:36:19 -05:00
|
|
|
static void test_removal()
|
2014-04-27 17:04:33 -04:00
|
|
|
{
|
2015-01-04 17:56:54 -05:00
|
|
|
/* Size should have only changed once each iteration. */
|
2015-01-04 16:36:19 -05:00
|
|
|
for (unsigned int i = 0; i < N; i+=2) {
|
|
|
|
DB->remove(i);
|
|
|
|
DB->remove(i);
|
2014-04-27 17:04:33 -04:00
|
|
|
}
|
2014-03-09 14:58:06 -04:00
|
|
|
|
2015-01-04 16:36:19 -05:00
|
|
|
test_equal(DB->size(), N / 2);
|
|
|
|
test_equal(DB->actual_size(), N);
|
2014-03-09 14:58:06 -04:00
|
|
|
|
2015-01-04 17:56:54 -05:00
|
|
|
/* Test out-of-bounds removal. */
|
2014-04-27 17:04:33 -04:00
|
|
|
for (unsigned int i = 0; i < 10; i++)
|
2015-01-04 16:36:19 -05:00
|
|
|
DB->remove(N + i);
|
2014-03-09 14:58:06 -04:00
|
|
|
|
2015-01-04 16:36:19 -05:00
|
|
|
test_equal(DB->size(), N / 2);
|
|
|
|
test_equal(DB->actual_size(), N);
|
2014-04-27 17:04:33 -04:00
|
|
|
}
|
2014-03-09 14:58:06 -04:00
|
|
|
|
2015-01-04 17:56:54 -05:00
|
|
|
|
|
|
|
static unsigned int _test_access_null(unsigned int i)
|
2014-04-27 17:04:33 -04:00
|
|
|
{
|
2015-01-04 17:56:54 -05:00
|
|
|
return (DB->at(i) == NULL) ? LOOP_PASSED : LOOP_FAILED;
|
|
|
|
}
|
2014-03-09 14:58:06 -04:00
|
|
|
|
2015-01-04 17:56:54 -05:00
|
|
|
static unsigned int _test_access_valid(unsigned int i)
|
|
|
|
{
|
|
|
|
IntEntry *ie = DB->at(i);
|
2014-03-25 10:57:09 -04:00
|
|
|
|
2015-01-04 17:56:54 -05:00
|
|
|
if ((ie == NULL) || (*IT != ie) ||
|
|
|
|
(ie->val != i) || (ie->index() != i))
|
|
|
|
return LOOP_FAILED;
|
|
|
|
IT = DB->next(IT);
|
|
|
|
return LOOP_PASSED;
|
|
|
|
}
|
2014-03-09 14:58:06 -04:00
|
|
|
|
2015-01-04 17:56:54 -05:00
|
|
|
static void test_access()
|
|
|
|
{
|
|
|
|
IT = DB->begin();
|
|
|
|
test_for_each(0, N, 2, _test_access_null);
|
|
|
|
test_for_each(1, N, 2, _test_access_valid);
|
|
|
|
test_for_each(N, N + 10, 1, _test_access_null);
|
|
|
|
}
|
2015-01-04 16:36:19 -05:00
|
|
|
|
2014-03-09 14:58:06 -04:00
|
|
|
|
2015-01-04 17:56:54 -05:00
|
|
|
static unsigned int _test_reinsert_check(unsigned int i)
|
|
|
|
{
|
|
|
|
IntEntry *it = DB->insert(IntEntry(i));
|
|
|
|
return (it->index() == (N + (i / 2))) ? LOOP_PASSED : LOOP_FAILED;
|
2014-04-27 17:04:33 -04:00
|
|
|
}
|
2014-03-09 14:58:06 -04:00
|
|
|
|
2015-01-04 16:36:19 -05:00
|
|
|
static void test_reinsert()
|
2014-04-27 17:04:33 -04:00
|
|
|
{
|
2015-01-04 17:56:54 -05:00
|
|
|
test_for_each(0, N, 2, _test_reinsert_check);
|
2015-01-04 16:36:19 -05:00
|
|
|
test_equal(DB->size(), N);
|
|
|
|
test_equal(DB->actual_size(), N + (N / 2));
|
2014-04-27 17:04:33 -04:00
|
|
|
}
|
2014-03-09 14:58:06 -04:00
|
|
|
|
2015-01-04 17:56:54 -05:00
|
|
|
|
|
|
|
static Database<IntEntry> *DB2;
|
|
|
|
|
|
|
|
static unsigned int _test_save_load_check(unsigned int i)
|
|
|
|
{
|
|
|
|
IntEntry *ie1 = DB->at(i);
|
|
|
|
IntEntry *ie2 = DB2->at(i);
|
|
|
|
|
|
|
|
if (ie1 == NULL)
|
|
|
|
return (ie2 == NULL) ? LOOP_PASSED : LOOP_FAILED;
|
|
|
|
else {
|
|
|
|
if ((ie2 == NULL) || (ie1->index() != ie2->index()) ||
|
|
|
|
(ie1->val != ie2->val))
|
|
|
|
return LOOP_FAILED;
|
|
|
|
}
|
|
|
|
|
|
|
|
return LOOP_PASSED;
|
|
|
|
}
|
|
|
|
|
2015-01-04 16:36:19 -05:00
|
|
|
static void test_save_load()
|
2014-04-27 17:04:33 -04:00
|
|
|
{
|
2015-01-04 16:36:19 -05:00
|
|
|
Database<IntEntry> db2("database.db", false);
|
2014-03-09 14:58:06 -04:00
|
|
|
db2.load();
|
2015-01-04 17:56:54 -05:00
|
|
|
DB2 = &db2;
|
2014-03-09 14:58:06 -04:00
|
|
|
|
2015-01-04 16:36:19 -05:00
|
|
|
if (AUTOSAVE == false) {
|
2014-04-27 17:04:33 -04:00
|
|
|
test_equal(db2.size(), (unsigned)0);
|
|
|
|
test_equal(db2.actual_size(), (unsigned)0);
|
2014-03-09 14:58:06 -04:00
|
|
|
|
2015-01-04 16:36:19 -05:00
|
|
|
DB->save();
|
2014-04-27 17:04:33 -04:00
|
|
|
db2.load();
|
|
|
|
}
|
2014-03-09 14:58:06 -04:00
|
|
|
|
2015-01-04 16:36:19 -05:00
|
|
|
test_equal(db2.size(), DB->size());
|
|
|
|
test_equal(db2.actual_size(), DB->actual_size());
|
2015-01-04 17:56:54 -05:00
|
|
|
test_for_each(0, DB->actual_size(), 1, _test_save_load_check);
|
2014-04-27 17:04:33 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
static void db_test(unsigned int n, bool autosave)
|
|
|
|
{
|
2015-01-26 09:40:48 -05:00
|
|
|
std::string n_str = " (n = " + string :: utos(n) + ")";
|
2015-01-04 17:56:54 -05:00
|
|
|
Database<IntEntry> db("database.db", autosave);
|
|
|
|
std::vector<IntEntry *> pointers;
|
2015-01-04 16:36:19 -05:00
|
|
|
|
|
|
|
N = n;
|
|
|
|
DB = &db;
|
|
|
|
AUTOSAVE = autosave;
|
2015-01-04 17:56:54 -05:00
|
|
|
POINTERS = &pointers;
|
2015-01-04 16:36:19 -05:00
|
|
|
|
2015-01-04 17:56:54 -05:00
|
|
|
test :: rm_data_dir();
|
|
|
|
test :: run("Database Insertion Test" + n_str, test_insertion);
|
|
|
|
test :: run("Database Removal Test" + n_str, test_removal);
|
|
|
|
test :: run("Database Access Test" + n_str, test_access);
|
|
|
|
test :: run("Database Reinsertion Test" + n_str, test_reinsert);
|
|
|
|
test :: run("Database Save and Load Test" + n_str, test_save_load);
|
2014-04-27 17:04:33 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
int main(int argc, char **argv)
|
|
|
|
{
|
|
|
|
db_test(0, true);
|
|
|
|
db_test(10, true);
|
|
|
|
db_test(100, true);
|
|
|
|
db_test(1000, true);
|
|
|
|
db_test(10000, false);
|
|
|
|
db_test(100000, false);
|
2014-03-09 14:58:06 -04:00
|
|
|
return 0;
|
|
|
|
}
|