提交 247d1114 编写于 作者: D dcubed

6964018: 3/4 AnonLoggerWeakRefLeak and LoggerWeakRefLeak can fail in JPRT

Summary: Refactor test/sun/tools/common/* code and refactor AnonLoggerWeakRefLeak and LoggerWeakRefLeak to use it.
Reviewed-by: ohair, alanb
上级 c3024ec5
......@@ -23,24 +23,32 @@
import java.util.logging.*;
public class AnonLoggerWeakRefLeak {
public static int DEFAULT_LOOP_TIME = 60; // time is in seconds
public class AnonLoggerWeakRefLeak extends SimpleApplication {
// The test driver script will allow this program to run until we
// reach DEFAULT_LOOP_TIME or a decrease in instance counts is
// observed. For this particular WeakReference leak, the count
// was always observed to be increasing so if we get a decreasing
// count, then the leak is fixed in the bits being tested.
// Two minutes has been enough time to observe a decrease in
// fixed bits on overloaded systems, but the test will likely
// finish more quickly.
public static int DEFAULT_LOOP_TIME = 120; // time is in seconds
public static void main(String[] args) {
// execute the AnonLoggerWeakRefLeak app work
public void doMyAppWork(String[] args) throws Exception {
int loop_time = 0;
int max_loop_time = DEFAULT_LOOP_TIME;
if (args.length == 0) {
// args[0] is the port-file
if (args.length < 2) {
System.out.println("INFO: using default time of "
+ max_loop_time + " seconds.");
} else {
try {
max_loop_time = Integer.parseInt(args[0]);
max_loop_time = Integer.parseInt(args[1]);
} catch (NumberFormatException nfe) {
System.err.println("Error: '" + args[0]
throw new RuntimeException("Error: '" + args[1]
+ "': is not a valid seconds value.");
System.err.println("Usage: AnonLoggerWeakRefLeak [seconds]");
System.exit(1);
}
}
......@@ -73,4 +81,12 @@ public class AnonLoggerWeakRefLeak {
System.out.println("INFO: final loop count = " + count);
}
public static void main(String[] args) throws Exception {
AnonLoggerWeakRefLeak myApp = new AnonLoggerWeakRefLeak();
SimpleApplication.setMyApp(myApp);
SimpleApplication.main(args);
}
}
#!/bin/sh
#
# Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
......@@ -23,76 +25,24 @@
# @test
# @bug 6942989
# @ignore until 6964018 is fixed
# @summary Check for WeakReference leak in anonymous Logger objects
# @author Daniel D. Daugherty
#
# @run build AnonLoggerWeakRefLeak
# @run shell/timeout=180 AnonLoggerWeakRefLeak.sh
# @library ../../../sun/tools/common
# @build SimpleApplication ShutdownSimpleApplication
# @build AnonLoggerWeakRefLeak
# @run shell/timeout=240 AnonLoggerWeakRefLeak.sh
# The timeout is: 2 minutes for infrastructure and 1 minute for the test
# The timeout is: 2 minutes for infrastructure and 2 minutes for the test
#
if [ "${TESTJAVA}" = "" ]
then
echo "TESTJAVA not set. Test cannot execute. Failed."
exit 1
fi
if [ "${TESTSRC}" = "" ]
then
echo "TESTSRC not set. Test cannot execute. Failed."
exit 1
fi
if [ "${TESTCLASSES}" = "" ]
then
echo "TESTCLASSES not set. Test cannot execute. Failed."
exit 1
fi
JAVA="${TESTJAVA}"/bin/java
JMAP="${TESTJAVA}"/bin/jmap
JPS="${TESTJAVA}"/bin/jps
. ${TESTSRC}/../../../sun/tools/common/CommonSetup.sh
. ${TESTSRC}/../../../sun/tools/common/ApplicationSetup.sh
set -eu
TEST_NAME="AnonLoggerWeakRefLeak"
TARGET_CLASS="java\.lang\.ref\.WeakReference"
is_cygwin=false
is_mks=false
is_windows=false
case `uname -s` in
CYGWIN*)
is_cygwin=true
is_windows=true
;;
Windows_*)
is_mks=true
is_windows=true
;;
*)
;;
esac
# wrapper for grep
#
grep_cmd() {
set +e
if $is_windows; then
# need dos2unix to get rid of CTRL-M chars from java output
dos2unix | grep "$@"
status="$?"
else
grep "$@"
status="$?"
fi
set -e
}
# MAIN begins here
#
......@@ -105,62 +55,39 @@ fi
# see if this version of jmap supports the '-histo:live' option
jmap_option="-histo:live"
set +e
"${JMAP}" "$jmap_option" 0 > "$TEST_NAME.jmap" 2>&1
grep '^Usage: ' "$TEST_NAME.jmap" > /dev/null 2>&1
"${JMAP}" 2>&1 | grep ':live' > /dev/null 2>&1
status="$?"
set -e
if [ "$status" = 0 ]; then
if [ "$status" != 0 ]; then
echo "INFO: switching jmap option from '$jmap_option'\c"
jmap_option="-histo"
echo " to '$jmap_option'."
fi
"${JAVA}" ${TESTVMOPTS} -classpath "${TESTCLASSES}" \
"$TEST_NAME" $seconds > "$TEST_NAME.log" 2>&1 &
test_pid="$!"
echo "INFO: starting $TEST_NAME as pid = $test_pid"
# Start application and use TEST_NAME.port for coordination
startApplication "$TEST_NAME" "$TEST_NAME.port" $seconds
# wait for test program to get going
count=0
while [ "$count" -lt 30 ]; do
sleep 2
grep_cmd '^INFO: call count = 0$' < "$TEST_NAME.log" > /dev/null 2>&1
if [ "$status" = 0 ]; then
break
fi
count=`expr $count + 1`
done
if [ "$count" -ge 30 ]; then
echo "ERROR: $TEST_NAME failed to get going." >&2
echo "INFO: killing $test_pid"
kill "$test_pid"
exit 1
elif [ "$count" -gt 1 ]; then
echo "INFO: $TEST_NAME took $count loops to start."
fi
if $is_cygwin; then
# We need the Windows pid for jmap and not the Cygwin pid.
# Note: '\t' works on Cygwin, but doesn't seem to work on Solaris.
jmap_pid=`"${JPS}"| grep_cmd "[ \t]$TEST_NAME$" | sed 's/[ \t].*//'`
if [ -z "$jmap_pid" ]; then
echo "FAIL: jps could not map Cygwin pid to Windows pid." >&2
echo "INFO: killing $test_pid"
kill "$test_pid"
exit 2
fi
echo "INFO: pid = $test_pid maps to Windows pid = $jmap_pid"
else
jmap_pid="$test_pid"
fi
finished_early=false
decreasing_cnt=0
increasing_cnt=0
loop_cnt=0
prev_instance_cnt=0
MAX_JMAP_TRY_CNT=10
jmap_retry_cnt=0
loop_cnt_on_retry=0
while true; do
# see if the target process has finished its run and bail if it has
set +e
grep "^INFO: final loop count = " "$appOutput" > /dev/null 2>&1
status="$?"
set -e
if [ "$status" = 0 ]; then
break
fi
# Output format for 'jmap -histo' in JDK1.5.0:
#
# <#bytes> <#instances> <class_name>
......@@ -170,38 +97,70 @@ while true; do
# <num>: <#instances> <#bytes> <class_name>
#
set +e
"${JMAP}" "$jmap_option" "$jmap_pid" > "$TEST_NAME.jmap" 2>&1
"${JMAP}" "$jmap_option" "$appJavaPid" > "$TEST_NAME.jmap" 2>&1
status="$?"
set -e
if [ "$status" != 0 ]; then
echo "INFO: jmap exited with exit code = $status"
if [ "$loop_cnt" = 0 ]; then
echo "INFO: on the first iteration so no samples were taken."
echo "INFO: start of jmap output:"
cat "$TEST_NAME.jmap"
echo "INFO: end of jmap output."
# There are intermittent jmap failures; see 6498448.
#
# So far the following have been observed in a jmap call
# that was not in a race with target process termination:
#
# (Solaris specific, 2nd sample)
# <pid>: Unable to open door: target process not responding or HotSpot VM not loaded
# The -F option can be used when the target process is not responding
#
# (on Solaris so far)
# java.io.IOException
#
# (on Solaris so far, 1st sample)
# <pid>: Permission denied
#
sed 's/^/INFO: /' "$TEST_NAME.jmap"
if [ "$loop_cnt" = "$loop_cnt_on_retry" ]; then
# loop count hasn't changed
jmap_retry_cnt=`expr $jmap_retry_cnt + 1`
else
# loop count has changed so remember it
jmap_retry_cnt=1
loop_cnt_on_retry="$loop_cnt"
fi
# This is '-ge' because we have the original attempt plus
# MAX_JMAP_TRY_CNT - 1 retries.
if [ "$jmap_retry_cnt" -ge "$MAX_JMAP_TRY_CNT" ]; then
echo "INFO: jmap failed $MAX_JMAP_TRY_CNT times in a row" \
"without making any progress."
echo "FAIL: jmap is unable to take any samples." >&2
echo "INFO: killing $test_pid"
kill "$test_pid"
killApplication
exit 2
fi
echo "INFO: The likely reason is that $TEST_NAME has finished running."
break
# short delay and try again
# Note: sleep 1 didn't help with "<pid>: Permission denied"
sleep 2
echo "INFO: retrying jmap (retry=$jmap_retry_cnt, loop=$loop_cnt)."
continue
fi
instance_cnt=`grep_cmd "[ ]$TARGET_CLASS$" \
< "$TEST_NAME.jmap" \
set +e
instance_cnt=`grep "${PATTERN_WS}${TARGET_CLASS}${PATTERN_EOL}" \
"$TEST_NAME.jmap" \
| sed '
# strip leading whitespace; does nothing in JDK1.5.0
s/^[ ][ ]*//
s/^'"${PATTERN_WS}${PATTERN_WS}"'*//
# strip <#bytes> in JDK1.5.0; does nothing otherwise
s/^[1-9][0-9]*[ ][ ]*//
s/^[1-9][0-9]*'"${PATTERN_WS}${PATTERN_WS}"'*//
# strip <num>: field; does nothing in JDK1.5.0
s/^[1-9][0-9]*:[ ][ ]*//
s/^[1-9][0-9]*:'"${PATTERN_WS}${PATTERN_WS}"'*//
# strip <class_name> field
s/[ ].*//
s/'"${PATTERN_WS}"'.*//
'`
set -e
if [ -z "$instance_cnt" ]; then
echo "INFO: instance count is unexpectedly empty"
if [ "$loop_cnt" = 0 ]; then
......@@ -211,8 +170,7 @@ while true; do
cat "$TEST_NAME.jmap"
echo "INFO: end of jmap output."
echo "FAIL: cannot find the instance count value." >&2
echo "INFO: killing $test_pid"
kill "$test_pid"
killApplication
exit 2
fi
else
......@@ -221,7 +179,17 @@ while true; do
if [ "$instance_cnt" -gt "$prev_instance_cnt" ]; then
increasing_cnt=`expr $increasing_cnt + 1`
else
# actually decreasing or the same
decreasing_cnt=`expr $decreasing_cnt + 1`
# For this particular WeakReference leak, the count was
# always observed to be increasing so if we get a decreasing
# or the same count, then the leak is fixed in the bits
# being tested.
echo "INFO: finishing early due to non-increasing instance count."
finished_early=true
killApplication
break
fi
prev_instance_cnt="$instance_cnt"
fi
......@@ -232,8 +200,22 @@ while true; do
loop_cnt=`expr $loop_cnt + 1`
done
if [ $finished_early = false ]; then
stopApplication "$TEST_NAME.port"
waitForApplication
fi
echo "INFO: $TEST_NAME has finished running."
echo "INFO: increasing_cnt = $increasing_cnt"
echo "INFO: decreasing_cnt = $decreasing_cnt"
if [ "$jmap_retry_cnt" -gt 0 ]; then
echo "INFO: jmap_retry_cnt = $jmap_retry_cnt (in $loop_cnt iterations)"
fi
if [ "$loop_cnt" = 0 ]; then
echo "FAIL: jmap is unable to take any samples." >&2
exit 2
fi
echo "INFO: The instance count of" `eval echo $TARGET_CLASS` "objects"
if [ "$decreasing_cnt" = 0 ]; then
......@@ -242,6 +224,6 @@ if [ "$decreasing_cnt" = 0 ]; then
exit 2
fi
echo "INFO: is both increasing and decreasing."
echo "INFO: is not always increasing."
echo "PASS: This indicates that there is not a memory leak."
exit 0
......@@ -23,27 +23,32 @@
import java.util.logging.*;
public class LoggerWeakRefLeak {
// AnonLoggerWeakRefLeak checks for one weak reference leak.
// LoggerWeakRefLeak checks for two weak reference leaks so
// this test runs twice as long, by default.
public class LoggerWeakRefLeak extends SimpleApplication {
// The test driver script will allow this program to run until we
// reach DEFAULT_LOOP_TIME or a decrease in instance counts is
// observed. For these particular WeakReference leaks, the count
// was always observed to be increasing so if we get a decreasing
// count, then the leaks are fixed in the bits being tested.
// Two minutes has been enough time to observe a decrease in
// fixed bits on overloaded systems, but the test will likely
// finish more quickly.
public static int DEFAULT_LOOP_TIME = 120; // time is in seconds
public static void main(String[] args) {
// execute the LoggerWeakRefLeak app work
public void doMyAppWork(String[] args) throws Exception {
int loop_time = 0;
int max_loop_time = DEFAULT_LOOP_TIME;
if (args.length == 0) {
// args[0] is the port-file
if (args.length < 2) {
System.out.println("INFO: using default time of "
+ max_loop_time + " seconds.");
} else {
try {
max_loop_time = Integer.parseInt(args[0]);
max_loop_time = Integer.parseInt(args[1]);
} catch (NumberFormatException nfe) {
System.err.println("Error: '" + args[0]
throw new RuntimeException("Error: '" + args[1]
+ "': is not a valid seconds value.");
System.err.println("Usage: LoggerWeakRefLeak [seconds]");
System.exit(1);
}
}
......@@ -86,4 +91,12 @@ public class LoggerWeakRefLeak {
System.out.println("INFO: final loop count = " + count);
}
public static void main(String[] args) throws Exception {
AnonLoggerWeakRefLeak myApp = new AnonLoggerWeakRefLeak();
SimpleApplication.setMyApp(myApp);
SimpleApplication.main(args);
}
}
#!/bin/sh
#
# Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
......@@ -23,76 +25,24 @@
# @test
# @bug 6942989
# @ignore until 6964018 is fixed
# @summary Check for WeakReference leak in Logger objects
# @author Daniel D. Daugherty
#
# @run build LoggerWeakRefLeak
# @library ../../../sun/tools/common
# @build SimpleApplication ShutdownSimpleApplication
# @build LoggerWeakRefLeak
# @run shell/timeout=240 LoggerWeakRefLeak.sh
# The timeout is: 2 minutes for infrastructure and 1 minute for the test
# The timeout is: 2 minutes for infrastructure and 2 minutes for the test
#
if [ "${TESTJAVA}" = "" ]
then
echo "TESTJAVA not set. Test cannot execute. Failed."
exit 1
fi
if [ "${TESTSRC}" = "" ]
then
echo "TESTSRC not set. Test cannot execute. Failed."
exit 1
fi
if [ "${TESTCLASSES}" = "" ]
then
echo "TESTCLASSES not set. Test cannot execute. Failed."
exit 1
fi
JAVA="${TESTJAVA}"/bin/java
JMAP="${TESTJAVA}"/bin/jmap
JPS="${TESTJAVA}"/bin/jps
. ${TESTSRC}/../../../sun/tools/common/CommonSetup.sh
. ${TESTSRC}/../../../sun/tools/common/ApplicationSetup.sh
set -eu
TEST_NAME="LoggerWeakRefLeak"
TARGET_CLASS="java\.lang\.ref\.WeakReference"
is_cygwin=false
is_mks=false
is_windows=false
case `uname -s` in
CYGWIN*)
is_cygwin=true
is_windows=true
;;
Windows_*)
is_mks=true
is_windows=true
;;
*)
;;
esac
# wrapper for grep
#
grep_cmd() {
set +e
if $is_windows; then
# need dos2unix to get rid of CTRL-M chars from java output
dos2unix | grep "$@"
status="$?"
else
grep "$@"
status="$?"
fi
set -e
}
# MAIN begins here
#
......@@ -105,62 +55,39 @@ fi
# see if this version of jmap supports the '-histo:live' option
jmap_option="-histo:live"
set +e
"${JMAP}" "$jmap_option" 0 > "$TEST_NAME.jmap" 2>&1
grep '^Usage: ' "$TEST_NAME.jmap" > /dev/null 2>&1
"${JMAP}" 2>&1 | grep ':live' > /dev/null 2>&1
status="$?"
set -e
if [ "$status" = 0 ]; then
if [ "$status" != 0 ]; then
echo "INFO: switching jmap option from '$jmap_option'\c"
jmap_option="-histo"
echo " to '$jmap_option'."
fi
"${JAVA}" ${TESTVMOPTS} -classpath "${TESTCLASSES}" \
"$TEST_NAME" $seconds > "$TEST_NAME.log" 2>&1 &
test_pid="$!"
echo "INFO: starting $TEST_NAME as pid = $test_pid"
# Start application and use TEST_NAME.port for coordination
startApplication "$TEST_NAME" "$TEST_NAME.port" $seconds
# wait for test program to get going
count=0
while [ "$count" -lt 30 ]; do
sleep 2
grep_cmd '^INFO: call count = 0$' < "$TEST_NAME.log" > /dev/null 2>&1
if [ "$status" = 0 ]; then
break
fi
count=`expr $count + 1`
done
if [ "$count" -ge 30 ]; then
echo "ERROR: $TEST_NAME failed to get going." >&2
echo "INFO: killing $test_pid"
kill "$test_pid"
exit 1
elif [ "$count" -gt 1 ]; then
echo "INFO: $TEST_NAME took $count loops to start."
fi
if $is_cygwin; then
# We need the Windows pid for jmap and not the Cygwin pid.
# Note: '\t' works on Cygwin, but doesn't seem to work on Solaris.
jmap_pid=`"${JPS}"| grep_cmd "[ \t]$TEST_NAME$" | sed 's/[ \t].*//'`
if [ -z "$jmap_pid" ]; then
echo "FAIL: jps could not map Cygwin pid to Windows pid." >&2
echo "INFO: killing $test_pid"
kill "$test_pid"
exit 2
fi
echo "INFO: pid = $test_pid maps to Windows pid = $jmap_pid"
else
jmap_pid="$test_pid"
fi
finished_early=false
decreasing_cnt=0
increasing_cnt=0
loop_cnt=0
prev_instance_cnt=0
MAX_JMAP_TRY_CNT=10
jmap_retry_cnt=0
loop_cnt_on_retry=0
while true; do
# see if the target process has finished its run and bail if it has
set +e
grep "^INFO: final loop count = " "$appOutput" > /dev/null 2>&1
status="$?"
set -e
if [ "$status" = 0 ]; then
break
fi
# Output format for 'jmap -histo' in JDK1.5.0:
#
# <#bytes> <#instances> <class_name>
......@@ -170,38 +97,70 @@ while true; do
# <num>: <#instances> <#bytes> <class_name>
#
set +e
"${JMAP}" "$jmap_option" "$jmap_pid" > "$TEST_NAME.jmap" 2>&1
"${JMAP}" "$jmap_option" "$appJavaPid" > "$TEST_NAME.jmap" 2>&1
status="$?"
set -e
if [ "$status" != 0 ]; then
echo "INFO: jmap exited with exit code = $status"
if [ "$loop_cnt" = 0 ]; then
echo "INFO: on the first iteration so no samples were taken."
echo "INFO: start of jmap output:"
cat "$TEST_NAME.jmap"
echo "INFO: end of jmap output."
# There are intermittent jmap failures; see 6498448.
#
# So far the following have been observed in a jmap call
# that was not in a race with target process termination:
#
# (Solaris specific, 2nd sample)
# <pid>: Unable to open door: target process not responding or HotSpot VM not loaded
# The -F option can be used when the target process is not responding
#
# (on Solaris so far)
# java.io.IOException
#
# (on Solaris so far, 1st sample)
# <pid>: Permission denied
#
sed 's/^/INFO: /' "$TEST_NAME.jmap"
if [ "$loop_cnt" = "$loop_cnt_on_retry" ]; then
# loop count hasn't changed
jmap_retry_cnt=`expr $jmap_retry_cnt + 1`
else
# loop count has changed so remember it
jmap_retry_cnt=1
loop_cnt_on_retry="$loop_cnt"
fi
# This is '-ge' because we have the original attempt plus
# MAX_JMAP_TRY_CNT - 1 retries.
if [ "$jmap_retry_cnt" -ge "$MAX_JMAP_TRY_CNT" ]; then
echo "INFO: jmap failed $MAX_JMAP_TRY_CNT times in a row" \
"without making any progress."
echo "FAIL: jmap is unable to take any samples." >&2
echo "INFO: killing $test_pid"
kill "$test_pid"
killApplication
exit 2
fi
echo "INFO: The likely reason is that $TEST_NAME has finished running."
break
# short delay and try again
# Note: sleep 1 didn't help with "<pid>: Permission denied"
sleep 2
echo "INFO: retrying jmap (retry=$jmap_retry_cnt, loop=$loop_cnt)."
continue
fi
instance_cnt=`grep_cmd "[ ]$TARGET_CLASS$" \
< "$TEST_NAME.jmap" \
set +e
instance_cnt=`grep "${PATTERN_WS}${TARGET_CLASS}${PATTERN_EOL}" \
"$TEST_NAME.jmap" \
| sed '
# strip leading whitespace; does nothing in JDK1.5.0
s/^[ ][ ]*//
s/^'"${PATTERN_WS}${PATTERN_WS}"'*//
# strip <#bytes> in JDK1.5.0; does nothing otherwise
s/^[1-9][0-9]*[ ][ ]*//
s/^[1-9][0-9]*'"${PATTERN_WS}${PATTERN_WS}"'*//
# strip <num>: field; does nothing in JDK1.5.0
s/^[1-9][0-9]*:[ ][ ]*//
s/^[1-9][0-9]*:'"${PATTERN_WS}${PATTERN_WS}"'*//
# strip <class_name> field
s/[ ].*//
s/'"${PATTERN_WS}"'.*//
'`
set -e
if [ -z "$instance_cnt" ]; then
echo "INFO: instance count is unexpectedly empty"
if [ "$loop_cnt" = 0 ]; then
......@@ -211,8 +170,7 @@ while true; do
cat "$TEST_NAME.jmap"
echo "INFO: end of jmap output."
echo "FAIL: cannot find the instance count value." >&2
echo "INFO: killing $test_pid"
kill "$test_pid"
killApplication
exit 2
fi
else
......@@ -221,7 +179,17 @@ while true; do
if [ "$instance_cnt" -gt "$prev_instance_cnt" ]; then
increasing_cnt=`expr $increasing_cnt + 1`
else
# actually decreasing or the same
decreasing_cnt=`expr $decreasing_cnt + 1`
# For these particular WeakReference leaks, the count was
# always observed to be increasing so if we get a decreasing
# or the same count, then the leaks are fixed in the bits
# being tested.
echo "INFO: finishing early due to non-increasing instance count."
finished_early=true
killApplication
break
fi
prev_instance_cnt="$instance_cnt"
fi
......@@ -232,8 +200,22 @@ while true; do
loop_cnt=`expr $loop_cnt + 1`
done
if [ $finished_early = false ]; then
stopApplication "$TEST_NAME.port"
waitForApplication
fi
echo "INFO: $TEST_NAME has finished running."
echo "INFO: increasing_cnt = $increasing_cnt"
echo "INFO: decreasing_cnt = $decreasing_cnt"
if [ "$jmap_retry_cnt" -gt 0 ]; then
echo "INFO: jmap_retry_cnt = $jmap_retry_cnt (in $loop_cnt iterations)"
fi
if [ "$loop_cnt" = 0 ]; then
echo "FAIL: jmap is unable to take any samples." >&2
exit 2
fi
echo "INFO: The instance count of" `eval echo $TARGET_CLASS` "objects"
if [ "$decreasing_cnt" = 0 ]; then
......@@ -242,6 +224,6 @@ if [ "$decreasing_cnt" = 0 ]; then
exit 2
fi
echo "INFO: is both increasing and decreasing."
echo "INFO: is not always increasing."
echo "PASS: This indicates that there is not a memory leak."
exit 0
#!/bin/sh
#
# Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved.
# Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
......@@ -24,54 +24,187 @@
#
# Support function to start and stop a given application
# Support functions to start, stop, wait for or kill a given SimpleApplication
# Starts a given application as background process, usage:
# startApplication <class> [args...]
# Starts a given app as background process, usage:
# startApplication <class> port-file [args...]
#
# The following variables are set:
#
# appJavaPid - application's Java pid
# appOtherPid - pid associated with the app other than appJavaPid
# appPidList - all pids associated with the app
# appOutput - file containing stdout and stderr from the app
#
# Waits for at least one line of output from the app to indicate
# that it is up and running.
#
# Waits for application to print something to indicate it is running
# (and initialized). Output is directed to ${TESTCLASSES}/Application.out.
# Sets $pid to be the process-id of the application.
startApplication()
{
OUTPUTFILE=${TESTCLASSES}/Application.out
${JAVA} $1 $2 $3 $4 $5 $6 > ${OUTPUTFILE} &
pid="$!"
# MKS creates an intermediate shell to launch ${JAVA} so
# ${pid} is not the actual pid. We have put in a small sleep
# to give the intermediate shell process time to launch the
# "java" process.
if [ "$OS" = "Windows" ]; then
sleep 2
if [ "${isCygwin}" = "true" ] ; then
realpid=`ps -p ${pid} | tail -1 | awk '{print $4;}'`
else
realpid=`ps -o pid,ppid,comm|grep ${pid}|grep "java"|cut -c1-6`
fi
pid=${realpid}
fi
appOutput="${TESTCLASSES}/Application.out"
echo "Waiting for Application to initialize..."
attempts=0
${JAVA} -classpath "${TESTCLASSES}" "$@" > "$appOutput" 2>&1 &
appJavaPid="$!"
appOtherPid=
appPidList="$appJavaPid"
echo "INFO: waiting for $1 to initialize..."
_cnt=0
while true; do
# if the app doesn't start then the JavaTest/JTREG timeout will
# kick in so this isn't really a endless loop
sleep 1
out=`tail -1 ${OUTPUTFILE}`
if [ ! -z "$out" ]; then
out=`tail -1 "$appOutput"`
if [ -n "$out" ]; then
# we got some output from the app so it's running
break
fi
attempts=`expr $attempts + 1`
echo "Waiting $attempts second(s) ..."
_cnt=`expr $_cnt + 1`
echo "INFO: waited $_cnt second(s) ..."
done
unset _cnt
if $isWindows; then
# Windows requires special handling
appOtherPid="$appJavaPid"
echo "Application is process $pid"
if $isCygwin; then
appJavaPid=`ps -p "$appOtherPid" \
| sed -n '
# See if $appOtherPid is in PID column; there are sometimes
# non-blanks in column 1 (I and S observed so far)
/^.'"${PATTERN_WS}${PATTERN_WS}*${appOtherPid}${PATTERN_WS}"'/{
# strip PID column
s/^.'"${PATTERN_WS}${PATTERN_WS}*${appOtherPid}${PATTERN_WS}${PATTERN_WS}"'*//
# strip PPID column
s/^[1-9][0-9]*'"${PATTERN_WS}${PATTERN_WS}"'*//
# strip PGID column
s/^[1-9][0-9]*'"${PATTERN_WS}${PATTERN_WS}"'*//
# strip everything after WINPID column
s/'"${PATTERN_WS}"'.*//
p
q
}
'`
echo "INFO: Cygwin pid=$appOtherPid maps to Windows pid=$appJavaPid"
else
# show PID, PPID and COMM columns only
appJavaPid=`ps -o pid,ppid,comm \
| sed -n '
# see if appOtherPid is in either PID or PPID columns
/'"${PATTERN_WS}${appOtherPid}${PATTERN_WS}"'/{
# see if this is a java command
/java'"${PATTERN_EOL}"'/{
# strip leading white space
s/^'"${PATTERN_WS}${PATTERN_WS}"'*//
# strip everything after the first word
s/'"${PATTERN_WS}"'.*//
# print the pid and we are done
p
q
}
}
'`
echo "INFO: MKS shell pid=$appOtherPid; Java pid=$appJavaPid"
fi
if [ -z "$appJavaPid" ]; then
echo "ERROR: could not find app's Java pid." >&2
killApplication
exit 2
fi
appPidList="$appOtherPid $appJavaPid"
fi
echo "INFO: $1 is process $appJavaPid"
echo "INFO: $1 output is in $appOutput"
}
# Stops an application by invoking the given class and argument, usage:
# stopApplication <class> <argument>
# Stops a simple application by invoking ShutdownSimpleApplication
# class with a specific port-file, usage:
# stopApplication port-file
#
# Note: When this function returns, the SimpleApplication (or a subclass)
# may still be running because the application has not yet reached the
# shutdown check.
#
stopApplication()
{
$JAVA -classpath "${TESTCLASSES}" $1 $2
$JAVA -classpath "${TESTCLASSES}" ShutdownSimpleApplication $1
}
# Wait for a simple application to stop running.
#
waitForApplication() {
if [ $isWindows = false ]; then
# non-Windows is easy; just one process
echo "INFO: waiting for $appJavaPid"
set +e
wait "$appJavaPid"
set -e
elif $isCygwin; then
# Cygwin pid and not the Windows pid
echo "INFO: waiting for $appOtherPid"
set +e
wait "$appOtherPid"
set -e
else # implied isMKS
# MKS has intermediate shell and Java process
echo "INFO: waiting for $appJavaPid"
# appJavaPid can be empty if pid search in startApplication() failed
if [ -n "$appJavaPid" ]; then
# only need to wait for the Java process
set +e
wait "$appJavaPid"
set -e
fi
fi
}
# Kills a simple application by sending a SIGTERM to the appropriate
# process(es); on Windows SIGQUIT (-9) is used.
#
killApplication()
{
if [ $isWindows = false ]; then
# non-Windows is easy; just one process
echo "INFO: killing $appJavaPid"
set +e
kill -TERM "$appJavaPid" # try a polite SIGTERM first
sleep 2
# send SIGQUIT (-9) just in case SIGTERM didn't do it
# but don't show any complaints
kill -QUIT "$appJavaPid" > /dev/null 2>&1
wait "$appJavaPid"
set -e
elif $isCygwin; then
# Cygwin pid and not the Windows pid
echo "INFO: killing $appOtherPid"
set +e
kill -9 "$appOtherPid"
wait "$appOtherPid"
set -e
else # implied isMKS
# MKS has intermediate shell and Java process
echo "INFO: killing $appPidList"
set +e
kill -9 $appPidList
set -e
# appJavaPid can be empty if pid search in startApplication() failed
if [ -n "$appJavaPid" ]; then
# only need to wait for the Java process
set +e
wait "$appJavaPid"
set -e
fi
fi
}
#!/bin/sh
#
# Copyright (c) 2005, 2006, Oracle and/or its affiliates. All rights reserved.
# Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
......@@ -24,56 +24,94 @@
#
# Common setup for tool tests.
# Common setup for tool tests and other tests that use jtools.
# Checks that TESTJAVA, TESTSRC, and TESTCLASSES environment variables are set.
# Creates the following for use by the tool tests
# JAVA java launcher
# JSTACK jstack utility
# JMAP jmap utility
# JINFO jinfo utility
# JHAT jhat utility
# PS path separator (";" or ":")
# OS operating system
#
# Creates the following constants for use by the caller:
# JAVA - java launcher
# JHAT - jhat utility
# JINFO - jinfo utility
# JMAP - jmap utility
# JPS - jps utility
# JSTACK - jstack utility
# OS - operating system name
# PATTERN_EOL - grep or sed end-of-line pattern
# PATTERN_WS - grep or sed whitespace pattern
# PS - path separator (";" or ":")
#
# Sets the following variables:
#
# isCygwin - true if environment is Cygwin
# isMKS - true if environment is MKS
# isLinux - true if OS is Linux
# isSolaris - true if OS is Solaris
# isWindows - true if OS is Windows
if [ "${TESTJAVA}" = "" ]
then
echo "TESTJAVA not set. Test cannot execute. Failed."
if [ -z "${TESTJAVA}" ]; then
echo "ERROR: TESTJAVA not set. Test cannot execute. Failed."
exit 1
fi
if [ "${TESTSRC}" = "" ]
then
echo "TESTSRC not set. Test cannot execute. Failed."
if [ -z "${TESTSRC}" ]; then
echo "ERROR: TESTSRC not set. Test cannot execute. Failed."
exit 1
fi
if [ "${TESTCLASSES}" = "" ]
then
echo "TESTCLASSES not set. Test cannot execute. Failed."
if [ -z "${TESTCLASSES}" ]; then
echo "ERROR: TESTCLASSES not set. Test cannot execute. Failed."
exit 1
fi
# only enable these after checking the expected incoming env variables
set -eu
JAVA="${TESTJAVA}/bin/java"
JSTACK="${TESTJAVA}/bin/jstack"
JMAP="${TESTJAVA}/bin/jmap"
JINFO="${TESTJAVA}/bin/jinfo"
JHAT="${TESTJAVA}/bin/jhat"
JINFO="${TESTJAVA}/bin/jinfo"
JMAP="${TESTJAVA}/bin/jmap"
JPS="${TESTJAVA}/bin/jps"
JSTACK="${TESTJAVA}/bin/jstack"
isCygwin=false
isMKS=false
isLinux=false
isSolaris=false
isUnknownOS=false
isWindows=false
OS=`uname -s`
# start with some UNIX like defaults
PATTERN_EOL='$'
# blank and tab
PATTERN_WS='[ ]'
PS=":"
case "$OS" in
Windows* )
PS=";"
OS="Windows"
;;
CYGWIN* )
PS=";"
OS="Windows"
PATTERN_EOL='[ ]*$'
# blank and tab
PATTERN_WS='[ \t]'
isCygwin=true
isWindows=true
;;
Linux )
OS="Linux"
isLinux=true
;;
SunOS )
OS="Solaris"
isSolaris=true
;;
Windows* )
OS="Windows"
PATTERN_EOL='[ ]*$'
PS=";"
isWindows=true
;;
* )
PS=":"
isUnknownOS=true
;;
esac
......
#!/bin/sh
#
# Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License version 2 only, as
# published by the Free Software Foundation.
#
# This code 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
# version 2 for more details (a copy is included in the LICENSE file that
# accompanied this code).
#
# You should have received a copy of the GNU General Public License version
# 2 along with this work; if not, write to the Free Software Foundation,
# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
#
# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
# or visit www.oracle.com if you need additional information or have any
# questions.
#
# @test
# @bug 6964018
# @summary Unit test for common tools infrastructure.
#
# @build SimpleApplication SleeperApplication ShutdownSimpleApplication
# @run shell CommonTests.sh
. ${TESTSRC}/CommonSetup.sh
. ${TESTSRC}/ApplicationSetup.sh
# hope for the best:
status=0
# Test program path constants from CommonSetup.sh:
#
for name in JAVA JHAT JINFO JMAP JPS JSTACK; do
eval value=$`echo $name`
echo "INFO: $name=$value"
if [ -x "$value" ]; then
echo "INFO: '$value' is executable."
else
echo "ERROR: '$value' is not executable." >&2
status=1
fi
done
# Display flag values from CommonSetup.sh:
#
for name in isCygwin isMKS isLinux isSolaris isUnknownOS isWindows; do
eval value=$`echo $name`
echo "INFO: flag $name=$value"
done
# Test OS constant from CommonSetup.sh:
#
if [ -z "$OS" ]; then
echo "ERROR: OS constant cannot be empty." >&2
status=1
fi
# Display the PATTERN_EOL value:
#
echo "INFO: PATTERN_EOL="`echo "$PATTERN_EOL" | od -c`
# Test PATTERN_EOL with 'grep' for a regular line.
#
TESTOUT="${TESTCLASSES}/testout.grep_reg_line_eol"
set +e
echo 'regular line' | grep "line${PATTERN_EOL}" > "$TESTOUT"
set -e
if [ -s "$TESTOUT" ]; then
echo "INFO: PATTERN_EOL works for regular line with grep."
else
echo "ERROR: PATTERN_EOL does not work for regular line with grep." >&2
status=1
fi
if $isWindows; then
# Test PATTERN_EOL with 'grep' for a CR line.
#
TESTOUT="${TESTCLASSES}/testout.grep_cr_line_eol"
set +e
echo 'CR line ' | grep "line${PATTERN_EOL}" > "$TESTOUT"
set -e
if [ -s "$TESTOUT" ]; then
echo "INFO: PATTERN_EOL works for CR line with grep."
else
echo "ERROR: PATTERN_EOL does not work for CR line with grep." >&2
status=1
fi
fi
# Test PATTERN_EOL with 'sed' for a regular line.
#
TESTOUT="${TESTCLASSES}/testout.sed_reg_line_eol"
echo 'regular line' | sed -n "/line${PATTERN_EOL}/p" > "$TESTOUT"
if [ -s "$TESTOUT" ]; then
echo "INFO: PATTERN_EOL works for regular line with sed."
else
echo "ERROR: PATTERN_EOL does not work for regular line with sed." >&2
status=1
fi
if $isWindows; then
# Test PATTERN_EOL with 'sed' for a CR line.
#
TESTOUT="${TESTCLASSES}/testout.sed_cr_line_eol"
echo 'CR line ' | sed -n "/line${PATTERN_EOL}/p" > "$TESTOUT"
if [ -s "$TESTOUT" ]; then
echo "INFO: PATTERN_EOL works for CR line with sed."
else
echo "ERROR: PATTERN_EOL does not work for CR line with sed." >&2
status=1
fi
fi
# Display the PATTERN_WS value:
#
echo "INFO: PATTERN_WS="`echo "$PATTERN_WS" | od -c`
# Test PATTERN_WS with 'grep' for a blank.
#
TESTOUT="${TESTCLASSES}/testout.grep_blank"
set +e
echo 'blank: ' | grep "$PATTERN_WS" > "$TESTOUT"
set -e
if [ -s "$TESTOUT" ]; then
echo "INFO: PATTERN_WS works for blanks with grep."
else
echo "ERROR: PATTERN_WS does not work for blanks with grep." >&2
status=1
fi
# Test PATTERN_WS with 'grep' for a tab.
#
TESTOUT="${TESTCLASSES}/testout.grep_tab"
set +e
echo 'tab: ' | grep "$PATTERN_WS" > "$TESTOUT"
set -e
if [ -s "$TESTOUT" ]; then
echo "INFO: PATTERN_WS works for tabs with grep."
else
echo "ERROR: PATTERN_WS does not work for tabs with grep." >&2
status=1
fi
# Test PATTERN_WS with 'sed' for a blank.
#
TESTOUT="${TESTCLASSES}/testout.sed_blank"
echo 'blank: ' | sed -n "/$PATTERN_WS/p" > "$TESTOUT"
if [ -s "$TESTOUT" ]; then
echo "INFO: PATTERN_WS works for blanks with sed."
else
echo "ERROR: PATTERN_WS does not work for blanks with sed." >&2
status=1
fi
# Test PATTERN_WS with 'sed' for a tab.
#
TESTOUT="${TESTCLASSES}/testout.sed_tab"
echo 'tab: ' | sed -n "/$PATTERN_WS/p" > "$TESTOUT"
if [ -s "$TESTOUT" ]; then
echo "INFO: PATTERN_WS works for tabs with sed."
else
echo "ERROR: PATTERN_WS does not work for tabs with sed." >&2
status=1
fi
# Test startApplication and use PORTFILE for coordination
# The app sleeps for 30 seconds.
#
PORTFILE="${TESTCLASSES}"/shutdown.port
startApplication SleeperApplication "${PORTFILE}" 30
# Test appJavaPid in "ps" cmd output.
#
TESTOUT="${TESTCLASSES}/testout.ps_app"
set +e
if $isCygwin; then
# On Cygwin, appJavaPid is the Windows pid for the Java process
# and appOtherPid is the Cygwin pid for the Java process.
ps -p "$appOtherPid" \
| grep "${PATTERN_WS}${appJavaPid}${PATTERN_WS}" > "$TESTOUT"
else
# output only pid and comm columns to avoid mismatches
ps -eo pid,comm \
| grep "^${PATTERN_WS}*${appJavaPid}${PATTERN_WS}" > "$TESTOUT"
fi
set -e
if [ -s "$TESTOUT" ]; then
echo "INFO: begin appJavaPid=$appJavaPid in 'ps' cmd output:"
cat "$TESTOUT"
echo "INFO: end appJavaPid=$appJavaPid in 'ps' cmd output."
else
echo "ERROR: 'ps' cmd should show appJavaPid=$appJavaPid." >&2
status=1
fi
if [ -n "$appOtherPid" ]; then
# Test appOtherPid in "ps" cmd output, if we have one.
#
TESTOUT="${TESTCLASSES}/testout.ps_other"
set +e
if $isCygwin; then
ps -p "$appOtherPid" \
| grep "${PATTERN_WS}${appOtherPid}${PATTERN_WS}" > "$TESTOUT"
else
# output only pid and comm columns to avoid mismatches
ps -eo pid,comm \
| grep "^${PATTERN_WS}*${appOtherPid}${PATTERN_WS}" > "$TESTOUT"
fi
set -e
if [ -s "$TESTOUT" ]; then
echo "INFO: begin appOtherPid=$appOtherPid in 'ps' cmd output:"
cat "$TESTOUT"
echo "INFO: end appOtherPid=$appOtherPid in 'ps' cmd output."
else
echo "ERROR: 'ps' cmd should show appOtherPid=$appOtherPid." >&2
status=1
fi
fi
# Test stopApplication and PORTFILE for coordination
#
stopApplication "${PORTFILE}"
# Test application still running after stopApplication.
#
# stopApplication just lets the app know that it can stop, but the
# app might still be doing work. This test just demonstrates that
# fact and doesn't fail if the app is already done.
#
TESTOUT="${TESTCLASSES}/testout.after_stop"
set +e
if $isCygwin; then
# On Cygwin, appJavaPid is the Windows pid for the Java process
# and appOtherPid is the Cygwin pid for the Java process.
ps -p "$appOtherPid" \
| grep "${PATTERN_WS}${appJavaPid}${PATTERN_WS}" > "$TESTOUT"
else
# output only pid and comm columns to avoid mismatches
ps -eo pid,comm \
| grep "^${PATTERN_WS}*${appJavaPid}${PATTERN_WS}" > "$TESTOUT"
fi
set -e
if [ -s "$TESTOUT" ]; then
echo "INFO: it is okay for appJavaPid=$appJavaPid to still be running" \
"after stopApplication() is called."
echo "INFO: begin 'after_stop' output:"
cat "$TESTOUT"
echo "INFO: end 'after_stop' output."
fi
# Test waitForApplication
#
# The app might already be gone so this function shouldn't generate
# a fatal error in either call.
#
waitForApplication
if [ $isWindows = false ]; then
# Windows can recycle pids quickly so we can't use this test there
TESTOUT="${TESTCLASSES}/testout.after_kill"
set +e
# output only pid and comm columns to avoid mismatches
ps -eo pid,comm \
| grep "^${PATTERN_WS}*${appJavaPid}${PATTERN_WS}" > "$TESTOUT"
set -e
if [ -s "$TESTOUT" ]; then
echo "ERROR: 'ps' cmd should not show appJavaPid." >&2
echo "ERROR: begin 'after_kill' output:" >&2
cat "$TESTOUT" >&2
echo "ERROR: end 'after_kill' output." >&2
status=1
else
echo "INFO: 'ps' cmd does not show appJavaPid after" \
"waitForApplication() is called."
fi
fi
# Test killApplication
#
# The app is already be gone so this function shouldn't generate
# a fatal error.
#
killApplication
exit $status
/*
* Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -22,10 +22,13 @@
*/
/*
* Used to shutdown SimpleApplication (or a subclass). The argument to
* this class is the name of a file that contains the TCP port number
* on which SimpleApplication (or a subclass) is listening.
*
*
* Used to shutdown SimpleApplication. The argument to this class is
* the TCP port number where SimpleApplication is listening.
* Note: When this program returns, the SimpleApplication (or a subclass)
* may still be running because the application has not yet reached the
* shutdown check.
*/
import java.net.Socket;
import java.net.InetSocketAddress;
......@@ -35,6 +38,11 @@ import java.io.FileInputStream;
public class ShutdownSimpleApplication {
public static void main(String args[]) throws Exception {
if (args.length != 1) {
throw new RuntimeException("Usage: ShutdownSimpleApplication" +
" port-file");
}
// read the (TCP) port number from the given file
File f = new File(args[0]);
......@@ -42,21 +50,27 @@ public class ShutdownSimpleApplication {
byte b[] = new byte[8];
int n = fis.read(b);
if (n < 1) {
throw new RuntimeException("Empty file");
throw new RuntimeException("Empty port-file");
}
fis.close();
String str = new String(b, 0, n, "UTF-8");
System.out.println("Port number of application is: " + str);
System.out.println("INFO: Port number of SimpleApplication: " + str);
int port = Integer.parseInt(str);
// Now connect to the port (which will shutdown application)
System.out.println("Connecting to port " + port +
" to shutdown Application ...");
System.out.println("INFO: Connecting to port " + port +
" to shutdown SimpleApplication ...");
System.out.flush();
Socket s = new Socket();
s.connect( new InetSocketAddress(port) );
s.close();
System.out.println("INFO: done connecting to SimpleApplication.");
System.out.flush();
System.exit(0);
}
}
/*
* Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -22,10 +22,12 @@
*/
/*
* A simple application used by unit tests. The first argument to this
* class is the name of a file to which a TCP port number can be written.
*
*
* A simple application used for tool unit tests. It does nothing else
* bind to a TCP port and wait for a shutdown message.
* By default, this class does nothing other than bind to a TCP port,
* write the TCP port number to a file, and wait for an incoming connection
* in order to complete the application shutdown protocol.
*/
import java.net.Socket;
import java.net.ServerSocket;
......@@ -33,25 +35,86 @@ import java.io.File;
import java.io.FileOutputStream;
public class SimpleApplication {
public static void main(String args[]) throws Exception {
private static SimpleApplication myApp; // simple app or a subclass
private static String myAppName; // simple app name
private static int myPort; // coordination port #
private static ServerSocket mySS; // coordination socket
// protected so a subclass can extend it; not public so creation is
// limited.
protected SimpleApplication() {
// save simple app (or subclass) name for messages
myAppName = getClass().getName();
}
// return the simple application (or a subclass)
final public static SimpleApplication getMyApp() {
return myApp;
}
// set the simple application (for use by a subclass)
final public static void setMyApp(SimpleApplication _myApp) {
myApp = _myApp;
}
// execute the application finish protocol
final public void doMyAppFinish(String[] args) throws Exception {
System.out.println("INFO: " + myAppName + " is waiting on port: " +
myPort);
System.out.flush();
// wait for test harness to connect
Socket s = mySS.accept();
s.close();
mySS.close();
System.out.println("INFO: " + myAppName + " is shutting down.");
System.out.flush();
}
// execute the application start protocol
final public void doMyAppStart(String[] args) throws Exception {
if (args.length < 1) {
throw new RuntimeException("Usage: " + myAppName +
" port-file [arg(s)]");
}
// bind to a random port
ServerSocket ss = new ServerSocket(0);
int port = ss.getLocalPort();
mySS = new ServerSocket(0);
myPort = mySS.getLocalPort();
// Write the port number to the given file
File f = new File(args[0]);
FileOutputStream fos = new FileOutputStream(f);
fos.write( Integer.toString(port).getBytes("UTF-8") );
fos.write( Integer.toString(myPort).getBytes("UTF-8") );
fos.close();
System.out.println("Application waiting on port: " + port);
System.out.println("INFO: " + myAppName + " created socket on port: " +
myPort);
System.out.flush();
}
// wait for test harness to connect
Socket s = ss.accept();
s.close();
ss.close();
// execute the app work (subclass can override this)
public void doMyAppWork(String[] args) throws Exception {
}
public static void main(String[] args) throws Exception {
if (myApp == null) {
// create myApp since a subclass hasn't done so
myApp = new SimpleApplication();
}
myApp.doMyAppStart(args); // do the app start protocol
System.out.println("INFO: " + myAppName + " is calling doMyAppWork()");
System.out.flush();
myApp.doMyAppWork(args); // do the app work
System.out.println("INFO: " + myAppName + " returned from" +
" doMyAppWork()");
System.out.flush();
myApp.doMyAppFinish(args); // do the app finish protocol
System.out.println("Application shutdown.");
System.exit(0);
}
}
/*
* Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* An example subclass of SimpleApplication that illustrates how to
* override the doMyAppWork() method.
*/
public class SleeperApplication extends SimpleApplication {
public static int DEFAULT_SLEEP_TIME = 60; // time is in seconds
// execute the sleeper app work
public void doMyAppWork(String[] args) throws Exception {
int sleep_time = DEFAULT_SLEEP_TIME;
// args[0] is the port-file
if (args.length < 2) {
System.out.println("INFO: using default sleep time of "
+ sleep_time + " seconds.");
} else {
try {
sleep_time = Integer.parseInt(args[1]);
} catch (NumberFormatException nfe) {
throw new RuntimeException("Error: '" + args[1] +
"': is not a valid seconds value.");
}
}
Thread.sleep(sleep_time * 1000); // our "work" is to sleep
}
public static void main(String[] args) throws Exception {
SleeperApplication myApp = new SleeperApplication();
SimpleApplication.setMyApp(myApp);
SimpleApplication.main(args);
}
}
#!/bin/sh
#
# Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved.
# Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
......@@ -32,7 +32,11 @@
# @run shell ParseTest.sh
. ${TESTSRC}/../common/CommonSetup.sh
. ${TESTSRC}/../common/ApplicationSetup.sh
# all return statuses are checked in this test
set +e
failed=0
DUMPFILE="minimal.bin"
......
#!/bin/sh
#
# Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved.
# Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
......@@ -35,53 +35,57 @@
. ${TESTSRC}/../common/CommonSetup.sh
. ${TESTSRC}/../common/ApplicationSetup.sh
# Start application (send output to shutdown.port)
# Start application and use PORTFILE for coordination
PORTFILE="${TESTCLASSES}"/shutdown.port
startApplication \
-classpath "${TESTCLASSES}" SimpleApplication "${PORTFILE}"
startApplication SimpleApplication "${PORTFILE}"
# all return statuses are checked in this test
set +e
failed=0
if [ "$OS" != "Windows" ]; then
if [ $isWindows = false ]; then
# -sysprops option
${JINFO} -sysprops $pid
${JINFO} -sysprops $appJavaPid
if [ $? != 0 ]; then failed=1; fi
# -flags option
${JINFO} -flags $pid
${JINFO} -flags $appJavaPid
if [ $? != 0 ]; then failed=1; fi
# no option
${JINFO} $pid
${JINFO} $appJavaPid
if [ $? != 0 ]; then failed=1; fi
fi
# -flag option
${JINFO} -flag +PrintGC $pid
${JINFO} -flag +PrintGC $appJavaPid
if [ $? != 0 ]; then failed=1; fi
${JINFO} -flag -PrintGC $pid
${JINFO} -flag -PrintGC $appJavaPid
if [ $? != 0 ]; then failed=1; fi
${JINFO} -flag PrintGC $pid
${JINFO} -flag PrintGC $appJavaPid
if [ $? != 0 ]; then failed=1; fi
if [ "$OS" = "SunOS" ]; then
if $isSolaris; then
${JINFO} -flag +ExtendedDTraceProbes $pid
${JINFO} -flag +ExtendedDTraceProbes $appJavaPid
if [ $? != 0 ]; then failed=1; fi
${JINFO} -flag -ExtendedDTraceProbes $pid
${JINFO} -flag -ExtendedDTraceProbes $appJavaPid
if [ $? != 0 ]; then failed=1; fi
${JINFO} -flag ExtendedDTraceProbes $pid
${JINFO} -flag ExtendedDTraceProbes $appJavaPid
if [ $? != 0 ]; then failed=1; fi
fi
stopApplication ShutdownSimpleApplication "${PORTFILE}"
set -e
exit $failed
stopApplication "${PORTFILE}"
waitForApplication
exit $failed
#!/bin/sh
#
# Copyright (c) 2005, 2006, Oracle and/or its affiliates. All rights reserved.
# Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
......@@ -35,24 +35,25 @@
. ${TESTSRC}/../common/CommonSetup.sh
. ${TESTSRC}/../common/ApplicationSetup.sh
# Start application (send output to shutdown.port)
# Start application and use PORTFILE for coordination
PORTFILE="${TESTCLASSES}"/shutdown.port
startApplication \
-classpath "${TESTCLASSES}" SimpleApplication "${PORTFILE}"
startApplication SimpleApplication "${PORTFILE}"
# all return statuses are checked in this test
set +e
failed=0
# -histo[:live] option
${JMAP} -histo $pid
${JMAP} -histo $appJavaPid
if [ $? != 0 ]; then failed=1; fi
${JMAP} -histo:live $pid
${JMAP} -histo:live $appJavaPid
if [ $? != 0 ]; then failed=1; fi
# -dump option
p=`expr $pid`
DUMPFILE="java_pid${p}.hprof"
${JMAP} -dump:format=b,file=${DUMPFILE} $pid
DUMPFILE="java_pid${appJavaPid}.hprof"
${JMAP} -dump:format=b,file=${DUMPFILE} $appJavaPid
if [ $? != 0 ]; then failed=1; fi
# check that heap dump is parsable
......@@ -63,7 +64,7 @@ if [ $? != 0 ]; then failed=1; fi
rm ${DUMPFILE}
# -dump:live option
${JMAP} -dump:live,format=b,file=${DUMPFILE} $pid
${JMAP} -dump:live,format=b,file=${DUMPFILE} $appJavaPid
if [ $? != 0 ]; then failed=1; fi
# check that heap dump is parsable
......@@ -71,9 +72,11 @@ ${JHAT} -parseonly true ${DUMPFILE}
if [ $? != 0 ]; then failed=1; fi
# dump file is large so remove it
rm ${DUMPFILE}
rm -f ${DUMPFILE}
stopApplication ShutdownSimpleApplication "${PORTFILE}"
set -e
exit $failed
stopApplication "${PORTFILE}"
waitForApplication
exit $failed
#!/bin/sh
#
# Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved.
# Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
......@@ -35,22 +35,26 @@
. ${TESTSRC}/../common/CommonSetup.sh
. ${TESTSRC}/../common/ApplicationSetup.sh
# Start application (send output to shutdown.port)
# Start application and use PORTFILE for coordination
PORTFILE="${TESTCLASSES}"/shutdown.port
startApplication \
-classpath "${TESTCLASSES}" SimpleApplication "${PORTFILE}"
startApplication SimpleApplication "${PORTFILE}"
# all return statuses are checked in this test
set +e
failed=0
# normal
$JSTACK $pid 2>&1
$JSTACK $appJavaPid 2>&1
if [ $? != 0 ]; then failed=1; fi
# long
$JSTACK -l $pid 2>&1
$JSTACK -l $appJavaPid 2>&1
if [ $? != 0 ]; then failed=1; fi
stopApplication ShutdownSimpleApplication "${PORTFILE}"
set -e
exit $failed
stopApplication "${PORTFILE}"
waitForApplication
exit $failed
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册