when(methodInstrumentationConfig.getTargetClassFqn()).thenReturn(className); when(methodInstrumentationConfig.getTargetMethodName()).thenReturn("<init>"); when(methodInstrumentationConfig.getReturnType()).thenReturn("void"); when(methodInstrumentationConfig.getParameterTypes()).thenReturn(Collections.<String> emptyList()); when(methodInstrumentationConfig.getSensorInstrumentationPoint()).thenReturn(sensorInstrumentationPoint); when(methodInstrumentationConfig.getAllInstrumentationPoints()).thenReturn(Collections.<IMethodInstrumentationPoint> singleton(sensorInstrumentationPoint)); when(instrumenterFactory.getMethodVisitor(eq(sensorInstrumentationPoint), Matchers.<MethodVisitor> any(), anyInt(), anyString(), anyString(), anyBoolean())).thenReturn(methodVisitor);
SpecialInstrumentationPoint specialInstrumentationPoint = config.getSpecialInstrumentationPoint(); if (null == specialInstrumentationPoint) { return null; ssc.setSensor(sensor); } else { String methodFull = config.getTargetClassFqn() + "#" + config.getTargetMethodName(); log.error("Sensor with the id " + sensorId + " does not exists on the agent, but it's defined for the method: " + methodFull);
@Test public void equalsContract() { MethodInstrumentationConfig c1 = new MethodInstrumentationConfig(); c1.setTargetClassFqn("c1"); MethodInstrumentationConfig c2 = new MethodInstrumentationConfig(); c2.setTargetClassFqn("c2"); EqualsVerifier.forClass(MethodType.class).usingGetClass().withPrefabValues(MethodInstrumentationConfig.class, c1, c2).suppress(Warning.NONFINAL_FIELDS).verify(); }
/** * Copies all the class/method information from the {@link MethodInstrumentationConfig} to the * {@link AbstractSensorConfig}. * * @param asc * {@link AbstractSensorConfig} * @param config * {@link MethodInstrumentationConfig} */ private void copyInfo(AbstractSensorConfig asc, MethodInstrumentationConfig config) { asc.setTargetClassFqn(config.getTargetClassFqn()); asc.setTargetMethodName(config.getTargetMethodName()); asc.setReturnType(config.getReturnType()); asc.setParameterTypes(config.getParameterTypes()); }
/** * Constructs the method instrumentation config based on the given {@link MethodType}. * * @param methodType * {@link MethodType} from which to copy the method properties. */ public MethodInstrumentationConfig(MethodType methodType) { if (null == methodType) { throw new IllegalArgumentException("Method instrumentation config can not be created when passed method type is null."); } this.setTargetClassFqn(methodType.getClassOrInterfaceType().getFQN()); this.setTargetMethodName(methodType.getName()); this.setReturnType(methodType.getReturnType()); this.setParameterTypes(new ArrayList<String>(methodType.getParameters())); }
/** * Checks if the {@link SensorInstrumentationPoint} exists in the * {@link MethodInstrumentationConfig}. If not new one is created, registered with registration * service and saved in the {@link MethodInstrumentationConfig}. * * @param agentConfiguration * {@link AgentConfig} to read platform id. * @param methodType * {@link MethodType} in question. * @param methodInstrumentationConfig * {@link MethodInstrumentationConfig}. * @return {@link SensorInstrumentationPoint} for the {@link MethodInstrumentationConfig}. */ protected SpecialInstrumentationPoint getOrCreateSpecialInstrumentationPoint(AgentConfig agentConfiguration, MethodType methodType, MethodInstrumentationConfig methodInstrumentationConfig) { // check for existing SpecialInstrumentationPoint specialInstrumentationPoint = methodInstrumentationConfig.getSpecialInstrumentationPoint(); // if not create new one if (null == specialInstrumentationPoint) { // if not create new and register long id = registerMethod(agentConfiguration, methodType, methodInstrumentationConfig); specialInstrumentationPoint = new SpecialInstrumentationPoint(); specialInstrumentationPoint.setId(id); // set to method instrumentation methodInstrumentationConfig.setSpecialInstrumentationPoint(specialInstrumentationPoint); } return specialInstrumentationPoint; }
@Test public void constructorUnexpectedExceptionTrowingNoEnhanced() throws Exception { Object[] parameters = { 3 }; long methodId = 9L; when(sip.getId()).thenReturn(methodId); prepareConfigurationMockConstructor(config, InstrumentationTestClass.class, false, int.class); doAnswer(CONSTRUCTOR_INSTRUMENTER_ANSWER).when(instrumenterFactory).getMethodVisitor(eq(sip), Matchers.<MethodVisitor> any(), anyInt(), anyString(), anyString(), anyBoolean()); when(config.getAllInstrumentationPoints()).thenReturn(Collections.<IMethodInstrumentationPoint> singleton(sip)); ClassReader cr = new ClassReader(TEST_CLASS_FQN); prepareWriter(cr, null, false, config); cr.accept(classInstrumenter, ClassReader.SKIP_FRAMES | ClassReader.SKIP_DEBUG); assertThat(classInstrumenter.isByteCodeAdded(), is(true)); byte b[] = classWriter.toByteArray(); Class<?> clazz = createClass(TEST_CLASS_FQN, b); Constructor<?> constructor = clazz.getConstructor(new Class[] { int.class }); try { constructor.newInstance(parameters); } catch (Throwable t) { } verify(hookDispatcher).dispatchConstructorBeforeBody(methodId, parameters); ArgumentCaptor<Object> captor = ArgumentCaptor.forClass(Object.class); verify(hookDispatcher).dispatchConstructorAfterBody(eq(methodId), captor.capture(), eq(parameters)); assertThat(captor.getValue().getClass().getName(), is(TEST_CLASS_FQN)); verifyNoMoreInteractions(hookDispatcher); }
when(methodInstrumentationConfig.getTargetMethodName()).thenReturn("<init>"); when(methodInstrumentationConfig.getReturnType()).thenReturn("void"); when(methodInstrumentationConfig.getAllInstrumentationPoints()).thenReturn(Collections.<IMethodInstrumentationPoint> singleton(specialInstrumentationPoint)); when(methodInstrumentationConfig.getSpecialInstrumentationPoint()).thenReturn(specialInstrumentationPoint); assertThat(sscCaptor.getValue().getId(), is(sscId)); assertThat(sscCaptor.getValue().getSensor(), is(methodSensor)); assertThat(sscCaptor.getValue().getTargetClassFqn(), is(methodInstrumentationConfig.getTargetClassFqn())); assertThat(sscCaptor.getValue().getTargetMethodName(), is(methodInstrumentationConfig.getTargetMethodName())); assertThat(sscCaptor.getValue().getReturnType(), is(methodInstrumentationConfig.getReturnType())); verifyNoMoreInteractions(hookDispatcherMapper, connection, classHashHelper);
when(methodInstrumentationConfig.getTargetMethodName()).thenReturn("someOtherNonExistingMethod"); when(methodInstrumentationConfig.getReturnType()).thenReturn("void"); when(methodInstrumentationConfig.getSensorInstrumentationPoint()).thenReturn(sensorInstrumentationPoint); when(methodInstrumentationConfig.getAllInstrumentationPoints()).thenReturn(Collections.<IMethodInstrumentationPoint> singleton(sensorInstrumentationPoint)); when(instrumenterFactory.getMethodVisitor(eq(sensorInstrumentationPoint), Matchers.<MethodVisitor> any(), anyInt(), anyString(), anyString(), anyBoolean())).thenReturn(methodVisitor);
SensorInstrumentationPoint sensorInstrumentationPoint = config.getSensorInstrumentationPoint(); if (null == sensorInstrumentationPoint) { return null; rsc.addMethodSensor(sensor); } else { String methodFull = config.getTargetClassFqn() + "#" + config.getTargetMethodName(); log.error("Sensor with the id " + sensorId + " does not exists on the agent, but it's defined for the method: " + methodFull);
if (!name.equals(instrumentationConfig.getTargetMethodName())) { return false; if (!methodType.getReturnType().getClassName().equals(instrumentationConfig.getReturnType())) { return false; List<String> parameterTypes = instrumentationConfig.getParameterTypes();
RegisteredSensorConfig registeredSensorConfig = createRegisteredSensorConfig(config); if (null != registeredSensorConfig) { SensorInstrumentationPoint sensorInstrumentationPoint = config.getSensorInstrumentationPoint(); hookDispatcherMapper.addMapping(registeredSensorConfig.getId(), registeredSensorConfig); methodToSensorMap.put(Long.valueOf(registeredSensorConfig.getId()), sensorInstrumentationPoint.getSensorIds()); SpecialInstrumentationPoint specialInstrumentationPoint = config.getSpecialInstrumentationPoint(); hookDispatcherMapper.addMapping(specialSensorConfig.getId(), specialSensorConfig); methodToSensorMap.put(Long.valueOf(specialSensorConfig.getId()), new long[] { specialInstrumentationPoint.getSensorId() });
/** * Checks if the {@link SensorInstrumentationPoint} exists in the * {@link MethodInstrumentationConfig}. If not new one is created, registered with registration * service and saved in the {@link MethodInstrumentationConfig}. * * @param agentConfiguration * {@link AgentConfig} to read platform id. * @param methodType * {@link MethodType} in question. * @param methodInstrumentationConfig * {@link MethodInstrumentationConfig}. * @return {@link SensorInstrumentationPoint} for the {@link MethodInstrumentationConfig}. */ protected SensorInstrumentationPoint getOrCreateSensorInstrumentationPoint(AgentConfig agentConfiguration, MethodType methodType, MethodInstrumentationConfig methodInstrumentationConfig) { // check for existing SensorInstrumentationPoint sensorInstrumentationPoint = methodInstrumentationConfig.getSensorInstrumentationPoint(); // if not create new one if (null == sensorInstrumentationPoint) { // if not create new and register long id = registerMethod(agentConfiguration, methodType, methodInstrumentationConfig); sensorInstrumentationPoint = new SensorInstrumentationPoint(); sensorInstrumentationPoint.setId(id); if (Character.CONSTRUCTOR.equals(methodType.getMethodCharacter())) { sensorInstrumentationPoint.setConstructor(true); } // set to method instrumentation methodInstrumentationConfig.setSensorInstrumentationPoint(sensorInstrumentationPoint); } return sensorInstrumentationPoint; }
SensorInstrumentationPoint rsc = instrumentationConfig.getSensorInstrumentationPoint();
/** * Registers method to the registration service. * * @param agentConfiguration * {@link AgentConfig} to read platform id. * @param methodType * {@link MethodType} in question. * @param methodInstrumentationConfig * {@link MethodInstrumentationConfig}. * @return Id of the method. */ private long registerMethod(AgentConfig agentConfiguration, MethodType methodType, MethodInstrumentationConfig methodInstrumentationConfig) { // extract package and class name String fqn = methodInstrumentationConfig.getTargetClassFqn(); int index = fqn.lastIndexOf('.'); String packageName = index >= 0 ? fqn.substring(0, index) : ""; String className = fqn.substring(index + 1); return registrationService.registerMethodIdent(agentConfiguration.getPlatformId(), packageName, className, methodType.getName(), methodType.getParameters(), methodType.getReturnType(), methodType.getModifiers()); }
/** * Creates method instrumentation configuration for the given {@link MethodType} or returns * existing one. * * @param methodType * {@link MethodType} to get {@link MethodInstrumentationConfig} for. * @return Existing or new {@link MethodInstrumentationConfig}. */ private MethodInstrumentationConfig getOrCreateMethodInstrumentationConfig(MethodType methodType) { // check for existing MethodInstrumentationConfig methodInstrumentationConfig = methodType.getMethodInstrumentationConfig(); // if not create new one if (null == methodInstrumentationConfig) { methodInstrumentationConfig = new MethodInstrumentationConfig(methodType); methodType.setMethodInstrumentationConfig(methodInstrumentationConfig); } return methodInstrumentationConfig; }
@Test public void noInstrumenatation() throws Exception { String methodName = "stringNullParameter"; long methodId = 3L; when(sip.getId()).thenReturn(methodId); when(config.getTargetMethodName()).thenReturn("nonExistingMethod"); ClassReader cr = new ClassReader(TEST_CLASS_FQN); prepareWriter(cr, null, false, config); cr.accept(classInstrumenter, ClassReader.SKIP_FRAMES | ClassReader.SKIP_DEBUG); assertThat(classInstrumenter.isByteCodeAdded(), is(false)); byte b[] = classWriter.toByteArray(); // now call this method Object testClass = this.createInstance(TEST_CLASS_FQN, b); // call this method via reflection as we would get a class cast // exception by casting to the concrete class. this.callMethod(testClass, methodName, null); verifyZeroInteractions(hookDispatcher); }
@Test public void staticConstructor() throws Exception { long methodId = 9L; when(sip.getId()).thenReturn(methodId); prepareConfigurationMockConstructor(config, InstrumentationTestClass.class, true); doAnswer(CONSTRUCTOR_INSTRUMENTER_ANSWER).when(instrumenterFactory).getMethodVisitor(eq(sip), Matchers.<MethodVisitor> any(), anyInt(), anyString(), anyString(), anyBoolean()); when(config.getAllInstrumentationPoints()).thenReturn(Collections.<IMethodInstrumentationPoint> singleton(sip)); ClassReader cr = new ClassReader(TEST_CLASS_FQN); prepareWriter(cr, null, false, config); cr.accept(classInstrumenter, ClassReader.SKIP_FRAMES | ClassReader.SKIP_DEBUG); assertThat(classInstrumenter.isByteCodeAdded(), is(true)); byte b[] = classWriter.toByteArray(); // create instance this.createInstance(TEST_CLASS_FQN, b); verify(hookDispatcher).dispatchConstructorBeforeBody(methodId, new Object[0]); verify(hookDispatcher).dispatchConstructorAfterBody(methodId, null, new Object[0]); verifyNoMoreInteractions(hookDispatcher); }
protected void prepareConfigurationMockConstructor(MethodInstrumentationConfig point, Class<?> clazz, boolean staticConstructor, Class<?>... parameterTypes) throws SecurityException, NoSuchMethodException { clazz.getDeclaredConstructor(parameterTypes); when(point.getTargetClassFqn()).thenReturn(clazz.getName()); when(point.getTargetMethodName()).thenReturn(staticConstructor ? "<clinit>" : "<init>"); when(point.getReturnType()).thenReturn("void"); if (ArrayUtils.isNotEmpty(parameterTypes)) { List<String> params = new ArrayList<String>(); for (Class<?> paramType : parameterTypes) { if (paramType.isArray()) { params.add(paramType.getComponentType().getName() + "[]"); } else { params.add(paramType.getName()); } } when(point.getParameterTypes()).thenReturn(params); } }
@Test public void instrumentationExist() throws Exception { long agentId = 13L; long sensorId = 15L; String sensorClassName = "sensorClassName"; MethodSensorTypeConfig methodSensorTypeConfig = mock(MethodSensorTypeConfig.class); when(methodSensorTypeConfig.getId()).thenReturn(sensorId); when(methodSensorTypeConfig.getPriority()).thenReturn(PriorityEnum.NORMAL); AgentConfig agentConfiguration = mock(AgentConfig.class); when(agentConfiguration.getPlatformId()).thenReturn(agentId); when(agentConfiguration.getMethodSensorTypeConfig(sensorClassName)).thenReturn(methodSensorTypeConfig); Map<String, Object> settings = Collections.<String, Object> singletonMap("key", "value"); when(assignment.getSettings()).thenReturn(settings); IMethodSensorConfig methodSensorConfig = mock(IMethodSensorConfig.class); when(methodSensorConfig.getClassName()).thenReturn(sensorClassName); when(environment.getMethodSensorTypeConfig(Matchers.<Class<? extends IMethodSensorConfig>> any())).thenReturn(methodSensorConfig); SensorInstrumentationPoint rsc = mock(SensorInstrumentationPoint.class); when(rsc.getSensorIds()).thenReturn(new long[] { sensorId }); MethodInstrumentationConfig instrumentationConfig = mock(MethodInstrumentationConfig.class); when(instrumentationConfig.getSensorInstrumentationPoint()).thenReturn(rsc); when(methodType.getMethodInstrumentationConfig()).thenReturn(instrumentationConfig); boolean changed = applier.addInstrumentationPoints(agentConfiguration, classType); // verify results assertThat(changed, is(true)); // verify no interaction verifyZeroInteractions(registrationService); verify(instrumentationConfig, times(0)).setSensorInstrumentationPoint(Matchers.<SensorInstrumentationPoint> any()); verify(methodType, times(0)).setMethodInstrumentationConfig(Matchers.<MethodInstrumentationConfig> any()); }