summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFrediano Ziglio <fziglio@redhat.com>2016-10-08 22:43:45 +0100
committerFrediano Ziglio <fziglio@redhat.com>2016-10-08 22:56:06 +0100
commite3121f52a7fa6e91061f9553ecc72214d071983a (patch)
tree2130de808abc119c6878966109653910e5b23634
parent3f034f3401d30b40b03a0ac44f923e324847aeba (diff)
Add bandwidth test
Signed-off-by: Frediano Ziglio <fziglio@redhat.com>
-rw-r--r--.gitignore1
-rw-r--r--tests/Makefile.am4
-rw-r--r--tests/bandwidth.c134
3 files changed, 139 insertions, 0 deletions
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 <poll.h>
+#include <pthread.h>
+
+#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;
+}