From 321472d7d7c924f9ac68945cf6cf2a1efa3debab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Yoann=20Rodi=C3=A8re?= Date: Mon, 27 Feb 2017 12:28:47 +0100 Subject: [PATCH] HSEARCH-2434 In ES schema validation ITs, do not rely on indexes starting in a particular order The index managers are stored in a hashmap, whose order is undefined. Strangely, our tests seem to have been working until now. --- .../test/ElasticsearchSchemaValidationIT.java | 6 +- .../util/impl/ExceptionMatcherBuilder.java | 66 ++++++++++++++++--- 2 files changed, 62 insertions(+), 10 deletions(-) diff --git a/elasticsearch/src/test/java/org/hibernate/search/elasticsearch/test/ElasticsearchSchemaValidationIT.java b/elasticsearch/src/test/java/org/hibernate/search/elasticsearch/test/ElasticsearchSchemaValidationIT.java index 1171876f29a..35fedb3acf5 100644 --- a/elasticsearch/src/test/java/org/hibernate/search/elasticsearch/test/ElasticsearchSchemaValidationIT.java +++ b/elasticsearch/src/test/java/org/hibernate/search/elasticsearch/test/ElasticsearchSchemaValidationIT.java @@ -596,12 +596,16 @@ public void multipleErrors_multipleIndexManagers() throws Exception { thrown.expect( isException( ElasticsearchSchemaValidationException.class ) + .withMainOrSuppressed( + isException( ElasticsearchSchemaValidationException.class ) .withMessage( VALIDATION_FAILED_MESSAGE_ID ) .withMessage( "\nindex 'org.hibernate.search.elasticsearch.test.elasticsearchschemavalidationit$simplebooleanentity', mapping 'org.hibernate.search.elasticsearch.test.ElasticsearchSchemaValidationIT$SimpleBooleanEntity':" + "\n\tInvalid value for attribute 'dynamic'. Expected 'STRICT', actual is 'FALSE'" ) - .withSuppressed( + .build() + ) + .withMainOrSuppressed( isException( ElasticsearchSchemaValidationException.class ) .withMessage( VALIDATION_FAILED_MESSAGE_ID ) .withMessage( diff --git a/engine/src/test/java/org/hibernate/search/test/util/impl/ExceptionMatcherBuilder.java b/engine/src/test/java/org/hibernate/search/test/util/impl/ExceptionMatcherBuilder.java index 50e85e0eb9e..161c11145a8 100644 --- a/engine/src/test/java/org/hibernate/search/test/util/impl/ExceptionMatcherBuilder.java +++ b/engine/src/test/java/org/hibernate/search/test/util/impl/ExceptionMatcherBuilder.java @@ -15,7 +15,9 @@ import org.hamcrest.CoreMatchers; import org.hamcrest.Description; import org.hamcrest.Matcher; +import org.hamcrest.TypeSafeDiagnosingMatcher; import org.hamcrest.TypeSafeMatcher; +import org.hibernate.search.util.impl.CollectionHelper; /** * @author Yoann Rodiere @@ -34,6 +36,10 @@ private ExceptionMatcherBuilder(Class clazz) { matchers.add( CoreMatchers.instanceOf( clazz ) ); } + public ExceptionMatcherBuilder withMainOrSuppressed(Matcher matcher) { + return matching( mainOrSuppressed( matcher ) ); + } + public ExceptionMatcherBuilder withSuppressed(Matcher matcher) { suppressedMatchers.add( matcher ); return this; @@ -44,16 +50,16 @@ public ExceptionMatcherBuilder causedBy(Class clazz) { } public Matcher build() { - if ( matchers.size() == 1 && suppressedMatchers.isEmpty() ) { + if ( !suppressedMatchers.isEmpty() ) { + @SuppressWarnings("unchecked") + Matcher[] suppressedMatchersAsArray = castedSuppressedMatchers().toArray( new Matcher[suppressedMatchers.size()] ); + ExceptionMatcherBuilder.this.matching( hasSuppressed( CoreMatchers.hasItems( suppressedMatchersAsArray ) ) ); + suppressedMatchers.clear(); + } + if ( matchers.size() == 1 ) { return castedMatchers().get( 0 ); } else { - if ( !suppressedMatchers.isEmpty() ) { - @SuppressWarnings("unchecked") - Matcher[] suppressedMatchersAsArray = castedSuppressedMatchers().toArray( new Matcher[suppressedMatchers.size()] ); - ExceptionMatcherBuilder.this.matching( hasSuppressed( CoreMatchers.hasItems( suppressedMatchersAsArray ) ) ); - suppressedMatchers.clear(); - } return CoreMatchers.allOf( castedMatchers() ); } } @@ -68,8 +74,8 @@ private List> castedSuppressedMatchers() { return new ArrayList>( (List) suppressedMatchers ); } - public ExceptionMatcherBuilder matching(final Matcher messageMatcher) { - matchers.add( messageMatcher ); + public ExceptionMatcherBuilder matching(final Matcher throwableMatcher) { + matchers.add( throwableMatcher ); return this; } @@ -194,4 +200,46 @@ protected void describeMismatchSafely(Throwable item, Description description) { private static Matcher hasSuppressed(Matcher suppressedMatcher) { return new ThrowableSuppressedMatcher( suppressedMatcher ); } + + public static class ThrowableMainOrSuppressedMatcher extends TypeSafeDiagnosingMatcher { + + private final Matcher mainOrSuppressedMatcher; + + public ThrowableMainOrSuppressedMatcher(Matcher suppressedMatcher) { + this.mainOrSuppressedMatcher = suppressedMatcher; + } + + @Override + public void describeTo(Description description) { + description.appendText( "exception (or one of its suppressed exceptions) " ); + description.appendDescriptionOf( mainOrSuppressedMatcher ); + } + + @Override + protected boolean matchesSafely(Throwable item, Description mismatchDescription) { + Throwable[] suppressedArray = item.getSuppressed(); + List mainAndSuppressed = CollectionHelper.newArrayList( suppressedArray.length + 1 ); + mainAndSuppressed.add( item ); + for ( Throwable suppressed : suppressedArray ) { + mainAndSuppressed.add( suppressed ); + } + + boolean first = true; + for ( Throwable element : mainAndSuppressed ) { + if ( mainOrSuppressedMatcher.matches( element ) ) { + return true; + } + if ( !first ) { + mismatchDescription.appendText( ", " ); + } + mainOrSuppressedMatcher.describeMismatch( element, mismatchDescription ); + first = false; + } + return false; + } + } + + private static Matcher mainOrSuppressed(Matcher mainOrSuppressedMatcher) { + return new ThrowableMainOrSuppressedMatcher( mainOrSuppressedMatcher ); + } }