From: Leandro Lucarella Date: Wed, 27 Dec 2006 19:21:13 +0000 (+0000) Subject: Add tests. X-Git-Tag: 0.1~20 X-Git-Url: https://git.llucax.com/software/eventxx.git/commitdiff_plain/3de7450f04f8d9cd241eb600da57cbe0539aa62c Add tests. Some tests are ported from C libevent to this C++ wrapper. --- diff --git a/test/Makefile b/test/Makefile new file mode 100644 index 0000000..63018a6 --- /dev/null +++ b/test/Makefile @@ -0,0 +1,16 @@ + +CXXFLAGS=-I.. -g +# Uncomment this if you have a fixed event_base_free(). +# See http://www.mail-archive.com/libevent-users@monkey.org/msg00112.html +#CXXFLAGS+=-DEVENT_BASE_FREE_FIX +LDFLAGS=-levent + +targets=bench test-eof test-time test-weof + +all: $(targets) + +clean: + $(RM) -fv *.o $(targets) + +.PHONY: clean all + diff --git a/test/bench.cpp b/test/bench.cpp new file mode 100644 index 0000000..a098012 --- /dev/null +++ b/test/bench.cpp @@ -0,0 +1,187 @@ +/* + * Copyright 2003 Niels Provos + * All rights reserved. + * + * 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. + * 4. 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. + * + * + * Mon 03/10/2003 - Modified by Davide Libenzi + * + * Added chain event propagation to improve the sensitivity of + * the measure respect to the event loop efficency. + * + * Wed 2006-12-27 - Modified by Leandro Lucarella + * + * Adapted to test the C++ inteface. + * + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + + +static int count, writes, fired; +static int *pipes; +static int num_pipes, num_active, num_writes; +static std::vector< event::cevent* > events; +static event::dispatcher d; + + +void +read_cb(int fd, short which, void *arg) +{ + int idx = (int) arg, widx = idx + 1; + u_char ch; + + count += read(fd, &ch, sizeof(ch)); + if (writes) { + if (widx >= num_pipes) + widx -= num_pipes; + write(pipes[2 * widx + 1], "e", 1); + writes--; + fired++; + } +} + +event::time * +run_once(void) +{ + int *cp, i, space; + static event::time ts, te; + + for (cp = pipes, i = 0; i < num_pipes; i++, cp += 2) { + events.push_back(new event::cevent(cp[0], EV_READ | EV_PERSIST, + read_cb, (void *) i)); + d.add(*events[i]); + } + + d.dispatch(EVLOOP_ONCE | EVLOOP_NONBLOCK); + + fired = 0; + space = num_pipes / num_active; + space = space * 2; + for (i = 0; i < num_active; i++, fired++) + write(pipes[i * space + 1], "e", 1); + + count = 0; + writes = num_writes; + { + int xcount = 0; + gettimeofday(&ts, NULL); + do { + d.dispatch(EVLOOP_ONCE | EVLOOP_NONBLOCK); + xcount++; + } while (count != fired); + gettimeofday(&te, NULL); + + if (xcount != count) fprintf(stderr, "Xcount: %d, Rcount: %d\n", xcount, count); + } + + timersub(&te, &ts, &te); + + for (i = 0; i < num_pipes; i++) { + d.del(*events[i]); + delete events[i]; + } + events.clear(); + + return (&te); +} + +int +main (int argc, char **argv) +{ + struct rlimit rl; + int i, c; + event::time* tv; + int *cp; + extern char *optarg; + + num_pipes = 100; + num_active = 1; + num_writes = num_pipes; + while ((c = getopt(argc, argv, "n:a:w:")) != -1) { + switch (c) { + case 'n': + num_pipes = atoi(optarg); + break; + case 'a': + num_active = atoi(optarg); + break; + case 'w': + num_writes = atoi(optarg); + break; + default: + fprintf(stderr, "Illegal argument \"%c\"\n", c); + exit(1); + } + } + + rl.rlim_cur = rl.rlim_max = num_pipes * 2 + 50; + if (setrlimit(RLIMIT_NOFILE, &rl) == -1) { + perror("setrlimit"); + exit(1); + } + + pipes = new int[num_pipes * 2]; + + for (cp = pipes, i = 0; i < num_pipes; i++, cp += 2) { +#ifdef USE_PIPES + if (pipe(cp) == -1) { +#else + if (socketpair(AF_UNIX, SOCK_STREAM, 0, cp) == -1) { +#endif + perror("pipe"); + exit(1); + } + } + + for (i = 0; i < 25; i++) { + tv = run_once(); + assert(tv); + fprintf(stdout, "%ld\n", + tv->sec() * 1000000L + tv->usec()); + } + + delete[] pipes; + + exit(0); +} diff --git a/test/test-eof.cpp b/test/test-eof.cpp new file mode 100644 index 0000000..a76b6b4 --- /dev/null +++ b/test/test-eof.cpp @@ -0,0 +1,73 @@ +/* + * Compile with: + * c++ -I/usr/local/include -o time-test time-test.c -L/usr/local/lib -levent + * + * + * Wed 2006-12-27 - Modified by Leandro Lucarella + * + * Adapted to test the C++ inteface. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +int test_okay = 1; +int called = 0; +event::dispatcher d; +event::cevent* ev; + +void +read_cb(int fd, short event, void *arg) +{ + char buf[256]; + int len; + + len = read(fd, buf, sizeof(buf)); + + printf("%s: read %d%s\n", __func__, + len, len ? "" : " - means EOF"); + + if (len) { + if (!called) + d.add(*ev); + } else if (called == 1) + test_okay = 0; + + called++; +} + +int +main (int argc, char **argv) +{ + char *test = "test string"; + int pair[2]; + + if (socketpair(AF_UNIX, SOCK_STREAM, 0, pair) == -1) + return (1); + + write(pair[0], test, strlen(test)+1); + shutdown(pair[0], SHUT_WR); + + /* Initalize one event */ + ev = new event::cevent(pair[1], EV_READ, read_cb, NULL); + + d.add(*ev); + + d.dispatch(); + + delete ev; + + return (test_okay); +} + diff --git a/test/test-time.cpp b/test/test-time.cpp new file mode 100644 index 0000000..c1326b4 --- /dev/null +++ b/test/test-time.cpp @@ -0,0 +1,60 @@ +/* + * Compile with: + * c++ -I/usr/local/include -o time-test time-test.cpp -L/usr/local/lib -levent + * + * Wed 2006-12-27 - Modified by Leandro Lucarella + * + * Adapted to test the C++ inteface. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +int called = 0; + +#define NEVENT 20000 + +event::ctimer* ev[NEVENT]; +event::dispatcher d; + +void +time_cb(int fd, short event, void *arg) +{ + called++; + + if (called < 10*NEVENT) { + for (int i = 0; i < 10; i++) { + event::time tv(0, random() % 50000L); + int j = random() % NEVENT; + if (tv.usec() % 2) + d.add(*ev[j], tv); + else + d.del(*ev[j]); + } + } +} + +int +main (int argc, char **argv) +{ + for (int i = 0; i < NEVENT; i++) { + /* Initalize one event */ + ev[i] = new event::ctimer(time_cb, NULL); + d.add(*ev[i], event::time(0, random() % 50000L)); + } + + d.dispatch(); + + return (called < NEVENT); +} + diff --git a/test/test-weof.cpp b/test/test-weof.cpp new file mode 100644 index 0000000..90f2c08 --- /dev/null +++ b/test/test-weof.cpp @@ -0,0 +1,74 @@ +/* + * Compile with: + * c++ -I/usr/local/include -o time-test time-test.cpp -L/usr/local/lib -levent + * + * Wed 2006-12-27 - Modified by Leandro Lucarella + * + * Adapted to test the C++ inteface. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +typedef void (cb_t)(int, short); + +int pair[2]; +int test_okay = 1; +int called = 0; +event::dispatcher d; +event::event< cb_t >* ev; + +void +write_cb(int fd, short event) +{ + char *test = "test string"; + int len; + + len = write(fd, test, strlen(test) + 1); + + printf("%s: write %d%s\n", __func__, + len, len ? "" : " - means EOF"); + + if (len > 0) { + if (!called) + d.add(*ev); + close(pair[0]); + } else if (called == 1) + test_okay = 0; + + called++; +} + +int +main (int argc, char **argv) +{ + if (signal(SIGPIPE, SIG_IGN) == SIG_IGN) + return (1); + + if (socketpair(AF_UNIX, SOCK_STREAM, 0, pair) == -1) + return (1); + + /* Initalize one event */ + ev = new event::event< cb_t >(pair[1], EV_WRITE, write_cb); + + d.add(*ev); + + d.dispatch(); + + delete ev; + + return (test_okay); +} +