Merge
This commit is contained in:
commit
800c634a8a
@ -142,9 +142,6 @@ java/lang/instrument/RetransformBigClass.sh generic-all
|
||||
# 8058492
|
||||
java/lang/management/ThreadMXBean/FindDeadlocks.java generic-all
|
||||
|
||||
# 8058506
|
||||
java/lang/management/ThreadMXBean/ThreadMXBeanStateTest.java generic-all
|
||||
|
||||
############################################################################
|
||||
|
||||
# jdk_jmx
|
||||
|
@ -421,8 +421,7 @@ needs_jdk = \
|
||||
java/util/Collections/EmptyIterator.java \
|
||||
java/util/concurrent/locks/Lock/TimedAcquireLeak.java \
|
||||
java/util/jar/JarInputStream/ExtraFileInMetaInf.java \
|
||||
java/util/logging/AnonLoggerWeakRefLeak.sh \
|
||||
java/util/logging/LoggerWeakRefLeak.sh \
|
||||
java/util/logging/TestLoggerWeakRefLeak.java \
|
||||
java/util/zip/3GBZipFiles.sh \
|
||||
jdk/lambda/FDTest.java \
|
||||
jdk/lambda/separate/Compiler.java \
|
||||
|
@ -23,6 +23,7 @@
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @ignore JDK-8068162
|
||||
* @bug 6331574
|
||||
* @summary test isModifiableClass
|
||||
* @author Robert Field, Sun Microsystems
|
||||
|
@ -1,92 +0,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.
|
||||
*/
|
||||
|
||||
import java.util.logging.*;
|
||||
|
||||
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
|
||||
|
||||
// execute the AnonLoggerWeakRefLeak app work
|
||||
public void doMyAppWork(String[] args) throws Exception {
|
||||
int loop_time = 0;
|
||||
int max_loop_time = DEFAULT_LOOP_TIME;
|
||||
|
||||
// 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[1]);
|
||||
} catch (NumberFormatException nfe) {
|
||||
throw new RuntimeException("Error: '" + args[1]
|
||||
+ "': is not a valid seconds value.");
|
||||
}
|
||||
}
|
||||
|
||||
long count = 0;
|
||||
long now = 0;
|
||||
long startTime = System.currentTimeMillis();
|
||||
|
||||
while (now < (startTime + (max_loop_time * 1000))) {
|
||||
if ((count % 1000) == 0) {
|
||||
// Print initial call count to let caller know that
|
||||
// we're up and running and then periodically
|
||||
System.out.println("INFO: call count = " + count);
|
||||
}
|
||||
|
||||
for (int i = 0; i < 100; i++) {
|
||||
// this Logger call is leaking a WeakReference in Logger.kids
|
||||
java.util.logging.Logger.getAnonymousLogger();
|
||||
count++;
|
||||
}
|
||||
|
||||
try {
|
||||
// delay for 1/10 of a second to avoid CPU saturation
|
||||
Thread.sleep(100);
|
||||
} catch (InterruptedException ie) {
|
||||
// ignore any exceptions
|
||||
}
|
||||
|
||||
now = System.currentTimeMillis();
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
@ -1,254 +0,0 @@
|
||||
#!/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 6942989
|
||||
# @summary Check for WeakReference leak in anonymous Logger objects
|
||||
# @author Daniel D. Daugherty
|
||||
#
|
||||
# @library ../../../sun/tools/common
|
||||
# @build SimpleApplication ShutdownSimpleApplication
|
||||
# @build AnonLoggerWeakRefLeak
|
||||
# @run shell/timeout=240 AnonLoggerWeakRefLeak.sh
|
||||
|
||||
# The timeout is: 2 minutes for infrastructure and 2 minutes for the test
|
||||
#
|
||||
|
||||
. ${TESTSRC}/../../../sun/tools/common/CommonSetup.sh
|
||||
. ${TESTSRC}/../../../sun/tools/common/ApplicationSetup.sh
|
||||
|
||||
|
||||
TEST_NAME="AnonLoggerWeakRefLeak"
|
||||
TARGET_CLASS="java\.lang\.ref\.WeakReference"
|
||||
|
||||
|
||||
# MAIN begins here
|
||||
#
|
||||
|
||||
seconds=
|
||||
if [ "$#" -gt 0 ]; then
|
||||
seconds="$1"
|
||||
fi
|
||||
|
||||
# see if this version of jmap supports the '-histo:live' option
|
||||
jmap_option="-histo:live"
|
||||
set +e
|
||||
"${JMAP}" 2>&1 | grep ':live' > /dev/null 2>&1
|
||||
status="$?"
|
||||
set -e
|
||||
if [ "$status" != 0 ]; then
|
||||
# usage message doesn't show ':live' option
|
||||
|
||||
if $isWindows; then
|
||||
# If SA isn't present, then jmap gives a different usage message
|
||||
# that doesn't show the ':live' option. However, that's a bug that
|
||||
# is covered by 6971851 so we try using the option just to be sure.
|
||||
# For some reason, this problem has only been seen on OpenJDK6 on
|
||||
# Windows. Not sure why.
|
||||
set +e
|
||||
# Note: Don't copy this code to try probing process 0 on Linux; it
|
||||
# will kill the process group in strange ways.
|
||||
"${JMAP}" "$jmap_option" 0 2>&1 | grep 'Usage' > /dev/null 2>&1
|
||||
status="$?"
|
||||
set -e
|
||||
if [ "$status" = 0 ]; then
|
||||
# Usage message generated so flag the problem.
|
||||
status=1
|
||||
else
|
||||
# No usage message so clear the flag.
|
||||
status=0
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ "$status" != 0 ]; then
|
||||
echo "WARNING: 'jmap $jmap_option' is not supported on this platform"
|
||||
echo "WARNING: so this test cannot work reliably. Aborting!"
|
||||
exit 0
|
||||
fi
|
||||
fi
|
||||
|
||||
# Start application and use TEST_NAME.port for coordination
|
||||
startApplication "$TEST_NAME" "$TEST_NAME.port" $seconds
|
||||
|
||||
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>
|
||||
#
|
||||
# Output format for 'jmap -histo:live':
|
||||
#
|
||||
# <num>: <#instances> <#bytes> <class_name>
|
||||
#
|
||||
set +e
|
||||
"${JMAP}" "$jmap_option" "$appJavaPid" > "$TEST_NAME.jmap" 2>&1
|
||||
status="$?"
|
||||
set -e
|
||||
|
||||
if [ "$status" != 0 ]; then
|
||||
echo "INFO: jmap exited with exit code = $status"
|
||||
|
||||
# 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
|
||||
killApplication
|
||||
exit 2
|
||||
fi
|
||||
|
||||
# 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
|
||||
|
||||
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/^'"${PATTERN_WS}${PATTERN_WS}"'*//
|
||||
# strip <#bytes> in JDK1.5.0; does nothing otherwise
|
||||
s/^[1-9][0-9]*'"${PATTERN_WS}${PATTERN_WS}"'*//
|
||||
# strip <num>: field; does nothing in JDK1.5.0
|
||||
s/^[1-9][0-9]*:'"${PATTERN_WS}${PATTERN_WS}"'*//
|
||||
# strip <class_name> field
|
||||
s/'"${PATTERN_WS}"'.*//
|
||||
'`
|
||||
set -e
|
||||
if [ -z "$instance_cnt" ]; then
|
||||
echo "INFO: instance count is unexpectedly empty"
|
||||
if [ "$loop_cnt" = 0 ]; then
|
||||
echo "INFO: on the first iteration so no sample was found."
|
||||
echo "INFO: There is likely a problem with the sed filter."
|
||||
echo "INFO: start of jmap output:"
|
||||
cat "$TEST_NAME.jmap"
|
||||
echo "INFO: end of jmap output."
|
||||
echo "FAIL: cannot find the instance count value." >&2
|
||||
killApplication
|
||||
exit 2
|
||||
fi
|
||||
else
|
||||
echo "INFO: instance_cnt = $instance_cnt"
|
||||
|
||||
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
|
||||
|
||||
# delay between samples
|
||||
sleep 5
|
||||
|
||||
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
|
||||
echo "INFO: is always increasing."
|
||||
echo "FAIL: This indicates that there is a memory leak." >&2
|
||||
exit 2
|
||||
fi
|
||||
|
||||
echo "INFO: is not always increasing."
|
||||
echo "PASS: This indicates that there is not a memory leak."
|
||||
exit 0
|
@ -1,102 +0,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.
|
||||
*/
|
||||
|
||||
import java.util.logging.*;
|
||||
|
||||
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
|
||||
|
||||
// execute the LoggerWeakRefLeak app work
|
||||
public void doMyAppWork(String[] args) throws Exception {
|
||||
int loop_time = 0;
|
||||
int max_loop_time = DEFAULT_LOOP_TIME;
|
||||
|
||||
// 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[1]);
|
||||
} catch (NumberFormatException nfe) {
|
||||
throw new RuntimeException("Error: '" + args[1]
|
||||
+ "': is not a valid seconds value.");
|
||||
}
|
||||
}
|
||||
|
||||
long count = 0;
|
||||
int loggerCount = 0;
|
||||
long now = 0;
|
||||
long startTime = System.currentTimeMillis();
|
||||
|
||||
while (now < (startTime + (max_loop_time * 1000))) {
|
||||
if ((count % 1000) == 0) {
|
||||
// Print initial call count to let caller know that
|
||||
// we're up and running and then periodically
|
||||
System.out.println("INFO: call count = " + count);
|
||||
}
|
||||
|
||||
for (int i = 0; i < 100; i++) {
|
||||
// This Logger call is leaking two different WeakReferences:
|
||||
// - one in LogManager.LogNode
|
||||
// - one in Logger.kids
|
||||
java.util.logging.Logger.getLogger("logger-" + loggerCount);
|
||||
count++;
|
||||
if (++loggerCount >= 25000) {
|
||||
// Limit the Logger namespace used by the test so
|
||||
// the weak refs in LogManager.loggers that are
|
||||
// being properly managed don't skew the counts
|
||||
// by too much.
|
||||
loggerCount = 0;
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
// delay for 1/10 of a second to avoid CPU saturation
|
||||
Thread.sleep(100);
|
||||
} catch (InterruptedException ie) {
|
||||
// ignore any exceptions
|
||||
}
|
||||
|
||||
now = System.currentTimeMillis();
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
@ -1,254 +0,0 @@
|
||||
#!/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 6942989
|
||||
# @summary Check for WeakReference leak in Logger objects
|
||||
# @author Daniel D. Daugherty
|
||||
#
|
||||
# @library ../../../sun/tools/common
|
||||
# @build SimpleApplication ShutdownSimpleApplication
|
||||
# @build LoggerWeakRefLeak
|
||||
# @run shell/timeout=240 LoggerWeakRefLeak.sh
|
||||
|
||||
# The timeout is: 2 minutes for infrastructure and 2 minutes for the test
|
||||
#
|
||||
|
||||
. ${TESTSRC}/../../../sun/tools/common/CommonSetup.sh
|
||||
. ${TESTSRC}/../../../sun/tools/common/ApplicationSetup.sh
|
||||
|
||||
|
||||
TEST_NAME="LoggerWeakRefLeak"
|
||||
TARGET_CLASS="java\.lang\.ref\.WeakReference"
|
||||
|
||||
|
||||
# MAIN begins here
|
||||
#
|
||||
|
||||
seconds=
|
||||
if [ "$#" -gt 0 ]; then
|
||||
seconds="$1"
|
||||
fi
|
||||
|
||||
# see if this version of jmap supports the '-histo:live' option
|
||||
jmap_option="-histo:live"
|
||||
set +e
|
||||
"${JMAP}" 2>&1 | grep ':live' > /dev/null 2>&1
|
||||
status="$?"
|
||||
set -e
|
||||
if [ "$status" != 0 ]; then
|
||||
# usage message doesn't show ':live' option
|
||||
|
||||
if $isWindows; then
|
||||
# If SA isn't present, then jmap gives a different usage message
|
||||
# that doesn't show the ':live' option. However, that's a bug that
|
||||
# is covered by 6971851 so we try using the option just to be sure.
|
||||
# For some reason, this problem has only been seen on OpenJDK6 on
|
||||
# Windows. Not sure why.
|
||||
set +e
|
||||
# Note: Don't copy this code to try probing process 0 on Linux; it
|
||||
# will kill the process group in strange ways.
|
||||
"${JMAP}" "$jmap_option" 0 2>&1 | grep 'Usage' > /dev/null 2>&1
|
||||
status="$?"
|
||||
set -e
|
||||
if [ "$status" = 0 ]; then
|
||||
# Usage message generated so flag the problem.
|
||||
status=1
|
||||
else
|
||||
# No usage message so clear the flag.
|
||||
status=0
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ "$status" != 0 ]; then
|
||||
echo "WARNING: 'jmap $jmap_option' is not supported on this platform"
|
||||
echo "WARNING: so this test cannot work reliably. Aborting!"
|
||||
exit 0
|
||||
fi
|
||||
fi
|
||||
|
||||
# Start application and use TEST_NAME.port for coordination
|
||||
startApplication "$TEST_NAME" "$TEST_NAME.port" $seconds
|
||||
|
||||
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>
|
||||
#
|
||||
# Output format for 'jmap -histo:live':
|
||||
#
|
||||
# <num>: <#instances> <#bytes> <class_name>
|
||||
#
|
||||
set +e
|
||||
"${JMAP}" "$jmap_option" "$appJavaPid" > "$TEST_NAME.jmap" 2>&1
|
||||
status="$?"
|
||||
set -e
|
||||
|
||||
if [ "$status" != 0 ]; then
|
||||
echo "INFO: jmap exited with exit code = $status"
|
||||
|
||||
# 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
|
||||
killApplication
|
||||
exit 2
|
||||
fi
|
||||
|
||||
# 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
|
||||
|
||||
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/^'"${PATTERN_WS}${PATTERN_WS}"'*//
|
||||
# strip <#bytes> in JDK1.5.0; does nothing otherwise
|
||||
s/^[1-9][0-9]*'"${PATTERN_WS}${PATTERN_WS}"'*//
|
||||
# strip <num>: field; does nothing in JDK1.5.0
|
||||
s/^[1-9][0-9]*:'"${PATTERN_WS}${PATTERN_WS}"'*//
|
||||
# strip <class_name> field
|
||||
s/'"${PATTERN_WS}"'.*//
|
||||
'`
|
||||
set -e
|
||||
if [ -z "$instance_cnt" ]; then
|
||||
echo "INFO: instance count is unexpectedly empty"
|
||||
if [ "$loop_cnt" = 0 ]; then
|
||||
echo "INFO: on the first iteration so no sample was found."
|
||||
echo "INFO: There is likely a problem with the sed filter."
|
||||
echo "INFO: start of jmap output:"
|
||||
cat "$TEST_NAME.jmap"
|
||||
echo "INFO: end of jmap output."
|
||||
echo "FAIL: cannot find the instance count value." >&2
|
||||
killApplication
|
||||
exit 2
|
||||
fi
|
||||
else
|
||||
echo "INFO: instance_cnt = $instance_cnt"
|
||||
|
||||
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
|
||||
|
||||
# delay between samples
|
||||
sleep 5
|
||||
|
||||
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
|
||||
echo "INFO: is always increasing."
|
||||
echo "FAIL: This indicates that there is a memory leak." >&2
|
||||
exit 2
|
||||
fi
|
||||
|
||||
echo "INFO: is not always increasing."
|
||||
echo "PASS: This indicates that there is not a memory leak."
|
||||
exit 0
|
164
jdk/test/java/util/logging/TestLoggerWeakRefLeak.java
Normal file
164
jdk/test/java/util/logging/TestLoggerWeakRefLeak.java
Normal file
@ -0,0 +1,164 @@
|
||||
/*
|
||||
* Copyright (c) 2010, 2014, 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.
|
||||
*/
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
|
||||
import static jdk.testlibrary.Asserts.assertGreaterThan;
|
||||
import jdk.testlibrary.ProcessTools;
|
||||
|
||||
import com.sun.tools.attach.AttachNotSupportedException;
|
||||
import com.sun.tools.attach.VirtualMachine;
|
||||
|
||||
import sun.tools.attach.HotSpotVirtualMachine;
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 6942989
|
||||
* @summary Check for WeakReference leak in Logger and anonymous Logger objects
|
||||
* @library /lib/testlibrary
|
||||
* @build jdk.testlibrary.*
|
||||
* @run main/othervm TestLoggerWeakRefLeak Logger
|
||||
* @run main/othervm TestLoggerWeakRefLeak AnonymousLogger
|
||||
*/
|
||||
public class TestLoggerWeakRefLeak {
|
||||
|
||||
private static final String TARGET_CLASS = "java.lang.ref.WeakReference";
|
||||
private static final int INSTANCE_COUNT = 100;
|
||||
private static int loggerCount = 0;
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
if (args[0].equals("AnonymousLogger")) {
|
||||
System.out.println("Test for WeakReference leak in AnonymousLogger object");
|
||||
testIfLeaking(TestLoggerWeakRefLeak::callAnonymousLogger);
|
||||
} else {
|
||||
System.out.println("Test for WeakReference leak in Logger object");
|
||||
testIfLeaking(TestLoggerWeakRefLeak::callLogger);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* For these particular WeakReference leaks, the count was always observed
|
||||
* to be increasing so if decreasing or the same count is observed,
|
||||
* then there is no leak.
|
||||
*/
|
||||
private static void testIfLeaking(Runnable callLogger) throws Exception {
|
||||
long count = 0;
|
||||
int instanceCount = 0;
|
||||
int previousInstanceCount = 0;
|
||||
int increasingCount = 0;
|
||||
int decreasingCount = 0;
|
||||
|
||||
while (true) {
|
||||
callLogger.run();
|
||||
count += INSTANCE_COUNT;
|
||||
|
||||
if ((count % 1000) == 0) {
|
||||
System.out.println("call count = " + count);
|
||||
|
||||
instanceCount = getInstanceCountFromHeapHisto();
|
||||
if (instanceCount > previousInstanceCount) {
|
||||
increasingCount++;
|
||||
} else {
|
||||
decreasingCount++;
|
||||
System.out.println("increasing count: " + increasingCount);
|
||||
System.out.println("decreasing or the same count: " + decreasingCount);
|
||||
System.out.println("Test passed: decreasing or the same instance count is observed");
|
||||
break;
|
||||
}
|
||||
previousInstanceCount = instanceCount;
|
||||
}
|
||||
|
||||
delayExecution();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This Logger call is leaking two different WeakReferences:
|
||||
* - one in LogManager.LogNode
|
||||
* - one in Logger.kids
|
||||
*/
|
||||
private static void callLogger() {
|
||||
for (int i = 0; i < INSTANCE_COUNT; i++) {
|
||||
java.util.logging.Logger.getLogger("logger-" + loggerCount);
|
||||
if (++loggerCount >= 25000) {
|
||||
// Limit the Logger namespace used by the test so the weak refs
|
||||
// in LogManager.loggers that are being properly managed
|
||||
// don't skew the counts by too much.
|
||||
loggerCount = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This Logger call is leaking a WeakReference in Logger.kids
|
||||
*/
|
||||
private static void callAnonymousLogger() {
|
||||
for (int i = 0; i < INSTANCE_COUNT; i++) {
|
||||
java.util.logging.Logger.getAnonymousLogger();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 'vm.heapHisto("-live")' will request a full GC
|
||||
*/
|
||||
private static int getInstanceCountFromHeapHisto() throws AttachNotSupportedException, Exception {
|
||||
int instanceCount = 0;
|
||||
|
||||
HotSpotVirtualMachine vm = (HotSpotVirtualMachine) VirtualMachine
|
||||
.attach(Integer.toString(ProcessTools.getProcessId()));
|
||||
try {
|
||||
try (InputStream heapHistoStream = vm.heapHisto("-live");
|
||||
BufferedReader in = new BufferedReader(new InputStreamReader(heapHistoStream))) {
|
||||
String inputLine;
|
||||
while ((inputLine = in.readLine()) != null) {
|
||||
if (inputLine.contains(TARGET_CLASS)) {
|
||||
instanceCount = Integer.parseInt(inputLine
|
||||
.split("[ ]+")[2]);
|
||||
System.out.println("instance count: " + instanceCount);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
vm.detach();
|
||||
}
|
||||
|
||||
assertGreaterThan(instanceCount, 0, "No instances of " + TARGET_CLASS + " are found");
|
||||
|
||||
return instanceCount;
|
||||
}
|
||||
|
||||
/**
|
||||
* Delay for 1/10 of a second to avoid CPU saturation
|
||||
*/
|
||||
private static void delayExecution() {
|
||||
try {
|
||||
Thread.sleep(100);
|
||||
} catch (InterruptedException ie) {
|
||||
// Ignore any exceptions
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,49 @@
|
||||
/*
|
||||
* Copyright (c) 2014, 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.
|
||||
*/
|
||||
package jdk.testlibrary;
|
||||
|
||||
import java.util.function.Predicate;
|
||||
/**
|
||||
* A classloader, which using target classloader in case provided condition
|
||||
* for class name is met, and using parent otherwise
|
||||
*/
|
||||
public class FilterClassLoader extends ClassLoader {
|
||||
|
||||
private final ClassLoader target;
|
||||
private final Predicate<String> condition;
|
||||
|
||||
public FilterClassLoader(ClassLoader target, ClassLoader parent,
|
||||
Predicate<String> condition) {
|
||||
super(parent);
|
||||
this.condition = condition;
|
||||
this.target = target;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<?> loadClass(String name) throws ClassNotFoundException {
|
||||
if (condition.test(name)) {
|
||||
return target.loadClass(name);
|
||||
}
|
||||
return super.loadClass(name);
|
||||
}
|
||||
}
|
@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Copyright (c) 2014, 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.
|
||||
*/
|
||||
package jdk.testlibrary;
|
||||
|
||||
import java.net.URL;
|
||||
import java.net.URLClassLoader;
|
||||
|
||||
/**
|
||||
* An url classloader, which trying to load class from provided URL[] first,
|
||||
* and using parent classloader in case it failed
|
||||
*/
|
||||
public class ParentLastURLClassLoader extends URLClassLoader {
|
||||
|
||||
public ParentLastURLClassLoader(URL urls[], ClassLoader parent) {
|
||||
super(urls, parent);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<?> loadClass(String name) throws ClassNotFoundException {
|
||||
try {
|
||||
Class c = findClass(name);
|
||||
if (c != null) {
|
||||
return c;
|
||||
}
|
||||
} catch (ClassNotFoundException e) {
|
||||
// ignore
|
||||
}
|
||||
return super.loadClass(name);
|
||||
}
|
||||
}
|
@ -28,6 +28,15 @@ public class Platform {
|
||||
private static final String dataModel = System.getProperty("sun.arch.data.model");
|
||||
private static final String vmVersion = System.getProperty("java.vm.version");
|
||||
private static final String osArch = System.getProperty("os.arch");
|
||||
private static final String vmName = System.getProperty("java.vm.name");
|
||||
|
||||
public static boolean isClient() {
|
||||
return vmName.endsWith(" Client VM");
|
||||
}
|
||||
|
||||
public static boolean isServer() {
|
||||
return vmName.endsWith(" Server VM");
|
||||
}
|
||||
|
||||
public static boolean is32bit() {
|
||||
return dataModel.equals("32");
|
||||
|
@ -39,6 +39,7 @@ import java.util.Collections;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.function.BooleanSupplier;
|
||||
|
||||
/**
|
||||
* Common library for various test helper functions.
|
||||
@ -270,25 +271,6 @@ public final class Utils {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns file content as a list of strings
|
||||
*
|
||||
* @param file File to operate on
|
||||
* @return List of strings
|
||||
* @throws IOException
|
||||
*/
|
||||
public static List<String> fileAsList(File file) throws IOException {
|
||||
assertTrue(file.exists() && file.isFile(),
|
||||
file.getAbsolutePath() + " does not exist or not a file");
|
||||
List<String> output = new ArrayList<>();
|
||||
try (BufferedReader reader = new BufferedReader(new FileReader(file.getAbsolutePath()))) {
|
||||
while (reader.ready()) {
|
||||
output.add(reader.readLine().replace(NEW_LINE, ""));
|
||||
}
|
||||
}
|
||||
return output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adjusts the provided timeout value for the TIMEOUT_FACTOR
|
||||
* @param tOut the timeout value to be adjusted
|
||||
@ -298,4 +280,50 @@ public final class Utils {
|
||||
public static long adjustTimeout(long tOut) {
|
||||
return Math.round(tOut * Utils.TIMEOUT_FACTOR);
|
||||
}
|
||||
|
||||
/**
|
||||
* Wait for condition to be true
|
||||
*
|
||||
* @param condition, a condition to wait for
|
||||
*/
|
||||
public static final void waitForCondition(BooleanSupplier condition) {
|
||||
waitForCondition(condition, -1L, 100L);
|
||||
}
|
||||
|
||||
/**
|
||||
* Wait until timeout for condition to be true
|
||||
*
|
||||
* @param condition, a condition to wait for
|
||||
* @param timeout a time in milliseconds to wait for condition to be true
|
||||
* specifying -1 will wait forever
|
||||
* @return condition value, to determine if wait was successfull
|
||||
*/
|
||||
public static final boolean waitForCondition(BooleanSupplier condition,
|
||||
long timeout) {
|
||||
return waitForCondition(condition, timeout, 100L);
|
||||
}
|
||||
|
||||
/**
|
||||
* Wait until timeout for condition to be true for specified time
|
||||
*
|
||||
* @param condition, a condition to wait for
|
||||
* @param timeout a time in milliseconds to wait for condition to be true,
|
||||
* specifying -1 will wait forever
|
||||
* @param sleepTime a time to sleep value in milliseconds
|
||||
* @return condition value, to determine if wait was successfull
|
||||
*/
|
||||
public static final boolean waitForCondition(BooleanSupplier condition,
|
||||
long timeout, long sleepTime) {
|
||||
long startTime = System.currentTimeMillis();
|
||||
while (!(condition.getAsBoolean() || (timeout != -1L
|
||||
&& ((System.currentTimeMillis() - startTime) > timeout)))) {
|
||||
try {
|
||||
Thread.sleep(sleepTime);
|
||||
} catch (InterruptedException e) {
|
||||
Thread.currentThread().interrupt();
|
||||
throw new Error(e);
|
||||
}
|
||||
}
|
||||
return condition.getAsBoolean();
|
||||
}
|
||||
}
|
||||
|
@ -1,314 +0,0 @@
|
||||
#!/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
|
@ -25,6 +25,9 @@ import static jdk.testlibrary.Asserts.*;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.List;
|
||||
|
||||
import jdk.testlibrary.JcmdBase;
|
||||
@ -95,11 +98,11 @@ public class TestJcmdDefaults {
|
||||
}
|
||||
|
||||
private static void verifyOutputAgainstFile(OutputAnalyzer output) throws IOException {
|
||||
File file = new File(TEST_SRC, "usage.out");
|
||||
List<String> fileOutput = Utils.fileAsList(file);
|
||||
Path path = Paths.get(TEST_SRC, "usage.out");
|
||||
List<String> fileOutput = Files.readAllLines(path);
|
||||
List<String> outputAsLines = output.asLines();
|
||||
assertTrue(outputAsLines.containsAll(fileOutput),
|
||||
"The ouput should contain all content of " + file.getAbsolutePath());
|
||||
"The ouput should contain all content of " + path.toAbsolutePath());
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -25,6 +25,9 @@ import static jdk.testlibrary.Asserts.*;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.List;
|
||||
|
||||
import jdk.testlibrary.JcmdBase;
|
||||
@ -160,11 +163,11 @@ public class TestJcmdSanity {
|
||||
}
|
||||
|
||||
private static void verifyOutputAgainstFile(OutputAnalyzer output) throws IOException {
|
||||
File file = new File(TEST_SRC, "help_help.out");
|
||||
List<String> fileOutput = Utils.fileAsList(file);
|
||||
Path path = Paths.get(TEST_SRC, "help_help.out");
|
||||
List<String> fileOutput = Files.readAllLines(path);
|
||||
List<String> outputAsLines = output.asLines();
|
||||
assertTrue(outputAsLines.containsAll(fileOutput),
|
||||
"The ouput should contain all content of " + file.getAbsolutePath());
|
||||
"The ouput should contain all content of " + path.toAbsolutePath());
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -28,6 +28,9 @@ import java.io.BufferedWriter;
|
||||
import java.io.File;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
@ -189,11 +192,11 @@ public final class JpsHelper {
|
||||
*/
|
||||
public static void verifyOutputAgainstFile(OutputAnalyzer output) throws IOException {
|
||||
String testSrc = System.getProperty("test.src", "?");
|
||||
File file = new File(testSrc, "usage.out");
|
||||
List<String> fileOutput = Utils.fileAsList(file);
|
||||
Path path = Paths.get(testSrc, "usage.out");
|
||||
List<String> fileOutput = Files.readAllLines(path);
|
||||
List<String> outputAsLines = output.asLines();
|
||||
assertTrue(outputAsLines.containsAll(fileOutput),
|
||||
"The ouput should contain all content of " + file.getAbsolutePath());
|
||||
"The ouput should contain all content of " + path.toAbsolutePath());
|
||||
}
|
||||
|
||||
private static File getManifest(String className) throws IOException {
|
||||
|
Loading…
Reference in New Issue
Block a user