summaryrefslogtreecommitdiffabout
path: root/tests
authorSergey Poznyakoff <gray@gnu.org>2019-06-11 14:30:25 (GMT)
committer Sergey Poznyakoff <gray@gnu.org>2019-06-11 14:30:25 (GMT)
commit07e7ee3d732b60e0b7f5b242bbfb0cdec8e99e7f (patch) (side-by-side diff)
treed8106ba7d4e4e92f4bb4f49427eb6e2db10897a3 /tests
parentbf6506cdc46446eada5090a428c2407ebd17468a (diff)
downloadpies-07e7ee3d732b60e0b7f5b242bbfb0cdec8e99e7f.tar.gz
pies-07e7ee3d732b60e0b7f5b242bbfb0cdec8e99e7f.tar.bz2
Test pass-fd components
* tests/recvfd.c: New source. * tests/.gitignore: Update. * tests/passfd.at: New test. * tests/Makefile.am: Add new test. * tests/testsuite.at: Add new test. * tests/nt.c: Check all revents bits.
Diffstat (limited to 'tests') (more/less context) (show whitespace changes)
-rw-r--r--tests/.gitignore1
-rw-r--r--tests/Makefile.am3
-rw-r--r--tests/nt.c10
-rw-r--r--tests/passfd.at57
-rw-r--r--tests/recvfd.c223
-rw-r--r--tests/testsuite.at1
-rw-r--r--tests/to.c16
7 files changed, 305 insertions, 6 deletions
diff --git a/tests/.gitignore b/tests/.gitignore
index 68159e3..7d2613a 100644
--- a/tests/.gitignore
+++ b/tests/.gitignore
@@ -8,3 +8,4 @@ testsuite.dir
testsuite.log
to
nt
+recvfd
diff --git a/tests/Makefile.am b/tests/Makefile.am
index fa1d6be..1fe78dc 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -55,6 +55,7 @@ TESTSUITE_AT = \
envop.at\
inet.at\
maxinst.at\
+ passfd.at\
respawn.at\
redirect.at\
ret-exec.at\
@@ -67,7 +68,7 @@ TESTSUITE_AT = \
TESTSUITE = $(srcdir)/testsuite
M4=m4
-noinst_PROGRAMS = envtest to lines nt
+noinst_PROGRAMS = envtest to lines nt recvfd
nt_SOURCES = nt.c iobuf.h
AM_CPPFLAGS = \
-I$(top_srcdir)/lib\
diff --git a/tests/nt.c b/tests/nt.c
index d30e447..98a4077 100644
--- a/tests/nt.c
+++ b/tests/nt.c
@@ -1,4 +1,4 @@
-/* This file is part of GNU Pies.
+/* This file is part of GNU Pies testsuite.
Copyright (C) 2019 Sergey Poznyakoff
GNU Pies is free software; you can redistribute it and/or modify
@@ -272,15 +272,15 @@ netcat (char const *urlstr)
& (srv->state | ((srv->state & POLLOUT) ? POLLHUP : 0)));
if (events)
{
+ if (events & POLLIN)
+ netcat_stream_read (srv);
+ if (events & POLLOUT)
+ netcat_stream_write (srv);
if (events & POLLHUP)
{
//grecs_error (NULL, 0, "HUP on %s", srv->id);
netcat_stream_disconnect (srv, srv->state);
}
- else if (events & POLLIN)
- netcat_stream_read (srv);
- else if (events & POLLOUT)
- netcat_stream_write (srv);
}
if (srv->state == 0 || srv->pollfd->fd == -1)
netcat_server_remove (srv);
diff --git a/tests/passfd.at b/tests/passfd.at
new file mode 100644
index 0000000..4a685a3
--- a/dev/null
+++ b/tests/passfd.at
@@ -0,0 +1,57 @@
+# This file is part of GNU pies testsuite. -*- Autotest -*-
+# Copyright (C) 2016-2019 Sergey Poznyakoff
+#
+# GNU pies is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU pies is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU pies. If not, see <http://www.gnu.org/licenses/>.
+AT_SETUP([pass-fd component])
+AT_CHECK([
+PIES_XFAIL_CHECK
+PIES_CONTROL_INIT
+
+AT_DATA([input],
+[now is
+the time
+stop
+])
+
+: ${PIES_TEST_INET_SOCKET:=unix://$PWD/in.sock}
+PIES_FD_SOCKET=$PWD/pfd.sock
+
+cat > pies.conf <<_EOT
+component pfd {
+ command "recvfd '$PIES_FD_SOCKET' $auxdir/in.test $PWD/inlog";
+ mode pass-fd;
+ pass-fd-timeout 3;
+ pass-fd-socket "$PIES_FD_SOCKET";
+ socket "$PIES_TEST_INET_SOCKET";
+ stderr file "$PWD/log.err";
+}
+component controller {
+ command "nt $PIES_TEST_INET_SOCKET -i input";
+}
+_EOT
+
+set -e
+to 10 \
+ pies --foreground --stderr \
+ --config-file control.conf --config-file pies.conf --debug 1 2>errlog
+
+cat inlog
+cat log.err >&2
+],
+[0],
+[now is
+the time
+stop
+])
+AT_CLEANUP \ No newline at end of file
diff --git a/tests/recvfd.c b/tests/recvfd.c
new file mode 100644
index 0000000..82455c7
--- a/dev/null
+++ b/tests/recvfd.c
@@ -0,0 +1,223 @@
+/* This file is part of GNU Pies testsuite.
+ Copyright (C) 2019 Sergey Poznyakoff
+
+ GNU Pies is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3, or (at your option)
+ any later version.
+
+ GNU Pies is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GNU Pies. If not, see <http://www.gnu.org/licenses/>. */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <sys/stat.h>
+#include <sys/wait.h>
+#include <signal.h>
+#include "libpies.h"
+
+char const *progname;
+
+void
+usage (void)
+{
+ fprintf (stderr, "usage: %s SOCKET COMMAND ARGS...\n", progname);
+ fprintf (stderr, "Test tool for pass-fd pies components.\n");
+ fprintf (stderr, "Listens on the file descriptor obtained from SOCKET.\n");
+ fprintf (stderr, "For each connection, execs COMMAND ARGS as a separate process.\n");
+ exit (64);
+}
+
+static int
+listen_socket (char const *socket_name)
+{
+ struct sockaddr_un addr;
+ int sockfd;
+
+ if (strlen (socket_name) > sizeof addr.sun_path)
+ {
+ fprintf (stderr, "%s: UNIX socket name too long\n", progname);
+ return -1;
+ }
+ addr.sun_family = AF_UNIX;
+ strcpy (addr.sun_path, socket_name);
+
+ sockfd = socket (PF_UNIX, SOCK_STREAM, 0);
+ if (sockfd == -1)
+ {
+ perror ("socket");
+ exit (1);
+ }
+
+ umask (0117);
+ if (bind (sockfd, (struct sockaddr *) &addr, sizeof (addr)) < 0)
+ {
+ perror ("bind");
+ exit (1);
+ }
+
+ if (listen (sockfd, 8) < 0)
+ {
+ perror ("listen");
+ exit (1);
+ }
+ return sockfd;
+}
+
+static int
+read_fd (int fd)
+{
+ struct msghdr msg;
+ struct iovec iov[1];
+ char base[1];
+
+#if HAVE_STRUCT_MSGHDR_MSG_CONTROL
+ union
+ {
+ struct cmsghdr cm;
+ char control[CMSG_SPACE (sizeof (int))];
+ } control_un;
+ struct cmsghdr *cmptr;
+
+ msg.msg_control = control_un.control;
+ msg.msg_controllen = sizeof (control_un.control);
+#elif HAVE_STRUCT_MSGHDR_MSG_ACCRIGHTS
+ int newfd;
+
+ msg.msg_accrights = (caddr_t) &newfd;
+ msg.msg_accrightslen = sizeof (int);
+#else
+ fprintf (stderr, "no way to get fd\n");
+ exit (77);
+#endif
+
+ msg.msg_name = NULL;
+ msg.msg_namelen = 0;
+
+ iov[0].iov_base = base;
+ iov[0].iov_len = sizeof (base);
+
+ msg.msg_iov = iov;
+ msg.msg_iovlen = 1;
+
+ if (recvmsg (fd, &msg, 0) > 0)
+ {
+#if HAVE_STRUCT_MSGHDR_MSG_CONTROL
+ if ((cmptr = CMSG_FIRSTHDR (&msg)) != NULL
+ && cmptr->cmsg_len == CMSG_LEN (sizeof (int))
+ && cmptr->cmsg_level == SOL_SOCKET
+ && cmptr->cmsg_type == SCM_RIGHTS)
+ return *((int*) CMSG_DATA (cmptr));
+#elif HAVE_STRUCT_MSGHDR_MSG_ACCRIGHTS
+ if (msg.msg_accrightslen == sizeof (int))
+ return newfd;
+#endif
+ }
+ return -1;
+}
+
+static int
+get_fd (int lfd)
+{
+ int sfd, fd = accept (lfd, NULL, NULL);
+ if (fd == -1)
+ {
+ perror ("accept");
+ exit (1);
+ }
+
+ sfd = read_fd (fd);
+ close (fd);
+ return sfd;
+}
+
+static void
+sigchld (int sig)
+{
+ pid_t pid;
+
+ while ((pid = waitpid ((pid_t)-1, NULL, WNOHANG)) >= 0)
+ ;
+ signal (sig, sigchld);
+}
+
+static void
+sigquit (int sig)
+{
+ kill (0, sig);
+ exit (0);
+}
+
+int
+main (int argc, char **argv)
+{
+ int sfd, fd;
+
+ progname = argv[0];
+
+ if (argc < 3)
+ usage ();
+
+ sfd = listen_socket (argv[1]);
+
+ argc -= 2;
+ argv += 2;
+
+ fd = get_fd (sfd);
+ close (sfd);
+
+ signal (SIGCHLD, sigchld);
+ signal (SIGTERM, sigquit);
+ signal (SIGHUP, sigquit);
+ signal (SIGINT, sigquit);
+ signal (SIGQUIT, sigquit);
+
+ while (1)
+ {
+ int cfd = accept (fd, NULL, NULL);
+ if (cfd == -1)
+ {
+ perror ("accept");
+ exit (1);
+ }
+
+ pid_t pid = fork ();
+ if (pid == 0)
+ {
+ int i;
+
+ for (i = getmaxfd (); i >= 0; i--)
+ if (i != cfd)
+ close (i);
+
+ if (cfd != 0)
+ dup2 (cfd, 0);
+ if (cfd != 1)
+ dup2 (cfd, 1);
+ if (cfd != 2)
+ dup2 (cfd, 2);
+ if (cfd > 2)
+ close (cfd);
+
+ execvp (argv[0], argv);
+ exit (127);
+ }
+ if (pid == -1)
+ {
+ perror ("fork");
+ }
+ close (cfd);
+ }
+ return 0;
+}
diff --git a/tests/testsuite.at b/tests/testsuite.at
index 0682b51..843d235 100644
--- a/tests/testsuite.at
+++ b/tests/testsuite.at
@@ -71,6 +71,7 @@ m4_include([shutdown.at])
m4_include([shell.at])
m4_include([inet.at])
m4_include([maxinst.at])
+m4_include([passfd.at])
m4_include([envop.at])
m4_include([env.at]) \ No newline at end of file
diff --git a/tests/to.c b/tests/to.c
index 6874bfd..0bfabac 100644
--- a/tests/to.c
+++ b/tests/to.c
@@ -1,3 +1,19 @@
+/* This file is part of GNU Pies testsuite.
+ Copyright (C) 2019 Sergey Poznyakoff
+
+ GNU Pies is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3, or (at your option)
+ any later version.
+
+ GNU Pies is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GNU Pies. If not, see <http://www.gnu.org/licenses/>. */
+
#include <config.h>
#include <stdlib.h>
#include <stdio.h>

Return to:

Send suggestions and report system problems to the System administrator.