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 <tchen@nicira.com>
Signed-off-by: Ben Pfaff <blp@nicira.com>
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
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 \
--- /dev/null
+# -*- 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";
+ }
+}
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 -- \
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 -- \
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" : ".*[ '\"
\r\\]"])
"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 \
[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])