diff --git a/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/test/GenericTestUtils.java b/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/test/GenericTestUtils.java index e4271f0407f52..102f143d9037d 100644 --- a/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/test/GenericTestUtils.java +++ b/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/test/GenericTestUtils.java @@ -318,6 +318,17 @@ public static void assertExceptionContains(String expectedText, Throwable t) { assertExceptionContains(expectedText, t, ""); } + /** + * Assert that an exception's toString() value + * matches the regex pattern. + * @param pattern regex pattern to match + * @param t thrown exception + * @throws AssertionError if the pattern does not match + */ + public static void assertExceptionMatches(Pattern pattern, Throwable t) { + assertExceptionMatches(pattern, t, ""); + } + /** * Assert that an exception's toString() value * contained the expected text. @@ -345,6 +356,33 @@ public static void assertExceptionContains(String expectedText, } } + /** + * Assert that an exception's toString() value + * matches the pattern. + * @param pattern regex pattern to match + * @param t thrown exception + * @param message any extra text for the string + * @throws AssertionError if the expected string is not found + */ + public static void assertExceptionMatches(Pattern pattern, + Throwable t, + String message) { + assertNotNull(t, E_NULL_THROWABLE); + String msg = t.toString(); + if (msg == null) { + throw new AssertionError(E_NULL_THROWABLE_STRING, t); + } + if (pattern != null && !pattern.matcher(msg).matches()) { + String prefix = org.apache.commons.lang3.StringUtils.isEmpty(message) + ? "" : (message + ": "); + throw new AssertionError( + String.format("%s Expected to match '%s' %s: %s", + prefix, pattern, E_UNEXPECTED_EXCEPTION, + StringUtils.stringifyException(t)), + t); + } + } + /** * Wait for the specified test to return true. The test will be performed * initially and then every {@code checkEveryMillis} until at least diff --git a/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/test/TestGenericTestUtils.java b/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/test/TestGenericTestUtils.java index d64ae7eadc919..54a997605fdc9 100644 --- a/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/test/TestGenericTestUtils.java +++ b/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/test/TestGenericTestUtils.java @@ -25,49 +25,37 @@ import org.slf4j.LoggerFactory; import java.util.function.Supplier; +import java.util.regex.Pattern; + import org.slf4j.event.Level; +import static org.apache.hadoop.test.LambdaTestUtils.intercept; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertTrue; import static org.junit.jupiter.api.Assertions.fail; + public class TestGenericTestUtils extends GenericTestUtils { @Test public void testAssertExceptionContainsNullEx() throws Throwable { - try { - assertExceptionContains("", null); - } catch (AssertionError e) { - if (!e.toString().contains(E_NULL_THROWABLE)) { - throw e; - } - } + intercept(AssertionError.class, E_NULL_THROWABLE, () -> assertExceptionContains("", null)); } @Test public void testAssertExceptionContainsNullString() throws Throwable { - try { - assertExceptionContains("", new BrokenException()); - } catch (AssertionError e) { - if (!e.toString().contains(E_NULL_THROWABLE_STRING)) { - throw e; - } - } + intercept(AssertionError.class, E_NULL_THROWABLE_STRING, () -> assertExceptionContains("", new BrokenException())); } @Test public void testAssertExceptionContainsWrongText() throws Throwable { - try { - assertExceptionContains("Expected", new Exception("(actual)")); - } catch (AssertionError e) { - String s = e.toString(); - if (!s.contains(E_UNEXPECTED_EXCEPTION) - || !s.contains("(actual)") ) { - throw e; - } - if (e.getCause() == null) { - throw new AssertionError("No nested cause in assertion", e); - } + AssertionError e = intercept(AssertionError.class, E_UNEXPECTED_EXCEPTION, + () -> assertExceptionContains("Expected", new Exception("(actual)"))); + if (!e.toString().contains("(actual)")) { + throw new AssertionError("no actual string in exception", e); + } + if (e.getCause() == null) { + throw new AssertionError("No nested cause in assertion", e); } } @@ -76,6 +64,33 @@ public void testAssertExceptionContainsWorking() throws Throwable { assertExceptionContains("Expected", new Exception("Expected")); } + @Test + public void testAssertExceptionMatchesNullEx() throws Throwable { + intercept(AssertionError.class, E_NULL_THROWABLE, () -> assertExceptionMatches(null, null)); + } + + @Test + public void testAssertExceptionMatchesNullString() throws Throwable { + intercept(AssertionError.class, E_NULL_THROWABLE_STRING, () -> assertExceptionMatches(null, new BrokenException())); + } + + @Test + public void testAssertExceptionMatchesWrongText() throws Throwable { + AssertionError e = intercept(AssertionError.class, E_UNEXPECTED_EXCEPTION, + () -> assertExceptionMatches(Pattern.compile(".*Expected.*"), new Exception("(actual)"))); + if (!e.toString().contains("(actual)")) { + throw new AssertionError("no actual string in exception", e); + } + if (e.getCause() == null) { + throw new AssertionError("No nested cause in assertion", e); + } + } + + @Test + public void testAssertExceptionMatchesWorking() throws Throwable { + assertExceptionMatches(Pattern.compile(".*Expected.*"), new Exception("Expected")); + } + private static class BrokenException extends Exception { public BrokenException() { } diff --git a/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/web/TestWebHdfsTimeouts.java b/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/web/TestWebHdfsTimeouts.java index 5924a8dedcef3..67bdb771ba392 100644 --- a/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/web/TestWebHdfsTimeouts.java +++ b/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/web/TestWebHdfsTimeouts.java @@ -37,12 +37,14 @@ import java.util.Collection; import java.util.List; import java.util.concurrent.TimeoutException; +import java.util.regex.Pattern; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.EnumSource; import org.junit.jupiter.params.provider.MethodSource; import org.slf4j.Logger; import org.slf4j.LoggerFactory; + import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.fs.Path; import org.apache.hadoop.hdfs.client.HdfsClientConfigKeys; @@ -152,8 +154,8 @@ public void testConnectTimeout(TimeoutSource src) throws Exception { fs.listFiles(new Path("/"), false); fail("expected timeout"); } catch (SocketTimeoutException e) { - GenericTestUtils.assertExceptionContains(fs.getUri().getAuthority() - + ": connect timed out",e); + GenericTestUtils.assertExceptionMatches(Pattern.compile( + ".*" + Pattern.quote(fs.getUri().getAuthority()) + ": [Cc]onnect timed out"), e); } } @@ -190,8 +192,8 @@ public void testAuthUrlConnectTimeout(TimeoutSource src) throws Exception { fs.getDelegationToken("renewer"); fail("expected timeout"); } catch (SocketTimeoutException e) { - GenericTestUtils.assertExceptionContains(fs.getUri().getAuthority() + - ": connect timed out", e); + GenericTestUtils.assertExceptionMatches(Pattern.compile( + ".*" + Pattern.quote(fs.getUri().getAuthority()) + ": [Cc]onnect timed out"), e); } } @@ -230,8 +232,8 @@ public void testRedirectConnectTimeout(TimeoutSource src) throws Exception { fail("expected timeout"); } catch (SocketTimeoutException e) { assumeBacklogConsumed(); - GenericTestUtils.assertExceptionContains( - fs.getUri().getAuthority() + ": connect timed out", e); + GenericTestUtils.assertExceptionMatches(Pattern.compile( + ".*" + Pattern.quote(fs.getUri().getAuthority()) + ": [Cc]onnect timed out"), e); } } @@ -272,8 +274,8 @@ public void testTwoStepWriteConnectTimeout(TimeoutSource src) throws Exception { fail("expected timeout"); } catch (SocketTimeoutException e) { assumeBacklogConsumed(); - GenericTestUtils.assertExceptionContains( - fs.getUri().getAuthority() + ": connect timed out", e); + GenericTestUtils.assertExceptionMatches(Pattern.compile( + ".*" + Pattern.quote(fs.getUri().getAuthority()) + ": [Cc]onnect timed out"), e); } finally { IOUtils.cleanupWithLogger(LOG, os); }