23 |
23 |
24 import java.io.IOException; |
24 import java.io.IOException; |
25 import java.io.File; |
25 import java.io.File; |
26 import java.nio.file.Files; |
26 import java.nio.file.Files; |
27 import java.util.Arrays; |
27 import java.util.Arrays; |
28 import java.util.regex.Pattern; |
|
29 import java.util.regex.Matcher; |
|
30 |
28 |
31 import jdk.testlibrary.OutputAnalyzer; |
|
32 import jdk.testlibrary.ProcessTools; |
29 import jdk.testlibrary.ProcessTools; |
33 import jdk.testlibrary.Utils; |
30 import jdk.testlibrary.Utils; |
34 import jdk.testlibrary.ProcessThread; |
31 import jdk.testlibrary.ProcessThread; |
35 |
32 |
36 /* |
33 /* |
47 * The Application must be started with flag "-Xshare:off" for the Retransform |
44 * The Application must be started with flag "-Xshare:off" for the Retransform |
48 * test in TestBasics to pass on all platforms. |
45 * test in TestBasics to pass on all platforms. |
49 * |
46 * |
50 * The Application will write its pid and shutdownPort in the given outFile. |
47 * The Application will write its pid and shutdownPort in the given outFile. |
51 */ |
48 */ |
52 public static ProcessThread startApplication(String outFile, String... additionalOpts) throws Throwable { |
49 public static ProcessThread startApplication(String... additionalOpts) throws Throwable { |
53 String classpath = System.getProperty("test.class.path", "."); |
50 String classpath = System.getProperty("test.class.path", "."); |
54 String[] myArgs = concat(additionalOpts, new String [] { "-Dattach.test=true", "-classpath", classpath, "Application", outFile }); |
51 String[] myArgs = concat(additionalOpts, new String [] { "-Dattach.test=true", "-classpath", classpath, "Application" }); |
55 String[] args = Utils.addTestJavaOpts(myArgs); |
52 String[] args = Utils.addTestJavaOpts(myArgs); |
56 ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(args); |
53 ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(args); |
57 ProcessThread pt = new ProcessThread("runApplication", pb); |
54 ProcessThread pt = new ProcessThread("runApplication", (line) -> line.equals(Application.READY_MSG), pb); |
58 pt.start(); |
55 pt.start(); |
59 return pt; |
56 return pt; |
60 } |
57 } |
61 |
58 |
62 public static String[] concat(String[] a, String[] b) { |
59 public static String[] concat(String[] a, String[] b) { |
79 * First tries to shutdown nicely by connecting to the shut down port. |
76 * First tries to shutdown nicely by connecting to the shut down port. |
80 * If that fails, the process will be killed hard with stopProcess(). |
77 * If that fails, the process will be killed hard with stopProcess(). |
81 * |
78 * |
82 * If the nice shutdown fails, then an Exception is thrown and the test should fail. |
79 * If the nice shutdown fails, then an Exception is thrown and the test should fail. |
83 * |
80 * |
84 * @param port The shut down port. |
|
85 * @param processThread The process to stop. |
81 * @param processThread The process to stop. |
86 */ |
82 */ |
87 public static void stopApplication(int port, ProcessThread processThread) throws Throwable { |
83 public static void stopApplication(ProcessThread processThread) throws Throwable { |
88 if (processThread == null) { |
84 if (processThread == null) { |
89 System.out.println("RunnerUtil.stopApplication ignored since proc is null"); |
85 System.out.println("RunnerUtil.stopApplication ignored since proc is null"); |
90 return; |
86 return; |
91 } |
87 } |
92 try { |
88 try { |
93 System.out.println("RunnerUtil.stopApplication waiting to for shutdown"); |
89 System.out.println("RunnerUtil.stopApplication waiting for shutdown"); |
94 OutputAnalyzer output = ProcessTools.executeTestJvm( |
90 processThread.sendMessage(Application.SHUTDOWN_MSG); |
95 "-classpath", |
|
96 System.getProperty("test.class.path", "."), |
|
97 "Shutdown", |
|
98 Integer.toString(port)); |
|
99 // Verify that both the Shutdown command and the Application finished ok. |
|
100 output.shouldHaveExitValue(0); |
|
101 processThread.joinAndThrow(); |
91 processThread.joinAndThrow(); |
102 processThread.getOutput().shouldHaveExitValue(0); |
92 processThread.getOutput().shouldHaveExitValue(0); |
103 } catch (Throwable t) { |
93 } catch (Throwable t) { |
104 System.out.println("RunnerUtil.stopApplication failed. Will kill it hard: " + t); |
94 System.out.println("RunnerUtil.stopApplication failed. Will kill it hard: " + t); |
105 processThread.stopProcess(); |
95 processThread.stopProcess(); |
118 throw new RuntimeException("jar failed: args=" + Arrays.toString(args)); |
108 throw new RuntimeException("jar failed: args=" + Arrays.toString(args)); |
119 } |
109 } |
120 } |
110 } |
121 |
111 |
122 /** |
112 /** |
123 * Read process info for the running Application. |
|
124 * The Application writes its info to a file with this format: |
|
125 * shutdownPort=42994 |
|
126 * pid=19597 |
|
127 * done |
|
128 * |
|
129 * The final "done" is used to make sure the complete file has been written |
|
130 * before we try to read it. |
|
131 * This function will wait until the file is available. |
|
132 * |
|
133 * @param filename Path to file to read. |
|
134 * @return The ProcessInfo containing pid and shutdownPort. |
|
135 */ |
|
136 public static ProcessInfo readProcessInfo(String filename) throws Throwable { |
|
137 System.out.println("Reading port and pid from file: " + filename); |
|
138 File file = new File(filename); |
|
139 String content = null; |
|
140 |
|
141 // Read file or wait for it to be created. |
|
142 long startTime = System.currentTimeMillis(); |
|
143 long lastWarningTime = 0; |
|
144 while (true) { |
|
145 content = readFile(file); |
|
146 if (content != null && content.indexOf("done") >= 0) { |
|
147 break; |
|
148 } |
|
149 Thread.sleep(100); |
|
150 long elapsedTime = (System.currentTimeMillis() - startTime) / 1000; |
|
151 if (elapsedTime > lastWarningTime) { |
|
152 lastWarningTime = elapsedTime; |
|
153 System.out.println("Waited " + elapsedTime + " seconds for file."); |
|
154 } |
|
155 } |
|
156 |
|
157 ProcessInfo info = new ProcessInfo(); |
|
158 // search for a line with format: key=nnn |
|
159 Pattern pattern = Pattern.compile("(\\w*)=([0-9]+)\\r?\\n"); |
|
160 Matcher matcher = pattern.matcher(content); |
|
161 while (matcher.find()) { |
|
162 String key = matcher.group(1); |
|
163 int value = Integer.parseInt(matcher.group(2)); |
|
164 if ("pid".equals(key)) { |
|
165 info.pid = value; |
|
166 } else if ("shutdownPort".equals(key)) { |
|
167 info.shutdownPort = value; |
|
168 } |
|
169 } |
|
170 System.out.println("processInfo.pid:" + info.pid); |
|
171 System.out.println("processInfo.shutdownPort:" + info.shutdownPort); |
|
172 return info; |
|
173 } |
|
174 |
|
175 /** |
|
176 * Read the content of a file. |
113 * Read the content of a file. |
177 * @param file The file to read. |
114 * @param file The file to read. |
178 * @return The file content or null if file does not exists. |
115 * @return The file content or null if file does not exists. |
179 */ |
116 */ |
180 public static String readFile(File file) throws IOException { |
117 public static String readFile(File file) throws IOException { |