[or-cvs] Commit initial libevent sandbox to the tor project reposito...
Nick Mathewson
nickm at seul.org
Tue Feb 22 03:43:54 UTC 2005
Update of /home/or/cvsroot/libevent/test
In directory moria.mit.edu:/tmp/cvs-serv18110/test
Added Files:
Makefile.am Makefile.in bench.c regress.c test-eof.c
test-init.c test-time.c test-weof.c test.sh
Log Message:
Commit initial libevent sandbox to the tor project repository (version 1.0b)
--- NEW FILE: Makefile.am ---
AUTOMAKE_OPTIONS = foreign no-dependencies
LDADD = -L.. -levent
CPPFPLAGS = -I..
CFLAGS = -I../compat @CFLAGS@
noinst_PROGRAMS = test-init test-eof test-weof test-time regress bench
test_init_sources = test-init.c
test_eof_sources = test-eof.c
test_weof_sources = test-weof.c
test_time_sources = test-time.c
regress_sources = regress.c
bench_sources = bench.c
DISTCLEANFILES = *~
test: test-init test-eof test-weof test-time regress
verify: test
@./test.sh
bench test-init test-eof test-weof test-time regress: ../libevent.a
--- NEW FILE: Makefile.in ---
# Makefile.in generated automatically by automake 1.4-p6 from Makefile.am
# Copyright (C) 1994, 1995-8, 1999, 2001 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.
SHELL = @SHELL@
srcdir = @srcdir@
top_srcdir = @top_srcdir@
VPATH = @srcdir@
prefix = @prefix@
exec_prefix = @exec_prefix@
bindir = @bindir@
sbindir = @sbindir@
libexecdir = @libexecdir@
datadir = @datadir@
sysconfdir = @sysconfdir@
sharedstatedir = @sharedstatedir@
localstatedir = @localstatedir@
libdir = @libdir@
infodir = @infodir@
mandir = @mandir@
includedir = @includedir@
oldincludedir = /usr/include
DESTDIR =
pkgdatadir = $(datadir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
top_builddir = ..
ACLOCAL = @ACLOCAL@
AUTOCONF = @AUTOCONF@
AUTOMAKE = @AUTOMAKE@
AUTOHEADER = @AUTOHEADER@
INSTALL = @INSTALL@
INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS)
INSTALL_DATA = @INSTALL_DATA@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
transform = @program_transform_name@
NORMAL_INSTALL = :
PRE_INSTALL = :
POST_INSTALL = :
NORMAL_UNINSTALL = :
PRE_UNINSTALL = :
POST_UNINSTALL = :
CC = @CC@
LN_S = @LN_S@
MAINT = @MAINT@
MAKEINFO = @MAKEINFO@
PACKAGE = @PACKAGE@
RANLIB = @RANLIB@
VERSION = @VERSION@
AUTOMAKE_OPTIONS = foreign no-dependencies
LDADD = -L.. -levent
CPPFPLAGS = -I..
CFLAGS = -I../compat @CFLAGS@
noinst_PROGRAMS = test-init test-eof test-weof test-time regress bench
test_init_sources = test-init.c
test_eof_sources = test-eof.c
test_weof_sources = test-weof.c
test_time_sources = test-time.c
regress_sources = regress.c
bench_sources = bench.c
DISTCLEANFILES = *~
mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
CONFIG_HEADER = ../config.h
CONFIG_CLEAN_FILES =
PROGRAMS = $(noinst_PROGRAMS)
DEFS = @DEFS@ -I. -I$(srcdir) -I..
CPPFLAGS = @CPPFLAGS@
LDFLAGS = @LDFLAGS@
LIBS = @LIBS@
test_init_SOURCES = test-init.c
test_init_OBJECTS = test-init.o
test_init_LDADD = $(LDADD)
test_init_DEPENDENCIES =
test_init_LDFLAGS =
test_eof_SOURCES = test-eof.c
test_eof_OBJECTS = test-eof.o
test_eof_LDADD = $(LDADD)
test_eof_DEPENDENCIES =
test_eof_LDFLAGS =
test_weof_SOURCES = test-weof.c
test_weof_OBJECTS = test-weof.o
test_weof_LDADD = $(LDADD)
test_weof_DEPENDENCIES =
test_weof_LDFLAGS =
test_time_SOURCES = test-time.c
test_time_OBJECTS = test-time.o
test_time_LDADD = $(LDADD)
test_time_DEPENDENCIES =
test_time_LDFLAGS =
regress_SOURCES = regress.c
regress_OBJECTS = regress.o
regress_LDADD = $(LDADD)
regress_DEPENDENCIES =
regress_LDFLAGS =
bench_SOURCES = bench.c
bench_OBJECTS = bench.o
bench_LDADD = $(LDADD)
bench_DEPENDENCIES =
bench_LDFLAGS =
COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
CCLD = $(CC)
LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@
DIST_COMMON = Makefile.am Makefile.in
DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
TAR = tar
GZIP_ENV = --best
SOURCES = test-init.c test-eof.c test-weof.c test-time.c regress.c bench.c
OBJECTS = test-init.o test-eof.o test-weof.o test-time.o regress.o bench.o
all: all-redirect
.SUFFIXES:
.SUFFIXES: .S .c .o .s
$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4)
cd $(top_srcdir) && $(AUTOMAKE) --foreign test/Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
cd $(top_builddir) \
&& CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
mostlyclean-noinstPROGRAMS:
clean-noinstPROGRAMS:
-test -z "$(noinst_PROGRAMS)" || rm -f $(noinst_PROGRAMS)
distclean-noinstPROGRAMS:
maintainer-clean-noinstPROGRAMS:
.c.o:
$(COMPILE) -c $<
.s.o:
$(COMPILE) -c $<
.S.o:
$(COMPILE) -c $<
mostlyclean-compile:
-rm -f *.o core *.core
clean-compile:
distclean-compile:
-rm -f *.tab.c
maintainer-clean-compile:
test-init: $(test_init_OBJECTS) $(test_init_DEPENDENCIES)
@rm -f test-init
$(LINK) $(test_init_LDFLAGS) $(test_init_OBJECTS) $(test_init_LDADD) $(LIBS)
test-eof: $(test_eof_OBJECTS) $(test_eof_DEPENDENCIES)
@rm -f test-eof
$(LINK) $(test_eof_LDFLAGS) $(test_eof_OBJECTS) $(test_eof_LDADD) $(LIBS)
test-weof: $(test_weof_OBJECTS) $(test_weof_DEPENDENCIES)
@rm -f test-weof
$(LINK) $(test_weof_LDFLAGS) $(test_weof_OBJECTS) $(test_weof_LDADD) $(LIBS)
test-time: $(test_time_OBJECTS) $(test_time_DEPENDENCIES)
@rm -f test-time
$(LINK) $(test_time_LDFLAGS) $(test_time_OBJECTS) $(test_time_LDADD) $(LIBS)
regress: $(regress_OBJECTS) $(regress_DEPENDENCIES)
@rm -f regress
$(LINK) $(regress_LDFLAGS) $(regress_OBJECTS) $(regress_LDADD) $(LIBS)
bench: $(bench_OBJECTS) $(bench_DEPENDENCIES)
@rm -f bench
$(LINK) $(bench_LDFLAGS) $(bench_OBJECTS) $(bench_LDADD) $(LIBS)
tags: TAGS
ID: $(HEADERS) $(SOURCES) $(LISP)
list='$(SOURCES) $(HEADERS)'; \
unique=`for i in $$list; do echo $$i; done | \
awk ' { files[$$0] = 1; } \
END { for (i in files) print i; }'`; \
here=`pwd` && cd $(srcdir) \
&& mkid -f$$here/ID $$unique $(LISP)
TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) $(LISP)
tags=; \
here=`pwd`; \
list='$(SOURCES) $(HEADERS)'; \
unique=`for i in $$list; do echo $$i; done | \
awk ' { files[$$0] = 1; } \
END { for (i in files) print i; }'`; \
test -z "$(ETAGS_ARGS)$$unique$(LISP)$$tags" \
|| (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags $$unique $(LISP) -o $$here/TAGS)
mostlyclean-tags:
clean-tags:
distclean-tags:
-rm -f TAGS ID
maintainer-clean-tags:
distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir)
subdir = test
distdir: $(DISTFILES)
@for file in $(DISTFILES); do \
d=$(srcdir); \
if test -d $$d/$$file; then \
cp -pr $$d/$$file $(distdir)/$$file; \
else \
test -f $(distdir)/$$file \
|| ln $$d/$$file $(distdir)/$$file 2> /dev/null \
|| cp -p $$d/$$file $(distdir)/$$file || :; \
fi; \
done
info-am:
info: info-am
dvi-am:
dvi: dvi-am
check-am: all-am
check: check-am
installcheck-am:
installcheck: installcheck-am
install-exec-am:
install-exec: install-exec-am
install-data-am:
install-data: install-data-am
install-am: all-am
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
install: install-am
uninstall-am:
uninstall: uninstall-am
all-am: Makefile $(PROGRAMS)
all-redirect: all-am
install-strip:
$(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install
installdirs:
mostlyclean-generic:
clean-generic:
distclean-generic:
-rm -f Makefile $(CONFIG_CLEAN_FILES)
-rm -f config.cache config.log stamp-h stamp-h[0-9]*
-test -z "$(DISTCLEANFILES)" || rm -f $(DISTCLEANFILES)
maintainer-clean-generic:
mostlyclean-am: mostlyclean-noinstPROGRAMS mostlyclean-compile \
mostlyclean-tags mostlyclean-generic
mostlyclean: mostlyclean-am
clean-am: clean-noinstPROGRAMS clean-compile clean-tags clean-generic \
mostlyclean-am
clean: clean-am
distclean-am: distclean-noinstPROGRAMS distclean-compile distclean-tags \
distclean-generic clean-am
distclean: distclean-am
maintainer-clean-am: maintainer-clean-noinstPROGRAMS \
maintainer-clean-compile maintainer-clean-tags \
maintainer-clean-generic distclean-am
@echo "This command is intended for maintainers to use;"
@echo "it deletes files that may require special tools to rebuild."
maintainer-clean: maintainer-clean-am
.PHONY: mostlyclean-noinstPROGRAMS distclean-noinstPROGRAMS \
clean-noinstPROGRAMS maintainer-clean-noinstPROGRAMS \
mostlyclean-compile distclean-compile clean-compile \
maintainer-clean-compile tags mostlyclean-tags distclean-tags \
clean-tags maintainer-clean-tags distdir info-am info dvi-am dvi check \
check-am installcheck-am installcheck install-exec-am install-exec \
install-data-am install-data install-am install uninstall-am uninstall \
all-redirect all-am all installdirs mostlyclean-generic \
distclean-generic clean-generic maintainer-clean-generic clean \
mostlyclean distclean maintainer-clean
test: test-init test-eof test-weof test-time regress
verify: test
@./test.sh
bench test-init test-eof test-weof test-time regress: ../libevent.a
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:
--- NEW FILE: bench.c ---
/*
* Copyright 2003 Niels Provos <provos at citi.umich.edu>
* 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 <davidel at xmailserver.org>
*
* Added chain event propagation to improve the sensitivity of
* the measure respect to the event loop efficency.
*
*
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <sys/socket.h>
#include <sys/signal.h>
#include <sys/resource.h>
#include <fcntl.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <event.h>
static int count, writes, fired;
static int *pipes;
static int num_pipes, num_active, num_writes;
static struct event *events;
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++;
}
}
struct timeval *
run_once(void)
{
int *cp, i, space;
static struct timeval ts, te;
for (cp = pipes, i = 0; i < num_pipes; i++, cp += 2) {
event_del(&events[i]);
event_set(&events[i], cp[0], EV_READ | EV_PERSIST, read_cb, (void *) i);
event_add(&events[i], NULL);
}
event_loop(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 {
event_loop(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);
return (&te);
}
int
main (int argc, char **argv)
{
struct rlimit rl;
int i, c;
struct timeval *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);
}
events = calloc(num_pipes, sizeof(struct event));
pipes = calloc(num_pipes * 2, sizeof(int));
if (events == NULL || pipes == NULL) {
perror("malloc");
exit(1);
}
event_init();
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();
if (tv == NULL)
exit(1);
fprintf(stdout, "%ld\n",
tv->tv_sec * 1000000L + tv->tv_usec);
}
exit(0);
}
--- NEW FILE: regress.c ---
/*
* Copyright (c) 2003, 2004 Niels Provos <provos at citi.umich.edu>
* 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.
* 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.
*/
#ifdef WIN32
#include <winsock2.h>
#include <windows.h>
#endif
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <sys/types.h>
#include <sys/stat.h>
#ifdef HAVE_SYS_TIME_H
#include <sys/time.h>
#endif
#ifndef WIN32
#include <sys/socket.h>
#include <sys/signal.h>
#include <unistd.h>
#endif
#include <fcntl.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <err.h>
#include <event.h>
static int pair[2];
static int test_ok;
static int called;
static char wbuf[4096];
static char rbuf[4096];
static int woff;
static int roff;
static int usepersist;
static struct timeval tset;
static struct timeval tcalled;
static struct event_base *event_base;
#define TEST1 "this is a test"
#define SECONDS 1
void
simple_read_cb(int fd, short event, void *arg)
{
char buf[256];
int len;
len = read(fd, buf, sizeof(buf));
if (len) {
if (!called) {
if (event_add(arg, NULL) == -1)
exit(1);
}
} else if (called == 1)
test_ok = 1;
called++;
}
void
simple_write_cb(int fd, short event, void *arg)
{
int len;
len = write(fd, TEST1, strlen(TEST1) + 1);
if (len == -1)
test_ok = 0;
else
test_ok = 1;
}
void
multiple_write_cb(int fd, short event, void *arg)
{
struct event *ev = arg;
int len;
len = 128;
if (woff + len >= sizeof(wbuf))
len = sizeof(wbuf) - woff;
len = write(fd, wbuf + woff, len);
if (len == -1) {
fprintf(stderr, "%s: write\n", __func__);
if (usepersist)
event_del(ev);
return;
}
woff += len;
if (woff >= sizeof(wbuf)) {
shutdown(fd, SHUT_WR);
if (usepersist)
event_del(ev);
return;
}
if (!usepersist) {
if (event_add(ev, NULL) == -1)
exit(1);
}
}
void
multiple_read_cb(int fd, short event, void *arg)
{
struct event *ev = arg;
int len;
len = read(fd, rbuf + roff, sizeof(rbuf) - roff);
if (len == -1)
fprintf(stderr, "%s: read\n", __func__);
if (len <= 0) {
if (usepersist)
event_del(ev);
return;
}
roff += len;
if (!usepersist) {
if (event_add(ev, NULL) == -1)
exit(1);
}
}
void
timeout_cb(int fd, short event, void *arg)
{
struct timeval tv;
int diff;
gettimeofday(&tcalled, NULL);
if (timercmp(&tcalled, &tset, >))
timersub(&tcalled, &tset, &tv);
else
timersub(&tset, &tcalled, &tv);
diff = tv.tv_sec*1000 + tv.tv_usec/1000 - SECONDS * 1000;
if (diff < 0)
diff = -diff;
if (diff < 100)
test_ok = 1;
}
void
signal_cb(int fd, short event, void *arg)
{
struct event *ev = arg;
signal_del(ev);
test_ok = 1;
}
struct both {
struct event ev;
int nread;
};
void
combined_read_cb(int fd, short event, void *arg)
{
struct both *both = arg;
char buf[128];
int len;
len = read(fd, buf, sizeof(buf));
if (len == -1)
fprintf(stderr, "%s: read\n", __func__);
if (len <= 0)
return;
both->nread += len;
if (event_add(&both->ev, NULL) == -1)
exit(1);
}
void
combined_write_cb(int fd, short event, void *arg)
{
struct both *both = arg;
char buf[128];
int len;
len = sizeof(buf);
if (len > both->nread)
len = both->nread;
len = write(fd, buf, len);
if (len == -1)
fprintf(stderr, "%s: write\n", __func__);
if (len <= 0) {
shutdown(fd, SHUT_WR);
return;
}
both->nread -= len;
if (event_add(&both->ev, NULL) == -1)
exit(1);
}
/* Test infrastructure */
int
setup_test(char *name)
{
fprintf(stdout, "%s", name);
if (socketpair(AF_UNIX, SOCK_STREAM, 0, pair) == -1) {
fprintf(stderr, "%s: socketpair\n", __func__);
exit(1);
}
#ifdef HAVE_FCNTL
if (fcntl(pair[0], F_SETFL, O_NONBLOCK) == -1)
warn("fcntl(O_NONBLOCK)");
if (fcntl(pair[1], F_SETFL, O_NONBLOCK) == -1)
warn("fcntl(O_NONBLOCK)");
#endif
test_ok = 0;
called = 0;
return (0);
}
int
cleanup_test(void)
{
#ifndef WIN32
close(pair[0]);
close(pair[1]);
#else
CloseHandle((HANDLE)pair[0]);
CloseHandle((HANDLE)pair[1]);
#endif
if (test_ok)
fprintf(stdout, "OK\n");
else {
fprintf(stdout, "FAILED\n");
exit(1);
}
return (0);
}
void
test1(void)
{
struct event ev;
/* Very simple read test */
setup_test("Simple read: ");
write(pair[0], TEST1, strlen(TEST1)+1);
shutdown(pair[0], SHUT_WR);
event_set(&ev, pair[1], EV_READ, simple_read_cb, &ev);
if (event_add(&ev, NULL) == -1)
exit(1);
event_dispatch();
cleanup_test();
}
void
test2(void)
{
struct event ev;
/* Very simple write test */
setup_test("Simple write: ");
event_set(&ev, pair[0], EV_WRITE, simple_write_cb, &ev);
if (event_add(&ev, NULL) == -1)
exit(1);
event_dispatch();
cleanup_test();
}
void
test3(void)
{
struct event ev, ev2;
int i;
/* Multiple read and write test */
setup_test("Multiple read/write: ");
memset(rbuf, 0, sizeof(rbuf));
for (i = 0; i < sizeof(wbuf); i++)
wbuf[i] = i;
roff = woff = 0;
usepersist = 0;
event_set(&ev, pair[0], EV_WRITE, multiple_write_cb, &ev);
if (event_add(&ev, NULL) == -1)
exit(1);
event_set(&ev2, pair[1], EV_READ, multiple_read_cb, &ev2);
if (event_add(&ev2, NULL) == -1)
exit(1);
event_dispatch();
if (roff == woff)
test_ok = memcmp(rbuf, wbuf, sizeof(wbuf)) == 0;
cleanup_test();
}
void
test4(void)
{
struct event ev, ev2;
int i;
/* Multiple read and write test with persist */
setup_test("Persist read/write: ");
memset(rbuf, 0, sizeof(rbuf));
for (i = 0; i < sizeof(wbuf); i++)
wbuf[i] = i;
roff = woff = 0;
usepersist = 1;
event_set(&ev, pair[0], EV_WRITE|EV_PERSIST, multiple_write_cb, &ev);
if (event_add(&ev, NULL) == -1)
exit(1);
event_set(&ev2, pair[1], EV_READ|EV_PERSIST, multiple_read_cb, &ev2);
if (event_add(&ev2, NULL) == -1)
exit(1);
event_dispatch();
if (roff == woff)
test_ok = memcmp(rbuf, wbuf, sizeof(wbuf)) == 0;
cleanup_test();
}
void
test5(void)
{
struct both r1, r2, w1, w2;
setup_test("Combined read/write: ");
memset(&r1, 0, sizeof(r1));
memset(&r2, 0, sizeof(r2));
memset(&w1, 0, sizeof(w1));
memset(&w2, 0, sizeof(w2));
w1.nread = 4096;
w2.nread = 8192;
event_set(&r1.ev, pair[0], EV_READ, combined_read_cb, &r1);
event_set(&w1.ev, pair[0], EV_WRITE, combined_write_cb, &w1);
event_set(&r2.ev, pair[1], EV_READ, combined_read_cb, &r2);
event_set(&w2.ev, pair[1], EV_WRITE, combined_write_cb, &w2);
if (event_add(&r1.ev, NULL) == -1)
exit(1);
if (event_add(&w1.ev, NULL))
exit(1);
if (event_add(&r2.ev, NULL))
exit(1);
if (event_add(&w2.ev, NULL))
exit(1);
event_dispatch();
if (r1.nread == 8192 && r2.nread == 4096)
test_ok = 1;
cleanup_test();
}
void
test6(void)
{
struct timeval tv;
struct event ev;
setup_test("Simple timeout: ");
tv.tv_usec = 0;
tv.tv_sec = SECONDS;
evtimer_set(&ev, timeout_cb, NULL);
evtimer_add(&ev, &tv);
gettimeofday(&tset, NULL);
event_dispatch();
cleanup_test();
}
#ifndef WIN32
void
test7(void)
{
struct event ev;
struct itimerval itv;
setup_test("Simple signal: ");
signal_set(&ev, SIGALRM, signal_cb, &ev);
signal_add(&ev, NULL);
memset(&itv, 0, sizeof(itv));
itv.it_value.tv_sec = 1;
if (setitimer(ITIMER_REAL, &itv, NULL) == -1)
goto skip_simplesignal;
event_dispatch();
skip_simplesignal:
signal_del(&ev);
cleanup_test();
}
#endif
void
test8(void)
{
struct timeval tv, tv_start, tv_end;
struct event ev;
setup_test("Loop exit: ");
tv.tv_usec = 0;
tv.tv_sec = 60*60*24;
evtimer_set(&ev, timeout_cb, NULL);
evtimer_add(&ev, &tv);
tv.tv_usec = 0;
tv.tv_sec = 1;
event_loopexit(&tv);
gettimeofday(&tv_start, NULL);
event_dispatch();
gettimeofday(&tv_end, NULL);
timersub(&tv_end, &tv_start, &tv_end);
evtimer_del(&ev);
if (tv.tv_sec < 2)
test_ok = 1;
cleanup_test();
}
void
readcb(struct bufferevent *bev, void *arg)
{
if (EVBUFFER_LENGTH(bev->input) == 8333) {
bufferevent_disable(bev, EV_READ);
test_ok++;
}
}
void
writecb(struct bufferevent *bev, void *arg)
{
if (EVBUFFER_LENGTH(bev->output) == 0)
test_ok++;
}
void
errorcb(struct bufferevent *bev, short what, void *arg)
{
test_ok = -2;
}
void
test9(void)
{
struct bufferevent *bev1, *bev2;
char buffer[8333];
int i;
setup_test("Bufferevent: ");
bev1 = bufferevent_new(pair[0], readcb, writecb, errorcb, NULL);
bev2 = bufferevent_new(pair[1], readcb, writecb, errorcb, NULL);
bufferevent_disable(bev1, EV_READ);
bufferevent_enable(bev2, EV_READ);
for (i = 0; i < sizeof(buffer); i++)
buffer[0] = i;
bufferevent_write(bev1, buffer, sizeof(buffer));
event_dispatch();
bufferevent_free(bev1);
bufferevent_free(bev2);
if (test_ok != 2)
test_ok = 0;
cleanup_test();
}
struct test_pri_event {
struct event ev;
int count;
};
void
test_priorities_cb(int fd, short what, void *arg)
{
struct test_pri_event *pri = arg;
struct timeval tv;
if (pri->count == 3) {
event_loopexit(NULL);
return;
}
pri->count++;
timerclear(&tv);
event_add(&pri->ev, &tv);
}
void
test_priorities(int npriorities)
{
char buf[32];
struct test_pri_event one, two;
struct timeval tv;
snprintf(buf, sizeof(buf), "Priorities %d: ", npriorities);
setup_test(buf);
event_base_priority_init(event_base, npriorities);
memset(&one, 0, sizeof(one));
memset(&two, 0, sizeof(two));
timeout_set(&one.ev, test_priorities_cb, &one);
if (event_priority_set(&one.ev, 0) == -1) {
fprintf(stderr, "%s: failed to set priority", __func__);
exit(1);
}
timeout_set(&two.ev, test_priorities_cb, &two);
if (event_priority_set(&two.ev, npriorities - 1) == -1) {
fprintf(stderr, "%s: failed to set priority", __func__);
exit(1);
}
timerclear(&tv);
if (event_add(&one.ev, &tv) == -1)
exit(1);
if (event_add(&two.ev, &tv) == -1)
exit(1);
event_dispatch();
event_del(&one.ev);
event_del(&two.ev);
if (npriorities == 1) {
if (one.count == 3 && two.count == 3)
test_ok = 1;
} else if (npriorities == 2) {
/* Two is called once because event_loopexit is priority 1 */
if (one.count == 3 && two.count == 1)
test_ok = 1;
} else {
if (one.count == 3 && two.count == 0)
test_ok = 1;
}
cleanup_test();
}
int
main (int argc, char **argv)
{
#ifdef WIN32
WORD wVersionRequested;
WSADATA wsaData;
int err;
wVersionRequested = MAKEWORD( 2, 2 );
err = WSAStartup( wVersionRequested, &wsaData );
#endif
setvbuf(stdout, NULL, _IONBF, 0);
/* Initalize the event library */
event_base = event_init();
test1();
test2();
test3();
test4();
test5();
test6();
#ifndef WIN32
test7();
#endif
test8();
test9();
test_priorities(1);
test_priorities(2);
test_priorities(3);
return (0);
}
--- NEW FILE: test-eof.c ---
/*
* Compile with:
* cc -I/usr/local/include -o time-test time-test.c -L/usr/local/lib -levent
*/
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <sys/socket.h>
#include <fcntl.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <event.h>
int test_okay = 1;
int called = 0;
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)
event_add(arg, NULL);
} else if (called == 1)
test_okay = 0;
called++;
}
int
main (int argc, char **argv)
{
struct event ev;
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 the event library */
event_init();
/* Initalize one event */
event_set(&ev, pair[1], EV_READ, read_cb, &ev);
event_add(&ev, NULL);
event_dispatch();
return (test_okay);
}
--- NEW FILE: test-init.c ---
/*
* Compile with:
* cc -I/usr/local/include -o time-test time-test.c -L/usr/local/lib -levent
*/
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <sys/socket.h>
#include <fcntl.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <event.h>
int
main(int argc, char **argv)
{
/* Initalize the event library */
event_init();
return (0);
}
--- NEW FILE: test-time.c ---
/*
* Compile with:
* cc -I/usr/local/include -o time-test time-test.c -L/usr/local/lib -levent
*/
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <fcntl.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <event.h>
int called = 0;
#define NEVENT 20000
struct event *ev[NEVENT];
void
time_cb(int fd, short event, void *arg)
{
struct timeval tv;
int i, j;
called++;
if (called < 10*NEVENT) {
for (i = 0; i < 10; i++) {
j = random() % NEVENT;
tv.tv_sec = 0;
tv.tv_usec = random() % 50000L;
if (tv.tv_usec % 2)
evtimer_add(ev[j], &tv);
else
evtimer_del(ev[j]);
}
}
}
int
main (int argc, char **argv)
{
struct timeval tv;
int i;
/* Initalize the event library */
event_init();
for (i = 0; i < NEVENT; i++) {
ev[i] = malloc(sizeof(struct event));
/* Initalize one event */
evtimer_set(ev[i], time_cb, ev[i]);
tv.tv_sec = 0;
tv.tv_usec = random() % 50000L;
evtimer_add(ev[i], &tv);
}
event_dispatch();
return (called < NEVENT);
}
--- NEW FILE: test-weof.c ---
/*
* Compile with:
* cc -I/usr/local/include -o time-test time-test.c -L/usr/local/lib -levent
*/
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <sys/socket.h>
#include <fcntl.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <signal.h>
#include <unistd.h>
#include <errno.h>
#include <event.h>
int pair[2];
int test_okay = 1;
int called = 0;
void
write_cb(int fd, short event, void *arg)
{
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)
event_add(arg, NULL);
close(pair[0]);
} else if (called == 1)
test_okay = 0;
called++;
}
int
main (int argc, char **argv)
{
struct event ev;
if (signal(SIGPIPE, SIG_IGN) == SIG_IGN)
return (1);
if (socketpair(AF_UNIX, SOCK_STREAM, 0, pair) == -1)
return (1);
/* Initalize the event library */
event_init();
/* Initalize one event */
event_set(&ev, pair[1], EV_WRITE, write_cb, &ev);
event_add(&ev, NULL);
event_dispatch();
return (test_okay);
}
--- NEW FILE: test.sh ---
(This appears to be a binary file; contents omitted.)
More information about the tor-commits
mailing list