From e3121f52a7fa6e91061f9553ecc72214d071983a Mon Sep 17 00:00:00 2001 From: Frediano Ziglio Date: Sat, 8 Oct 2016 22:43:45 +0100 Subject: Add bandwidth test Signed-off-by: Frediano Ziglio --- .gitignore | 1 + tests/Makefile.am | 4 ++ tests/bandwidth.c | 134 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 139 insertions(+) create mode 100644 tests/bandwidth.c diff --git a/.gitignore b/.gitignore index d453e3b..f781164 100644 --- a/.gitignore +++ b/.gitignore @@ -21,4 +21,5 @@ latency.spec ar-lib tests/libtest.a tests/delay +tests/bandwidth .*.swp diff --git a/tests/Makefile.am b/tests/Makefile.am index b3c9f45..9a98d58 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -15,3 +15,7 @@ LDADD = \ TESTS += delay delay_SOURCES = delay.c + +TESTS += bandwidth +bandwidth_SOURCES = bandwidth.c +bandwidth_LDFLAGS = -pthread diff --git a/tests/bandwidth.c b/tests/bandwidth.c new file mode 100644 index 0000000..3e2fe59 --- /dev/null +++ b/tests/bandwidth.c @@ -0,0 +1,134 @@ +/* check that the delay we setup is respected */ +#include "common.h" +#include "../utils.h" +#include +#include + +#define MIN_IP_UDP_HEADER 28 + +static int udp_socks[2] = { -1, -1 }; + +typedef struct { + uint8_t data[1024]; +} test_payload; + +#define SOCK2PTR(s) ((void *)(uintptr_t)(s)) +#define PTR2SOCK(p) ((int)(uintptr_t)(p)) + +static void * +send_proc(void *arg) +{ + int sock = PTR2SOCK(arg); + test_payload payload; + + int n; + for (n = 0; n < sizeof(payload.data); ++n) + payload.data[n] = n * 123 + 456; + + uint64_t start_time = get_time_us(); + while (get_time_us() - start_time < 130 * 1000) { + send(sock, &payload, sizeof(payload), MSG_NOSIGNAL); + send(sock, &payload, sizeof(payload), MSG_NOSIGNAL); + send(sock, &payload, sizeof(payload), MSG_NOSIGNAL); + send(sock, &payload, sizeof(payload), MSG_NOSIGNAL); + send(sock, &payload, sizeof(payload), MSG_NOSIGNAL); + usleep(1000); + } + return NULL; +} + +static void * +recv_proc(void *arg) +{ + int sock = PTR2SOCK(arg); + test_payload payload; + + uint64_t bytes_received = 0; + uint64_t start_time = 0; + for (;;) { + ssize_t len = recv(sock, &payload, sizeof(payload), MSG_TRUNC); + assert(len > 0); + + uint64_t curr_time = get_time_us(); + assert(bytes_received <= 0xffffffffu - len - MIN_IP_UDP_HEADER); + if (start_time == 0) + start_time = curr_time; + else + bytes_received += len + MIN_IP_UDP_HEADER; + if (curr_time - start_time >= 100 * 1000) + break; + } + return (void *) (uintptr_t) bytes_received; +} + +static void +flush_socks(void) +{ + struct pollfd fds[2]; + int i; + + fds[0].fd = udp_socks[0]; + fds[0].events = POLLIN; + fds[1].fd = udp_socks[1]; + fds[1].events = POLLIN; + for (;;) { + // wait any packet for 30 ms + fds[0].revents = 0; + fds[1].revents = 0; + int res = poll(fds, 2, 30); + if (res == 0) + break; + + for (i = 0; i < 2; ++i) { + char buf[1024]; + if (fds[i].revents) + recv(fds[i].fd, buf, sizeof(buf), MSG_TRUNC); + } + } +} + +static void +test_bandwidth(unsigned bw) +{ + pthread_t th[3]; + void *thread_res; + unsigned bytes_received; + unsigned expected = 1024 * 1024 * bw / 8 / 10 + 1 * (1024 + MIN_IP_UDP_HEADER); + + // launch program with given latency + launch_latency("10 %uMbit", bw); + create_udp_pair(udp_socks); + + // one direction + assert(pthread_create(th, NULL, recv_proc, SOCK2PTR(udp_socks[1])) == 0); + send_proc(SOCK2PTR(udp_socks[0])); + assert(pthread_join(th[0], &thread_res) == 0); + bytes_received = (uintptr_t) thread_res; + printf("received %u/%u\n", bytes_received, expected); + // check into -5% to +5% + assert(bytes_received >= expected * 0.96 && bytes_received <= expected * 1.04); + + // other direction + flush_socks(); + assert(pthread_create(th, NULL, recv_proc, SOCK2PTR(udp_socks[0])) == 0); + send_proc(SOCK2PTR(udp_socks[1])); + assert(pthread_join(th[0], &thread_res) == 0); + bytes_received = (uintptr_t) thread_res; + printf("received %u/%u\n", bytes_received, expected); + // check into -5% to +5% + assert(bytes_received >= expected * 0.96 && bytes_received <= expected * 1.04); + + close_udp_pair(udp_socks); + kill_latency(); +} + +int main(void) +{ + printf("Testing bandwidth limitation\n"); + + test_bandwidth(2); + test_bandwidth(4); + test_bandwidth(8); + test_bandwidth(16); + return 0; +} -- cgit v1.2.3