index: Update the index test
I switched to the new testing functions, and now everything is cleaner. Signed-off-by: Anna Schumaker <Anna@OcarinaProject.net>
This commit is contained in:
parent
f627f8337d
commit
90bd93b10f
|
@ -14,8 +14,8 @@ for arg in sys.argv:
|
||||||
|
|
||||||
src = SConscript("src/Sconscript")
|
src = SConscript("src/Sconscript")
|
||||||
|
|
||||||
tests = [ "version" , "file", "database" ]
|
tests = [ "version" , "file", "database", "index" ]
|
||||||
# "database", "index", "filter", "idle", "tag_db",
|
# "filter", "idle", "tag_db",
|
||||||
# "queue" ]
|
# "queue" ]
|
||||||
#scripts = [ "playlist", "library", "deck", "audio", "gui" ]
|
#scripts = [ "playlist", "library", "deck", "audio", "gui" ]
|
||||||
|
|
||||||
|
|
47
tests/index
47
tests/index
|
@ -1,47 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
# Copyright 2014 (c) Anna Schumaker
|
|
||||||
|
|
||||||
. $(dirname $0)/_functions
|
|
||||||
|
|
||||||
function test_autosave
|
|
||||||
{
|
|
||||||
new_test "Index Test (n = $1, autosave = true)"
|
|
||||||
src/index.run -a $1
|
|
||||||
if [ ! -f $DATA_DIR/index.idx ]; then
|
|
||||||
echo "ERROR: $DATA_DIR/index.db doesn't exist!"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
function test_noautosave
|
|
||||||
{
|
|
||||||
new_test "Index Test (n = $1, autosave = false)"
|
|
||||||
src/index.run $1
|
|
||||||
if [ -f $DATA_DIR/index.idx ]; then
|
|
||||||
echo "ERROR: $DATA_DIR/index.idx exists!"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
function run_test
|
|
||||||
{
|
|
||||||
rm $DATA_DIR/* 2>/dev/null || true
|
|
||||||
|
|
||||||
if [ $1 -lt 1000 ]; then
|
|
||||||
test_autosave $1
|
|
||||||
else
|
|
||||||
test_noautosave $1
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
run_test 0
|
|
||||||
echo
|
|
||||||
run_test 10
|
|
||||||
echo
|
|
||||||
run_test 100
|
|
||||||
echo
|
|
||||||
run_test 1000
|
|
||||||
echo
|
|
||||||
run_test 10000
|
|
||||||
echo
|
|
||||||
run_test 100000
|
|
|
@ -4,153 +4,168 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <index.h>
|
#include <index.h>
|
||||||
#include <print.h>
|
#include "test.h"
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <sstream>
|
||||||
#include <unistd.h>
|
|
||||||
|
static IndexEntry *IDX_NULL = NULL;
|
||||||
|
|
||||||
|
/***
|
||||||
|
*
|
||||||
|
* Struct for passing around arguments to tests
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
struct TestArgs {
|
||||||
|
const unsigned int n;
|
||||||
|
Index *index;
|
||||||
|
|
||||||
|
TestArgs(const unsigned int, Index *);
|
||||||
|
};
|
||||||
|
|
||||||
|
TestArgs :: TestArgs(const unsigned int _n, Index *_index)
|
||||||
|
: n(_n), index(_index)
|
||||||
|
{}
|
||||||
|
|
||||||
|
|
||||||
unsigned int test_num = 0;
|
|
||||||
|
|
||||||
void test_results(bool success, unsigned int line)
|
/***
|
||||||
|
*
|
||||||
|
* Run tests with varying index sizes
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
static void test_single_item()
|
||||||
{
|
{
|
||||||
print(" %u: ", test_num);
|
Index index("index.idx", false);
|
||||||
if (success)
|
|
||||||
print("Success!\n");
|
index.insert("a", 0);
|
||||||
else {
|
IndexEntry *it = index.find("a");
|
||||||
print("FAILED (%u) =(\n", line);
|
|
||||||
exit(1);
|
test_not_equal(it, IDX_NULL);
|
||||||
}
|
test_equal(index.size(), (unsigned)1);
|
||||||
test_num++;
|
test_equal(it->values.size(), (size_t)1);
|
||||||
|
test_equal(*(it->values.begin()), (unsigned)0);
|
||||||
|
|
||||||
|
index.remove("a", 0);
|
||||||
|
test_equal(index.size(), (unsigned)1);
|
||||||
|
test_equal(it->values.size(), (size_t)0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void test_size(Index &index, unsigned int expected, unsigned int line)
|
static void test_insertion(struct TestArgs *args)
|
||||||
{
|
{
|
||||||
test_results(index.size() == expected, line);
|
std::string key;
|
||||||
|
IndexEntry *it;
|
||||||
|
|
||||||
|
test :: begin();
|
||||||
|
for (char c = 'a'; c <= 'z'; c++) {
|
||||||
|
key = c;
|
||||||
|
|
||||||
|
for (unsigned int i = 0; i < args->n; i++)
|
||||||
|
args->index->insert(key, i);
|
||||||
|
}
|
||||||
|
test :: success();
|
||||||
|
|
||||||
|
if (args->n == 0)
|
||||||
|
test_equal(args->index->size(), (unsigned int)0);
|
||||||
|
else
|
||||||
|
test_equal(args->index->size(), (unsigned int)26);
|
||||||
|
|
||||||
|
test :: begin();
|
||||||
|
for (char c = 'a'; c <= 'z'; c++) {
|
||||||
|
key = c;
|
||||||
|
it = args->index->find(key);
|
||||||
|
|
||||||
|
if (args->n == 0)
|
||||||
|
check_equal(it, IDX_NULL);
|
||||||
|
else {
|
||||||
|
check_not_equal(it, IDX_NULL);
|
||||||
|
check_equal(it->values.size(), (size_t)args->n);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
test :: success();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void test_removal(struct TestArgs *args)
|
||||||
|
{
|
||||||
|
std::string key;
|
||||||
|
IndexEntry *it;
|
||||||
|
|
||||||
|
test :: begin();
|
||||||
|
for (char c = 'a'; c <= 'z'; c++) {
|
||||||
|
key = c;
|
||||||
|
|
||||||
|
for (unsigned int i = 0; i < args->n; i++)
|
||||||
|
args->index->remove(key, i);
|
||||||
|
it = args->index->find(key);
|
||||||
|
if (args->n == 0)
|
||||||
|
check_equal(it, IDX_NULL);
|
||||||
|
else {
|
||||||
|
check_not_equal(it, IDX_NULL);
|
||||||
|
check_equal(it->values.size(), (size_t)0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
test :: success();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void test_saving(struct TestArgs *args)
|
||||||
|
{
|
||||||
|
std::string key;
|
||||||
|
IndexEntry *it1, *it2;
|
||||||
|
|
||||||
|
Index idx2("index.idx", false);
|
||||||
|
idx2.load();
|
||||||
|
test_equal(idx2.size(), (unsigned)0);
|
||||||
|
|
||||||
|
args->index->save();
|
||||||
|
idx2.load();
|
||||||
|
|
||||||
|
test_equal(idx2.size(), args->index->size());
|
||||||
|
test_equal(idx2.actual_size(), args->index->actual_size());
|
||||||
|
|
||||||
|
test :: begin();
|
||||||
|
for (char c = 'a'; c <= 'z'; c++) {
|
||||||
|
key = c;
|
||||||
|
it1 = args->index->find(key);
|
||||||
|
it2 = idx2.find(key);
|
||||||
|
|
||||||
|
if (args->n == 0) {
|
||||||
|
check_equal(it1, IDX_NULL);
|
||||||
|
check_equal(it2, IDX_NULL);
|
||||||
|
} else {
|
||||||
|
check_not_equal(it1, IDX_NULL);
|
||||||
|
check_not_equal(it2, IDX_NULL);
|
||||||
|
check_equal(it1->values.size(), it2->values.size());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
test :: success();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void index_test(unsigned int n)
|
||||||
|
{
|
||||||
|
test :: rm_data_dir();
|
||||||
|
|
||||||
|
std::stringstream ss;
|
||||||
|
ss << " (n = " << n << ")";
|
||||||
|
const std::string n_str = ss.str();
|
||||||
|
|
||||||
|
Index index("index.idx", false);
|
||||||
|
struct TestArgs args(n, &index);
|
||||||
|
|
||||||
|
if (n == 0)
|
||||||
|
run_test("Index Single Item Test", test_single_item);
|
||||||
|
run_test("Index Insertion Test" + n_str, test_insertion, &args);
|
||||||
|
run_test("Index Removal Test" + n_str, test_removal, &args);
|
||||||
|
run_test("Index Save and Load Test" + n_str, test_saving, &args);
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
bool autosave = false;
|
index_test(0);
|
||||||
unsigned int n;
|
index_test(10);
|
||||||
char c;
|
index_test(100);
|
||||||
|
index_test(1000);
|
||||||
while ((c = getopt(argc, argv, "a")) != -1) {
|
index_test(10000);
|
||||||
switch (c) {
|
index_test(100000);
|
||||||
case 'a':
|
|
||||||
autosave = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
n = atoi(argv[optind]);
|
|
||||||
Index index("index.idx", autosave);
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 0: Test inserting when there is no key
|
|
||||||
*/
|
|
||||||
index.insert("a", 0);
|
|
||||||
IndexEntry *it = index.find("a");
|
|
||||||
if (it == NULL)
|
|
||||||
test_results(false, __LINE__);
|
|
||||||
if (it->values.size() == 0)
|
|
||||||
test_results(false, __LINE__);
|
|
||||||
test_results(*(it->values.begin()) == 0, __LINE__);
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 1: Test removing
|
|
||||||
*/
|
|
||||||
index.remove("a", 0);
|
|
||||||
test_results((index.size() == 1) && (index.find("a")->values.size() == 0), __LINE__);
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 2: Test adding multiple values
|
|
||||||
*/
|
|
||||||
for (c = 'a'; c <= 'z'; c++) {
|
|
||||||
std::string key = "";
|
|
||||||
key += c;
|
|
||||||
|
|
||||||
for (unsigned int i = 0; i < n; i++)
|
|
||||||
index.insert(key, i);
|
|
||||||
}
|
|
||||||
|
|
||||||
test_size(index, (n == 0) ? 1 : 26, __LINE__);
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 3: Make sure we have multiple values for each key
|
|
||||||
*/
|
|
||||||
for (c = 'a'; c <= 'z'; c++) {
|
|
||||||
std::string key = "";
|
|
||||||
key += c;
|
|
||||||
|
|
||||||
IndexEntry *it = index.find(key);
|
|
||||||
if (n == 0 && c > 'a') {
|
|
||||||
if (it != NULL)
|
|
||||||
test_results(false, __LINE__);
|
|
||||||
} else if (it->values.size() != n)
|
|
||||||
test_results(false, __LINE__);
|
|
||||||
}
|
|
||||||
test_results(true, __LINE__);
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 4: Test removing multiple values
|
|
||||||
*/
|
|
||||||
for (c = 'a'; c <= 'z'; c+=2) {
|
|
||||||
std::string key = "";
|
|
||||||
key += c;
|
|
||||||
|
|
||||||
for (unsigned int i = 0; i < n; i++)
|
|
||||||
index.remove(key, i);
|
|
||||||
|
|
||||||
IndexEntry *it = index.find(key);
|
|
||||||
if (n == 0 && c > 'a') {
|
|
||||||
if (it != NULL)
|
|
||||||
test_results(false, __LINE__);
|
|
||||||
} else if (it->values.size() != 0)
|
|
||||||
test_results(false, __LINE__);
|
|
||||||
}
|
|
||||||
|
|
||||||
test_size(index, (n == 0) ? 1 : 26, __LINE__);
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Everything after this point tests loading from a file
|
|
||||||
*/
|
|
||||||
if (autosave == false)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
Index index2("index.idx", autosave);
|
|
||||||
index2.load();
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 5: Load database from file
|
|
||||||
*/
|
|
||||||
test_results(index.size() == index2.size(), __LINE__);
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 6: Check that everything is the right size
|
|
||||||
*/
|
|
||||||
for (c = 'a'; c <= 'z'; c++) {
|
|
||||||
std::string key = "";
|
|
||||||
key += c;
|
|
||||||
|
|
||||||
IndexEntry *it1 = index.find(key);
|
|
||||||
IndexEntry *it2 = index2.find(key);
|
|
||||||
|
|
||||||
if (n == 0 && c > 'a') {
|
|
||||||
if (it1 != NULL || it2 != NULL)
|
|
||||||
test_results(false, __LINE__);
|
|
||||||
} else if (it1->values.size() != it2->values.size())
|
|
||||||
test_results(false, __LINE__);
|
|
||||||
}
|
|
||||||
test_results(true, __LINE__);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -75,6 +75,13 @@ namespace test
|
||||||
check_equal(lhs, rhs, line);
|
check_equal(lhs, rhs, line);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
void not_equal(const T &lhs, const T &rhs, unsigned int line)
|
||||||
|
{
|
||||||
|
begin();
|
||||||
|
check_not_equal(lhs, rhs, line);
|
||||||
|
}
|
||||||
|
|
||||||
std::string data_dir()
|
std::string data_dir()
|
||||||
{
|
{
|
||||||
std::string res = g_get_user_data_dir();
|
std::string res = g_get_user_data_dir();
|
||||||
|
@ -117,6 +124,11 @@ namespace test
|
||||||
test :: equal(lhs, rhs, __LINE__); \
|
test :: equal(lhs, rhs, __LINE__); \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
|
#define test_not_equal(lhs, rhs) \
|
||||||
|
do { \
|
||||||
|
test :: not_equal(lhs, rhs, __LINE__); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
#define check_equal(lhs, rhs) \
|
#define check_equal(lhs, rhs) \
|
||||||
do { \
|
do { \
|
||||||
if (lhs != rhs) \
|
if (lhs != rhs) \
|
||||||
|
|
Loading…
Reference in New Issue