Commit 986d2e3d authored by David S. Miller's avatar David S. Miller

Merge branch 'mptcp-selftests'

Mat Martineau says:

====================
mptcp: Some selftest improvements

Here are a couple of selftest changes for MPTCP.

Patch 1 fixes a mistake where the wrong protocol (TCP vs MPTCP) could be
requested on the listening socket in some link failure tests.

Patch 2 refactors the simulataneous flow tests to improve timing
accuracy and give more consistent results.
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents f7536ffb b6ab64b0
......@@ -14,6 +14,7 @@
#include <strings.h>
#include <signal.h>
#include <unistd.h>
#include <time.h>
#include <sys/poll.h>
#include <sys/sendfile.h>
......@@ -64,6 +65,7 @@ static int cfg_sndbuf;
static int cfg_rcvbuf;
static bool cfg_join;
static bool cfg_remove;
static unsigned int cfg_time;
static unsigned int cfg_do_w;
static int cfg_wait;
static uint32_t cfg_mark;
......@@ -78,9 +80,10 @@ static struct cfg_cmsg_types cfg_cmsg_types;
static void die_usage(void)
{
fprintf(stderr, "Usage: mptcp_connect [-6] [-u] [-s MPTCP|TCP] [-p port] [-m mode]"
"[-l] [-w sec] connect_address\n");
"[-l] [-w sec] [-t num] [-T num] connect_address\n");
fprintf(stderr, "\t-6 use ipv6\n");
fprintf(stderr, "\t-t num -- set poll timeout to num\n");
fprintf(stderr, "\t-T num -- set expected runtime to num ms\n");
fprintf(stderr, "\t-S num -- set SO_SNDBUF to num\n");
fprintf(stderr, "\t-R num -- set SO_RCVBUF to num\n");
fprintf(stderr, "\t-p num -- use port num\n");
......@@ -448,7 +451,7 @@ static void set_nonblock(int fd)
fcntl(fd, F_SETFL, flags | O_NONBLOCK);
}
static int copyfd_io_poll(int infd, int peerfd, int outfd)
static int copyfd_io_poll(int infd, int peerfd, int outfd, bool *in_closed_after_out)
{
struct pollfd fds = {
.fd = peerfd,
......@@ -487,9 +490,11 @@ static int copyfd_io_poll(int infd, int peerfd, int outfd)
*/
fds.events &= ~POLLIN;
if ((fds.events & POLLOUT) == 0)
if ((fds.events & POLLOUT) == 0) {
*in_closed_after_out = true;
/* and nothing more to send */
break;
}
/* Else, still have data to transmit */
} else if (len < 0) {
......@@ -547,7 +552,7 @@ static int copyfd_io_poll(int infd, int peerfd, int outfd)
}
/* leave some time for late join/announce */
if (cfg_join || cfg_remove)
if (cfg_remove)
usleep(cfg_wait);
close(peerfd);
......@@ -646,7 +651,7 @@ static int do_sendfile(int infd, int outfd, unsigned int count)
}
static int copyfd_io_mmap(int infd, int peerfd, int outfd,
unsigned int size)
unsigned int size, bool *in_closed_after_out)
{
int err;
......@@ -664,13 +669,14 @@ static int copyfd_io_mmap(int infd, int peerfd, int outfd,
shutdown(peerfd, SHUT_WR);
err = do_recvfile(peerfd, outfd);
*in_closed_after_out = true;
}
return err;
}
static int copyfd_io_sendfile(int infd, int peerfd, int outfd,
unsigned int size)
unsigned int size, bool *in_closed_after_out)
{
int err;
......@@ -685,6 +691,7 @@ static int copyfd_io_sendfile(int infd, int peerfd, int outfd,
if (err)
return err;
err = do_recvfile(peerfd, outfd);
*in_closed_after_out = true;
}
return err;
......@@ -692,27 +699,62 @@ static int copyfd_io_sendfile(int infd, int peerfd, int outfd,
static int copyfd_io(int infd, int peerfd, int outfd)
{
bool in_closed_after_out = false;
struct timespec start, end;
int file_size;
int ret;
if (cfg_time && (clock_gettime(CLOCK_MONOTONIC, &start) < 0))
xerror("can not fetch start time %d", errno);
switch (cfg_mode) {
case CFG_MODE_POLL:
return copyfd_io_poll(infd, peerfd, outfd);
ret = copyfd_io_poll(infd, peerfd, outfd, &in_closed_after_out);
break;
case CFG_MODE_MMAP:
file_size = get_infd_size(infd);
if (file_size < 0)
return file_size;
return copyfd_io_mmap(infd, peerfd, outfd, file_size);
ret = copyfd_io_mmap(infd, peerfd, outfd, file_size, &in_closed_after_out);
break;
case CFG_MODE_SENDFILE:
file_size = get_infd_size(infd);
if (file_size < 0)
return file_size;
return copyfd_io_sendfile(infd, peerfd, outfd, file_size);
}
ret = copyfd_io_sendfile(infd, peerfd, outfd, file_size, &in_closed_after_out);
break;
default:
fprintf(stderr, "Invalid mode %d\n", cfg_mode);
die_usage();
return 1;
}
if (ret)
return ret;
if (cfg_time) {
unsigned int delta_ms;
if (clock_gettime(CLOCK_MONOTONIC, &end) < 0)
xerror("can not fetch end time %d", errno);
delta_ms = (end.tv_sec - start.tv_sec) * 1000 + (end.tv_nsec - start.tv_nsec) / 1000000;
if (delta_ms > cfg_time) {
xerror("transfer slower than expected! runtime %d ms, expected %d ms",
delta_ms, cfg_time);
}
/* show the runtime only if this end shutdown(wr) before receiving the EOF,
* (that is, if this end got the longer runtime)
*/
if (in_closed_after_out)
fprintf(stderr, "%d", delta_ms);
}
return 0;
}
static void check_sockaddr(int pf, struct sockaddr_storage *ss,
......@@ -1005,12 +1047,11 @@ static void parse_opts(int argc, char **argv)
{
int c;
while ((c = getopt(argc, argv, "6jr:lp:s:hut:m:S:R:w:M:P:c:")) != -1) {
while ((c = getopt(argc, argv, "6jr:lp:s:hut:T:m:S:R:w:M:P:c:")) != -1) {
switch (c) {
case 'j':
cfg_join = true;
cfg_mode = CFG_MODE_POLL;
cfg_wait = 400000;
break;
case 'r':
cfg_remove = true;
......@@ -1043,6 +1084,9 @@ static void parse_opts(int argc, char **argv)
if (poll_timeout <= 0)
poll_timeout = -1;
break;
case 'T':
cfg_time = atoi(optarg);
break;
case 'm':
cfg_mode = parse_mode(optarg);
break;
......
......@@ -297,7 +297,7 @@ do_transfer()
if [ "$test_link_fail" -eq 2 ];then
timeout ${timeout_test} \
ip netns exec ${listener_ns} \
$mptcp_connect -t ${timeout_poll} -l -p $port -s ${cl_proto} \
$mptcp_connect -t ${timeout_poll} -l -p $port -s ${srv_proto} \
${local_addr} < "$sinfail" > "$sout" &
else
timeout ${timeout_test} \
......
......@@ -51,7 +51,7 @@ setup()
sout=$(mktemp)
cout=$(mktemp)
capout=$(mktemp)
size=$((2048 * 4096))
size=$((2 * 2048 * 4096))
dd if=/dev/zero of=$small bs=4096 count=20 >/dev/null 2>&1
dd if=/dev/zero of=$large bs=4096 count=$((size / 4096)) >/dev/null 2>&1
......@@ -161,17 +161,15 @@ do_transfer()
timeout ${timeout_test} \
ip netns exec ${ns3} \
./mptcp_connect -jt ${timeout_poll} -l -p $port \
./mptcp_connect -jt ${timeout_poll} -l -p $port -T $time \
0.0.0.0 < "$sin" > "$sout" &
local spid=$!
wait_local_port_listen "${ns3}" "${port}"
local start
start=$(date +%s%3N)
timeout ${timeout_test} \
ip netns exec ${ns1} \
./mptcp_connect -jt ${timeout_poll} -p $port \
./mptcp_connect -jt ${timeout_poll} -p $port -T $time \
10.0.3.3 < "$cin" > "$cout" &
local cpid=$!
......@@ -180,27 +178,20 @@ do_transfer()
wait $spid
local rets=$?
local stop
stop=$(date +%s%3N)
if $capture; then
sleep 1
kill ${cappid_listener}
kill ${cappid_connector}
fi
local duration
duration=$((stop-start))
cmp $sin $cout > /dev/null 2>&1
local cmps=$?
cmp $cin $sout > /dev/null 2>&1
local cmpc=$?
printf "%16s" "$duration max $max_time "
printf "%-16s" " max $max_time "
if [ $retc -eq 0 ] && [ $rets -eq 0 ] && \
[ $cmpc -eq 0 ] && [ $cmps -eq 0 ] && \
[ $duration -lt $max_time ]; then
[ $cmpc -eq 0 ] && [ $cmps -eq 0 ]; then
echo "[ OK ]"
cat "$capout"
return 0
......@@ -244,23 +235,24 @@ run_test()
tc -n $ns2 qdisc add dev ns2eth1 root netem rate ${rate1}mbit $delay1
tc -n $ns2 qdisc add dev ns2eth2 root netem rate ${rate2}mbit $delay2
# time is measure in ms
local time=$((size * 8 * 1000 / (( $rate1 + $rate2) * 1024 *1024) ))
# time is measured in ms, account for transfer size, affegated link speed
# and header overhead (10%)
local time=$((size * 8 * 1000 * 10 / (( $rate1 + $rate2) * 1024 *1024 * 9) ))
# mptcp_connect will do some sleeps to allow the mp_join handshake
# completion
time=$((time + 1350))
# completion (see mptcp_connect): 200ms on each side, add some slack
time=$((time + 450))
printf "%-50s" "$msg"
do_transfer $small $large $((time * 11 / 10))
printf "%-60s" "$msg"
do_transfer $small $large $time
lret=$?
if [ $lret -ne 0 ]; then
ret=$lret
[ $bail -eq 0 ] || exit $ret
fi
printf "%-50s" "$msg - reverse direction"
do_transfer $large $small $((time * 11 / 10))
printf "%-60s" "$msg - reverse direction"
do_transfer $large $small $time
lret=$?
if [ $lret -ne 0 ]; then
ret=$lret
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment