[ovs-dev] [PATCH 2/3] tests: Use Linux-specific way to get parent PID, to avoid noncompliant "ps".

Ben Pfaff blp at ovn.org
Thu Sep 29 21:41:50 UTC 2016


POSIX defines "ps" -o and -p options, but the "ps" implementation in
busybox (used in Alpine Linux) doesn't support -p, which makes some tests
fail for no good reason.  Therefore, this commit makes the testsuite
instead check for support for the Linux-specific /proc-based way to find
the parent of a process and prefer that over "ps" when available.

Reported-by: Stuart Cardall <developer at it-offshore.co.uk>
Reported-at: http://openvswitch.org/pipermail/discuss/2016-September/022803.html
Signed-off-by: Ben Pfaff <blp at ovn.org>
---
 tests/daemon-py.at  | 16 ++++++++--------
 tests/daemon.at     | 12 ++++++------
 tests/ovs-macros.at | 14 ++++++++++++++
 3 files changed, 28 insertions(+), 14 deletions(-)

diff --git a/tests/daemon-py.at b/tests/daemon-py.at
index 11833c8..a32762b 100644
--- a/tests/daemon-py.at
+++ b/tests/daemon-py.at
@@ -40,7 +40,7 @@ m4_define([DAEMON_MONITOR_PYN],
    # Check that the pidfile names a running process,
    # and that the parent process of that process is our child process.
    AT_CHECK([kill -0 `cat pid`], [0], [], [], [kill `cat parent`])
-   AT_CHECK([ps -o ppid= -p `cat pid` > parentpid],
+   AT_CHECK([parent_pid `cat pid` > parentpid],
      [0], [], [], [kill `cat parent`])
    AT_CHECK(
      [parentpid=`cat parentpid` &&
@@ -57,7 +57,7 @@ m4_define([DAEMON_MONITOR_PYN],
    AT_CHECK([cp pid newpid], [0], [], [], [kill `cat parent`])
    # Check that the pidfile names a running process,
    # and that the parent process of that process is our child process.
-   AT_CHECK([ps -o ppid= -p `cat pid` > parentpid],
+   AT_CHECK([parent_pid `cat pid` > parentpid],
      [0], [], [], [kill `cat parent`])
    AT_CHECK(
      [parentpid=`cat parentpid` &&
@@ -89,7 +89,7 @@ m4_define([DAEMON_MONITOR_RESTART_PYN],
    # Check that the pidfile names a running process,
    # and that the parent process of that process is our child process.
    AT_CHECK([kill -0 `cat pid`], [0], [], [], [kill `cat parent`])
-   AT_CHECK([ps -o ppid= -p `cat pid` > parentpid],
+   AT_CHECK([parent_pid `cat pid` > parentpid],
      [0], [], [], [kill `cat parent`])
    AT_CHECK(
      [parentpid=`cat parentpid` &&
@@ -106,7 +106,7 @@ m4_define([DAEMON_MONITOR_RESTART_PYN],
    AT_CHECK([cp pid newpid], [0], [], [], [kill `cat parent`])
    # Check that the pidfile names a running process,
    # and that the parent process of that process is our child process.
-   AT_CHECK([ps -o ppid= -p `cat pid` > parentpid],
+   AT_CHECK([parent_pid `cat pid` > parentpid],
      [0], [], [], [kill `cat parent`])
    AT_CHECK(
      [parentpid=`cat parentpid` &&
@@ -167,9 +167,9 @@ m4_define([DAEMON_DETACH_MONITOR_PYN],
    # and that the parent process of that process is a running process,
    # and that the parent process of that process is init.
    CHECK([kill -0 `cat daemon`])
-   CHECK([ps -o ppid= -p `cat daemon` > monitor])
+   CHECK([parent_pid `cat daemon` > monitor])
    CHECK([kill -0 `cat monitor`])
-   CHECK([ps -o ppid= -p `cat monitor` > init])
+   CHECK([parent_pid `cat monitor` > init])
    CHECK([test `cat init` != $$])
    # Kill the daemon process, making it look like a segfault,
    # and wait for a new daemon process to get spawned.
@@ -183,10 +183,10 @@ m4_define([DAEMON_DETACH_MONITOR_PYN],
    # and that the parent process of that process is our child process.
    CHECK([kill -0 `cat daemon`])
    CHECK([diff olddaemon newdaemon], [1], [ignore])
-   CHECK([ps -o ppid= -p `cat daemon` > newmonitor])
+   CHECK([parent_pid `cat daemon` > newmonitor])
    CHECK([diff monitor newmonitor])
    CHECK([kill -0 `cat newmonitor`])
-   CHECK([ps -o ppid= -p `cat newmonitor` > init])
+   CHECK([parent_pid `cat newmonitor` > init])
    CHECK([test `cat init` != $$])
    # Kill the daemon process with SIGTERM, and wait for the daemon
    # and the monitor processes to go away and the pidfile to get deleted.
diff --git a/tests/daemon.at b/tests/daemon.at
index cf95cde..817d9fe 100644
--- a/tests/daemon.at
+++ b/tests/daemon.at
@@ -41,7 +41,7 @@ OVS_WAIT_UNTIL([test -s pid], [kill `cat parent`])
 # Check that the pidfile names a running process,
 # and that the parent process of that process is our child process.
 AT_CHECK([kill -0 `cat pid`], [0], [], [], [kill `cat parent`])
-AT_CHECK([ps -o ppid= -p `cat pid` > parentpid],
+AT_CHECK([parent_pid `cat pid` > parentpid],
   [0], [], [], [kill `cat parent`])
 AT_CHECK(
   [parentpid=`cat parentpid` && 
@@ -63,7 +63,7 @@ OVS_WAIT_UNTIL([test -s pid && test `cat pid` != `cat oldpid`],
 AT_CHECK([cp pid newpid], [0], [], [], [kill `cat parent`])
 # Check that the pidfile names a running process,
 # and that the parent process of that process is our child process.
-AT_CHECK([ps -o ppid= -p `cat pid` > parentpid],
+AT_CHECK([parent_pid `cat pid` > parentpid],
   [0], [], [], [kill `cat parent`])
 AT_CHECK(
   [parentpid=`cat parentpid` && 
@@ -120,9 +120,9 @@ AT_CHECK([test -s daemon])
 # and that the parent process of that process is a running process,
 # and that the parent process of that process is init.
 CHECK([kill -0 `cat daemon`])
-CHECK([ps -o ppid= -p `cat daemon` > monitor])
+CHECK([parent_pid `cat daemon` > monitor])
 CHECK([kill -0 `cat monitor`])
-CHECK([ps -o ppid= -p `cat monitor` > init])
+CHECK([parent_pid `cat monitor` > init])
 CHECK([test `cat init` != $$])
 # Kill the daemon process, making it look like a segfault,
 # and wait for a new daemon process to get spawned.
@@ -136,10 +136,10 @@ CHECK([cp daemon newdaemon])
 # and that the parent process of that process is our child process.
 CHECK([kill -0 `cat daemon`])
 CHECK([diff olddaemon newdaemon], [1], [ignore])
-CHECK([ps -o ppid= -p `cat daemon` > newmonitor])
+CHECK([parent_pid `cat daemon` > newmonitor])
 CHECK([diff monitor newmonitor])
 CHECK([kill -0 `cat newmonitor`])
-CHECK([ps -o ppid= -p `cat newmonitor` > init])
+CHECK([parent_pid `cat newmonitor` > init])
 CHECK([test `cat init` != $$])
 # Kill the daemon process with SIGTERM, and wait for the daemon
 # and the monitor processes to go away and the pidfile to get deleted.
diff --git a/tests/ovs-macros.at b/tests/ovs-macros.at
index fadd2be..f3b7c36 100644
--- a/tests/ovs-macros.at
+++ b/tests/ovs-macros.at
@@ -99,6 +99,20 @@ if test "$IS_WIN32" = "yes"; then
         return $retval
     }
 fi
+
+# parent_pid PID
+#
+# Prints the PID of the parent of process PID.
+parent_pid () {
+    # Using "ps" is portable to any POSIX system, but busybox "ps" (used in
+    # e.g. Alpine Linux) is noncompliant, so we use a Linux-specific approach
+    # when it's available.
+    if test ! -e /proc/$1/status; then
+        ps -o ppid= -p $1
+    else
+        sed -n 's/^PPid:	\([0-9]*\)/\1/p' /proc/$1/status
+    fi
+}
 ]
 m4_divert_pop([PREPARE_TESTS])
 
-- 
2.1.3




More information about the dev mailing list