From 065e245cec1962f01bd16c6136750c9473a66661 Mon Sep 17 00:00:00 2001
From: Marek Vavrusa <marek@vavrusa.com>
Date: Tue, 19 Oct 2010 11:36:26 +0200
Subject: [PATCH] Implemented skip list test.

---
 CuteDNS.files              |   1 +
 src/tests/main.c           |   5 +-
 src/tests/skiplist_tests.c | 167 +++++++++++++++++++++++++++++++++++++
 3 files changed, 172 insertions(+), 1 deletion(-)
 create mode 100644 src/tests/skiplist_tests.c

diff --git a/CuteDNS.files b/CuteDNS.files
index 83df21712..cb99e3cb6 100644
--- a/CuteDNS.files
+++ b/CuteDNS.files
@@ -37,6 +37,7 @@ src/tests/tests.h
 src/tests/cuckoo-test.c
 src/tests/cuckoo-test.h
 src/tests/server_tests.c
+src/tests/skiplist_tests.c
 src/tests/tap_unit.h
 src/tests/template_tests.c
 src/other/log.h
diff --git a/src/tests/main.c b/src/tests/main.c
index 24ed2ddd8..ca535dbd6 100644
--- a/src/tests/main.c
+++ b/src/tests/main.c
@@ -3,13 +3,15 @@
 
 // Units to test
 #include "server_tests.c"
+#include "skiplist_tests.c"
 
 // Run all loaded units
 int main(int argc, char * argv[])
 {
    // Build test set
    unit_api* tests[] = {
-      &server_tests_api, //! Server unit
+      &server_tests_api,   //! Server unit
+      &skiplist_tests_api, //! Skip list unit
       NULL
    };
 
@@ -17,6 +19,7 @@ int main(int argc, char * argv[])
    int id = 0;
    int test_count = 0;
    while(tests[id] != NULL) {
+      fprintf(stderr, "#test %s : %d tests\n", tests[id]->name, tests[id]->count(argc, argv));
       test_count += tests[id]->count(argc, argv);
       ++id;
    }
diff --git a/src/tests/skiplist_tests.c b/src/tests/skiplist_tests.c
new file mode 100644
index 000000000..f2f7785bb
--- /dev/null
+++ b/src/tests/skiplist_tests.c
@@ -0,0 +1,167 @@
+#include "tap_unit.h"
+#include "skip-list.h"
+
+static int skiplist_tests_count(int argc, char * argv[]);
+static int skiplist_tests_run(int argc, char * argv[]);
+
+/*
+ * Unit API.
+ */
+unit_api skiplist_tests_api = {
+   "Skip list",
+   &skiplist_tests_count,
+   &skiplist_tests_run
+};
+
+/*
+ * Unit implementation.
+ */
+
+static const int SKIPLIST_TEST_COUNT = 5;
+
+static int skiplist_tests_count(int argc, char *argv[])
+{
+   return SKIPLIST_TEST_COUNT;
+}
+
+/* Comparing and merging limited to int keys used in test.
+ */
+int test_skip_compare_keys( void *key1, void *key2 )
+{
+   return ((long)key1 < (long)key2) ? -1 : (((long)key1 > (long)key2) ? 1 : 0);
+}
+
+int test_skip_merge_values( void **lvalue, void **rvalue )
+{
+	(*lvalue) = (void *)((long)(*lvalue) + (long)(*rvalue));
+	return 0;
+}
+
+int test_skiplist_create(skip_list** list)
+{
+   *list = skip_create_list(test_skip_compare_keys);
+   return *list != NULL;
+}
+
+int test_skiplist_fill(skip_list* list, long* uitems, int loops)
+{
+	int uitem_count = 0;
+	for (int i = 0; i < loops; ++i) {
+		long key = rand() % 100 + 1;
+		long value = rand() % 100 + 1;
+		int res = skip_insert(list, (void *)key, (void *)value,
+						  test_skip_merge_values);
+		switch (res) {
+			case -2:
+				diag("skiplist: merging failed");
+				return 0;
+				break;
+			case -1:
+				diag("skiplist: insert failed");
+				return 0;
+				break;
+			case 0:
+				uitems[uitem_count++] = key;
+				break;
+			default:
+				break;
+		}
+	}
+
+	return uitem_count;
+}
+
+int test_skiplist_lookup_seq(skip_list* list, long* uitems, int uitems_count)
+{
+	int errors = 0;
+
+	// Sequential lookup
+	for(int i = 0; i < uitems_count; ++i) {
+		void *found = skip_find(list, (void*) uitems[i]);
+		if(found == NULL) {
+			diag("skiplist: sequential lookup failed, key: %d", uitems[i]);
+			++errors;
+		}
+	}
+
+	if(errors) {
+		diag("skiplist: sequential lookup: %d found %d missed, %.2f%% success rate",
+			  uitems_count - errors, errors, (uitems_count-errors)/(float) uitems_count*100.0);
+	}
+
+	return errors == 0;
+}
+
+int test_skiplist_lookup_rand(skip_list* list, long* uitems, int uitems_count)
+{
+	int errors = 0;
+	srand((unsigned)time(NULL));
+
+	// Random lookup
+	for(int i = 0; i < uitems_count; ++i) {
+		long key = rand() % uitems_count + 1;
+		void *found = skip_find(list, (void*) key);
+		if(found == NULL) {
+			diag("skiplist: random lookup failed, key: %d", uitems[i]);
+			++errors;
+		}
+	}
+
+	if(errors) {
+		diag("skiplist: sequential lookup: %d found %d missed, %.2f%% success rate",
+			  uitems_count - errors, errors, (uitems_count-errors)/(float) uitems_count*100.0);
+	}
+	return errors == 0;
+}
+
+
+int test_skiplist_remove(skip_list* list, long* uitems, int uitems_count)
+{
+	int errors = 0;
+
+	// delete items
+	for (int i = 0; i < uitems_count; ++i) {
+		int res = skip_remove(list, (void *) uitems[i], NULL, NULL);
+		switch (res) {
+			case 0:
+				break;
+			default:
+				++errors;
+				break;
+		}
+	}
+
+	if(errors) {
+		diag("skiplist: sequential lookup: %d found %d missed, %.2f%% success rate",
+			  uitems_count - errors, errors, (uitems_count-errors)/(float) uitems_count*100.0);
+	}
+	return errors == 0;
+}
+
+static int skiplist_tests_run(int argc, char *argv[])
+{
+   const int loops = 100;
+   int uitems_count = 0;
+   long* uitems = malloc(loops * sizeof(long));
+   skip_list* list = 0;
+
+   // Test 1: create
+   ok(test_skiplist_create(&list), "skiplist: create");
+
+   // Test 2: fill
+   ok(uitems_count = test_skiplist_fill(list, uitems, loops), "skiplist: fill");
+
+   // Test 3: sequential lookup
+   ok(test_skiplist_lookup_seq(list, uitems, uitems_count), "skiplist: sequential lookup");
+
+   // Test 4: sequential lookup
+   ok(test_skiplist_lookup_seq(list, uitems, uitems_count), "skiplist: random lookup lookup");
+
+   // Test 5: remove items
+   ok(test_skiplist_remove(list, uitems, uitems_count), "skiplist: random lookup lookup");
+
+   // Cleanup
+   skip_destroy_list(&list, NULL, NULL);
+   free(uitems);
+   return 0;
+}
-- 
GitLab