/*
* Licensed to Elasticsearch under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch 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.elasticsearch.test.hamcrest;
import com.google.common.base.Function;
import com.google.common.base.Predicate;
import com.google.common.base.Predicates;
import com.google.common.collect.FluentIterable;
import com.google.common.collect.Iterables;
import org.apache.lucene.search.BooleanQuery;
import org.apache.lucene.search.Query;
import org.elasticsearch.ElasticsearchException;
import org.elasticsearch.ExceptionsHelper;
import org.elasticsearch.Version;
import org.elasticsearch.action.ActionFuture;
import org.elasticsearch.action.ActionRequest;
import org.elasticsearch.action.ActionRequestBuilder;
import org.elasticsearch.action.ShardOperationFailedException;
import org.elasticsearch.action.admin.cluster.health.ClusterHealthRequestBuilder;
import org.elasticsearch.action.admin.cluster.health.ClusterHealthResponse;
import org.elasticsearch.action.admin.cluster.node.info.NodesInfoResponse;
import org.elasticsearch.plugins.PluginInfo;
import org.elasticsearch.action.admin.cluster.node.info.PluginsAndModules;
import org.elasticsearch.action.admin.indices.alias.exists.AliasesExistResponse;
import org.elasticsearch.action.admin.indices.delete.DeleteIndexRequestBuilder;
import org.elasticsearch.action.admin.indices.delete.DeleteIndexResponse;
import org.elasticsearch.action.admin.indices.template.get.GetIndexTemplatesResponse;
import org.elasticsearch.action.bulk.BulkResponse;
import org.elasticsearch.action.count.CountResponse;
import org.elasticsearch.action.exists.ExistsResponse;
import org.elasticsearch.action.get.GetResponse;
import org.elasticsearch.action.percolate.PercolateResponse;
import org.elasticsearch.action.search.SearchPhaseExecutionException;
import org.elasticsearch.action.search.SearchRequestBuilder;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.action.search.ShardSearchFailure;
import org.elasticsearch.action.support.broadcast.BroadcastResponse;
import org.elasticsearch.action.support.master.AcknowledgedRequestBuilder;
import org.elasticsearch.action.support.master.AcknowledgedResponse;
import org.elasticsearch.cluster.block.ClusterBlock;
import org.elasticsearch.cluster.block.ClusterBlockException;
import org.elasticsearch.cluster.metadata.IndexTemplateMetaData;
import org.elasticsearch.common.Nullable;
import org.elasticsearch.common.bytes.BytesReference;
import org.elasticsearch.common.io.stream.BytesStreamOutput;
import org.elasticsearch.common.io.stream.StreamInput;
import org.elasticsearch.common.io.stream.StreamOutput;
import org.elasticsearch.common.io.stream.Streamable;
import org.elasticsearch.rest.RestStatus;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.suggest.Suggest;
import org.elasticsearch.test.VersionUtils;
import org.elasticsearch.test.rest.client.http.HttpResponse;
import org.hamcrest.CoreMatchers;
import org.hamcrest.Matcher;
import org.hamcrest.Matchers;
import org.junit.Assert;
import java.io.IOException;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.*;
import static com.google.common.base.Predicates.isNull;
import static com.google.common.base.Predicates.notNull;
import static org.elasticsearch.test.ESTestCase.*;
import static org.elasticsearch.test.VersionUtils.randomVersion;
import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.*;
/**
*
*/
public class ElasticsearchAssertions {
public static void assertAcked(AcknowledgedRequestBuilder<?, ?, ?> builder) {
assertAcked(builder.get());
}
public static void assertNoTimeout(ClusterHealthRequestBuilder requestBuilder) {
assertNoTimeout(requestBuilder.get());
}
public static void assertNoTimeout(ClusterHealthResponse response) {
assertThat("ClusterHealthResponse has timed out - returned: [" + response + "]", response.isTimedOut(), is(false));
}
public static void assertAcked(AcknowledgedResponse response) {
assertThat(response.getClass().getSimpleName() + " failed - not acked", response.isAcknowledged(), equalTo(true));
assertVersionSerializable(response);
}
public static void assertAcked(DeleteIndexRequestBuilder builder) {
assertAcked(builder.get());
}
public static void assertAcked(DeleteIndexResponse response) {
assertThat("Delete Index failed - not acked", response.isAcknowledged(), equalTo(true));
assertVersionSerializable(response);
}
/**
* Executes the request and fails if the request has not been blocked.
*
* @param builder the request builder
*/
public static void assertBlocked(ActionRequestBuilder builder) {
assertBlocked(builder, null);
}
/**
* Checks that all shard requests of a replicated brodcast request failed due to a cluster block
*
* @param replicatedBroadcastResponse the response that should only contain failed shard responses
*
* */
public static void assertBlocked(BroadcastResponse replicatedBroadcastResponse) {
assertThat("all shard requests should have failed", replicatedBroadcastResponse.getFailedShards(), Matchers.equalTo(replicatedBroadcastResponse.getTotalShards()));
for (ShardOperationFailedException exception : replicatedBroadcastResponse.getShardFailures()) {
ClusterBlockException clusterBlockException = (ClusterBlockException) ExceptionsHelper.unwrap(exception.getCause(), ClusterBlockException.class);
assertNotNull("expected the cause of failure to be a ClusterBlockException but got " + exception.getCause().getMessage(), clusterBlockException);
assertThat(clusterBlockException.blocks().size(), greaterThan(0));
assertThat(clusterBlockException.status(), CoreMatchers.equalTo(RestStatus.FORBIDDEN));
}
}
/**
* Executes the request and fails if the request has not been blocked by a specific {@link ClusterBlock}.
*
* @param builder the request builder
* @param expectedBlock the expected block
*/
public static void assertBlocked(ActionRequestBuilder builder, ClusterBlock expectedBlock) {
try {
builder.get();
fail("Request executed with success but a ClusterBlockException was expected");
} catch (ClusterBlockException e) {
assertThat(e.blocks().size(), greaterThan(0));
assertThat(e.status(), equalTo(RestStatus.FORBIDDEN));
if (expectedBlock != null) {
boolean found = false;
for (ClusterBlock clusterBlock : e.blocks()) {
if (clusterBlock.id() == expectedBlock.id()) {
found = true;
break;
}
}
assertThat("Request should have been blocked by [" + expectedBlock + "] instead of " + e.blocks(), found, equalTo(true));
}
}
}
public static String formatShardStatus(BroadcastResponse response) {
String msg = " Total shards: " + response.getTotalShards() + " Successful shards: " + response.getSuccessfulShards() + " & "
+ response.getFailedShards() + " shard failures:";
for (ShardOperationFailedException failure : response.getShardFailures()) {
msg += "\n " + failure.toString();
}
return msg;
}
public static String formatShardStatus(SearchResponse response) {
String msg = " Total shards: " + response.getTotalShards() + " Successful shards: " + response.getSuccessfulShards() + " & "
+ response.getFailedShards() + " shard failures:";
for (ShardSearchFailure failure : response.getShardFailures()) {
msg += "\n " + failure.toString();
}
return msg;
}
/*
* assertions
*/
public static void assertHitCount(SearchResponse searchResponse, long expectedHitCount) {
if (searchResponse.getHits().totalHits() != expectedHitCount) {
fail("Hit count is " + searchResponse.getHits().totalHits() + " but " + expectedHitCount + " was expected. "
+ formatShardStatus(searchResponse));
}
assertVersionSerializable(searchResponse);
}
public static void assertNoSearchHits(SearchResponse searchResponse) {
assertEquals(0, searchResponse.getHits().getHits().length);
}
public static void assertSearchHits(SearchResponse searchResponse, String... ids) {
String shardStatus = formatShardStatus(searchResponse);
Set<String> idsSet = new HashSet<>(Arrays.asList(ids));
for (SearchHit hit : searchResponse.getHits()) {
assertThat("id [" + hit.getId() + "] was found in search results but wasn't expected (type [" + hit.getType() + "], index [" + hit.index() + "])"
+ shardStatus, idsSet.remove(hit.getId()),
equalTo(true));
}
assertThat("Some expected ids were not found in search results: " + Arrays.toString(idsSet.toArray(new String[idsSet.size()])) + "."
+ shardStatus, idsSet.size(), equalTo(0));
assertVersionSerializable(searchResponse);
}
public static void assertSortValues(SearchResponse searchResponse, Object[]... sortValues) {
assertSearchResponse(searchResponse);
SearchHit[] hits = searchResponse.getHits().getHits();
assertEquals(sortValues.length, hits.length);
for (int i = 0; i < sortValues.length; ++i) {
final Object[] hitsSortValues = hits[i].getSortValues();
assertArrayEquals("Offset " + Integer.toString(i) + ", id " + hits[i].getId(), sortValues[i], hitsSortValues);
}
assertVersionSerializable(searchResponse);
}
public static void assertOrderedSearchHits(SearchResponse searchResponse, String... ids) {
String shardStatus = formatShardStatus(searchResponse);
assertThat("Expected different hit count. " + shardStatus, searchResponse.getHits().hits().length, equalTo(ids.length));
for (int i = 0; i < ids.length; i++) {
SearchHit hit = searchResponse.getHits().hits()[i];
assertThat("Expected id: " + ids[i] + " at position " + i + " but wasn't." + shardStatus, hit.getId(), equalTo(ids[i]));
}
assertVersionSerializable(searchResponse);
}
public static void assertHitCount(CountResponse countResponse, long expectedHitCount) {
if (countResponse.getCount() != expectedHitCount) {
fail("Count is " + countResponse.getCount() + " but " + expectedHitCount + " was expected. " + formatShardStatus(countResponse));
}
assertVersionSerializable(countResponse);
}
public static void assertExists(ExistsResponse existsResponse, boolean expected) {
if (existsResponse.exists() != expected) {
fail("Exist is " + existsResponse.exists() + " but " + expected + " was expected " + formatShardStatus(existsResponse));
}
assertVersionSerializable(existsResponse);
}
public static void assertMatchCount(PercolateResponse percolateResponse, long expectedHitCount) {
if (percolateResponse.getCount() != expectedHitCount) {
fail("Count is " + percolateResponse.getCount() + " but " + expectedHitCount + " was expected. " + formatShardStatus(percolateResponse));
}
assertVersionSerializable(percolateResponse);
}
public static void assertExists(GetResponse response) {
String message = String.format(Locale.ROOT, "Expected %s/%s/%s to exist, but does not", response.getIndex(), response.getType(), response.getId());
assertThat(message, response.isExists(), is(true));
}
public static void assertFirstHit(SearchResponse searchResponse, Matcher<SearchHit> matcher) {
assertSearchHit(searchResponse, 1, matcher);
}
public static void assertSecondHit(SearchResponse searchResponse, Matcher<SearchHit> matcher) {
assertSearchHit(searchResponse, 2, matcher);
}
public static void assertThirdHit(SearchResponse searchResponse, Matcher<SearchHit> matcher) {
assertSearchHit(searchResponse, 3, matcher);
}
public static void assertFourthHit(SearchResponse searchResponse, Matcher<SearchHit> matcher) {
assertSearchHit(searchResponse, 4, matcher);
}
public static void assertFifthHit(SearchResponse searchResponse, Matcher<SearchHit> matcher) {
assertSearchHit(searchResponse, 5, matcher);
}
public static void assertSearchHit(SearchResponse searchResponse, int number, Matcher<SearchHit> matcher) {
assertThat(number, greaterThan(0));
assertThat("SearchHit number must be greater than 0", number, greaterThan(0));
assertThat(searchResponse.getHits().totalHits(), greaterThanOrEqualTo((long) number));
assertSearchHit(searchResponse.getHits().getAt(number - 1), matcher);
assertVersionSerializable(searchResponse);
}
public static void assertNoFailures(SearchResponse searchResponse) {
assertThat("Unexpected ShardFailures: " + Arrays.toString(searchResponse.getShardFailures()),
searchResponse.getShardFailures().length, equalTo(0));
assertVersionSerializable(searchResponse);
}
public static void assertFailures(SearchResponse searchResponse) {
assertThat("Expected at least one shard failure, got none",
searchResponse.getShardFailures().length, greaterThan(0));
assertVersionSerializable(searchResponse);
}
public static void assertNoFailures(BulkResponse response) {
assertThat("Unexpected ShardFailures: " + response.buildFailureMessage(),
response.hasFailures(), is(false));
assertVersionSerializable(response);
}
public static void assertFailures(SearchRequestBuilder searchRequestBuilder, RestStatus restStatus, Matcher<String> reasonMatcher) {
//when the number for shards is randomized and we expect failures
//we can either run into partial or total failures depending on the current number of shards
try {
SearchResponse searchResponse = searchRequestBuilder.get();
assertThat("Expected shard failures, got none", searchResponse.getShardFailures().length, greaterThan(0));
for (ShardSearchFailure shardSearchFailure : searchResponse.getShardFailures()) {
assertThat(shardSearchFailure.status(), equalTo(restStatus));
assertThat(shardSearchFailure.reason(), reasonMatcher);
}
assertVersionSerializable(searchResponse);
} catch (SearchPhaseExecutionException e) {
assertThat(e.status(), equalTo(restStatus));
assertThat(e.toString(), reasonMatcher);
for (ShardSearchFailure shardSearchFailure : e.shardFailures()) {
assertThat(shardSearchFailure.status(), equalTo(restStatus));
assertThat(shardSearchFailure.reason(), reasonMatcher);
}
} catch (Exception e) {
fail("SearchPhaseExecutionException expected but got " + e.getClass());
}
}
public static void assertFailures(PercolateResponse percolateResponse) {
assertThat("Expected at least one shard failure, got none",
percolateResponse.getShardFailures().length, greaterThan(0));
assertVersionSerializable(percolateResponse);
}
public static void assertNoFailures(BroadcastResponse response) {
assertThat("Unexpected ShardFailures: " + Arrays.toString(response.getShardFailures()), response.getFailedShards(), equalTo(0));
assertVersionSerializable(response);
}
public static void assertAllSuccessful(BroadcastResponse response) {
assertNoFailures(response);
assertThat("Expected all shards successful but got successful [" + response.getSuccessfulShards() + "] total [" + response.getTotalShards() + "]",
response.getTotalShards(), equalTo(response.getSuccessfulShards()));
assertVersionSerializable(response);
}
public static void assertAllSuccessful(SearchResponse response) {
assertNoFailures(response);
assertThat("Expected all shards successful but got successful [" + response.getSuccessfulShards() + "] total [" + response.getTotalShards() + "]",
response.getTotalShards(), equalTo(response.getSuccessfulShards()));
assertVersionSerializable(response);
}
public static void assertSearchHit(SearchHit searchHit, Matcher<SearchHit> matcher) {
assertThat(searchHit, matcher);
assertVersionSerializable(searchHit);
}
public static void assertHighlight(SearchResponse resp, int hit, String field, int fragment, Matcher<String> matcher) {
assertHighlight(resp, hit, field, fragment, greaterThan(fragment), matcher);
}
public static void assertHighlight(SearchResponse resp, int hit, String field, int fragment, int totalFragments, Matcher<String> matcher) {
assertHighlight(resp, hit, field, fragment, equalTo(totalFragments), matcher);
}
public static void assertHighlight(SearchHit hit, String field, int fragment, Matcher<String> matcher) {
assertHighlight(hit, field, fragment, greaterThan(fragment), matcher);
}
public static void assertHighlight(SearchHit hit, String field, int fragment, int totalFragments, Matcher<String> matcher) {
assertHighlight(hit, field, fragment, equalTo(totalFragments), matcher);
}
private static void assertHighlight(SearchResponse resp, int hit, String field, int fragment, Matcher<Integer> fragmentsMatcher, Matcher<String> matcher) {
assertNoFailures(resp);
assertThat("not enough hits", resp.getHits().hits().length, greaterThan(hit));
assertHighlight(resp.getHits().hits()[hit], field, fragment, fragmentsMatcher, matcher);
assertVersionSerializable(resp);
}
private static void assertHighlight(SearchHit hit, String field, int fragment, Matcher<Integer> fragmentsMatcher, Matcher<String> matcher) {
assertThat(hit.getHighlightFields(), hasKey(field));
assertThat(hit.getHighlightFields().get(field).fragments().length, fragmentsMatcher);
assertThat(hit.highlightFields().get(field).fragments()[fragment].string(), matcher);
}
public static void assertNotHighlighted(SearchResponse resp, int hit, String field) {
assertNoFailures(resp);
assertThat("not enough hits", resp.getHits().hits().length, greaterThan(hit));
assertThat(resp.getHits().hits()[hit].getHighlightFields(), not(hasKey(field)));
}
public static void assertSuggestionSize(Suggest searchSuggest, int entry, int size, String key) {
assertThat(searchSuggest, notNullValue());
String msg = "Suggest result: " + searchSuggest.toString();
assertThat(msg, searchSuggest.size(), greaterThanOrEqualTo(1));
assertThat(msg, searchSuggest.getSuggestion(key).getName(), equalTo(key));
assertThat(msg, searchSuggest.getSuggestion(key).getEntries().size(), greaterThanOrEqualTo(entry));
assertThat(msg, searchSuggest.getSuggestion(key).getEntries().get(entry).getOptions().size(), equalTo(size));
assertVersionSerializable(searchSuggest);
}
public static void assertSuggestionPhraseCollateMatchExists(Suggest searchSuggest, String key, int numberOfPhraseExists) {
int counter = 0;
assertThat(searchSuggest, notNullValue());
String msg = "Suggest result: " + searchSuggest.toString();
assertThat(msg, searchSuggest.size(), greaterThanOrEqualTo(1));
assertThat(msg, searchSuggest.getSuggestion(key).getName(), equalTo(key));
for (Suggest.Suggestion.Entry.Option option : searchSuggest.getSuggestion(key).getEntries().get(0).getOptions()) {
if (option.collateMatch()) {
counter++;
}
}
assertThat(counter, equalTo(numberOfPhraseExists));
}
public static void assertSuggestion(Suggest searchSuggest, int entry, int ord, String key, String text) {
assertThat(searchSuggest, notNullValue());
String msg = "Suggest result: " + searchSuggest.toString();
assertThat(msg, searchSuggest.size(), greaterThanOrEqualTo(1));
assertThat(msg, searchSuggest.getSuggestion(key).getName(), equalTo(key));
assertThat(msg, searchSuggest.getSuggestion(key).getEntries().size(), greaterThanOrEqualTo(entry));
assertThat(msg, searchSuggest.getSuggestion(key).getEntries().get(entry).getOptions().size(), greaterThan(ord));
assertThat(msg, searchSuggest.getSuggestion(key).getEntries().get(entry).getOptions().get(ord).getText().string(), equalTo(text));
assertVersionSerializable(searchSuggest);
}
/**
* Assert suggestion returns exactly the provided text.
*/
public static void assertSuggestion(Suggest searchSuggest, int entry, String key, String... text) {
assertSuggestion(searchSuggest, entry, key, text.length, text);
}
/**
* Assert suggestion returns size suggestions and the first are the provided
* text.
*/
public static void assertSuggestion(Suggest searchSuggest, int entry, String key, int size, String... text) {
assertSuggestionSize(searchSuggest, entry, size, key);
for (int i = 0; i < text.length; i++) {
assertSuggestion(searchSuggest, entry, i, key, text[i]);
}
}
/**
* Assert that an index template is missing
*/
public static void assertIndexTemplateMissing(GetIndexTemplatesResponse templatesResponse, String name) {
List<String> templateNames = new ArrayList<>();
for (IndexTemplateMetaData indexTemplateMetaData : templatesResponse.getIndexTemplates()) {
templateNames.add(indexTemplateMetaData.name());
}
assertThat(templateNames, not(hasItem(name)));
}
/**
* Assert that an index template exists
*/
public static void assertIndexTemplateExists(GetIndexTemplatesResponse templatesResponse, String name) {
List<String> templateNames = new ArrayList<>();
for (IndexTemplateMetaData indexTemplateMetaData : templatesResponse.getIndexTemplates()) {
templateNames.add(indexTemplateMetaData.name());
}
assertThat(templateNames, hasItem(name));
}
/**
* Assert that aliases are missing
*/
public static void assertAliasesMissing(AliasesExistResponse aliasesExistResponse) {
assertFalse("Aliases shouldn't exist", aliasesExistResponse.exists());
}
/**
* Assert that aliases exist
*/
public static void assertAliasesExist(AliasesExistResponse aliasesExistResponse) {
assertTrue("Aliases should exist", aliasesExistResponse.exists());
}
/*
* matchers
*/
public static Matcher<SearchHit> hasId(final String id) {
return new ElasticsearchMatchers.SearchHitHasIdMatcher(id);
}
public static Matcher<SearchHit> hasType(final String type) {
return new ElasticsearchMatchers.SearchHitHasTypeMatcher(type);
}
public static Matcher<SearchHit> hasIndex(final String index) {
return new ElasticsearchMatchers.SearchHitHasIndexMatcher(index);
}
public static Matcher<SearchHit> hasScore(final float score) {
return new ElasticsearchMatchers.SearchHitHasScoreMatcher(score);
}
public static Matcher<HttpResponse> hasStatus(RestStatus restStatus) {
return new ElasticsearchMatchers.HttpResponseHasStatusMatcher(restStatus);
}
public static <T extends Query> T assertBooleanSubQuery(Query query, Class<T> subqueryType, int i) {
assertThat(query, instanceOf(BooleanQuery.class));
BooleanQuery q = (BooleanQuery) query;
assertThat(q.getClauses().length, greaterThan(i));
assertThat(q.getClauses()[i].getQuery(), instanceOf(subqueryType));
return (T) q.getClauses()[i].getQuery();
}
/**
* Run the request from a given builder and check that it throws an exception of the right type
*/
public static <E extends Throwable> void assertThrows(ActionRequestBuilder<?, ?, ?> builder, Class<E> exceptionClass) {
assertThrows(builder.execute(), exceptionClass);
}
/**
* Run the request from a given builder and check that it throws an exception of the right type, with a given {@link org.elasticsearch.rest.RestStatus}
*/
public static <E extends Throwable> void assertThrows(ActionRequestBuilder<?, ?, ?> builder, Class<E> exceptionClass, RestStatus status) {
assertThrows(builder.execute(), exceptionClass, status);
}
/**
* Run the request from a given builder and check that it throws an exception of the right type
*
* @param extraInfo extra information to add to the failure message
*/
public static <E extends Throwable> void assertThrows(ActionRequestBuilder<?, ?, ?> builder, Class<E> exceptionClass, String extraInfo) {
assertThrows(builder.execute(), exceptionClass, extraInfo);
}
/**
* Run future.actionGet() and check that it throws an exception of the right type
*/
public static <E extends Throwable> void assertThrows(ActionFuture future, Class<E> exceptionClass) {
assertThrows(future, exceptionClass, null, null);
}
/**
* Run future.actionGet() and check that it throws an exception of the right type, with a given {@link org.elasticsearch.rest.RestStatus}
*/
public static <E extends Throwable> void assertThrows(ActionFuture future, Class<E> exceptionClass, RestStatus status) {
assertThrows(future, exceptionClass, status, null);
}
/**
* Run future.actionGet() and check that it throws an exception of the right type
*
* @param extraInfo extra information to add to the failure message
*/
public static <E extends Throwable> void assertThrows(ActionFuture future, Class<E> exceptionClass, String extraInfo) {
assertThrows(future, exceptionClass, null, extraInfo);
}
/**
* Run future.actionGet() and check that it throws an exception of the right type, optionally checking the exception's rest status
*
* @param exceptionClass expected exception class
* @param status {@link org.elasticsearch.rest.RestStatus} to check for. Can be null to disable the check
* @param extraInfo extra information to add to the failure message. Can be null.
*/
public static <E extends Throwable> void assertThrows(ActionFuture future, Class<E> exceptionClass, @Nullable RestStatus status, @Nullable String extraInfo) {
boolean fail = false;
extraInfo = extraInfo == null || extraInfo.isEmpty() ? "" : extraInfo + ": ";
extraInfo += "expected a " + exceptionClass + " exception to be thrown";
if (status != null) {
extraInfo += " with status [" + status + "]";
}
try {
future.actionGet();
fail = true;
} catch (ElasticsearchException esException) {
assertThat(extraInfo, esException.unwrapCause(), instanceOf(exceptionClass));
if (status != null) {
assertThat(extraInfo, ExceptionsHelper.status(esException), equalTo(status));
}
} catch (Throwable e) {
assertThat(extraInfo, e, instanceOf(exceptionClass));
if (status != null) {
assertThat(extraInfo, ExceptionsHelper.status(e), equalTo(status));
}
}
// has to be outside catch clause to get a proper message
if (fail) {
throw new AssertionError(extraInfo);
}
}
public static <E extends Throwable> void assertThrows(ActionRequestBuilder<?, ?, ?> builder, RestStatus status) {
assertThrows(builder.execute(), status);
}
public static <E extends Throwable> void assertThrows(ActionRequestBuilder<?, ?, ?> builder, RestStatus status, String extraInfo) {
assertThrows(builder.execute(), status, extraInfo);
}
public static <E extends Throwable> void assertThrows(ActionFuture future, RestStatus status) {
assertThrows(future, status, null);
}
public static void assertThrows(ActionFuture future, RestStatus status, String extraInfo) {
boolean fail = false;
extraInfo = extraInfo == null || extraInfo.isEmpty() ? "" : extraInfo + ": ";
extraInfo += "expected a " + status + " status exception to be thrown";
try {
future.actionGet();
fail = true;
} catch (Throwable e) {
assertThat(extraInfo, ExceptionsHelper.status(e), equalTo(status));
}
// has to be outside catch clause to get a proper message
if (fail) {
throw new AssertionError(extraInfo);
}
}
private static BytesReference serialize(Version version, Streamable streamable) throws IOException {
BytesStreamOutput output = new BytesStreamOutput();
output.setVersion(version);
streamable.writeTo(output);
output.flush();
return output.bytes();
}
public static void assertVersionSerializable(Streamable streamable) {
assertTrue(Version.CURRENT.after(VersionUtils.getPreviousVersion()));
assertVersionSerializable(randomVersion(random()), streamable);
}
public static void assertVersionSerializable(Version version, Streamable streamable) {
try {
Streamable newInstance = tryCreateNewInstance(streamable);
if (newInstance == null) {
return; // can't create a new instance - we never modify a
// streamable that comes in.
}
if (streamable instanceof ActionRequest) {
((ActionRequest<?>) streamable).validate();
}
BytesReference orig = serialize(version, streamable);
StreamInput input = StreamInput.wrap(orig);
input.setVersion(version);
newInstance.readFrom(input);
assertThat("Stream should be fully read with version [" + version + "] for streamable [" + streamable + "]", input.available(), equalTo(0));
assertThat("Serialization failed with version [" + version + "] bytes should be equal for streamable [" + streamable + "]", serialize(version, streamable), equalTo(orig));
} catch (Throwable ex) {
throw new RuntimeException("failed to check serialization - version [" + version + "] for streamable [" + streamable + "]", ex);
}
}
public static void assertVersionSerializable(Version version, final Throwable t) {
ElasticsearchAssertions.assertVersionSerializable(version, new ThrowableWrapper(t));
}
public static final class ThrowableWrapper implements Streamable {
Throwable throwable;
public ThrowableWrapper(Throwable t) {
throwable = t;
}
public ThrowableWrapper() {
throwable = null;
}
@Override
public void readFrom(StreamInput in) throws IOException {
throwable = in.readThrowable();
}
@Override
public void writeTo(StreamOutput out) throws IOException {
out.writeThrowable(throwable);
}
}
private static Streamable tryCreateNewInstance(Streamable streamable) throws NoSuchMethodException, InstantiationException,
IllegalAccessException, InvocationTargetException {
try {
Class<? extends Streamable> clazz = streamable.getClass();
Constructor<? extends Streamable> constructor = clazz.getDeclaredConstructor();
assertThat(constructor, Matchers.notNullValue());
Streamable newInstance = constructor.newInstance();
return newInstance;
} catch (Throwable e) {
return null;
}
}
/**
* Applies basic assertions on the SearchResponse. This method checks if all shards were successful, if
* any of the shards threw an exception and if the response is serializeable.
*/
public static SearchResponse assertSearchResponse(SearchRequestBuilder request) {
return assertSearchResponse(request.get());
}
/**
* Applies basic assertions on the SearchResponse. This method checks if all shards were successful, if
* any of the shards threw an exception and if the response is serializeable.
*/
public static SearchResponse assertSearchResponse(SearchResponse response) {
assertNoFailures(response);
return response;
}
public static void assertNodeContainsPlugins(NodesInfoResponse response, String nodeId,
List<String> expectedJvmPluginNames,
List<String> expectedJvmPluginDescriptions,
List<String> expectedJvmVersions,
List<String> expectedSitePluginNames,
List<String> expectedSitePluginDescriptions,
List<String> expectedSiteVersions) {
Assert.assertThat(response.getNodesMap().get(nodeId), notNullValue());
PluginsAndModules plugins = response.getNodesMap().get(nodeId).getPlugins();
Assert.assertThat(plugins, notNullValue());
List<String> pluginNames = FluentIterable.from(plugins.getPluginInfos()).filter(jvmPluginPredicate).transform(nameFunction).toList();
for (String expectedJvmPluginName : expectedJvmPluginNames) {
Assert.assertThat(pluginNames, hasItem(expectedJvmPluginName));
}
List<String> pluginDescriptions = FluentIterable.from(plugins.getPluginInfos()).filter(jvmPluginPredicate).transform(descriptionFunction).toList();
for (String expectedJvmPluginDescription : expectedJvmPluginDescriptions) {
Assert.assertThat(pluginDescriptions, hasItem(expectedJvmPluginDescription));
}
List<String> jvmPluginVersions = FluentIterable.from(plugins.getPluginInfos()).filter(jvmPluginPredicate).transform(versionFunction).toList();
for (String pluginVersion : expectedJvmVersions) {
Assert.assertThat(jvmPluginVersions, hasItem(pluginVersion));
}
FluentIterable<String> jvmUrls = FluentIterable.from(plugins.getPluginInfos())
.filter(Predicates.and(jvmPluginPredicate, Predicates.not(sitePluginPredicate)))
.transform(urlFunction)
.filter(notNull());
Assert.assertThat(Iterables.size(jvmUrls), is(0));
List<String> sitePluginNames = FluentIterable.from(plugins.getPluginInfos()).filter(sitePluginPredicate).transform(nameFunction).toList();
Assert.assertThat(sitePluginNames.isEmpty(), is(expectedSitePluginNames.isEmpty()));
for (String expectedSitePluginName : expectedSitePluginNames) {
Assert.assertThat(sitePluginNames, hasItem(expectedSitePluginName));
}
List<String> sitePluginDescriptions = FluentIterable.from(plugins.getPluginInfos()).filter(sitePluginPredicate).transform(descriptionFunction).toList();
Assert.assertThat(sitePluginDescriptions.isEmpty(), is(expectedSitePluginDescriptions.isEmpty()));
for (String sitePluginDescription : expectedSitePluginDescriptions) {
Assert.assertThat(sitePluginDescriptions, hasItem(sitePluginDescription));
}
List<String> sitePluginUrls = FluentIterable.from(plugins.getPluginInfos()).filter(sitePluginPredicate).transform(urlFunction).toList();
Assert.assertThat(sitePluginUrls, not(contains(nullValue())));
List<String> sitePluginVersions = FluentIterable.from(plugins.getPluginInfos()).filter(sitePluginPredicate).transform(versionFunction).toList();
Assert.assertThat(sitePluginVersions.isEmpty(), is(expectedSiteVersions.isEmpty()));
for (String pluginVersion : expectedSiteVersions) {
Assert.assertThat(sitePluginVersions, hasItem(pluginVersion));
}
}
private static Predicate<PluginInfo> jvmPluginPredicate = new Predicate<PluginInfo>() {
@Override
public boolean apply(PluginInfo pluginInfo) {
return pluginInfo.isJvm();
}
};
private static Predicate<PluginInfo> sitePluginPredicate = new Predicate<PluginInfo>() {
@Override
public boolean apply(PluginInfo pluginInfo) {
return pluginInfo.isSite();
}
};
private static Function<PluginInfo, String> nameFunction = new Function<PluginInfo, String>() {
@Override
public String apply(PluginInfo pluginInfo) {
return pluginInfo.getName();
}
};
private static Function<PluginInfo, String> descriptionFunction = new Function<PluginInfo, String>() {
@Override
public String apply(PluginInfo pluginInfo) {
return pluginInfo.getDescription();
}
};
private static Function<PluginInfo, String> urlFunction = new Function<PluginInfo, String>() {
@Override
public String apply(PluginInfo pluginInfo) {
return pluginInfo.getUrl();
}
};
private static Function<PluginInfo, String> versionFunction = new Function<PluginInfo, String>() {
@Override
public String apply(PluginInfo pluginInfo) {
return pluginInfo.getVersion();
}
};
/**
* Check if a file exists
*/
public static void assertFileExists(Path file) {
assertThat("file/dir [" + file + "] should exist.", Files.exists(file), is(true));
}
/**
* Check if a file does not exist
*/
public static void assertFileNotExists(Path file) {
assertThat("file/dir [" + file + "] should not exist.", Files.exists(file), is(false));
}
/**
* Check if a directory exists
*/
public static void assertDirectoryExists(Path dir) {
assertFileExists(dir);
assertThat("file [" + dir + "] should be a directory.", Files.isDirectory(dir), is(true));
}
}