From 90bd93b10f4ba478999c43e785e5c16826db153e Mon Sep 17 00:00:00 2001 From: Anna Schumaker Date: Sat, 3 May 2014 18:42:54 -0400 Subject: [PATCH] index: Update the index test I switched to the new testing functions, and now everything is cleaner. Signed-off-by: Anna Schumaker --- tests/Sconscript | 4 +- tests/index | 47 -------- tests/src/index.cpp | 287 +++++++++++++++++++++++--------------------- tests/src/test.h | 12 ++ 4 files changed, 165 insertions(+), 185 deletions(-) delete mode 100755 tests/index diff --git a/tests/Sconscript b/tests/Sconscript index e1b7f05c..f8e9bb9b 100644 --- a/tests/Sconscript +++ b/tests/Sconscript @@ -14,8 +14,8 @@ for arg in sys.argv: src = SConscript("src/Sconscript") -tests = [ "version" , "file", "database" ] -# "database", "index", "filter", "idle", "tag_db", +tests = [ "version" , "file", "database", "index" ] +# "filter", "idle", "tag_db", # "queue" ] #scripts = [ "playlist", "library", "deck", "audio", "gui" ] diff --git a/tests/index b/tests/index deleted file mode 100755 index fd013b79..00000000 --- a/tests/index +++ /dev/null @@ -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 diff --git a/tests/src/index.cpp b/tests/src/index.cpp index b7ac7664..0001dfde 100644 --- a/tests/src/index.cpp +++ b/tests/src/index.cpp @@ -4,153 +4,168 @@ */ #include -#include +#include "test.h" -#include -#include +#include + +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); - if (success) - print("Success!\n"); - else { - print("FAILED (%u) =(\n", line); - exit(1); - } - test_num++; + Index index("index.idx", false); + + index.insert("a", 0); + IndexEntry *it = index.find("a"); + + test_not_equal(it, IDX_NULL); + test_equal(index.size(), (unsigned)1); + 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) { - bool autosave = false; - unsigned int n; - char c; - - while ((c = getopt(argc, argv, "a")) != -1) { - switch (c) { - 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__); - + index_test(0); + index_test(10); + index_test(100); + index_test(1000); + index_test(10000); + index_test(100000); return 0; } diff --git a/tests/src/test.h b/tests/src/test.h index d3ba05ad..26d60df8 100644 --- a/tests/src/test.h +++ b/tests/src/test.h @@ -75,6 +75,13 @@ namespace test check_equal(lhs, rhs, line); } + template + 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 res = g_get_user_data_dir(); @@ -117,6 +124,11 @@ namespace test test :: equal(lhs, rhs, __LINE__); \ } while (0) +#define test_not_equal(lhs, rhs) \ + do { \ + test :: not_equal(lhs, rhs, __LINE__); \ + } while (0) + #define check_equal(lhs, rhs) \ do { \ if (lhs != rhs) \