mirror of
https://github.com/genodelabs/genode.git
synced 2025-01-18 18:56:29 +00:00
Simple bulk TCP test
Send 8 MiB from one socket to another, anticipating short writes and short reads from sockets. Fix #2989
This commit is contained in:
parent
f65a7650c5
commit
c697fb6345
112
repos/libports/run/tcp_bulk.inc
Normal file
112
repos/libports/run/tcp_bulk.inc
Normal file
@ -0,0 +1,112 @@
|
||||
create_boot_directory
|
||||
|
||||
append build_components {
|
||||
core init
|
||||
drivers/timer
|
||||
server/nic_bridge
|
||||
server/nic_loopback
|
||||
test/tcp
|
||||
}
|
||||
|
||||
append_socket_fs_build_components
|
||||
|
||||
build $build_components
|
||||
|
||||
append config {
|
||||
<config verbose="yes">
|
||||
<parent-provides>
|
||||
<service name="ROM"/>
|
||||
<service name="IRQ"/>
|
||||
<service name="IO_MEM"/>
|
||||
<service name="IO_PORT"/>
|
||||
<service name="PD"/>
|
||||
<service name="RM"/>
|
||||
<service name="CPU"/>
|
||||
<service name="LOG"/>
|
||||
</parent-provides>
|
||||
<default-route>
|
||||
<any-service> <parent/> <any-child/> </any-service>
|
||||
</default-route>
|
||||
<default caps="256"/>
|
||||
<start name="timer">
|
||||
<resource name="RAM" quantum="1M"/>
|
||||
<provides> <service name="Timer"/> </provides>
|
||||
</start>
|
||||
<start name="nic_loopback">
|
||||
<resource name="RAM" quantum="1M"/>
|
||||
<provides> <service name="Nic"/> </provides>
|
||||
</start>
|
||||
<start name="nic_bridge">
|
||||
<resource name="RAM" quantum="4M"/>
|
||||
<provides><service name="Nic"/></provides>
|
||||
<config verbose="no">
|
||||
<policy label_prefix="recv" ip_addr="192.168.1.1" />
|
||||
<policy label_prefix="send" ip_addr="192.168.1.2" />
|
||||
</config>
|
||||
<route>
|
||||
<service name="Nic"> <child name="nic_loopback"/> </service>
|
||||
<any-service> <parent/> <any-child/> </any-service>
|
||||
</route>
|
||||
</start>
|
||||
|
||||
<start name="recv">
|
||||
<binary name="test-tcp"/>
|
||||
<resource name="RAM" quantum="32M"/>
|
||||
<config>
|
||||
<arg value="recv"/>
|
||||
<libc stdout="/log" stderr="/log" socket="/sockets"/>
|
||||
<vfs>
|
||||
<log/>
|
||||
<dir name="sockets">
|
||||
<} [socket_fs_plugin] { ip_addr="192.168.1.1" netmask="255.255.255.0"/>
|
||||
</dir>
|
||||
</vfs>
|
||||
</config>
|
||||
<route>
|
||||
<service name="Nic"> <child name="nic_bridge"/> </service>
|
||||
<any-service> <parent/> <any-child/> </any-service>
|
||||
</route>
|
||||
</start>
|
||||
|
||||
<start name="send">
|
||||
<binary name="test-tcp"/>
|
||||
<resource name="RAM" quantum="32M"/>
|
||||
<config>
|
||||
<arg value="send"/>
|
||||
<arg value="192.168.1.1"/>
|
||||
<libc stdout="/log" stderr="/log" socket="/sockets"/>
|
||||
<vfs>
|
||||
<log/>
|
||||
<dir name="sockets">
|
||||
<} [socket_fs_plugin] { ip_addr="192.168.1.2" netmask="255.255.255.0"/>
|
||||
</dir>
|
||||
</vfs>
|
||||
</config>
|
||||
<route>
|
||||
<service name="Nic"> <child name="nic_bridge"/> </service>
|
||||
<any-service> <parent/> <any-child/> </any-service>
|
||||
</route>
|
||||
</start>
|
||||
|
||||
</config>
|
||||
}
|
||||
|
||||
install_config $config
|
||||
|
||||
append boot_modules {
|
||||
core ld.lib.so init timer
|
||||
nic_bridge
|
||||
nic_loopback
|
||||
posix.lib.so libc.lib.so libm.lib.so vfs.lib.so vfs_lwip.lib.so
|
||||
test-tcp
|
||||
}
|
||||
|
||||
append_socket_fs_boot_modules
|
||||
|
||||
build_boot_image $boot_modules
|
||||
|
||||
append qemu_args " -nographic"
|
||||
|
||||
run_genode_until {child "recv" exited with exit value 0} 240
|
||||
|
||||
# vi: set ft=tcl :
|
2
repos/libports/run/tcp_bulk_lwip.run
Normal file
2
repos/libports/run/tcp_bulk_lwip.run
Normal file
@ -0,0 +1,2 @@
|
||||
source ${genode_dir}/repos/libports/run/vfs_lwip.inc
|
||||
source ${genode_dir}/repos/libports/run/tcp_bulk.inc
|
2
repos/libports/run/tcp_bulk_lxip.run
Normal file
2
repos/libports/run/tcp_bulk_lxip.run
Normal file
@ -0,0 +1,2 @@
|
||||
source ${genode_dir}/repos/dde_linux/run/vfs_lxip.inc
|
||||
source ${genode_dir}/repos/libports/run/tcp_bulk.inc
|
167
repos/libports/src/test/tcp/main.c
Normal file
167
repos/libports/src/test/tcp/main.c
Normal file
@ -0,0 +1,167 @@
|
||||
/*
|
||||
* \brief Libc tcp send and recv test
|
||||
* \author Emery Hemingway
|
||||
* \date 2018-09-17
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2018 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU Affero General Public License version 3.
|
||||
*/
|
||||
|
||||
/* Libc includes */
|
||||
#include <arpa/inet.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <netinet/in.h>
|
||||
#include <pwd.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
|
||||
/* PCG includes */
|
||||
#include <pcg_variants.h>
|
||||
|
||||
enum { NUM_TEST_INTS = 1<<20, BULK_ITERATIONS = 2 };
|
||||
|
||||
static uint32_t data[NUM_TEST_INTS];
|
||||
|
||||
int test_send(char const *host)
|
||||
{
|
||||
usleep(1000000);
|
||||
|
||||
int sock = socket(AF_INET, SOCK_STREAM, 0);
|
||||
if (sock < 0) {
|
||||
perror("`socket` failed");
|
||||
return sock;
|
||||
}
|
||||
|
||||
{
|
||||
struct sockaddr_in addr;
|
||||
addr.sin_family = AF_INET;
|
||||
addr.sin_addr.s_addr = inet_addr(host);
|
||||
addr.sin_port = htons(2);
|
||||
|
||||
fprintf(stderr, "connect to %s\n", host);
|
||||
if (connect(sock, (struct sockaddr *)&addr, sizeof(addr))) {
|
||||
perror("`connect` failed");
|
||||
return ~0;
|
||||
}
|
||||
}
|
||||
|
||||
pcg32_random_t rng = PCG32_INITIALIZER;
|
||||
for (int j = 0; j < BULK_ITERATIONS; ++j) {
|
||||
for (size_t i = 0; i < NUM_TEST_INTS; ++i)
|
||||
data[i] = pcg32_random_r(&rng);
|
||||
|
||||
size_t total = sizeof(data);
|
||||
size_t offset = 0;
|
||||
|
||||
char *buf = (char *)data;
|
||||
while (offset < total) {
|
||||
ssize_t res = send(sock, buf+offset, total-offset, 0);
|
||||
if (res < 1) {
|
||||
perror("send failed");
|
||||
return -1;
|
||||
}
|
||||
offset += res;
|
||||
}
|
||||
}
|
||||
|
||||
fprintf(stderr, "close server\n");
|
||||
shutdown(sock, SHUT_RDWR);
|
||||
usleep(10000000);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int test_recv()
|
||||
{
|
||||
int sock = socket(AF_INET, SOCK_STREAM, 0);
|
||||
if (sock < 0) {
|
||||
perror("`socket` failed");
|
||||
return sock;
|
||||
}
|
||||
|
||||
{
|
||||
struct sockaddr_in addr;
|
||||
addr.sin_family = AF_INET;
|
||||
addr.sin_addr.s_addr = INADDR_ANY;
|
||||
addr.sin_port = htons(2);
|
||||
|
||||
if (bind(sock, (struct sockaddr *)&addr, sizeof(addr))) {
|
||||
perror("`bind` failed");
|
||||
return ~0;
|
||||
}
|
||||
}
|
||||
|
||||
if (listen(sock, 1)) {
|
||||
perror("listen broke");
|
||||
}
|
||||
|
||||
for (;;) {
|
||||
char string[INET_ADDRSTRLEN];
|
||||
struct sockaddr_in addr;
|
||||
socklen_t super_socket_safety = sizeof(addr);
|
||||
|
||||
int client = accept(sock, (struct sockaddr*)&addr, &super_socket_safety);
|
||||
if (client < 0) {
|
||||
perror("invalid socket from accept!");
|
||||
return ~0;
|
||||
}
|
||||
|
||||
inet_ntop(AF_INET, &(addr.sin_addr), string, super_socket_safety);
|
||||
fprintf(stderr, "recv from %s\n", string);
|
||||
|
||||
pcg32_random_t rng = PCG32_INITIALIZER;
|
||||
for (int j = 0; j < BULK_ITERATIONS; ++j) {
|
||||
|
||||
size_t total = sizeof(data);
|
||||
size_t offset = 0;
|
||||
char *buf = (char *)data;
|
||||
while (offset < total) {
|
||||
ssize_t res = recv(client, buf+offset, total-offset, 0);
|
||||
if (res < 1) {
|
||||
perror("recv failed");
|
||||
return ~0;
|
||||
}
|
||||
offset += res;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < NUM_TEST_INTS; ++i) {
|
||||
if (data[i] != pcg32_random_r(&rng)) {
|
||||
fprintf(stderr, "bad data at byte offset %ld\n", i<<2);
|
||||
return ~0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fprintf(stderr, "close client\n");
|
||||
shutdown(client, SHUT_RDWR);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
if (argc < 1) {
|
||||
fprintf(stderr, "no test name passed thru argv\n");
|
||||
return ~0;
|
||||
}
|
||||
if (argc < 2) {
|
||||
if (strcmp(argv[0], "recv") == 0)
|
||||
return test_recv();
|
||||
}
|
||||
if (argc < 3) {
|
||||
if (strcmp(argv[0], "send") == 0)
|
||||
return test_send(argv[1]);
|
||||
}
|
||||
|
||||
fprintf(stderr, "\"%s\" not a valid test\n", argv[0]);
|
||||
return ~0;
|
||||
}
|
5
repos/libports/src/test/tcp/target.mk
Normal file
5
repos/libports/src/test/tcp/target.mk
Normal file
@ -0,0 +1,5 @@
|
||||
TARGET = test-tcp
|
||||
LIBS += posix libc libpcg_random
|
||||
SRC_C += main.c
|
||||
|
||||
CC_CXX_WARN_STRICT =
|
Loading…
Reference in New Issue
Block a user