| /* |
| * Licensed to the Apache Software Foundation (ASF) under one or more contributor license |
| * agreements. See the NOTICE file distributed with this work for additional information regarding |
| * copyright ownership. The ASF 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.apache.geode.management.internal.cli.functions; |
| |
| import static org.assertj.core.api.Assertions.assertThat; |
| import static org.mockito.Mockito.doReturn; |
| import static org.mockito.Mockito.mock; |
| import static org.mockito.Mockito.spy; |
| import static org.mockito.Mockito.when; |
| |
| import java.util.Arrays; |
| import java.util.Collections; |
| import java.util.HashMap; |
| import java.util.HashSet; |
| import java.util.LinkedList; |
| import java.util.List; |
| import java.util.Set; |
| |
| import org.junit.Before; |
| import org.junit.Test; |
| |
| import org.apache.geode.cache.Cache; |
| import org.apache.geode.cache.Region; |
| import org.apache.geode.cache.configuration.RegionConfig; |
| import org.apache.geode.cache.execute.FunctionContext; |
| import org.apache.geode.cache.execute.ResultSender; |
| import org.apache.geode.cache.query.Index; |
| import org.apache.geode.cache.query.IndexCreationException; |
| import org.apache.geode.cache.query.IndexType; |
| import org.apache.geode.cache.query.MultiIndexCreationException; |
| import org.apache.geode.cache.query.QueryService; |
| import org.apache.geode.cache.query.internal.InternalQueryService; |
| import org.apache.geode.cache.query.internal.index.CompactMapRangeIndex; |
| import org.apache.geode.cache.query.internal.index.HashIndex; |
| import org.apache.geode.cache.query.internal.index.PrimaryKeyIndex; |
| import org.apache.geode.internal.cache.execute.FunctionContextImpl; |
| import org.apache.geode.test.fake.Fakes; |
| |
| public class CreateDefinedIndexesFunctionTest { |
| private Cache cache; |
| private Region region1; |
| private Region region2; |
| private FunctionContext context; |
| private QueryService queryService; |
| private TestResultSender resultSender; |
| private Set<RegionConfig.Index> indexDefinitions; |
| private CreateDefinedIndexesFunction function; |
| |
| @Before |
| public void setUp() throws Exception { |
| cache = Fakes.cache(); |
| resultSender = new TestResultSender(); |
| queryService = spy(InternalQueryService.class); |
| region1 = Fakes.region("Region1", cache); |
| region2 = Fakes.region("Region2", cache); |
| function = spy(CreateDefinedIndexesFunction.class); |
| doReturn(queryService).when(cache).getQueryService(); |
| |
| indexDefinitions = new HashSet<>(); |
| indexDefinitions.add(new RegionConfig.Index() { |
| { |
| setName("index1"); |
| setExpression("value1"); |
| setFromClause("/Region1"); |
| setType(IndexType.HASH.getName()); |
| } |
| }); |
| indexDefinitions.add(new RegionConfig.Index() { |
| { |
| setName("index2"); |
| setExpression("value2"); |
| setFromClause("/Region2"); |
| setType(IndexType.FUNCTIONAL.getName()); |
| } |
| }); |
| indexDefinitions.add(new RegionConfig.Index() { |
| { |
| setName("index3"); |
| setExpression("value3"); |
| setFromClause("/Region1"); |
| setType(IndexType.PRIMARY_KEY.getName()); |
| } |
| }); |
| } |
| |
| @Test |
| public void noIndexDefinitionsAsFunctionArgument() throws Exception { |
| context = new FunctionContextImpl(cache, CreateDefinedIndexesFunction.class.getName(), |
| Collections.emptySet(), resultSender); |
| |
| function.execute(context); |
| List<?> results = resultSender.getResults(); |
| |
| assertThat(results).isNotNull(); |
| assertThat(results.size()).isEqualTo(2); |
| Object firstResult = results.get(0); |
| assertThat(firstResult).isInstanceOf(CliFunctionResult.class); |
| assertThat(((CliFunctionResult) firstResult).isSuccessful()).isTrue(); |
| assertThat(((CliFunctionResult) firstResult).getMessage()).isNotEmpty(); |
| assertThat(((CliFunctionResult) firstResult).getMessage()).contains("No indexes defined"); |
| } |
| |
| @Test |
| public void noIndexPreviouslyDefinedInQueryService() throws Exception { |
| when(queryService.createDefinedIndexes()).thenReturn(Collections.emptyList()); |
| context = new FunctionContextImpl(cache, CreateDefinedIndexesFunction.class.getName(), |
| indexDefinitions, resultSender); |
| |
| function.execute(context); |
| List<?> results = resultSender.getResults(); |
| |
| assertThat(results).isNotNull(); |
| assertThat(results.size()).isEqualTo(2); |
| Object firstResult = results.get(0); |
| assertThat(firstResult).isInstanceOf(CliFunctionResult.class); |
| assertThat(((CliFunctionResult) firstResult).isSuccessful()).isTrue(); |
| assertThat(((CliFunctionResult) firstResult).getMessage()).isNotEmpty(); |
| assertThat(((CliFunctionResult) firstResult).getMessage()).contains("No indexes defined"); |
| } |
| |
| @Test |
| public void multiIndexCreationExceptionThrowByQueryService() throws Exception { |
| HashMap<String, Exception> exceptions = new HashMap<>(); |
| exceptions.put("index1", new IndexCreationException("Mock Failure.")); |
| exceptions.put("index3", new IndexCreationException("Another Mock Failure.")); |
| when(queryService.createDefinedIndexes()) |
| .thenThrow(new MultiIndexCreationException(exceptions)); |
| context = new FunctionContextImpl(cache, CreateDefinedIndexesFunction.class.getName(), |
| indexDefinitions, resultSender); |
| |
| function.execute(context); |
| List<?> results = resultSender.getResults(); |
| |
| assertThat(results).isNotNull(); |
| assertThat(results.size()).isEqualTo(4); |
| |
| CliFunctionResult result1 = (CliFunctionResult) results.get(0); |
| assertThat(result1.isSuccessful()).isTrue(); |
| assertThat(result1.getStatusMessage()).isEqualTo("Created index index2"); |
| |
| CliFunctionResult result2 = (CliFunctionResult) results.get(1); |
| assertThat(result2.isSuccessful()).isFalse(); |
| assertThat(result2.getStatusMessage()) |
| .isEqualTo("Failed to create index index1: Mock Failure."); |
| |
| CliFunctionResult result3 = (CliFunctionResult) results.get(2); |
| assertThat(result3.isSuccessful()).isFalse(); |
| assertThat(result3.getStatusMessage()) |
| .isEqualTo("Failed to create index index3: Another Mock Failure."); |
| } |
| |
| @Test |
| public void unexpectedExceptionThrowByQueryService() throws Exception { |
| when(queryService.createDefinedIndexes()).thenThrow(new RuntimeException("Mock Exception")); |
| context = new FunctionContextImpl(cache, CreateDefinedIndexesFunction.class.getName(), |
| indexDefinitions, resultSender); |
| |
| function.execute(context); |
| List<?> results = resultSender.getResults(); |
| |
| assertThat(results).isNotNull(); |
| assertThat(results.size()).isEqualTo(2); |
| CliFunctionResult firstResult = (CliFunctionResult) results.get(0); |
| |
| assertThat(firstResult.isSuccessful()).isFalse(); |
| assertThat(firstResult.getStatusMessage()).isEqualTo("Mock Exception"); |
| } |
| |
| @Test |
| public void creationSuccess() throws Exception { |
| Index index1 = mock(HashIndex.class); |
| when(index1.getName()).thenReturn("index1"); |
| when(index1.getRegion()).thenReturn(region1); |
| |
| Index index2 = mock(CompactMapRangeIndex.class); |
| when(index2.getName()).thenReturn("index2"); |
| when(index2.getRegion()).thenReturn(region2); |
| |
| Index index3 = mock(PrimaryKeyIndex.class); |
| when(index3.getName()).thenReturn("index3"); |
| when(index3.getRegion()).thenReturn(region1); |
| |
| when(queryService.createDefinedIndexes()).thenReturn(Arrays.asList(index1, index2, index3)); |
| context = new FunctionContextImpl(cache, CreateDefinedIndexesFunction.class.getName(), |
| indexDefinitions, resultSender); |
| |
| function.execute(context); |
| List<?> results = resultSender.getResults(); |
| |
| assertThat(results).isNotNull(); |
| assertThat(results.size()).isEqualTo(4); |
| |
| Object firstIndex = results.get(0); |
| assertThat(firstIndex).isNotNull(); |
| assertThat(firstIndex).isInstanceOf(CliFunctionResult.class); |
| assertThat(((CliFunctionResult) firstIndex).isSuccessful()); |
| } |
| |
| private static class TestResultSender implements ResultSender { |
| |
| private final List<Object> results = new LinkedList<>(); |
| |
| private Exception t; |
| |
| protected List<Object> getResults() throws Exception { |
| if (t != null) { |
| throw t; |
| } |
| return Collections.unmodifiableList(results); |
| } |
| |
| @Override |
| public void lastResult(final Object lastResult) { |
| results.add(lastResult); |
| } |
| |
| @Override |
| public void sendResult(final Object oneResult) { |
| results.add(oneResult); |
| } |
| |
| @Override |
| public void sendException(final Throwable t) { |
| this.t = (Exception) t; |
| } |
| } |
| } |