dovecot-2.2: lib: test-array - new equality testers

dovecot at dovecot.org dovecot at dovecot.org
Tue Nov 25 01:54:01 UTC 2014


details:   http://hg.dovecot.org/dovecot-2.2/rev/5522d5ce87a5
changeset: 18112:5522d5ce87a5
user:      Phil Carmody <phil at dovecot.fi>
date:      Tue Nov 25 03:44:31 2014 +0200
description:
lib: test-array - new equality testers
One using strings that get dereferenced, the other using the context pointer
to pass in external data.

Signed-off-by: Phil Carmody <phil at dovecot.fi>

diffstat:

 src/lib/test-array.c |  87 ++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 85 insertions(+), 2 deletions(-)

diffs (127 lines):

diff -r b8ac4e5a1002 -r 5522d5ce87a5 src/lib/test-array.c
--- a/src/lib/test-array.c	Tue Nov 25 03:43:02 2014 +0200
+++ b/src/lib/test-array.c	Tue Nov 25 03:44:31 2014 +0200
@@ -52,7 +52,19 @@
 	}
 	test_end();
 }
-
+static int test_compare_ushort(const unsigned short *c1, const unsigned short *c2)
+{
+	return *c1 > *c2 ? 1
+		: *c1 < *c2 ? -1
+		: 0;
+}
+static int test_compare_ushort_fuzz(const unsigned short *c1, const unsigned short *c2, const int *pfuzz)
+{
+	int d = (int)*c1 - (int)*c2;
+	if (d <= *pfuzz && -d <= *pfuzz)
+		return 0;
+	return d;
+}
 static void test_array_cmp(void)
 {
 	static const unsigned short deltas[] = {
@@ -62,8 +74,9 @@
 
 #define NELEMS 5u
 	ARRAY(unsigned short) arr1, arr2;
-	unsigned short elems[NELEMS];
+	unsigned short elems[NELEMS+1];
 	unsigned int i;
+	int fuzz;
 
 	test_begin("array compare (ushort)");
 	t_array_init(&arr1, NELEMS);
@@ -74,6 +87,10 @@
 	}
 	array_append(&arr1, elems, NELEMS);
 	test_assert(array_cmp(&arr1, &arr2) == 1);
+	test_assert(array_equal_fn(&arr1, &arr2, test_compare_ushort) == 1);
+	fuzz = 0;
+	test_assert(array_equal_fn_ctx(&arr1, &arr2, test_compare_ushort_fuzz, &fuzz) == 1);
+
 	for (i = 0; i < 256; i++) {
 		unsigned int j = rand() % NELEMS;
 		unsigned short tmp = *array_idx(&arr2, j);
@@ -81,9 +98,74 @@
 
 		array_idx_set(&arr2, j, &repl);
 		test_assert_idx(array_cmp(&arr1, &arr2) == (tmp == repl), i);
+		test_assert_idx(array_equal_fn(&arr1, &arr2, test_compare_ushort) == (tmp == repl), i);
+		fuzz = (int)tmp - (int)repl;
+		if (fuzz < 0)
+			fuzz = -fuzz;
+		test_assert_idx(array_equal_fn_ctx(&arr1, &arr2, test_compare_ushort_fuzz, &fuzz) == 1, i);
+		if (fuzz > 0) {
+			fuzz--;
+			test_assert_idx(array_equal_fn_ctx(&arr1, &arr2, test_compare_ushort_fuzz, &fuzz) == 0, i);
+		}
 		array_idx_set(&arr2, j, &tmp);
 		test_assert_idx(array_cmp(&arr1, &arr2) == TRUE, i);
+		test_assert_idx(array_equal_fn(&arr1, &arr2, test_compare_ushort) == 1, i);
+		fuzz = 0;
+		test_assert_idx(array_equal_fn_ctx(&arr1, &arr2, test_compare_ushort_fuzz, &fuzz) == 1, i);
 	}
+	elems[NELEMS] = 0;
+	array_append(&arr2, &elems[NELEMS], 1);
+	test_assert(array_cmp(&arr1, &arr2) == 0);
+	test_assert(array_equal_fn(&arr1, &arr2, test_compare_ushort) == 0);
+	test_assert_idx(array_equal_fn_ctx(&arr1, &arr2, test_compare_ushort_fuzz, &fuzz) == 0, i);
+
+	test_end();
+}
+
+static int test_compare_string(const char *const *c1, const char *const *c2)
+{
+	return strcmp(*c1, *c2);
+}
+static void test_array_cmp_str(void)
+{
+#define NELEMS 5u
+	ARRAY(const char *) arr1, arr2;
+	const char *elemstrs[NELEMS+1];
+	unsigned int i;
+
+	test_begin("array compare (char*)");
+	t_array_init(&arr1, NELEMS);
+	t_array_init(&arr2, NELEMS);
+	for (i = 0; i < NELEMS; i++) {
+		elemstrs[i] = t_strdup_printf("%x", rand()); /* never 0-length */
+		array_append(&arr2, &elemstrs[i], 1);
+	}
+	array_append(&arr1, elemstrs, NELEMS);
+	test_assert(array_cmp(&arr1, &arr2) == 1); /* pointers shared, so identical */
+	test_assert(array_equal_fn(&arr1, &arr2, test_compare_string) == 1); /* therefore value same */
+	for (i = 0; i < 2560; i++) {
+		unsigned int j = rand() % NELEMS;
+		const char *ostr = *array_idx(&arr2, j);
+		unsigned int olen = strlen(ostr);
+		unsigned int rc = rand() % (olen + 1);
+		char ochar = ostr[rc];
+		char buf[12];
+		const char *bufp = buf;
+		memcpy(buf, ostr, olen+1);
+		buf[rc] = rand() % (CHAR_MAX + 1 - CHAR_MIN) + CHAR_MIN;
+		if(rc == olen)
+			buf[rc+1] = '\0';
+		array_idx_set(&arr2, j, &bufp);
+		test_assert(array_cmp(&arr1, &arr2) == 0); /* pointers now differ */
+		test_assert_idx(array_equal_fn(&arr1, &arr2, test_compare_string)
+				== (strcmp(ostr, buf) == 0), i); /* sometimes still the same */
+		test_assert_idx(array_equal_fn(&arr1, &arr2, test_compare_string)
+				== (ochar == buf[rc]), i); /* ditto */
+		array_idx_set(&arr2, j, &ostr);
+		test_assert(array_cmp(&arr1, &arr2) == 1); /* pointers now same again */
+		test_assert_idx(array_equal_fn(&arr1, &arr2, test_compare_string) == 1, i); /* duh! */
+	}
+	/* length differences being detected are tested in other tests */
 	test_end();
 }
 
@@ -92,4 +174,5 @@
 	test_array_foreach();
 	test_array_reverse();
 	test_array_cmp();
+	test_array_cmp_str();
 }


More information about the dovecot-cvs mailing list