package rocks.inspectit.agent.java.sensor.method.averagetimer; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.is; import static org.mockito.Matchers.argThat; import static org.mockito.Matchers.eq; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verifyNoMoreInteractions; import static org.mockito.Mockito.verifyZeroInteractions; import static org.mockito.Mockito.when; import java.util.Map; import org.mockito.ArgumentMatcher; import org.mockito.Mock; import org.testng.annotations.BeforeMethod; import org.testng.annotations.Test; import rocks.inspectit.agent.java.AbstractLogSupport; import rocks.inspectit.agent.java.config.IPropertyAccessor; import rocks.inspectit.agent.java.config.impl.RegisteredSensorConfig; import rocks.inspectit.agent.java.core.ICoreService; import rocks.inspectit.agent.java.core.IPlatformManager; import rocks.inspectit.agent.java.util.Timer; import rocks.inspectit.shared.all.communication.data.TimerData; import rocks.inspectit.shared.all.util.ObjectUtils; @SuppressWarnings("PMD") public class AverageTimerHookTest extends AbstractLogSupport { @Mock private Timer timer; @Mock private IPlatformManager platformManager; @Mock private IPropertyAccessor propertyAccessor; @Mock private ICoreService coreService; @Mock private RegisteredSensorConfig registeredSensorConfig; @Mock private Map<String, Object> parameter; private AverageTimerHook averageTimerHook; @BeforeMethod public void initTestClass() { averageTimerHook = new AverageTimerHook(timer, platformManager, propertyAccessor, parameter); } @Test public void oneRecord() { // set up data long platformId = 1L; long methodId = 3L; long sensorTypeId = 11L; Object object = mock(Object.class); Object[] parameters = new Object[0]; Object result = mock(Object.class); Double firstTimerValue = 1000.453d; Double secondTimerValue = 1323.675d; when(timer.getCurrentTime()).thenReturn(firstTimerValue).thenReturn(secondTimerValue); when(platformManager.getPlatformId()).thenReturn(platformId); averageTimerHook.beforeBody(methodId, sensorTypeId, object, parameters, registeredSensorConfig); verify(timer, times(1)).getCurrentTime(); averageTimerHook.firstAfterBody(methodId, sensorTypeId, object, parameters, result, registeredSensorConfig); verify(timer, times(2)).getCurrentTime(); averageTimerHook.secondAfterBody(coreService, methodId, sensorTypeId, object, parameters, result, registeredSensorConfig); verify(platformManager).getPlatformId(); verify(coreService).getMethodSensorData(sensorTypeId, methodId, null); verify(registeredSensorConfig).isPropertyAccess(); TimerData timerData = new TimerData(); timerData.setPlatformIdent(platformId); timerData.setMethodIdent(methodId); timerData.setSensorTypeIdent(sensorTypeId); timerData.setCount(1L); timerData.setDuration(secondTimerValue - firstTimerValue); timerData.calculateMax(secondTimerValue - firstTimerValue); timerData.calculateMin(secondTimerValue - firstTimerValue); verify(coreService).addMethodSensorData(eq(sensorTypeId), eq(methodId), (String) eq(null), argThat(new TimerDataVerifier(timerData))); verifyNoMoreInteractions(timer, platformManager, coreService, registeredSensorConfig); verifyZeroInteractions(propertyAccessor, object, result); } @Test public void twoRecords() { long platformId = 1L; long methodIdOne = 3L; long methodIdTwo = 9L; long sensorTypeId = 11L; Object object = mock(Object.class); Object[] parameters = new Object[0]; Object result = mock(Object.class); Double firstTimerValue = 1000.453d; Double secondTimerValue = 1323.675d; Double thirdTimerValue = 1578.92d; Double fourthTimerValue = 2319.712d; when(timer.getCurrentTime()).thenReturn(firstTimerValue).thenReturn(secondTimerValue).thenReturn(thirdTimerValue).thenReturn(fourthTimerValue); when(platformManager.getPlatformId()).thenReturn(platformId); averageTimerHook.beforeBody(methodIdOne, sensorTypeId, object, parameters, registeredSensorConfig); averageTimerHook.beforeBody(methodIdTwo, sensorTypeId, object, parameters, registeredSensorConfig); averageTimerHook.firstAfterBody(methodIdTwo, sensorTypeId, object, parameters, result, registeredSensorConfig); averageTimerHook.secondAfterBody(coreService, methodIdTwo, sensorTypeId, object, parameters, result, registeredSensorConfig); TimerData timerDataTwo = new TimerData(); timerDataTwo.setPlatformIdent(platformId); timerDataTwo.setMethodIdent(methodIdTwo); timerDataTwo.setSensorTypeIdent(sensorTypeId); timerDataTwo.setCount(1L); timerDataTwo.setDuration(thirdTimerValue - secondTimerValue); timerDataTwo.calculateMax(thirdTimerValue - secondTimerValue); timerDataTwo.calculateMin(thirdTimerValue - secondTimerValue); verify(coreService).addMethodSensorData(eq(sensorTypeId), eq(methodIdTwo), (String) eq(null), argThat(new TimerDataVerifier(timerDataTwo))); averageTimerHook.firstAfterBody(methodIdOne, sensorTypeId, object, parameters, result, registeredSensorConfig); averageTimerHook.secondAfterBody(coreService, methodIdOne, sensorTypeId, object, parameters, result, registeredSensorConfig); TimerData timerDataOne = new TimerData(); timerDataOne.setPlatformIdent(platformId); timerDataOne.setMethodIdent(methodIdOne); timerDataOne.setSensorTypeIdent(sensorTypeId); timerDataOne.setCount(1L); timerDataOne.setDuration(fourthTimerValue - firstTimerValue); timerDataOne.calculateMax(fourthTimerValue - firstTimerValue); timerDataOne.calculateMin(fourthTimerValue - firstTimerValue); verify(coreService).addMethodSensorData(eq(sensorTypeId), eq(methodIdOne), (String) eq(null), argThat(new TimerDataVerifier(timerDataOne))); } @Test public void sameMethodTwice() { // set up data long platformId = 1L; long methodId = 3L; long sensorTypeId = 11L; Object object = mock(Object.class); Object[] parameters = new Object[0]; Object result = mock(Object.class); Double firstTimerValue = 1000.0d; Double secondTimerValue = 1323.0d; Double thirdTimerValue = 1894.0d; Double fourthTimerValue = 2812.0d; when(timer.getCurrentTime()).thenReturn(firstTimerValue).thenReturn(secondTimerValue).thenReturn(thirdTimerValue).thenReturn(fourthTimerValue); when(platformManager.getPlatformId()).thenReturn(platformId); // First call averageTimerHook.beforeBody(methodId, sensorTypeId, object, parameters, registeredSensorConfig); verify(timer, times(1)).getCurrentTime(); averageTimerHook.firstAfterBody(methodId, sensorTypeId, object, parameters, result, registeredSensorConfig); verify(timer, times(2)).getCurrentTime(); averageTimerHook.secondAfterBody(coreService, methodId, sensorTypeId, object, parameters, result, registeredSensorConfig); verify(platformManager).getPlatformId(); verify(coreService).getMethodSensorData(sensorTypeId, methodId, null); verify(registeredSensorConfig).isPropertyAccess(); TimerData timerData = new TimerData(); timerData.setPlatformIdent(platformId); timerData.setMethodIdent(methodId); timerData.setSensorTypeIdent(sensorTypeId); timerData.setCount(1L); timerData.setDuration(secondTimerValue - firstTimerValue); timerData.calculateMax(secondTimerValue - firstTimerValue); timerData.calculateMin(secondTimerValue - firstTimerValue); verify(coreService).addMethodSensorData(eq(sensorTypeId), eq(methodId), (String) eq(null), argThat(new TimerDataVerifier(timerData))); // second one averageTimerHook.beforeBody(methodId, sensorTypeId, object, parameters, registeredSensorConfig); verify(timer, times(3)).getCurrentTime(); averageTimerHook.firstAfterBody(methodId, sensorTypeId, object, parameters, result, registeredSensorConfig); verify(timer, times(4)).getCurrentTime(); when(coreService.getMethodSensorData(sensorTypeId, methodId, null)).thenReturn(timerData); averageTimerHook.secondAfterBody(coreService, methodId, sensorTypeId, object, parameters, result, registeredSensorConfig); verify(coreService, times(2)).getMethodSensorData(sensorTypeId, methodId, null); verify(registeredSensorConfig, times(2)).isPropertyAccess(); assertThat(timerData.getPlatformIdent(), is(equalTo(platformId))); assertThat(timerData.getMethodIdent(), is(equalTo(methodId))); assertThat(timerData.getSensorTypeIdent(), is(equalTo(sensorTypeId))); assertThat(timerData.getCount(), is(equalTo(2L))); assertThat(timerData.getDuration(), is(equalTo(((fourthTimerValue - thirdTimerValue) + secondTimerValue) - firstTimerValue))); assertThat(timerData.getMax(), is(equalTo(fourthTimerValue - thirdTimerValue))); assertThat(timerData.getMin(), is(equalTo(secondTimerValue - firstTimerValue))); verifyNoMoreInteractions(timer, platformManager, coreService, registeredSensorConfig); verifyZeroInteractions(propertyAccessor, object, result); } @Test public void newMinValue() { // set up data long platformId = 1L; long methodId = 3L; long sensorTypeId = 11L; Object object = mock(Object.class); Object[] parameters = new Object[0]; Object result = mock(Object.class); Double firstTimerValue = 1000.0d; Double secondTimerValue = 1323.0d; Double thirdTimerValue = 1894.0d; Double fourthTimerValue = 1934.0d; when(timer.getCurrentTime()).thenReturn(firstTimerValue).thenReturn(secondTimerValue).thenReturn(thirdTimerValue).thenReturn(fourthTimerValue); when(platformManager.getPlatformId()).thenReturn(platformId); // First call averageTimerHook.beforeBody(methodId, sensorTypeId, object, parameters, registeredSensorConfig); verify(timer, times(1)).getCurrentTime(); averageTimerHook.firstAfterBody(methodId, sensorTypeId, object, parameters, result, registeredSensorConfig); verify(timer, times(2)).getCurrentTime(); averageTimerHook.secondAfterBody(coreService, methodId, sensorTypeId, object, parameters, result, registeredSensorConfig); verify(platformManager).getPlatformId(); verify(coreService).getMethodSensorData(sensorTypeId, methodId, null); verify(registeredSensorConfig).isPropertyAccess(); TimerData timerData = new TimerData(); timerData.setPlatformIdent(platformId); timerData.setMethodIdent(methodId); timerData.setSensorTypeIdent(sensorTypeId); timerData.setCount(1L); timerData.setDuration(secondTimerValue - firstTimerValue); timerData.calculateMax(secondTimerValue - firstTimerValue); timerData.calculateMin(secondTimerValue - firstTimerValue); verify(coreService).addMethodSensorData(eq(sensorTypeId), eq(methodId), (String) eq(null), argThat(new TimerDataVerifier(timerData))); // second one averageTimerHook.beforeBody(methodId, sensorTypeId, object, parameters, registeredSensorConfig); verify(timer, times(3)).getCurrentTime(); averageTimerHook.firstAfterBody(methodId, sensorTypeId, object, parameters, result, registeredSensorConfig); verify(timer, times(4)).getCurrentTime(); when(coreService.getMethodSensorData(sensorTypeId, methodId, null)).thenReturn(timerData); averageTimerHook.secondAfterBody(coreService, methodId, sensorTypeId, object, parameters, result, registeredSensorConfig); verify(coreService, times(2)).getMethodSensorData(sensorTypeId, methodId, null); verify(registeredSensorConfig, times(2)).isPropertyAccess(); assertThat(timerData.getPlatformIdent(), is(equalTo(platformId))); assertThat(timerData.getMethodIdent(), is(equalTo(methodId))); assertThat(timerData.getSensorTypeIdent(), is(equalTo(sensorTypeId))); assertThat(timerData.getCount(), is(equalTo(2L))); assertThat(timerData.getDuration(), is(equalTo(((fourthTimerValue - thirdTimerValue) + secondTimerValue) - firstTimerValue))); assertThat(timerData.getMax(), is(equalTo(secondTimerValue - firstTimerValue))); assertThat(timerData.getMin(), is(equalTo(fourthTimerValue - thirdTimerValue))); verifyNoMoreInteractions(timer, platformManager, coreService, registeredSensorConfig); verifyZeroInteractions(propertyAccessor, object, result); } /** * Inner class used to verify the contents of TimerData objects. */ private static class TimerDataVerifier extends ArgumentMatcher<TimerData> { private final TimerData timerData; public TimerDataVerifier(TimerData timerData) { this.timerData = timerData; } @Override public boolean matches(Object object) { if (!TimerData.class.isInstance(object)) { return false; } TimerData otherTimerData = (TimerData) object; if (timerData.getPlatformIdent() != otherTimerData.getPlatformIdent()) { return false; } else if (timerData.getMethodIdent() != otherTimerData.getMethodIdent()) { return false; } else if (timerData.getSensorTypeIdent() != otherTimerData.getSensorTypeIdent()) { return false; } else if (timerData.getCount() != otherTimerData.getCount()) { return false; } else if (timerData.getDuration() != otherTimerData.getDuration()) { return false; } else if (timerData.getMax() != otherTimerData.getMax()) { return false; } else if (timerData.getMin() != otherTimerData.getMin()) { return false; } else if (timerData.getAverage() != otherTimerData.getAverage()) { return false; } else if (!ObjectUtils.equals(timerData.getParameterContentData(), otherTimerData.getParameterContentData())) { return false; } else if (timerData.getVariance() != otherTimerData.getVariance()) { return false; } return true; } } @Test public void propertyAccess() { // set up data long platformId = 1L; long methodId = 3L; long sensorTypeId = 11L; Object object = mock(Object.class); Object[] parameters = new Object[2]; Object result = mock(Object.class); Double firstTimerValue = 1000.453d; Double secondTimerValue = 1323.675d; when(timer.getCurrentTime()).thenReturn(firstTimerValue).thenReturn(secondTimerValue); when(platformManager.getPlatformId()).thenReturn(platformId); when(registeredSensorConfig.isPropertyAccess()).thenReturn(true); averageTimerHook.beforeBody(methodId, sensorTypeId, object, parameters, registeredSensorConfig); averageTimerHook.firstAfterBody(methodId, sensorTypeId, object, parameters, result, registeredSensorConfig); averageTimerHook.secondAfterBody(coreService, methodId, sensorTypeId, object, parameters, result, registeredSensorConfig); verify(registeredSensorConfig, times(1)).isPropertyAccess(); verify(propertyAccessor, times(1)).getParameterContentData(registeredSensorConfig.getPropertyAccessorList(), object, parameters, result); } }