# HG changeset patch # User ykantser # Date 1432730155 -7200 # Node ID 483cbf74cf0883bc386977f83d6f7ca20cb45548 # Parent c847a158d3ec025e7a0a448124543173e1addb6a 8081037: serviceability/sa/ tests time out on Windows Reviewed-by: jbachorik, sla, dsamersoff diff -r c847a158d3ec -r 483cbf74cf08 jdk/test/sun/tools/jmap/heapconfig/JMapHeapConfigTest.java --- a/jdk/test/sun/tools/jmap/heapconfig/JMapHeapConfigTest.java Thu May 28 15:03:57 2015 -0700 +++ b/jdk/test/sun/tools/jmap/heapconfig/JMapHeapConfigTest.java Wed May 27 14:35:55 2015 +0200 @@ -21,25 +21,29 @@ * questions. */ -/* - * @test - * @bug 8042397 - * @summary Unit test for jmap utility test heap configuration reader - * @library /lib/testlibrary - * @modules java.management - * @build jdk.testlibrary.* - * @build JMapHeapConfigTest LingeredApp TmtoolTestScenario - * @run main JMapHeapConfigTest - */ import java.io.IOException; import java.math.BigDecimal; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; + +import jdk.test.lib.apps.LingeredApp; import jdk.testlibrary.Utils; import jdk.testlibrary.Platform; +/* + * @test + * @bug 8042397 + * @summary Unit test for jmap utility test heap configuration reader + * @library /../../test/lib/share/classes + * @library /lib/testlibrary + * @modules java.management + * @build jdk.testlibrary.* + * @build jdk.test.lib.apps.* + * @build JMapHeapConfigTest TmtoolTestScenario + * @run main JMapHeapConfigTest + */ public class JMapHeapConfigTest { static final String expectedJMapValues[] = { diff -r c847a158d3ec -r 483cbf74cf08 jdk/test/sun/tools/jmap/heapconfig/LingeredApp.java --- a/jdk/test/sun/tools/jmap/heapconfig/LingeredApp.java Thu May 28 15:03:57 2015 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,431 +0,0 @@ -/* - * Copyright (c) 2015, 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.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.nio.file.Files; -import java.nio.file.NoSuchFileException; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.nio.file.attribute.BasicFileAttributes; -import java.nio.file.attribute.FileTime; -import java.util.ArrayList; -import java.util.Date; -import java.util.List; -import java.util.Map; -import java.util.UUID; - -/** - * This is a framework to launch an app that could be synchronized with caller - * to make further attach actions reliable across supported platforms - - * Caller example: - * SmartTestApp a = SmartTestApp.startApp(cmd); - * // do something - * a.stopApp(); - * - * or fine grained control - * - * a = new SmartTestApp("MyLock.lck"); - * a.createLock(); - * a.runApp(); - * a.waitAppReady(); - * // do something - * a.deleteLock(); - * a.waitAppTerminate(); - * - * Then you can work with app output and process object - * - * output = a.getAppOutput(); - * process = a.getProcess(); - * - */ -public class LingeredApp { - - private static final long spinDelay = 1000; - - private final String lockFileName; - private long lockCreationTime; - private Process appProcess; - private final ArrayList storedAppOutput; - - /* - * Drain child process output, store it into string array - */ - class InputGobbler extends Thread { - - InputStream is; - List astr; - - InputGobbler(InputStream is, List astr) { - this.is = is; - this.astr = astr; - } - - public void run() { - try { - InputStreamReader isr = new InputStreamReader(is); - BufferedReader br = new BufferedReader(isr); - String line = null; - while ((line = br.readLine()) != null) { - astr.add(line); - } - } catch (IOException ex) { - // pass - } - } - } - - /** - * Create LingeredApp object on caller side. Lock file have be a valid filename - * at writable location - * - * @param lockFileName - the name of lock file - */ - public LingeredApp(String lockFileName) { - this.lockFileName = lockFileName; - this.storedAppOutput = new ArrayList(); - } - - /** - * - * @return name of lock file - */ - public String getLockFileName() { - return this.lockFileName; - } - - /** - * - * @return name of testapp - */ - public String getAppName() { - return this.getClass().getName(); - } - - /** - * - * @return pid of java process running testapp - */ - public long getPid() { - if (appProcess == null) { - throw new RuntimeException("Process is not alive"); - } - return appProcess.getPid(); - } - - /** - * - * @return process object - */ - public Process getProcess() { - return appProcess; - } - - /** - * - * @return application output as string array. Empty array if application produced no output - */ - List getAppOutput() { - if (appProcess.isAlive()) { - throw new RuntimeException("Process is still alive. Can't get its output."); - } - return storedAppOutput; - } - - /* Make sure all part of the app use the same method to get dates, - as different methods could produce different results - */ - private static long epoch() { - return new Date().getTime(); - } - - private static long lastModified(String fileName) throws IOException { - Path path = Paths.get(fileName); - BasicFileAttributes attr = Files.readAttributes(path, BasicFileAttributes.class); - return attr.lastModifiedTime().toMillis(); - } - - private static void setLastModified(String fileName, long newTime) throws IOException { - Path path = Paths.get(fileName); - FileTime fileTime = FileTime.fromMillis(newTime); - Files.setLastModifiedTime(path, fileTime); - } - - /** - * create lock - * - * @throws IOException - */ - public void createLock() throws IOException { - Path path = Paths.get(lockFileName); - // Files.deleteIfExists(path); - Files.createFile(path); - lockCreationTime = lastModified(lockFileName); - } - - /** - * Delete lock - * - * @throws IOException - */ - public void deleteLock() throws IOException { - try { - Path path = Paths.get(lockFileName); - Files.delete(path); - } catch (NoSuchFileException ex) { - // Lock already deleted. Ignore error - } - } - - public void waitAppTerminate() { - while (true) { - try { - appProcess.waitFor(); - break; - } catch (InterruptedException ex) { - // pass - } - } - } - - /** - * The app touches the lock file when it's started - * wait while it happens. Caller have to delete lock on wait error. - * - * @param timeout - * @throws java.io.IOException - */ - public void waitAppReady(long timeout) throws IOException { - long here = epoch(); - while (true) { - long epoch = epoch(); - if (epoch - here > (timeout * 1000)) { - throw new IOException("App waiting timeout"); - } - - // Live process should touch lock file every second - long lm = lastModified(lockFileName); - if (lm > lockCreationTime) { - break; - } - - // Make sure process didn't already exit - if (!appProcess.isAlive()) { - throw new IOException("App exited unexpectedly with " + appProcess.exitValue()); - } - - try { - Thread.sleep(spinDelay); - } catch (InterruptedException ex) { - // pass - } - } - } - - /** - * Run the app - * - * @param vmArguments - * @throws IOException - */ - public void runApp(List vmArguments) - throws IOException { - - // We should always use testjava or throw an exception, - // so we can't use JDKToolFinder.getJDKTool("java"); - // that falls back to compile java on error - String jdkPath = System.getProperty("test.jdk"); - if (jdkPath == null) { - // we are not under jtreg, try env - Map env = System.getenv(); - jdkPath = env.get("TESTJAVA"); - } - - if (jdkPath == null) { - throw new RuntimeException("Can't determine jdk path neither test.jdk property no TESTJAVA env are set"); - } - - String osname = System.getProperty("os.name"); - String javapath = jdkPath + ((osname.startsWith("window")) ? "/bin/java.exe" : "/bin/java"); - - List cmd = new ArrayList(); - cmd.add(javapath); - - - if (vmArguments == null) { - // Propagate test.vm.options to LingeredApp, filter out possible empty options - String testVmOpts[] = System.getProperty("test.vm.opts","").split("\\s+"); - for (String s : testVmOpts) { - if (!s.equals("")) { - cmd.add(s); - } - } - } - else{ - // Lets user manage LingerApp options - cmd.addAll(vmArguments); - } - - // Make sure we set correct classpath to run the app - cmd.add("-cp"); - String classpath = System.getProperty("test.class.path"); - cmd.add((classpath == null) ? "." : classpath); - - cmd.add(this.getAppName()); - cmd.add(lockFileName); - - // Reporting - StringBuilder cmdLine = new StringBuilder(); - for (String strCmd : cmd) { - cmdLine.append("'").append(strCmd).append("' "); - } - - // A bit of verbosity - System.out.println("Command line: [" + cmdLine.toString() + "]"); - - ProcessBuilder pb = new ProcessBuilder(cmd); - // we don't expect any error output but make sure we are not stuck on pipe - // pb.redirectErrorStream(false); - pb.redirectError(ProcessBuilder.Redirect.INHERIT); - - appProcess = pb.start(); - - // Create pipe reader for process, and read stdin and stderr to array of strings - InputGobbler gb = new InputGobbler(appProcess.getInputStream(), storedAppOutput); - gb.start(); - } - - /** - * High level interface for test writers - */ - /** - * Factory method that creates SmartAppTest object with ready to use application - * lock name is autogenerated, wait timeout is hardcoded - * @param cmd - vm options, could be null to auto add testvm.options - * @return LingeredApp object - * @throws IOException - */ - public static LingeredApp startApp(List cmd) throws IOException { - final String lockName = UUID.randomUUID().toString() + ".lck"; - final int waitTime = 10; - - LingeredApp a = new LingeredApp(lockName); - a.createLock(); - try { - a.runApp(cmd); - a.waitAppReady(waitTime); - } catch (Exception ex) { - a.deleteLock(); - throw ex; - } - - return a; - } - - public static LingeredApp startApp() throws IOException { - return startApp(null); - } - - /** - * Delete lock file that signal app to terminate, then - * waits until app is actually terminated. - * @throws IOException - */ - public void stopApp() throws IOException { - deleteLock(); - waitAppTerminate(); - int exitcode = appProcess.exitValue(); - if (exitcode != 0) { - throw new IOException("LingeredApp terminated with non-zero exit code " + exitcode); - } - } - - /** - * LastModified time might not work correctly in some cases it might - * cause later failures - */ - - public static boolean isLastModifiedWorking() { - boolean sane = true; - try { - long lm = lastModified("."); - if (lm == 0) { - System.err.println("SANITY Warning! The lastModifiedTime() doesn't work on this system, it returns 0"); - sane = false; - } - - long now = epoch(); - if (lm > now) { - System.err.println("SANITY Warning! The Clock is wrong on this system lastModifiedTime() > getTime()"); - sane = false; - } - - setLastModified(".", epoch()); - long lm1 = lastModified("."); - if (lm1 <= lm) { - System.err.println("SANITY Warning! The setLastModified doesn't work on this system"); - sane = false; - } - } - catch(IOException e) { - System.err.println("SANITY Warning! IOException during sanity check " + e); - sane = false; - } - - return sane; - } - - /** - * This part is the application it self - */ - public static void main(String args[]) { - - if (args.length != 1) { - System.err.println("Lock file name is not specified"); - System.exit(7); - } - - String theLockFileName = args[0]; - - try { - Path path = Paths.get(theLockFileName); - - while (Files.exists(path)) { - // Touch the lock to indicate our readiness - setLastModified(theLockFileName, epoch()); - Thread.sleep(spinDelay); - } - } catch (NoSuchFileException ex) { - // Lock deleted while we are setting last modified time. - // Ignore error and lets the app exits - } catch (Exception ex) { - System.err.println("LingeredApp ERROR: " + ex); - // Leave exit_code = 1 to Java launcher - System.exit(3); - } - - System.exit(0); - } -} diff -r c847a158d3ec -r 483cbf74cf08 jdk/test/sun/tools/jmap/heapconfig/LingeredAppTest.java --- a/jdk/test/sun/tools/jmap/heapconfig/LingeredAppTest.java Thu May 28 15:03:57 2015 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,70 +0,0 @@ -/* - * Copyright (c) 2015, 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 - * @summary Unit test for LingeredApp - * @compile LingeredAppTest.java - * @compile LingeredApp.java - * @run main LingeredAppTest - */ -import java.io.IOException; -import java.util.ArrayList; -import java.util.Arrays; - -public class LingeredAppTest { - - public static void main(String[] args) { - try { - System.out.println("Starting LingeredApp with default parameters"); - - ArrayList cmd = new ArrayList(); - - // Propagate test.vm.options to LingeredApp, filter out possible empty options - String testVmOpts[] = System.getProperty("test.vm.opts","").split("\\s+"); - for (String s : testVmOpts) { - if (!s.equals("")) { - cmd.add(s); - } - } - - cmd.add("-XX:+PrintFlagsFinal"); - - LingeredApp a = LingeredApp.startApp(cmd); - System.out.printf("App pid: %d\n", a.getPid()); - a.stopApp(); - - System.out.println("App output:"); - int count = 0; - for (String line : a.getAppOutput()) { - count += 1; - } - System.out.println("Found " + count + " lines in VM output"); - System.out.println("Test PASSED"); - } catch (IOException ex) { - ex.printStackTrace(); - System.out.println("Test ERROR"); - System.exit(3); - } - } -} diff -r c847a158d3ec -r 483cbf74cf08 jdk/test/sun/tools/jmap/heapconfig/TmtoolTestScenario.java --- a/jdk/test/sun/tools/jmap/heapconfig/TmtoolTestScenario.java Thu May 28 15:03:57 2015 -0700 +++ b/jdk/test/sun/tools/jmap/heapconfig/TmtoolTestScenario.java Wed May 27 14:35:55 2015 +0200 @@ -31,6 +31,8 @@ import java.util.Map; import java.util.logging.Level; import java.util.logging.Logger; + +import jdk.test.lib.apps.LingeredApp; import jdk.testlibrary.JDKToolLauncher; import jdk.testlibrary.Utils;