Skip to content

Commit 3f40f4c

Browse files
committed
8370975: OutputAnalyzer.matches() should use Matcher with Pattern.MULTILINE
Reviewed-by: stefank
1 parent 188da51 commit 3f40f4c

File tree

2 files changed

+98
-24
lines changed

2 files changed

+98
-24
lines changed

test/lib-test/jdk/test/lib/process/OutputAnalyzerTest.java

Lines changed: 69 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2013, 2022, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2013, 2025, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -217,6 +217,69 @@ public static void main(String args[]) throws Exception {
217217
}
218218
}
219219

220+
{
221+
// Multi-line output: OutputAnalyzer uses MULTILINE but not DOTALL, so "." doesn't match newline, but
222+
// "^" and "$" matches just after or just before, respectively, a newline.
223+
stdout = "aaaaaa\nxxxxxx\n";
224+
stderr = "bbbbbb\nyyyyyy\n";
225+
226+
OutputAnalyzer out = new OutputAnalyzer(stdout, stderr);
227+
228+
out.shouldMatch("aaa");
229+
out.shouldMatch("xxx");
230+
out.shouldMatch("bbb");
231+
out.shouldMatch("yyy");
232+
233+
out.stdoutShouldMatch("aaaaaa");
234+
out.stdoutShouldMatch("xxxxxx");
235+
out.stderrShouldMatch("bbbbbb");
236+
out.stderrShouldMatch("yyyyyy");
237+
238+
out.shouldMatch("^aaaaaa$");
239+
out.shouldMatch("^xxxxxx$");
240+
out.shouldMatch("^bbbbbb$");
241+
out.shouldMatch("^yyyyyy$");
242+
243+
out.stdoutShouldMatch("^aaaaaa$");
244+
out.stdoutShouldMatch("^xxxxxx$");
245+
out.stderrShouldMatch("^bbbbbb$");
246+
out.stderrShouldMatch("^yyyyyy$");
247+
248+
out.shouldMatch ("a.*");
249+
out.shouldNotMatch("a.*x");
250+
out.shouldMatch ("b.*");
251+
out.shouldNotMatch("b.*y");
252+
out.stdoutShouldMatch ("a.*");
253+
out.stdoutShouldNotMatch("a.*x");
254+
out.stderrShouldMatch ("b.*");
255+
out.stderrShouldNotMatch("b.*y");
256+
257+
check(out.matches("^aaaaaa$"));
258+
check(out.matches("^yyyyyy$"));
259+
check(out.stdoutMatches("^aaaaaa$"));
260+
check(out.stderrMatches("^yyyyyy$"));
261+
262+
check( out.matches("a.*"));
263+
check(!out.matches("a.*x"));
264+
265+
check( out.stdoutMatches("a.*"));
266+
check(!out.stdoutMatches("a.*x"));
267+
268+
check( out.stderrMatches("b.*"));
269+
check(!out.stderrMatches("b.*y"));
270+
271+
// Test the "contains" methods as well
272+
check(out.contains("aaa\nxxx"));
273+
check(out.contains("bbb\nyyy"));
274+
check(out.stdoutContains("aaa\nxxx"));
275+
check(out.stderrContains("bbb\nyyy"));
276+
277+
check(!out.contains("X"));
278+
check(!out.contains("X"));
279+
check(!out.stdoutContains("X"));
280+
check(!out.stderrContains("X"));
281+
}
282+
220283
{
221284
try {
222285
// Verify the exception message
@@ -244,4 +307,9 @@ public static void main(String args[]) throws Exception {
244307
}
245308
}
246309

310+
private static void check(boolean b) {
311+
if (!b) {
312+
throw new RuntimeException("Check failed");
313+
}
314+
}
247315
}

test/lib/jdk/test/lib/process/OutputAnalyzer.java

Lines changed: 29 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -354,25 +354,44 @@ public OutputAnalyzer stderrShouldNotContain(String notExpectedString) {
354354
return this;
355355
}
356356

357+
/**
358+
* Returns true if the pattern can be found in the given string(s).
359+
*
360+
* NOTE: The meaning of "match" in OutputAnalyzer is NOT the same as String.matches().
361+
* Rather it means "can the pattern be found in stdout and/or stderr".
362+
*
363+
* The pattern is comiled with MULTILINE but without DOTALL, so "." doesn't match newline, but
364+
* "^" and "$" matches just after or just before, respectively, a newline.
365+
*/
366+
private boolean findPattern(String regexp, String... strings) {
367+
Pattern pattern = Pattern.compile(regexp, Pattern.MULTILINE);
368+
for (String s : strings) {
369+
if (pattern.matcher(s).find()) {
370+
return true;
371+
}
372+
}
373+
return false;
374+
}
375+
357376
/**
358377
* Returns true if stdout matches the given pattern
359378
*/
360379
public boolean stdoutMatches(String regexp) {
361-
return getStdout().matches(regexp);
380+
return findPattern(regexp, getStdout());
362381
}
363382

364383
/**
365384
* Returns true if stderr matches the given pattern
366385
*/
367386
public boolean stderrMatches(String regexp) {
368-
return getStderr().matches(regexp);
387+
return findPattern(regexp, getStderr());
369388
}
370389

371390
/**
372391
* Returns true if either stdout or stderr matches the given pattern
373392
*/
374393
public boolean matches(String regexp) {
375-
return stdoutMatches(regexp) || stderrMatches(regexp);
394+
return findPattern(regexp, getStdout(), getStderr());
376395
}
377396

378397
/**
@@ -383,12 +402,7 @@ public boolean matches(String regexp) {
383402
* @throws RuntimeException If the pattern was not found
384403
*/
385404
public OutputAnalyzer shouldMatch(String regexp) {
386-
String stdout = getStdout();
387-
String stderr = getStderr();
388-
Pattern pattern = Pattern.compile(regexp, Pattern.MULTILINE);
389-
Matcher stdoutMatcher = pattern.matcher(stdout);
390-
Matcher stderrMatcher = pattern.matcher(stderr);
391-
if (!stdoutMatcher.find() && !stderrMatcher.find()) {
405+
if (!matches(regexp)) {
392406
reportDiagnosticSummary();
393407
throw new RuntimeException("'" + regexp
394408
+ "' missing from stdout/stderr");
@@ -404,9 +418,7 @@ public OutputAnalyzer shouldMatch(String regexp) {
404418
* @throws RuntimeException If the pattern was not found
405419
*/
406420
public OutputAnalyzer stdoutShouldMatch(String regexp) {
407-
String stdout = getStdout();
408-
Matcher matcher = Pattern.compile(regexp, Pattern.MULTILINE).matcher(stdout);
409-
if (!matcher.find()) {
421+
if (!stdoutMatches(regexp)) {
410422
reportDiagnosticSummary();
411423
throw new RuntimeException("'" + regexp
412424
+ "' missing from stdout");
@@ -421,12 +433,10 @@ public OutputAnalyzer stdoutShouldMatch(String regexp) {
421433
* @param pattern
422434
* @throws RuntimeException If the pattern was not found
423435
*/
424-
public OutputAnalyzer stderrShouldMatch(String pattern) {
425-
String stderr = getStderr();
426-
Matcher matcher = Pattern.compile(pattern, Pattern.MULTILINE).matcher(stderr);
427-
if (!matcher.find()) {
436+
public OutputAnalyzer stderrShouldMatch(String regexp) {
437+
if (!stderrMatches(regexp)) {
428438
reportDiagnosticSummary();
429-
throw new RuntimeException("'" + pattern
439+
throw new RuntimeException("'" + regexp
430440
+ "' missing from stderr");
431441
}
432442
return this;
@@ -468,9 +478,7 @@ public OutputAnalyzer shouldNotMatch(String regexp) {
468478
* @throws RuntimeException If the pattern was found
469479
*/
470480
public OutputAnalyzer stdoutShouldNotMatch(String regexp) {
471-
String stdout = getStdout();
472-
Matcher matcher = Pattern.compile(regexp, Pattern.MULTILINE).matcher(stdout);
473-
if (matcher.find()) {
481+
if (stdoutMatches(regexp)) {
474482
reportDiagnosticSummary();
475483
throw new RuntimeException("'" + regexp
476484
+ "' found in stdout");
@@ -486,9 +494,7 @@ public OutputAnalyzer stdoutShouldNotMatch(String regexp) {
486494
* @throws RuntimeException If the pattern was found
487495
*/
488496
public OutputAnalyzer stderrShouldNotMatch(String regexp) {
489-
String stderr = getStderr();
490-
Matcher matcher = Pattern.compile(regexp, Pattern.MULTILINE).matcher(stderr);
491-
if (matcher.find()) {
497+
if (stderrMatches(regexp)) {
492498
reportDiagnosticSummary();
493499
throw new RuntimeException("'" + regexp
494500
+ "' found in stderr");

0 commit comments

Comments
 (0)