1 #!/bin/sh
   2 
   3 #
   4 # Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved.
   5 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   6 #
   7 # This code is free software; you can redistribute it and/or modify it
   8 # under the terms of the GNU General Public License version 2 only, as
   9 # published by the Free Software Foundation.
  10 #
  11 # This code is distributed in the hope that it will be useful, but WITHOUT
  12 # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13 # FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14 # version 2 for more details (a copy is included in the LICENSE file that
  15 # accompanied this code).
  16 #
  17 # You should have received a copy of the GNU General Public License version
  18 # 2 along with this work; if not, write to the Free Software Foundation,
  19 # Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20 #
  21 # Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22 # or visit www.oracle.com if you need additional information or have any
  23 # questions.
  24 #
  25 
  26 
  27 # Support functions to start, stop, wait for or kill a given SimpleApplication
  28 
  29 # Starts a given app as background process, usage:
  30 #   startApplication <class> port-file [args...]
  31 #
  32 # The following variables are set:
  33 #
  34 # appJavaPid  - application's Java pid
  35 # appOtherPid - pid associated with the app other than appJavaPid
  36 # appPidList  - all pids associated with the app
  37 # appOutput   - file containing stdout and stderr from the app
  38 #
  39 # Waits for at least one line of output from the app to indicate
  40 # that it is up and running.
  41 #
  42 startApplication()
  43 {
  44   appOutput="${TESTCLASSES}/Application.out"
  45 
  46   ${JAVA} -XX:+UsePerfData -classpath "${TESTCLASSES}" "$@" > "$appOutput" 2>&1 &
  47   appJavaPid="$!"
  48   appOtherPid=
  49   appPidList="$appJavaPid"
  50 
  51   echo "INFO: waiting for $1 to initialize..."
  52   _cnt=0
  53   while true; do
  54     # if the app doesn't start then the JavaTest/JTREG timeout will
  55     # kick in so this isn't really a endless loop
  56     sleep 1
  57     out=`tail -1 "$appOutput"`
  58     if [ -n "$out" ]; then
  59       # we got some output from the app so it's running
  60       break
  61     fi
  62     _cnt=`expr $_cnt + 1`
  63     echo "INFO: waited $_cnt second(s) ..."
  64   done
  65   unset _cnt
  66 
  67   if $isWindows; then
  68     # Windows requires special handling
  69     appOtherPid="$appJavaPid"
  70 
  71     if $isCygwin; then
  72       appJavaPid=`ps -p "$appOtherPid" \
  73         | sed -n '
  74           # See if $appOtherPid is in PID column; there are sometimes
  75           # non-blanks in column 1 (I and S observed so far)
  76           /^.'"${PATTERN_WS}${PATTERN_WS}*${appOtherPid}${PATTERN_WS}"'/{
  77             # strip PID column
  78             s/^.'"${PATTERN_WS}${PATTERN_WS}*${appOtherPid}${PATTERN_WS}${PATTERN_WS}"'*//
  79             # strip PPID column
  80             s/^[1-9][0-9]*'"${PATTERN_WS}${PATTERN_WS}"'*//
  81             # strip PGID column
  82             s/^[1-9][0-9]*'"${PATTERN_WS}${PATTERN_WS}"'*//
  83             # strip everything after WINPID column
  84             s/'"${PATTERN_WS}"'.*//
  85             p
  86             q
  87           }
  88         '`
  89       echo "INFO: Cygwin pid=$appOtherPid maps to Windows pid=$appJavaPid"
  90     else
  91       # show PID, PPID and COMM columns only
  92       appJavaPid=`ps -o pid,ppid,comm \
  93         | sed -n '
  94           # see if appOtherPid is in either PID or PPID columns
  95           /'"${PATTERN_WS}${appOtherPid}${PATTERN_WS}"'/{
  96             # see if this is a java command
  97             /java'"${PATTERN_EOL}"'/{
  98               # strip leading white space
  99               s/^'"${PATTERN_WS}${PATTERN_WS}"'*//
 100               # strip everything after the first word
 101               s/'"${PATTERN_WS}"'.*//
 102               # print the pid and we are done
 103               p
 104               q
 105             }
 106           }
 107         '`
 108       echo "INFO: MKS shell pid=$appOtherPid; Java pid=$appJavaPid"
 109     fi
 110 
 111     if [ -z "$appJavaPid" ]; then
 112       echo "ERROR: could not find app's Java pid." >&2
 113       killApplication
 114       exit 2
 115     fi
 116     appPidList="$appOtherPid $appJavaPid"
 117   fi
 118 
 119   echo "INFO: $1 is process $appJavaPid"
 120   echo "INFO: $1 output is in $appOutput"
 121 }
 122 
 123 
 124 # Stops a simple application by invoking ShutdownSimpleApplication
 125 # class with a specific port-file, usage:
 126 #   stopApplication port-file
 127 #
 128 # Note: When this function returns, the SimpleApplication (or a subclass)
 129 # may still be running because the application has not yet reached the
 130 # shutdown check.
 131 #
 132 stopApplication()
 133 {
 134   $JAVA -XX:+UsePerfData -classpath "${TESTCLASSES}" ShutdownSimpleApplication $1
 135 }
 136 
 137 
 138 # Wait for a simple application to stop running.
 139 #
 140 waitForApplication() {
 141   if [ $isWindows = false ]; then
 142     # non-Windows is easy; just one process
 143     echo "INFO: waiting for $appJavaPid"
 144     set +e
 145     wait "$appJavaPid"
 146     set -e
 147 
 148   elif $isCygwin; then
 149     # Cygwin pid and not the Windows pid
 150     echo "INFO: waiting for $appOtherPid"
 151     set +e
 152     wait "$appOtherPid"
 153     set -e
 154 
 155   else # implied isMKS
 156     # MKS has intermediate shell and Java process
 157     echo "INFO: waiting for $appJavaPid"
 158 
 159     # appJavaPid can be empty if pid search in startApplication() failed
 160     if [ -n "$appJavaPid" ]; then
 161       # only need to wait for the Java process
 162       set +e
 163       wait "$appJavaPid"
 164       set -e
 165     fi
 166   fi
 167 }
 168 
 169 
 170 # Kills a simple application by sending a SIGTERM to the appropriate
 171 # process(es); on Windows SIGQUIT (-9) is used.
 172 #
 173 killApplication()
 174 {
 175   if [ $isWindows = false ]; then
 176     # non-Windows is easy; just one process
 177     echo "INFO: killing $appJavaPid"
 178     set +e
 179     kill -TERM "$appJavaPid"  # try a polite SIGTERM first
 180     sleep 2
 181     # send SIGQUIT (-9) just in case SIGTERM didn't do it
 182     # but don't show any complaints
 183     kill -QUIT "$appJavaPid" > /dev/null 2>&1
 184     wait "$appJavaPid"
 185     set -e
 186 
 187   elif $isCygwin; then
 188     # Cygwin pid and not the Windows pid
 189     echo "INFO: killing $appOtherPid"
 190     set +e
 191     kill -9 "$appOtherPid"
 192     wait "$appOtherPid"
 193     set -e
 194 
 195   else # implied isMKS
 196     # MKS has intermediate shell and Java process
 197     echo "INFO: killing $appPidList"
 198     set +e
 199     kill -9 $appPidList
 200     set -e
 201 
 202     # appJavaPid can be empty if pid search in startApplication() failed
 203     if [ -n "$appJavaPid" ]; then
 204       # only need to wait for the Java process
 205       set +e
 206       wait "$appJavaPid"
 207       set -e
 208     fi
 209   fi
 210 }