package rocks.inspectit.shared.cs.indexing.impl; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.greaterThanOrEqualTo; import static org.hamcrest.Matchers.instanceOf; import static org.hamcrest.Matchers.is; import static org.hamcrest.Matchers.lessThanOrEqualTo; import static org.hamcrest.Matchers.nullValue; import static org.mockito.Matchers.anyList; import static org.mockito.Matchers.anyObject; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; import java.sql.Timestamp; import java.util.ArrayList; import java.util.Date; import java.util.List; import java.util.concurrent.ForkJoinPool; import org.testng.annotations.BeforeClass; import org.testng.annotations.BeforeMethod; 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.SqlStatementData; import rocks.inspectit.shared.all.communication.data.TimerData; import rocks.inspectit.shared.cs.indexing.buffer.IBufferTreeComponent; import rocks.inspectit.shared.cs.indexing.buffer.impl.Branch; import rocks.inspectit.shared.cs.indexing.buffer.impl.BufferBranchIndexer; import rocks.inspectit.shared.cs.indexing.indexer.impl.MethodIdentIndexer; import rocks.inspectit.shared.cs.indexing.indexer.impl.ObjectTypeIndexer; import rocks.inspectit.shared.cs.indexing.indexer.impl.PlatformIdentIndexer; import rocks.inspectit.shared.cs.indexing.indexer.impl.SensorTypeIdentIndexer; import rocks.inspectit.shared.cs.indexing.indexer.impl.TimestampIndexer; import rocks.inspectit.shared.cs.indexing.restriction.IIndexQueryRestrictionProcessor; /** * Test class for testing functionality of {@link IBufferTreeComponent}. * * @author Ivan Senic * */ @SuppressWarnings("PMD") public class BufferIndexingTest { /** * Index query to use. */ private IndexQuery indexQuery; /** * The mocked processor. */ private IIndexQueryRestrictionProcessor processor; /** * The forkJoinPool which starts the forks */ private ForkJoinPool forkJoinPool = new ForkJoinPool(); /** * Initializes the mocks. */ @SuppressWarnings("unchecked") @BeforeClass public void init() { processor = mock(IIndexQueryRestrictionProcessor.class); when(processor.areAllRestrictionsFulfilled(anyObject(), anyList())).thenReturn(true); } /** * Initializes the index query. */ @BeforeMethod public void initMethod() { indexQuery = new IndexQuery(); indexQuery.restrictionProcessor = processor; } /** * Test tree with empty query. All elements should be returned. * * @throws IndexingException * If {@link IndexingException} occurs. */ @Test public void emptyQueryTest() throws IndexingException { IBufferTreeComponent<DefaultData> rootBranch = new Branch<>(new BufferBranchIndexer<>(new ObjectTypeIndexer<>())); DefaultData defaultData = mock(DefaultData.class); when(defaultData.getId()).thenReturn(1L); when(defaultData.isQueryComplied(indexQuery)).thenReturn(true); rootBranch.put(defaultData); SqlStatementData defaultData2 = mock(SqlStatementData.class); when(defaultData2.getId()).thenReturn(2L); when(defaultData2.isQueryComplied(indexQuery)).thenReturn(true); rootBranch.put(defaultData2); List<DefaultData> results = rootBranch.query(indexQuery); assertThat(results.size(), is(equalTo(2))); // Test for forkJoinPool List<DefaultData> resultsForkJoin = rootBranch.query(indexQuery, forkJoinPool); assertThat(resultsForkJoin.size(), is(equalTo(2))); } /** * Test put and retrieval of one element. * * @throws IndexingException * If {@link IndexingException} occurs. */ @Test public void putAndGetElement() throws IndexingException { IBufferTreeComponent<DefaultData> rootBranch = new Branch<>(new BufferBranchIndexer<>(new ObjectTypeIndexer<>())); DefaultData defaultData = mock(DefaultData.class); when(defaultData.getId()).thenReturn(1L); rootBranch.put(defaultData); assertThat(rootBranch.get(defaultData), is(equalTo(defaultData))); } /** * Test tree with query that holds only platform ident. * * @throws IndexingException * If {@link IndexingException} occurs. */ @Test public void queryBranchWithPlatformIdent() throws IndexingException { IBufferTreeComponent<DefaultData> rootBranch = new Branch<>(new BufferBranchIndexer<>(new PlatformIdentIndexer<>())); DefaultData defaultData1 = mock(DefaultData.class); when(defaultData1.getId()).thenReturn(1L); when(defaultData1.getPlatformIdent()).thenReturn(10L); when(defaultData1.isQueryComplied(indexQuery)).thenReturn(true); rootBranch.put(defaultData1); DefaultData defaultData2 = mock(DefaultData.class); when(defaultData2.getId()).thenReturn(2L); when(defaultData2.getPlatformIdent()).thenReturn(20L); when(defaultData2.isQueryComplied(indexQuery)).thenReturn(true); rootBranch.put(defaultData2); indexQuery.setPlatformIdent(10L); List<DefaultData> results = rootBranch.query(indexQuery); assertThat(results.size(), is(equalTo(1))); for (DefaultData result : results) { assertThat(result.getPlatformIdent(), is(equalTo(10L))); } // Test for forkJoinPool List<DefaultData> resultsForkJoin = rootBranch.query(indexQuery, forkJoinPool); assertThat(resultsForkJoin.size(), is(equalTo(1))); for (DefaultData result : resultsForkJoin) { assertThat(result.getPlatformIdent(), is(equalTo(10L))); } } /** * Test tree with query that holds only method ident. * * @throws IndexingException * If {@link IndexingException} occurs. */ @Test public void queryBranchWithMethodIdent() throws IndexingException { IBufferTreeComponent<MethodSensorData> rootBranch = new Branch<>(new BufferBranchIndexer<>(new MethodIdentIndexer<MethodSensorData>())); MethodSensorData defaultData1 = mock(MethodSensorData.class); when(defaultData1.getId()).thenReturn(1L); when(defaultData1.getMethodIdent()).thenReturn(10L); when(defaultData1.isQueryComplied(indexQuery)).thenReturn(true); rootBranch.put(defaultData1); MethodSensorData defaultData2 = mock(MethodSensorData.class); when(defaultData2.getId()).thenReturn(2L); when(defaultData2.getMethodIdent()).thenReturn(20L); when(defaultData2.isQueryComplied(indexQuery)).thenReturn(true); rootBranch.put(defaultData2); indexQuery.setMethodIdent(10L); List<MethodSensorData> results = rootBranch.query(indexQuery); assertThat(results.size(), is(equalTo(1))); for (MethodSensorData result : results) { assertThat(result.getMethodIdent(), is(equalTo(10L))); } // Test for forkJoinPool List<MethodSensorData> resultsForkJoin = rootBranch.query(indexQuery, forkJoinPool); assertThat(resultsForkJoin.size(), is(equalTo(1))); for (MethodSensorData result : resultsForkJoin) { assertThat(result.getMethodIdent(), is(equalTo(10L))); } } /** * Test tree with query that holds only object type. * * @throws IndexingException * If {@link IndexingException} occurs. */ @Test public void queryBranchWithObjectType() throws IndexingException { IBufferTreeComponent<DefaultData> rootBranch = new Branch<>(new BufferBranchIndexer<>(new ObjectTypeIndexer<>())); TimerData defaultData1 = mock(TimerData.class); when(defaultData1.getId()).thenReturn(1L); when(defaultData1.isQueryComplied(indexQuery)).thenReturn(true); rootBranch.put(defaultData1); SqlStatementData defaultData2 = mock(SqlStatementData.class); when(defaultData2.getId()).thenReturn(2L); when(defaultData2.isQueryComplied(indexQuery)).thenReturn(true); rootBranch.put(defaultData2); List<Class<?>> searchedClasses = new ArrayList<>(); searchedClasses.add(defaultData1.getClass()); indexQuery.setObjectClasses(searchedClasses); List<DefaultData> results = rootBranch.query(indexQuery); assertThat(results.size(), is(equalTo(1))); for (DefaultData result : results) { assertThat(result, is(instanceOf(defaultData1.getClass()))); } // Test for forkJoinPool List<DefaultData> resultsForkJoin = rootBranch.query(indexQuery, forkJoinPool); assertThat(resultsForkJoin.size(), is(equalTo(1))); for (DefaultData result : resultsForkJoin) { assertThat(result, is(instanceOf(defaultData1.getClass()))); } } /** * Test tree with query that holds only time interval. * * @throws IndexingException * If {@link IndexingException} occurs. */ @Test public void queryBranchWithTimestampInterval() throws IndexingException { Timestamp minusHour = new Timestamp(new Date().getTime() + (20 * 60 * 1000)); Timestamp plusHour = new Timestamp(new Date().getTime() + (25 * 60 * 1000)); IBufferTreeComponent<DefaultData> rootBranch = new Branch<>(new BufferBranchIndexer<>(new TimestampIndexer<>())); DefaultData defaultData1 = mock(DefaultData.class); when(defaultData1.getId()).thenReturn(1L); when(defaultData1.getTimeStamp()).thenReturn(new Timestamp(new Date().getTime())); when(defaultData1.isQueryComplied(indexQuery)).thenReturn(true); rootBranch.put(defaultData1); DefaultData defaultData2 = mock(DefaultData.class); when(defaultData2.getId()).thenReturn(2L); when(defaultData2.getTimeStamp()).thenReturn(plusHour); when(defaultData2.isQueryComplied(indexQuery)).thenReturn(true); rootBranch.put(defaultData2); indexQuery.setFromDate(minusHour); indexQuery.setToDate(plusHour); List<DefaultData> results = rootBranch.query(indexQuery); assertThat(results.size(), is(equalTo(1))); for (DefaultData result : results) { assertThat(result.getTimeStamp().getTime(), is(greaterThanOrEqualTo(minusHour.getTime()))); assertThat(result.getTimeStamp().getTime(), is(lessThanOrEqualTo(plusHour.getTime()))); } // Test for forkJoinPool List<DefaultData> resultsForkJoin = rootBranch.query(indexQuery, forkJoinPool); assertThat(resultsForkJoin.size(), is(equalTo(1))); for (DefaultData result : resultsForkJoin) { assertThat(result.getTimeStamp().getTime(), is(greaterThanOrEqualTo(minusHour.getTime()))); assertThat(result.getTimeStamp().getTime(), is(lessThanOrEqualTo(plusHour.getTime()))); } } /** * Test tree with query that holds platform ident and sensor ident in different levels. * * @throws IndexingException * If {@link IndexingException} occurs. */ @Test public void queryDifferentLevels() throws IndexingException { BufferBranchIndexer<DefaultData> sensorTypeIndexer = new BufferBranchIndexer<>(new SensorTypeIdentIndexer<>()); BufferBranchIndexer<DefaultData> objectTypeIndexer = new BufferBranchIndexer<>(new ObjectTypeIndexer<>(), sensorTypeIndexer); BufferBranchIndexer<DefaultData> platformTypeIndexer = new BufferBranchIndexer<>(new PlatformIdentIndexer<>(), objectTypeIndexer); IBufferTreeComponent<DefaultData> rootBranch = new Branch<>(platformTypeIndexer); TimerData defaultData1 = mock(TimerData.class); when(defaultData1.getId()).thenReturn(1L); when(defaultData1.getPlatformIdent()).thenReturn(10L); when(defaultData1.getSensorTypeIdent()).thenReturn(10L); when(defaultData1.isQueryComplied(indexQuery)).thenReturn(true); rootBranch.put(defaultData1); SqlStatementData defaultData2 = mock(SqlStatementData.class); when(defaultData2.getId()).thenReturn(2L); when(defaultData2.getPlatformIdent()).thenReturn(10L); when(defaultData2.getSensorTypeIdent()).thenReturn(20L); when(defaultData2.isQueryComplied(indexQuery)).thenReturn(true); rootBranch.put(defaultData2); indexQuery.setPlatformIdent(10L); List<DefaultData> results = rootBranch.query(indexQuery); assertThat(results.size(), is(equalTo(2))); for (DefaultData result : results) { assertThat(result.getPlatformIdent(), is(equalTo(10L))); } indexQuery.setPlatformIdent(10L); indexQuery.setSensorTypeIdent(10L); results = rootBranch.query(indexQuery); assertThat(results.size(), is(equalTo(1))); for (DefaultData result : results) { assertThat(result.getPlatformIdent(), is(equalTo(10L))); assertThat(result.getSensorTypeIdent(), is(equalTo(10L))); } } @Test /** * Same Test as queryDifferentLevels() except with ForkJoin * * @throws IndexingException */ public void queryDifferentLevelsForkJoin() throws IndexingException { BufferBranchIndexer<DefaultData> sensorTypeIndexer = new BufferBranchIndexer<>(new SensorTypeIdentIndexer<>()); BufferBranchIndexer<DefaultData> objectTypeIndexer = new BufferBranchIndexer<>(new ObjectTypeIndexer<>(), sensorTypeIndexer); BufferBranchIndexer<DefaultData> platformTypeIndexer = new BufferBranchIndexer<>(new PlatformIdentIndexer<>(), objectTypeIndexer); IBufferTreeComponent<DefaultData> rootBranch = new Branch<>(platformTypeIndexer); TimerData defaultData1 = mock(TimerData.class); when(defaultData1.getId()).thenReturn(1L); when(defaultData1.getPlatformIdent()).thenReturn(10L); when(defaultData1.getSensorTypeIdent()).thenReturn(10L); when(defaultData1.isQueryComplied(indexQuery)).thenReturn(true); rootBranch.put(defaultData1); SqlStatementData defaultData2 = mock(SqlStatementData.class); when(defaultData2.getId()).thenReturn(2L); when(defaultData2.getPlatformIdent()).thenReturn(10L); when(defaultData2.getSensorTypeIdent()).thenReturn(20L); when(defaultData2.isQueryComplied(indexQuery)).thenReturn(true); rootBranch.put(defaultData2); indexQuery.setPlatformIdent(10L); List<DefaultData> results = rootBranch.query(indexQuery, forkJoinPool); assertThat(results.size(), is(equalTo(2))); for (DefaultData result : results) { assertThat(result.getPlatformIdent(), is(equalTo(10L))); } indexQuery.setPlatformIdent(10L); indexQuery.setSensorTypeIdent(10L); results = rootBranch.query(indexQuery, forkJoinPool); assertThat(results.size(), is(equalTo(1))); for (DefaultData result : results) { assertThat(result.getPlatformIdent(), is(equalTo(10L))); assertThat(result.getSensorTypeIdent(), is(equalTo(10L))); } } /** * Test a removal of one element from the indexing tree. * * @throws IndexingException * If {@link IndexingException} occurs. */ @Test public void removeElement() throws IndexingException { IBufferTreeComponent<DefaultData> rootBranch = new Branch<>(new BufferBranchIndexer<>(new BufferBranchIndexer<>(new ObjectTypeIndexer<>()))); DefaultData defaultData = mock(DefaultData.class); when(defaultData.getId()).thenReturn(1L); rootBranch.put(defaultData); rootBranch.getAndRemove(defaultData); assertThat(rootBranch.get(defaultData), is(nullValue())); } /** * Clear all test. * * @throws IndexingException * If {@link IndexingException} occurs. */ @Test public void clearBranch() throws IndexingException { IBufferTreeComponent<DefaultData> rootBranch = new Branch<>(new BufferBranchIndexer<>(new ObjectTypeIndexer<>())); DefaultData defaultData = mock(DefaultData.class); when(defaultData.getId()).thenReturn(1L); rootBranch.put(defaultData); rootBranch.clearAll(); assertThat(rootBranch.getNumberOfElements(), is(equalTo(0L))); } /** * Confirm {@link IndexingException} will be reaised when key can not be generated for element. * * @throws IndexingException */ @Test(expectedExceptions = { IndexingException.class }) public void putWithNoKey() throws IndexingException { IBufferTreeComponent<DefaultData> rootBranch = new Branch<>(new BufferBranchIndexer<>(new TimestampIndexer<>())); DefaultData defaultData = mock(DefaultData.class); when(defaultData.getId()).thenReturn(1L); rootBranch.put(defaultData); } /** * Test that get will work even when branch can not generate key for the element if ID is * correctly set. * * @throws IndexingException */ @Test public void getWithNoKey() throws IndexingException { IBufferTreeComponent<DefaultData> rootBranch = new Branch<>(new BufferBranchIndexer<>(new TimestampIndexer<>())); DefaultData defaultData = mock(DefaultData.class); when(defaultData.getId()).thenReturn(1L); when(defaultData.getTimeStamp()).thenReturn(new Timestamp(new Date().getTime())); rootBranch.put(defaultData); when(defaultData.getTimeStamp()).thenReturn(null); // test get assertThat(rootBranch.get(defaultData), is(equalTo(defaultData))); // then get and remove assertThat(rootBranch.getAndRemove(defaultData), is(equalTo(defaultData))); // confirm it is removed assertThat(rootBranch.get(defaultData), is(nullValue())); } }