aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorArne Schwabe2024-02-09 11:59:02 +0100
committerGert Doering2024-02-10 11:38:39 +0100
commit91b057a2b5b4d16b64d9d01824a8ec9327a61da1 (patch)
treee0b146be7cda36217f3eab5400f8a3b7f8cfb5eb
parent7435114d9a979611dfe5ab751c213900cc1773e8 (diff)
downloadopenvpn-91b057a2b5b4d16b64d9d01824a8ec9327a61da1.zip
openvpn-91b057a2b5b4d16b64d9d01824a8ec9327a61da1.tar.gz
Turn dead list test code into unit test
Change-Id: I7511bc43cd6a0bcb89476f27d5822ab4a78d0d21 Signed-off-by: Arne Schwabe <arne@rfc2549.org> Acked-by: Frank Lichtenheld <frank@lichtenheld.com> Message-Id: <20240209105902.14506-1-frank@lichtenheld.com> URL: https://www.mail-archive.com/openvpn-devel@lists.sourceforge.net/msg28201.html Signed-off-by: Gert Doering <gert@greenie.muc.de>
-rw-r--r--CMakeLists.txt1
-rw-r--r--src/openvpn/init.c5
-rw-r--r--src/openvpn/list.c179
-rw-r--r--src/openvpn/list.h7
-rw-r--r--tests/unit_tests/openvpn/Makefile.am6
-rw-r--r--tests/unit_tests/openvpn/test_misc.c205
6 files changed, 210 insertions, 193 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index fdd2b01..3127611 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -747,6 +747,7 @@ if (BUILD_TESTING)
tests/unit_tests/openvpn/mock_get_random.c
src/openvpn/options_util.c
src/openvpn/ssl_util.c
+ src/openvpn/list.c
)
target_sources(test_ncp PRIVATE
diff --git a/src/openvpn/init.c b/src/openvpn/init.c
index c5cc154..52b4308 100644
--- a/src/openvpn/init.c
+++ b/src/openvpn/init.c
@@ -865,11 +865,6 @@ init_static(void)
return false;
#endif
-#ifdef LIST_TEST
- list_test();
- return false;
-#endif
-
#ifdef IFCONFIG_POOL_TEST
ifconfig_pool_test(0x0A010004, 0x0A0100FF);
return false;
diff --git a/src/openvpn/list.c b/src/openvpn/list.c
index 480f39d..dc4b1df 100644
--- a/src/openvpn/list.c
+++ b/src/openvpn/list.c
@@ -326,185 +326,6 @@ hash_iterator_delete_element(struct hash_iterator *hi)
}
-#ifdef LIST_TEST
-
-/*
- * Test the hash code by implementing a simple
- * word frequency algorithm.
- */
-
-struct word
-{
- const char *word;
- int n;
-};
-
-static uint32_t
-word_hash_function(const void *key, uint32_t iv)
-{
- const char *str = (const char *) key;
- const int len = strlen(str);
- return hash_func((const uint8_t *)str, len, iv);
-}
-
-static bool
-word_compare_function(const void *key1, const void *key2)
-{
- return strcmp((const char *)key1, (const char *)key2) == 0;
-}
-
-static void
-print_nhash(struct hash *hash)
-{
- struct hash_iterator hi;
- struct hash_element *he;
- int count = 0;
-
- hash_iterator_init(hash, &hi, true);
-
- while ((he = hash_iterator_next(&hi)))
- {
- printf("%d ", (int) he->value);
- ++count;
- }
- printf("\n");
-
- hash_iterator_free(&hi);
- ASSERT(count == hash_n_elements(hash));
-}
-
-static void
-rmhash(struct hash *hash, const char *word)
-{
- hash_remove(hash, word);
-}
-
-void
-list_test(void)
-{
- openvpn_thread_init();
-
- {
- struct gc_arena gc = gc_new();
- struct hash *hash = hash_init(10000, get_random(), word_hash_function, word_compare_function);
- struct hash *nhash = hash_init(256, get_random(), word_hash_function, word_compare_function);
-
- printf("hash_init n_buckets=%d mask=0x%08x\n", hash->n_buckets, hash->mask);
-
- /* parse words from stdin */
- while (true)
- {
- char buf[256];
- char wordbuf[256];
- int wbi;
- int bi;
- char c;
-
- if (!fgets(buf, sizeof(buf), stdin))
- {
- break;
- }
-
- bi = wbi = 0;
- do
- {
- c = buf[bi++];
- if (isalnum(c) || c == '_')
- {
- ASSERT(wbi < (int) sizeof(wordbuf));
- wordbuf[wbi++] = c;
- }
- else
- {
- if (wbi)
- {
- struct word *w;
- ASSERT(wbi < (int) sizeof(wordbuf));
- wordbuf[wbi++] = '\0';
-
- /* word is parsed from stdin */
-
- /* does it already exist in table? */
- w = (struct word *) hash_lookup(hash, wordbuf);
-
- if (w)
- {
- /* yes, increment count */
- ++w->n;
- }
- else
- {
- /* no, make a new object */
- ALLOC_OBJ_GC(w, struct word, &gc);
- w->word = string_alloc(wordbuf, &gc);
- w->n = 1;
- ASSERT(hash_add(hash, w->word, w, false));
- ASSERT(hash_add(nhash, w->word, (void *) ((random() & 0x0F) + 1), false));
- }
- }
- wbi = 0;
- }
- } while (c);
- }
-
-#if 1
- /* remove some words from the table */
- {
- rmhash(hash, "true");
- rmhash(hash, "false");
- }
-#endif
-
- /* output contents of hash table */
- {
- int base;
- int inc = 0;
- int count = 0;
-
- for (base = 0; base < hash_n_buckets(hash); base += inc)
- {
- struct hash_iterator hi;
- struct hash_element *he;
- inc = (get_random() % 3) + 1;
- hash_iterator_init_range(hash, &hi, true, base, base + inc);
-
- while ((he = hash_iterator_next(&hi)))
- {
- struct word *w = (struct word *) he->value;
- printf("%6d '%s'\n", w->n, w->word);
- ++count;
- }
-
- hash_iterator_free(&hi);
- }
- ASSERT(count == hash_n_elements(hash));
- }
-
-#if 1
- /* test hash_remove_by_value function */
- {
- int i;
- for (i = 1; i <= 16; ++i)
- {
- printf("[%d] ***********************************\n", i);
- print_nhash(nhash);
- hash_remove_by_value(nhash, (void *) i, true);
- }
- printf("FINAL **************************\n");
- print_nhash(nhash);
- }
-#endif
-
- hash_free(hash);
- hash_free(nhash);
- gc_free(&gc);
- }
-
- openvpn_thread_cleanup();
-}
-
-#endif /* ifdef LIST_TEST */
-
/*
* --------------------------------------------------------------------
* hash() -- hash a variable-length key into a 32-bit value
diff --git a/src/openvpn/list.h b/src/openvpn/list.h
index 94d14f2..18afc54 100644
--- a/src/openvpn/list.h
+++ b/src/openvpn/list.h
@@ -33,8 +33,6 @@
* client instances over various key spaces.
*/
-/* define this to enable special list test mode */
-/*#define LIST_TEST*/
#include "basic.h"
#include "buffer.h"
@@ -114,11 +112,6 @@ void hash_iterator_free(struct hash_iterator *hi);
uint32_t hash_func(const uint8_t *k, uint32_t length, uint32_t initval);
-#ifdef LIST_TEST
-void list_test(void);
-
-#endif
-
static inline uint32_t
hash_value(const struct hash *hash, const void *key)
{
diff --git a/tests/unit_tests/openvpn/Makefile.am b/tests/unit_tests/openvpn/Makefile.am
index 88a694d..ce6f812 100644
--- a/tests/unit_tests/openvpn/Makefile.am
+++ b/tests/unit_tests/openvpn/Makefile.am
@@ -288,7 +288,8 @@ ncp_testdriver_SOURCES = test_ncp.c mock_msg.c \
$(top_srcdir)/src/openvpn/ssl_util.c
misc_testdriver_CFLAGS = @TEST_CFLAGS@ \
- -I$(top_srcdir)/include -I$(top_srcdir)/src/compat -I$(top_srcdir)/src/openvpn
+ -I$(top_srcdir)/include -I$(top_srcdir)/src/compat -I$(top_srcdir)/src/openvpn \
+ -DSOURCEDIR=\"$(top_srcdir)\"
misc_testdriver_LDFLAGS = @TEST_LDFLAGS@
@@ -298,4 +299,5 @@ misc_testdriver_SOURCES = test_misc.c mock_msg.c \
$(top_srcdir)/src/openvpn/options_util.c \
$(top_srcdir)/src/openvpn/ssl_util.c \
$(top_srcdir)/src/openvpn/win32-util.c \
- $(top_srcdir)/src/openvpn/platform.c
+ $(top_srcdir)/src/openvpn/platform.c \
+ $(top_srcdir)/src/openvpn/list.c
diff --git a/tests/unit_tests/openvpn/test_misc.c b/tests/unit_tests/openvpn/test_misc.c
index 193f131..04dbd5a 100644
--- a/tests/unit_tests/openvpn/test_misc.c
+++ b/tests/unit_tests/openvpn/test_misc.c
@@ -37,6 +37,7 @@
#include "ssl_util.h"
#include "options_util.h"
#include "test_common.h"
+#include "list.h"
static void
test_compat_lzo_string(void **state)
@@ -108,11 +109,215 @@ test_auth_fail_temp_flags_msg(void **state)
assert_int_equal(o.server_backoff_time, 77);
}
+
+
+struct word
+{
+ const char *word;
+ int n;
+};
+
+
+static uint32_t
+word_hash_function(const void *key, uint32_t iv)
+{
+ const char *str = (const char *) key;
+ const int len = strlen(str);
+ return hash_func((const uint8_t *)str, len, iv);
+}
+
+static bool
+word_compare_function(const void *key1, const void *key2)
+{
+ return strcmp((const char *)key1, (const char *)key2) == 0;
+}
+
+static unsigned long
+get_random(void)
+{
+ /* rand() is not very random, but it's C99 and this is just for testing */
+ return rand();
+}
+
+static struct hash_element *
+hash_lookup_by_value(struct hash *hash, void *value)
+{
+ struct hash_iterator hi;
+ struct hash_element *he;
+ struct hash_element *ret = NULL;
+ hash_iterator_init(hash, &hi);
+
+ while ((he = hash_iterator_next(&hi)))
+ {
+ if (he->value == value)
+ {
+ ret = he;
+ }
+ }
+ hash_iterator_free(&hi);
+ return ret;
+}
+
+static void
+test_list(void **state)
+{
+
+/*
+ * Test the hash code by implementing a simple
+ * word frequency algorithm.
+ */
+
+ struct gc_arena gc = gc_new();
+ struct hash *hash = hash_init(10000, get_random(), word_hash_function, word_compare_function);
+ struct hash *nhash = hash_init(256, get_random(), word_hash_function, word_compare_function);
+
+ printf("hash_init n_buckets=%d mask=0x%08x\n", hash->n_buckets, hash->mask);
+
+ char wordfile[PATH_MAX] = { 0 };
+ openvpn_test_get_srcdir_dir(wordfile, PATH_MAX, "/../../../COPYRIGHT.GPL" );
+
+ FILE *words = fopen(wordfile, "r");
+ assert_non_null(words);
+
+ int wordcount = 0;
+
+ /* parse words from file */
+ while (true)
+ {
+ char buf[256];
+ char wordbuf[256];
+
+ if (!fgets(buf, sizeof(buf), words))
+ {
+ break;
+ }
+
+ char c = 0;
+ int bi = 0, wbi = 0;
+
+ do
+ {
+ c = buf[bi++];
+ if (isalnum(c) || c == '_')
+ {
+ assert_true(wbi < (int) sizeof(wordbuf));
+ wordbuf[wbi++] = c;
+ }
+ else
+ {
+ if (wbi)
+ {
+ wordcount++;
+
+ ASSERT(wbi < (int) sizeof(wordbuf));
+ wordbuf[wbi++] = '\0';
+
+ /* word is parsed from stdin */
+
+ /* does it already exist in table? */
+ struct word *w = (struct word *) hash_lookup(hash, wordbuf);
+
+ if (w)
+ {
+ assert_string_equal(w->word, wordbuf);
+ /* yes, increment count */
+ ++w->n;
+ }
+ else
+ {
+ /* no, make a new object */
+ ALLOC_OBJ_GC(w, struct word, &gc);
+ w->word = string_alloc(wordbuf, &gc);
+ w->n = 1;
+ assert_true(hash_add(hash, w->word, w, false));
+ assert_true(hash_add(nhash, w->word, (void *) ((ptr_type )(random() & 0x0F) + 1), false));
+ }
+ }
+ wbi = 0;
+ }
+ }
+ while (c);
+ }
+
+ assert_int_equal(wordcount, 2978);
+
+ /* remove some words from the table */
+ {
+ assert_true(hash_remove(hash, "DEFECTIVE"));
+ assert_false(hash_remove(hash, "false"));
+ }
+
+ /* output contents of hash table */
+ {
+ ptr_type inc = 0;
+ int count = 0;
+
+ for (ptr_type base = 0; base < hash_n_buckets(hash); base += inc)
+ {
+ struct hash_iterator hi;
+ struct hash_element *he;
+ inc = (get_random() % 3) + 1;
+ hash_iterator_init_range(hash, &hi, base, base + inc);
+
+ while ((he = hash_iterator_next(&hi)))
+ {
+ struct word *w = (struct word *) he->value;
+ /*printf("%6d '%s'\n", w->n, w->word); */
+ ++count;
+ /* check a few words to match prior results */
+ if (!strcmp(w->word, "is"))
+ {
+ assert_int_equal(w->n, 49);
+ }
+ else if (!strcmp(w->word, "redistribute"))
+ {
+ assert_int_equal(w->n, 5);
+ }
+ else if (!strcmp(w->word, "circumstances"))
+ {
+ assert_int_equal(w->n, 1);
+ }
+ else if (!strcmp(w->word, "so"))
+ {
+ assert_int_equal(w->n, 8);
+ }
+ else if (!strcmp(w->word, "BECAUSE"))
+ {
+ assert_int_equal(w->n, 1);
+ }
+ }
+
+ hash_iterator_free(&hi);
+ }
+ assert_int_equal(count, hash_n_elements(hash));
+ }
+
+ /* test hash_remove_by_value function */
+ {
+ for (ptr_type i = 1; i <= 16; ++i)
+ {
+ struct hash_element *item = hash_lookup_by_value(nhash, (void *) i);
+ hash_remove_by_value(nhash, (void *) i);
+ /* check item got removed if it was present before */
+ if (item)
+ {
+ assert_null(hash_lookup_by_value(nhash, (void *) i));
+ }
+ }
+ }
+
+ hash_free(hash);
+ hash_free(nhash);
+ gc_free(&gc);
+}
+
+
const struct CMUnitTest misc_tests[] = {
cmocka_unit_test(test_compat_lzo_string),
cmocka_unit_test(test_auth_fail_temp_no_flags),
cmocka_unit_test(test_auth_fail_temp_flags),
cmocka_unit_test(test_auth_fail_temp_flags_msg),
+ cmocka_unit_test(test_list)
};
int