aboutsummaryrefslogtreecommitdiff
path: root/test/regress_buffer.c
diff options
context:
space:
mode:
authorJosh Gao <jmgao@google.com>2017-08-10 12:30:25 -0700
committerJosh Gao <jmgao@google.com>2017-08-10 12:30:47 -0700
commit83a0c9c65a60a92d3ea5542596b3ba56db492c37 (patch)
tree64bb0c050c4db9ad9d721e05e3e199bfd02e60b0 /test/regress_buffer.c
parentaf241a5c8c2cde0fab7d7d563276c1095b00e3b4 (diff)
downloadlibevent-o-iot-preview-5.tar.gz
Revert "Upgrade to 2.1.8-stable (2017-01-22)." and "Probably Mac build fix?"android-o-iot-preview-5o-iot-preview-5
This reverts commits 2a572d125a91a4aafd3ad8ce87259fc640fa0763 and af241a5c8c2cde0fab7d7d563276c1095b00e3b4, which break tombstoned. Bug: http://b/64543673 Test: manual + treehugger
Diffstat (limited to 'test/regress_buffer.c')
-rw-r--r--test/regress_buffer.c2563
1 files changed, 0 insertions, 2563 deletions
diff --git a/test/regress_buffer.c b/test/regress_buffer.c
deleted file mode 100644
index 1af75f5..0000000
--- a/test/regress_buffer.c
+++ /dev/null
@@ -1,2563 +0,0 @@
-/*
- * Copyright (c) 2003-2007 Niels Provos <provos@citi.umich.edu>
- * Copyright (c) 2007-2012 Niels Provos and Nick Mathewson
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-#include "util-internal.h"
-
-#ifdef _WIN32
-#include <winsock2.h>
-#include <windows.h>
-#endif
-
-#include "event2/event-config.h"
-
-#include <sys/types.h>
-#include <sys/stat.h>
-#ifdef EVENT__HAVE_SYS_TIME_H
-#include <sys/time.h>
-#endif
-#include <sys/queue.h>
-#ifndef _WIN32
-#include <sys/socket.h>
-#include <sys/wait.h>
-#include <signal.h>
-#include <unistd.h>
-#include <netdb.h>
-#endif
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <errno.h>
-#include <assert.h>
-
-#include "event2/event.h"
-#include "event2/buffer.h"
-#include "event2/buffer_compat.h"
-#include "event2/util.h"
-
-#include "defer-internal.h"
-#include "evbuffer-internal.h"
-#include "log-internal.h"
-
-#include "regress.h"
-
-/* Validates that an evbuffer is good. Returns false if it isn't, true if it
- * is*/
-static int
-evbuffer_validate_(struct evbuffer *buf)
-{
- struct evbuffer_chain *chain;
- size_t sum = 0;
- int found_last_with_datap = 0;
-
- if (buf->first == NULL) {
- tt_assert(buf->last == NULL);
- tt_assert(buf->total_len == 0);
- }
-
- chain = buf->first;
-
- tt_assert(buf->last_with_datap);
- if (buf->last_with_datap == &buf->first)
- found_last_with_datap = 1;
-
- while (chain != NULL) {
- if (&chain->next == buf->last_with_datap)
- found_last_with_datap = 1;
- sum += chain->off;
- if (chain->next == NULL) {
- tt_assert(buf->last == chain);
- }
- tt_assert(chain->buffer_len >= chain->misalign + chain->off);
- chain = chain->next;
- }
-
- if (buf->first)
- tt_assert(*buf->last_with_datap);
-
- if (*buf->last_with_datap) {
- chain = *buf->last_with_datap;
- if (chain->off == 0 || buf->total_len == 0) {
- tt_assert(chain->off == 0)
- tt_assert(chain == buf->first);
- tt_assert(buf->total_len == 0);
- }
- chain = chain->next;
- while (chain != NULL) {
- tt_assert(chain->off == 0);
- chain = chain->next;
- }
- } else {
- tt_assert(buf->last_with_datap == &buf->first);
- }
- tt_assert(found_last_with_datap);
-
- tt_assert(sum == buf->total_len);
- return 1;
- end:
- return 0;
-}
-
-static void
-evbuffer_get_waste(struct evbuffer *buf, size_t *allocatedp, size_t *wastedp, size_t *usedp)
-{
- struct evbuffer_chain *chain;
- size_t a, w, u;
- int n = 0;
- u = a = w = 0;
-
- chain = buf->first;
- /* skip empty at start */
- while (chain && chain->off==0) {
- ++n;
- a += chain->buffer_len;
- chain = chain->next;
- }
- /* first nonempty chain: stuff at the end only is wasted. */
- if (chain) {
- ++n;
- a += chain->buffer_len;
- u += chain->off;
- if (chain->next && chain->next->off)
- w += (size_t)(chain->buffer_len - (chain->misalign + chain->off));
- chain = chain->next;
- }
- /* subsequent nonempty chains */
- while (chain && chain->off) {
- ++n;
- a += chain->buffer_len;
- w += (size_t)chain->misalign;
- u += chain->off;
- if (chain->next && chain->next->off)
- w += (size_t) (chain->buffer_len - (chain->misalign + chain->off));
- chain = chain->next;
- }
- /* subsequent empty chains */
- while (chain) {
- ++n;
- a += chain->buffer_len;
- }
- *allocatedp = a;
- *wastedp = w;
- *usedp = u;
-}
-
-#define evbuffer_validate(buf) \
- TT_STMT_BEGIN if (!evbuffer_validate_(buf)) TT_DIE(("Buffer format invalid")); TT_STMT_END
-
-static void
-test_evbuffer(void *ptr)
-{
- static char buffer[512], *tmp;
- struct evbuffer *evb = evbuffer_new();
- struct evbuffer *evb_two = evbuffer_new();
- size_t sz_tmp;
- int i;
-
- evbuffer_validate(evb);
- evbuffer_add_printf(evb, "%s/%d", "hello", 1);
- evbuffer_validate(evb);
-
- tt_assert(evbuffer_get_length(evb) == 7);
- tt_assert(!memcmp((char*)EVBUFFER_DATA(evb), "hello/1", 1));
-
- evbuffer_add_buffer(evb, evb_two);
- evbuffer_validate(evb);
-
- evbuffer_drain(evb, strlen("hello/"));
- evbuffer_validate(evb);
- tt_assert(evbuffer_get_length(evb) == 1);
- tt_assert(!memcmp((char*)EVBUFFER_DATA(evb), "1", 1));
-
- evbuffer_add_printf(evb_two, "%s", "/hello");
- evbuffer_validate(evb);
- evbuffer_add_buffer(evb, evb_two);
- evbuffer_validate(evb);
-
- tt_assert(evbuffer_get_length(evb_two) == 0);
- tt_assert(evbuffer_get_length(evb) == 7);
- tt_assert(!memcmp((char*)EVBUFFER_DATA(evb), "1/hello", 7));
-
- memset(buffer, 0, sizeof(buffer));
- evbuffer_add(evb, buffer, sizeof(buffer));
- evbuffer_validate(evb);
- tt_assert(evbuffer_get_length(evb) == 7 + 512);
-
- tmp = (char *)evbuffer_pullup(evb, 7 + 512);
- tt_assert(tmp);
- tt_assert(!strncmp(tmp, "1/hello", 7));
- tt_assert(!memcmp(tmp + 7, buffer, sizeof(buffer)));
- evbuffer_validate(evb);
-
- evbuffer_prepend(evb, "something", 9);
- evbuffer_validate(evb);
- evbuffer_prepend(evb, "else", 4);
- evbuffer_validate(evb);
-
- tmp = (char *)evbuffer_pullup(evb, 4 + 9 + 7);
- tt_assert(!strncmp(tmp, "elsesomething1/hello", 4 + 9 + 7));
- evbuffer_validate(evb);
-
- evbuffer_drain(evb, -1);
- evbuffer_validate(evb);
- evbuffer_drain(evb_two, -1);
- evbuffer_validate(evb);
-
- for (i = 0; i < 3; ++i) {
- evbuffer_add(evb_two, buffer, sizeof(buffer));
- evbuffer_validate(evb_two);
- evbuffer_add_buffer(evb, evb_two);
- evbuffer_validate(evb);
- evbuffer_validate(evb_two);
- }
-
- tt_assert(evbuffer_get_length(evb_two) == 0);
- tt_assert(evbuffer_get_length(evb) == i * sizeof(buffer));
-
- /* test remove buffer */
- sz_tmp = (size_t)(sizeof(buffer)*2.5);
- evbuffer_remove_buffer(evb, evb_two, sz_tmp);
- tt_assert(evbuffer_get_length(evb_two) == sz_tmp);
- tt_assert(evbuffer_get_length(evb) == sizeof(buffer) / 2);
- evbuffer_validate(evb);
-
- if (memcmp(evbuffer_pullup(
- evb, -1), buffer, sizeof(buffer) / 2) != 0 ||
- memcmp(evbuffer_pullup(
- evb_two, -1), buffer, sizeof(buffer)) != 0)
- tt_abort_msg("Pullup did not preserve content");
-
- evbuffer_validate(evb);
-
-
- /* testing one-vector reserve and commit */
- {
- struct evbuffer_iovec v[1];
- char *buf;
- int i, j, r;
-
- for (i = 0; i < 3; ++i) {
- r = evbuffer_reserve_space(evb, 10000, v, 1);
- tt_int_op(r, ==, 1);
- tt_assert(v[0].iov_len >= 10000);
- tt_assert(v[0].iov_base != NULL);
-
- evbuffer_validate(evb);
- buf = v[0].iov_base;
- for (j = 0; j < 10000; ++j) {
- buf[j] = j;
- }
- evbuffer_validate(evb);
-
- tt_int_op(evbuffer_commit_space(evb, v, 1), ==, 0);
- evbuffer_validate(evb);
-
- tt_assert(evbuffer_get_length(evb) >= 10000);
-
- evbuffer_drain(evb, j * 5000);
- evbuffer_validate(evb);
- }
- }
-
- end:
- evbuffer_free(evb);
- evbuffer_free(evb_two);
-}
-
-static void
-no_cleanup(const void *data, size_t datalen, void *extra)
-{
-}
-
-static void
-test_evbuffer_remove_buffer_with_empty(void *ptr)
-{
- struct evbuffer *src = evbuffer_new();
- struct evbuffer *dst = evbuffer_new();
- char buf[2];
-
- evbuffer_validate(src);
- evbuffer_validate(dst);
-
- /* setup the buffers */
- /* we need more data in src than we will move later */
- evbuffer_add_reference(src, buf, sizeof(buf), no_cleanup, NULL);
- evbuffer_add_reference(src, buf, sizeof(buf), no_cleanup, NULL);
- /* we need one buffer in dst and one empty buffer at the end */
- evbuffer_add(dst, buf, sizeof(buf));
- evbuffer_add_reference(dst, buf, 0, no_cleanup, NULL);
-
- evbuffer_validate(src);
- evbuffer_validate(dst);
-
- /* move three bytes over */
- evbuffer_remove_buffer(src, dst, 3);
-
- evbuffer_validate(src);
- evbuffer_validate(dst);
-
-end:
- evbuffer_free(src);
- evbuffer_free(dst);
-}
-
-static void
-test_evbuffer_remove_buffer_with_empty2(void *ptr)
-{
- struct evbuffer *src = evbuffer_new();
- struct evbuffer *dst = evbuffer_new();
- struct evbuffer *buf = evbuffer_new();
-
- evbuffer_add(buf, "foo", 3);
- evbuffer_add_reference(buf, "foo", 3, NULL, NULL);
-
- evbuffer_add_reference(src, "foo", 3, NULL, NULL);
- evbuffer_add_reference(src, NULL, 0, NULL, NULL);
- evbuffer_add_buffer(src, buf);
-
- evbuffer_add(buf, "foo", 3);
- evbuffer_add_reference(buf, "foo", 3, NULL, NULL);
-
- evbuffer_add_reference(dst, "foo", 3, NULL, NULL);
- evbuffer_add_reference(dst, NULL, 0, NULL, NULL);
- evbuffer_add_buffer(dst, buf);
-
- tt_int_op(evbuffer_get_length(src), ==, 9);
- tt_int_op(evbuffer_get_length(dst), ==, 9);
-
- evbuffer_validate(src);
- evbuffer_validate(dst);
-
- evbuffer_remove_buffer(src, dst, 8);
-
- evbuffer_validate(src);
- evbuffer_validate(dst);
-
- tt_int_op(evbuffer_get_length(src), ==, 1);
- tt_int_op(evbuffer_get_length(dst), ==, 17);
-
- end:
- evbuffer_free(src);
- evbuffer_free(dst);
- evbuffer_free(buf);
-}
-
-static void
-test_evbuffer_remove_buffer_with_empty3(void *ptr)
-{
- struct evbuffer *src = evbuffer_new();
- struct evbuffer *dst = evbuffer_new();
- struct evbuffer *buf = evbuffer_new();
-
- evbuffer_add(buf, "foo", 3);
- evbuffer_add_reference(buf, NULL, 0, NULL, NULL);
-
- evbuffer_add_reference(src, "foo", 3, NULL, NULL);
- evbuffer_add_reference(src, NULL, 0, NULL, NULL);
- evbuffer_prepend_buffer(src, buf);
-
- evbuffer_add(buf, "foo", 3);
- evbuffer_add_reference(buf, NULL, 0, NULL, NULL);
-
- evbuffer_add_reference(dst, "foo", 3, NULL, NULL);
- evbuffer_add_reference(dst, NULL, 0, NULL, NULL);
- evbuffer_prepend_buffer(dst, buf);
-
- tt_int_op(evbuffer_get_length(src), ==, 6);
- tt_int_op(evbuffer_get_length(dst), ==, 6);
-
- evbuffer_validate(src);
- evbuffer_validate(dst);
-
- evbuffer_remove_buffer(src, dst, 5);
-
- evbuffer_validate(src);
- evbuffer_validate(dst);
-
- tt_int_op(evbuffer_get_length(src), ==, 1);
- tt_int_op(evbuffer_get_length(dst), ==, 11);
-
- end:
- evbuffer_free(src);
- evbuffer_free(dst);
- evbuffer_free(buf);
-}
-
-static void
-test_evbuffer_add_buffer_with_empty(void *ptr)
-{
- struct evbuffer *src = evbuffer_new();
- struct evbuffer *dst = evbuffer_new();
- struct evbuffer *buf = evbuffer_new();
-
- evbuffer_add(buf, "foo", 3);
-
- evbuffer_add_reference(src, "foo", 3, NULL, NULL);
- evbuffer_add_reference(src, NULL, 0, NULL, NULL);
- evbuffer_add_buffer(src, buf);
-
- evbuffer_add(buf, "foo", 3);
-
- evbuffer_add_reference(dst, "foo", 3, NULL, NULL);
- evbuffer_add_reference(dst, NULL, 0, NULL, NULL);
- evbuffer_add_buffer(dst, buf);
-
- tt_int_op(evbuffer_get_length(src), ==, 6);
- tt_int_op(evbuffer_get_length(dst), ==, 6);
-
- evbuffer_validate(src);
- evbuffer_validate(dst);
-
- end:
- evbuffer_free(src);
- evbuffer_free(dst);
- evbuffer_free(buf);
-}
-
-static void
-test_evbuffer_add_buffer_with_empty2(void *ptr)
-{
- struct evbuffer *src = evbuffer_new();
- struct evbuffer *dst = evbuffer_new();
- struct evbuffer *buf = evbuffer_new();
-
- evbuffer_add(buf, "foo", 3);
-
- evbuffer_add_reference(src, NULL, 0, NULL, NULL);
- evbuffer_add_buffer(src, buf);
-
- evbuffer_add(buf, "foo", 3);
-
- evbuffer_add_reference(dst, NULL, 0, NULL, NULL);
- evbuffer_add_buffer(dst, buf);
-
- tt_int_op(evbuffer_get_length(src), ==, 3);
- tt_int_op(evbuffer_get_length(dst), ==, 3);
-
- evbuffer_validate(src);
- evbuffer_validate(dst);
-
- end:
- evbuffer_free(src);
- evbuffer_free(dst);
- evbuffer_free(buf);
-}
-
-static void
-test_evbuffer_reserve2(void *ptr)
-{
- /* Test the two-vector cases of reserve/commit. */
- struct evbuffer *buf = evbuffer_new();
- int n, i;
- struct evbuffer_iovec v[2];
- size_t remaining;
- char *cp, *cp2;
-
- /* First chunk will necessarily be one chunk. Use 512 bytes of it.*/
- n = evbuffer_reserve_space(buf, 1024, v, 2);
- tt_int_op(n, ==, 1);
- tt_int_op(evbuffer_get_length(buf), ==, 0);
- tt_assert(v[0].iov_base != NULL);
- tt_int_op(v[0].iov_len, >=, 1024);
- memset(v[0].iov_base, 'X', 512);
- cp = v[0].iov_base;
- remaining = v[0].iov_len - 512;
- v[0].iov_len = 512;
- evbuffer_validate(buf);
- tt_int_op(0, ==, evbuffer_commit_space(buf, v, 1));
- tt_int_op(evbuffer_get_length(buf), ==, 512);
- evbuffer_validate(buf);
-
- /* Ask for another same-chunk request, in an existing chunk. Use 8
- * bytes of it. */
- n = evbuffer_reserve_space(buf, 32, v, 2);
- tt_int_op(n, ==, 1);
- tt_assert(cp + 512 == v[0].iov_base);
- tt_int_op(remaining, ==, v[0].iov_len);
- memset(v[0].iov_base, 'Y', 8);
- v[0].iov_len = 8;
- tt_int_op(0, ==, evbuffer_commit_space(buf, v, 1));
- tt_int_op(evbuffer_get_length(buf), ==, 520);
- remaining -= 8;
- evbuffer_validate(buf);
-
- /* Now ask for a request that will be split. Use only one byte of it,
- though. */
- n = evbuffer_reserve_space(buf, remaining+64, v, 2);
- tt_int_op(n, ==, 2);
- tt_assert(cp + 520 == v[0].iov_base);
- tt_int_op(remaining, ==, v[0].iov_len);
- tt_assert(v[1].iov_base);
- tt_assert(v[1].iov_len >= 64);
- cp2 = v[1].iov_base;
- memset(v[0].iov_base, 'Z', 1);
- v[0].iov_len = 1;
- tt_int_op(0, ==, evbuffer_commit_space(buf, v, 1));
- tt_int_op(evbuffer_get_length(buf), ==, 521);
- remaining -= 1;
- evbuffer_validate(buf);
-
- /* Now ask for a request that will be split. Use some of the first
- * part and some of the second. */
- n = evbuffer_reserve_space(buf, remaining+64, v, 2);
- evbuffer_validate(buf);
- tt_int_op(n, ==, 2);
- tt_assert(cp + 521 == v[0].iov_base);
- tt_int_op(remaining, ==, v[0].iov_len);
- tt_assert(v[1].iov_base == cp2);
- tt_assert(v[1].iov_len >= 64);
- memset(v[0].iov_base, 'W', 400);
- v[0].iov_len = 400;
- memset(v[1].iov_base, 'x', 60);
- v[1].iov_len = 60;
- tt_int_op(0, ==, evbuffer_commit_space(buf, v, 2));
- tt_int_op(evbuffer_get_length(buf), ==, 981);
- evbuffer_validate(buf);
-
- /* Now peek to make sure stuff got made how we like. */
- memset(v,0,sizeof(v));
- n = evbuffer_peek(buf, -1, NULL, v, 2);
- tt_int_op(n, ==, 2);
- tt_int_op(v[0].iov_len, ==, 921);
- tt_int_op(v[1].iov_len, ==, 60);
-
- cp = v[0].iov_base;
- for (i=0; i<512; ++i)
- tt_int_op(cp[i], ==, 'X');
- for (i=512; i<520; ++i)
- tt_int_op(cp[i], ==, 'Y');
- for (i=520; i<521; ++i)
- tt_int_op(cp[i], ==, 'Z');
- for (i=521; i<921; ++i)
- tt_int_op(cp[i], ==, 'W');
-
- cp = v[1].iov_base;
- for (i=0; i<60; ++i)
- tt_int_op(cp[i], ==, 'x');
-
-end:
- evbuffer_free(buf);
-}
-
-static void
-test_evbuffer_reserve_many(void *ptr)
-{
- /* This is a glass-box test to handle expanding a buffer with more
- * chunks and reallocating chunks as needed */
- struct evbuffer *buf = evbuffer_new();
- struct evbuffer_iovec v[8];
- int n;
- size_t sz;
- int add_data = ptr && !strcmp(ptr, "add");
- int fill_first = ptr && !strcmp(ptr, "fill");
- char *cp1, *cp2;
-
- /* When reserving the the first chunk, we just allocate it */
- n = evbuffer_reserve_space(buf, 128, v, 2);
- evbuffer_validate(buf);
- tt_int_op(n, ==, 1);
- tt_assert(v[0].iov_len >= 128);
- sz = v[0].iov_len;
- cp1 = v[0].iov_base;
- if (add_data) {
- *(char*)v[0].iov_base = 'X';
- v[0].iov_len = 1;
- n = evbuffer_commit_space(buf, v, 1);
- tt_int_op(n, ==, 0);
- } else if (fill_first) {
- memset(v[0].iov_base, 'X', v[0].iov_len);
- n = evbuffer_commit_space(buf, v, 1);
- tt_int_op(n, ==, 0);
- n = evbuffer_reserve_space(buf, 128, v, 2);
- tt_int_op(n, ==, 1);
- sz = v[0].iov_len;
- tt_assert(v[0].iov_base != cp1);
- cp1 = v[0].iov_base;
- }
-
- /* Make another chunk get added. */
- n = evbuffer_reserve_space(buf, sz+128, v, 2);
- evbuffer_validate(buf);
- tt_int_op(n, ==, 2);
- sz = v[0].iov_len + v[1].iov_len;
- tt_int_op(sz, >=, v[0].iov_len+128);
- if (add_data) {
- tt_assert(v[0].iov_base == cp1 + 1);
- } else {
- tt_assert(v[0].iov_base == cp1);
- }
- cp1 = v[0].iov_base;
- cp2 = v[1].iov_base;
-
- /* And a third chunk. */
- n = evbuffer_reserve_space(buf, sz+128, v, 3);
- evbuffer_validate(buf);
- tt_int_op(n, ==, 3);
- tt_assert(cp1 == v[0].iov_base);
- tt_assert(cp2 == v[1].iov_base);
- sz = v[0].iov_len + v[1].iov_len + v[2].iov_len;
-
- /* Now force a reallocation by asking for more space in only 2
- * buffers. */
- n = evbuffer_reserve_space(buf, sz+128, v, 2);
- evbuffer_validate(buf);
- if (add_data) {
- tt_int_op(n, ==, 2);
- tt_assert(cp1 == v[0].iov_base);
- } else {
- tt_int_op(n, ==, 1);
- }
-
-end:
- evbuffer_free(buf);
-}
-
-static void
-test_evbuffer_expand(void *ptr)
-{
- char data[4096];
- struct evbuffer *buf;
- size_t a,w,u;
- void *buffer;
-
- memset(data, 'X', sizeof(data));
-
- /* Make sure that expand() works on an empty buffer */
- buf = evbuffer_new();
- tt_int_op(evbuffer_expand(buf, 20000), ==, 0);
- evbuffer_validate(buf);
- a=w=u=0;
- evbuffer_get_waste(buf, &a,&w,&u);
- tt_assert(w == 0);
- tt_assert(u == 0);
- tt_assert(a >= 20000);
- tt_assert(buf->first);
- tt_assert(buf->first == buf->last);
- tt_assert(buf->first->off == 0);
- tt_assert(buf->first->buffer_len >= 20000);
-
- /* Make sure that expand() works as a no-op when there's enough
- * contiguous space already. */
- buffer = buf->first->buffer;
- evbuffer_add(buf, data, 1024);
- tt_int_op(evbuffer_expand(buf, 1024), ==, 0);
- tt_assert(buf->first->buffer == buffer);
- evbuffer_validate(buf);
- evbuffer_free(buf);
-
- /* Make sure that expand() can work by moving misaligned data
- * when it makes sense to do so. */
- buf = evbuffer_new();
- evbuffer_add(buf, data, 400);
- {
- int n = (int)(buf->first->buffer_len - buf->first->off - 1);
- tt_assert(n < (int)sizeof(data));
- evbuffer_add(buf, data, n);
- }
- tt_assert(buf->first == buf->last);
- tt_assert(buf->first->off == buf->first->buffer_len - 1);
- evbuffer_drain(buf, buf->first->off - 1);
- tt_assert(1 == evbuffer_get_length(buf));
- tt_assert(buf->first->misalign > 0);
- tt_assert(buf->first->off == 1);
- buffer = buf->first->buffer;
- tt_assert(evbuffer_expand(buf, 40) == 0);
- tt_assert(buf->first == buf->last);
- tt_assert(buf->first->off == 1);
- tt_assert(buf->first->buffer == buffer);
- tt_assert(buf->first->misalign == 0);
- evbuffer_validate(buf);
- evbuffer_free(buf);
-
- /* add, expand, pull-up: This used to crash libevent. */
- buf = evbuffer_new();
-
- evbuffer_add(buf, data, sizeof(data));
- evbuffer_add(buf, data, sizeof(data));
- evbuffer_add(buf, data, sizeof(data));
-
- evbuffer_validate(buf);
- evbuffer_expand(buf, 1024);
- evbuffer_validate(buf);
- evbuffer_pullup(buf, -1);
- evbuffer_validate(buf);
-
-end:
- evbuffer_free(buf);
-}
-
-static void
-test_evbuffer_expand_overflow(void *ptr)
-{
- struct evbuffer *buf;
-
- buf = evbuffer_new();
- evbuffer_add(buf, "1", 1);
- evbuffer_expand(buf, EVBUFFER_CHAIN_MAX);
- evbuffer_validate(buf);
-
- evbuffer_expand(buf, EV_SIZE_MAX);
- evbuffer_validate(buf);
-
-end:
- evbuffer_free(buf);
-}
-
-static void
-test_evbuffer_add1(void *ptr)
-{
- struct evbuffer *buf;
- char *str;
-
- buf = evbuffer_new();
- evbuffer_add(buf, "1", 1);
- evbuffer_validate(buf);
- evbuffer_expand(buf, 2048);
- evbuffer_validate(buf);
- evbuffer_add(buf, "2", 1);
- evbuffer_validate(buf);
- evbuffer_add_printf(buf, "3");
- evbuffer_validate(buf);
-
- tt_assert(evbuffer_get_length(buf) == 3);
- str = (char *)evbuffer_pullup(buf, -1);
- tt_assert(str[0] == '1');
- tt_assert(str[1] == '2');
- tt_assert(str[2] == '3');
-end:
- evbuffer_free(buf);
-}
-
-static void
-test_evbuffer_add2(void *ptr)
-{
- struct evbuffer *buf;
- static char data[4096];
- int data_len = MIN_BUFFER_SIZE-EVBUFFER_CHAIN_SIZE-10;
- char *str;
- int len;
-
- memset(data, 'P', sizeof(data));
- buf = evbuffer_new();
- evbuffer_add(buf, data, data_len);
- evbuffer_validate(buf);
- evbuffer_expand(buf, 100);
- evbuffer_validate(buf);
- evbuffer_add(buf, "2", 1);
- evbuffer_validate(buf);
- evbuffer_add_printf(buf, "3");
- evbuffer_validate(buf);
-
- len = evbuffer_get_length(buf);
- tt_assert(len == data_len+2);
- str = (char *)evbuffer_pullup(buf, -1);
- tt_assert(str[len-3] == 'P');
- tt_assert(str[len-2] == '2');
- tt_assert(str[len-1] == '3');
-end:
- evbuffer_free(buf);
-}
-
-static int reference_cb_called;
-static void
-reference_cb(const void *data, size_t len, void *extra)
-{
- tt_str_op(data, ==, "this is what we add as read-only memory.");
- tt_int_op(len, ==, strlen(data));
- tt_want(extra == (void *)0xdeadaffe);
- ++reference_cb_called;
-end:
- ;
-}
-
-static void
-test_evbuffer_reference(void *ptr)
-{
- struct evbuffer *src = evbuffer_new();
- struct evbuffer *dst = evbuffer_new();
- struct evbuffer_iovec v[1];
- const char *data = "this is what we add as read-only memory.";
- reference_cb_called = 0;
-
- tt_assert(evbuffer_add_reference(src, data, strlen(data),
- reference_cb, (void *)0xdeadaffe) != -1);
-
- evbuffer_reserve_space(dst, strlen(data), v, 1);
- tt_assert(evbuffer_remove(src, v[0].iov_base, 10) != -1);
-
- evbuffer_validate(src);
- evbuffer_validate(dst);
-
- /* make sure that we don't write data at the beginning */
- evbuffer_prepend(src, "aaaaa", 5);
- evbuffer_validate(src);
- evbuffer_drain(src, 5);
-
- tt_assert(evbuffer_remove(src, ((char*)(v[0].iov_base)) + 10,
- strlen(data) - 10) != -1);
-
- v[0].iov_len = strlen(data);
-
- evbuffer_commit_space(dst, v, 1);
- evbuffer_validate(src);
- evbuffer_validate(dst);
-
- tt_int_op(reference_cb_called, ==, 1);
-
- tt_assert(!memcmp(evbuffer_pullup(dst, strlen(data)),
- data, strlen(data)));
- evbuffer_validate(dst);
-
- end:
- evbuffer_free(dst);
- evbuffer_free(src);
-}
-
-static void
-test_evbuffer_reference2(void *ptr)
-{
- struct evbuffer *buf;
- static char data[4096];
- int data_len = MIN_BUFFER_SIZE-EVBUFFER_CHAIN_SIZE-10;
- char *str;
- int len;
-
- memset(data, 'P', sizeof(data));
- buf = evbuffer_new();
- evbuffer_add(buf, data, data_len);
- evbuffer_validate(buf);
- evbuffer_expand(buf, 100);
- evbuffer_validate(buf);
- evbuffer_add_reference(buf, "2", 1, no_cleanup, NULL);
- evbuffer_validate(buf);
- evbuffer_add_printf(buf, "3");
- evbuffer_validate(buf);
-
- len = evbuffer_get_length(buf);
- tt_assert(len == data_len+2);
- str = (char *)evbuffer_pullup(buf, -1);
- tt_assert(str[len-3] == 'P');
- tt_assert(str[len-2] == '2');
- tt_assert(str[len-1] == '3');
-end:
- evbuffer_free(buf);
-}
-
-static struct event_base *addfile_test_event_base;
-static int addfile_test_done_writing;
-static int addfile_test_total_written;
-static int addfile_test_total_read;
-
-static void
-addfile_test_writecb(evutil_socket_t fd, short what, void *arg)
-{
- struct evbuffer *b = arg;
- int r;
- evbuffer_validate(b);
- while (evbuffer_get_length(b)) {
- r = evbuffer_write(b, fd);
- if (r > 0) {
- addfile_test_total_written += r;
- TT_BLATHER(("Wrote %d/%d bytes", r, addfile_test_total_written));
- } else {
- int e = evutil_socket_geterror(fd);
- if (EVUTIL_ERR_RW_RETRIABLE(e))
- return;
- tt_fail_perror("write");
- event_base_loopexit(addfile_test_event_base,NULL);
- }
- evbuffer_validate(b);
- }
- addfile_test_done_writing = 1;
- return;
-end:
- event_base_loopexit(addfile_test_event_base,NULL);
-}
-
-static void
-addfile_test_readcb(evutil_socket_t fd, short what, void *arg)
-{
- struct evbuffer *b = arg;
- int e, r = 0;
- do {
- r = evbuffer_read(b, fd, 1024);
- if (r > 0) {
- addfile_test_total_read += r;
- TT_BLATHER(("Read %d/%d bytes", r, addfile_test_total_read));
- }
- } while (r > 0);
- if (r < 0) {
- e = evutil_socket_geterror(fd);
- if (! EVUTIL_ERR_RW_RETRIABLE(e)) {
- tt_fail_perror("read");
- event_base_loopexit(addfile_test_event_base,NULL);
- }
- }
- if (addfile_test_done_writing &&
- addfile_test_total_read >= addfile_test_total_written) {
- event_base_loopexit(addfile_test_event_base,NULL);
- }
-}
-
-static void
-test_evbuffer_add_file(void *ptr)
-{
- struct basic_test_data *testdata = ptr;
- const char *impl = testdata->setup_data;
- struct evbuffer *src = evbuffer_new(), *dest = evbuffer_new();
- char *tmpfilename = NULL;
- char *data = NULL;
- const char *expect_data;
- size_t datalen, expect_len;
- const char *compare;
- int fd = -1;
- int want_ismapping = -1, want_cansendfile = -1;
- unsigned flags = 0;
- int use_segment = 1, use_bigfile = 0, map_from_offset = 0,
- view_from_offset = 0;
- struct evbuffer_file_segment *seg = NULL;
- ev_off_t starting_offset = 0, mapping_len = -1;
- ev_off_t segment_offset = 0, segment_len = -1;
- struct event *rev=NULL, *wev=NULL;
- struct event_base *base = testdata->base;
- evutil_socket_t pair[2] = {-1, -1};
- struct evutil_weakrand_state seed = { 123456789U };
-
- /* This test is highly parameterized based on substrings of its
- * argument. The strings are: */
- tt_assert(impl);
- if (strstr(impl, "nosegment")) {
- /* If nosegment is set, use the older evbuffer_add_file
- * interface */
- use_segment = 0;
- }
- if (strstr(impl, "bigfile")) {
- /* If bigfile is set, use a 512K file. Else use a smaller
- * one. */
- use_bigfile = 1;
- }
- if (strstr(impl, "map_offset")) {
- /* If map_offset is set, we build the file segment starting
- * from a point other than byte 0 and ending somewhere other
- * than the last byte. Otherwise we map the whole thing */
- map_from_offset = 1;
- }
- if (strstr(impl, "offset_in_segment")) {
- /* If offset_in_segment is set, we add a subsection of the
- * file semgment starting from a point other than byte 0 of
- * the segment. */
- view_from_offset = 1;
- }
- if (strstr(impl, "sendfile")) {
- /* If sendfile is set, we try to use a sendfile/splice style
- * backend. */
- flags = EVBUF_FS_DISABLE_MMAP;
- want_cansendfile = 1;
- want_ismapping = 0;
- } else if (strstr(impl, "mmap")) {
- /* If sendfile is set, we try to use a mmap/CreateFileMapping
- * style backend. */
- flags = EVBUF_FS_DISABLE_SENDFILE;
- want_ismapping = 1;
- want_cansendfile = 0;
- } else if (strstr(impl, "linear")) {
- /* If linear is set, we try to use a read-the-whole-thing
- * backend. */
- flags = EVBUF_FS_DISABLE_SENDFILE|EVBUF_FS_DISABLE_MMAP;
- want_ismapping = 0;
- want_cansendfile = 0;
- } else if (strstr(impl, "default")) {
- /* The caller doesn't care which backend we use. */
- ;
- } else {
- /* The caller must choose a backend. */
- TT_DIE(("Didn't recognize the implementation"));
- }
-
- if (use_bigfile) {
- unsigned int i;
- datalen = 1024*512;
- data = malloc(1024*512);
- tt_assert(data);
- for (i = 0; i < datalen; ++i)
- data[i] = (char)evutil_weakrand_(&seed);
- } else {
- data = strdup("here is a relatively small string.");
- tt_assert(data);
- datalen = strlen(data);
- }
-
- fd = regress_make_tmpfile(data, datalen, &tmpfilename);
-
- if (map_from_offset) {
- starting_offset = datalen/4 + 1;
- mapping_len = datalen / 2 - 1;
- expect_data = data + starting_offset;
- expect_len = mapping_len;
- } else {
- expect_data = data;
- expect_len = datalen;
- }
- if (view_from_offset) {
- tt_assert(use_segment); /* Can't do this with add_file*/
- segment_offset = expect_len / 3;
- segment_len = expect_len / 2;
- expect_data = expect_data + segment_offset;
- expect_len = segment_len;
- }
-
- if (use_segment) {
- seg = evbuffer_file_segment_new(fd, starting_offset,
- mapping_len, flags);
- tt_assert(seg);
- if (want_ismapping >= 0) {
- if (seg->is_mapping != (unsigned)want_ismapping)
- tt_skip();
- }
- if (want_cansendfile >= 0) {
- if (seg->can_sendfile != (unsigned)want_cansendfile)
- tt_skip();
- }
- }
-
- /* Say that it drains to a fd so that we can use sendfile. */
- evbuffer_set_flags(src, EVBUFFER_FLAG_DRAINS_TO_FD);
-
-#if defined(EVENT__HAVE_SENDFILE) && defined(__sun__) && defined(__svr4__)
- /* We need to use a pair of AF_INET sockets, since Solaris
- doesn't support sendfile() over AF_UNIX. */
- if (evutil_ersatz_socketpair_(AF_INET, SOCK_STREAM, 0, pair) == -1)
- tt_abort_msg("ersatz_socketpair failed");
-#else
- if (evutil_socketpair(AF_UNIX, SOCK_STREAM, 0, pair) == -1)
- tt_abort_msg("socketpair failed");
-#endif
- evutil_make_socket_nonblocking(pair[0]);
- evutil_make_socket_nonblocking(pair[1]);
-
- tt_assert(fd != -1);
-
- if (use_segment) {
- tt_assert(evbuffer_add_file_segment(src, seg,
- segment_offset, segment_len)!=-1);
- } else {
- tt_assert(evbuffer_add_file(src, fd, starting_offset,
- mapping_len) != -1);
- }
-
- evbuffer_validate(src);
-
- addfile_test_event_base = base;
- addfile_test_done_writing = 0;
- addfile_test_total_written = 0;
- addfile_test_total_read = 0;
-
- wev = event_new(base, pair[0], EV_WRITE|EV_PERSIST,
- addfile_test_writecb, src);
- rev = event_new(base, pair[1], EV_READ|EV_PERSIST,
- addfile_test_readcb, dest);
-
- event_add(wev, NULL);
- event_add(rev, NULL);
- event_base_dispatch(base);
-
- evbuffer_validate(src);
- evbuffer_validate(dest);
-
- tt_assert(addfile_test_done_writing);
- tt_int_op(addfile_test_total_written, ==, expect_len);
- tt_int_op(addfile_test_total_read, ==, expect_len);
-
- compare = (char *)evbuffer_pullup(dest, expect_len);
- tt_assert(compare != NULL);
- if (memcmp(compare, expect_data, expect_len)) {
- tt_abort_msg("Data from add_file differs.");
- }
-
- evbuffer_validate(dest);
- end:
- if (data)
- free(data);
- if (seg)
- evbuffer_file_segment_free(seg);
- if (src)
- evbuffer_free(src);
- if (dest)
- evbuffer_free(dest);
- if (pair[0] >= 0)
- evutil_closesocket(pair[0]);
- if (pair[1] >= 0)
- evutil_closesocket(pair[1]);
- if (wev)
- event_free(wev);
- if (rev)
- event_free(rev);
- if (tmpfilename) {
- unlink(tmpfilename);
- free(tmpfilename);
- }
-}
-
-static int file_segment_cleanup_cb_called_count = 0;
-static struct evbuffer_file_segment const* file_segment_cleanup_cb_called_with = NULL;
-static int file_segment_cleanup_cb_called_with_flags = 0;
-static void* file_segment_cleanup_cb_called_with_arg = NULL;
-static void
-file_segment_cleanup_cp(struct evbuffer_file_segment const* seg, int flags, void* arg)
-{
- ++file_segment_cleanup_cb_called_count;
- file_segment_cleanup_cb_called_with = seg;
- file_segment_cleanup_cb_called_with_flags = flags;
- file_segment_cleanup_cb_called_with_arg = arg;
-}
-
-static void
-test_evbuffer_file_segment_add_cleanup_cb(void* ptr)
-{
- char *tmpfilename = NULL;
- int fd = -1;
- struct evbuffer *evb = NULL;
- struct evbuffer_file_segment *seg = NULL, *segptr;
- char const* arg = "token";
-
- fd = regress_make_tmpfile("file_segment_test_file", 22, &tmpfilename);
- tt_int_op(fd, >=, 0);
-
- evb = evbuffer_new();
- tt_assert(evb);
-
- segptr = seg = evbuffer_file_segment_new(fd, 0, -1, 0);
- tt_assert(seg);
-
- evbuffer_file_segment_add_cleanup_cb(
- seg, &file_segment_cleanup_cp, (void*)arg);
-
- tt_assert(fd != -1);
-
- tt_assert(evbuffer_add_file_segment(evb, seg, 0, -1)!=-1);
-
- evbuffer_validate(evb);
-
- tt_int_op(file_segment_cleanup_cb_called_count, ==, 0);
- evbuffer_file_segment_free(seg);
- seg = NULL; /* Prevent double-free. */
-
- tt_int_op(file_segment_cleanup_cb_called_count, ==, 0);
- evbuffer_free(evb);
- evb = NULL; /* pevent double-free */
-
- tt_int_op(file_segment_cleanup_cb_called_count, ==, 1);
- tt_assert(file_segment_cleanup_cb_called_with == segptr);
- tt_assert(file_segment_cleanup_cb_called_with_flags == 0);
- tt_assert(file_segment_cleanup_cb_called_with_arg == (void*)arg);
-
-end:
- if (evb)
- evbuffer_free(evb);
- if (seg)
- evbuffer_file_segment_free(seg);
- if (tmpfilename) {
- unlink(tmpfilename);
- free(tmpfilename);
- }
-}
-
-#ifndef EVENT__DISABLE_MM_REPLACEMENT
-static void *
-failing_malloc(size_t how_much)
-{
- errno = ENOMEM;
- return NULL;
-}
-#endif
-
-static void
-test_evbuffer_readln(void *ptr)
-{
- struct evbuffer *evb = evbuffer_new();
- struct evbuffer *evb_tmp = evbuffer_new();
- const char *s;
- char *cp = NULL;
- size_t sz;
-
-#define tt_line_eq(content) \
- TT_STMT_BEGIN \
- if (!cp || sz != strlen(content) || strcmp(cp, content)) { \
- TT_DIE(("Wanted %s; got %s [%d]", content, cp, (int)sz)); \
- } \
- TT_STMT_END
-
- /* Test EOL_ANY. */
- s = "complex silly newline\r\n\n\r\n\n\rmore\0\n";
- evbuffer_add(evb, s, strlen(s)+2);
- evbuffer_validate(evb);
- cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_ANY);
- tt_line_eq("complex silly newline");
- free(cp);
- evbuffer_validate(evb);
- cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_ANY);
- if (!cp || sz != 5 || memcmp(cp, "more\0\0", 6))
- tt_abort_msg("Not as expected");
- tt_uint_op(evbuffer_get_length(evb), ==, 0);
- evbuffer_validate(evb);
- s = "\nno newline";
- evbuffer_add(evb, s, strlen(s));
- free(cp);
- evbuffer_validate(evb);
- cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_ANY);
- tt_line_eq("");
- free(cp);
- evbuffer_validate(evb);
- cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_ANY);
- tt_assert(!cp);
- evbuffer_validate(evb);
- evbuffer_drain(evb, evbuffer_get_length(evb));
- tt_assert(evbuffer_get_length(evb) == 0);
- evbuffer_validate(evb);
-
- /* Test EOL_CRLF */
- s = "Line with\rin the middle\nLine with good crlf\r\n\nfinal\n";
- evbuffer_add(evb, s, strlen(s));
- evbuffer_validate(evb);
- cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_CRLF);
- tt_line_eq("Line with\rin the middle");
- free(cp);
- evbuffer_validate(evb);
-
- cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_CRLF);
- tt_line_eq("Line with good crlf");
- free(cp);
- evbuffer_validate(evb);
-
- cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_CRLF);
- tt_line_eq("");
- free(cp);
- evbuffer_validate(evb);
-
- cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_CRLF);
- tt_line_eq("final");
- s = "x";
- evbuffer_validate(evb);
- evbuffer_add(evb, s, 1);
- evbuffer_validate(evb);
- free(cp);
- cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_CRLF);
- tt_assert(!cp);
- evbuffer_validate(evb);
-
- /* Test CRLF_STRICT */
- s = " and a bad crlf\nand a good one\r\n\r\nMore\r";
- evbuffer_add(evb, s, strlen(s));
- evbuffer_validate(evb);
- cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_CRLF_STRICT);
- tt_line_eq("x and a bad crlf\nand a good one");
- free(cp);
- evbuffer_validate(evb);
-
- cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_CRLF_STRICT);
- tt_line_eq("");
- free(cp);
- evbuffer_validate(evb);
-
- cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_CRLF_STRICT);
- tt_assert(!cp);
- evbuffer_validate(evb);
- evbuffer_add(evb, "\n", 1);
- evbuffer_validate(evb);
-
- cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_CRLF_STRICT);
- tt_line_eq("More");
- free(cp);
- tt_assert(evbuffer_get_length(evb) == 0);
- evbuffer_validate(evb);
-
- s = "An internal CR\r is not an eol\r\nNor is a lack of one";
- evbuffer_add(evb, s, strlen(s));
- cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_CRLF_STRICT);
- tt_line_eq("An internal CR\r is not an eol");
- free(cp);
- evbuffer_validate(evb);
-
- cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_CRLF_STRICT);
- tt_assert(!cp);
- evbuffer_validate(evb);
-
- evbuffer_add(evb, "\r\n", 2);
- evbuffer_validate(evb);
- cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_CRLF_STRICT);
- tt_line_eq("Nor is a lack of one");
- free(cp);
- tt_assert(evbuffer_get_length(evb) == 0);
- evbuffer_validate(evb);
-
- /* Test LF */
- s = "An\rand a nl\n\nText";
- evbuffer_add(evb, s, strlen(s));
- evbuffer_validate(evb);
-
- cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_LF);
- tt_line_eq("An\rand a nl");
- free(cp);
- evbuffer_validate(evb);
-
- cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_LF);
- tt_line_eq("");
- free(cp);
- evbuffer_validate(evb);
-
- cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_LF);
- tt_assert(!cp);
- free(cp);
- evbuffer_add(evb, "\n", 1);
- evbuffer_validate(evb);
- cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_LF);
- tt_line_eq("Text");
- free(cp);
- evbuffer_validate(evb);
-
- /* Test NUL */
- tt_int_op(evbuffer_get_length(evb), ==, 0);
- {
- char x[] =
- "NUL\n\0\0"
- "The all-zeros character which may serve\0"
- "to accomplish time fill\0and media fill";
- /* Add all but the final NUL of x. */
- evbuffer_add(evb, x, sizeof(x)-1);
- }
- cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_NUL);
- tt_line_eq("NUL\n");
- free(cp);
- cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_NUL);
- tt_line_eq("");
- free(cp);
- cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_NUL);
- tt_line_eq("The all-zeros character which may serve");
- free(cp);
- cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_NUL);
- tt_line_eq("to accomplish time fill");
- free(cp);
- cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_NUL);
- tt_ptr_op(cp, ==, NULL);
- evbuffer_drain(evb, -1);
-
- /* Test CRLF_STRICT - across boundaries*/
- s = " and a bad crlf\nand a good one\r";
- evbuffer_add(evb_tmp, s, strlen(s));
- evbuffer_validate(evb);
- evbuffer_add_buffer(evb, evb_tmp);
- evbuffer_validate(evb);
- s = "\n\r";
- evbuffer_add(evb_tmp, s, strlen(s));
- evbuffer_validate(evb);
- evbuffer_add_buffer(evb, evb_tmp);
- evbuffer_validate(evb);
- s = "\nMore\r";
- evbuffer_add(evb_tmp, s, strlen(s));
- evbuffer_validate(evb);
- evbuffer_add_buffer(evb, evb_tmp);
- evbuffer_validate(evb);
-
- cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_CRLF_STRICT);
- tt_line_eq(" and a bad crlf\nand a good one");
- free(cp);
- evbuffer_validate(evb);
-
- cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_CRLF_STRICT);
- tt_line_eq("");
- free(cp);
- evbuffer_validate(evb);
-
- cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_CRLF_STRICT);
- tt_assert(!cp);
- free(cp);
- evbuffer_validate(evb);
- evbuffer_add(evb, "\n", 1);
- evbuffer_validate(evb);
- cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_CRLF_STRICT);
- tt_line_eq("More");
- free(cp); cp = NULL;
- evbuffer_validate(evb);
- tt_assert(evbuffer_get_length(evb) == 0);
-
- /* Test memory problem*/
- s = "one line\ntwo line\nblue line";
- evbuffer_add(evb_tmp, s, strlen(s));
- evbuffer_validate(evb);
- evbuffer_add_buffer(evb, evb_tmp);
- evbuffer_validate(evb);
-
- cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_LF);
- tt_line_eq("one line");
- free(cp); cp = NULL;
- evbuffer_validate(evb);
-
- /* the next call to readline should fail */
-#ifndef EVENT__DISABLE_MM_REPLACEMENT
- event_set_mem_functions(failing_malloc, realloc, free);
- cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_LF);
- tt_assert(cp == NULL);
- evbuffer_validate(evb);
-
- /* now we should get the next line back */
- event_set_mem_functions(malloc, realloc, free);
-#endif
- cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_LF);
- tt_line_eq("two line");
- free(cp); cp = NULL;
- evbuffer_validate(evb);
-
- end:
- evbuffer_free(evb);
- evbuffer_free(evb_tmp);
- if (cp) free(cp);
-}
-
-static void
-test_evbuffer_search_eol(void *ptr)
-{
- struct evbuffer *buf = evbuffer_new();
- struct evbuffer_ptr ptr1, ptr2;
- const char *s;
- size_t eol_len;
-
- s = "string! \r\n\r\nx\n";
- evbuffer_add(buf, s, strlen(s));
- eol_len = -1;
- ptr1 = evbuffer_search_eol(buf, NULL, &eol_len, EVBUFFER_EOL_CRLF);
- tt_int_op(ptr1.pos, ==, 8);
- tt_int_op(eol_len, ==, 2);
-
- eol_len = -1;
- ptr2 = evbuffer_search_eol(buf, &ptr1, &eol_len, EVBUFFER_EOL_CRLF);
- tt_int_op(ptr2.pos, ==, 8);
- tt_int_op(eol_len, ==, 2);
-
- evbuffer_ptr_set(buf, &ptr1, 1, EVBUFFER_PTR_ADD);
- eol_len = -1;
- ptr2 = evbuffer_search_eol(buf, &ptr1, &eol_len, EVBUFFER_EOL_CRLF);
- tt_int_op(ptr2.pos, ==, 9);
- tt_int_op(eol_len, ==, 1);
-
- eol_len = -1;
- ptr2 = evbuffer_search_eol(buf, &ptr1, &eol_len, EVBUFFER_EOL_CRLF_STRICT);
- tt_int_op(ptr2.pos, ==, 10);
- tt_int_op(eol_len, ==, 2);
-
- eol_len = -1;
- ptr1 = evbuffer_search_eol(buf, NULL, &eol_len, EVBUFFER_EOL_LF);
- tt_int_op(ptr1.pos, ==, 9);
- tt_int_op(eol_len, ==, 1);
-
- eol_len = -1;
- ptr2 = evbuffer_search_eol(buf, &ptr1, &eol_len, EVBUFFER_EOL_LF);
- tt_int_op(ptr2.pos, ==, 9);
- tt_int_op(eol_len, ==, 1);
-
- evbuffer_ptr_set(buf, &ptr1, 1, EVBUFFER_PTR_ADD);
- eol_len = -1;
- ptr2 = evbuffer_search_eol(buf, &ptr1, &eol_len, EVBUFFER_EOL_LF);
- tt_int_op(ptr2.pos, ==, 11);
- tt_int_op(eol_len, ==, 1);
-
- tt_assert(evbuffer_ptr_set(buf, &ptr1, evbuffer_get_length(buf), EVBUFFER_PTR_SET) == 0);
- eol_len = -1;
- ptr2 = evbuffer_search_eol(buf, &ptr1, &eol_len, EVBUFFER_EOL_LF);
- tt_int_op(ptr2.pos, ==, -1);
- tt_int_op(eol_len, ==, 0);
-
-end:
- evbuffer_free(buf);
-}
-
-static void
-test_evbuffer_iterative(void *ptr)
-{
- struct evbuffer *buf = evbuffer_new();
- const char *abc = "abcdefghijklmnopqrstvuwxyzabcdefghijklmnopqrstvuwxyzabcdefghijklmnopqrstvuwxyzabcdefghijklmnopqrstvuwxyz";
- unsigned i, j, sum, n;
-
- sum = 0;
- n = 0;
- for (i = 0; i < 1000; ++i) {
- for (j = 1; j < strlen(abc); ++j) {
- char format[32];
- evutil_snprintf(format, sizeof(format), "%%%u.%us", j, j);
- evbuffer_add_printf(buf, format, abc);
-
- /* Only check for rep violations every so often.
- Walking over the whole list of chains can get
- pretty expensive as it gets long.
- */
- if ((n % 337) == 0)
- evbuffer_validate(buf);
-
- sum += j;
- n++;
- }
- }
- evbuffer_validate(buf);
-
- tt_uint_op(sum, ==, evbuffer_get_length(buf));
-
- {
- size_t a,w,u;
- a=w=u=0;
- evbuffer_get_waste(buf, &a, &w, &u);
- if (0)
- printf("Allocated: %u.\nWasted: %u.\nUsed: %u.",
- (unsigned)a, (unsigned)w, (unsigned)u);
- tt_assert( ((double)w)/a < .125);
- }
- end:
- evbuffer_free(buf);
-
-}
-
-static void
-test_evbuffer_find(void *ptr)
-{
- unsigned char* p;
- const char* test1 = "1234567890\r\n";
- const char* test2 = "1234567890\r";
-#define EVBUFFER_INITIAL_LENGTH 256
- char test3[EVBUFFER_INITIAL_LENGTH];
- unsigned int i;
- struct evbuffer * buf = evbuffer_new();
-
- tt_assert(buf);
-
- /* make sure evbuffer_find doesn't match past the end of the buffer */
- evbuffer_add(buf, (unsigned char*)test1, strlen(test1));
- evbuffer_validate(buf);
- evbuffer_drain(buf, strlen(test1));
- evbuffer_validate(buf);
- evbuffer_add(buf, (unsigned char*)test2, strlen(test2));
- evbuffer_validate(buf);
- p = evbuffer_find(buf, (unsigned char*)"\r\n", 2);
- tt_want(p == NULL);
-
- /*
- * drain the buffer and do another find; in r309 this would
- * read past the allocated buffer causing a valgrind error.
- */
- evbuffer_drain(buf, strlen(test2));
- evbuffer_validate(buf);
- for (i = 0; i < EVBUFFER_INITIAL_LENGTH; ++i)
- test3[i] = 'a';
- test3[EVBUFFER_INITIAL_LENGTH - 1] = 'x';
- evbuffer_add(buf, (unsigned char *)test3, EVBUFFER_INITIAL_LENGTH);
- evbuffer_validate(buf);
- p = evbuffer_find(buf, (unsigned char *)"xy", 2);
- tt_want(p == NULL);
-
- /* simple test for match at end of allocated buffer */
- p = evbuffer_find(buf, (unsigned char *)"ax", 2);
- tt_assert(p != NULL);
- tt_want(strncmp((char*)p, "ax", 2) == 0);
-
-end:
- if (buf)
- evbuffer_free(buf);
-}
-
-static void
-test_evbuffer_ptr_set(void *ptr)
-{
- struct evbuffer *buf = evbuffer_new();
- struct evbuffer_ptr pos;
- struct evbuffer_iovec v[1];
-
- tt_assert(buf);
-
- tt_int_op(evbuffer_get_length(buf), ==, 0);
-
- tt_assert(evbuffer_ptr_set(buf, &pos, 0, EVBUFFER_PTR_SET) == 0);
- tt_assert(pos.pos == 0);
- tt_assert(evbuffer_ptr_set(buf, &pos, 1, EVBUFFER_PTR_ADD) == -1);
- tt_assert(pos.pos == -1);
- tt_assert(evbuffer_ptr_set(buf, &pos, 1, EVBUFFER_PTR_SET) == -1);
- tt_assert(pos.pos == -1);
-
- /* create some chains */
- evbuffer_reserve_space(buf, 5000, v, 1);
- v[0].iov_len = 5000;
- memset(v[0].iov_base, 1, v[0].iov_len);
- evbuffer_commit_space(buf, v, 1);
- evbuffer_validate(buf);
-
- evbuffer_reserve_space(buf, 4000, v, 1);
- v[0].iov_len = 4000;
- memset(v[0].iov_base, 2, v[0].iov_len);
- evbuffer_commit_space(buf, v, 1);
-
- evbuffer_reserve_space(buf, 3000, v, 1);
- v[0].iov_len = 3000;
- memset(v[0].iov_base, 3, v[0].iov_len);
- evbuffer_commit_space(buf, v, 1);
- evbuffer_validate(buf);
-
- tt_int_op(evbuffer_get_length(buf), ==, 12000);
-
- tt_assert(evbuffer_ptr_set(buf, &pos, 13000, EVBUFFER_PTR_SET) == -1);
- tt_assert(pos.pos == -1);
- tt_assert(evbuffer_ptr_set(buf, &pos, 0, EVBUFFER_PTR_SET) == 0);
- tt_assert(pos.pos == 0);
- tt_assert(evbuffer_ptr_set(buf, &pos, 13000, EVBUFFER_PTR_ADD) == -1);
-
- tt_assert(evbuffer_ptr_set(buf, &pos, 0, EVBUFFER_PTR_SET) == 0);
- tt_assert(pos.pos == 0);
- tt_assert(evbuffer_ptr_set(buf, &pos, 10000, EVBUFFER_PTR_ADD) == 0);
- tt_assert(pos.pos == 10000);
- tt_assert(evbuffer_ptr_set(buf, &pos, 1000, EVBUFFER_PTR_ADD) == 0);
- tt_assert(pos.pos == 11000);
- tt_assert(evbuffer_ptr_set(buf, &pos, 1000, EVBUFFER_PTR_ADD) == 0);
- tt_assert(pos.pos == 12000);
- tt_assert(evbuffer_ptr_set(buf, &pos, 1000, EVBUFFER_PTR_ADD) == -1);
- tt_assert(pos.pos == -1);
-
-end:
- if (buf)
- evbuffer_free(buf);
-}
-
-static void
-test_evbuffer_search(void *ptr)
-{
- struct evbuffer *buf = evbuffer_new();
- struct evbuffer *tmp = evbuffer_new();
- struct evbuffer_ptr pos, end;
-
- tt_assert(buf);
- tt_assert(tmp);
-
- pos = evbuffer_search(buf, "x", 1, NULL);
- tt_int_op(pos.pos, ==, -1);
- tt_assert(evbuffer_ptr_set(buf, &pos, 0, EVBUFFER_PTR_SET) == 0);
- pos = evbuffer_search(buf, "x", 1, &pos);
- tt_int_op(pos.pos, ==, -1);
- tt_assert(evbuffer_ptr_set(buf, &pos, 0, EVBUFFER_PTR_SET) == 0);
- pos = evbuffer_search_range(buf, "x", 1, &pos, &pos);
- tt_int_op(pos.pos, ==, -1);
- tt_assert(evbuffer_ptr_set(buf, &pos, 0, EVBUFFER_PTR_SET) == 0);
- pos = evbuffer_search_range(buf, "x", 1, &pos, NULL);
- tt_int_op(pos.pos, ==, -1);
-
- /* set up our chains */
- evbuffer_add_printf(tmp, "hello"); /* 5 chars */
- evbuffer_add_buffer(buf, tmp);
- evbuffer_add_printf(tmp, "foo"); /* 3 chars */
- evbuffer_add_buffer(buf, tmp);
- evbuffer_add_printf(tmp, "cat"); /* 3 chars */
- evbuffer_add_buffer(buf, tmp);
- evbuffer_add_printf(tmp, "attack");
- evbuffer_add_buffer(buf, tmp);
-
- pos = evbuffer_search(buf, "attack", 6, NULL);
- tt_int_op(pos.pos, ==, 11);
- pos = evbuffer_search(buf, "attacker", 8, NULL);
- tt_int_op(pos.pos, ==, -1);
-
- /* test continuing search */
- pos = evbuffer_search(buf, "oc", 2, NULL);
- tt_int_op(pos.pos, ==, 7);
- pos = evbuffer_search(buf, "cat", 3, &pos);
- tt_int_op(pos.pos, ==, 8);
- pos = evbuffer_search(buf, "tacking", 7, &pos);
- tt_int_op(pos.pos, ==, -1);
-
- evbuffer_ptr_set(buf, &pos, 5, EVBUFFER_PTR_SET);
- pos = evbuffer_search(buf, "foo", 3, &pos);
- tt_int_op(pos.pos, ==, 5);
-
- evbuffer_ptr_set(buf, &pos, 2, EVBUFFER_PTR_ADD);
- pos = evbuffer_search(buf, "tat", 3, &pos);
- tt_int_op(pos.pos, ==, 10);
-
- /* test bounded search. */
- /* Set "end" to the first t in "attack". */
- evbuffer_ptr_set(buf, &end, 12, EVBUFFER_PTR_SET);
- pos = evbuffer_search_range(buf, "foo", 3, NULL, &end);
- tt_int_op(pos.pos, ==, 5);
- pos = evbuffer_search_range(buf, "foocata", 7, NULL, &end);
- tt_int_op(pos.pos, ==, 5);
- pos = evbuffer_search_range(buf, "foocatat", 8, NULL, &end);
- tt_int_op(pos.pos, ==, -1);
- pos = evbuffer_search_range(buf, "ack", 3, NULL, &end);
- tt_int_op(pos.pos, ==, -1);
-
- /* Set "end" after the last byte in the buffer. */
- tt_assert(evbuffer_ptr_set(buf, &end, 17, EVBUFFER_PTR_SET) == 0);
-
- pos = evbuffer_search_range(buf, "attack", 6, NULL, &end);
- tt_int_op(pos.pos, ==, 11);
- tt_assert(evbuffer_ptr_set(buf, &pos, 11, EVBUFFER_PTR_SET) == 0);
- pos = evbuffer_search_range(buf, "attack", 6, &pos, &end);
- tt_int_op(pos.pos, ==, 11);
- tt_assert(evbuffer_ptr_set(buf, &pos, 17, EVBUFFER_PTR_SET) == 0);
- pos = evbuffer_search_range(buf, "attack", 6, &pos, &end);
- tt_int_op(pos.pos, ==, -1);
- tt_assert(evbuffer_ptr_set(buf, &pos, 17, EVBUFFER_PTR_SET) == 0);
- pos = evbuffer_search_range(buf, "attack", 6, &pos, NULL);
- tt_int_op(pos.pos, ==, -1);
-
-end:
- if (buf)
- evbuffer_free(buf);
- if (tmp)
- evbuffer_free(tmp);
-}
-
-static void
-log_change_callback(struct evbuffer *buffer,
- const struct evbuffer_cb_info *cbinfo,
- void *arg)
-{
-
- size_t old_len = cbinfo->orig_size;
- size_t new_len = old_len + cbinfo->n_added - cbinfo->n_deleted;
- struct evbuffer *out = arg;
- evbuffer_add_printf(out, "%lu->%lu; ", (unsigned long)old_len,
- (unsigned long)new_len);
-}
-static void
-self_draining_callback(struct evbuffer *evbuffer, size_t old_len,
- size_t new_len, void *arg)
-{
- if (new_len > old_len)
- evbuffer_drain(evbuffer, new_len);
-}
-
-static void
-test_evbuffer_callbacks(void *ptr)
-{
- struct evbuffer *buf = evbuffer_new();
- struct evbuffer *buf_out1 = evbuffer_new();
- struct evbuffer *buf_out2 = evbuffer_new();
- struct evbuffer_cb_entry *cb1, *cb2;
-
- tt_assert(buf);
- tt_assert(buf_out1);
- tt_assert(buf_out2);
-
- cb1 = evbuffer_add_cb(buf, log_change_callback, buf_out1);
- cb2 = evbuffer_add_cb(buf, log_change_callback, buf_out2);
-
- /* Let's run through adding and deleting some stuff from the buffer
- * and turning the callbacks on and off and removing them. The callback
- * adds a summary of length changes to buf_out1/buf_out2 when called. */
- /* size: 0-> 36. */
- evbuffer_add_printf(buf, "The %d magic words are spotty pudding", 2);
- evbuffer_validate(buf);
- evbuffer_cb_clear_flags(buf, cb2, EVBUFFER_CB_ENABLED);
- evbuffer_drain(buf, 10); /*36->26*/
- evbuffer_validate(buf);
- evbuffer_prepend(buf, "Hello", 5);/*26->31*/
- evbuffer_cb_set_flags(buf, cb2, EVBUFFER_CB_ENABLED);
- evbuffer_add_reference(buf, "Goodbye", 7, NULL, NULL); /*31->38*/
- evbuffer_remove_cb_entry(buf, cb1);
- evbuffer_validate(buf);
- evbuffer_drain(buf, evbuffer_get_length(buf)); /*38->0*/;
- tt_assert(-1 == evbuffer_remove_cb(buf, log_change_callback, NULL));
- evbuffer_add(buf, "X", 1); /* 0->1 */
- tt_assert(!evbuffer_remove_cb(buf, log_change_callback, buf_out2));
- evbuffer_validate(buf);
-
- tt_str_op((const char *) evbuffer_pullup(buf_out1, -1), ==,
- "0->36; 36->26; 26->31; 31->38; ");
- tt_str_op((const char *) evbuffer_pullup(buf_out2, -1), ==,
- "0->36; 31->38; 38->0; 0->1; ");
- evbuffer_drain(buf_out1, evbuffer_get_length(buf_out1));
- evbuffer_drain(buf_out2, evbuffer_get_length(buf_out2));
- /* Let's test the obsolete buffer_setcb function too. */
- cb1 = evbuffer_add_cb(buf, log_change_callback, buf_out1);
- tt_assert(cb1 != NULL);
- cb2 = evbuffer_add_cb(buf, log_change_callback, buf_out2);
- tt_assert(cb2 != NULL);
- evbuffer_setcb(buf, self_draining_callback, NULL);
- evbuffer_add_printf(buf, "This should get drained right away.");
- tt_uint_op(evbuffer_get_length(buf), ==, 0);
- tt_uint_op(evbuffer_get_length(buf_out1), ==, 0);
- tt_uint_op(evbuffer_get_length(buf_out2), ==, 0);
- evbuffer_setcb(buf, NULL, NULL);
- evbuffer_add_printf(buf, "This will not.");
- tt_str_op((const char *) evbuffer_pullup(buf, -1), ==, "This will not.");
- evbuffer_validate(buf);
- evbuffer_drain(buf, evbuffer_get_length(buf));
- evbuffer_validate(buf);
-#if 0
- /* Now let's try a suspended callback. */
- cb1 = evbuffer_add_cb(buf, log_change_callback, buf_out1);
- cb2 = evbuffer_add_cb(buf, log_change_callback, buf_out2);
- evbuffer_cb_suspend(buf,cb2);
- evbuffer_prepend(buf,"Hello world",11); /*0->11*/
- evbuffer_validate(buf);
- evbuffer_cb_suspend(buf,cb1);
- evbuffer_add(buf,"more",4); /* 11->15 */
- evbuffer_cb_unsuspend(buf,cb2);
- evbuffer_drain(buf, 4); /* 15->11 */
- evbuffer_cb_unsuspend(buf,cb1);
- evbuffer_drain(buf, evbuffer_get_length(buf)); /* 11->0 */
-
- tt_str_op(evbuffer_pullup(buf_out1, -1), ==,
- "0->11; 11->11; 11->0; ");
- tt_str_op(evbuffer_pullup(buf_out2, -1), ==,
- "0->15; 15->11; 11->0; ");
-#endif
-
- end:
- if (buf)
- evbuffer_free(buf);
- if (buf_out1)
- evbuffer_free(buf_out1);
- if (buf_out2)
- evbuffer_free(buf_out2);
-}
-
-static int ref_done_cb_called_count = 0;
-static void *ref_done_cb_called_with = NULL;
-static const void *ref_done_cb_called_with_data = NULL;
-static size_t ref_done_cb_called_with_len = 0;
-static void ref_done_cb(const void *data, size_t len, void *info)
-{
- ++ref_done_cb_called_count;
- ref_done_cb_called_with = info;
- ref_done_cb_called_with_data = data;
- ref_done_cb_called_with_len = len;
-}
-
-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);
- evbuffer_validate(buf1);
-
- /* 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_assert(ref_done_cb_called_with_data == chunk1);
- tt_assert(ref_done_cb_called_with_len == len1);
- tt_int_op(ref_done_cb_called_count, ==, 1);
- evbuffer_validate(buf1);
-
- /* 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);
- evbuffer_validate(buf2);
-
- /* 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.", 35);
- 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);
-}
-
-static void
-test_evbuffer_multicast(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(buf1, chunk1, len1);
- evbuffer_add(buf1, ", ", 2);
- evbuffer_add(buf1, chunk2, len2);
- tt_int_op(evbuffer_get_length(buf1), ==, len1+len2+2);
-
- buf2 = evbuffer_new();
- tt_assert(buf2);
-
- tt_int_op(evbuffer_add_buffer_reference(buf2, buf1), ==, 0);
- /* nested references are not allowed */
- tt_int_op(evbuffer_add_buffer_reference(buf2, buf2), ==, -1);
- tt_int_op(evbuffer_add_buffer_reference(buf1, buf2), ==, -1);
-
- /* both buffers contain the same amount of data */
- tt_int_op(evbuffer_get_length(buf1), ==, evbuffer_get_length(buf1));
-
- /* Make sure we can drain a little from the first buffer. */
- 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);
- evbuffer_validate(buf1);
-
- /* Make sure we can drain a little from the second buffer. */
- tt_int_op(evbuffer_remove(buf2, tmp, 6), ==, 6);
- tt_int_op(memcmp(tmp, "If you", 6), ==, 0);
- tt_int_op(evbuffer_remove(buf2, 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(buf2, "I have ", 7), ==, 0);
- tt_int_op(memcmp(chunk1, "If you", 6), ==, 0);
- evbuffer_validate(buf2);
-
- /* Make sure the data can be read from the second buffer when the first is freed */
- evbuffer_free(buf1);
- buf1 = NULL;
-
- tt_int_op(evbuffer_remove(buf2, tmp, 6), ==, 6);
- tt_int_op(memcmp(tmp, "I have", 6), ==, 0);
-
- tt_int_op(evbuffer_remove(buf2, tmp, 6), ==, 6);
- tt_int_op(memcmp(tmp, " foun", 6), ==, 0);
-
-end:
- if (buf1)
- evbuffer_free(buf1);
- if (buf2)
- evbuffer_free(buf2);
-}
-
-static void
-test_evbuffer_multicast_drain(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 */
- size_t len1 = strlen(chunk1), len2=strlen(chunk2);
-
- struct evbuffer *buf1 = NULL, *buf2 = NULL;
-
- buf1 = evbuffer_new();
- tt_assert(buf1);
-
- evbuffer_add(buf1, chunk1, len1);
- evbuffer_add(buf1, ", ", 2);
- evbuffer_add(buf1, chunk2, len2);
- tt_int_op(evbuffer_get_length(buf1), ==, len1+len2+2);
-
- buf2 = evbuffer_new();
- tt_assert(buf2);
-
- tt_int_op(evbuffer_add_buffer_reference(buf2, buf1), ==, 0);
- tt_int_op(evbuffer_get_length(buf2), ==, len1+len2+2);
- tt_int_op(evbuffer_drain(buf1, evbuffer_get_length(buf1)), ==, 0);
- tt_int_op(evbuffer_get_length(buf2), ==, len1+len2+2);
- tt_int_op(evbuffer_drain(buf2, evbuffer_get_length(buf2)), ==, 0);
- evbuffer_validate(buf1);
- evbuffer_validate(buf2);
-
-end:
- if (buf1)
- evbuffer_free(buf1);
- if (buf2)
- evbuffer_free(buf2);
-}
-
-static void
-check_prepend(struct evbuffer *buffer,
- const struct evbuffer_cb_info *cbinfo,
- void *arg)
-{
- tt_int_op(cbinfo->orig_size, ==, 3);
- tt_int_op(cbinfo->n_added, ==, 8096);
- tt_int_op(cbinfo->n_deleted, ==, 0);
-end:
- ;
-}
-/* Some cases that we didn't get in test_evbuffer() above, for more coverage. */
-static void
-test_evbuffer_prepend(void *ptr)
-{
- struct evbuffer *buf1 = NULL, *buf2 = NULL;
- char tmp[128], *buffer = malloc(8096);
- int n;
-
- buf1 = evbuffer_new();
- tt_assert(buf1);
-
- /* Case 0: The evbuffer is entirely empty. */
- evbuffer_prepend(buf1, "This string has 29 characters", 29);
- evbuffer_validate(buf1);
-
- /* Case 1: Prepend goes entirely in new chunk. */
- evbuffer_prepend(buf1, "Short.", 6);
- evbuffer_validate(buf1);
-
- /* Case 2: prepend goes entirely in first chunk. */
- evbuffer_drain(buf1, 6+11);
- evbuffer_prepend(buf1, "it", 2);
- evbuffer_validate(buf1);
- tt_assert(!memcmp(buf1->first->buffer+buf1->first->misalign,
- "it has", 6));
-
- /* Case 3: prepend is split over multiple chunks. */
- evbuffer_prepend(buf1, "It is no longer true to say ", 28);
- evbuffer_validate(buf1);
- n = evbuffer_remove(buf1, tmp, sizeof(tmp)-1);
- tt_int_op(n, >=, 0);
- tmp[n]='\0';
- tt_str_op(tmp,==,"It is no longer true to say it has 29 characters");
-
- buf2 = evbuffer_new();
- tt_assert(buf2);
-
- /* Case 4: prepend a buffer to an empty buffer. */
- n = 999;
- evbuffer_add_printf(buf1, "Here is string %d. ", n++);
- evbuffer_prepend_buffer(buf2, buf1);
- evbuffer_validate(buf2);
-
- /* Case 5: prepend a buffer to a nonempty buffer. */
- evbuffer_add_printf(buf1, "Here is string %d. ", n++);
- evbuffer_prepend_buffer(buf2, buf1);
- evbuffer_validate(buf2);
- evbuffer_validate(buf1);
- n = evbuffer_remove(buf2, tmp, sizeof(tmp)-1);
- tt_int_op(n, >=, 0);
- tmp[n]='\0';
- tt_str_op(tmp,==,"Here is string 1000. Here is string 999. ");
-
- /* Case 5: evbuffer_prepend() will need a new buffer, with callbacks */
- memset(buffer, 'A', 8096);
- evbuffer_free(buf2);
- buf2 = evbuffer_new();
- tt_assert(buf2);
- evbuffer_prepend(buf2, "foo", 3);
- evbuffer_add_cb(buf2, check_prepend, NULL);
- evbuffer_prepend(buf2, buffer, 8096);
- evbuffer_remove_cb(buf2, check_prepend, NULL);
- evbuffer_validate(buf2);
- tt_nstr_op(8096,(char *)evbuffer_pullup(buf2, 8096),==,buffer);
- evbuffer_drain(buf2, 8096);
- tt_nstr_op(3,(char *)evbuffer_pullup(buf2, 3),==,"foo");
- evbuffer_drain(buf2, 3);
-
-end:
- free(buffer);
- if (buf1)
- evbuffer_free(buf1);
- if (buf2)
- evbuffer_free(buf2);
-
-}
-
-static void
-test_evbuffer_peek_first_gt(void *info)
-{
- struct evbuffer *buf = NULL, *tmp_buf = NULL;
- struct evbuffer_ptr ptr;
- struct evbuffer_iovec v[2];
-
- buf = evbuffer_new();
- tmp_buf = evbuffer_new();
- evbuffer_add_printf(tmp_buf, "Contents of chunk 100\n");
- evbuffer_add_buffer(buf, tmp_buf);
- evbuffer_add_printf(tmp_buf, "Contents of chunk 1\n");
- evbuffer_add_buffer(buf, tmp_buf);
-
- evbuffer_ptr_set(buf, &ptr, 0, EVBUFFER_PTR_SET);
-
- /** The only case that matters*/
- tt_int_op(evbuffer_peek(buf, -1, &ptr, NULL, 0), ==, 2);
- /** Just in case */
- tt_int_op(evbuffer_peek(buf, -1, &ptr, v, 2), ==, 2);
-
- evbuffer_ptr_set(buf, &ptr, 20, EVBUFFER_PTR_ADD);
- tt_int_op(evbuffer_peek(buf, -1, &ptr, NULL, 0), ==, 2);
- tt_int_op(evbuffer_peek(buf, -1, &ptr, v, 2), ==, 2);
- tt_int_op(evbuffer_peek(buf, 2, &ptr, NULL, 0), ==, 1);
- tt_int_op(evbuffer_peek(buf, 2, &ptr, v, 2), ==, 1);
- tt_int_op(evbuffer_peek(buf, 3, &ptr, NULL, 0), ==, 2);
- tt_int_op(evbuffer_peek(buf, 3, &ptr, v, 2), ==, 2);
-
-end:
- if (buf)
- evbuffer_free(buf);
- if (tmp_buf)
- evbuffer_free(tmp_buf);
-}
-
-static void
-test_evbuffer_peek(void *info)
-{
- struct evbuffer *buf = NULL, *tmp_buf = NULL;
- int i;
- struct evbuffer_iovec v[20];
- struct evbuffer_ptr ptr;
-
-#define tt_iov_eq(v, s) \
- tt_int_op((v)->iov_len, ==, strlen(s)); \
- tt_assert(!memcmp((v)->iov_base, (s), strlen(s)))
-
- /* Let's make a very fragmented buffer. */
- buf = evbuffer_new();
- tmp_buf = evbuffer_new();
- for (i = 0; i < 16; ++i) {
- evbuffer_add_printf(tmp_buf, "Contents of chunk [%d]\n", i);
- evbuffer_add_buffer(buf, tmp_buf);
- }
-
- /* How many chunks do we need for everything? */
- i = evbuffer_peek(buf, -1, NULL, NULL, 0);
- tt_int_op(i, ==, 16);
-
- /* Simple peek: get everything. */
- i = evbuffer_peek(buf, -1, NULL, v, 20);
- tt_int_op(i, ==, 16); /* we used only 16 chunks. */
- tt_iov_eq(&v[0], "Contents of chunk [0]\n");
- tt_iov_eq(&v[3], "Contents of chunk [3]\n");
- tt_iov_eq(&v[12], "Contents of chunk [12]\n");
- tt_iov_eq(&v[15], "Contents of chunk [15]\n");
-
- /* Just get one chunk worth. */
- memset(v, 0, sizeof(v));
- i = evbuffer_peek(buf, -1, NULL, v, 1);
- tt_int_op(i, ==, 1);
- tt_iov_eq(&v[0], "Contents of chunk [0]\n");
- tt_assert(v[1].iov_base == NULL);
-
- /* Suppose we want at least the first 40 bytes. */
- memset(v, 0, sizeof(v));
- i = evbuffer_peek(buf, 40, NULL, v, 16);
- tt_int_op(i, ==, 2);
- tt_iov_eq(&v[0], "Contents of chunk [0]\n");
- tt_iov_eq(&v[1], "Contents of chunk [1]\n");
- tt_assert(v[2].iov_base == NULL);
-
- /* How many chunks do we need for 100 bytes? */
- memset(v, 0, sizeof(v));
- i = evbuffer_peek(buf, 100, NULL, NULL, 0);
- tt_int_op(i, ==, 5);
- tt_assert(v[0].iov_base == NULL);
-
- /* Now we ask for more bytes than we provide chunks for */
- memset(v, 0, sizeof(v));
- i = evbuffer_peek(buf, 60, NULL, v, 1);
- tt_int_op(i, ==, 3);
- tt_iov_eq(&v[0], "Contents of chunk [0]\n");
- tt_assert(v[1].iov_base == NULL);
-
- /* Now we ask for more bytes than the buffer has. */
- memset(v, 0, sizeof(v));
- i = evbuffer_peek(buf, 65536, NULL, v, 20);
- tt_int_op(i, ==, 16); /* we used only 16 chunks. */
- tt_iov_eq(&v[0], "Contents of chunk [0]\n");
- tt_iov_eq(&v[3], "Contents of chunk [3]\n");
- tt_iov_eq(&v[12], "Contents of chunk [12]\n");
- tt_iov_eq(&v[15], "Contents of chunk [15]\n");
- tt_assert(v[16].iov_base == NULL);
-
- /* What happens if we try an empty buffer? */
- memset(v, 0, sizeof(v));
- i = evbuffer_peek(tmp_buf, -1, NULL, v, 20);
- tt_int_op(i, ==, 0);
- tt_assert(v[0].iov_base == NULL);
- memset(v, 0, sizeof(v));
- i = evbuffer_peek(tmp_buf, 50, NULL, v, 20);
- tt_int_op(i, ==, 0);
- tt_assert(v[0].iov_base == NULL);
-
- /* Okay, now time to have fun with pointers. */
- memset(v, 0, sizeof(v));
- evbuffer_ptr_set(buf, &ptr, 30, EVBUFFER_PTR_SET);
- i = evbuffer_peek(buf, 50, &ptr, v, 20);
- tt_int_op(i, ==, 3);
- tt_iov_eq(&v[0], " of chunk [1]\n");
- tt_iov_eq(&v[1], "Contents of chunk [2]\n");
- tt_iov_eq(&v[2], "Contents of chunk [3]\n"); /*more than we asked for*/
-
- /* advance to the start of another chain. */
- memset(v, 0, sizeof(v));
- evbuffer_ptr_set(buf, &ptr, 14, EVBUFFER_PTR_ADD);
- i = evbuffer_peek(buf, 44, &ptr, v, 20);
- tt_int_op(i, ==, 2);
- tt_iov_eq(&v[0], "Contents of chunk [2]\n");
- tt_iov_eq(&v[1], "Contents of chunk [3]\n"); /*more than we asked for*/
-
- /* peek at the end of the buffer */
- memset(v, 0, sizeof(v));
- tt_assert(evbuffer_ptr_set(buf, &ptr, evbuffer_get_length(buf), EVBUFFER_PTR_SET) == 0);
- i = evbuffer_peek(buf, 44, &ptr, v, 20);
- tt_int_op(i, ==, 0);
- tt_assert(v[0].iov_base == NULL);
-
-end:
- if (buf)
- evbuffer_free(buf);
- if (tmp_buf)
- evbuffer_free(tmp_buf);
-}
-
-/* Check whether evbuffer freezing works right. This is called twice,
- once with the argument "start" and once with the argument "end".
- When we test "start", we freeze the start of an evbuffer and make sure
- that modifying the start of the buffer doesn't work. When we test
- "end", we freeze the end of an evbuffer and make sure that modifying
- the end of the buffer doesn't work.
- */
-static void
-test_evbuffer_freeze(void *ptr)
-{
- struct evbuffer *buf = NULL, *tmp_buf=NULL;
- const char string[] = /* Year's End, Richard Wilbur */
- "I've known the wind by water banks to shake\n"
- "The late leaves down, which frozen where they fell\n"
- "And held in ice as dancers in a spell\n"
- "Fluttered all winter long into a lake...";
- const int start = !strcmp(ptr, "start");
- char *cp;
- char charbuf[128];
- int r;
- size_t orig_length;
- struct evbuffer_iovec v[1];
-
- if (!start)
- tt_str_op(ptr, ==, "end");
-
- buf = evbuffer_new();
- tmp_buf = evbuffer_new();
- tt_assert(tmp_buf);
-
- evbuffer_add(buf, string, strlen(string));
- evbuffer_freeze(buf, start); /* Freeze the start or the end.*/
-
-#define FREEZE_EQ(a, startcase, endcase) \
- do { \
- if (start) { \
- tt_int_op((a), ==, (startcase)); \
- } else { \
- tt_int_op((a), ==, (endcase)); \
- } \
- } while (0)
-
-
- orig_length = evbuffer_get_length(buf);
-
- /* These functions all manipulate the end of buf. */
- r = evbuffer_add(buf, "abc", 0);
- FREEZE_EQ(r, 0, -1);
- r = evbuffer_reserve_space(buf, 10, v, 1);
- FREEZE_EQ(r, 1, -1);
- if (r == 1) {
- memset(v[0].iov_base, 'X', 10);
- v[0].iov_len = 10;
- }
- r = evbuffer_commit_space(buf, v, 1);
- FREEZE_EQ(r, 0, -1);
- r = evbuffer_add_reference(buf, string, 5, NULL, NULL);
- FREEZE_EQ(r, 0, -1);
- r = evbuffer_add_printf(buf, "Hello %s", "world");
- FREEZE_EQ(r, 11, -1);
- /* TODO: test add_buffer, add_file, read */
-
- if (!start)
- tt_int_op(orig_length, ==, evbuffer_get_length(buf));
-
- orig_length = evbuffer_get_length(buf);
-
- /* These functions all manipulate the start of buf. */
- r = evbuffer_remove(buf, charbuf, 1);
- FREEZE_EQ(r, -1, 1);
- r = evbuffer_drain(buf, 3);
- FREEZE_EQ(r, -1, 0);
- r = evbuffer_prepend(buf, "dummy", 5);
- FREEZE_EQ(r, -1, 0);
- cp = evbuffer_readln(buf, NULL, EVBUFFER_EOL_LF);
- FREEZE_EQ(cp==NULL, 1, 0);
- if (cp)
- free(cp);
- /* TODO: Test remove_buffer, add_buffer, write, prepend_buffer */
-
- if (start)
- tt_int_op(orig_length, ==, evbuffer_get_length(buf));
-
-end:
- if (buf)
- evbuffer_free(buf);
-
- if (tmp_buf)
- evbuffer_free(tmp_buf);
-}
-
-static void
-test_evbuffer_add_iovec(void * ptr)
-{
- struct evbuffer * buf = NULL;
- struct evbuffer_iovec vec[4];
- const char * data[] = {
- "Guilt resembles a sword with two edges.",
- "On the one hand, it cuts for Justice, imposing practical morality upon those who fear it.",
- "Conscience does not always adhere to rational judgment.",
- "Guilt is always a self-imposed burden, but it is not always rightly imposed."
- /* -- R.A. Salvatore, _Sojurn_ */
- };
- size_t expected_length = 0;
- size_t returned_length = 0;
- int i;
-
- buf = evbuffer_new();
-
- tt_assert(buf);
-
- for (i = 0; i < 4; i++) {
- vec[i].iov_len = strlen(data[i]);
- vec[i].iov_base = (char*) data[i];
- expected_length += vec[i].iov_len;
- }
-
- returned_length = evbuffer_add_iovec(buf, vec, 4);
-
- tt_int_op(returned_length, ==, evbuffer_get_length(buf));
- tt_int_op(evbuffer_get_length(buf), ==, expected_length);
-
- for (i = 0; i < 4; i++) {
- char charbuf[1024];
-
- memset(charbuf, 0, 1024);
- evbuffer_remove(buf, charbuf, strlen(data[i]));
- tt_assert(strcmp(charbuf, data[i]) == 0);
- }
-
- tt_assert(evbuffer_get_length(buf) == 0);
-end:
- if (buf) {
- evbuffer_free(buf);
- }
-}
-
-static void
-test_evbuffer_copyout(void *dummy)
-{
- const char string[] =
- "Still they skirmish to and fro, men my messmates on the snow "
- "When we headed off the aurochs turn for turn; "
- "When the rich Allobrogenses never kept amanuenses, "
- "And our only plots were piled in lakes at Berne.";
- /* -- Kipling, "In The Neolithic Age" */
- char tmp[1024];
- struct evbuffer_ptr ptr;
- struct evbuffer *buf;
-
- (void)dummy;
-
- buf = evbuffer_new();
- tt_assert(buf);
-
- tt_int_op(strlen(string), ==, 206);
-
- /* Ensure separate chains */
- evbuffer_add_reference(buf, string, 80, no_cleanup, NULL);
- evbuffer_add_reference(buf, string+80, 80, no_cleanup, NULL);
- evbuffer_add(buf, string+160, strlen(string)-160);
-
- tt_int_op(206, ==, evbuffer_get_length(buf));
-
- /* First, let's test plain old copyout. */
-
- /* Copy a little from the beginning. */
- tt_int_op(10, ==, evbuffer_copyout(buf, tmp, 10));
- tt_int_op(0, ==, memcmp(tmp, "Still they", 10));
-
- /* Now copy more than a little from the beginning */
- memset(tmp, 0, sizeof(tmp));
- tt_int_op(100, ==, evbuffer_copyout(buf, tmp, 100));
- tt_int_op(0, ==, memcmp(tmp, string, 100));
-
- /* Copy too much; ensure truncation. */
- memset(tmp, 0, sizeof(tmp));
- tt_int_op(206, ==, evbuffer_copyout(buf, tmp, 230));
- tt_int_op(0, ==, memcmp(tmp, string, 206));
-
- /* That was supposed to be nondestructive, btw */
- tt_int_op(206, ==, evbuffer_get_length(buf));
-
- /* Now it's time to test copyout_from! First, let's start in the
- * first chain. */
- evbuffer_ptr_set(buf, &ptr, 15, EVBUFFER_PTR_SET);
- memset(tmp, 0, sizeof(tmp));
- tt_int_op(10, ==, evbuffer_copyout_from(buf, &ptr, tmp, 10));
- tt_int_op(0, ==, memcmp(tmp, "mish to an", 10));
-
- /* Right up to the end of the first chain */
- memset(tmp, 0, sizeof(tmp));
- tt_int_op(65, ==, evbuffer_copyout_from(buf, &ptr, tmp, 65));
- tt_int_op(0, ==, memcmp(tmp, string+15, 65));
-
- /* Span into the second chain */
- memset(tmp, 0, sizeof(tmp));
- tt_int_op(90, ==, evbuffer_copyout_from(buf, &ptr, tmp, 90));
- tt_int_op(0, ==, memcmp(tmp, string+15, 90));
-
- /* Span into the third chain */
- memset(tmp, 0, sizeof(tmp));
- tt_int_op(160, ==, evbuffer_copyout_from(buf, &ptr, tmp, 160));
- tt_int_op(0, ==, memcmp(tmp, string+15, 160));
-
- /* Overrun */
- memset(tmp, 0, sizeof(tmp));
- tt_int_op(206-15, ==, evbuffer_copyout_from(buf, &ptr, tmp, 999));
- tt_int_op(0, ==, memcmp(tmp, string+15, 206-15));
-
- /* That was supposed to be nondestructive, too */
- tt_int_op(206, ==, evbuffer_get_length(buf));
-
-end:
- if (buf)
- evbuffer_free(buf);
-}
-
-static void *
-setup_passthrough(const struct testcase_t *testcase)
-{
- return testcase->setup_data;
-}
-static int
-cleanup_passthrough(const struct testcase_t *testcase, void *ptr)
-{
- (void) ptr;
- return 1;
-}
-
-static const struct testcase_setup_t nil_setup = {
- setup_passthrough,
- cleanup_passthrough
-};
-
-struct testcase_t evbuffer_testcases[] = {
- { "evbuffer", test_evbuffer, 0, NULL, NULL },
- { "remove_buffer_with_empty", test_evbuffer_remove_buffer_with_empty, 0, NULL, NULL },
- { "remove_buffer_with_empty2", test_evbuffer_remove_buffer_with_empty2, 0, NULL, NULL },
- { "remove_buffer_with_empty3", test_evbuffer_remove_buffer_with_empty3, 0, NULL, NULL },
- { "add_buffer_with_empty", test_evbuffer_add_buffer_with_empty, 0, NULL, NULL },
- { "add_buffer_with_empty2", test_evbuffer_add_buffer_with_empty2, 0, NULL, NULL },
- { "reserve2", test_evbuffer_reserve2, 0, NULL, NULL },
- { "reserve_many", test_evbuffer_reserve_many, 0, NULL, NULL },
- { "reserve_many2", test_evbuffer_reserve_many, 0, &nil_setup, (void*)"add" },
- { "reserve_many3", test_evbuffer_reserve_many, 0, &nil_setup, (void*)"fill" },
- { "expand", test_evbuffer_expand, 0, NULL, NULL },
- { "expand_overflow", test_evbuffer_expand_overflow, 0, NULL, NULL },
- { "add1", test_evbuffer_add1, 0, NULL, NULL },
- { "add2", test_evbuffer_add2, 0, NULL, NULL },
- { "reference", test_evbuffer_reference, 0, NULL, NULL },
- { "reference2", test_evbuffer_reference2, 0, NULL, NULL },
- { "iterative", test_evbuffer_iterative, 0, NULL, NULL },
- { "readln", test_evbuffer_readln, TT_NO_LOGS, &basic_setup, NULL },
- { "search_eol", test_evbuffer_search_eol, 0, NULL, NULL },
- { "find", test_evbuffer_find, 0, NULL, NULL },
- { "ptr_set", test_evbuffer_ptr_set, 0, NULL, NULL },
- { "search", test_evbuffer_search, 0, NULL, NULL },
- { "callbacks", test_evbuffer_callbacks, 0, NULL, NULL },
- { "add_reference", test_evbuffer_add_reference, 0, NULL, NULL },
- { "multicast", test_evbuffer_multicast, 0, NULL, NULL },
- { "multicast_drain", test_evbuffer_multicast_drain, 0, NULL, NULL },
- { "prepend", test_evbuffer_prepend, TT_FORK, NULL, NULL },
- { "peek", test_evbuffer_peek, 0, NULL, NULL },
- { "peek_first_gt", test_evbuffer_peek_first_gt, 0, NULL, NULL },
- { "freeze_start", test_evbuffer_freeze, 0, &nil_setup, (void*)"start" },
- { "freeze_end", test_evbuffer_freeze, 0, &nil_setup, (void*)"end" },
- { "add_iovec", test_evbuffer_add_iovec, 0, NULL, NULL},
- { "copyout", test_evbuffer_copyout, 0, NULL, NULL},
- { "file_segment_add_cleanup_cb", test_evbuffer_file_segment_add_cleanup_cb, 0, NULL, NULL },
-
-#define ADDFILE_TEST(name, parameters) \
- { name, test_evbuffer_add_file, TT_FORK|TT_NEED_BASE, \
- &basic_setup, (void*)(parameters) }
-
-#define ADDFILE_TEST_GROUP(name, parameters) \
- ADDFILE_TEST(name "_sendfile", "sendfile " parameters), \
- ADDFILE_TEST(name "_mmap", "mmap " parameters), \
- ADDFILE_TEST(name "_linear", "linear " parameters)
-
- ADDFILE_TEST_GROUP("add_file", ""),
- ADDFILE_TEST("add_file_nosegment", "default nosegment"),
-
- ADDFILE_TEST_GROUP("add_big_file", "bigfile"),
- ADDFILE_TEST("add_big_file_nosegment", "default nosegment bigfile"),
-
- ADDFILE_TEST_GROUP("add_file_offset", "bigfile map_offset"),
- ADDFILE_TEST("add_file_offset_nosegment",
- "default nosegment bigfile map_offset"),
-
- ADDFILE_TEST_GROUP("add_file_offset2", "bigfile offset_in_segment"),
-
- ADDFILE_TEST_GROUP("add_file_offset3",
- "bigfile offset_in_segment map_offset"),
-
- END_OF_TESTCASES
-};