[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