Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/tests/net/mcast Make the test stable under load or when runn...



details:   https://anonhg.NetBSD.org/src/rev/925ae36a4fa8
branches:  trunk
changeset: 808656:925ae36a4fa8
user:      ozaki-r <ozaki-r%NetBSD.org@localhost>
date:      Thu May 28 10:19:17 2015 +0000

description:
Make the test stable under load or when running on a slow machine

Let sender and receiver synchronize explicitly via a socketpair
and don't rely on sleep.

diffstat:

 tests/net/mcast/mcast.c |  85 ++++++++++++++++++++++++++++++++++++++++++------
 1 files changed, 73 insertions(+), 12 deletions(-)

diffs (177 lines):

diff -r 73a267dc74aa -r 925ae36a4fa8 tests/net/mcast/mcast.c
--- a/tests/net/mcast/mcast.c   Thu May 28 09:51:31 2015 +0000
+++ b/tests/net/mcast/mcast.c   Thu May 28 10:19:17 2015 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: mcast.c,v 1.2 2015/05/28 08:32:53 ozaki-r Exp $        */
+/*     $NetBSD: mcast.c,v 1.3 2015/05/28 10:19:17 ozaki-r Exp $        */
 
 /*-
  * Copyright (c) 2014 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 #include <sys/cdefs.h>
 #ifdef __RCSID
-__RCSID("$NetBSD: mcast.c,v 1.2 2015/05/28 08:32:53 ozaki-r Exp $");
+__RCSID("$NetBSD: mcast.c,v 1.3 2015/05/28 10:19:17 ozaki-r Exp $");
 #else
 extern const char *__progname;
 #define getprogname() __progname
@@ -59,6 +59,7 @@
 #include <atf-c.h>
 
 #define ERRX(ev, msg, ...)     ATF_REQUIRE_MSG(0, msg, __VA_ARGS__)
+#define ERRX0(ev, msg)         ATF_REQUIRE_MSG(0, msg)
 
 #define SKIPX(ev, msg, ...)    do {                    \
        atf_tc_skip(msg, __VA_ARGS__);                  \
@@ -67,6 +68,7 @@
 
 #else
 #define ERRX(ev, msg, ...)     errx(ev, msg, __VA_ARGS__)
+#define ERRX0(ev, msg)         errx(ev, msg)
 #define SKIPX(ev, msg, ...)    errx(ev, msg, __VA_ARGS__)
 #endif
 
@@ -232,8 +234,38 @@
        return s;
 }
 
-static void
-sender(const char *host, const char *port, size_t n, bool conn, bool bug)
+static int
+synchronize(const int fd, bool waiter)
+{
+       int syncmsg = 0;
+       int r;
+       struct pollfd pfd;
+
+       if (waiter) {
+               pfd.fd = fd;
+               pfd.events = POLLIN;
+
+               /* We use poll to avoid lock up when the peer died unexpectedly */
+               r = poll(&pfd, 1, 10000);
+               if (r == -1)
+                       ERRX(EXIT_FAILURE, "poll (%s)", strerror(errno));
+               if (r == 0)
+                       /* Timed out */
+                       return -1;
+
+               if (read(fd, &syncmsg, sizeof(syncmsg)) == -1)
+                       ERRX(EXIT_FAILURE, "read (%s)", strerror(errno));
+       } else {
+               if (write(fd, &syncmsg, sizeof(syncmsg)) == -1)
+                       ERRX(EXIT_FAILURE, "write (%s)", strerror(errno));
+       }
+
+       return 0;
+}
+
+static int
+sender(const int fd, const char *host, const char *port, size_t n, bool conn,
+    bool bug)
 {
        int s;
        ssize_t l;
@@ -242,6 +274,11 @@
        socklen_t slen;
 
        s = getsocket(host, port, conn ? connect : connector, &slen, bug);
+
+       /* Wait until receiver gets ready. */
+       if (synchronize(fd, true) == -1)
+               return -1;
+
        for (msg.seq = 0; msg.seq < n; msg.seq++) {
 #ifdef CLOCK_MONOTONIC
                if (clock_gettime(CLOCK_MONOTONIC, &msg.ts) == -1)
@@ -261,10 +298,17 @@
                        ERRX(EXIT_FAILURE, "send (%s)", strerror(errno));
                usleep(100);
        }
+
+       /* Wait until receiver finishes its work. */
+       if (synchronize(fd, true) == -1)
+               return -1;
+
+       return 0;
 }
 
 static void
-receiver(const char *host, const char *port, size_t n, bool conn, bool bug)
+receiver(const int fd, const char *host, const char *port, size_t n, bool conn,
+    bool bug)
 {
        int s;
        ssize_t l;
@@ -276,6 +320,10 @@
        s = getsocket(host, port, bind, &slen, bug);
        pfd.fd = s;
        pfd.events = POLLIN;
+
+       /* Tell I'm ready */
+       synchronize(fd, false);
+
        for (seq = 0; seq < n; seq++) {
                if (poll(&pfd, 1, 10000) == -1)
                        ERRX(EXIT_FAILURE, "poll (%s)", strerror(errno));
@@ -289,6 +337,9 @@
                        ERRX(EXIT_FAILURE, "seq: expect=%zu actual=%zu",
                            seq, msg.seq);
        }
+
+       /* Tell I'm finished */
+       synchronize(fd, false);
 }
 
 static void
@@ -296,22 +347,32 @@
 {
        pid_t pid;
        int status;
+       int syncfds[2];
+       int error;
+
+       if (socketpair(AF_UNIX, SOCK_STREAM, 0, syncfds) == -1)
+               ERRX(EXIT_FAILURE, "socketpair (%s)", strerror(errno));
 
        switch ((pid = fork())) {
        case 0:
-               receiver(host, port, n, conn, bug);
+               receiver(syncfds[0], host, port, n, conn, bug);
                return;
        case -1:
                ERRX(EXIT_FAILURE, "fork (%s)", strerror(errno));
        default:
-               usleep(1000);
-               sender(host, port, n, conn, bug);
-               usleep(100);
+               error = sender(syncfds[1], host, port, n, conn, bug);
        again:
                switch (waitpid(pid, &status, WNOHANG)) {
                case -1:
                        ERRX(EXIT_FAILURE, "wait (%s)", strerror(errno));
                case 0:
+                       if (error == 0)
+                               /*
+                                * Receiver is still alive, but we know
+                                * it will exit soon.
+                                */
+                               goto again;
+
                        if (kill(pid, SIGTERM) == -1)
                                ERRX(EXIT_FAILURE, "kill (%s)",
                                    strerror(errno));
@@ -319,9 +380,9 @@
                default:
                        if (WIFSIGNALED(status)) {
                                if (WTERMSIG(status) == SIGTERM)
-                                       ERRX(EXIT_FAILURE,
-                                           "receiver got terminated due to " \
-                                           "deadline (%d usec)", 100);
+                                       ERRX0(EXIT_FAILURE,
+                                           "receiver failed and was killed" \
+                                           "by sender");
                                else
                                        ERRX(EXIT_FAILURE,
                                            "receiver got signaled (%s)",



Home | Main Index | Thread Index | Old Index