From 37b694e7a76ca6abc62c78eceae26f655cf6bccf Mon Sep 17 00:00:00 2001 From: Ben Pfaff Date: Thu, 2 Feb 2012 16:37:31 -0800 Subject: [PATCH] tests: Reduce risk of port collision and remove bash dependency. A few tests need a random TCP port on which to listen for connections. Until now, the tests have used the $RANDOM bash extension to do this, but this runs the risk of occasionally colliding with an in-use port. This commit removes the bash dependency by switching to using a small Perl program to pick random ports and reduces the risk of collision by attempting to bind the port that it chooses. Reported-by: Timothy Chen Signed-off-by: Ben Pfaff --- AUTHORS | 1 + tests/automake.mk | 2 ++ tests/choose-port.pl | 26 ++++++++++++++++++++++++++ tests/ofproto-dpif.at | 8 ++++---- tests/ovsdb-server.at | 8 ++++---- 5 files changed, 37 insertions(+), 8 deletions(-) create mode 100644 tests/choose-port.pl diff --git a/AUTHORS b/AUTHORS index 87bb7212..c19bbde5 100644 --- a/AUTHORS +++ b/AUTHORS @@ -127,6 +127,7 @@ Srini Seetharaman seethara@stanford.edu Stephen Hemminger shemminger@vyatta.com Takayuki HAMA t-hama@cb.jp.nec.com Teemu Koponen koponen@nicira.com +Timothy Chen tchen@nicira.com Vishal Swarankar vishal.swarnkar@gmail.com Voravit T. voravit@kth.se YAMAMOTO Takashi yamamoto@valinux.co.jp diff --git a/tests/automake.mk b/tests/automake.mk index 37925823..28b2749a 100644 --- a/tests/automake.mk +++ b/tests/automake.mk @@ -334,6 +334,8 @@ noinst_PROGRAMS += tests/test-byte-order tests_test_byte_order_SOURCES = tests/test-byte-order.c tests_test_byte_order_LDADD = lib/libopenvswitch.a +EXTRA_DIST += tests/choose-port.pl + # Python tests. EXTRA_DIST += \ tests/test-daemon.py \ diff --git a/tests/choose-port.pl b/tests/choose-port.pl new file mode 100644 index 00000000..46c8db5e --- /dev/null +++ b/tests/choose-port.pl @@ -0,0 +1,26 @@ +# -*- perl -*- + +# Picks a random TCP port and attempts to bind it, retrying a few +# times if the chosen port is in use. This is better than just +# picking a random number without checking whether it is in use (but +# of course a race window still exists). +# +# On success, prints a port number on stdout and exits with status 0. +# On failure, prints an error on stderr and exits with a nonzero status. + +use warnings; +use strict; +use Socket; + +socket(SOCK, PF_INET, SOCK_STREAM, 0) || die "socket: $!\n"; +for (my ($i) = 0; ; $i++) { + my ($port) = int(rand(16383)) + 49152; + if (bind(SOCK, sockaddr_in($port, INADDR_ANY))) { + print "$port\n"; + exit 0; + } elsif ($i < 10 && $!{EADDRINUSE}) { + # Address already in use. Try again. + } else { + die "bind: $!\n"; + } +} diff --git a/tests/ofproto-dpif.at b/tests/ofproto-dpif.at index bb00714e..3860b01d 100644 --- a/tests/ofproto-dpif.at +++ b/tests/ofproto-dpif.at @@ -915,8 +915,8 @@ dnl - Flow actions changing (in this case, due to MAC learning) dnl cause a record to be sent. AT_SETUP([ofproto-dpif - NetFlow flow expiration]) -AT_SKIP_IF([test "x$RANDOM" = x]) -NETFLOW_PORT=`expr 32767 + \( $RANDOM % 32767 \)` +AT_CHECK([perl $srcdir/choose-port.pl], [0], [stdout]) +NETFLOW_PORT=`cat stdout` OVS_VSWITCHD_START( [set Bridge br0 fail-mode=standalone -- \ @@ -957,8 +957,8 @@ AT_CLEANUP dnl Test that basic NetFlow reports active expirations correctly. AT_SETUP([ofproto-dpif - NetFlow active expiration]) -AT_SKIP_IF([test "x$RANDOM" = x]) -NETFLOW_PORT=`expr 32767 + \( $RANDOM % 32767 \)` +AT_CHECK([perl $srcdir/choose-port.pl], [0], [stdout]) +NETFLOW_PORT=`cat stdout` OVS_VSWITCHD_START( [set Bridge br0 fail-mode=standalone -- \ diff --git a/tests/ovsdb-server.at b/tests/ovsdb-server.at index 7d79d220..ce558866 100644 --- a/tests/ovsdb-server.at +++ b/tests/ovsdb-server.at @@ -199,8 +199,6 @@ AT_CLEANUP AT_SETUP([SSL db: implementation]) AT_KEYWORDS([ovsdb server positive ssl $5]) AT_SKIP_IF([test "$HAVE_OPENSSL" = no]) -AT_SKIP_IF([test "x$RANDOM" = x]) -SSL_PORT=`expr 32767 + \( $RANDOM % 32767 \)` PKIDIR=$abs_top_builddir/tests AT_SKIP_IF([expr "$PKIDIR" : ".*[ '\" \\]"]) @@ -223,6 +221,8 @@ AT_CHECK( "certificate": "'"$PKIDIR/testpki-cert2.pem"'", "ca_cert": "'"$PKIDIR/testpki-cacert.pem"'"}}]']], [0], [ignore], [ignore]) +AT_CHECK([perl $srcdir/choose-port.pl], [0], [stdout]) +SSL_PORT=`cat stdout` AT_CHECK( [ovsdb-server --detach --pidfile=$PWD/pid \ --private-key=db:SSL,private_key \ @@ -390,10 +390,10 @@ m4_define([OVSDB_CHECK_EXECUTION], [AT_SETUP([$1]) AT_KEYWORDS([ovsdb server positive ssl $5]) AT_SKIP_IF([test "$HAVE_OPENSSL" = no]) - AT_SKIP_IF([test "x$RANDOM" = x]) AT_DATA([schema], [$2 ]) - SSL_PORT=`expr 32767 + \( $RANDOM % 32767 \)` + AT_CHECK([perl $srcdir/choose-port.pl], [0], [stdout]) + SSL_PORT=`cat stdout` PKIDIR=$abs_top_builddir/tests AT_CHECK([ovsdb-tool create db schema], [0], [stdout], [ignore]) AT_CHECK([ovsdb-server --detach --pidfile=$PWD/pid --private-key=$PKIDIR/testpki-privkey2.pem --certificate=$PKIDIR/testpki-cert2.pem --ca-cert=$PKIDIR/testpki-cacert.pem --remote=pssl:$SSL_PORT:127.0.0.1 --unixctl=$PWD/unixctl db], [0], [ignore], [ignore]) -- 2.30.2