dovecot-2.2: lib: test-data-stack - too important a library not ...

dovecot at dovecot.org dovecot at dovecot.org
Mon Jul 28 13:54:27 UTC 2014


details:   http://hg.dovecot.org/dovecot-2.2/rev/1778c2e77cfa
changeset: 17641:1778c2e77cfa
user:      Phil Carmody <phil at dovecot.fi>
date:      Mon Jul 28 16:45:33 2014 +0300
description:
lib: test-data-stack - too important a library not to be thrashed hard
OK, it's thrashed a bit by other tests such as aqueue, str, etc., but these
tests attempt to probe all corner cases given detailed knowledge of the
limits of the block/frame implementation.

At the moment, no realloc functionality is tested, as with DEBUG builds
they would fail very noisily.

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

diffstat:

 src/lib/Makefile.am       |    1 +
 src/lib/test-data-stack.c |  119 ++++++++++++++++++++++++++++++++++++++++++++++
 src/lib/test-lib.c        |    1 +
 src/lib/test-lib.h        |    1 +
 4 files changed, 122 insertions(+), 0 deletions(-)

diffs (156 lines):

diff -r 3e7dbf85d034 -r 1778c2e77cfa src/lib/Makefile.am
--- a/src/lib/Makefile.am	Mon Jul 28 16:45:33 2014 +0300
+++ b/src/lib/Makefile.am	Mon Jul 28 16:45:33 2014 +0300
@@ -279,6 +279,7 @@
 	test-bsearch-insert-pos.c \
 	test-buffer.c \
 	test-crc32.c \
+	test-data-stack.c \
 	test-hash.c \
 	test-hash-format.c \
 	test-hash-method.c \
diff -r 3e7dbf85d034 -r 1778c2e77cfa src/lib/test-data-stack.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/lib/test-data-stack.c	Mon Jul 28 16:45:33 2014 +0300
@@ -0,0 +1,119 @@
+/* Copyright (c) 2014-2014 Dovecot authors, see the included COPYING file */
+
+#include "test-lib.h"
+#include "data-stack.h"
+#include <stdlib.h>
+
+static void test_ds_buffers(void)
+{
+	test_begin("data-stack buffer growth");
+	T_BEGIN {
+		size_t i;
+		unsigned char *p;
+		size_t left = t_get_bytes_available();
+		while (left < 10000) {
+			t_malloc(left); /* force a new block */
+			left = t_get_bytes_available();
+		}
+		left -= 64; /* make room for the sentry if DEBUG */
+		p = t_buffer_get(1);
+		p[0] = 1;
+		for (i = 2; i <= left; i++) {
+			/* grow it */
+			unsigned char *p2 = t_buffer_get(i);
+			test_assert_idx(p == p2, i);
+			p[i-1] = i;
+			test_assert_idx(p[i-2] == (unsigned char)(i-1), i);
+		}
+		/* now fix it permanently */
+		t_buffer_alloc_last_full();
+		test_assert(t_get_bytes_available() < 64 + MEM_ALIGN(1));
+	} T_END;
+	test_end();
+
+	test_begin("data-stack buffer interruption");
+	T_BEGIN {
+		void *b = t_buffer_get(1000);
+		void *a = t_malloc(1);
+		void *b2 = t_buffer_get(1001);
+		test_assert(a == b); /* expected, not guaranteed */
+		test_assert(b2 != b);
+	} T_END;
+	test_end();
+
+	test_begin("data-stack buffer with reallocs");
+	T_BEGIN {
+		size_t bigleft = t_get_bytes_available();
+		size_t i;
+		for (i = 1; i < bigleft-64; i += rand()%32) T_BEGIN {
+			unsigned char *p, *p2;
+			size_t left;
+			t_malloc(i);
+			left = t_get_bytes_available();
+			/* The most useful idx for the assert is 'left' */
+			test_assert_idx(left <= bigleft-i, left);
+			p = t_buffer_get(left/2);
+			p[0] = 'Z'; p[left/2 - 1] = 'Z';
+			p2 = t_buffer_get(left + left/2);
+			test_assert_idx(p != p2, left);
+			test_assert_idx(p[0] == 'Z', left);
+			test_assert_idx(p[left/2 -1] == 'Z', left);
+		} T_END;
+	} T_END;
+	test_end();
+}
+
+static void test_ds_recurse(int depth, int number, size_t size)
+{
+	int i;
+	char **ps;
+	char tag[2] = { depth+1, '\0' };
+	int try_fails = 0;
+	unsigned int t_id = t_push_named("test_ds_recurse[%i]", depth);
+	ps = t_buffer_get_type(char *, number);
+	test_assert_idx(ps != NULL, depth);
+	t_buffer_alloc_type(char *, number);
+
+	for (i = 0; i < number; i++) {
+		ps[i] = t_malloc(size/2);
+		bool re = t_try_realloc(ps[i], size);
+		test_assert_idx(ps[i] != NULL, i);
+		if (!re) {
+			try_fails++;
+			ps[i] = t_malloc(size);
+		}
+		/* drop our own canaries */
+		memset(ps[i], tag[0], size);
+		ps[i][size-2] = 0;
+	}
+
+	/* Now recurse... */
+	if(depth>0)
+		test_ds_recurse(depth-1, number, size);
+
+	/* Test our canaries are still intact */
+	for (i = 0; i < number; i++) {
+		test_assert_idx(strspn(ps[i], tag) == size - 2, i);
+		test_assert_idx(ps[i][size-1] == tag[0], i);
+	}
+	test_assert_idx(t_id == t_pop(), depth);
+}
+
+static void test_ds_recursive(int count, int depth)
+{
+	int i;
+
+	test_begin("data-stack recursive");
+	for(i = 0; i < count; i++) T_BEGIN {
+			int number=rand()%100+50;
+			int size=rand()%100+50;
+			test_ds_recurse(depth, number, size);
+		} T_END;
+	test_end();
+}
+
+void test_data_stack(void)
+{
+	test_ds_buffers();
+	test_ds_recursive(20, 80);
+}
diff -r 3e7dbf85d034 -r 1778c2e77cfa src/lib/test-lib.c
--- a/src/lib/test-lib.c	Mon Jul 28 16:45:33 2014 +0300
+++ b/src/lib/test-lib.c	Mon Jul 28 16:45:33 2014 +0300
@@ -12,6 +12,7 @@
 		test_bsearch_insert_pos,
 		test_buffer,
 		test_crc32,
+		test_data_stack,
 		test_hash,
 		test_hash_format,
 		test_hash_method,
diff -r 3e7dbf85d034 -r 1778c2e77cfa src/lib/test-lib.h
--- a/src/lib/test-lib.h	Mon Jul 28 16:45:33 2014 +0300
+++ b/src/lib/test-lib.h	Mon Jul 28 16:45:33 2014 +0300
@@ -11,6 +11,7 @@
 void test_bsearch_insert_pos(void);
 void test_buffer(void);
 void test_crc32(void);
+void test_data_stack(void);
 void test_hash(void);
 void test_hash_format(void);
 void test_hash_method(void);


More information about the dovecot-cvs mailing list