[SCM] Socket Wrapper Repository - branch master updated
Andreas Schneider
asn at samba.org
Tue Dec 10 02:15:06 MST 2013
The branch, master has been updated
via 2b53d42 tests: Add test_echo_udp_sendto_recvfrom.
via b853eac cmake: Remove swrap env variables.
via 76c362f tests: Add a simple echo server
from 9f7d7b4 swrap: Remove obsolete init functions.
http://gitweb.samba.org/?p=socket_wrapper.git;a=shortlog;h=master
- Log -----------------------------------------------------------------
commit 2b53d420caa157aa7084ace2c07365bd675e026a
Author: Andreas Schneider <asn at samba.org>
Date: Fri Dec 6 12:03:24 2013 +0100
tests: Add test_echo_udp_sendto_recvfrom.
commit b853eac01a7c79b280410b5bdc3eadfce4d1ee27
Author: Andreas Schneider <asn at samba.org>
Date: Fri Dec 6 12:02:46 2013 +0100
cmake: Remove swrap env variables.
They should be set up in the test!
commit 76c362fa3be7c65e5c50b9400cbc52a8cc81ed3b
Author: Jakub Hrozek <jhrozek at redhat.com>
Date: Thu Dec 5 20:36:05 2013 +0100
tests: Add a simple echo server
-----------------------------------------------------------------------
Summary of changes:
tests/CMakeLists.txt | 45 ++---
tests/echo_srv.c | 330 +++++++++++++++++++++++++++++++++
tests/test_echo_udp_sendto_recvfrom.c | 200 ++++++++++++++++++++
tests/torture.h | 45 +++++
4 files changed, 595 insertions(+), 25 deletions(-)
create mode 100644 tests/echo_srv.c
create mode 100644 tests/test_echo_udp_sendto_recvfrom.c
create mode 100644 tests/torture.h
Changeset truncated at 500 lines:
diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
index ab55d07..49cd62a 100644
--- a/tests/CMakeLists.txt
+++ b/tests/CMakeLists.txt
@@ -6,29 +6,24 @@ include_directories(
${CMOCKA_INCLUDE_DIR}
)
+add_executable(echo_srv echo_srv.c)
+
add_cmocka_test(testsuite testsuite.c ${CMOCKA_LIBRARY} ${SWRAP_REQUIRED_LIBRARIES})
-if (OSX)
-set_property(
- TEST
- testsuite
- PROPERTY
- ENVIRONMENT DYLD_FORCE_FLAT_NAMESPACE=1;DYLD_INSERT_LIBRARIES=${CMAKE_BINARY_DIR}/src/libsocket_wrapper.dylib)
-else ()
-set_property(
- TEST
- testsuite
- PROPERTY
- ENVIRONMENT LD_PRELOAD=${CMAKE_BINARY_DIR}/src/libsocket_wrapper.so)
-endif()
-set_property(
- TEST
- testsuite
- APPEND
- PROPERTY
- ENVIRONMENT SOCKET_WRAPPER_DIR=${CMAKE_CURRENT_BINARY_DIR})
-set_property(
- TEST
- testsuite
- APPEND
- PROPERTY
- ENVIRONMENT SOCKET_WRAPPER_DEFAULT_IFACE="11")
+add_cmocka_test(test_echo_udp_sendto_recvfrom test_echo_udp_sendto_recvfrom.c ${CMOCKA_LIBRARY} ${SWRAP_REQUIRED_LIBRARIES})
+
+set(SWRAP_TESTS testsuite test_echo_udp_sendto_recvfrom)
+foreach(_SWRAP_TEST ${SWRAP_TESTS})
+ if (OSX)
+ set_property(
+ TEST
+ ${_SWRAP_TEST}
+ PROPERTY
+ ENVIRONMENT DYLD_FORCE_FLAT_NAMESPACE=1;DYLD_INSERT_LIBRARIES=${CMAKE_BINARY_DIR}/src/libsocket_wrapper.dylib)
+ else ()
+ set_property(
+ TEST
+ ${_SWRAP_TEST}
+ PROPERTY
+ ENVIRONMENT LD_PRELOAD=${CMAKE_BINARY_DIR}/src/libsocket_wrapper.so)
+ endif()
+endforeach()
diff --git a/tests/echo_srv.c b/tests/echo_srv.c
new file mode 100644
index 0000000..13e2bc3
--- /dev/null
+++ b/tests/echo_srv.c
@@ -0,0 +1,330 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <resolv.h>
+#include <arpa/inet.h>
+#include <errno.h>
+#include <netdb.h>
+#include <string.h>
+#include <getopt.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <stdbool.h>
+
+#ifndef PIDFILE
+#define PIDFILE "echo_srv.pid"
+#endif /* PIDFILE */
+
+#define DFL_PORT 7
+#define BACKLOG 5
+
+#ifndef BUFSIZE
+#define BUFSIZE 4194304
+#endif /* BUFSIZE */
+
+struct echo_srv_opts {
+ int port;
+ int socktype;
+ bool daemon;
+ char *bind;
+ const char *pidfile;
+};
+
+static int pidfile(const char *path)
+{
+ int err;
+ int fd;
+ char pid_str[32];
+
+ fd = open(path, O_RDONLY, 0644);
+ err = errno;
+ if (fd != -1) {
+ close(fd);
+ return EEXIST;
+ } else if (err != ENOENT) {
+ return err;
+ }
+
+ fd = open(path, O_CREAT | O_WRONLY | O_EXCL, 0644);
+ err = errno;
+ if (fd == -1) {
+ return err;
+ }
+
+ memset(pid_str, 0, sizeof(pid_str));
+ snprintf(pid_str, sizeof(pid_str) -1, "%u\n", (unsigned int) getpid());
+ write(fd, pid_str, strlen(pid_str));
+
+ return 0;
+}
+
+static int become_daemon(struct echo_srv_opts *opts)
+{
+ int ret;
+ pid_t child_pid;
+ int fd;
+
+ if (getppid() == 1) {
+ return 0;
+ }
+
+ child_pid = fork();
+ if (child_pid == -1) {
+ ret = errno;
+ perror("fork");
+ return ret;
+ } else if (child_pid > 0) {
+ exit(0);
+ }
+
+ /* If a working directory was defined, go there */
+#ifdef WORKING_DIR
+ chdir(WORKING_DIR);
+#endif
+
+ ret = pidfile(opts->pidfile);
+ if (ret != 0) {
+ fprintf(stderr, "Cannot create pidfile %s: %s\n",
+ opts->pidfile, strerror(ret));
+ return ret;
+ }
+
+ ret = setsid();
+ if (ret == -1) {
+ ret = errno;
+ perror("setsid");
+ return ret;
+ }
+
+ for (fd = getdtablesize(); fd >= 0; --fd) {
+ close(fd);
+ }
+
+ fd = open("/dev/null", O_RDWR);
+ if (fd == -1) {
+ ret = errno;
+ perror("open");
+ return ret;
+ }
+ dup(fd);
+ dup(fd);
+
+ umask(0177);
+ return 0;
+}
+
+/* Returns 0 on success, errno on failure. If successful,
+ * sock is a ready to use socket */
+static int setup_srv(struct echo_srv_opts *opts, int *_sock)
+{
+ struct addrinfo hints;
+ struct addrinfo *res, *ri;
+ char svc[6];
+ int ret;
+ int sock;
+
+ memset(&hints, 0, sizeof(hints));
+ hints.ai_family = AF_UNSPEC;
+ hints.ai_socktype = opts->socktype;
+ hints.ai_flags = AI_PASSIVE;
+
+ snprintf(svc, sizeof(svc), "%d", opts->port);
+
+ ret = getaddrinfo(opts->bind, svc, &hints, &res);
+ if (ret != 0) {
+ return errno;
+ }
+
+ for (ri = res; ri != NULL; ri = ri->ai_next) {
+ sock = socket(ri->ai_family, ri->ai_socktype,
+ ri->ai_protocol);
+ if (sock == -1) {
+ ret = errno;
+ freeaddrinfo(res);
+ perror("socket");
+ return ret;
+ }
+
+ ret = bind(sock, ri->ai_addr, ri->ai_addrlen);
+ if (ret == 0) {
+ break;
+ }
+
+ close(sock);
+ }
+ freeaddrinfo(res);
+
+ if (ri == NULL) {
+ fprintf(stderr, "Could not bind\n");
+ return EFAULT;
+ }
+
+ if (opts->socktype == SOCK_STREAM) {
+ ret = listen(sock, BACKLOG);
+ if (ret == -1) {
+ ret = errno;
+ perror("listen");
+ return ret;
+ }
+ }
+
+ *_sock = sock;
+ return 0;
+}
+
+static void echo_tcp(int sock)
+{
+ int client_sock;
+ struct sockaddr_storage css;
+ socklen_t addrlen = sizeof(css);
+ ssize_t bret;
+ char buf[BUFSIZE];
+
+ client_sock = accept(sock, (struct sockaddr *) &css, &addrlen);
+ if (client_sock == -1) {
+ perror("accept");
+ return;
+ }
+
+ while (1) {
+ bret = recv(client_sock, buf, BUFSIZE, 0);
+ if (bret == -1) {
+ close(client_sock);
+ perror("recv");
+ continue;
+ } else if (bret == 0) {
+ break;
+ }
+
+ bret = send(client_sock, buf, bret, 0);
+ if (bret == -1) {
+ close(client_sock);
+ perror("send");
+ continue;
+ }
+ }
+
+ close(client_sock);
+}
+
+static void echo_udp(int sock)
+{
+ struct sockaddr_storage css;
+ socklen_t addrlen = sizeof(css);
+ ssize_t bret;
+ char buf[BUFSIZE];
+
+ while (1) {
+ bret = recvfrom(sock, buf, BUFSIZE, 0,
+ (struct sockaddr *) &css, &addrlen);
+ if (bret == -1) {
+ perror("recvfrom");
+ continue;
+ }
+
+ bret = sendto(sock, buf, bret, 0,
+ (struct sockaddr *) &css, addrlen);
+ if (bret == -1) {
+ perror("sendto");
+ continue;
+ }
+ }
+}
+
+static void echo(int sock, struct echo_srv_opts *opts)
+{
+ switch (opts->socktype) {
+ case SOCK_STREAM:
+ echo_tcp(sock);
+ return;
+ case SOCK_DGRAM:
+ echo_udp(sock);
+ return;
+ default:
+ fprintf(stderr, "Unsupported protocol\n");
+ return;
+ }
+}
+
+int main(int argc, char **argv)
+{
+ int ret;
+ int sock;
+ struct echo_srv_opts opts;
+ int opt;
+ int optindex;
+ static struct option long_options[] = {
+ {"tcp", no_argument, 0, 't' },
+ {"udp", no_argument, 0, 'u' },
+ {"bind-addr", required_argument, 0, 'b' },
+ {"port", required_argument, 0, 'p' },
+ {"daemon", no_argument, 0, 'D' },
+ {"pid", required_argument, 0, 0 },
+ {0, 0, 0, 0 }
+ };
+
+ opts.port = DFL_PORT;
+ opts.socktype = SOCK_STREAM;
+ opts.bind = NULL;
+ opts.pidfile = PIDFILE;
+ opts.daemon = false;
+
+ while ((opt = getopt_long(argc, argv, "Dutp:b:",
+ long_options, &optindex)) != -1) {
+ switch (opt) {
+ case 0:
+ if (optindex == 5) {
+ opts.pidfile = optarg;
+ }
+ break;
+ case 'p':
+ opts.port = atoi(optarg);
+ break;
+ case 'b':
+ opts.bind = optarg;
+ break;
+ case 'u':
+ opts.socktype = SOCK_DGRAM;
+ break;
+ case 't':
+ opts.socktype = SOCK_STREAM;
+ break;
+ case 'D':
+ opts.daemon = true;
+ break;
+ default: /* '?' */
+ fprintf(stderr, "Usage: %s [-p port] [-u] [-t] [--pid pidfile]\n",
+ argv[0]);
+ ret = 1;
+ goto done;
+ }
+ }
+
+ if (opts.daemon) {
+ ret = become_daemon(&opts);
+ if (ret != 0) {
+ fprintf(stderr, "Cannot become daemon: %s\n", strerror(ret));
+ goto done;
+ }
+ }
+
+ ret = setup_srv(&opts, &sock);
+ if (ret != 0) {
+ fprintf(stderr, "Cannot setup server: %s\n", strerror(ret));
+ goto done;
+ }
+
+ echo(sock, &opts);
+ close(sock);
+
+ if (opts.daemon) {
+ unlink(opts.pidfile);
+ }
+
+ ret = 0;
+done:
+ return ret;
+}
diff --git a/tests/test_echo_udp_sendto_recvfrom.c b/tests/test_echo_udp_sendto_recvfrom.c
new file mode 100644
index 0000000..9596e5e
--- /dev/null
+++ b/tests/test_echo_udp_sendto_recvfrom.c
@@ -0,0 +1,200 @@
+#include <stdarg.h>
+#include <stddef.h>
+#include <setjmp.h>
+#include <cmocka.h>
+
+#include "config.h"
+#include "torture.h"
+
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+#include <signal.h>
+
+#include <sys/stat.h>
+#include <fcntl.h>
+
+#include <unistd.h>
+
+#define ECHO_SRV_IP "127.0.0.10"
+#define ECHO_SRV_PORT 7
+
+#define ECHO_SRV_PIDFILE "echo_srv.pid"
+
+struct test_opts {
+ char *socket_wrapper_dir;
+ char *pidfile;
+};
+
+static void setup(void **state)
+{
+ char test_tmpdir[256];
+ struct test_opts *o;
+ size_t len;
+ const char *p;
+
+ o = malloc(sizeof(struct test_opts));
+ assert_non_null(o);
+
+ snprintf(test_tmpdir, sizeof(test_tmpdir), "/tmp/test_socket_wrapper_XXXXXX");
+
+ p = mkdtemp(test_tmpdir);
+ assert_non_null(p);
+
+ o->socket_wrapper_dir = strdup(p);
+ assert_non_null(o->socket_wrapper_dir);
+
+ len = strlen(p) + 1 + strlen(ECHO_SRV_PIDFILE) + 1;
+
+ o->pidfile = malloc(len);
+ assert_non_null(o->pidfile);
+
+ snprintf(o->pidfile, len, "%s/%s", p, ECHO_SRV_PIDFILE);
+
+ setenv("SOCKET_WRAPPER_DIR", p, 1);
+ setenv("SOCKET_WRAPPER_DEFAULT_IFACE", "21", 1);
+
+ *state = o;
+}
+
+static void setup_echo_srv_udp(void **state)
+{
+ struct test_opts *o;
+ char start_echo_srv[1024] = {0};
+ int rc;
+
+ setup(state);
+ o = *state;
+
+ snprintf(start_echo_srv, sizeof(start_echo_srv),
+ "%s/tests/echo_srv -b %s -D -u --pid %s",
+ BINARYDIR, ECHO_SRV_IP, o->pidfile);
+
+ rc = system(start_echo_srv);
+ assert_int_equal(rc, 0);
+
+ sleep(1);
+}
+
+static void teardown(void **state)
+{
+ struct test_opts *o = *state;
+ char remove_cmd[1024] = {0};
+ int rc;
+
+ (void) state; /* unused */
+
+ snprintf(remove_cmd, sizeof(remove_cmd), "rm -rf %s", o->socket_wrapper_dir);
+
+ rc = system(remove_cmd);
+ if (rc < 0) {
+ fprintf(stderr, "%s failed: %s", remove_cmd, strerror(errno));
+ }
+
+ free(o->socket_wrapper_dir);
+ free(o->pidfile);
+ free(o);
+}
+
--
Socket Wrapper Repository
More information about the samba-cvs
mailing list