1 /* 2 * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 24 import java.io.File; 25 import java.net.URL; 26 import java.util.List; 27 28 import jdk.testlibrary.OutputAnalyzer; 29 import jdk.testlibrary.ProcessTools; 30 31 /** 32 * The base class for testing the jps utility. 33 * The test sequence is to start jps with different combinations of arguments 34 * and verify the output contains proper values. 35 */ 36 public final class JpsBase { 37 38 /** 39 * The jps output should contain processes' names 40 * (except when jps is started in quite mode). 41 * The expected name of the test process is prepared here. 42 */ 43 44 private static String getShortProcessName() { 45 URL url = JpsBase.class.getResource("JpsBase.class"); 46 boolean isJar = url.getProtocol().equals("jar"); 47 return (isJar) ? JpsBase.class.getSimpleName() + ".jar" : JpsBase.class.getSimpleName(); 48 } 49 50 private static String getFullProcessName() { 51 URL url = JpsBase.class.getResource("JpsBase.class"); 52 boolean isJar = url.getProtocol().equals("jar"); 53 if (isJar) { 54 String urlPath = url.getPath(); 55 File jar = new File(urlPath.substring(urlPath.indexOf("file:") + 5, urlPath.indexOf("jar!") + 3)); 56 return jar.getAbsolutePath(); 57 } 58 59 return JpsBase.class.getName(); 60 } 61 62 private static boolean userDirSanityCheck(String fullProcessName) { 63 String userDir = System.getProperty("user.dir"); 64 if (!fullProcessName.startsWith(userDir)) { 65 System.err.printf("Test skipped. user.dir '%s' is not a prefix of '%s'\n", userDir, fullProcessName); 66 return false; 67 } 68 return true; 69 } 70 71 public static void main(String[] args) throws Exception { 72 System.out.printf("INFO: user.dir: '%s''\n", System.getProperty("user.dir")); 73 long pid = ProcessTools.getProcessId(); 74 75 List<List<JpsHelper.JpsArg>> combinations = JpsHelper.JpsArg.generateCombinations(); 76 for (List<JpsHelper.JpsArg> combination : combinations) { 77 OutputAnalyzer output = JpsHelper.jps(JpsHelper.JpsArg.asCmdArray(combination)); 78 output.shouldHaveExitValue(0); 79 80 boolean isQuiet = false; 81 boolean isFull = false; 82 String pattern; 83 for (JpsHelper.JpsArg jpsArg : combination) { 84 switch (jpsArg) { 85 case q: 86 // If '-q' is specified output should contain only a list of local VM identifiers: 87 // 30673 88 isQuiet = true; 89 JpsHelper.verifyJpsOutput(output, "^\\d+$"); 90 output.shouldContain(Long.toString(pid)); 91 break; 92 case l: 93 // If '-l' is specified output should contain the full package name for the application's main class 94 // or the full path name to the application's JAR file: 95 // 30673 /tmp/jtreg/jtreg-workdir/scratch/JpsBase.jar ... 96 isFull = true; 97 String fullProcessName = getFullProcessName(); 98 // Skip the test if user.dir is not a prefix of the current path 99 // It's possible if the test is run from symlinked dir or windows alias drive 100 if (userDirSanityCheck(fullProcessName)) { 101 pattern = "^" + pid + "\\s+" + replaceSpecialChars(fullProcessName) + ".*"; 102 output.shouldMatch(pattern); 103 } 104 break; 105 case m: 106 // If '-m' is specified output should contain the arguments passed to the main method: 107 // 30673 JpsBase monkey ... 108 for (String arg : args) { 109 pattern = "^" + pid + ".*" + replaceSpecialChars(arg) + ".*"; 110 output.shouldMatch(pattern); 111 } 112 break; 113 case v: 114 // If '-v' is specified output should contain VM arguments: 115 // 30673 JpsBase -Xmx512m -XX:+UseParallelGC -XX:Flags=/tmp/jtreg/jtreg-workdir/scratch/vmflags ... 116 for (String vmArg : JpsHelper.getVmArgs()) { 117 pattern = "^" + pid + ".*" + replaceSpecialChars(vmArg) + ".*"; 118 output.shouldMatch(pattern); 119 } 120 break; 121 case V: 122 // If '-V' is specified output should contain VM flags: 123 // 30673 JpsBase +DisableExplicitGC ... 124 pattern = "^" + pid + ".*" + replaceSpecialChars(JpsHelper.VM_FLAG) + ".*"; 125 output.shouldMatch(pattern); 126 break; 127 } 128 129 if (isQuiet) { 130 break; 131 } 132 } 133 134 if (!isQuiet) { 135 // Verify output line by line. 136 // Output should only contain lines with pids after the first line with pid. 137 JpsHelper.verifyJpsOutput(output, "^\\d+\\s+.*"); 138 if (!isFull) { 139 String shortProcessName = getShortProcessName(); 140 pattern = "^" + pid + "\\s+" + replaceSpecialChars(shortProcessName); 141 if (combination.isEmpty()) { 142 // If no arguments are specified output should only contain 143 // pid and process name 144 pattern += "$"; 145 } else { 146 pattern += ".*"; 147 } 148 output.shouldMatch(pattern); 149 } 150 } 151 } 152 } 153 154 private static String replaceSpecialChars(String str) { 155 String tmp = str.replace("\\", "\\\\"); 156 tmp = tmp.replace("+", "\\+"); 157 tmp = tmp.replace(".", "\\."); 158 tmp = tmp.replace("\n", "\\\\n"); 159 tmp = tmp.replace("\r", "\\\\r"); 160 return tmp; 161 } 162 163 }