blob: 04fad64161412bde5635c8edf416efc368efed41 [file] [log] [blame]
/*
* 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.assertj.core.api.Assertions.assertThatThrownBy;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
import java.util.concurrent.atomic.AtomicLong;
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.execute.FunctionContext;
import org.apache.geode.cache.execute.ResultSender;
import org.apache.geode.cache.query.Index;
import org.apache.geode.cache.query.IndexStatistics;
import org.apache.geode.cache.query.IndexType;
import org.apache.geode.cache.query.QueryService;
import org.apache.geode.distributed.DistributedMember;
import org.apache.geode.distributed.DistributedSystem;
import org.apache.geode.internal.lang.ObjectUtils;
import org.apache.geode.internal.util.CollectionUtils;
import org.apache.geode.management.internal.cli.domain.IndexDetails;
import org.apache.geode.management.internal.cli.domain.IndexDetails.IndexStatisticsDetails;
/**
* The ListIndexFunctionJUnitTest class is test suite of test cases testing the contract and
* functionality of the ListIndexFunction GemFire function.
* </p>
* </p>
*
* @see org.apache.geode.management.internal.cli.functions.ListIndexFunction
* @see org.junit.Test
* @since GemFire 7.0
*/
public class ListIndexFunctionJUnitTest {
private AtomicLong counter;
private QueryService mockQueryService;
private TestResultSender testResultSender;
private FunctionContext mockFunctionContext;
private final String mockMemberId = "mockMemberId";
private final String mockMemberName = "mockMemberName";
@Before
public void setup() {
counter = new AtomicLong(0L);
testResultSender = new TestResultSender();
mockQueryService = mock(QueryService.class, "QueryService");
mockFunctionContext = mock(FunctionContext.class, "FunctionContext");
final Cache mockCache = mock(Cache.class, "Cache");
final DistributedSystem mockDistributedSystem =
mock(DistributedSystem.class, "DistributedSystem");
final DistributedMember mockDistributedMember =
mock(DistributedMember.class, "DistributedMember");
when(mockCache.getQueryService()).thenReturn(mockQueryService);
when(mockCache.getDistributedSystem()).thenReturn(mockDistributedSystem);
when(mockDistributedSystem.getDistributedMember()).thenReturn(mockDistributedMember);
when(mockDistributedMember.getId()).thenReturn(mockMemberId);
when(mockDistributedMember.getName()).thenReturn(mockMemberName);
when(mockFunctionContext.getCache()).thenReturn(mockCache);
when(mockFunctionContext.getResultSender()).thenReturn(testResultSender);
}
private void assertIndexStatisticsDetailsEquals(
final IndexStatisticsDetails actualIndexStatisticsDetails,
final IndexStatisticsDetails expectedIndexStatisticsDetails) {
if (expectedIndexStatisticsDetails != null) {
assertThat(actualIndexStatisticsDetails).isNotNull();
assertThat(actualIndexStatisticsDetails.getNumberOfKeys())
.isEqualTo(expectedIndexStatisticsDetails.getNumberOfKeys());
assertThat(actualIndexStatisticsDetails.getNumberOfUpdates())
.isEqualTo(expectedIndexStatisticsDetails.getNumberOfUpdates());
assertThat(actualIndexStatisticsDetails.getNumberOfValues())
.isEqualTo(expectedIndexStatisticsDetails.getNumberOfValues());
assertThat(actualIndexStatisticsDetails.getTotalUpdateTime())
.isEqualTo(expectedIndexStatisticsDetails.getTotalUpdateTime());
assertThat(actualIndexStatisticsDetails.getTotalUses())
.isEqualTo(expectedIndexStatisticsDetails.getTotalUses());
} else {
assertThat(actualIndexStatisticsDetails).isNull();
}
}
private void assertIndexDetailsEquals(final IndexDetails actualIndexDetails,
final IndexDetails expectedIndexDetails) {
assertThat(actualIndexDetails).isNotNull();
assertThat(actualIndexDetails.getFromClause()).isEqualTo(expectedIndexDetails.getFromClause());
assertThat(actualIndexDetails.getIndexedExpression())
.isEqualTo(expectedIndexDetails.getIndexedExpression());
assertThat(actualIndexDetails.getIndexName()).isEqualTo(expectedIndexDetails.getIndexName());
assertThat(actualIndexDetails.getIndexType()).isEqualTo(expectedIndexDetails.getIndexType());
assertThat(actualIndexDetails.getMemberId()).isEqualTo(expectedIndexDetails.getMemberId());
assertThat(actualIndexDetails.getMemberName()).isEqualTo(expectedIndexDetails.getMemberName());
assertThat(actualIndexDetails.getProjectionAttributes())
.isEqualTo(expectedIndexDetails.getProjectionAttributes());
assertThat(actualIndexDetails.getRegionName()).isEqualTo(expectedIndexDetails.getRegionName());
assertThat(actualIndexDetails.getRegionPath()).isEqualTo(expectedIndexDetails.getRegionPath());
assertIndexStatisticsDetailsEquals(actualIndexDetails.getIndexStatisticsDetails(),
expectedIndexDetails.getIndexStatisticsDetails());
}
private IndexDetails createIndexDetails(final String regionPath, final String indexName,
final IndexType indexType, final String fromClause, final String indexedExpression,
final String projectionAttributes, final String regionName) {
final IndexDetails indexDetails = new IndexDetails(mockMemberId, regionPath, indexName);
indexDetails.setFromClause(fromClause);
indexDetails.setIndexedExpression(indexedExpression);
indexDetails.setIndexType(indexType);
indexDetails.setMemberName(mockMemberName);
indexDetails.setProjectionAttributes(projectionAttributes);
indexDetails.setRegionName(regionName);
return indexDetails;
}
private IndexStatisticsDetails createIndexStatisticsDetails(final Long numberOfKeys,
final Long numberOfUpdates, final Long numberOfValues, final Long totalUpdateTime,
final Long totalUses) {
final IndexStatisticsDetails indexStatisticsDetails = new IndexStatisticsDetails();
indexStatisticsDetails.setNumberOfKeys(numberOfKeys);
indexStatisticsDetails.setNumberOfUpdates(numberOfUpdates);
indexStatisticsDetails.setNumberOfValues(numberOfValues);
indexStatisticsDetails.setTotalUpdateTime(totalUpdateTime);
indexStatisticsDetails.setTotalUses(totalUses);
return indexStatisticsDetails;
}
@SuppressWarnings("unchecked")
private Index createMockIndex(final IndexDetails indexDetails) {
final Region mockRegion =
mock(Region.class, "Region " + indexDetails.getRegionPath() + " " + counter
.getAndIncrement());
when(mockRegion.getName()).thenReturn(indexDetails.getRegionName());
when(mockRegion.getFullPath()).thenReturn(indexDetails.getRegionPath());
final Index mockIndex = mock(Index.class, "Index " + indexDetails.getIndexName() + " " + counter
.getAndIncrement());
when(mockIndex.getRegion()).thenReturn(mockRegion);
when(mockIndex.getType()).thenReturn(indexDetails.getIndexType());
when(mockIndex.getName()).thenReturn(indexDetails.getIndexName());
when(mockIndex.getFromClause()).thenReturn(indexDetails.getFromClause());
when(mockIndex.getIndexedExpression()).thenReturn(indexDetails.getIndexedExpression());
when(mockIndex.getProjectionAttributes()).thenReturn(indexDetails.getProjectionAttributes());
if (indexDetails.getIndexStatisticsDetails() != null) {
final IndexStatistics mockIndexStatistics = mock(IndexStatistics.class,
"IndexStatistics " + indexDetails.getIndexName() + " " + counter
.getAndIncrement());
when(mockIndex.getStatistics()).thenReturn(mockIndexStatistics);
when(mockIndexStatistics.getNumUpdates())
.thenReturn(indexDetails.getIndexStatisticsDetails().getNumberOfUpdates());
when(mockIndexStatistics.getNumberOfKeys())
.thenReturn(indexDetails.getIndexStatisticsDetails().getNumberOfKeys());
when(mockIndexStatistics.getNumberOfValues())
.thenReturn(indexDetails.getIndexStatisticsDetails().getNumberOfValues());
when(mockIndexStatistics.getTotalUpdateTime())
.thenReturn(indexDetails.getIndexStatisticsDetails().getTotalUpdateTime());
when(mockIndexStatistics.getTotalUses())
.thenReturn(indexDetails.getIndexStatisticsDetails().getTotalUses());
} else {
when(mockIndex.getStatistics()).thenReturn(null);
}
return mockIndex;
}
@Test
@SuppressWarnings("unchecked")
public void testExecute() throws Throwable {
// Expected Results
final IndexDetails indexDetailsOne = createIndexDetails("/Employees", "empIdIdx",
IndexType.PRIMARY_KEY, "/Employees", "id", "id, firstName, lastName", "Employees");
indexDetailsOne.setIndexStatisticsDetails(
createIndexStatisticsDetails(10124L, 4096L, 10124L, 1284100L, 280120L));
final IndexDetails indexDetailsTwo = createIndexDetails("/Employees", "empGivenNameIdx",
IndexType.FUNCTIONAL, "/Employees", "lastName", "id, firstName, lastName", "Employees");
final IndexDetails indexDetailsThree = createIndexDetails("/Contractors", "empIdIdx",
IndexType.PRIMARY_KEY, "/Contrators", "id", "id, firstName, lastName", "Contractors");
indexDetailsThree.setIndexStatisticsDetails(
createIndexStatisticsDetails(1024L, 256L, 20248L, 768001L, 24480L));
final IndexDetails indexDetailsFour = createIndexDetails("/Employees", "empIdIdx",
IndexType.FUNCTIONAL, "/Employees", "emp_id", "id, surname, givenname", "Employees");
final Set<IndexDetails> expectedIndexDetailsSet =
new HashSet<>(Arrays.asList(indexDetailsOne, indexDetailsTwo, indexDetailsThree));
// Prepare Mocks
List<Index> indexes =
Arrays.asList(createMockIndex(indexDetailsOne), createMockIndex(indexDetailsTwo),
createMockIndex(indexDetailsThree), createMockIndex(indexDetailsFour));
when(mockQueryService.getIndexes()).thenReturn(indexes);
// Execute Function and Assert Results
final ListIndexFunction function = new ListIndexFunction();
function.execute(mockFunctionContext);
final List<?> results = testResultSender.getResults();
assertThat(results).isNotNull();
assertThat(results.size()).isEqualTo(1);
final Set<IndexDetails> actualIndexDetailsSet = (Set<IndexDetails>) results.get(0);
assertThat(actualIndexDetailsSet).isNotNull();
assertThat(actualIndexDetailsSet.size()).isEqualTo(expectedIndexDetailsSet.size());
for (final IndexDetails expectedIndexDetails : expectedIndexDetailsSet) {
final IndexDetails actualIndexDetails = CollectionUtils.findBy(actualIndexDetailsSet,
indexDetails -> ObjectUtils.equals(expectedIndexDetails, indexDetails));
assertIndexDetailsEquals(actualIndexDetails, expectedIndexDetails);
}
}
@Test
@SuppressWarnings("unchecked")
public void testExecuteWithNoIndexes() throws Throwable {
// Prepare Mocks
when(mockQueryService.getIndexes()).thenReturn(Collections.emptyList());
// Execute Function and assert results
final ListIndexFunction function = new ListIndexFunction();
function.execute(mockFunctionContext);
final List<?> results = testResultSender.getResults();
assertThat(results).isNotNull();
assertThat(results.size()).isEqualTo(1);
final Set<IndexDetails> actualIndexDetailsSet = (Set<IndexDetails>) results.get(0);
assertThat(actualIndexDetailsSet).isNotNull();
assertThat(actualIndexDetailsSet.isEmpty()).isTrue();
}
@Test
public void testExecuteThrowsException() {
// Prepare Mocks
when(mockQueryService.getIndexes()).thenThrow(new RuntimeException("Mocked Exception"));
// Execute Function and assert results
final ListIndexFunction function = new ListIndexFunction();
function.execute(mockFunctionContext);
assertThatThrownBy(() -> testResultSender.getResults()).isInstanceOf(RuntimeException.class)
.hasMessage("Mocked Exception");
}
private static class TestResultSender implements ResultSender {
private Throwable t;
private final List<Object> results = new LinkedList<>();
protected List<Object> getResults() throws Throwable {
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 = t;
}
}
}