From 6ce6b5a9430b1b8749d832ecabe840a7b65d74de Mon Sep 17 00:00:00 2001 Message-Id: <6ce6b5a9430b1b8749d832ecabe840a7b65d74de.1714058891.git.mdw@distorted.org.uk> From: Mark Wooding Date: Sun, 2 Dec 2007 17:48:41 +0000 Subject: [PATCH] tests/udplog: new program to log packets sent by speaker during testing. Also means that (on Linux at least) we don't get ECONNREFUSED. Organization: Straylight/Edgeware From: Richard Kettlewell tests/play.py corrected. --- .bzrignore | 1 + tests/Makefile.am | 8 +++ tests/dtest.py | 18 ++++-- tests/play.py | 13 ++-- tests/udplog.c | 150 ++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 179 insertions(+), 11 deletions(-) create mode 100644 tests/udplog.c diff --git a/.bzrignore b/.bzrignore index caa175b..e34c30c 100644 --- a/.bzrignore +++ b/.bzrignore @@ -139,3 +139,4 @@ disobedience/index.html lib/index.html server/index.html .DS_Store +tests/disorder-udplog diff --git a/tests/Makefile.am b/tests/Makefile.am index c865c58..4e9f008 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -18,6 +18,14 @@ # USA # +noinst_PROGRAMS=disorder-udplog + +AM_CPPFLAGS=-I${top_srcdir}/lib -I../lib + +disorder_udplog_SOURCES=udplog.c +disorder_udplog_LDADD=$(LIBOBJS) ../lib/libdisorder.a +disorder_udplog_DEPENDENCIES=../lib/libdisorder.a + check: ${PYTHON} ${srcdir}/alltests diff --git a/tests/dtest.py b/tests/dtest.py index 3f0788f..cd87c50 100644 --- a/tests/dtest.py +++ b/tests/dtest.py @@ -45,6 +45,7 @@ import disorder ospath = os.environ["PATH"].split(os.pathsep) ospath.insert(0, os.path.join(top_builddir, "server")) ospath.insert(0, os.path.join(top_builddir, "clients")) +ospath.insert(0, os.path.join(top_builddir, "tests")) os.environ["PATH"] = os.pathsep.join(ospath) # Parse the makefile in the current directory to identify the source directory @@ -168,11 +169,18 @@ def bindable(p): def common_setup(): remove_dir(testroot) os.mkdir(testroot) + # Choose a port global port port = random.randint(49152, 65535) - while not bindable(port): - print "port %d is not bindable, trying another" % port + while not bindable(port + 1): + print "port %d is not bindable, trying another" % (port + 1) port = random.randint(49152, 65535) + # Log anything sent to that port + packetlog = "%s/packetlog" % testroot + subprocess.Popen(["disorder-udplog", + "--output", packetlog, + "127.0.0.1", "%d" % port]) + # disorder-udplog will quit when its parent process terminates open("%s/config" % testroot, "w").write( """home %s collection fs UTF-8 %s/tracks @@ -212,10 +220,10 @@ def start_daemon(): Start the daemon.""" global daemon, errs, port assert daemon == None, "no daemon running" - if not bindable(port): - print "waiting for speaker socket to become bindable again..." + if not bindable(port + 1): + print "waiting for port %d to become bindable again..." % (port + 1) time.sleep(1) - while not bindable(port): + while not bindable(port + 1): time.sleep(1) print " starting daemon" # remove the socket if it exists diff --git a/tests/play.py b/tests/play.py index cbbb0ec..5c2df1b 100755 --- a/tests/play.py +++ b/tests/play.py @@ -30,7 +30,7 @@ def test(): print "checking track turned up in queue" q = c.queue() ts = filter(lambda t: t['track'] == track and 'submitter' in t, q) - assert len(ts) == 1 + assert len(ts) == 1, "checking track appears exactly once in queue" t = ts[0] assert t['submitter'] == u'fred', "check queue submitter" i = t['id'] @@ -43,13 +43,14 @@ def test(): p = c.playing() r = c.recent() print "checking track turned up in recent list" - q = c.recent() - ts = filter(lambda t: t['track'] == track and 'submitter' in t, q) - assert len(ts) == 1 + while (p is not None and p['id'] == i): + time.sleep(1) + p = c.playing() + r = c.recent() + ts = filter(lambda t: t['track'] == track and 'submitter' in t, r) + assert len(ts) == 1, "check track appears exactly once in recent" t = ts[0] assert t['submitter'] == u'fred', "check recent entry submitter" - - if __name__ == '__main__': dtest.run() diff --git a/tests/udplog.c b/tests/udplog.c new file mode 100644 index 0000000..4d52efc --- /dev/null +++ b/tests/udplog.c @@ -0,0 +1,150 @@ +/* + * This file is part of DisOrder + * Copyright (C) 2007 Richard Kettlewell + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + */ + +#include +#include "types.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "configuration.h" +#include "syscalls.h" +#include "log.h" +#include "addr.h" +#include "defs.h" +#include "mem.h" + +static const struct option options[] = { + { "help", no_argument, 0, 'h' }, + { "version", no_argument, 0, 'V' }, + { "output", required_argument, 0, 'o' }, + { 0, 0, 0, 0 } +}; + +/* display usage message and terminate */ +static void help(void) { + xprintf("Usage:\n" + " disorder-udplog [OPTIONS] ADDRESS PORT\n" + "Options:\n" + " --output, -o PATH Output to PATH (default: stdout)\n" + " --help, -h Display usage message\n" + " --version, -V Display version number\n" + "\n" + "UDP packet receiver.\n"); + xfclose(stdout); + exit(0); +} + +/* display version number and terminate */ +static void version(void) { + xprintf("disorder-udplog version %s\n", disorder_version_string); + xfclose(stdout); + exit(0); +} + +int main(int argc, char **argv) { + int n, fd, err, i, j; + struct addrinfo *ai; + struct stringlist a; + char *name, h[4096], s[4096]; + uint8_t buffer[4096]; + union { + struct sockaddr sa; + struct sockaddr_in sin; + struct sockaddr_in6 sin6; + } sa; + socklen_t len; + static const struct addrinfo pref = { + 0, /* ai_flags */ + AF_UNSPEC, /* ai_family */ + SOCK_DGRAM, /* ai_socktype */ + IPPROTO_UDP, /* ai_protocol */ + 0, + 0, + 0, + 0 + }; + + set_progname(argv); + mem_init(); + if(!setlocale(LC_CTYPE, "")) fatal(errno, "error calling setlocale"); + while((n = getopt_long(argc, argv, "hVo:", options, 0)) >= 0) { + switch(n) { + case 'h': help(); + case 'V': version(); + case 'o': + if(!freopen(optarg, "w", stdout)) + fatal(errno, "%s", optarg); + break; + default: fatal(0, "invalid option"); + } + } + if(optind + 2 != argc) + fatal(0, "missing arguments"); + a.n = 2; + a.s = &argv[optind]; + if(!(ai = get_address(&a, &pref, &name))) + exit(1); + fd = xsocket(ai->ai_family, ai->ai_socktype, ai->ai_protocol); + if(bind(fd, ai->ai_addr, ai->ai_addrlen) < 0) + fatal(errno, "error binding to %s", name); + while(getppid() != 1) { + len = sizeof sa; + n = recvfrom(fd, buffer, sizeof buffer, 0, &sa.sa, &len); + if(n < 0) { + if(errno == EINTR || errno == EAGAIN) + continue; + fatal(errno, "%s: recvfrom", name); + } + if((err = getnameinfo(&sa.sa, len, h, sizeof h, s, sizeof s, + NI_NUMERICHOST|NI_NUMERICSERV|NI_DGRAM))) + fatal(0, "getnameinfo: %s", gai_strerror(err)); + xprintf("from host %s service %s: %d bytes\n", h, s, n); + for(i = 0; i < n; i += 16) { + for(j = i; j < n && j < i + 16; ++j) + xprintf(" %02x", buffer[j]); + for(; j < i + 16; ++j) + xprintf(" "); + xprintf(" "); + for(j = i; j < n && j < i + 16; ++j) + xprintf("%c", buffer[j] < 128 && isprint(buffer[j]) ? buffer[j] : '.'); + xprintf("\n"); + if(fflush(stdout) < 0) + fatal(errno, "stdout"); + } + } + return 0; +} + +/* +Local Variables: +c-basic-offset:2 +comment-column:40 +fill-column:79 +indent-tabs-mode:nil +End: +*/ -- [mdw]