From bf6506cdc46446eada5090a428c2407ebd17468a Mon Sep 17 00:00:00 2001 From: Sergey Poznyakoff Date: Tue, 11 Jun 2019 12:54:02 +0300 Subject: Improve the nt tool. Test inet running instance limit. * tests/Makefile.am: Add new test. * tests/aux/in.test (PIESCTL): Provide the necessary options. Discontinue the use of STOPCMD environment variable. New commands: enable, sleep, touch. * tests/testsuite.at (PIES_CONTROL_INIT): Rename pidfile to PIES_PIDFILE and ctlsock to PIES_CTLSOCK. Export both. Include maxinst.at * tests/control.at: Use new variables. * tests/inet.at: Remove the env block. * tests/iobuf.h (iobuf_copy): Return number of bytes copied. * tests/maxinst.at: New file. * tests/nt.c (netcat_stream_disconnect): New function. (netcat_stream_read): Disconnect the peer stream if no more input is available and the peer is not available for output (i.e. its output buffer is empty). (netcat_stream_write): Stop polling if output buffer is empty. (netcat): Fix event mask --- tests/Makefile.am | 1 + tests/aux/in.test | 19 ++++++++----- tests/control.at | 11 ++++---- tests/inet.at | 18 ++++++++++--- tests/iobuf.h | 2 +- tests/maxinst.at | 78 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ tests/nt.c | 62 +++++++++++++++++++++++++------------------ tests/testsuite.at | 16 ++++++----- 8 files changed, 159 insertions(+), 48 deletions(-) create mode 100644 tests/maxinst.at (limited to 'tests') diff --git a/tests/Makefile.am b/tests/Makefile.am index 0290f61..fa1d6be 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -54,6 +54,7 @@ TESTSUITE_AT = \ env.at\ envop.at\ inet.at\ + maxinst.at\ respawn.at\ redirect.at\ ret-exec.at\ diff --git a/tests/aux/in.test b/tests/aux/in.test index 4a98763..1fae034 100755 --- a/tests/aux/in.test +++ b/tests/aux/in.test @@ -3,16 +3,23 @@ FILE=${1:?} IFS=' ' +: ${PIESCTL:=piesctl} +PIESCTL="$PIESCTL --no-netrc${PIES_CTLSOCK:+ --url=}$PIES_CTLSOCK" while read COMMAND ARG do echo $COMMAND $ARG >> $FILE case $COMMAND in - stop) if [ -n "$STOPCMD" ]; then - echo "STOP" - $STOPCMD - else - echo "OK $COMMAND $ARG" - fi + stop) echo "OK shutting down" + $PIESCTL shutdown + ;; + enable) + $PIESCTL start component ${ARG:?component name not supplied} + ;; + sleep) + sleep ${ARG:-1} + ;; + touch) + touch ${ARG:?touch argument required} ;; quit) exit $ARG;; *) echo "OK $COMMAND $ARG" diff --git a/tests/control.at b/tests/control.at index 8814b30..3d0c218 100644 --- a/tests/control.at +++ b/tests/control.at @@ -23,13 +23,14 @@ PIES_CONTROL_INIT pies --config-file control.conf sleep 1 -if test -f $pidfile; then - pid0=`head -1 $pidfile` - pid1=`piesctl --url "$ctlsock" id PID|sed 's/^PID: //'` +PIESCTL="piesctl --no-netrc --url '$PIES_CTLSOCK'" +if test -f $PIES_PIDFILE; then + pid0=`head -1 $PIES_PIDFILE` + pid1=`$PIESCTL id PID|sed 's/^PID: //'` if test "$pid1" = "$pid0"; then - if piesctl --url "$ctlsock" shutdown; then + if $PIESCTL shutdown; then sleep 1 - if test -f $pidfile; then + if test -f $PIES_PIDFILE; then PIES_XFAIL_MSG([pies does not respond to control commands]) kill -9 $pid0 exit 1 diff --git a/tests/inet.at b/tests/inet.at index 41cae6a..893e45f 100644 --- a/tests/inet.at +++ b/tests/inet.at @@ -1,3 +1,18 @@ +# 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 . AT_SETUP([inet component]) AT_CHECK([ PIES_XFAIL_CHECK @@ -11,9 +26,6 @@ stop cat > pies.conf <<_EOT component in { command "$auxdir/in.test $PWD/inlog"; - env { - set "STOPCMD=piesctl --url unix:///$PWD/pies.ctl --no-netrc shutdown"; - } mode inetd; socket "$PIES_TEST_INET_SOCKET"; stderr file "$PWD/log.err"; diff --git a/tests/iobuf.h b/tests/iobuf.h index 4e43338..737a8b7 100644 --- a/tests/iobuf.h +++ b/tests/iobuf.h @@ -135,7 +135,7 @@ iobuf_copy (struct iobuf *dst, struct iobuf *src) iobuf_data_advance (src, n); } } - return 0; + return n; } diff --git a/tests/maxinst.at b/tests/maxinst.at new file mode 100644 index 0000000..f67d15e --- /dev/null +++ b/tests/maxinst.at @@ -0,0 +1,78 @@ +# This file is part of GNU pies testsuite. -*- Autotest -*- +# 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 . + +AT_SETUP([inet component: max instances]) +AT_CHECK([ +PIES_XFAIL_CHECK +PIES_CONTROL_INIT + +AT_DATA([in1], +[test +enable con2 +sleep 10 +quit +]) + +AT_DATA([in2], +[test +enable con3 +sleep 10 +quit +]) + +: ${PIES_TEST_INET_SOCKET:=unix://$PWD/in.sock} + +cat > pies.conf <<_EOT +component in { + command "$auxdir/in.test /tmp/in.log"; + mode inetd; + socket "$PIES_TEST_INET_SOCKET"; + stderr file "$PWD/in.err"; + max-instances 2; + max-instances-message "too many instances running\n"; +} +component con1 { + command "nt $PIES_TEST_INET_SOCKET -i in1 -o con1.out"; + stderr file "/tmp/con1.err"; +} +component con2 { + command "nt $PIES_TEST_INET_SOCKET -i in2 -o con2.out"; + stderr file "/tmp/con2.err"; + flags (disable); +} +component con3 { + flags (disable); + command "nt $PIES_TEST_INET_SOCKET -o con3.out"; + stderr file "/tmp/con3.err"; + return-code * { + action disable; + exec "$abs_top_builddir/src/piesctl --url unix://$PWD/pies.ctl --no-netrc shutdown"; + } +} +_EOT + +set -e +to 10 \ + pies --foreground --stderr \ + --config-file control.conf --config-file pies.conf --debug 1 2>errlog + +cat con3.out +], +[0], +[too many instances running +]) + +AT_CLEANUP diff --git a/tests/nt.c b/tests/nt.c index 7501586..d30e447 100644 --- a/tests/nt.c +++ b/tests/nt.c @@ -107,29 +107,49 @@ stdin_reader (same as net_reader) net_writer (peer -> stdin_reader) same as stdout_writer */ +static inline int +peer_is_state (netcat_server_t *srv, int state) +{ + return srv->peer && (srv->peer->state & state); +} + +static void +netcat_stream_disconnect (netcat_server_t *srv, int mask) +{ + srv->disconnect (srv); + srv->state &= ~mask; + srv->pollfd->events &= ~mask; + if (srv->pollfd->events == 0) + srv->pollfd->fd = -1; +} + 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; return -1; } - if (n == 0) + if (n == 0 || !peer_is_state (srv, POLLOUT)) { - /* No more input is expected */ - srv->disconnect (srv); - srv->state &= ~POLLIN; - srv->pollfd->events &= ~POLLIN; - if (srv->pollfd->events == 0) - srv->pollfd->fd = -1; + /* No more input is expected || needed */ + netcat_stream_disconnect (srv, POLLIN); + + if (srv->peer) + netcat_stream_disconnect (srv->peer, POLLOUT); + return 0; } + else + srv->peer->pollfd->events |= POLLOUT; } else { @@ -139,12 +159,6 @@ netcat_stream_read (netcat_server_t *srv) return n; } -static inline int -peer_is_state (netcat_server_t *srv, int state) -{ - return srv->peer && (srv->peer->state & state); -} - ssize_t netcat_stream_write (netcat_server_t *srv) { @@ -155,22 +169,21 @@ netcat_stream_write (netcat_server_t *srv) if (!peer_is_state (srv, POLLIN)) { // shutdown write end - srv->disconnect (srv); - srv->state &= ~POLLOUT; - srv->pollfd->events &= ~POLLOUT; - if (srv->pollfd->events == 0) - srv->pollfd->fd = -1; + netcat_stream_disconnect (srv, POLLOUT); return -1; } if (iobuf_copy (&srv->buf[OUT], &srv->peer->buf[IN]) == 0) { 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); return -1; } @@ -253,19 +266,16 @@ netcat (char const *urlstr) { netcat_server_t *next = srv->next; int events; - + events = (srv->pollfd->events|POLLHUP) - & (srv->pollfd->revents & (srv->state|POLLHUP)); + & (srv->pollfd->revents + & (srv->state | ((srv->state & POLLOUT) ? POLLHUP : 0))); if (events) { if (events & POLLHUP) { //grecs_error (NULL, 0, "HUP on %s", srv->id); - srv->disconnect (srv); - srv->pollfd->events &= ~srv->state; - if (srv->pollfd->events == 0) - srv->pollfd->fd = -1; - srv->state = 0; + netcat_stream_disconnect (srv, srv->state); } else if (events & POLLIN) netcat_stream_read (srv); diff --git a/tests/testsuite.at b/tests/testsuite.at index 822ac7b..0682b51 100644 --- a/tests/testsuite.at +++ b/tests/testsuite.at @@ -28,25 +28,26 @@ _EOT m4_define([PIES_XFAIL_CHECK],[AT_XFAIL_IF([test -f $[]XFAILFILE])]) m4_define([PIES_CONTROL_INIT],[ -pidfile="$PWD/pies.pid" -ctlsock="unix://$PWD/pies.ctl"; +PIES_PIDFILE="$PWD/pies.pid" +PIES_CTLSOCK="unix://$PWD/pies.ctl"; +export PIES_PIDFILE PIES_CTLSOCK cat > control.conf <<_EOT -pidfile "$pidfile"; +pidfile "$PIES_PIDFILE"; control { - socket "$ctlsock"; + socket "$PIES_CTLSOCK"; } _EOT ]) m4_define([PIES_STOP],[ -piesctl --url "$ctlsock" shutdown +piesctl --url "$PIES_CTLSOCK" shutdown pies_stop_spinner=0 -while test -f $pidfile +while test -f $PIES_PIDFILE do sleep 1 pies_stop_spinner=$(($pies_stop_spinner + 1)) if test $pies_stop_spinner -gt 3; then - kill `cat $pidfile` + kill `cat $PIES_PIDFILE` echo >&2 "timed out waiting for shutdown" fi done]) @@ -69,6 +70,7 @@ m4_include([startup.at]) m4_include([shutdown.at]) m4_include([shell.at]) m4_include([inet.at]) +m4_include([maxinst.at]) m4_include([envop.at]) m4_include([env.at]) \ No newline at end of file -- cgit v1.2.1