55 |
55 |
56 import jdk.test.lib.process.OutputAnalyzer; |
56 import jdk.test.lib.process.OutputAnalyzer; |
57 |
57 |
58 public class Compatibility { |
58 public class Compatibility { |
59 |
59 |
60 public static void main(String[] args) throws Throwable { |
60 protected List<UseCase> getUseCases() { |
61 String javaSecurityFile |
61 return UseCase.getAllUseCases(); |
62 = System.getProperty("test.src") + "/java.security"; |
62 } |
63 boolean debug = Utils.getBoolProperty("debug"); |
63 |
64 |
64 protected Set<JdkInfo> getJdkInfos() { |
65 Set<JdkInfo> jdkInfos = jdkInfoList(); |
65 return jdkInfoList(); |
66 |
66 } |
67 System.out.println("Test start"); |
67 |
|
68 protected List<TestCase> runTest() throws Exception { |
|
69 Set<JdkInfo> jdkInfos = getJdkInfos(); |
68 |
70 |
69 List<TestCase> testCases = new ArrayList<>(); |
71 List<TestCase> testCases = new ArrayList<>(); |
70 ExecutorService executor = Executors.newCachedThreadPool(); |
72 ExecutorService executor = Executors.newCachedThreadPool(); |
71 PrintStream origStdOut = System.out; |
73 PrintStream origStdOut = System.out; |
72 PrintStream origStdErr = System.err; |
74 PrintStream origStdErr = System.err; |
73 |
75 |
|
76 boolean debug = Boolean.getBoolean("debug"); |
|
77 |
|
78 String securityPropertiesFile = System.getProperty( |
|
79 "test.security.properties", |
|
80 System.getProperty("test.src") + "/java.security"); |
|
81 System.out.println("security properties: " + securityPropertiesFile); |
|
82 |
|
83 // If true, server and client CANNOT be a same JDK |
|
84 boolean disallowSameEndpoint = Boolean.getBoolean("disallowSameEndpoint"); |
|
85 System.out.println("disallowSameEndpoint: " + disallowSameEndpoint); |
|
86 |
74 try (PrintStream printStream = new PrintStream( |
87 try (PrintStream printStream = new PrintStream( |
75 new FileOutputStream(Utils.TEST_LOG, true))) { |
88 new FileOutputStream(Utils.TEST_LOG, true))) { |
76 System.setOut(printStream); |
89 System.setOut(printStream); |
77 System.setErr(printStream); |
90 System.setErr(printStream); |
78 |
91 |
79 System.out.println(Utils.startHtml()); |
92 System.out.println(Utils.startHtml()); |
80 System.out.println(Utils.startPre()); |
93 System.out.println(Utils.startPre()); |
81 |
94 |
82 for (UseCase useCase : UseCase.getAllUseCases()) { |
95 for (UseCase useCase : getUseCases()) { |
83 for (JdkInfo serverJdk : jdkInfos) { |
96 for (JdkInfo serverJdk : jdkInfos) { |
84 Map<String, String> props = new LinkedHashMap<>(); |
97 Map<String, String> props = new LinkedHashMap<>(); |
85 if (debug) { |
98 if (debug) { |
86 props.put("javax.net.debug", "all"); |
99 props.put("javax.net.debug", "all"); |
87 } |
100 } |
88 props.put("java.security.properties", javaSecurityFile); |
101 props.put("java.security.properties", securityPropertiesFile); |
89 |
102 |
90 props.put(Utils.PROP_PROTOCOL, useCase.protocol.name); |
103 props.put(Utils.PROP_PROTOCOL, useCase.protocol.name); |
91 props.put(Utils.PROP_CIPHER_SUITE, useCase.cipherSuite.name()); |
104 props.put(Utils.PROP_CIPHER_SUITE, useCase.cipherSuite.name()); |
92 props.put(Utils.PROP_CLIENT_AUTH, String.valueOf(useCase.clientAuth)); |
105 props.put(Utils.PROP_CLIENT_AUTH, String.valueOf(useCase.clientAuth)); |
93 if (useCase.appProtocol != UseCase.AppProtocol.NONE) { |
106 if (useCase.appProtocol != UseCase.AppProtocol.NONE) { |
103 serverJdk.supportsSNI + ""); |
116 serverJdk.supportsSNI + ""); |
104 props.put(Utils.PROP_SUPPORTS_ALPN_ON_SERVER, |
117 props.put(Utils.PROP_SUPPORTS_ALPN_ON_SERVER, |
105 serverJdk.supportsALPN + ""); |
118 serverJdk.supportsALPN + ""); |
106 |
119 |
107 for (JdkInfo clientJdk : jdkInfos) { |
120 for (JdkInfo clientJdk : jdkInfos) { |
|
121 if (disallowSameEndpoint && clientJdk == serverJdk) { |
|
122 continue; |
|
123 } |
|
124 |
108 TestCase testCase = new TestCase(serverJdk, clientJdk, |
125 TestCase testCase = new TestCase(serverJdk, clientJdk, |
109 useCase); |
126 useCase); |
110 System.out.println(Utils.anchorName(testCase.toString(), |
127 System.out.println(Utils.anchorName(testCase.toString(), |
111 "===== Case start =====")); |
128 "===== Case start =====")); |
112 System.out.println(testCase.toString()); |
129 System.out.println(testCase.toString()); |
160 } |
177 } |
161 System.setOut(origStdOut); |
178 System.setOut(origStdOut); |
162 System.setErr(origStdErr); |
179 System.setErr(origStdErr); |
163 executor.shutdown(); |
180 executor.shutdown(); |
164 |
181 |
165 System.out.println("Test end"); |
182 return testCases; |
166 System.out.println("Report is being generated..."); |
|
167 boolean failed = generateReport(testCases); |
|
168 System.out.println("Report is generated."); |
|
169 if (failed) { |
|
170 throw new RuntimeException("At least one case failed. " |
|
171 + "Please check logs for more details."); |
|
172 } |
|
173 } |
|
174 |
|
175 private static Status getStatus(String log) { |
|
176 if (log.contains(Status.UNEXPECTED_SUCCESS.name())) { |
|
177 return Status.UNEXPECTED_SUCCESS; |
|
178 } else if (log.contains(Status.SUCCESS.name())) { |
|
179 return Status.SUCCESS; |
|
180 } else if (log.contains(Status.EXPECTED_FAIL.name())) { |
|
181 return Status.EXPECTED_FAIL; |
|
182 } else if (log.contains(Status.TIMEOUT.name())) { |
|
183 return Status.TIMEOUT; |
|
184 } else { |
|
185 return Status.FAIL; |
|
186 } |
|
187 } |
|
188 |
|
189 private static Status caseStatus(Status serverStatus, Status clientStatus) { |
|
190 if (clientStatus == null || clientStatus == Status.TIMEOUT) { |
|
191 return serverStatus == Status.EXPECTED_FAIL |
|
192 ? Status.EXPECTED_FAIL |
|
193 : Status.FAIL; |
|
194 } else if (serverStatus == Status.TIMEOUT) { |
|
195 return clientStatus == Status.EXPECTED_FAIL |
|
196 ? Status.EXPECTED_FAIL |
|
197 : Status.FAIL; |
|
198 } else { |
|
199 return serverStatus == clientStatus |
|
200 ? serverStatus |
|
201 : Status.FAIL; |
|
202 } |
|
203 } |
|
204 |
|
205 // Retrieves JDK info from the file which is specified by jdkListFile. |
|
206 // If no such file or no JDK is specified by the file, the current testing |
|
207 // JDK will be used. |
|
208 private static Set<JdkInfo> jdkInfoList() throws Throwable { |
|
209 List<String> jdkList = jdkList("jdkListFile"); |
|
210 if (jdkList.size() == 0) { |
|
211 jdkList.add(System.getProperty("test.jdk")); |
|
212 } |
|
213 |
|
214 Set<JdkInfo> jdkInfoList = new LinkedHashSet<>(); |
|
215 for (String jdkPath : jdkList) { |
|
216 JdkInfo jdkInfo = new JdkInfo(jdkPath); |
|
217 // JDK version must be unique. |
|
218 if (!jdkInfoList.add(jdkInfo)) { |
|
219 System.out.println("The JDK version is duplicate: " + jdkPath); |
|
220 } |
|
221 } |
|
222 return jdkInfoList; |
|
223 } |
|
224 |
|
225 private static List<String> jdkList(String listFileProp) throws IOException { |
|
226 String listFile = System.getProperty(listFileProp); |
|
227 System.out.println(listFileProp + "=" + listFile); |
|
228 if (listFile != null && Files.exists(Paths.get(listFile))) { |
|
229 try (Stream<String> lines = Files.lines(Paths.get(listFile))) { |
|
230 return lines.filter(line -> { |
|
231 return !line.trim().isEmpty(); |
|
232 }).collect(Collectors.toList()); |
|
233 } |
|
234 } else { |
|
235 return new ArrayList<>(); |
|
236 } |
|
237 } |
|
238 |
|
239 // Checks if server is already launched, and returns server port. |
|
240 private static int waitForServerStarted() |
|
241 throws IOException, InterruptedException { |
|
242 System.out.print("Waiting for server"); |
|
243 long deadline = System.currentTimeMillis() + Utils.TIMEOUT; |
|
244 int port; |
|
245 while ((port = getServerPort()) == -1 |
|
246 && System.currentTimeMillis() < deadline) { |
|
247 System.out.print("."); |
|
248 TimeUnit.SECONDS.sleep(1); |
|
249 } |
|
250 System.out.println(); |
|
251 |
|
252 return port; |
|
253 } |
|
254 |
|
255 // Retrieves the latest server port from port.log. |
|
256 private static int getServerPort() throws IOException { |
|
257 if (!Files.exists(Paths.get(Utils.PORT_LOG))) { |
|
258 return -1; |
|
259 } |
|
260 |
|
261 try (Stream<String> lines = Files.lines(Paths.get(Utils.PORT_LOG))) { |
|
262 return Integer.valueOf(lines.findFirst().get()); |
|
263 } |
|
264 } |
|
265 |
|
266 private static OutputAnalyzer runServer(String jdkPath, |
|
267 Map<String, String> props) { |
|
268 return ProcessUtils.java(jdkPath, props, Server.class); |
|
269 } |
|
270 |
|
271 private static OutputAnalyzer runClient(String jdkPath, |
|
272 Map<String, String> props) { |
|
273 return ProcessUtils.java(jdkPath, props, Client.class); |
|
274 } |
183 } |
275 |
184 |
276 // Generates the test result report. |
185 // Generates the test result report. |
277 private static boolean generateReport(List<TestCase> testCases) |
186 protected boolean generateReport(List<TestCase> testCases) |
278 throws IOException { |
187 throws IOException { |
279 boolean failed = false; |
188 boolean failed = false; |
280 StringBuilder report = new StringBuilder(); |
189 StringBuilder report = new StringBuilder(); |
281 report.append(Utils.startHtml()); |
190 report.append(Utils.startHtml()); |
282 report.append(Utils.tableStyle()); |
191 report.append(Utils.tableStyle()); |
319 |
228 |
320 generateFile("report.html", report.toString()); |
229 generateFile("report.html", report.toString()); |
321 return failed; |
230 return failed; |
322 } |
231 } |
323 |
232 |
|
233 protected void run() throws Exception { |
|
234 System.out.println("Test start"); |
|
235 List<TestCase> testCases= runTest(); |
|
236 System.out.println("Test end"); |
|
237 |
|
238 boolean failed = generateReport(testCases); |
|
239 System.out.println("Report was generated."); |
|
240 |
|
241 if (failed) { |
|
242 throw new RuntimeException("At least one case failed. " |
|
243 + "Please check logs for more details."); |
|
244 } |
|
245 } |
|
246 |
|
247 public static void main(String[] args) throws Throwable { |
|
248 new Compatibility().run();; |
|
249 } |
|
250 |
|
251 private static Status getStatus(String log) { |
|
252 if (log.contains(Status.UNEXPECTED_SUCCESS.name())) { |
|
253 return Status.UNEXPECTED_SUCCESS; |
|
254 } else if (log.contains(Status.SUCCESS.name())) { |
|
255 return Status.SUCCESS; |
|
256 } else if (log.contains(Status.EXPECTED_FAIL.name())) { |
|
257 return Status.EXPECTED_FAIL; |
|
258 } else if (log.contains(Status.TIMEOUT.name())) { |
|
259 return Status.TIMEOUT; |
|
260 } else { |
|
261 return Status.FAIL; |
|
262 } |
|
263 } |
|
264 |
|
265 private static Status caseStatus(Status serverStatus, Status clientStatus) { |
|
266 if (clientStatus == null || clientStatus == Status.TIMEOUT) { |
|
267 return serverStatus == Status.EXPECTED_FAIL |
|
268 ? Status.EXPECTED_FAIL |
|
269 : Status.FAIL; |
|
270 } else if (serverStatus == Status.TIMEOUT) { |
|
271 return clientStatus == Status.EXPECTED_FAIL |
|
272 ? Status.EXPECTED_FAIL |
|
273 : Status.FAIL; |
|
274 } else { |
|
275 return serverStatus == clientStatus |
|
276 ? serverStatus |
|
277 : Status.FAIL; |
|
278 } |
|
279 } |
|
280 |
|
281 // Retrieves JDK info from the file which is specified by jdkListFile. |
|
282 // And the current testing JDK, which is specified by test.jdk, always be used. |
|
283 private static Set<JdkInfo> jdkInfoList() { |
|
284 List<String> jdkList = jdkList(); |
|
285 jdkList.add(System.getProperty("test.jdk")); |
|
286 |
|
287 Set<JdkInfo> jdkInfoList = new LinkedHashSet<>(); |
|
288 for (String jdkPath : jdkList) { |
|
289 JdkInfo jdkInfo = new JdkInfo(jdkPath); |
|
290 // JDK version must be unique. |
|
291 if (!jdkInfoList.add(jdkInfo)) { |
|
292 System.out.println("The JDK version is duplicate: " + jdkPath); |
|
293 } |
|
294 } |
|
295 return jdkInfoList; |
|
296 } |
|
297 |
|
298 private static List<String> jdkList() { |
|
299 String listFile = System.getProperty("jdkListFile"); |
|
300 System.out.println("jdk list file: " + listFile); |
|
301 if (listFile != null && Files.exists(Paths.get(listFile))) { |
|
302 try (Stream<String> lines = Files.lines(Paths.get(listFile))) { |
|
303 return lines.filter(line -> { |
|
304 return !line.trim().isEmpty(); |
|
305 }).collect(Collectors.toList()); |
|
306 } catch (IOException e) { |
|
307 throw new RuntimeException("Cannot get jdk list", e); |
|
308 } |
|
309 } else { |
|
310 return new ArrayList<>(); |
|
311 } |
|
312 } |
|
313 |
|
314 // Checks if server is already launched, and returns server port. |
|
315 private static int waitForServerStarted() |
|
316 throws IOException, InterruptedException { |
|
317 System.out.print("Waiting for server"); |
|
318 long deadline = System.currentTimeMillis() + Utils.TIMEOUT; |
|
319 int port; |
|
320 while ((port = getServerPort()) == -1 |
|
321 && System.currentTimeMillis() < deadline) { |
|
322 System.out.print("."); |
|
323 TimeUnit.SECONDS.sleep(1); |
|
324 } |
|
325 System.out.println(); |
|
326 |
|
327 return port; |
|
328 } |
|
329 |
|
330 // Retrieves the latest server port from port.log. |
|
331 private static int getServerPort() throws IOException { |
|
332 if (!Files.exists(Paths.get(Utils.PORT_LOG))) { |
|
333 return -1; |
|
334 } |
|
335 |
|
336 try (Stream<String> lines = Files.lines(Paths.get(Utils.PORT_LOG))) { |
|
337 return Integer.valueOf(lines.findFirst().get()); |
|
338 } |
|
339 } |
|
340 |
|
341 private static OutputAnalyzer runServer(String jdkPath, |
|
342 Map<String, String> props) { |
|
343 return ProcessUtils.java(jdkPath, props, Server.class); |
|
344 } |
|
345 |
|
346 private static OutputAnalyzer runClient(String jdkPath, |
|
347 Map<String, String> props) { |
|
348 return ProcessUtils.java(jdkPath, props, Client.class); |
|
349 } |
|
350 |
324 private static void generateFile(String path, String content) |
351 private static void generateFile(String path, String content) |
325 throws IOException { |
352 throws IOException { |
326 try(FileWriter writer = new FileWriter(new File(path))) { |
353 try(FileWriter writer = new FileWriter(new File(path))) { |
327 writer.write(content); |
354 writer.write(content); |
328 } |
355 } |