package rocks.inspectit.server.instrumentation.config.applier; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.hasItem; import static org.hamcrest.Matchers.is; import static org.mockito.Matchers.anyInt; import static org.mockito.Matchers.anyString; 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.when; import java.util.Arrays; import java.util.Collections; import java.util.List; import org.mockito.ArgumentCaptor; import org.mockito.Matchers; import org.mockito.Mock; import org.testng.annotations.BeforeMethod; import org.testng.annotations.Test; import rocks.inspectit.server.instrumentation.config.filter.AssignmentFilterProvider; import rocks.inspectit.server.instrumentation.config.filter.ClassSensorAssignmentFilter; import rocks.inspectit.server.instrumentation.config.filter.MethodSensorAssignmentFilter; import rocks.inspectit.shared.all.instrumentation.classcache.ClassType; import rocks.inspectit.shared.all.instrumentation.classcache.MethodType; import rocks.inspectit.shared.all.instrumentation.classcache.MethodType.Character; import rocks.inspectit.shared.all.instrumentation.config.PriorityEnum; import rocks.inspectit.shared.all.instrumentation.config.impl.AgentConfig; import rocks.inspectit.shared.all.instrumentation.config.impl.MethodInstrumentationConfig; import rocks.inspectit.shared.all.instrumentation.config.impl.MethodSensorTypeConfig; import rocks.inspectit.shared.all.instrumentation.config.impl.PropertyPathStart; import rocks.inspectit.shared.all.instrumentation.config.impl.SensorInstrumentationPoint; import rocks.inspectit.shared.all.testbase.TestBase; import rocks.inspectit.shared.cs.ci.Environment; import rocks.inspectit.shared.cs.ci.assignment.AbstractClassSensorAssignment; import rocks.inspectit.shared.cs.ci.assignment.impl.MethodSensorAssignment; import rocks.inspectit.shared.cs.ci.assignment.impl.TimerMethodSensorAssignment; import rocks.inspectit.shared.cs.ci.context.AbstractContextCapture; import rocks.inspectit.shared.cs.ci.sensor.method.IMethodSensorConfig; import rocks.inspectit.shared.cs.ci.sensor.method.impl.InvocationSequenceSensorConfig; import rocks.inspectit.shared.cs.cmr.service.IRegistrationService; /** * @author Ivan Senic * */ @SuppressWarnings("PMD") public class TimerMethodSensorInstrumentationApplierTest extends TestBase { protected TimerMethodSensorInstrumentationApplier applier; @Mock protected TimerMethodSensorAssignment assignment; @Mock protected AssignmentFilterProvider filterProvider; @Mock protected Environment environment; @Mock protected IRegistrationService registrationService; @Mock protected ClassType classType; @Mock protected MethodType methodType; @Mock protected MethodSensorAssignmentFilter methodFilter; @Mock protected ClassSensorAssignmentFilter classFilter; @BeforeMethod public void setup() { applier = new TimerMethodSensorInstrumentationApplier(assignment, environment, registrationService); applier.assignmentFilterProvider = filterProvider; // filters to true by default when(filterProvider.getClassSensorAssignmentFilter()).thenReturn(classFilter); when(filterProvider.getMethodSensorAssignmentFilter()).thenReturn(methodFilter); when(methodFilter.matches(Matchers.<MethodSensorAssignment> any(), Matchers.<MethodType> any())).thenReturn(true); when(classFilter.matches(Matchers.<AbstractClassSensorAssignment<?>> any(), Matchers.<ClassType> any(), Matchers.eq(false))).thenReturn(true); // class to return one method when(classType.getMethods()).thenReturn(Collections.singleton(methodType)); } public class AddInstrumentationPoints extends TimerMethodSensorInstrumentationApplierTest { @Test public void add() throws Exception { long agentId = 13L; long sensorId = 15L; long methodId = 17L; long invocationSensorId = 19L; String sensorClassName = "sensorClassName"; String invocClassName = "invocClassName"; when(registrationService.registerMethodIdent(eq(agentId), anyString(), anyString(), anyString(), Matchers.<List<String>> any(), anyString(), anyInt())).thenReturn(methodId); MethodSensorTypeConfig methodSensorTypeConfig = mock(MethodSensorTypeConfig.class); when(methodSensorTypeConfig.getId()).thenReturn(sensorId); when(methodSensorTypeConfig.getPriority()).thenReturn(PriorityEnum.NORMAL); MethodSensorTypeConfig invocSensorTypeConfig = mock(MethodSensorTypeConfig.class); when(invocSensorTypeConfig.getId()).thenReturn(invocationSensorId); when(invocSensorTypeConfig.getPriority()).thenReturn(PriorityEnum.INVOC); AgentConfig agentConfiguration = mock(AgentConfig.class); when(agentConfiguration.getPlatformId()).thenReturn(agentId); when(agentConfiguration.getMethodSensorTypeConfig(sensorClassName)).thenReturn(methodSensorTypeConfig); when(agentConfiguration.getMethodSensorTypeConfig(invocClassName)).thenReturn(invocSensorTypeConfig); when(assignment.isStartsInvocation()).thenReturn(true); AbstractContextCapture contextCapture = mock(AbstractContextCapture.class); PropertyPathStart propertyPathStart = mock(PropertyPathStart.class); when(contextCapture.getPropertyPathStart()).thenReturn(propertyPathStart); when(assignment.getContextCaptures()).thenReturn(Collections.singletonList(contextCapture)); IMethodSensorConfig methodSensorConfig = mock(IMethodSensorConfig.class); when(methodSensorConfig.getClassName()).thenReturn(sensorClassName); when(environment.getMethodSensorTypeConfig(Matchers.<Class<? extends IMethodSensorConfig>> any())).thenReturn(methodSensorConfig); IMethodSensorConfig invocSensorConfig = mock(IMethodSensorConfig.class); when(invocSensorConfig.getClassName()).thenReturn(invocClassName); when(environment.getMethodSensorTypeConfig(InvocationSequenceSensorConfig.class)).thenReturn(invocSensorConfig); String packageName = "my.favorite.package"; String className = "ClassName"; String methodName = "methodName"; String returnType = "returnType"; List<String> parameters = Arrays.asList(new String[] { "p1", "p2" }); int mod = 10; when(classType.getFQN()).thenReturn(packageName + '.' + className); when(methodType.getClassOrInterfaceType()).thenReturn(classType); when(methodType.getName()).thenReturn(methodName); when(methodType.getParameters()).thenReturn(parameters); when(methodType.getReturnType()).thenReturn(returnType); when(methodType.getMethodCharacter()).thenReturn(Character.METHOD); when(methodType.getModifiers()).thenReturn(mod); boolean changed = applier.addInstrumentationPoints(agentConfiguration, classType); // verify results assertThat(changed, is(true)); // verify registration service verify(registrationService, times(1)).registerMethodIdent(agentId, packageName, className, methodName, parameters, returnType, mod); verifyNoMoreInteractions(registrationService); // check RSC ArgumentCaptor<MethodInstrumentationConfig> captor = ArgumentCaptor.forClass(MethodInstrumentationConfig.class); verify(methodType, times(1)).setMethodInstrumentationConfig(captor.capture()); MethodInstrumentationConfig instrumentationConfig = captor.getValue(); SensorInstrumentationPoint rsc = instrumentationConfig.getSensorInstrumentationPoint(); // just check related to the timer sensor stuff assertThat(rsc.getId(), is(methodId)); assertThat(rsc.getSensorIds().length, is(2)); assertThat(rsc.getSensorIds()[0], is(sensorId)); assertThat(rsc.getSensorIds()[1], is(invocationSensorId)); assertThat(rsc.isStartsInvocation(), is(true)); assertThat(rsc.isPropertyAccess(), is(true)); assertThat(rsc.getPropertyAccessorList(), hasItem(propertyPathStart)); } } }