[PATCH 1/2] new routines for socket based synchronisation

Hubert Kario hkario at redhat.com
Tue Nov 19 14:49:10 UTC 2013


Add new function, rlWaitForSocket, that can wait for a network service
to start. To be used instead of `sleep' when testing network-centric
services.

Signed-off-by: Hubert Kario <hkario at redhat.com>
---
is the fatal error handling OK?

 src/synchronisation.sh | 182 +++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 182 insertions(+)
 create mode 100644 src/synchronisation.sh

diff --git a/src/synchronisation.sh b/src/synchronisation.sh
new file mode 100644
index 0000000..66078e3
--- /dev/null
+++ b/src/synchronisation.sh
@@ -0,0 +1,182 @@
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+#
+#   Name: synchronisation.sh - part of the BeakerLib project
+#   Description: Process synchronisation routines
+#
+#   Author: Hubert Kario <hkario at redhat.com>
+#
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+#
+#   Copyright (c) 2013 Red Hat, Inc. All rights reserved.
+#
+#   This copyrighted material is made available to anyone wishing
+#   to use, modify, copy, or redistribute it subject to the terms
+#   and conditions of the GNU General Public License version 2.
+#
+#   This program 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 this program; if not, write to the Free
+#   Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+#   Boston, MA 02110-1301, USA.
+#
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+getopt -T || ret=$?
+if [ ${ret:-0} -ne 4 ]; then
+    echo "ERROR: Non enhanced getopt version detected" 1>&2
+    exit 1
+fi
+
+: <<'=cut'
+=pod
+
+=head1 NAME
+
+BeakerLib - synchronisation - Process synchronisation routines
+
+=head1 DESCRIPTION
+
+This is a library of helpers for process synchronisation
+of applications.
+
+=head1 FUNCTIONS
+
+=cut
+
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# name of routine
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+: <<'=cut'
+=pod
+
+=head2 Process Synchronisation
+
+=head3 rlWaitForSocket
+
+Pauses script execution until socket starts listening.
+
+    rlWaitForSocket {port|path} [-p PID] [-t time]
+
+=over
+
+=item port|path
+
+Network port to wait for opening or a path to UNIX socket.
+Regular expressions are also supported.
+
+=item -t time
+
+Timeout in seconds (optional, default=120). If the socket
+isn't opened between the time elapses the command FAILs.
+
+=item -p PID
+
+PID of the process to check before running command. If the process
+exits before the socket is opened, the command FAILs.
+
+=back
+
+=cut
+
+rlWaitForSocket(){
+
+    local timeout=120
+    local proc_pid=1
+    local socket=""
+    local child_pid=0
+
+    # that is the GNU extended getopt syntax!
+    TEMP=$(getopt -o t:p: -n 'rlWaitForSocket' -- "$@")
+    if [[ $? != 0 ]] ; then echo "Terminating..." >&2 ; exit 1 ; fi
+
+    eval set -- "$TEMP"
+
+    while true ; do
+        case "$1" in
+            -t) timeout="$2"; shift 2
+                ;;
+            -p) proc_pid="$2"; shift 2
+                ;;
+            --) shift 1
+                break
+                ;;
+            *) echo "Internal error!" >&2; exit 1
+                ;;
+        esac
+    done
+    socket="$1"
+    # the case statement is a portable way to check if variable contains only
+    # digits (regexps are not available in old, RHEL3-era, bash)
+    case "$timeout" in
+        ''|*[!0-9]*) echo "rlWaitForSocket: Invalid timeout provided" 1>&2; exit 1;;
+    esac
+    case "$proc_pid" in
+        ''|*[!0-9]*) echo "rlWaitForSocket: Invalid PID provided" 1>&2; exit 1;;
+    esac
+    case "$socket" in
+        ''|*[!0-9]*)
+            #socket_type="network"
+            grep_opt="\:$socket[[:space:]]"
+            ;;
+        "") echo "rlWaitForSocket: Empty socket specified" 1>&2
+            exit 1
+            ;;
+        *)
+            #socket_type="unix"
+            grep_opt="$socket"
+            ;;
+    esac
+    rlLog "Waiting max ${timeout}s for socket \`$socket' to start listening"
+
+    ( while true ; do
+        netstat -nl | grep -E "$grep_opt" >/dev/null
+        if [[ $? -eq 0 ]]; then
+            exit 0;
+        else
+            if [[ ! -e "/proc/$proc_pid" ]]; then
+                exit 1;
+            fi
+            sleep 1
+        fi
+    done ) &
+    netstat_pid=$!
+
+    ( sleep $timeout && kill -HUP $netstat_pid ) 2>/dev/null &
+    watcher=$!
+
+    wait $netstat_pid
+    ret=$?
+    if [[ $ret -eq 0 ]]; then
+        kill -s SIGKILL $watcher 2>/dev/null
+        rlLog "Socket opened!"
+    else
+        if [[ $ret -eq 1 ]]; then
+            kill -s SIGKILL $watcher 2>/dev/null
+            rlLogWarning "PID terminated!"
+        else
+            rlLogWarning "Timeout elapsed"
+        fi
+    fi
+}
+
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# AUTHORS
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+: <<'=cut'
+=pod
+
+=head1 AUTHORS
+
+=over
+
+=item *
+
+Hubert Kario <hkario at redhat.com>
+
+=back
+
+=cut
-- 
1.8.3.1



More information about the beakerlib-devel mailing list