aboutsummaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org>2019-06-12 19:23:39 +0300
committerSergey Poznyakoff <gray@gnu.org>2019-06-12 19:29:45 +0300
commit85563afeac954a50de7e4c207f43b57a4e63e474 (patch)
tree967054eb92014811e067f1d56c99e12c268f1824 /tests
parentf5c72b5e74ea7aaf1375f763f977e3249c6b7fc4 (diff)
downloadpies-85563afeac954a50de7e4c207f43b57a4e63e474.tar.gz
pies-85563afeac954a50de7e4c207f43b57a4e63e474.tar.bz2
More tests for built-in services
* tests/builtin.at: Check tcpmux services. * tests/nt.c: Add tcpmux support, improve error checking. * tests/chargen.c: Improve error checking.
Diffstat (limited to 'tests')
-rw-r--r--tests/builtin.at77
-rw-r--r--tests/chargen.c11
-rw-r--r--tests/nt.c145
3 files changed, 211 insertions, 22 deletions
diff --git a/tests/builtin.at b/tests/builtin.at
index 40f65fa..893f213 100644
--- a/tests/builtin.at
+++ b/tests/builtin.at
@@ -120,12 +120,89 @@ three
IT_SPECIAL([time],[readtime])
IT_SPECIAL([daytime],[readtime -H])
IT_SPECIAL([chargen],[chargen])
IT_BUILTIN([qotd],[],
[A useful debugging and measurement tool is a quote of the day service.
A quote of the day service simply sends a short message without regard
to the input.
])
m4_popdef([IT_BUILTIN])
m4_popdef([IT_SPECIAL])
+
+# IT_TCPMUX([KW],[ID],[INPUT],[OUTPUT])
+m4_define([IT_TCPMUX],
+[AT_SETUP([tcpmux: $1])
+AT_KEYWORDS([inetd builtin internal tcpmux $1])
+AT_CHECK([
+PIES_XFAIL_CHECK
+PIES_CONTROL_INIT
+: ${PIES_TEST_INET_SOCKET:=unix://$PWD/in.sock}
+m4_if([$3],[],[],[AT_DATA([input],[$3])])
+cat > pies.conf <<_EOT
+component master {
+ socket "$PIES_TEST_INET_SOCKET";
+ service tcpmux;
+ flags internal;
+}
+component one {
+ service one;
+ flags (tcpmuxplus);
+ tcpmux-master master;
+ command "$auxdir/in.test $PWD/one.log";
+ stderr file "$PWD/one.err";
+}
+component two {
+ service two;
+ flags (tcpmuxplus);
+ tcpmux-master master;
+ command "$auxdir/in.test $PWD/two.log";
+ stderr file "$PWD/two.err";
+}
+component test {
+ command "nt -t [$2]m4_if([$3],[],,[ -i $PWD/input]) -o $PWD/test.out '$PIES_TEST_INET_SOCKET'";
+ stderr file "$PWD/test.err";
+ return-code * {
+ action disable;
+ exec "piesctl --no-netrc --url=$PIES_CTLSOCK shutdown";
+ }
+}
+_EOT
+
+set -e
+to 10 \
+ pies --foreground --stderr \
+ --config-file control.conf --config-file pies.conf --debug 1 2>errlog
+
+for err in one.err two.err test.err
+do
+ if test -s $err; then
+ echo "$err:"
+ cat $err
+ fi
+done >&2
+
+if test -f test.out; then
+ cat test.out | tr -d '\r'
+fi
+],
+[0],
+[$4])
+AT_CLEANUP
+])
+
+IT_TCPMUX([help],[help],[],
+[one
+two
+])
+
+IT_TCPMUX([service],[one],
+[Test one
+quit
+],
+[OK Test one
+])
+
+m4_popdef([IT_TCPMUX])
+
+
diff --git a/tests/chargen.c b/tests/chargen.c
index a3b3290..75d096c 100644
--- a/tests/chargen.c
+++ b/tests/chargen.c
@@ -67,31 +67,38 @@ main (int argc, char **argv)
int c, first;
char *progname = argv[0];
if (argc != 2)
{
fprintf (stderr, "usage: %s URL\n", progname);
fprintf (stderr, "Tests the character generator protocol\n");
return 64;
}
if (pies_url_create (&url, argv[1]))
{
- perror (argv[0]);
+ perror (argv[1]);
return 64;
}
fd = url_connect (url, NULL);
+ if (fd == -1)
+ return 1;
fp = fdopen (fd, "r");
-
+ if (!fp)
+ {
+ perror ("fdopen");
+ return 1;
+ }
+
first = next_char (0);
c = first;
do
{
int in = fgetc (fp);
if (in == EOF)
{
fprintf (stderr, "%s: unexpected EOF in %u\n", progname, n);
return 1;
}
if (in != c)
{
diff --git a/tests/nt.c b/tests/nt.c
index 876ffb1..c7f4be7 100644
--- a/tests/nt.c
+++ b/tests/nt.c
@@ -127,25 +127,25 @@ ssize_t
netcat_stream_read (netcat_server_t *srv)
{
ssize_t n;
if (iobuf_avail_size (&srv->buf[IN]))
{
n = iobuf_fill (&srv->buf[IN], srv->pollfd->fd);
if (n == -1)
{
if (errno == EINTR)
return 0;
grecs_error (NULL, errno, "%s: read", srv->id);
- srv->pollfd->events &= ~POLLIN;
+ netcat_stream_disconnect (srv, POLLIN);
return -1;
}
if (n == 0 || !peer_is_state (srv, POLLOUT))
{
/* No more input is expected || needed */
netcat_stream_disconnect (srv, POLLIN);
if (srv->peer)
netcat_stream_disconnect (srv->peer, POLLOUT);
return 0;
}
else
@@ -176,29 +176,30 @@ netcat_stream_write (netcat_server_t *srv)
{
srv->peer->pollfd->events |= POLLIN;
srv->pollfd->events &= ~POLLOUT;
return 0;
}
}
n = iobuf_flush (&srv->buf[OUT], srv->pollfd->fd);
if (n == -1)
{
if (errno == EINTR)
return 0;
grecs_error (NULL, errno, "%s: write", srv->id);
+ netcat_stream_disconnect (srv, POLLOUT);
return -1;
}
if (n == 0)
{
- // FIXME: eof
+ netcat_stream_disconnect (srv, POLLOUT);
return -1;
}
return 0;
}
int
disconnect_in (netcat_server_t *srv)
{
return shutdown (srv->pollfd->fd, SHUT_RD);
}
int
@@ -211,43 +212,137 @@ int
disconnect_stdin (netcat_server_t *srv)
{
return close (srv->pollfd->fd);
}
int
disconnect_stdout (netcat_server_t *srv)
{
close (srv->pollfd->fd);
exit (0);
}
+void
+fd_write (int fd, char const *str, size_t len)
+{
+ while (len)
+ {
+ ssize_t n = write (fd, str, len);
+ if (n == -1)
+ {
+ perror ("socket write");
+ exit (1);
+ }
+ if (n == 0)
+ {
+ fprintf (stderr, "zero write\n");
+ exit (1);
+ }
+ len -= n;
+ str += n;
+ }
+}
+
+void
+fd_writeln (int fd, char const *str)
+{
+ fd_write (fd, str, strlen (str));
+ fd_write (fd, "\r\n", 2);
+}
+
+int
+fd_getc (int fd)
+{
+ char c;
+ ssize_t n = read (fd, &c, 1);
+ if (n == -1)
+ {
+ perror ("socket read");
+ exit (1);
+ }
+ if (n == 0)
+ c = EOF;
+ return c;
+}
+
+static void
+tcpmux_init (int fd, char const *service)
+{
+ int c;
+
+ fd_writeln (fd, service);
+
+ if (strcmp (service, "help") == 0)
+ {
+ while ((c = fd_getc (fd)) != EOF)
+ {
+ fputc (c, stdout);
+ }
+ close (fd);
+ exit (0);
+ }
+
+ c = fd_getc (fd);
+ if (c == 0)
+ {
+ fprintf (stderr, "socket read: unexpected eof\n");
+ exit (1);
+ }
+ if (c == '+')
+ {
+ while ((c = fd_getc (fd)) != '\n')
+ {
+ if (c == EOF)
+ {
+ fprintf (stderr, "socket read: unexpected eof\n");
+ exit (1);
+ }
+ }
+ }
+ else
+ {
+ fprintf (stderr, "service rejected: ");
+ do
+ {
+ if (c != '\r')
+ fputc (c, stderr);
+ }
+ while ((c = fd_getc (fd)) != 0 && c != '\n');
+ fputc ('\n', stderr);
+ exit (1);
+ }
+}
+
static int
-netcat (char const *urlstr)
+netcat (char const *urlstr, char const *tcpmux_service)
{
int fd;
struct pies_url *url;
struct pollfd pfd[3];
int nfd = sizeof (pfd) / sizeof (pfd[0]);
netcat_server_t *srvin, *srvout, *srv;
if (pies_url_create (&url, urlstr))
{
perror (urlstr);
return 64;
}
fd = url_connect (url, NULL);
if (fd == -1)
return 1;
+ if (tcpmux_service)
+ tcpmux_init (fd, tcpmux_service);
+
pfd[0].fd = 0;
pfd[0].events = 0;
srvin = netcat_server_create ("stdin", &pfd[0], POLLIN, disconnect_stdin, NULL);
pfd[1].fd = 1;
pfd[1].events = 0;
srvout = netcat_server_create ("stdout", &pfd[1], POLLOUT, disconnect_stdout, NULL);
pfd[2].fd = fd;
pfd[2].events = 0;
netcat_server_create ("netread", &pfd[2], POLLIN, disconnect_in, srvout);
@@ -256,43 +351,44 @@ netcat (char const *urlstr)
while (server_head)
{
ssize_t n = poll (pfd, nfd, -1);
if (n == -1)
{
if (errno != EINTR)
grecs_error (NULL, errno, "poll");
continue;
}
for (srv = server_head; srv; )
{
netcat_server_t *next = srv->next;
- int events;
- events = (srv->pollfd->events|POLLHUP)
- & (srv->pollfd->revents
- & (srv->state | ((srv->state & POLLOUT) ? POLLHUP : 0)));
- if (events)
+ if ((srv->pollfd->revents & srv->state) & POLLIN)
+ netcat_stream_read (srv);
+ if ((srv->pollfd->revents & srv->state) & POLLOUT)
+ netcat_stream_write (srv);
+ if ((srv->state & POLLOUT) && (srv->pollfd->revents & POLLHUP))
{
- 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);
+ }
+ if (srv->state == 0 || srv->pollfd->fd == -1)
+ {
+ netcat_server_t *peer = srv->peer;
+ if (peer && peer->pollfd->events == 0)
{
- //grecs_error (NULL, 0, "HUP on %s", srv->id);
- netcat_stream_disconnect (srv, srv->state);
+ netcat_stream_disconnect (peer, peer->state);
+ netcat_server_remove (peer);
}
+ netcat_server_remove (srv);
}
- if (srv->state == 0 || srv->pollfd->fd == -1)
- netcat_server_remove (srv);
srv = next;
}
}
return 0;
}
static void
redirect (int sfd, char const *name)
{
int fd;
fd = open (name, sfd ? (O_CREAT | O_TRUNC | O_WRONLY) : O_RDONLY, 0644);
@@ -302,50 +398,59 @@ redirect (int sfd, char const *name)
exit (1);
}
if (dup2 (fd, sfd) == -1)
{
perror ("dup2");
exit (1);
}
}
static void
usage (FILE *fp)
{
- fprintf (fp, "usage: nt [-i IFILE] [-o OFILE] URL\n");
+ fprintf (fp, "usage: nt [-i IFILE] [-o OFILE] [-t SERVICE] URL\n");
fprintf (fp, "Reads data from stdin (or IFILE) and sends them to URL.\n");
fprintf (fp, "Reads replies from URL and sends them to stdout (or OFILE).\n");
+ fprintf (fp, "\nOPTIONS\n\n");
+ fprintf (fp, " -t SERVICE use TCPMUX service\n");
+ fprintf (fp, " -i IFILE read input from IFILE\n");
+ fprintf (fp, " -o OFILE write output to OFILE\n");
}
int
main (int argc, char **argv)
{
int c;
+ char const *tcpmux_service = NULL;
- while ((c = getopt (argc, argv, "i:o:")) != EOF)
+ while ((c = getopt (argc, argv, "i:o:t:")) != EOF)
{
switch (c)
{
case 'i':
redirect (0, optarg);
break;
case 'o':
redirect (1, optarg);
break;
+ case 't':
+ tcpmux_service = optarg;
+ break;
+
default:
exit (64);
}
}
argc -= optind;
argv += optind;
if (argc != 1)
{
usage (stderr);
exit (64);
}
- return netcat (argv[0]);
+ return netcat (argv[0], tcpmux_service);
}

Return to:

Send suggestions and report system problems to the System administrator.