/* * Licensed to Crate under one or more contributor license agreements. * See the NOTICE file distributed with this work for additional * information regarding copyright ownership. Crate 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. * * However, if you have executed another commercial license agreement * with Crate these terms will supersede the license and you may use the * software solely pursuant to the terms of the relevant commercial * agreement. */ package io.crate.operation.collect.sources; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; import com.google.common.collect.Iterables; import io.crate.analyze.OrderBy; import io.crate.analyze.WhereClause; import io.crate.data.Row; import io.crate.integrationtests.SQLTransportIntegrationTest; import io.crate.metadata.*; import io.crate.metadata.shard.unassigned.UnassignedShard; import io.crate.operation.reference.sys.snapshot.SysSnapshot; import io.crate.operation.reference.sys.snapshot.SysSnapshots; import io.crate.planner.distribution.DistributionInfo; import io.crate.planner.node.dql.RoutedCollectPhase; import io.crate.types.DataTypes; import org.elasticsearch.cluster.routing.ShardRoutingState; import org.elasticsearch.cluster.service.ClusterService; import org.elasticsearch.common.UUIDs; import org.elasticsearch.index.shard.ShardId; import org.elasticsearch.repositories.RepositoryException; import org.elasticsearch.snapshots.SnapshotException; import org.elasticsearch.test.ESIntegTestCase; import org.junit.Test; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.UUID; import java.util.concurrent.CompletableFuture; import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeUnit; import java.util.function.Supplier; import static org.hamcrest.Matchers.containsString; import static org.hamcrest.Matchers.is; import static org.mockito.Mockito.mock; @ESIntegTestCase.ClusterScope(numDataNodes = 1, supportsDedicatedMasters = false) public class SystemCollectSourceTest extends SQLTransportIntegrationTest { @Test public void testOrderBySymbolsDoNotAppearTwiceInRows() throws Exception { SystemCollectSource systemCollectSource = internalCluster().getDataNodeInstance(SystemCollectSource.class); Reference shardId = new Reference( new ReferenceIdent(new TableIdent("sys", "shards"), "id"), RowGranularity.SHARD, DataTypes.INTEGER); RoutedCollectPhase collectPhase = new RoutedCollectPhase( UUID.randomUUID(), 1, "collect", new Routing(ImmutableMap.of()), RowGranularity.SHARD, Collections.singletonList(shardId), ImmutableList.of(), WhereClause.MATCH_ALL, DistributionInfo.DEFAULT_BROADCAST ); collectPhase.orderBy(new OrderBy(Collections.singletonList(shardId), new boolean[]{false}, new Boolean[]{null})); Iterable<? extends Row> rows = systemCollectSource.toRowsIterableTransformation(collectPhase, false) .apply(Collections.singletonList(new UnassignedShard( new ShardId("foo", UUIDs.randomBase64UUID(),1), mock(ClusterService.class), true, ShardRoutingState.UNASSIGNED))); Row next = rows.iterator().next(); assertThat(next.numColumns(), is(1)); } @Test public void testReadIsolation() throws Exception { SystemCollectSource systemCollectSource = internalCluster().getDataNodeInstance(SystemCollectSource.class); RoutedCollectPhase collectPhase = new RoutedCollectPhase( UUID.randomUUID(), 1, "collect", new Routing(ImmutableMap.of()), RowGranularity.SHARD, ImmutableList.of(), ImmutableList.of(), WhereClause.MATCH_ALL, DistributionInfo.DEFAULT_BROADCAST); // No read isolation List<String> noReadIsolationIterable = new ArrayList<>(); noReadIsolationIterable.add("a"); noReadIsolationIterable.add("b"); Iterable<? extends Row> rows = systemCollectSource.toRowsIterableTransformation(collectPhase, false) .apply(noReadIsolationIterable); assertThat(Iterables.size(rows), is(2)); noReadIsolationIterable.add("c"); assertThat(Iterables.size(rows), is(3)); // Read isolation List<String> readIsolationIterable = new ArrayList<>(); readIsolationIterable.add("a"); readIsolationIterable.add("b"); rows = systemCollectSource.toRowsIterableTransformation(collectPhase, true) .apply(readIsolationIterable); assertThat(Iterables.size(rows), is(2)); readIsolationIterable.add("c"); assertThat(Iterables.size(rows), is(2)); } @Test public void testSnapshotSupplierExposesError() throws Exception { // SysSnapshots issues queries, so errors may occur. This test ensures that this errors are exposed. expectedException.expect(ExecutionException.class); expectedException.expectMessage(containsString("[my_repository] failed to find repository")); Supplier<CompletableFuture<? extends Iterable<?>>> snapshotSupplier = SystemCollectSource.snapshotSupplier( new SysSnapshots(null, null) { @Override public Iterable<SysSnapshot> snapshotsGetter() throws SnapshotException, RepositoryException { throw new RepositoryException("my_repository", "failed to find repository"); } } ); CompletableFuture future = snapshotSupplier.get(); future.get(1, TimeUnit.SECONDS); } }