18
18
19
19
package org .apache .hadoop .test ;
20
20
21
- import org .apache .hadoop .util .Preconditions ;
22
21
import org .junit .Assert ;
23
22
import org .slf4j .Logger ;
24
23
import org .slf4j .LoggerFactory ;
25
24
26
25
import org .apache .hadoop .security .UserGroupInformation ;
26
+ import org .apache .hadoop .util .Preconditions ;
27
27
import org .apache .hadoop .util .Time ;
28
28
29
29
import java .io .IOException ;
30
30
import java .security .PrivilegedExceptionAction ;
31
+ import java .util .Collection ;
31
32
import java .util .Optional ;
32
33
import java .util .concurrent .Callable ;
33
34
import java .util .concurrent .CancellationException ;
34
35
import java .util .concurrent .ExecutionException ;
35
36
import java .util .concurrent .Future ;
36
37
import java .util .concurrent .TimeUnit ;
37
38
import java .util .concurrent .TimeoutException ;
39
+ import java .util .stream .Collectors ;
38
40
39
41
/**
40
42
* Class containing methods and associated classes to make the most of Lambda
@@ -476,7 +478,7 @@ public static <T, E extends Throwable> E intercept(
476
478
* <i>or a subclass</i>.
477
479
* @param contained string which must be in the {@code toString()} value
478
480
* of the exception
479
- * @param message any message tho include in exception/log messages
481
+ * @param message any message to include in exception/log messages
480
482
* @param eval expression to eval
481
483
* @param <T> return type of expression
482
484
* @param <E> exception class
@@ -528,7 +530,7 @@ public static <E extends Throwable> E intercept(
528
530
throws Exception {
529
531
return intercept (clazz , contained ,
530
532
"Expecting " + clazz .getName ()
531
- + (contained != null ? (" with text " + contained ) : "" )
533
+ + (contained != null ? (" with text " + contained ) : "" )
532
534
+ " but got " ,
533
535
() -> {
534
536
eval .call ();
@@ -543,7 +545,7 @@ public static <E extends Throwable> E intercept(
543
545
* <i>or a subclass</i>.
544
546
* @param contained string which must be in the {@code toString()} value
545
547
* of the exception
546
- * @param message any message tho include in exception/log messages
548
+ * @param message any message to include in exception/log messages
547
549
* @param eval expression to eval
548
550
* @param <E> exception class
549
551
* @return the caught exception if it was of the expected type
@@ -563,6 +565,105 @@ public static <E extends Throwable> E intercept(
563
565
});
564
566
}
565
567
568
+ /**
569
+ * Intercept an exception; throw an {@code AssertionError} if one not raised.
570
+ * The caught exception is rethrown if it is of the wrong class or
571
+ * does not contain the text defined in {@code contained}.
572
+ * <p>
573
+ * Example: expect deleting a nonexistent file to raise a
574
+ * {@code FileNotFoundException} with the {@code toString()} value
575
+ * containing the text {@code "missing"}.
576
+ * <pre>
577
+ * FileNotFoundException ioe = interceptAndValidateMessageContains(
578
+ * FileNotFoundException.class,
579
+ * "missing",
580
+ * "path should not be found",
581
+ * () -> {
582
+ * filesystem.delete(new Path("/missing"), false);
583
+ * });
584
+ * </pre>
585
+ *
586
+ * @param clazz class of exception; the raised exception must be this class
587
+ * <i>or a subclass</i>.
588
+ * @param contains strings which must be in the {@code toString()} value
589
+ * of the exception (order does not matter)
590
+ * @param eval expression to eval
591
+ * @param <T> return type of expression
592
+ * @param <E> exception class
593
+ * @return the caught exception if it was of the expected type and contents
594
+ * @throws Exception any other exception raised
595
+ * @throws AssertionError if the evaluation call didn't raise an exception.
596
+ * The error includes the {@code toString()} value of the result, if this
597
+ * can be determined.
598
+ * @see GenericTestUtils#assertExceptionContains(String, Throwable)
599
+ */
600
+ public static <T , E extends Throwable > E interceptAndValidateMessageContains (
601
+ Class <E > clazz ,
602
+ Collection <String > contains ,
603
+ VoidCallable eval )
604
+ throws Exception {
605
+ String message = "Expecting " + clazz .getName ()
606
+ + (contains .isEmpty () ? "" : (" with text values " + toString (contains )))
607
+ + " but got " ;
608
+ return interceptAndValidateMessageContains (clazz , contains , message , eval );
609
+ }
610
+
611
+ /**
612
+ * Intercept an exception; throw an {@code AssertionError} if one not raised.
613
+ * The caught exception is rethrown if it is of the wrong class or
614
+ * does not contain the text defined in {@code contained}.
615
+ * <p>
616
+ * Example: expect deleting a nonexistent file to raise a
617
+ * {@code FileNotFoundException} with the {@code toString()} value
618
+ * containing the text {@code "missing"}.
619
+ * <pre>
620
+ * FileNotFoundException ioe = interceptAndValidateMessageContains(
621
+ * FileNotFoundException.class,
622
+ * "missing",
623
+ * "path should not be found",
624
+ * () -> {
625
+ * filesystem.delete(new Path("/missing"), false);
626
+ * });
627
+ * </pre>
628
+ *
629
+ * @param clazz class of exception; the raised exception must be this class
630
+ * <i>or a subclass</i>.
631
+ * @param contains strings which must be in the {@code toString()} value
632
+ * of the exception (order does not matter)
633
+ * @param message any message to include in exception/log messages
634
+ * @param eval expression to eval
635
+ * @param <T> return type of expression
636
+ * @param <E> exception class
637
+ * @return the caught exception if it was of the expected type and contents
638
+ * @throws Exception any other exception raised
639
+ * @throws AssertionError if the evaluation call didn't raise an exception.
640
+ * The error includes the {@code toString()} value of the result, if this
641
+ * can be determined.
642
+ * @see GenericTestUtils#assertExceptionContains(String, Throwable)
643
+ */
644
+ public static <T , E extends Throwable > E interceptAndValidateMessageContains (
645
+ Class <E > clazz ,
646
+ Collection <String > contains ,
647
+ String message ,
648
+ VoidCallable eval )
649
+ throws Exception {
650
+ E ex ;
651
+ try {
652
+ eval .call ();
653
+ throw new AssertionError (message );
654
+ } catch (Throwable e ) {
655
+ if (!clazz .isAssignableFrom (e .getClass ())) {
656
+ throw e ;
657
+ } else {
658
+ ex = (E ) e ;
659
+ }
660
+ }
661
+ for (String contained : contains ) {
662
+ GenericTestUtils .assertExceptionContains (contained , ex , message );
663
+ }
664
+ return ex ;
665
+ }
666
+
566
667
/**
567
668
* Robust string converter for exception messages; if the {@code toString()}
568
669
* method throws an exception then that exception is caught and logged,
@@ -607,7 +708,6 @@ public static <T> void assertOptionalEquals(String message,
607
708
* Assert that an optional value matches an expected one;
608
709
* checks include null and empty on the actual value.
609
710
* @param message message text
610
- * @param expected expected value
611
711
* @param actual actual optional value
612
712
* @param <T> type
613
713
*/
@@ -641,7 +741,6 @@ public static <T> T eval(Callable<T> closure) {
641
741
* Invoke a callable; wrap all checked exceptions with an
642
742
* AssertionError.
643
743
* @param closure closure to execute
644
- * @return the value of the closure
645
744
* @throws AssertionError if the operation raised an IOE or
646
745
* other checked exception.
647
746
*/
@@ -823,6 +922,11 @@ public static <E extends Throwable> E verifyCause(
823
922
}
824
923
}
825
924
925
+ private static String toString (Collection <String > strings ) {
926
+ return strings .stream ()
927
+ .collect (Collectors .joining ("," , "[" , "]" ));
928
+ }
929
+
826
930
/**
827
931
* Returns {@code TimeoutException} on a timeout. If
828
932
* there was a inner class passed in, includes it as the
@@ -1037,3 +1141,4 @@ public Void run() throws Exception {
1037
1141
}
1038
1142
}
1039
1143
}
1144
+
0 commit comments