]> granicus.if.org Git - libevent/commitdiff
More unit tests for evbuffer_add_reference to make sure that certain interleaved...
authorNick Mathewson <nickm@torproject.org>
Tue, 10 Feb 2009 19:38:54 +0000 (19:38 +0000)
committerNick Mathewson <nickm@torproject.org>
Tue, 10 Feb 2009 19:38:54 +0000 (19:38 +0000)
svn:r1107

test/regress_buffer.c

index 8bf3aac0539d0d0055b19def531a8717a7dbb489..ed50deb1abaa33d884fe5c83dc3eb5d05d468faf 100644 (file)
@@ -274,7 +274,7 @@ test_evbuffer_readln(void *ptr)
 
 #define tt_line_eq(content)                                            \
        TT_STMT_BEGIN                                                   \
-       if (!cp || sz != strlen(content) || strcmp(cp, content)) {      \
+       if (!cp || sz != strlen(content) || strcmp(cp, content)) {      \
                TT_DIE(("Wanted %s; got %s [%d]", content, cp, (int)sz)); \
        }                                                               \
        TT_STMT_END
@@ -481,7 +481,7 @@ test_evbuffer_find(void *ptr)
        evbuffer_add(buf, (u_char*)test2, strlen(test2));
        evbuffer_validate(buf);
        p = evbuffer_find(buf, (u_char*)"\r\n", 2);
-        tt_want(p == NULL);
+       tt_want(p == NULL);
 
        /*
         * drain the buffer and do another find; in r309 this would
@@ -495,16 +495,16 @@ test_evbuffer_find(void *ptr)
        evbuffer_add(buf, (u_char *)test3, EVBUFFER_INITIAL_LENGTH);
        evbuffer_validate(buf);
        p = evbuffer_find(buf, (u_char *)"xy", 2);
-        tt_want(p == NULL);
+       tt_want(p == NULL);
 
        /* simple test for match at end of allocated buffer */
        p = evbuffer_find(buf, (u_char *)"ax", 2);
-        tt_assert(p != NULL);
-        tt_want(strncmp((char*)p, "ax", 2) == 0);
+       tt_assert(p != NULL);
+       tt_want(strncmp((char*)p, "ax", 2) == 0);
 
 end:
-        if (buf)
-                evbuffer_free(buf);
+       if (buf)
+               evbuffer_free(buf);
 }
 
 static void
@@ -598,6 +598,85 @@ test_evbuffer_callbacks(void *ptr)
                evbuffer_free(buf_out2);
 }
 
+static int ref_done_cb_called_count = 0;
+static void *ref_done_cb_called_with = NULL;
+static void ref_done_cb(void *data)
+{
+       ++ref_done_cb_called_count;
+       ref_done_cb_called_with = data;
+}
+
+static void
+test_evbuffer_add_reference(void *ptr)
+{
+       const char chunk1[] = "If you have found the answer to such a problem";
+       const char chunk2[] = "you ought to write it up for publication";
+                         /* -- Knuth's "Notes on the Exercises" from TAOCP */
+       char tmp[16];
+       size_t len1 = strlen(chunk1), len2=strlen(chunk2);
+
+       struct evbuffer *buf1 = NULL, *buf2 = NULL;
+
+       buf1 = evbuffer_new();
+       tt_assert(buf1);
+
+       evbuffer_add_reference(buf1, chunk1, len1, ref_done_cb, (void*)111);
+       evbuffer_add(buf1, ", ", 2);
+       evbuffer_add_reference(buf1, chunk2, len2, ref_done_cb, (void*)222);
+       tt_int_op(evbuffer_get_length(buf1), ==, len1+len2+2);
+
+       /* Make sure we can drain a little from a reference. */
+       tt_int_op(evbuffer_remove(buf1, tmp, 6), ==, 6);
+       tt_int_op(memcmp(tmp, "If you", 6), ==, 0);
+       tt_int_op(evbuffer_remove(buf1, tmp, 5), ==, 5);
+       tt_int_op(memcmp(tmp, " have", 5), ==, 0);
+
+       /* Make sure that prepending does not meddle with immutable data */
+       tt_int_op(evbuffer_prepend(buf1, "I have ", 7), ==, 0);
+       tt_int_op(memcmp(chunk1, "If you", 6), ==, 0);
+
+       /* Make sure that when the chunk is over, the callback is invoked. */
+       evbuffer_drain(buf1, 7); /* Remove prepended stuff. */
+       evbuffer_drain(buf1, len1-11-1); /* remove all but one byte of chunk1 */
+       tt_int_op(ref_done_cb_called_count, ==, 0);
+       evbuffer_remove(buf1, tmp, 1);
+       tt_int_op(tmp[0], ==, 'm');
+       tt_assert(ref_done_cb_called_with == (void*)111);
+       tt_int_op(ref_done_cb_called_count, ==, 1);
+
+       /* Drain some of the remaining chunk, then add it to another buffer */
+       evbuffer_drain(buf1, 6); /* Remove the ", you ". */
+       buf2 = evbuffer_new();
+       tt_assert(buf2);
+       tt_int_op(ref_done_cb_called_count, ==, 1);
+       evbuffer_add(buf2, "I ", 2);
+
+       evbuffer_add_buffer(buf2, buf1);
+       tt_int_op(ref_done_cb_called_count, ==, 1);
+       evbuffer_remove(buf2, tmp, 16);
+       tt_int_op(memcmp("I ought to write", tmp, 16), ==, 0);
+       evbuffer_drain(buf2, evbuffer_get_length(buf2));
+       tt_int_op(ref_done_cb_called_count, ==, 2);
+       tt_assert(ref_done_cb_called_with == (void*)222);
+
+       /* Now add more stuff to buf1 and make sure that it gets removed on
+        * free. */
+       evbuffer_add(buf1, "You shake and shake the ", 24);
+       evbuffer_add_reference(buf1, "ketchup bottle", 14, ref_done_cb,
+           (void*)3333);
+       evbuffer_add(buf1, ". Nothing comes and then a lot'll.", 42);
+       evbuffer_free(buf1);
+       buf1 = NULL;
+       tt_int_op(ref_done_cb_called_count, ==, 3);
+       tt_assert(ref_done_cb_called_with == (void*)3333);
+
+end:
+       if (buf1)
+               evbuffer_free(buf1);
+       if (buf2)
+               evbuffer_free(buf2);
+}
+
 struct testcase_t evbuffer_testcases[] = {
        { "evbuffer", test_evbuffer, 0, NULL, NULL },
        { "reference", test_evbuffer_reference, 0, NULL, NULL },
@@ -605,6 +684,7 @@ struct testcase_t evbuffer_testcases[] = {
        { "readln", test_evbuffer_readln, 0, NULL, NULL },
        { "find", test_evbuffer_find, 0, NULL, NULL },
        { "callbacks", test_evbuffer_callbacks, 0, NULL, NULL },
+       { "add_reference", test_evbuffer_add_reference, 0, NULL, NULL },
 
        END_OF_TESTCASES
 };