private static void exceptionShouldContains(String substr, Throwable throwable) {
    Throwable t = throwable;
    while (t != null) {
      String msg = t.toString();
      if (msg != null && msg.toLowerCase().contains(substr.toLowerCase())) {
        return;
      }
      t = t.getCause();
    }
    throw new AssertionError("Expected to find '" + substr + "' but got unexpected exception:"
      + StringUtils.stringifyException(throwable), throwable);
  }
Assert that a throwable or one of its causes should contain the substr in its message. Ideally
we should use {@link GenericTestUtils#assertExceptionContains(String, Throwable)} util method
which asserts t.toString() contains the substr. As the original throwable may have been wrapped
in Hadoop3 because of HADOOP-12897, it's required to check all the wrapped causes. After stop
supporting Hadoop2, this method can be removed and assertion in tests can use t.getCause()
directly, similar to HADOOP-15280.
hbase-http/src/test/java/org/apache/hadoop/hbase/http/log/TestLogLevel.java