package rocks.inspectit.shared.cs.indexing.indexer.impl;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.arrayWithSize;
import static org.hamcrest.Matchers.emptyArray;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.not;
import static org.hamcrest.Matchers.notNullValue;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.RandomStringUtils;
import org.testng.annotations.Test;
import rocks.inspectit.shared.all.communication.DefaultData;
import rocks.inspectit.shared.all.communication.MethodSensorData;
import rocks.inspectit.shared.all.communication.data.InvocationSequenceData;
import rocks.inspectit.shared.all.communication.data.SqlStatementData;
import rocks.inspectit.shared.all.indexing.IIndexQuery;
import rocks.inspectit.shared.cs.indexing.impl.IndexQuery;
import rocks.inspectit.shared.cs.indexing.storage.impl.StorageIndexQuery;
/**
* Tests all available branch indexer classes.
*
* @author Ivan Senic
*
*/
@SuppressWarnings("PMD")
public class BranchIndexersTest {
/**
* Testing that the {@link InvocationChildrenIndexer} will return different keys based on if the
* invocation has children or not.
*/
@Test
public void invocationChildIndexer() {
// different keys for invocation with and without children
InvocationSequenceData data1 = mock(InvocationSequenceData.class);
when(data1.getNestedSequences()).thenReturn(Collections.<InvocationSequenceData> emptyList());
InvocationSequenceData data2 = mock(InvocationSequenceData.class);
when(data2.getNestedSequences()).thenReturn(Collections.singletonList(data1));
InvocationChildrenIndexer<DefaultData> indexer = new InvocationChildrenIndexer<>();
Object key1 = indexer.getKey(data1);
Object key2 = indexer.getKey(data2);
assertThat(key1, is(not(key2)));
StorageIndexQuery query = mock(StorageIndexQuery.class);
when(query.isOnlyInvocationsWithoutChildren()).thenReturn(true).thenReturn(false);
key1 = indexer.getKeys(query);
key2 = indexer.getKeys(query);
assertThat(key1, is(not(key2)));
}
/**
* Testing that the {@link MethodIdentIndexer} returns different keys based on the method ident.
*/
@Test
public void methodIdentIndexer() {
// different keys if method idents differ
MethodSensorData data = mock(MethodSensorData.class);
when(data.getMethodIdent()).thenReturn(10L).thenReturn(20L);
MethodIdentIndexer<DefaultData> indexer = new MethodIdentIndexer<>();
Object key1 = indexer.getKey(data);
Object key2 = indexer.getKey(data);
assertThat(key1, is(not(key2)));
IIndexQuery query = mock(IIndexQuery.class);
when(query.getMethodIdent()).thenReturn(0L);
assertThat(indexer.getKeys(query), is(emptyArray()));
when(query.getMethodIdent()).thenReturn(10L);
key1 = indexer.getKeys(query);
when(query.getMethodIdent()).thenReturn(20L);
key2 = indexer.getKeys(query);
assertThat(key1, is(not(key2)));
}
/**
* Testing that the {@link PlatformIdentIndexer} returns different keys based on the platform
* ident.
*/
@Test
public void platformIdentIndexer() {
// different keys if platform idents differ
DefaultData data = mock(DefaultData.class);
PlatformIdentIndexer<DefaultData> indexer = new PlatformIdentIndexer<>();
when(data.getPlatformIdent()).thenReturn(10L);
Object key1 = indexer.getKey(data);
when(data.getPlatformIdent()).thenReturn(20L);
Object key2 = indexer.getKey(data);
assertThat(key1, is(not(key2)));
IIndexQuery query = mock(IIndexQuery.class);
when(query.getPlatformIdent()).thenReturn(0L);
assertThat(indexer.getKeys(query), is(emptyArray()));
when(query.getPlatformIdent()).thenReturn(10L);
key1 = indexer.getKeys(query);
when(query.getPlatformIdent()).thenReturn(20L);
key2 = indexer.getKeys(query);
assertThat(key1, is(not(key2)));
}
/**
* Testing that the {@link SensorTypeIdentIndexer} returns different keys based on the sensor
* type ident.
*/
@Test
public void sensorTypeIdentIndexer() {
// different keys if sensor type idents differ
DefaultData data = mock(DefaultData.class);
SensorTypeIdentIndexer<DefaultData> indexer = new SensorTypeIdentIndexer<>();
when(data.getSensorTypeIdent()).thenReturn(10L);
Object key1 = indexer.getKey(data);
when(data.getSensorTypeIdent()).thenReturn(20L);
Object key2 = indexer.getKey(data);
assertThat(key1, is(not(key2)));
IIndexQuery query = mock(IIndexQuery.class);
when(query.getSensorTypeIdent()).thenReturn(0L);
assertThat(indexer.getKeys(query), is(emptyArray()));
when(query.getSensorTypeIdent()).thenReturn(10L);
key1 = indexer.getKeys(query);
when(query.getSensorTypeIdent()).thenReturn(20L);
key2 = indexer.getKeys(query);
assertThat(key1, is(not(key2)));
}
/**
* Tests the {@link ObjectTypeIndexer} for different keys when different objects are indexed.
*/
@Test
public void objectTypeIndexer() {
DefaultData data1 = mock(InvocationSequenceData.class);
DefaultData data2 = mock(SqlStatementData.class);
ObjectTypeIndexer<DefaultData> indexer = new ObjectTypeIndexer<>();
Object key1 = indexer.getKey(data1);
Object key2 = indexer.getKey(data2);
assertThat(key1, is(not(key2)));
IIndexQuery query = mock(IIndexQuery.class);
when(query.getObjectClasses()).thenReturn(null);
assertThat(indexer.getKeys(query), is(emptyArray()));
List<Class<?>> classes = new ArrayList<>();
CollectionUtils.addAll(classes, new Object[] { InvocationSequenceData.class, SqlStatementData.class });
when(query.getObjectClasses()).thenReturn(classes);
Object[] keys = indexer.getKeys(query);
assertThat(keys, is(arrayWithSize(2)));
assertThat(keys[0], is(not(keys[1])));
}
/**
* Tests the functionality of the {@link SqlStringIndexer}.
*/
@Test
public void sqlStringIndexer() {
SqlStatementData data = mock(SqlStatementData.class);
SqlStringIndexer<DefaultData> indexer = new SqlStringIndexer<>();
when(data.getSql()).thenReturn(RandomStringUtils.random(100));
Object key1 = indexer.getKey(data);
when(data.getSql()).thenReturn(RandomStringUtils.random(100));
Object key2 = indexer.getKey(data);
assertThat(key1, is(not(key2)));
// assert that if max keys is set it will work
indexer = new SqlStringIndexer<>(1);
when(data.getSql()).thenReturn(RandomStringUtils.random(100));
key1 = indexer.getKey(data);
when(data.getSql()).thenReturn(RandomStringUtils.random(100));
key2 = indexer.getKey(data);
assertThat(key1, is(key2));
StorageIndexQuery query = mock(StorageIndexQuery.class);
assertThat(indexer.getKeys(query), is(emptyArray()));
when(query.getSql()).thenReturn(RandomStringUtils.random(100));
Object[] keys = indexer.getKeys(query);
assertThat(keys, is(arrayWithSize(1)));
assertThat(keys[0], is(notNullValue()));
}
/**
* Tests the {@link TimestampIndexer}.
*/
@Test
public void timestampIndexer() {
DefaultData data = mock(DefaultData.class);
TimestampIndexer<DefaultData> indexer = new TimestampIndexer<>();
when(data.getTimeStamp()).thenReturn(new Timestamp(System.currentTimeMillis()));
Object key1 = indexer.getKey(data);
when(data.getTimeStamp()).thenReturn(new Timestamp(System.currentTimeMillis() + (20 * 60 * 1000))); // 20
Object key2 = indexer.getKey(data);
assertThat(key1, is(not(key2)));
IIndexQuery query = mock(IndexQuery.class);
assertThat(indexer.getKeys(query), is(emptyArray()));
when(query.isIntervalSet()).thenReturn(true);
// not index period should also return empty array
when(query.getFromDate()).thenReturn(new Timestamp(System.currentTimeMillis() - (30 * 60 * 1000)));
when(query.getToDate()).thenReturn(new Timestamp(System.currentTimeMillis() - (20 * 60 * 1000)));
assertThat(indexer.getKeys(query), is(emptyArray()));
// when only one indexed time stamp is in interval return only one key
when(query.getFromDate()).thenReturn(new Timestamp(System.currentTimeMillis() - (20 * 60 * 1000)));
when(query.getToDate()).thenReturn(new Timestamp(System.currentTimeMillis() + (3 * 60 * 1000)));
assertThat(indexer.getKeys(query), is(arrayWithSize(1)));
// when both indexed time stamps are in interval return two keys
when(query.getFromDate()).thenReturn(new Timestamp(System.currentTimeMillis() - (10 * 60 * 1000)));
when(query.getToDate()).thenReturn(new Timestamp(System.currentTimeMillis() + (30 * 60 * 1000)));
assertThat(indexer.getKeys(query), is(arrayWithSize(2)));
}
}