]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lib: test-array - new equality testers
authorPhil Carmody <phil@dovecot.fi>
Tue, 25 Nov 2014 01:44:31 +0000 (03:44 +0200)
committerPhil Carmody <phil@dovecot.fi>
Tue, 25 Nov 2014 01:44:31 +0000 (03:44 +0200)
One using strings that get dereferenced, the other using the context pointer
to pass in external data.

Signed-off-by: Phil Carmody <phil@dovecot.fi>
src/lib/test-array.c

index 9021c2c8b8c672c787e5089486660d1f33cbab70..2b407c8ed8042971f9213214438f80bb121ee652 100644 (file)
@@ -52,7 +52,19 @@ static void test_array_reverse(void)
        }
        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 @@ static void test_array_cmp(void)
 
 #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 @@ static void test_array_cmp(void)
        }
        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 @@ static void test_array_cmp(void)
 
                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 @@ void test_array(void)
        test_array_foreach();
        test_array_reverse();
        test_array_cmp();
+       test_array_cmp_str();
 }