summaryrefslogtreecommitdiffstats
path: root/clib/cunit
diff options
context:
space:
mode:
authorBrad Bishop <bradleyb@us.ibm.com>2014-06-30 22:10:16 -0500
committerPatrick Williams <iawillia@us.ibm.com>2014-07-02 22:49:29 -0500
commitbf4630076762d9c20c16c80c1c791f352b046dd1 (patch)
treeefc67bad010a28fd1abf5aeeefda2a969514fd97 /clib/cunit
downloadffs-bf4630076762d9c20c16c80c1c791f352b046dd1.tar.gz
ffs-bf4630076762d9c20c16c80c1c791f352b046dd1.zip
Port FFS tools over from Building Block repository.
Diffstat (limited to 'clib/cunit')
-rw-r--r--clib/cunit/clib.c49
-rw-r--r--clib/cunit/ecc.c91
-rw-r--r--clib/cunit/ecc.h19
-rw-r--r--clib/cunit/map.c301
-rw-r--r--clib/cunit/map.h19
-rw-r--r--clib/cunit/slab.c63
-rw-r--r--clib/cunit/slab.h19
-rw-r--r--clib/cunit/splay.c384
-rw-r--r--clib/cunit/splay.h19
-rw-r--r--clib/cunit/tree.c398
-rw-r--r--clib/cunit/tree.h19
-rw-r--r--clib/cunit/vector.c169
-rw-r--r--clib/cunit/vector.h19
13 files changed, 1569 insertions, 0 deletions
diff --git a/clib/cunit/clib.c b/clib/cunit/clib.c
new file mode 100644
index 0000000..e9f1053
--- /dev/null
+++ b/clib/cunit/clib.c
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) International Business Machines Corp., 2014
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <CUnit/Basic.h>
+
+#include "vector.h"
+#include "slab.h"
+#include "tree.h"
+#include "splay.h"
+#include "map.h"
+#include "ecc.h"
+
+int main(void) {
+ /* initialize the CUnit test registry */
+ if (CUE_SUCCESS != CU_initialize_registry())
+ return CU_get_error();
+
+ vector_test();
+ slab_test();
+ tree_test();
+ splay_test();
+ map_test();
+ ecc_test();
+
+ /* Run all tests using the CUnit Basic interface */
+ CU_basic_set_mode(CU_BRM_VERBOSE);
+ CU_basic_run_tests();
+ CU_cleanup_registry();
+
+ return CU_get_error();
+}
diff --git a/clib/cunit/ecc.c b/clib/cunit/ecc.c
new file mode 100644
index 0000000..3ae6303
--- /dev/null
+++ b/clib/cunit/ecc.c
@@ -0,0 +1,91 @@
+/*
+ * Copyright (c) International Business Machines Corp., 2014
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <clib/exception.h>
+#include <clib/assert.h>
+#include <clib/type.h>
+
+#include <clib/ecc.h>
+#include <clib/misc.h>
+
+#include <CUnit/Basic.h>
+
+#define COUNT 10000
+#define SEED 41
+
+static int init_ecc(void) {
+ return 0;
+}
+
+static int clean_ecc(void) {
+ return 0;
+}
+
+static void ecc_1(void) {
+ int size[] = {7, 8, 16, 1024+16, 4096+32, 8*1024*4+64, 0};
+
+ for (int * s = size; *s != 0; s++) {
+ unsigned char in[*s];
+ unsigned char out[*s + (*s / 8)];
+
+ ssize_t in_sz = sizeof in;
+ ssize_t out_sz = sizeof out;
+
+ memset(in, 0, in_sz);
+ memset(out, 0, out_sz);
+
+ FILE * f = fopen("/dev/urandom", "r");
+ CU_ASSERT_FATAL(f != NULL);
+ CU_ASSERT_FATAL(fread(in, in_sz, 1, f) == 1);
+ fclose(f);
+
+ ssize_t rc = sfc_ecc_inject(out, out_sz, in, in_sz);
+ if ((*s % 8) != 0) {
+ CU_ASSERT(rc == -1);
+ } else {
+ CU_ASSERT(rc == in_sz + (in_sz / 8));
+ }
+
+ unsigned char cmp[*s];
+ ssize_t cmp_sz = sizeof cmp;
+ memset(cmp, 0, cmp_sz);
+
+ rc = sfc_ecc_remove(cmp, cmp_sz, out, out_sz);
+ if ((out_sz % 9) != 0) {
+ CU_ASSERT(rc == -1);
+ } else {
+ CU_ASSERT(rc == in_sz)
+ CU_ASSERT_FATAL(memcmp(in, cmp, in_sz) == 0);
+#ifdef DEBUG
+ dump_memory(stdout, 0, in, in_sz);
+ dump_memory(stdout, 0, cmp, cmp_sz);
+#endif
+ }
+ }
+}
+
+void ecc_test(void) {
+ CU_pSuite suite = CU_add_suite("ecc", init_ecc, clean_ecc);
+ if (NULL == suite)
+ return;
+
+ if (CU_add_test(suite, "test of --> ecc_1", ecc_1) == NULL) return;
+}
diff --git a/clib/cunit/ecc.h b/clib/cunit/ecc.h
new file mode 100644
index 0000000..0eec8da
--- /dev/null
+++ b/clib/cunit/ecc.h
@@ -0,0 +1,19 @@
+/*
+ * Copyright (c) International Business Machines Corp., 2014
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+void ecc_test(void);
diff --git a/clib/cunit/map.c b/clib/cunit/map.c
new file mode 100644
index 0000000..3761b1a
--- /dev/null
+++ b/clib/cunit/map.c
@@ -0,0 +1,301 @@
+/*
+ * Copyright (c) International Business Machines Corp., 2014
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <clib/libclib.h>
+
+#include <clib/slab.h>
+#include <clib/map.h>
+#include <clib/map_iter.h>
+
+#include <CUnit/Basic.h>
+
+#define COUNT 20000
+#define SEED 22
+
+slab_t slab;
+
+typedef struct {
+ map_node_t node;
+ int i;
+ float f;
+} data_t;
+
+static int init_map(void) {
+ slab_init(&slab, "my_slab", sizeof(data_t), 4096);
+ return 0;
+}
+
+static int clean_map(void) {
+ slab_delete(&slab);
+ return 0;
+}
+
+static void __insert(map_t * t, int i) {
+ data_t * d = (data_t *)slab_alloc(&slab);
+
+ i %= INT32_MAX;
+
+ d->i = i;
+ d->f = (float)i;
+ map_node_init(&d->node, (const void *)(intptr_t)(d->i));
+
+ if (map_insert(t, &d->node) < 0) {
+ err_t * err = err_get();
+ fprintf(stderr, "%s(%d): %.*s\n",
+ err_file(err), err_line(err), err_size(err),
+ (const char *)err_data(err));
+ }
+}
+
+static data_t * __remove(map_t * t, int i) {
+
+ i %= INT32_MAX;
+
+ map_node_t * n = map_find(t, (const void *)i);
+ if (n == NULL) map_dump(t, stdout);
+ CU_ASSERT_PTR_NOT_NULL_FATAL(n);
+
+ map_remove(t, n);
+
+ data_t * d = container_of(n, data_t, node);
+ CU_ASSERT_PTR_NOT_NULL_FATAL(n);
+
+ if (0 <= i)
+ CU_ASSERT((int)d->node.key == i);
+
+ return d;
+}
+
+static int compare(const void * v1, const void * v2) {
+ const int i1 = (const int)v1, i2 = (const int)v2;
+ return i1 - i2;
+}
+
+static void map_1(void) {
+ map_t t;
+ map_init(&t, compare);
+
+ CU_ASSERT(map_min(&t) == NULL);
+ CU_ASSERT(map_max(&t) == NULL);
+ CU_ASSERT(map_empty(&t) == true);
+ CU_ASSERT(map_size(&t) == 0);
+}
+
+static void map_2(void) {
+ map_t t;
+ map_init(&t, compare);
+
+ CU_ASSERT(map_empty(&t) == true);
+ CU_ASSERT(map_size(&t) == 0);
+
+ for (int i=1; i<=COUNT; i++)
+ __insert(&t, i);
+
+ CU_ASSERT(map_empty(&t) == false);
+ CU_ASSERT(map_size(&t) == COUNT);
+
+ for (int i=1; i<=COUNT; i++) {
+ CU_ASSERT(i == (int)map_min(&t)->key);
+ CU_ASSERT(COUNT == (int)map_max(&t)->key);
+ __remove(&t, (int)map_min(&t)->key);
+ CU_ASSERT(map_size(&t) + i == COUNT);
+ }
+
+ CU_ASSERT(map_empty(&t) == true);
+ CU_ASSERT(map_size(&t) == 0);
+
+ for (int i=1; i<=COUNT; i++)
+ __insert(&t, i);
+
+ CU_ASSERT(map_empty(&t) == false);
+ CU_ASSERT(map_size(&t) == COUNT);
+
+ for (int i=1; i<=COUNT; i++) {
+ CU_ASSERT(1 == (int)map_min(&t)->key);
+ CU_ASSERT(COUNT - i + 1 == (int)map_max(&t)->key);
+ __remove(&t, (int)map_max(&t)->key);
+ CU_ASSERT(map_size(&t) + i == COUNT);
+ }
+
+ CU_ASSERT(map_empty(&t) == true);
+ CU_ASSERT(map_size(&t) == 0);
+}
+
+static void map_3(void) {
+ map_t t;
+ map_init(&t, compare);
+
+ CU_ASSERT(map_empty(&t) == true);
+ CU_ASSERT(map_size(&t) == 0);
+
+ for (int i=1; i<=COUNT; i++)
+ __insert(&t, COUNT - i + 1);
+
+ CU_ASSERT(map_empty(&t) == false);
+ CU_ASSERT(map_size(&t) == COUNT);
+
+ for (int i=1; i<=COUNT; i++) {
+ CU_ASSERT(1 == (int)map_min(&t)->key);
+ CU_ASSERT(COUNT - i + 1 == (int)map_max(&t)->key);
+ __remove(&t, (int)map_max(&t)->key);
+ CU_ASSERT(map_size(&t) + i == COUNT);
+ }
+
+ CU_ASSERT(map_empty(&t) == true);
+ CU_ASSERT(map_size(&t) == 0);
+
+ for (int i=1; i<=COUNT; i++)
+ __insert(&t, COUNT - i + 1);
+
+ CU_ASSERT(map_empty(&t) == false);
+ CU_ASSERT(map_size(&t) == COUNT);
+
+ for (int i=1; i<=COUNT; i++) {
+ CU_ASSERT(i == (int)map_min(&t)->key);
+ CU_ASSERT(COUNT == (int)map_max(&t)->key);
+ __remove(&t, (int)map_min(&t)->key);
+ CU_ASSERT(map_size(&t) + i == COUNT);
+ }
+
+ CU_ASSERT(map_empty(&t) == true);
+ CU_ASSERT(map_size(&t) == 0);
+}
+
+static void map_4(void) {
+ map_t t;
+ map_init(&t, compare);
+
+ CU_ASSERT(map_empty(&t) == true);
+ CU_ASSERT(map_size(&t) == 0);
+
+ srandom(SEED);
+ for (int i=1; i<=COUNT; i++)
+ __insert(&t, (int)random());
+
+ CU_ASSERT(map_empty(&t) == false);
+ CU_ASSERT(map_size(&t) == COUNT);
+
+ for (int i=1; i<=COUNT; i++) {
+ __remove(&t, (int)map_min(&t)->key);
+ CU_ASSERT(map_size(&t) + i == COUNT);
+ }
+
+ CU_ASSERT(map_empty(&t) == true);
+ CU_ASSERT(map_size(&t) == 0);
+
+ srandom(SEED);
+ for (int i=1; i<=COUNT; i++)
+ __insert(&t, (int)random());
+
+ CU_ASSERT(map_empty(&t) == false);
+ CU_ASSERT(map_size(&t) == COUNT);
+
+ for (int i=1; i<=COUNT; i++) {
+ __remove(&t, (int)map_max(&t)->key);
+ CU_ASSERT(map_size(&t) + i == COUNT);
+ }
+
+ CU_ASSERT(map_empty(&t) == true);
+ CU_ASSERT(map_size(&t) == 0);
+
+ srandom(SEED);
+ for (int i=1; i<=COUNT; i++)
+ __insert(&t, (int)random());
+
+ CU_ASSERT(map_empty(&t) == false);
+ CU_ASSERT(map_size(&t) == COUNT);
+
+ srandom(SEED);
+ for (int i=1; i<=COUNT; i++) {
+ __remove(&t, (int)random());
+ CU_ASSERT(map_size(&t) + i == COUNT);
+ }
+
+ CU_ASSERT(map_empty(&t) == true);
+ CU_ASSERT(map_size(&t) == 0);
+}
+
+static void map_5(void) {
+ map_t t;
+ map_init(&t, compare);
+
+ CU_ASSERT(map_empty(&t) == true);
+ CU_ASSERT(map_size(&t) == 0);
+
+ srandom(SEED);
+ for (int i=1; i<=COUNT; i++)
+ __insert(&t, (int)random());
+
+ CU_ASSERT(map_empty(&t) == false);
+ CU_ASSERT(map_size(&t) == COUNT);
+
+ data_t * d;
+ int key = 0;
+
+ map_iter_t it;
+ map_iter_init(&it, &t, MI_FLAG_FWD);
+ map_for_each(&it, d, node) {
+ CU_ASSERT(key < (int)d->node.key);
+ key = (int)d->node.key;
+ }
+
+ key = INT32_MAX;
+ map_iter_init(&it, &t, MI_FLAG_BWD);
+ map_for_each(&it, d, node) {
+ CU_ASSERT((int)d->node.key < key);
+ key = (int)d->node.key;
+ }
+}
+
+static void map_6(void) {
+ map_t t;
+ map_init(&t, compare);
+
+ CU_ASSERT(map_empty(&t) == true);
+ CU_ASSERT(map_size(&t) == 0);
+
+ srandom(SEED);
+ for (int i=1; i<=COUNT; i++)
+ __insert(&t, (int)random());
+
+ CU_ASSERT(map_empty(&t) == false);
+ CU_ASSERT(map_size(&t) == COUNT);
+
+ srandom(SEED);
+ for (int i=1; i<=COUNT; i++) {
+ map_node_t * node = map_find(&t, (const void *)random());
+ CU_ASSERT_PTR_NOT_NULL_FATAL(node);
+ }
+}
+
+void map_test(void) {
+ CU_pSuite suite = CU_add_suite("map", init_map, clean_map);
+ if (NULL == suite)
+ return;
+
+ if (CU_add_test(suite, "test of --> map_1", map_1) == NULL) return;
+ if (CU_add_test(suite, "test of --> map_2", map_2) == NULL) return;
+ if (CU_add_test(suite, "test of --> map_3", map_3) == NULL) return;
+ if (CU_add_test(suite, "test of --> map_4", map_4) == NULL) return;
+ if (CU_add_test(suite, "test of --> map_5", map_5) == NULL) return;
+ if (CU_add_test(suite, "test of --> map_6", map_6) == NULL) return;
+}
diff --git a/clib/cunit/map.h b/clib/cunit/map.h
new file mode 100644
index 0000000..9996b54
--- /dev/null
+++ b/clib/cunit/map.h
@@ -0,0 +1,19 @@
+/*
+ * Copyright (c) International Business Machines Corp., 2014
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+void map_test(void);
diff --git a/clib/cunit/slab.c b/clib/cunit/slab.c
new file mode 100644
index 0000000..c9585d3
--- /dev/null
+++ b/clib/cunit/slab.c
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) International Business Machines Corp., 2014
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <clib/exception.h>
+#include <clib/assert.h>
+#include <clib/type.h>
+
+#include <clib/slab.h>
+
+#include <CUnit/Basic.h>
+
+#define COUNT 10000
+#define SEED 41
+
+static int init_slab(void) {
+ return 0;
+}
+
+static int clean_slab(void) {
+ return 0;
+}
+
+static void slab_1(void) {
+ slab_t s[SLAB_ALLOC_MAX+1] = {INIT_SLAB,};
+
+ for (int i=SLAB_ALLOC_MIN; i<=SLAB_ALLOC_MAX; i+=3) {
+ slab_init(&s[i], "my_slab", i);
+//slab_dump(&s[i], stdout);
+
+ for (int j=0; j<COUNT; j++) {
+ void * ptr = slab_alloc(&s[i]);
+ memset(ptr, j, i);
+ }
+
+ slab_delete(&s[i]);
+ }
+}
+
+void slab_test(void) {
+ CU_pSuite suite = CU_add_suite("slab", init_slab, clean_slab);
+ if (NULL == suite)
+ return;
+
+ if (CU_add_test(suite, "test of --> slab_1", slab_1) == NULL) return;
+}
diff --git a/clib/cunit/slab.h b/clib/cunit/slab.h
new file mode 100644
index 0000000..32e2aa6
--- /dev/null
+++ b/clib/cunit/slab.h
@@ -0,0 +1,19 @@
+/*
+ * Copyright (c) International Business Machines Corp., 2014
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+void slab_test(void);
diff --git a/clib/cunit/splay.c b/clib/cunit/splay.c
new file mode 100644
index 0000000..302310e
--- /dev/null
+++ b/clib/cunit/splay.c
@@ -0,0 +1,384 @@
+/*
+ * Copyright (c) International Business Machines Corp., 2014
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <clib/libclib.h>
+
+#include <clib/slab.h>
+#include <clib/tree.h>
+#include <clib/tree_iter.h>
+
+#include <CUnit/Basic.h>
+
+#define COUNT 30000
+#define SEED 22
+
+slab_t slab;
+
+typedef struct {
+ tree_node_t node;
+ int i;
+ float f;
+} data_t;
+
+static int init_splay(void) {
+ slab_init(&slab, "my_slab", sizeof(data_t), 4096);
+ return 0;
+}
+
+static int clean_splay(void) {
+ slab_delete(&slab);
+ return 0;
+}
+
+static void __insert(tree_t * t, int i) {
+ data_t * d = (data_t *)slab_alloc(&slab);
+
+ d->i = i;
+ d->f = (float)i;
+
+ tree_node_init(&d->node, (const void *)(d->i));
+
+ if (splay_insert(t, &d->node) < 0) {
+ tree_dump(t, stdout);
+
+ fprintf(stdout, "key: %d root->key: %d\n",
+ i, (int)tree_root(t)->key);
+
+ err_t * err = err_get();
+ fprintf(stderr, "%s(%d): %.*s\n",
+ err_file(err), err_line(err), err_size(err),
+ (const char *)err_data(err));
+ }
+}
+
+static data_t * __remove(tree_t * t, int i) {
+ tree_node_t * n = tree_find(t, (const void *)i);
+ if (n == NULL) tree_dump(t, stdout);
+ CU_ASSERT_PTR_NOT_NULL_FATAL(n);
+
+ splay_remove(t, n);
+ CU_ASSERT_PTR_NULL(tree_node_parent(n));
+ CU_ASSERT_PTR_NULL(tree_node_left(n));
+ CU_ASSERT_PTR_NULL(tree_node_right(n));
+ CU_ASSERT_PTR_NOT_NULL(tree_node_key(n));
+
+ data_t * d = container_of(n, data_t, node);
+ CU_ASSERT_PTR_NOT_NULL_FATAL(n);
+
+ if (0 <= i)
+ CU_ASSERT(d->i == i);
+
+ return d;
+}
+
+static int compare(const void * v1, const void * v2) {
+ const int i1 = (const int)v1, i2 = (const int)v2;
+ return i1 - i2;
+}
+
+static void splay_1(void) {
+ tree_t t;
+ tree_init(&t, compare);
+
+ CU_ASSERT(tree_min(&t) == NULL);
+ CU_ASSERT(tree_max(&t) == NULL);
+ CU_ASSERT(t.compare != NULL);
+
+ CU_ASSERT(tree_root(&t) == NULL);
+ CU_ASSERT(tree_empty(&t) == true);
+ CU_ASSERT(tree_size(&t) == 0);
+}
+
+static void splay_2(void) {
+ tree_t t;
+ tree_init(&t, compare);
+
+ CU_ASSERT(tree_empty(&t) == true);
+ CU_ASSERT(tree_size(&t) == 0);
+
+ for (int i=1; i<=COUNT; i++)
+ __insert(&t, i);
+
+ CU_ASSERT(tree_empty(&t) == false);
+ CU_ASSERT(tree_root(&t) != NULL);
+ CU_ASSERT(tree_size(&t) == COUNT);
+
+ for (int i=1; i<=COUNT; i++) {
+ CU_ASSERT(i == (int)tree_min(&t)->key);
+ CU_ASSERT(COUNT == (int)tree_max(&t)->key);
+ __remove(&t, (int)tree_min(&t)->key);
+ CU_ASSERT(tree_size(&t) + i == COUNT);
+ }
+
+ CU_ASSERT(tree_empty(&t) == true);
+ CU_ASSERT(tree_size(&t) == 0);
+
+ for (int i=1; i<=COUNT; i++)
+ __insert(&t, i);
+
+ CU_ASSERT(tree_empty(&t) == false);
+ CU_ASSERT(tree_root(&t) != NULL);
+ CU_ASSERT(tree_size(&t) == COUNT);
+
+ for (int i=1; i<=COUNT; i++) {
+ CU_ASSERT(1 == (int)tree_min(&t)->key);
+ CU_ASSERT(COUNT - i + 1 == (int)tree_max(&t)->key);
+ __remove(&t, (int)tree_max(&t)->key);
+ CU_ASSERT(tree_size(&t) + i == COUNT);
+ }
+
+ CU_ASSERT(tree_empty(&t) == true);
+ CU_ASSERT(tree_size(&t) == 0);
+}
+
+static void splay_3(void) {
+ tree_t t;
+ tree_init(&t, compare);
+
+ CU_ASSERT(tree_empty(&t) == true);
+ CU_ASSERT(tree_size(&t) == 0);
+
+ for (int i=1; i<=COUNT; i++)
+ __insert(&t, COUNT - i + 1);
+
+ CU_ASSERT(tree_empty(&t) == false);
+ CU_ASSERT(tree_root(&t) != NULL);
+ CU_ASSERT(tree_size(&t) == COUNT);
+
+ for (int i=1; i<=COUNT; i++) {
+ CU_ASSERT(1 == (int)tree_min(&t)->key);
+ CU_ASSERT(COUNT - i + 1 == (int)tree_max(&t)->key);
+ __remove(&t, (int)tree_max(&t)->key);
+ CU_ASSERT(tree_size(&t) + i == COUNT);
+ }
+
+ CU_ASSERT(tree_empty(&t) == true);
+ CU_ASSERT(tree_size(&t) == 0);
+
+ for (int i=1; i<=COUNT; i++)
+ __insert(&t, COUNT - i + 1);
+
+ CU_ASSERT(tree_empty(&t) == false);
+ CU_ASSERT(tree_root(&t) != NULL);
+ CU_ASSERT(tree_size(&t) == COUNT);
+
+ for (int i=1; i<=COUNT; i++) {
+ CU_ASSERT(i == (int)tree_min(&t)->key);
+ CU_ASSERT(COUNT == (int)tree_max(&t)->key);
+ __remove(&t, (int)tree_min(&t)->key);
+ CU_ASSERT(tree_size(&t) + i == COUNT);
+ }
+
+ CU_ASSERT(tree_empty(&t) == true);
+ CU_ASSERT(tree_size(&t) == 0);
+}
+
+static void splay_4(void) {
+ tree_t t;
+ tree_init(&t, compare);
+
+ CU_ASSERT(tree_empty(&t) == true);
+ CU_ASSERT(tree_size(&t) == 0);
+
+ srandom(SEED);
+ for (int i=1; i<=COUNT; i++)
+ __insert(&t, random());
+
+ CU_ASSERT(tree_empty(&t) == false);
+ CU_ASSERT(tree_size(&t) == COUNT);
+
+ for (int i=1; i<=COUNT; i++) {
+ __remove(&t, (int)tree_min(&t)->key);
+ CU_ASSERT(tree_size(&t) + i == COUNT);
+ }
+
+ CU_ASSERT(tree_empty(&t) == true);
+ CU_ASSERT(tree_size(&t) == 0);
+
+ srandom(SEED);
+ for (int i=1; i<=COUNT; i++)
+ __insert(&t, random());
+
+ CU_ASSERT(tree_empty(&t) == false);
+ CU_ASSERT(tree_size(&t) == COUNT);
+
+ for (int i=1; i<=COUNT; i++) {
+ __remove(&t, (int)tree_max(&t)->key);
+ CU_ASSERT(tree_size(&t) + i == COUNT);
+ }
+
+ CU_ASSERT(tree_empty(&t) == true);
+ CU_ASSERT(tree_size(&t) == 0);
+
+ srandom(SEED);
+ for (int i=1; i<=COUNT; i++)
+ __insert(&t, random());
+
+ CU_ASSERT(tree_empty(&t) == false);
+ CU_ASSERT(tree_size(&t) == COUNT);
+
+ for (int i=1; i<=COUNT; i++) {
+ __remove(&t, (int)tree_root(&t)->key);
+ CU_ASSERT(tree_size(&t) + i == COUNT);
+ }
+
+ CU_ASSERT(tree_empty(&t) == true);
+ CU_ASSERT(tree_size(&t) == 0);
+
+ srandom(SEED);
+ for (int i=1; i<=COUNT; i++)
+ __insert(&t, random());
+
+ CU_ASSERT(tree_empty(&t) == false);
+ CU_ASSERT(tree_size(&t) == COUNT);
+
+ srandom(SEED);
+ for (int i=1; i<=COUNT; i++) {
+ __remove(&t, random());
+ CU_ASSERT(tree_size(&t) + i == COUNT);
+ }
+
+ CU_ASSERT(tree_empty(&t) == true);
+ CU_ASSERT(tree_size(&t) == 0);
+}
+
+static void splay_5(void) {
+ tree_t t;
+ tree_init(&t, compare);
+
+ CU_ASSERT(tree_empty(&t) == true);
+ CU_ASSERT(tree_size(&t) == 0);
+
+ srandom(SEED);
+ for (int i=1; i<=COUNT; i++)
+ __insert(&t, random());
+
+ CU_ASSERT(tree_empty(&t) == false);
+ CU_ASSERT(tree_size(&t) == COUNT);
+ data_t * d;
+
+ tree_iter_t it;
+
+ int key = 0;
+ tree_iter_init(&it, &t, TI_FLAG_FWD);
+ tree_for_each(&it, d, node) {
+ CU_ASSERT(key < d->i);
+ key = d->i;
+ }
+
+ key = INT32_MAX;
+ tree_iter_init(&it, &t, TI_FLAG_BWD);
+ tree_for_each(&it, d, node) {
+ CU_ASSERT(d->i < key);
+ key = d->i;
+ }
+}
+
+static void splay_6(void) {
+ tree_t t;
+ tree_init(&t, compare);
+
+ data_t * d;
+
+ CU_ASSERT(tree_empty(&t) == true);
+ CU_ASSERT(tree_size(&t) == 0);
+
+ srandom(SEED);
+ for (int i=1; i<=COUNT; i++)
+ __insert(&t, random());
+
+ CU_ASSERT(tree_empty(&t) == false);
+ CU_ASSERT(tree_size(&t) == COUNT);
+
+ for (int i=1; i<=COUNT; i++) {
+ tree_iter_t it;
+ tree_iter_init(&it, &t, TI_FLAG_FWD);
+
+ int key = 0;
+ tree_for_each(&it, d, node) {
+ CU_ASSERT(key < d->i);
+ key = d->i;
+ }
+
+ __remove(&t, (int)tree_min(&t)->key);
+
+ if (0 < tree_size(&t)) {
+ CU_ASSERT(tree_min(&t) != NULL);
+ } else if (tree_size(&t) <= 0) {
+ CU_ASSERT(tree_min(&t) == NULL);
+ }
+
+ CU_ASSERT(tree_size(&t) + i == COUNT);
+ }
+}
+
+static void splay_7(void) {
+ tree_t t;
+ tree_init(&t, compare);
+
+ data_t * d;
+
+ CU_ASSERT(tree_empty(&t) == true);
+ CU_ASSERT(tree_size(&t) == 0);
+
+ srandom(SEED);
+ for (int i=1; i<=COUNT; i++)
+ __insert(&t, random());
+
+ CU_ASSERT(tree_empty(&t) == false);
+ CU_ASSERT(tree_size(&t) == COUNT);
+
+ for (int i=1; i<=COUNT; i++) {
+ tree_iter_t it;
+
+ int key = INT32_MAX;
+ tree_iter_init(&it, &t, TI_FLAG_BWD);
+ tree_for_each(&it, d, node) {
+ CU_ASSERT(d->i < key);
+ key = d->i;
+ }
+
+ __remove(&t, (int)tree_max(&t)->key);
+
+ if (0 < tree_size(&t)) {
+ CU_ASSERT(tree_max(&t) != NULL);
+ } else if ( tree_size(&t) <= 0) {
+ CU_ASSERT(tree_max(&t) == NULL);
+ }
+
+ CU_ASSERT(tree_size(&t) + i == COUNT);
+ }
+}
+
+void splay_test(void) {
+ CU_pSuite suite = CU_add_suite("splay", init_splay, clean_splay);
+ if (NULL == suite)
+ return;
+
+ if (CU_add_test(suite, "test of --> splay_1", splay_1) == NULL) return;
+ if (CU_add_test(suite, "test of --> splay_2", splay_2) == NULL) return;
+ if (CU_add_test(suite, "test of --> splay_3", splay_3) == NULL) return;
+ if (CU_add_test(suite, "test of --> splay_4", splay_4) == NULL) return;
+ if (CU_add_test(suite, "test of --> splay_5", splay_5) == NULL) return;
+ if (CU_add_test(suite, "test of --> splay_6", splay_6) == NULL) return;
+ if (CU_add_test(suite, "test of --> splay_7", splay_7) == NULL) return;
+}
diff --git a/clib/cunit/splay.h b/clib/cunit/splay.h
new file mode 100644
index 0000000..2cc256d
--- /dev/null
+++ b/clib/cunit/splay.h
@@ -0,0 +1,19 @@
+/*
+ * Copyright (c) International Business Machines Corp., 2014
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+void splay_test(void);
diff --git a/clib/cunit/tree.c b/clib/cunit/tree.c
new file mode 100644
index 0000000..2f67ab7
--- /dev/null
+++ b/clib/cunit/tree.c
@@ -0,0 +1,398 @@
+/*
+ * Copyright (c) International Business Machines Corp., 2014
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <clib/libclib.h>
+
+#include <clib/slab.h>
+#include <clib/tree.h>
+#include <clib/tree_iter.h>
+
+#include <CUnit/Basic.h>
+
+#define COUNT 30000
+#define SEED 22
+
+slab_t slab;
+
+typedef struct {
+ tree_node_t node;
+ int i;
+ float f;
+} data_t;
+
+static int init_tree(void) {
+ slab_init(&slab, "my_slab", sizeof(data_t), 4096);
+ return 0;
+}
+
+static int clean_tree(void) {
+ slab_delete(&slab);
+ return 0;
+}
+
+static void __insert(tree_t * t, int i) {
+ data_t * d = (data_t *)slab_alloc(&slab);
+
+ d->i = i;
+ d->f = (float)i;
+
+ tree_node_init(&d->node, (const void *)(d->i));
+
+ if (tree_insert(t, &d->node) < 0) {
+ err_t * err = err_get();
+ fprintf(stderr, "%s(%d): UNEXPECTED: %.*s\n",
+ err_file(err), err_line(err), err_size(err),
+ (const char *)err_data(err));
+ }
+}
+
+static data_t * __remove(tree_t * t, int i) {
+ tree_node_t * n = tree_find(t, (const void *)i);
+ if (n == NULL) tree_dump(t, stdout);
+ CU_ASSERT_PTR_NOT_NULL_FATAL(n);
+
+ tree_remove(t, n);
+ CU_ASSERT_PTR_NULL(tree_node_parent(n));
+ CU_ASSERT_PTR_NULL(tree_node_left(n));
+ CU_ASSERT_PTR_NULL(tree_node_right(n));
+ CU_ASSERT_PTR_NOT_NULL(tree_node_key(n));
+
+ data_t * d = container_of(n, data_t, node);
+ CU_ASSERT_PTR_NOT_NULL_FATAL(n);
+
+ if (0 <= i)
+ CU_ASSERT(d->i == i);
+
+ return d;
+}
+
+static int compare(const void * v1, const void * v2) {
+ const int i1 = (const int)v1, i2 = (const int)v2;
+ return i1 - i2;
+}
+
+static void tree_1(void) {
+ tree_t t;
+ tree_init(&t, compare);
+
+ CU_ASSERT(tree_min(&t) == NULL);
+ CU_ASSERT(tree_max(&t) == NULL);
+ CU_ASSERT(t.compare != NULL);
+
+ CU_ASSERT(tree_root(&t) == NULL);
+ CU_ASSERT(tree_empty(&t) == true);
+ CU_ASSERT(tree_size(&t) == 0);
+}
+
+static void tree_2(void) {
+ tree_t t;
+ tree_init(&t, compare);
+
+ CU_ASSERT(tree_empty(&t) == true);
+ CU_ASSERT(tree_size(&t) == 0);
+
+ for (int i=1; i<=COUNT; i++)
+ __insert(&t, i);
+
+ CU_ASSERT(tree_empty(&t) == false);
+ CU_ASSERT(tree_root(&t) != NULL);
+ CU_ASSERT(tree_size(&t) == COUNT);
+
+ for (int i=1; i<=COUNT; i++) {
+ CU_ASSERT(i == (int)tree_min(&t)->key);
+ CU_ASSERT(COUNT == (int)tree_max(&t)->key);
+ __remove(&t, (int)tree_min(&t)->key);
+ CU_ASSERT(tree_size(&t) + i == COUNT);
+ }
+
+ CU_ASSERT(tree_empty(&t) == true);
+ CU_ASSERT(tree_size(&t) == 0);
+
+ for (int i=1; i<=COUNT; i++)
+ __insert(&t, i);
+
+ CU_ASSERT(tree_empty(&t) == false);
+ CU_ASSERT(tree_root(&t) != NULL);
+ CU_ASSERT(tree_size(&t) == COUNT);
+
+ for (int i=1; i<=COUNT; i++) {
+ CU_ASSERT(1 == (int)tree_min(&t)->key);
+ CU_ASSERT(COUNT - i + 1 == (int)tree_max(&t)->key);
+ __remove(&t, (int)tree_max(&t)->key);
+ CU_ASSERT(tree_size(&t) + i == COUNT);
+ }
+
+ CU_ASSERT(tree_empty(&t) == true);
+ CU_ASSERT(tree_size(&t) == 0);
+}
+
+static void tree_3(void) {
+ tree_t t;
+ tree_init(&t, compare);
+
+ CU_ASSERT(tree_empty(&t) == true);
+ CU_ASSERT(tree_size(&t) == 0);
+
+ for (int i=1; i<=COUNT; i++)
+ __insert(&t, COUNT - i + 1);
+
+ CU_ASSERT(tree_empty(&t) == false);
+ CU_ASSERT(tree_root(&t) != NULL);
+ CU_ASSERT(tree_size(&t) == COUNT);
+
+ for (int i=1; i<=COUNT; i++) {
+ CU_ASSERT(1 == (int)tree_min(&t)->key);
+ CU_ASSERT(COUNT - i + 1 == (int)tree_max(&t)->key);
+ __remove(&t, (int)tree_max(&t)->key);
+ CU_ASSERT(tree_size(&t) + i == COUNT);
+ }
+
+ CU_ASSERT(tree_empty(&t) == true);
+ CU_ASSERT(tree_size(&t) == 0);
+
+ for (int i=1; i<=COUNT; i++)
+ __insert(&t, COUNT - i + 1);
+
+ CU_ASSERT(tree_empty(&t) == false);
+ CU_ASSERT(tree_root(&t) != NULL);
+ CU_ASSERT(tree_size(&t) == COUNT);
+
+ for (int i=1; i<=COUNT; i++) {
+ CU_ASSERT(i == (int)tree_min(&t)->key);
+ CU_ASSERT(COUNT == (int)tree_max(&t)->key);
+ __remove(&t, (int)tree_min(&t)->key);
+ CU_ASSERT(tree_size(&t) + i == COUNT);
+ }
+
+ CU_ASSERT(tree_empty(&t) == true);
+ CU_ASSERT(tree_size(&t) == 0);
+}
+
+static void tree_4(void) {
+ tree_t t;
+ tree_init(&t, compare);
+
+ CU_ASSERT(tree_empty(&t) == true);
+ CU_ASSERT(tree_size(&t) == 0);
+
+ srandom(SEED);
+ for (int i=1; i<=COUNT; i++)
+ __insert(&t, random());
+
+ CU_ASSERT(tree_empty(&t) == false);
+ CU_ASSERT(tree_size(&t) == COUNT);
+
+ for (int i=1; i<=COUNT; i++) {
+ __remove(&t, (int)tree_min(&t)->key);
+ CU_ASSERT(tree_size(&t) + i == COUNT);
+ }
+
+ CU_ASSERT(tree_empty(&t) == true);
+ CU_ASSERT(tree_size(&t) == 0);
+
+ srandom(SEED);
+ for (int i=1; i<=COUNT; i++)
+ __insert(&t, random());
+
+ CU_ASSERT(tree_empty(&t) == false);
+ CU_ASSERT(tree_size(&t) == COUNT);
+
+ for (int i=1; i<=COUNT; i++) {
+ __remove(&t, (int)tree_max(&t)->key);
+ CU_ASSERT(tree_size(&t) + i == COUNT);
+ }
+
+ CU_ASSERT(tree_empty(&t) == true);
+ CU_ASSERT(tree_size(&t) == 0);
+
+ srandom(SEED);
+ for (int i=1; i<=COUNT; i++)
+ __insert(&t, random());
+
+ CU_ASSERT(tree_empty(&t) == false);
+ CU_ASSERT(tree_size(&t) == COUNT);
+
+ for (int i=1; i<=COUNT; i++) {
+ __remove(&t, (int)tree_root(&t)->key);
+ CU_ASSERT(tree_size(&t) + i == COUNT);
+ }
+
+ CU_ASSERT(tree_empty(&t) == true);
+ CU_ASSERT(tree_size(&t) == 0);
+
+ srandom(SEED);
+ for (int i=1; i<=COUNT; i++)
+ __insert(&t, random());
+
+ CU_ASSERT(tree_empty(&t) == false);
+ CU_ASSERT(tree_size(&t) == COUNT);
+
+ srandom(SEED);
+ for (int i=1; i<=COUNT; i++) {
+ __remove(&t, random());
+ CU_ASSERT(tree_size(&t) + i == COUNT);
+ }
+
+ CU_ASSERT(tree_empty(&t) == true);
+ CU_ASSERT(tree_size(&t) == 0);
+}
+
+static void tree_5(void) {
+ tree_t t;
+ tree_init(&t, compare);
+
+ CU_ASSERT(tree_empty(&t) == true);
+ CU_ASSERT(tree_size(&t) == 0);
+
+ srandom(SEED);
+ for (int i=1; i<=COUNT; i++)
+ __insert(&t, random());
+
+ CU_ASSERT(tree_empty(&t) == false);
+ CU_ASSERT(tree_size(&t) == COUNT);
+
+ data_t * d;
+
+ tree_iter_t it;
+
+ int key = 0;
+ tree_iter_init(&it, &t, TI_FLAG_FWD);
+ tree_for_each(&it, d, node) {
+ CU_ASSERT(key < d->i);
+ key = d->i;
+ }
+
+ key = INT32_MAX;
+ tree_iter_init(&it, &t, TI_FLAG_BWD);
+ tree_for_each(&it, d, node) {
+ CU_ASSERT(d->i < key);
+ key = d->i;
+ }
+}
+
+static void tree_6(void) {
+ tree_t t;
+ tree_init(&t, compare);
+
+ data_t * d;
+
+ CU_ASSERT(tree_empty(&t) == true);
+ CU_ASSERT(tree_size(&t) == 0);
+
+ srandom(SEED);
+ for (int i=1; i<=COUNT; i++)
+ __insert(&t, random());
+
+ CU_ASSERT(tree_empty(&t) == false);
+ CU_ASSERT(tree_size(&t) == COUNT);
+
+ for (int i=1; i<=COUNT; i++) {
+ tree_iter_t it;
+ tree_iter_init(&it, &t, TI_FLAG_FWD);
+
+ int key = 0;
+ tree_for_each(&it, d, node) {
+ CU_ASSERT(key < d->i);
+ key = d->i;
+ }
+
+ __remove(&t, (int)tree_min(&t)->key);
+
+ if (0 < tree_size(&t)) {
+ CU_ASSERT(tree_min(&t) != NULL);
+ } else if (tree_size(&t) <= 0) {
+ CU_ASSERT(tree_min(&t) == NULL);
+ }
+
+ CU_ASSERT(tree_size(&t) + i == COUNT);
+ }
+}
+
+static void tree_7(void) {
+ tree_t t;
+ tree_init(&t, compare);
+
+ data_t * d;
+
+ CU_ASSERT(tree_empty(&t) == true);
+ CU_ASSERT(tree_size(&t) == 0);
+
+ srandom(SEED);
+ for (int i=1; i<=COUNT; i++)
+ __insert(&t, random());
+
+ CU_ASSERT(tree_empty(&t) == false);
+ CU_ASSERT(tree_size(&t) == COUNT);
+
+ for (int i=1; i<=COUNT; i++) {
+ tree_iter_t it;
+
+ int key = INT32_MAX;
+ tree_iter_init(&it, &t, TI_FLAG_BWD);
+ tree_for_each(&it, d, node) {
+ CU_ASSERT(d->i < key);
+ key = d->i;
+ }
+
+ __remove(&t, (int)tree_max(&t)->key);
+
+ if (0 < tree_size(&t)) {
+ CU_ASSERT(tree_max(&t) != NULL);
+ } else if ( tree_size(&t) <= 0) {
+ CU_ASSERT(tree_max(&t) == NULL);
+ }
+
+ CU_ASSERT(tree_size(&t) + i == COUNT);
+ }
+}
+
+
+void tree_test(void) {
+ CU_pSuite suite = CU_add_suite("tree", init_tree, clean_tree);
+ if (NULL == suite)
+ return;
+
+ if (CU_add_test(suite, "test of --> tree_1", tree_1) == NULL)
+ goto error;
+ if (CU_add_test(suite, "test of --> tree_2", tree_2) == NULL)
+ goto error;
+ if (CU_add_test(suite, "test of --> tree_3", tree_3) == NULL)
+ goto error;
+ if (CU_add_test(suite, "test of --> tree_4", tree_4) == NULL)
+ goto error;
+ if (CU_add_test(suite, "test of --> tree_5", tree_5) == NULL)
+ goto error;
+ if (CU_add_test(suite, "test of --> tree_6", tree_6) == NULL)
+ goto error;
+ if (CU_add_test(suite, "test of --> tree_7", tree_7) == NULL)
+ goto error;
+
+ if (false) {
+ err_t * err;
+error:
+ err = err_get();
+ fprintf(stderr, "%s(%d): UNEXPECTED: %.*s\n",
+ err_file(err), err_line(err), err_size(err),
+ (const char *)err_data(err));
+ }
+
+}
diff --git a/clib/cunit/tree.h b/clib/cunit/tree.h
new file mode 100644
index 0000000..264670c
--- /dev/null
+++ b/clib/cunit/tree.h
@@ -0,0 +1,19 @@
+/*
+ * Copyright (c) International Business Machines Corp., 2014
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+void tree_test(void);
diff --git a/clib/cunit/vector.c b/clib/cunit/vector.c
new file mode 100644
index 0000000..7ead584
--- /dev/null
+++ b/clib/cunit/vector.c
@@ -0,0 +1,169 @@
+/*
+ * Copyright (c) International Business Machines Corp., 2014
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <clib/libclib.h>
+
+#include <clib/crc32.h>
+#include <clib/vector.h>
+
+#include <CUnit/Basic.h>
+
+#define COUNT 10000
+#define SEED 41
+
+static int init_vector(void) {
+ return 0;
+}
+
+static int clean_vector(void) {
+ return 0;
+}
+
+static void vector_1(void) {
+ vector_t v;
+
+ CU_ASSERT(vector_init(&v, "my_vector", 0) == -1)
+ err_t * err = err_get();
+ fprintf(stderr, "%s(%d): %.*s\n",
+ err_file(err), err_line(err), err_size(err),
+ (const char *)err_data(err));
+
+ for (size_t i=VECTOR_ELEM_MIN; i<=VECTOR_ELEM_MAX; i++) {
+ CU_ASSERT(vector_init(&v, "my_vector", i) == 0);
+
+ CU_ASSERT(vector_size(&v) == 0);
+ CU_ASSERT(vector_pages(&v) == 0);
+ CU_ASSERT(vector_capacity(&v) == 0);
+ CU_ASSERT(vector_elem_size(&v) == i);
+ CU_ASSERT(vector_elem_size(&v) * v.hdr.elem_num <= v.hdr.page_size);
+
+ CU_ASSERT(vector_delete(&v) == 0);
+ }
+}
+
+uint32_t crc2;
+
+static void vector_2(void) {
+ vector_t v;
+
+ CU_ASSERT(vector_init(&v, "my_vector.bin", 1) == 0);
+ CU_ASSERT(vector_size(&v) == 0);
+ CU_ASSERT(vector_pages(&v) == 0);
+ CU_ASSERT(vector_capacity(&v) == 0);
+ CU_ASSERT(vector_elem_size(&v) == 1);
+
+ CU_ASSERT(vector_size(&v, COUNT) == COUNT);
+ CU_ASSERT(COUNT <= vector_capacity(&v));
+ CU_ASSERT(COUNT <= vector_size(&v));
+ CU_ASSERT(3 <= vector_pages(&v));
+
+ for (int i=0; i<COUNT; i++) {
+ unsigned char c = (unsigned char)i;
+ crc2 = clib_crc32(c, crc2);
+ CU_ASSERT(vector_put(&v, i, &c) == 0);
+ }
+ CU_ASSERT_FATAL(crc2 != 0);
+
+ FILE * f = fopen(v.hdr.name, "w");
+ CU_ASSERT_FATAL(f != NULL);
+ CU_ASSERT(COUNT < vector_save(&v, f));
+ fclose(f), f = NULL;
+
+ CU_ASSERT(vector_delete(&v) == 0);
+}
+
+uint32_t crc3;
+
+static void vector_3(void) {
+ vector_t v;
+ vector_init(&v, __func__, 1);
+
+ CU_ASSERT(vector_size(&v) == 0);
+ CU_ASSERT(vector_pages(&v) == 0);
+ CU_ASSERT(vector_capacity(&v) == 0);
+ CU_ASSERT(vector_elem_size(&v) == 1);
+
+ FILE * f = fopen("my_vector.bin", "r");
+ CU_ASSERT_FATAL(f != NULL);
+ CU_ASSERT(COUNT < vector_load(&v, f));
+ fclose(f), f = NULL;
+
+ crc3 = 0;
+
+ for (int i=0; i<COUNT; i++) {
+ unsigned char c;
+ vector_get(&v, i, &c);
+ crc3 = clib_crc32(c, crc3);
+ }
+ CU_ASSERT_FATAL(crc3 != 0);
+
+ CU_ASSERT_FATAL(crc2 == crc3);
+
+ vector_delete(&v);
+}
+
+static void vector_4(void) {
+ vector_t v;
+
+ if (vector_init(&v, NULL, 0) < 0) {
+ err_t * err = err_get();
+ fprintf(stderr, "%s(%d): UNEXPECTED: %.*s\n",
+ err_file(err), err_line(err), err_size(err),
+ (const char *)err_data(err));
+ }
+
+ if (vector_init(&v, "my_vector", 0) < 0) {
+ err_t * err = err_get();
+ fprintf(stderr, "%s(%d): UNEXPECTED: %.*s\n",
+ err_file(err), err_line(err), err_size(err),
+ (const char *)err_data(err));
+ }
+
+ for (size_t i=VECTOR_ELEM_MIN; i<=VECTOR_ELEM_MAX; i+=3) {
+ vector_init(&v, "my_vector", i);
+
+ CU_ASSERT(vector_size(&v) == 0);
+ CU_ASSERT(vector_pages(&v) == 0);
+ CU_ASSERT(vector_capacity(&v) == 0);
+ CU_ASSERT(vector_elem_size(&v) == i);
+ CU_ASSERT(vector_elem_size(&v) * v.hdr.elem_num <= v.hdr.page_size);
+
+ vector_size(&v, COUNT);
+
+ CU_ASSERT(vector_size(&v) == COUNT);
+ CU_ASSERT(vector_size(&v) <= vector_capacity(&v));
+ CU_ASSERT(0 < vector_pages(&v));
+
+ vector_delete(&v);
+ }
+}
+
+void vector_test(void) {
+ CU_pSuite suite = CU_add_suite("vector", init_vector, clean_vector);
+ if (NULL == suite)
+ return;
+
+ if (CU_add_test(suite, "vector_1: vector_init()", vector_1) == NULL) return;
+ if (CU_add_test(suite, "vector_2: vector_save()", vector_2) == NULL) return;
+ if (CU_add_test(suite, "vector_3: vector_load()", vector_3) == NULL) return;
+ if (CU_add_test(suite, "vector_4: vector_size()", vector_4) == NULL) return;
+}
diff --git a/clib/cunit/vector.h b/clib/cunit/vector.h
new file mode 100644
index 0000000..c201b1a
--- /dev/null
+++ b/clib/cunit/vector.h
@@ -0,0 +1,19 @@
+/*
+ * Copyright (c) International Business Machines Corp., 2014
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+void vector_test(void);
OpenPOWER on IntegriCloud