diff --git a/hadoop-common-project/hadoop-common/CHANGES.txt b/hadoop-common-project/hadoop-common/CHANGES.txt
index 4764488c47e..1b4b27e4291 100644
--- a/hadoop-common-project/hadoop-common/CHANGES.txt
+++ b/hadoop-common-project/hadoop-common/CHANGES.txt
@@ -907,6 +907,9 @@ Release 2.8.0 - UNRELEASED
HADOOP-7266. Deprecate metrics v1. (Akira AJISAKA via ozawa)
+ HADOOP-12472. Make GenericTestUtils.assertExceptionContains robust.
+ (Steve Loughran via jing9)
+
OPTIMIZATIONS
HADOOP-11785. Reduce the number of listStatus operation in distcp
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 5bc1252dfc6..3f0b89dec91 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
@@ -142,12 +142,32 @@ public abstract class GenericTestUtils {
Joiner.on(",").join(expectedSet),
Joiner.on(",").join(found));
}
-
+
+ protected static String E_NULL_THROWABLE = "Null Throwable";
+ protected static String E_NULL_THROWABLE_STRING =
+ "Null Throwable.toString() value";
+ protected static String E_UNEXPECTED_EXCEPTION =
+ "but got unexpected exception";
+
+ /**
+ * Assert that an exception's toString()
value
+ * contained the expected text.
+ * @param string expected string
+ * @param t thrown exception
+ * @throws AssertionError if the expected string is not found
+ */
public static void assertExceptionContains(String string, Throwable t) {
- String msg = t.getMessage();
- Assert.assertTrue(
- "Expected to find '" + string + "' but got unexpected exception:"
- + StringUtils.stringifyException(t), msg.contains(string));
+ Assert.assertNotNull(E_NULL_THROWABLE, t);
+ String msg = t.toString();
+ if (msg == null) {
+ throw new AssertionError(E_NULL_THROWABLE_STRING, t);
+ }
+ if (!msg.contains(string)) {
+ throw new AssertionError("Expected to find '" + string + "' "
+ + E_UNEXPECTED_EXCEPTION + ":"
+ + StringUtils.stringifyException(t),
+ t);
+ }
}
public static void waitFor(Supplier check,
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
new file mode 100644
index 00000000000..8a7b5f67a8e
--- /dev/null
+++ b/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/test/TestGenericTestUtils.java
@@ -0,0 +1,78 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.hadoop.test;
+
+import org.junit.Test;
+
+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;
+ }
+ }
+ }
+
+ @Test
+ public void testAssertExceptionContainsNullString() throws Throwable {
+ try {
+ assertExceptionContains("", new BrokenException());
+ } catch (AssertionError e) {
+ if (!e.toString().contains(E_NULL_THROWABLE_STRING)) {
+ throw e;
+ }
+ }
+ }
+
+ @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);
+ }
+ }
+ }
+
+ @Test
+ public void testAssertExceptionContainsWorking() throws Throwable {
+ assertExceptionContains("Expected", new Exception("Expected"));
+ }
+
+ private static class BrokenException extends Exception {
+ public BrokenException() {
+ }
+
+ @Override
+ public String toString() {
+ return null;
+ }
+ }
+
+}