summaryrefslogtreecommitdiffstats
path: root/tests
diff options
context:
space:
mode:
Diffstat (limited to 'tests')
-rw-r--r--tests/Makefile.am8
-rw-r--r--tests/test-symtab.c344
-rw-r--r--tests/test-vector.c1209
3 files changed, 1559 insertions, 2 deletions
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 4ab507bb..33861328 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -6,7 +6,7 @@ AM_LDFLAGS = $(PILDFLAGS)
noinst_PROGRAMS = testsig testbuffer testmemory heavy heavywq heavythread \
aspathtest testprivs teststream testbgpcap ecommtest \
- testbgpmpattr testchecksum
+ testbgpmpattr testchecksum testvector testsymtab
testsig_SOURCES = test-sig.c
testbuffer_SOURCES = test-buffer.c
@@ -21,6 +21,8 @@ testbgpcap_SOURCES = bgp_capability_test.c
ecommtest_SOURCES = ecommunity_test.c
testbgpmpattr_SOURCES = bgp_mp_attr_test.c
testchecksum_SOURCES = test-checksum.c
+testvector_SOURCES = test-vector.c
+testsymtab_SOURCES = test-symtab.c
testsig_LDADD = ../lib/libzebra.la @LIBCAP@
testbuffer_LDADD = ../lib/libzebra.la @LIBCAP@
@@ -34,4 +36,6 @@ aspathtest_LDADD = ../lib/libzebra.la @LIBCAP@ -lm ../bgpd/libbgp.a
testbgpcap_LDADD = ../lib/libzebra.la @LIBCAP@ -lm ../bgpd/libbgp.a
ecommtest_LDADD = ../lib/libzebra.la @LIBCAP@ -lm ../bgpd/libbgp.a
testbgpmpattr_LDADD = ../lib/libzebra.la @LIBCAP@ -lm ../bgpd/libbgp.a
-testchecksum_LDADD = ../lib/libzebra.la @LIBCAP@
+testchecksum_LDADD = ../lib/libzebra.la @LIBCAP@
+testvector_LDADD = ../lib/libzebra.la @LIBCAP@
+testsymtab_LDADD = ../lib/libzebra.la @LIBCAP@
diff --git a/tests/test-symtab.c b/tests/test-symtab.c
new file mode 100644
index 00000000..ed83e607
--- /dev/null
+++ b/tests/test-symtab.c
@@ -0,0 +1,344 @@
+#include <zebra.h>
+#include <symtab.h>
+
+/* Symtab torture tests
+ *
+ */
+
+/* prototypes */
+void assert_true(int result, const char * message);
+int main(int argc, char **argv);
+void test_symbol_table_init_new(void);
+void test_symbol_table_lookup(void);
+void call_back_function_set(symbol sym, void* value);
+void call_back_function_change(symbol sym, void* value);
+void call_back_function_unset(symbol sym, void* value);
+void test_call_back(void);
+void test_ref(void);
+void test_ref_heavy(void);
+
+struct thread_master *master;
+
+void
+assert_true(int result, const char * message)
+{
+ if (!result)
+ {
+ printf("Assert failed: %s\n", message);
+ }
+}
+
+int
+main(int argc, char **argv)
+{
+
+ test_symbol_table_init_new();
+ test_symbol_table_lookup();
+ test_call_back();
+ test_ref();
+ test_ref_heavy();
+
+ return 0;
+}
+
+void
+test_symbol_table_init_new(void)
+{
+ symbol_table table = NULL;
+ char name[] = "name";
+ char value[] = "value";
+ symbol sym = NULL;
+ symbol sym2 = NULL;
+ void * old_value = NULL;
+
+ printf("test_symbol_table_init_new\n");
+ table = symbol_table_init_new(table, NULL, 0, 0, NULL, NULL);
+ assert_true(table != NULL, "table == NULL");
+
+ /* expect to not find */
+ sym = symbol_lookup(table, name, 0);
+ assert_true(sym == NULL, "sym != NULL");
+
+ /* add */
+ sym = symbol_lookup(table, name, 1);
+ symbol_set_value(sym, value);
+ assert_true(sym != NULL, "sym == NULL");
+ assert_true(strcmp(symbol_get_name(sym), name) == 0, "strcmp(symbol_get_name(sym), name) != 0");
+
+ /* find */
+ sym2 = symbol_lookup(table, name, 0);
+ assert_true(sym == sym2, "sym != sym2");
+ assert_true(symbol_get_value(sym) == value, "symbol_get_value(sym) != value");
+
+ old_value = symbol_delete(sym);
+ assert_true(value == old_value, "value != old_value");
+
+ while ((old_value = symbol_table_ream(table, 1)) != NULL)
+ {
+ }
+
+}
+
+void
+test_symbol_table_lookup(void)
+{
+ symbol_table table = NULL;
+ char buf[20];
+ symbol sym = NULL;
+ int i;
+ char *value = NULL;
+ const int len = 100000;
+ struct symbol_walker itr;
+ vector v = NULL;
+
+ printf("test_symbol_table_lookup\n");
+ table = symbol_table_init_new(table, NULL, 0, 0, NULL, NULL);
+
+ /* add */
+ for (i = 0; i < len; ++i)
+ {
+ sprintf(buf, "%d-name", i);
+ sym = symbol_lookup(table, buf, 1);
+ assert_true(sym != NULL, "add: sym == NULL");
+ assert_true(strcmp(symbol_get_name(sym), buf) == 0,
+ "strcmp(symbol_get_name(sym), buf) != 0");
+
+ sprintf(buf, "%d-value", i);
+ value = strdup(buf);
+ symbol_set_value(sym, value);
+ assert_true(symbol_get_value(sym) == value,
+ "symbol_get_value(sym) != value");
+ }
+
+ /* find */
+ for (i = 0; i < len; ++i)
+ {
+ sprintf(buf, "%d-name", i);
+ sym = symbol_lookup(table, buf, 0);
+ assert_true(sym != NULL, "find: sym == NULL");
+ assert_true(strcmp(symbol_get_name(sym), buf) == 0,
+ "strcmp(symbol_get_name(sym), buf) != 0");
+
+ sprintf(buf, "%d-value", i);
+ assert_true(strcmp(symbol_get_value(sym), buf) == 0,
+ "strcmp(symbol_get_value(sym), buf) != 0");
+ }
+
+ /* walk with symbol_walker */
+ symbol_walk_start(table, &itr);
+ i = 0;
+ do
+ {
+ sym = symbol_walk_next(&itr);
+ if (sym != NULL) {
+ ++i;
+ }
+ } while (sym != NULL);
+ assert_true(i == len, "i != len");
+
+ /* extract vector */
+ v = symbol_table_extract(table, NULL, NULL, 1, NULL);
+ assert_true(vector_end(v) == (unsigned)len, "vector_get_end(v) != len");
+ vector_free(v);
+
+ while ((value = symbol_table_ream(table, 1)) != NULL)
+ {
+ free(value);
+ }
+}
+
+void
+test_call_back(void)
+{
+ symbol_table table = NULL;
+ char name[] = "name";
+ char value[] = "value";
+ char new_value[] = "new value";
+ symbol sym = NULL;
+
+ printf("test_call_back\n");
+ table = symbol_table_init_new(table, NULL, 0, 0, NULL, NULL);
+ assert_true(table != NULL, "table == NULL");
+
+ /* add */
+ symbol_table_set_value_call_back(table, call_back_function_set);
+ sym = symbol_lookup(table, name, 1);
+ symbol_set_value(sym, value);
+
+ /* change */
+ symbol_table_set_value_call_back(table, call_back_function_change);
+ sym = symbol_lookup(table, name, 1);
+ symbol_set_value(sym, new_value);
+
+ /* delete */
+ symbol_table_set_value_call_back(table, call_back_function_unset);
+ symbol_unset_value(sym);
+
+ while ((symbol_table_ream(table, 1)) != NULL)
+ {
+ }
+}
+
+void call_back_function_set(symbol sym, void* value)
+{
+ assert_true(symbol_get_value(sym) != NULL && value == NULL,
+ "symbol_get_value(sym) == NULL || value != NULL");
+}
+
+void call_back_function_change(symbol sym, void* value)
+{
+ assert_true(symbol_get_value(sym) != NULL && value != NULL,
+ "symbol_get_value(sym) == NULL || value == NULL");
+}
+
+
+void call_back_function_unset(symbol sym, void* value)
+{
+ assert_true(symbol_get_value(sym) == NULL && value != NULL,
+ "symbol_get_value(sym) != NULL || value == NULL");
+}
+
+void
+test_ref(void)
+{
+ symbol_table table = NULL;
+ char name[] = "name";
+ char value[] = "value";
+ symbol sym = NULL;
+ symbol_ref ref = NULL;
+ symbol_ref ref1 = NULL;
+ symbol_ref ref2 = NULL;
+ struct symbol_ref walk;
+ const int num_refs = 2;
+ long int itag = 0;
+
+ printf("test_ref\n");
+ table = symbol_table_init_new(table, NULL, 0, 0, NULL, NULL);
+
+ /* add */
+ sym = symbol_lookup(table, name, 1);
+ symbol_set_value(sym, value);
+
+ /* create references, in reverse order so that walk in order */
+ ref2 = symbol_set_ref(NULL, sym);
+ assert_true(ref2 != NULL, "ref2 == NULL");
+ sym_ref_set_i_tag(ref2, 2);
+ assert_true(sym_ref_i_tag(ref2) == 2, "sym_ref_i_tag(ref2) != 2");
+
+ ref1 = symbol_set_ref(NULL, sym);
+ assert_true(ref1 != NULL, "ref1 == NULL");
+ sym_ref_set_i_tag(ref1, 1);
+ assert_true(sym_ref_i_tag(ref1) == 1, "sym_ref_i_tag(ref1) != 1");
+
+ /* walk references */
+ itag = 1;
+ symbol_ref_walk_start(sym, &walk) ;
+ assert_true(sym->ref_list == &walk, "sym->ref_list != &walk");
+ assert_true(walk.next == ref1, "walk.next != ref1");
+ assert_true(ref1->next == ref2, "ref1->next != ref2");
+ assert_true(ref2->next == NULL, "ref2->next != NULL");
+
+ while ((ref = symbol_ref_walk_step(&walk)) != NULL)
+ {
+ assert_true(sym_ref_i_tag(ref) == itag, "sym_ref_i_tag(ref) != itag");
+ ++itag;
+ }
+ assert_true(itag == num_refs + 1, "itag != num_refs + 1");
+
+ symbol_ref_walk_end(&walk);
+
+ /* clean up */
+ symbol_unset_ref(ref1, 1);
+ symbol_unset_ref(ref2, 1);
+
+ while ((symbol_table_ream(table, 1)) != NULL)
+ {
+ }
+}
+
+void
+test_ref_heavy(void)
+{
+ symbol_table table = NULL;
+ char name[] = "name";
+ char value[] = "value";
+ symbol sym = NULL;
+ symbol_ref ref = NULL;
+ struct symbol_ref walk;
+ const long int num_refs = 100000;
+ long int itag = 0;
+
+ printf("test_ref_heavy\n");
+ table = symbol_table_init_new(table, NULL, 0, 0, NULL, NULL);
+
+ /* add */
+ sym = symbol_lookup(table, name, 1);
+ symbol_set_value(sym, value);
+
+ /* create references, in reverse order so that walk in order */
+ for (itag = num_refs; itag > 0; --itag)
+ {
+ ref = symbol_set_ref(NULL, sym);
+ assert_true(ref != NULL, "ref == NULL");
+ sym_ref_set_i_tag(ref, itag);
+ assert_true(sym_ref_i_tag(ref) == itag, "sym_ref_i_tag(ref) != itag");
+ }
+
+ /* walk references */
+ itag = 1;
+ symbol_ref_walk_start(sym, &walk) ;
+ assert_true(sym->ref_list == &walk, "sym->ref_list != &walk");
+
+ while ((ref = symbol_ref_walk_step(&walk)) != NULL)
+ {
+ assert_true(sym_ref_i_tag(ref) == itag, "sym_ref_i_tag(ref) != itag");
+ ++itag;
+ symbol_unset_ref(ref, 1);
+ }
+ assert_true(itag == num_refs + 1, "itag != num_refs + 1");
+
+ symbol_ref_walk_end(&walk);
+
+ while ((symbol_table_ream(table, 1)) != NULL)
+ {
+ }
+}
+
+
+/*
+ *
+ * TODO
+ *
+
+symbol_table_set_parent
+symbol_table_get_parent
+symbol_hash_string
+symbol_hash_bytes
+symbol_table_set_value_call_back
+symbol_table_free
+symbol_unset_value
+symbol_select_cmp
+symbol_sort_cmp
+symbol_table_extract
+symbol_sort_cmp
+symbol_get_name_len
+symbol_get_table
+symbol_zero_ref
+symbol_dec_ref
+symbol_init_ref
+symbol_set_ref
+symbol_unset_ref
+symbol_unset_ref_free
+symbol_unset_ref_keep
+sym_ref_symbol
+sym_ref_value
+sym_ref_name
+sym_ref_name_len
+sym_ref_parent
+sym_ref_p_tag
+sym_ref_u_tag
+sym_ref_i_tag
+sym_ref_set_parent
+sym_ref_set_p_tag
+sym_ref_set_i_tag
+ */
diff --git a/tests/test-vector.c b/tests/test-vector.c
new file mode 100644
index 00000000..6aecfd6e
--- /dev/null
+++ b/tests/test-vector.c
@@ -0,0 +1,1209 @@
+#include <zebra.h>
+#include <vector.h>
+
+/* Vector torture tests
+ *
+ */
+
+/* prototypes */
+void assert_true(int result, const char * message);
+int main(int argc, char **argv);
+void test_vector_init(void);
+void test_vector_set_index(void);
+void test_vector_lookup(void);
+void test_vector_lookup_ensure(void);
+void test_vector_unset(void);
+void test_vector_set_index_null(void);
+void test_vector_copy(void);
+void test_vector_set(void);
+void test_vector_growth(void);
+
+/* GMCH interface */
+void test_vector_init_new(void);
+void test_vector_set_item(void);
+void test_vector_insert_item(void);
+void test_vector_insert_item_here(void);
+void test_vector_delete_item(void);
+void do_test_insert(const int rider);
+int sort_cmp(const void** a, const void** b);
+void test_vector_sort(void);
+void test_vector_bsearch(void);
+void test_vector_move_item_here(void);
+void do_test_move_item_here(const int rider);
+void test_vector_part_reverse(void);
+void test_vector_copy_here(void);
+void test_vector_move_here(void);
+void test_vector_copy_append(void);
+void test_vector_move_append(void);
+void test_vector_insert(void);
+void test_vector_delete(void);
+void test_vector_discard(void);
+void test_vector_sak(void);
+
+struct thread_master *master;
+
+/* objects to put in the vectors */
+static char s0[5];
+static char s1000[5];
+static char s2000[5];
+
+void
+assert_true(int result, const char * message)
+{
+ if (!result)
+ {
+ printf("Assert failed: %s\n", message);
+ }
+}
+
+int
+main(int argc, char **argv)
+{
+ strcpy(s0, "0");
+ strcpy(s1000, "1000");
+ strcpy(s2000, "2000");
+
+ test_vector_init();
+ test_vector_set_index();
+ test_vector_lookup();
+ test_vector_lookup_ensure();
+ test_vector_unset();
+ test_vector_set_index_null();
+ test_vector_copy();
+ test_vector_set();
+ test_vector_growth();
+
+ /* GMCH interface */
+ test_vector_init_new();
+ test_vector_set_item();
+ test_vector_insert_item();
+ test_vector_insert_item_here();
+ test_vector_delete_item();
+ test_vector_sort();
+ test_vector_bsearch();
+ test_vector_move_item_here();
+ test_vector_part_reverse();
+ test_vector_copy_here();
+ test_vector_move_here();
+ test_vector_copy_append();
+ test_vector_move_append();
+ test_vector_insert();
+ test_vector_delete();
+ test_vector_discard();
+ test_vector_sak();
+
+ return 0;
+}
+
+void
+test_vector_init(void)
+{
+ vector v = NULL;
+
+ printf("test_vector_init\n");
+ v = vector_init(10);
+
+ assert_true(v != NULL,
+ "v == NULL");
+ assert_true(vector_count(v) == 0,
+ "vector_count != 0");
+ assert_true(vector_active(v) == 0,
+ "vector_active != 0");
+ assert_true(vector_empty_slot(v) == 0,
+ "test_vector_init: vector_empty_slot != 0");
+
+ vector_free(v);
+}
+
+void
+test_vector_set_index(void)
+{
+ vector v = NULL;
+
+ printf("test_vector_set_index\n");
+ v = vector_init(0);
+
+ vector_set_index(v, 1000, s1000);
+ assert_true(vector_count(v) == 1,
+ "vector_count != 1");
+ assert_true(vector_active(v) == 1001,
+ "vector_active != 1001");
+ assert_true(vector_empty_slot(v) == 0,
+ "vector_empty_slot != 0");
+ assert_true(vector_slot(v,1000) == s1000,
+ "vector_slot != 1000");
+
+ vector_free(v);
+}
+
+void
+test_vector_lookup(void)
+{
+ vector v = NULL;
+
+ printf("test_vector_lookup\n");
+ v = vector_init(0);
+
+ vector_set_index(v, 1000, s1000);
+
+ assert_true(vector_lookup(v,1000) == s1000,
+ "vector_lookup != 1000");
+ assert_true(vector_lookup(v,1001) == NULL,
+ "vector_lookup != NULL");
+
+ vector_free(v);
+}
+
+void
+test_vector_lookup_ensure(void)
+{
+ vector v = NULL;
+
+ printf("test_vector_lookup_ensure\n");
+ v = vector_init(0);
+
+ vector_set_index(v, 1000, s1000);
+
+ assert_true(vector_lookup_ensure(v,1000) == s1000,
+ "vector_lookup_ensure != 1000");
+ assert_true(vector_lookup_ensure(v,1001) == NULL,
+ "vector_lookup_ensure != NULL");
+
+ vector_free(v);
+}
+
+void
+test_vector_unset(void)
+{
+ vector v = NULL;
+
+ printf("test_vector_unset\n");
+ v = vector_init(0);
+
+ vector_set_index(v, 1000, s1000);
+ vector_set_index(v, 2000, s2000);
+ assert_true(vector_count(v) == 2,
+ "vector_count != 2");
+ assert_true(vector_active(v) == 2001,
+ "vector_active != 2001");
+
+ vector_unset(v, 2000);
+ assert_true(vector_count(v) == 1,
+ "vector_count != 1");
+ assert_true(vector_active(v) == 1001,
+ "vector_active != 1001");
+
+ vector_free(v);
+}
+
+void
+test_vector_set_index_null(void)
+{
+ vector v = NULL;
+
+ printf("test_vector_set_index_null\n");
+ v = vector_init(0);
+
+ vector_set_index(v, 1000, s1000);
+ vector_set_index(v, 2000, s2000);
+ assert_true(vector_count(v) == 2,
+ "vector_count != 2");
+ assert_true(vector_active(v) == 2001,
+ "vector_active != 2001");
+
+ /* storing a NULL is not the same as vector_unset() */
+ vector_set_index(v, 2000, NULL);
+ assert_true(vector_count(v) == 1,
+ "vector_count != 1");
+ assert_true(vector_active(v) == 2001,
+ "vector_active != 2001");
+
+ /* GMCH change in semantics */
+ vector_unset(v, 1000);
+ assert_true(vector_count(v) == 0,
+ "vector_count != 0");
+ assert_true(vector_active(v) == 2001,
+ "vector_active != 2001 ignore post GMCH");
+ assert_true(vector_active(v) == 0,
+ "vector_active != 0 ignore pre GMCH");
+
+ vector_free(v);
+}
+
+void
+test_vector_copy(void)
+{
+ vector v1 = NULL;
+ vector v2 = NULL;
+ int i;
+ const int len = 100;
+ char buf[10];
+
+ printf("test_vector_copy\n");
+
+ /* to help debug objects are strings of their index */
+ v1 = vector_init(0);
+ for (i = 0; i < len; ++i)
+ {
+ sprintf(buf, "%d", i);
+ vector_set_index(v1, i, strdup(buf));
+ }
+
+ v2 = vector_copy(v1);
+ assert_true(v2 != NULL, "v2 == NULL");
+ assert_true(v1 != v2, "v1 == v2");
+
+ /* check contents are the same */
+ for (i = 0; i < len; ++i)
+ {
+ assert_true(vector_slot(v1, i) == vector_slot(v2, i), "v1 != v2");
+ }
+
+ /* free contents */
+ for (i = 0; i < len; ++i)
+ {
+ free(vector_slot(v1, i));
+ }
+
+ vector_free(v1);
+ vector_free(v2);
+}
+
+void
+test_vector_set(void)
+{
+ vector v = NULL;
+ int i;
+ const int len = 1000;
+ char buf[10];
+
+ printf("test_vector_set\n");
+
+ /* to help debug objects are strings of their index */
+ v = vector_init(0);
+ for (i = 0; i < len; ++i)
+ {
+ sprintf(buf, "%d", i);
+ vector_set_index(v, i, strdup(buf));
+ }
+
+ assert_true(vector_count(v) == (unsigned)len,
+ "vector_count != 1000");
+ assert_true(vector_active(v) == (unsigned)len,
+ "vector_active != 1000");
+
+ vector_set(v, s1000);
+ assert_true(vector_count(v) == len + 1,
+ "vector_count != 1001");
+ assert_true(vector_active(v) == len + 1,
+ "vector_active != 1001");
+ assert_true(vector_slot(v,1000) == s1000,
+ "vector_slot != 1000");
+
+ /* free contents */
+ for (i = 0; i < len; ++i)
+ {
+ free(vector_slot(v, i));
+ }
+
+ vector_free(v);
+}
+
+void
+test_vector_growth(void)
+{
+ vector v = NULL;
+ int i;
+ const int len = 150000;
+ char buf[10];
+
+ printf("test_vector_growth\n");
+
+ /* to help debug objects are strings of their index */
+ v = vector_init(0);
+ for (i = 0; i < len; ++i)
+ {
+ sprintf(buf, "%d", i);
+ vector_set_index(v, i, strdup(buf));
+ }
+
+ assert_true(vector_count(v) == (unsigned)len,
+ "vector_count != len");
+ assert_true(vector_active(v) == (unsigned)len,
+ "vector_active != len");
+
+ /* check contents are correct */
+ for (i = 0; i < len; ++i)
+ {
+ sprintf(buf, "%d", i);
+ assert_true(strcmp(vector_slot(v, i), buf) == 0, "vector_slot(v, i) != buf");
+ }
+
+ /* free contents */
+ for (i = 0; i < len; ++i)
+ {
+ free(vector_slot(v, i));
+ }
+
+ vector_free(v);
+}
+
+
+/* post GMCH interface */
+
+void
+test_vector_init_new(void)
+{
+ vector v = NULL;
+ void * item = NULL;
+
+ printf("test_vector_init_new\n");
+
+ v = vector_init_new(v, 0);
+ assert_true(v != NULL, "v == NULL");
+ assert_true(vector_is_empty(v), "!vector_is_empty(v)");
+ assert_true(vector_end(v) == 0, "vector_end(v) != 0");
+
+ vector_push_item(v, s0);
+ assert_true(vector_end(v) == 1, "vector_end(v) != 1");
+
+ item = vector_pop_item(v);
+ assert_true(item == s0, "item != s0");
+ assert_true(vector_is_empty(v), "!vector_is_empty(v)");
+ assert_true(vector_end(v) == 0, "vector_end(v) != 0");
+
+ vector_free(v);
+}
+
+void
+test_vector_set_item(void)
+{
+ vector v = NULL;
+ void * item = NULL;
+
+ printf("test_vector_set_item\n");
+
+ v = vector_init_new(v, 0);
+ vector_set_item(v, 0, s0);
+ vector_set_item(v, 1000, s1000);
+ vector_set_item(v, 2000, s2000);
+ assert_true(vector_end(v) == 2001, "vector_end(v) != 2001");
+
+ item = vector_get_item(v, 0);
+ assert_true(item == s0, "item != s0");
+ item = vector_get_item(v, 1000);
+ assert_true(item == s1000, "item != s1000");
+ item = vector_get_item(v, 2000);
+ assert_true(item == s2000, "item != s2000");
+
+ item = vector_get_first_item(v);
+ assert_true(item == s0, "item != s0");
+
+ item = vector_get_last_item(v);
+ assert_true(item == s2000, "item != s2000");
+
+ vector_free(v);
+}
+void
+test_vector_insert_item(void)
+{
+ do_test_insert(2);
+}
+
+void
+test_vector_insert_item_here(void)
+{
+ do_test_insert(-1);
+ do_test_insert(0);
+ do_test_insert(1);
+}
+
+void
+test_vector_delete_item(void)
+{
+ do_test_insert(3);
+}
+
+void
+do_test_insert(const int rider)
+{
+ vector v = NULL;
+ const vector_index len = 100;
+ const vector_index ins = 50;
+ vector_index i;
+ char buf[10];
+ vector_index check_end = len + 1;
+ vector_index check_ins = ins;
+ int check_shift = 1;
+
+ switch(rider)
+ {
+ case -1:
+ printf("test_vector_insert_here before\n");
+ break;
+ case 0:
+ printf("test_vector_insert_here at\n");
+ check_shift = 0;
+ check_end = len;
+ break;
+ case 1:
+ printf("test_vector_insert_here after\n");
+ check_ins++;
+ break;
+ case 2:
+ printf("test_vector_insert\n");
+ break;
+ case 3:
+ printf("test_vector_delete\n");
+ check_shift = -1;
+ check_end = len - 1;
+ break;
+ }
+
+ v = vector_init_new(v, 0);
+
+ for (i = 0; i < len; ++i)
+ {
+ sprintf(buf, "%d", i);
+ vector_set_item(v, i, strdup(buf));
+ }
+
+ switch(rider)
+ {
+ case -1:
+ case 0:
+ case 1:
+ vector_insert_item_here(v, ins, rider, strdup(s1000));
+ break;
+ case 2:
+ vector_insert_item(v, ins, strdup(s1000));
+ break;
+ case 3:
+ free(vector_delete_item(v, ins));
+ break;
+ }
+
+ assert_true(vector_end(v) == check_end, "vector_end(v) != check_end");
+
+ /* check contents are correct */
+ for (i = 0; i < check_ins; ++i)
+ {
+ sprintf(buf, "%d", i);
+ assert_true(strcmp(vector_get_item(v, i), buf) == 0,
+ "vector_get_item(v, i) != buf");
+ }
+
+ if (rider != 3)
+ {
+ assert_true(strcmp(vector_get_item(v, check_ins), s1000) == 0,
+ "vector_get_item(v, check_ins) != s1000");
+ }
+
+ for (i = check_ins + 1; i < check_end; ++i)
+ {
+ sprintf(buf, "%d", i - check_shift);
+ assert_true(strcmp(vector_get_item(v, i), buf) == 0, "vector_get_item(v, i) != buf");
+ }
+
+ /* free contents */
+ for (i = 0; i < vector_end(v); ++i)
+ {
+ free(vector_slot(v, i));
+ }
+
+ vector_free(v);
+}
+
+void
+test_vector_sort(void)
+{
+ vector v = NULL;
+ int i;
+ const int len = 100;
+ char buf[10];
+
+ printf("test_vector_sort\n");
+
+ v = vector_init(0);
+
+ vector_sort(v, sort_cmp); /* null sort */
+
+ /* initialize backwards, using width so that lexical = numerical order */
+ for (i = 0; i < len; ++i)
+ {
+ sprintf(buf, "%9d", i);
+ vector_set_index(v, len - i - 1, strdup(buf));
+ }
+
+ vector_sort(v, sort_cmp);
+
+ /* check contents are correct */
+ for (i = 0; i < len; ++i)
+ {
+ sprintf(buf, "%9d", i);
+ assert_true(strcmp(vector_slot(v, i), buf) == 0, "vector_slot(v, i) != buf");
+ }
+
+ /* free contents */
+ for (i = 0; i < len; ++i)
+ {
+ free(vector_slot(v, i));
+ }
+
+ vector_free(v);
+}
+
+int
+sort_cmp(const void** a, const void** b)
+{
+ return strcmp(*a, *b);
+}
+
+void
+test_vector_bsearch(void)
+{
+ vector v = NULL;
+ int i;
+ const int len = 2000;
+ char buf[20];
+ char target[20];
+ vector_index target_index = 0;
+ int result;
+ vector_index index;
+
+ printf("test_vector_bsearch\n");
+
+ sprintf(target, "%9u", target_index);
+ v = vector_init(0);
+
+ index = vector_bsearch(v, sort_cmp, target, &result); /* null search */
+ assert_true(index == 0, "index != 0");
+ assert_true(result == -1, "result != -1");
+
+ /* initialize, using width so that lexical = numerical order */
+ for (i = 0; i < len; ++i)
+ {
+ sprintf(buf, "%9d", i);
+ vector_set_index(v, i, strdup(buf));
+ }
+
+ for (target_index = 0; target_index < (unsigned)len; ++target_index)
+ {
+ sprintf(target, "%9u", target_index);
+ index = vector_bsearch(v, sort_cmp, target, &result);
+ assert_true(index == target_index, "index != target_index");
+ assert_true(result == 0, "result != 0");
+ assert_true(strcmp(vector_get_item(v, index), target) == 0,
+ "strcmp(vector_get_item(v, index), target)) != 0");
+ }
+
+ /* free contents */
+ for (i = 0; i < len; ++i)
+ {
+ free(vector_slot(v, i));
+ }
+
+ vector_free(v);
+}
+
+void
+test_vector_move_item_here(void)
+{
+ do_test_move_item_here(-1);
+ do_test_move_item_here(0);
+ do_test_move_item_here(1);
+}
+
+void
+do_test_move_item_here(const int rider)
+{
+ vector v = NULL;
+ const vector_index len = 100;
+ const vector_index ins = 50;
+ const vector_index src = 70;
+ vector_index i;
+ char buf[10];
+ vector_index check_dest = 0;
+ vector_index check_src = 0;
+ vector_index check_end = 0;
+ int check_shift = 0;
+ p_vector_item dest_item = NULL;
+
+
+ switch(rider)
+ {
+ case -1:
+ printf("test_vector_move_here before\n");
+ check_dest = ins;
+ check_src = src;
+ check_end = len;
+ check_shift = 1;
+ break;
+ case 0:
+ printf("test_vector_move_here at\n");
+ check_dest = ins;
+ check_src = src - 1;
+ check_end = len - 1;
+ check_shift = 0;
+ break;
+ case 1:
+ printf("test_vector_move_here after\n");
+ check_dest = ins + 1;
+ check_src = src;
+ check_end = len;
+ check_shift = 1;
+ break;
+ }
+
+ v = vector_init_new(v, 0);
+
+ for (i = 0; i < len; ++i)
+ {
+ sprintf(buf, "%u", i);
+ vector_set_item(v, i, strdup(buf));
+ }
+
+ dest_item = vector_get_item(v, ins); /* item to free if rider == 0 */
+
+ vector_move_item_here(v, ins, rider, src);
+ assert_true(vector_end(v) == check_end, "vector_end(v) != check_end");
+
+ /* check contents are correct */
+
+ /* from start to insertion point */
+ for (i = 0; i < check_dest - 1; ++i)
+ {
+ sprintf(buf, "%u", i);
+ assert_true(strcmp(vector_get_item(v, i), buf) == 0,
+ "vector_get_item(v, i) != buf");
+ }
+
+ /* at insertion point */
+ sprintf(buf, "%u", src);
+ assert_true(strcmp(vector_get_item(v, check_dest), buf) == 0,
+ "vector_get_item(v, check_dest) != buf");
+
+ /* from insertion point to src */
+ for (i = check_dest + 1; i <= check_src; ++i)
+ {
+ sprintf(buf, "%u", i - check_shift);
+ assert_true(strcmp(vector_get_item(v, i), buf) == 0, "vector_get_item(v, i) != buf");
+ }
+
+ /* from src to end */
+ for (i = check_src + 1; i < check_end; ++i)
+ {
+ sprintf(buf, "%u", i - (check_shift - 1));
+ assert_true(strcmp(vector_get_item(v, i), buf) == 0, "vector_get_item(v, i) != buf");
+ }
+
+ /* free contents */
+ for (i = 0; i < vector_end(v); ++i)
+ {
+ free(vector_slot(v, i));
+ }
+
+ if (rider == 0)
+ {
+ free(dest_item);
+ }
+
+ vector_free(v);
+}
+
+void
+test_vector_part_reverse(void)
+{
+ vector v = NULL;
+ const vector_index len = 100;
+ const vector_index rstart = 50;
+ const vector_index rstop = 70;
+ vector_index i;
+ char buf[10];
+
+ printf("test_vector_part_reverse\n");
+
+ v = vector_init_new(v, 0);
+
+ for (i = 0; i < len; ++i)
+ {
+ sprintf(buf, "%u", i);
+ vector_set_item(v, i, strdup(buf));
+ }
+
+ vector_part_reverse(v, rstart, rstop - rstart);
+ assert_true(vector_end(v) == len, "vector_end(v) != len");
+
+ /* check contents are correct */
+
+ /* before reversed section */
+ for (i = 0; i < rstart - 1; ++i)
+ {
+ sprintf(buf, "%u", i);
+ assert_true(strcmp(vector_get_item(v, i), buf) == 0,
+ "before reversed vector_get_item(v, i) != buf");
+ }
+
+ /* reversed section */
+ for (i = rstart; i < rstop; ++i)
+ {
+ sprintf(buf, "%u", rstop - (i - rstart + 1));
+ assert_true(strcmp(vector_get_item(v, i), buf) == 0,
+ "reversed vector_get_item(v, i) != buf");
+ }
+
+ /* after reversed section */
+ for (i = rstop; i < len; ++i)
+ {
+ sprintf(buf, "%u", i);
+ assert_true(strcmp(vector_get_item(v, i), buf) == 0,
+ "after reversed vector_get_item(v, i) != buf");
+ }
+
+ /* free contents */
+ for (i = 0; i < vector_end(v); ++i)
+ {
+ free(vector_slot(v, i));
+ }
+
+ vector_free(v);
+}
+
+void
+test_vector_copy_here(void)
+{
+ vector v1 = NULL;
+ vector v2 = NULL;
+ vector_index i;
+ const vector_index len = 100;
+ char buf[10];
+
+ printf("test_vector_copy_here\n");
+
+ /* to help debug objects are strings of their index */
+ v1 = vector_init(0);
+ for (i = 0; i < len; ++i)
+ {
+ sprintf(buf, "%u", i);
+ vector_set_index(v1, i, strdup(buf));
+ }
+
+ v2 = vector_copy_here(v2, v1);
+ assert_true(v2 != NULL, "v2 == NULL");
+ assert_true(v1 != v2, "v1 == v2");
+
+ /* check contents are the same */
+ for (i = 0; i < len; ++i)
+ {
+ assert_true(vector_get_item(v1, i) == vector_get_item(v2, i), "v1 != v2");
+ }
+
+ /* free contents */
+ for (i = 0; i < len; ++i)
+ {
+ free(vector_get_item(v1, i));
+ }
+
+ vector_free(v1);
+ vector_free(v2);
+}
+
+void
+test_vector_move_here(void)
+{
+ vector v1 = NULL;
+ vector v2 = NULL;
+ vector_index i;
+ const vector_index len = 100;
+ char buf[10];
+
+ printf("test_vector_move_here\n");
+
+ /* to help debug objects are strings of their index */
+ v1 = vector_init(0);
+ for (i = 0; i < len; ++i)
+ {
+ sprintf(buf, "%u", i);
+ vector_set_index(v1, i, strdup(buf));
+ }
+
+ v2 = vector_move_here(v2, v1);
+ assert_true(v2 != NULL, "v2 == NULL");
+ assert_true(v1 != v2, "v1 == v2");
+ assert_true(vector_end(v1) == 0, "vector_end(v1) != 0");
+
+ /* check contents are the same */
+ for (i = 0; i < len; ++i)
+ {
+ sprintf(buf, "%u", i);
+ assert_true(strcmp(vector_get_item(v2, i), buf) == 0,
+ "vector_get_item(v2, i) != buf");
+ }
+
+ /* free contents */
+ for (i = 0; i < len; ++i)
+ {
+ free(vector_get_item(v2, i));
+ }
+
+ vector_free(v1);
+ vector_free(v2);
+}
+
+void
+test_vector_copy_append(void)
+{
+ vector v1 = NULL;
+ vector v2 = NULL;
+ vector_index i;
+ const vector_index len = 100;
+ char buf[10];
+
+ printf("test_vector_copy_append\n");
+
+ /* to help debug objects are strings of their index */
+ v2 = vector_init(0);
+ for (i = 0; i < len; ++i)
+ {
+ sprintf(buf, "%u", i);
+ vector_set_index(v2, i, strdup(buf));
+ }
+
+ v1 = vector_init(0);
+ for (i = len; i < 2 * len; ++i)
+ {
+ sprintf(buf, "%u", i);
+ vector_set_index(v1, i - len, strdup(buf));
+ }
+
+ v2 = vector_copy_append(v2, v1);
+ assert_true(v2 != NULL, "v2 == NULL");
+ assert_true(v1 != v2, "v1 == v2");
+ assert_true(vector_end(v2) == 2 * len, "vector_end(v2) != 2 * len");
+
+ /* check contents */
+ for (i = 0; i < 2 * len; ++i)
+ {
+ sprintf(buf, "%u", i);
+ assert_true(strcmp(vector_get_item(v2, i), buf) == 0,
+ "vector_get_item(v2, i) != buf");
+ }
+
+ /* free contents */
+ for (i = 0; i < 2 * len; ++i)
+ {
+ free(vector_get_item(v2, i));
+ }
+
+ vector_free(v1);
+ vector_free(v2);
+}
+
+void
+test_vector_move_append(void)
+{
+ vector v1 = NULL;
+ vector v2 = NULL;
+ vector_index i;
+ const vector_index len = 100;
+ char buf[10];
+
+ printf("test_vector_move_append\n");
+
+ /* to help debug objects are strings of their index */
+ v2 = vector_init(0);
+ for (i = 0; i < len; ++i)
+ {
+ sprintf(buf, "%u", i);
+ vector_set_index(v2, i, strdup(buf));
+ }
+
+ v1 = vector_init(0);
+ for (i = len; i < 2 * len; ++i)
+ {
+ sprintf(buf, "%u", i);
+ vector_set_index(v1, i - len, strdup(buf));
+ }
+
+ v2 = vector_move_append(v2, v1);
+ assert_true(v2 != NULL, "v2 == NULL");
+ assert_true(v1 != v2, "v1 == v2");
+ assert_true(vector_end(v2) == 2 * len, "vector_end(v2) != 2 * len");
+ assert_true(vector_end(v1) == 0, "vector_end(v1) != 0");
+
+ /* check contents */
+ for (i = 0; i < 2 * len; ++i)
+ {
+ sprintf(buf, "%u", i);
+ assert_true(strcmp(vector_get_item(v2, i), buf) == 0,
+ "vector_get_item(v2, i) != buf");
+ }
+
+ /* free contents */
+ for (i = 0; i < 2 * len; ++i)
+ {
+ free(vector_get_item(v2, i));
+ }
+
+ vector_free(v1);
+ vector_free(v2);
+}
+
+void
+test_vector_insert(void)
+{
+ vector v = NULL;
+ vector_index i;
+ const vector_index len = 100;
+ const vector_index istart = 50;
+ const vector_index istop = 70;
+ char buf[10];
+
+ printf("test_vector_insert\n");
+
+ /* to help debug objects are strings of their index */
+
+ v = vector_init(0);
+ for (i = 0; i < len; ++i)
+ {
+ sprintf(buf, "%u", i);
+ vector_set_index(v, i, strdup(buf));
+ }
+
+ vector_insert(v, istart, istop - istart);
+ assert_true(vector_end(v) == len + (istop - istart),
+ "vector_end(v) != len + (istop - istart)");
+
+ /* check contents */
+ for (i = 0; i < istart; ++i)
+ {
+ sprintf(buf, "%u", i);
+ assert_true(strcmp(vector_get_item(v, i), buf) == 0,
+ "vector_get_item(v, i) != buf");
+ }
+
+ for (i = istart + 1; i < istop; ++i)
+ {
+ assert_true(vector_get_item(v, i) == NULL,
+ "vector_get_item(v, i) != NULL");
+ }
+
+ for (i = istop; i < len + (istop - istart); ++i)
+ {
+ sprintf(buf, "%u", i - (istop - istart));
+ assert_true(strcmp(vector_get_item(v, i), buf) == 0,
+ "vector_get_item(v, i) != buf");
+ }
+
+ /* free contents */
+ for (i = 0; i < len + (istop - istart); ++i)
+ {
+ free(vector_get_item(v, i));
+ }
+
+ vector_free(v);
+}
+
+void
+test_vector_delete(void)
+{
+ vector v = NULL;
+ vector_index i;
+ const vector_index len = 100;
+ const vector_index dstart = 50;
+ const vector_index dstop = 70;
+ char buf[10];
+
+ printf("test_vector_delete\n");
+
+ /* to help debug objects are strings of their index */
+
+ v = vector_init(0);
+ for (i = 0; i < len; ++i)
+ {
+ if (i < dstart || i >= dstop)
+ {
+ sprintf(buf, "%u", i);
+ vector_set_index(v, i, strdup(buf));
+ }
+ else
+ {
+ vector_set_index(v, i, s0);
+ }
+ }
+
+ vector_delete(v, dstart, dstop - dstart);
+ assert_true(vector_end(v) == len - (dstop - dstart),
+ "vector_end(v) != len - (dstop - dstart)");
+
+ /* check contents */
+ for (i = 0; i < dstart; ++i)
+ {
+ sprintf(buf, "%u", i);
+ assert_true(strcmp(vector_get_item(v, i), buf) == 0,
+ "vector_get_item(v, i) != buf");
+ }
+
+ for (i = dstart; i < len - (dstop - dstart); ++i)
+ {
+ sprintf(buf, "%u", i + (dstop - dstart));
+ assert_true(strcmp(vector_get_item(v, i), buf) == 0,
+ "vector_get_item(v, i) != buf");
+ }
+
+ /* free contents */
+ for (i = 0; i < len - (dstop - dstart); ++i)
+ {
+ free(vector_get_item(v, i));
+ }
+
+ vector_free(v);
+}
+
+void
+test_vector_discard(void)
+{
+ vector v = NULL;
+ vector_index i;
+ const vector_index len = 100;
+ const vector_index dstart = 50;
+ char buf[10];
+
+ printf("test_vector_discard\n");
+
+ /* to help debug objects are strings of their index */
+
+ v = vector_init(0);
+ for (i = 0; i < len; ++i)
+ {
+ if (i < dstart)
+ {
+ sprintf(buf, "%u", i);
+ vector_set_index(v, i, strdup(buf));
+ }
+ else
+ {
+ vector_set_index(v, i, s0);
+ }
+ }
+
+ vector_discard(v, dstart);
+ assert_true(vector_end(v) == dstart,
+ "vector_end(v) != dstart");
+
+ /* check contents */
+ for (i = 0; i < dstart; ++i)
+ {
+ sprintf(buf, "%u", i);
+ assert_true(strcmp(vector_get_item(v, i), buf) == 0,
+ "vector_get_item(v, i) != buf");
+ }
+
+ /* free contents */
+ for (i = 0; i < dstart; ++i)
+ {
+ free(vector_get_item(v, i));
+ }
+
+ vector_free(v);
+}
+
+void
+test_vector_sak(void)
+{
+ vector v1 = NULL;
+ vector v2 = NULL;
+ vector v3 = NULL;
+ vector_index i;
+ const vector_index len = 100;
+ const vector_index sstart = 60;
+ const vector_index sstop = 70;
+ const vector_index dstart = 40;
+ const vector_index dstop = 50;
+ char buf[10];
+
+ printf("test_vector_sak\n");
+
+ /* to help debug objects are strings of their index */
+
+ v2 = vector_init(0);
+ v3 = vector_init(0);
+ for (i = 0; i < len; ++i)
+ {
+ sprintf(buf, "%u", i);
+ vector_set_index(v2, i, strdup(buf));
+ vector_set_index(v3, i, strdup(buf));
+ }
+
+ v1 = vector_sak(1, v1, v2, dstart, dstop - dstart,
+ v3, sstart, sstop - sstart, 0);
+ assert_true(v1 != NULL, "v1 == NULL");
+
+ assert_true(vector_end(v1) == (dstop - dstart),
+ "vector_end(v1) != (dstop - dstart)");
+ assert_true(vector_end(v2) == len,
+ "vector_end(v2) != len");
+ assert_true(vector_end(v3) == len,
+ "vector_end(v3) != len");
+
+ /* check contents v1 */
+ for (i = 0; i < dstop - dstart; ++i)
+ {
+ sprintf(buf, "%u", i + dstart);
+ assert_true(vector_get_item(v1, i) != NULL,
+ "vector_get_item(v1, i) == NULL");
+ assert_true(strcmp(vector_get_item(v1, i), buf) == 0,
+ "vector_get_item(v1, i) != buf");
+ }
+
+ /* check contents v2 */
+ for (i = 0; i < dstart; ++i)
+ {
+ sprintf(buf, "%u", i);
+ assert_true(strcmp(vector_get_item(v2, i), buf) == 0,
+ "vector_get_item(v2, i) != buf");
+ }
+ for (i = dstart; i < dstop; ++i)
+ {
+ sprintf(buf, "%u", i - dstart + sstart);
+ assert_true(strcmp(vector_get_item(v2, i), buf) == 0,
+ "vector_get_item(v2, i) != buf");
+ }
+ for (i = dstop; i < len; ++i)
+ {
+ sprintf(buf, "%u", i);
+ assert_true(strcmp(vector_get_item(v2, i), buf) == 0,
+ "vector_get_item(v2, i) != buf");
+ }
+
+ /* check contents v3 */
+ for (i = 0; i < len; ++i)
+ {
+ sprintf(buf, "%u", i);
+ assert_true(strcmp(vector_get_item(v3, i), buf) == 0,
+ "vector_get_item(v3, i) != buf");
+ }
+
+ /* free contents */
+ for (i = 0; i < len; ++i)
+ {
+ free(vector_get_item(v3, i));
+ }
+
+ vector_free(v1);
+ vector_free(v2);
+ vector_free(v3);
+}
+/*
+ * TODO
+ *
+
+vector_re_init
+vector_reset
+vector_ream
+vector_sak
+vector_chop
+vector_decant
+vector_extend_by_1
+
+*/