package rocks.inspectit.server.instrumentation.config;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.empty;
import static org.hamcrest.Matchers.hasItem;
import static org.hamcrest.Matchers.hasSize;
import static org.hamcrest.Matchers.is;
import static org.mockito.Matchers.anyBoolean;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.doReturn;
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.Collection;
import java.util.Collections;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
import rocks.inspectit.server.instrumentation.classcache.ClassCache;
import rocks.inspectit.server.instrumentation.classcache.ClassCacheLookup;
import rocks.inspectit.shared.all.instrumentation.classcache.AnnotationType;
import rocks.inspectit.shared.all.instrumentation.classcache.ClassType;
import rocks.inspectit.shared.all.instrumentation.classcache.ImmutableClassType;
import rocks.inspectit.shared.all.instrumentation.classcache.InterfaceType;
import rocks.inspectit.shared.all.instrumentation.classcache.MethodType;
import rocks.inspectit.shared.all.testbase.TestBase;
import rocks.inspectit.shared.cs.ci.assignment.impl.ExceptionSensorAssignment;
import rocks.inspectit.shared.cs.ci.assignment.impl.MethodSensorAssignment;
@SuppressWarnings({ "PMD", "unchecked" })
public class ClassCacheSearchNarrowerTest extends TestBase {
@InjectMocks
ClassCacheSearchNarrower narrower;
@Mock
MethodSensorAssignment methodSensorAssignment;
@Mock
ExceptionSensorAssignment exceptionSensorAssignment;
@Mock
ClassCache classCache;
@Mock
ClassCacheLookup lookup;
@BeforeMethod
public void setup() {
when(classCache.getLookupService()).thenReturn(lookup);
}
public class NarrowByClassSensorAssignment extends ClassCacheSearchNarrowerTest {
@Test
public void byDirectName() {
String className = "info.novatec.MyClass";
when(methodSensorAssignment.getClassName()).thenReturn(className);
when(methodSensorAssignment.isInterf()).thenReturn(false);
when(methodSensorAssignment.isSuperclass()).thenReturn(false);
ClassType classType = new ClassType(className, "hash", 0);
doReturn(Collections.singleton(classType)).when(lookup).findClassTypesByPattern(eq(className), anyBoolean());
Collection<? extends ImmutableClassType> result = narrower.narrowByClassSensorAssignment(classCache, methodSensorAssignment);
assertThat(result, hasSize(1));
assertThat(result.iterator().next(), is((ImmutableClassType) classType));
verify(lookup, times(1)).findClassTypesByPattern(className, true);
verifyNoMoreInteractions(lookup);
}
@Test
public void initializedByInterface() {
String interfaceName = "info.novatec.MyClass";
when(methodSensorAssignment.getClassName()).thenReturn(interfaceName);
when(methodSensorAssignment.isInterf()).thenReturn(true);
when(methodSensorAssignment.isSuperclass()).thenReturn(false);
InterfaceType interfaceType = new InterfaceType(interfaceName);
ClassType classType = new ClassType("initialized", "hash", 0);
classType.addInterface(interfaceType);
doReturn(Collections.singleton(interfaceType)).when(lookup).findInterfaceTypesByPattern(eq(interfaceName), anyBoolean());
Collection<? extends ImmutableClassType> result = narrower.narrowByClassSensorAssignment(classCache, methodSensorAssignment);
assertThat(result, hasSize(1));
assertThat(result.iterator().next(), is((ImmutableClassType) classType));
verify(lookup, times(1)).findInterfaceTypesByPattern(interfaceName, false);
verifyNoMoreInteractions(lookup);
}
@Test
public void nonInitializedByInterface() {
String interfaceName = "info.novatec.MyClass";
when(methodSensorAssignment.getClassName()).thenReturn(interfaceName);
when(methodSensorAssignment.isInterf()).thenReturn(true);
when(methodSensorAssignment.isSuperclass()).thenReturn(false);
InterfaceType interfaceType = new InterfaceType(interfaceName);
ClassType classType = new ClassType("not-initialized");
classType.addInterface(interfaceType);
doReturn(Collections.singleton(interfaceType)).when(lookup).findInterfaceTypesByPattern(eq(interfaceName), anyBoolean());
Collection<? extends ImmutableClassType> result = narrower.narrowByClassSensorAssignment(classCache, methodSensorAssignment);
assertThat(result, is(empty()));
verify(lookup, times(1)).findInterfaceTypesByPattern(interfaceName, false);
verifyNoMoreInteractions(lookup);
}
@Test
public void initializedByInterfaceIndirect() {
String interfaceName = "info.novatec.MyClass";
when(methodSensorAssignment.getClassName()).thenReturn(interfaceName);
when(methodSensorAssignment.isInterf()).thenReturn(true);
when(methodSensorAssignment.isSuperclass()).thenReturn(false);
InterfaceType interfaceType = new InterfaceType(interfaceName);
InterfaceType indirectInterfaceType = new InterfaceType("indirectInterfaceType");
indirectInterfaceType.addSuperInterface(interfaceType);
ClassType classType = new ClassType("initialized", "hash", 0);
classType.addInterface(indirectInterfaceType);
doReturn(Collections.singleton(interfaceType)).when(lookup).findInterfaceTypesByPattern(eq(interfaceName), anyBoolean());
Collection<? extends ImmutableClassType> result = narrower.narrowByClassSensorAssignment(classCache, methodSensorAssignment);
assertThat(result, hasSize(1));
assertThat(result.iterator().next(), is((ImmutableClassType) classType));
verify(lookup, times(1)).findInterfaceTypesByPattern(interfaceName, false);
verifyNoMoreInteractions(lookup);
}
@Test
public void nonInitializedByInterfaceIndirect() {
String interfaceName = "info.novatec.MyClass";
when(methodSensorAssignment.getClassName()).thenReturn(interfaceName);
when(methodSensorAssignment.isInterf()).thenReturn(true);
when(methodSensorAssignment.isSuperclass()).thenReturn(false);
InterfaceType interfaceType = new InterfaceType(interfaceName);
InterfaceType indirectInterfaceType = new InterfaceType("indirectInterfaceType");
indirectInterfaceType.addSuperInterface(interfaceType);
ClassType classType = new ClassType("non-initialized");
classType.addInterface(indirectInterfaceType);
doReturn(Collections.singleton(interfaceType)).when(lookup).findInterfaceTypesByPattern(eq(interfaceName), anyBoolean());
Collection<? extends ImmutableClassType> result = narrower.narrowByClassSensorAssignment(classCache, methodSensorAssignment);
assertThat(result, is(empty()));
verify(lookup, times(1)).findInterfaceTypesByPattern(interfaceName, false);
verifyNoMoreInteractions(lookup);
}
@Test
public void initializedBySuperClassInterface() {
String interfaceName = "info.novatec.MyClass";
when(methodSensorAssignment.getClassName()).thenReturn(interfaceName);
when(methodSensorAssignment.isInterf()).thenReturn(true);
when(methodSensorAssignment.isSuperclass()).thenReturn(false);
InterfaceType interfaceType = new InterfaceType(interfaceName);
ClassType superClassType = new ClassType("superclass", "superhash", 0);
ClassType classType = new ClassType("initialized", "hash", 0);
classType.addSuperClass(superClassType);
superClassType.addInterface(interfaceType);
doReturn(Collections.singleton(interfaceType)).when(lookup).findInterfaceTypesByPattern(eq(interfaceName), anyBoolean());
Collection<? extends ImmutableClassType> result = narrower.narrowByClassSensorAssignment(classCache, methodSensorAssignment);
assertThat(result, hasSize(2));
assertThat((Collection<ClassType>) result, hasItem(classType));
assertThat((Collection<ClassType>) result, hasItem(superClassType));
verify(lookup, times(1)).findInterfaceTypesByPattern(interfaceName, false);
verifyNoMoreInteractions(lookup);
}
@Test
public void initializedBySuperClassInterfaceIndirect() {
String interfaceName = "info.novatec.MyClass";
when(methodSensorAssignment.getClassName()).thenReturn(interfaceName);
when(methodSensorAssignment.isInterf()).thenReturn(true);
when(methodSensorAssignment.isSuperclass()).thenReturn(false);
InterfaceType interfaceType = new InterfaceType(interfaceName);
InterfaceType indirectInterfaceType = new InterfaceType("indirectInterfaceType");
indirectInterfaceType.addSuperInterface(interfaceType);
ClassType superClassType = new ClassType("superclass", "superhash", 0);
ClassType classType = new ClassType("initialized", "hash", 0);
classType.addSuperClass(superClassType);
superClassType.addInterface(interfaceType);
doReturn(Collections.singleton(interfaceType)).when(lookup).findInterfaceTypesByPattern(eq(interfaceName), anyBoolean());
Collection<? extends ImmutableClassType> result = narrower.narrowByClassSensorAssignment(classCache, methodSensorAssignment);
assertThat(result, hasSize(2));
assertThat((Collection<ClassType>) result, hasItem(classType));
assertThat((Collection<ClassType>) result, hasItem(superClassType));
verify(lookup, times(1)).findInterfaceTypesByPattern(interfaceName, false);
verifyNoMoreInteractions(lookup);
}
@Test
public void initializedBySuperClassInterfaceAndInterfaceIndirect() {
String interfaceName = "info.novatec.MyClass";
when(methodSensorAssignment.getClassName()).thenReturn(interfaceName);
when(methodSensorAssignment.isInterf()).thenReturn(true);
when(methodSensorAssignment.isSuperclass()).thenReturn(false);
InterfaceType interfaceType = new InterfaceType(interfaceName);
InterfaceType indirectInterfaceType = new InterfaceType("indirectInterfaceType");
indirectInterfaceType.addSuperInterface(interfaceType);
ClassType superClassType = new ClassType("superclass", "superhash", 0);
ClassType classType = new ClassType("initialized", "hash", 0);
classType.addSuperClass(superClassType);
classType.addInterface(indirectInterfaceType);
superClassType.addInterface(interfaceType);
doReturn(Collections.singleton(interfaceType)).when(lookup).findInterfaceTypesByPattern(eq(interfaceName), anyBoolean());
Collection<? extends ImmutableClassType> result = narrower.narrowByClassSensorAssignment(classCache, methodSensorAssignment);
assertThat(result, hasSize(2));
assertThat((Collection<ClassType>) result, hasItem(classType));
assertThat((Collection<ClassType>) result, hasItem(superClassType));
verify(lookup, times(1)).findInterfaceTypesByPattern(interfaceName, false);
verifyNoMoreInteractions(lookup);
}
@Test
public void initializedBySuperClass() {
String superClassName = "info.novatec.MyClass";
when(methodSensorAssignment.getClassName()).thenReturn(superClassName);
when(methodSensorAssignment.isInterf()).thenReturn(false);
when(methodSensorAssignment.isSuperclass()).thenReturn(true);
ClassType superClassType = new ClassType(superClassName);
ClassType classType = new ClassType("initialized", "hash", 0);
classType.addSuperClass(superClassType);
doReturn(Collections.singleton(superClassType)).when(lookup).findClassTypesByPattern(eq(superClassName), anyBoolean());
Collection<? extends ImmutableClassType> result = narrower.narrowByClassSensorAssignment(classCache, methodSensorAssignment);
assertThat(result, hasSize(1));
assertThat(result.iterator().next(), is((ImmutableClassType) classType));
verify(lookup, times(1)).findClassTypesByPattern(superClassName, false);
verifyNoMoreInteractions(lookup);
}
@Test
public void nonInitializedBySuperClass() {
String superClassName = "info.novatec.MyClass";
when(methodSensorAssignment.getClassName()).thenReturn(superClassName);
when(methodSensorAssignment.isInterf()).thenReturn(false);
when(methodSensorAssignment.isSuperclass()).thenReturn(true);
ClassType superClassType = new ClassType(superClassName);
ClassType classType = new ClassType("non-initialized");
classType.addSuperClass(superClassType);
doReturn(Collections.singleton(superClassType)).when(lookup).findClassTypesByPattern(eq(superClassName), anyBoolean());
Collection<? extends ImmutableClassType> result = narrower.narrowByClassSensorAssignment(classCache, methodSensorAssignment);
assertThat(result, is(empty()));
verify(lookup, times(1)).findClassTypesByPattern(superClassName, false);
verifyNoMoreInteractions(lookup);
}
@Test
public void initializedBySuperClassIndirect() {
String superClassName = "info.novatec.MyClass";
when(methodSensorAssignment.getClassName()).thenReturn(superClassName);
when(methodSensorAssignment.isInterf()).thenReturn(false);
when(methodSensorAssignment.isSuperclass()).thenReturn(true);
ClassType superClassType = new ClassType(superClassName);
ClassType indirectSuperClassType = new ClassType("indirectSuperClassType");
indirectSuperClassType.addSuperClass(superClassType);
ClassType classType = new ClassType("initialized", "hash", 0);
classType.addSuperClass(indirectSuperClassType);
doReturn(Collections.singleton(superClassType)).when(lookup).findClassTypesByPattern(eq(superClassName), anyBoolean());
Collection<? extends ImmutableClassType> result = narrower.narrowByClassSensorAssignment(classCache, methodSensorAssignment);
assertThat(result, hasSize(1));
assertThat(result.iterator().next(), is((ImmutableClassType) classType));
verify(lookup, times(1)).findClassTypesByPattern(superClassName, false);
verifyNoMoreInteractions(lookup);
}
@Test
public void initializedBySuperClassIndirectBoth() {
String superClassName = "info.novatec.MyClass";
when(methodSensorAssignment.getClassName()).thenReturn(superClassName);
when(methodSensorAssignment.isInterf()).thenReturn(false);
when(methodSensorAssignment.isSuperclass()).thenReturn(true);
ClassType superClassType = new ClassType(superClassName);
ClassType indirectSuperClassType = new ClassType("indirectSuperClassType", "hash", 0);
indirectSuperClassType.addSuperClass(superClassType);
ClassType classType = new ClassType("initialized", "hash", 0);
classType.addSuperClass(indirectSuperClassType);
doReturn(Collections.singleton(superClassType)).when(lookup).findClassTypesByPattern(eq(superClassName), anyBoolean());
Collection<? extends ImmutableClassType> result = narrower.narrowByClassSensorAssignment(classCache, methodSensorAssignment);
assertThat(result, hasSize(2));
assertThat((Collection<ImmutableClassType>) result, hasItem((ImmutableClassType) classType));
assertThat((Collection<ImmutableClassType>) result, hasItem((ImmutableClassType) indirectSuperClassType));
verify(lookup, times(1)).findClassTypesByPattern(superClassName, false);
verifyNoMoreInteractions(lookup);
}
@Test
public void nonInitializedBySuperClassIndirect() {
String superClassName = "info.novatec.MyClass";
when(methodSensorAssignment.getClassName()).thenReturn(superClassName);
when(methodSensorAssignment.isInterf()).thenReturn(false);
when(methodSensorAssignment.isSuperclass()).thenReturn(true);
ClassType superClassType = new ClassType(superClassName);
ClassType indirectSuperClassType = new ClassType("indirectSuperClassType");
indirectSuperClassType.addSuperClass(superClassType);
ClassType classType = new ClassType("non-initialized");
classType.addSuperClass(indirectSuperClassType);
doReturn(Collections.singleton(superClassType)).when(lookup).findClassTypesByPattern(eq(superClassName), anyBoolean());
Collection<? extends ImmutableClassType> result = narrower.narrowByClassSensorAssignment(classCache, methodSensorAssignment);
assertThat(result, is(empty()));
verify(lookup, times(1)).findClassTypesByPattern(superClassName, false);
verifyNoMoreInteractions(lookup);
}
@Test
public void initializedByAnnotation() {
String className = "*";
String annotationName = "info.novatec.MyAnnotation";
when(methodSensorAssignment.getClassName()).thenReturn(className);
when(methodSensorAssignment.isInterf()).thenReturn(false);
when(methodSensorAssignment.isSuperclass()).thenReturn(false);
when(methodSensorAssignment.getAnnotation()).thenReturn(annotationName);
AnnotationType annotationType = new AnnotationType(annotationName);
ClassType classType = new ClassType("initialized", "hash", 0);
classType.addAnnotation(annotationType);
doReturn(Collections.singleton(annotationType)).when(lookup).findAnnotationTypesByPattern(eq(annotationName), anyBoolean());
Collection<? extends ImmutableClassType> result = narrower.narrowByClassSensorAssignment(classCache, methodSensorAssignment);
assertThat(result, hasSize(1));
assertThat(result.iterator().next(), is((ImmutableClassType) classType));
verify(lookup, times(1)).findAnnotationTypesByPattern(annotationName, false);
verifyNoMoreInteractions(lookup);
}
@Test
public void nonInitializedByAnnotation() {
String className = "*";
String annotationName = "info.novatec.MyAnnotation";
when(methodSensorAssignment.getClassName()).thenReturn(className);
when(methodSensorAssignment.isInterf()).thenReturn(false);
when(methodSensorAssignment.isSuperclass()).thenReturn(false);
when(methodSensorAssignment.getAnnotation()).thenReturn(annotationName);
AnnotationType annotationType = new AnnotationType(annotationName);
ClassType classType = new ClassType("non-initialized");
classType.addAnnotation(annotationType);
doReturn(Collections.singleton(annotationType)).when(lookup).findAnnotationTypesByPattern(eq(annotationName), anyBoolean());
Collection<? extends ImmutableClassType> result = narrower.narrowByClassSensorAssignment(classCache, methodSensorAssignment);
assertThat(result, is(empty()));
verify(lookup, times(1)).findAnnotationTypesByPattern(annotationName, false);
verifyNoMoreInteractions(lookup);
}
@Test
public void initializedBySuperClassAnnotation() {
String className = "*";
String annotationName = "info.novatec.MyAnnotation";
when(methodSensorAssignment.getClassName()).thenReturn(className);
when(methodSensorAssignment.isInterf()).thenReturn(false);
when(methodSensorAssignment.isSuperclass()).thenReturn(false);
when(methodSensorAssignment.getAnnotation()).thenReturn(annotationName);
AnnotationType annotationType = new AnnotationType(annotationName);
ClassType superClassType = new ClassType("superClass");
superClassType.addAnnotation(annotationType);
ClassType classType = new ClassType("initialized", "hash", 0);
classType.addSuperClass(superClassType);
doReturn(Collections.singleton(annotationType)).when(lookup).findAnnotationTypesByPattern(eq(annotationName), anyBoolean());
Collection<? extends ImmutableClassType> result = narrower.narrowByClassSensorAssignment(classCache, methodSensorAssignment);
assertThat(result, hasSize(1));
assertThat(result.iterator().next(), is((ImmutableClassType) classType));
verify(lookup, times(1)).findAnnotationTypesByPattern(annotationName, false);
verifyNoMoreInteractions(lookup);
}
@Test
public void nonInitializedBySuperClassAnnotation() {
String className = "*";
String annotationName = "info.novatec.MyAnnotation";
when(methodSensorAssignment.getClassName()).thenReturn(className);
when(methodSensorAssignment.isInterf()).thenReturn(false);
when(methodSensorAssignment.isSuperclass()).thenReturn(false);
when(methodSensorAssignment.getAnnotation()).thenReturn(annotationName);
AnnotationType annotationType = new AnnotationType(annotationName);
ClassType superClassType = new ClassType("superClass");
superClassType.addAnnotation(annotationType);
ClassType classType = new ClassType("non-initialized");
classType.addSuperClass(superClassType);
doReturn(Collections.singleton(annotationType)).when(lookup).findAnnotationTypesByPattern(eq(annotationName), anyBoolean());
Collection<? extends ImmutableClassType> result = narrower.narrowByClassSensorAssignment(classCache, methodSensorAssignment);
assertThat(result, is(empty()));
verify(lookup, times(1)).findAnnotationTypesByPattern(annotationName, false);
verifyNoMoreInteractions(lookup);
}
@Test
public void initializedByInterfaceAnnotation() {
String className = "*";
String annotationName = "info.novatec.MyAnnotation";
when(methodSensorAssignment.getClassName()).thenReturn(className);
when(methodSensorAssignment.isInterf()).thenReturn(false);
when(methodSensorAssignment.isSuperclass()).thenReturn(false);
when(methodSensorAssignment.getAnnotation()).thenReturn(annotationName);
AnnotationType annotationType = new AnnotationType(annotationName);
InterfaceType interfaceType = new InterfaceType("interface");
interfaceType.addAnnotation(annotationType);
ClassType classType = new ClassType("initialized", "hash", 0);
classType.addInterface(interfaceType);
doReturn(Collections.singleton(annotationType)).when(lookup).findAnnotationTypesByPattern(eq(annotationName), anyBoolean());
Collection<? extends ImmutableClassType> result = narrower.narrowByClassSensorAssignment(classCache, methodSensorAssignment);
assertThat(result, hasSize(1));
assertThat(result.iterator().next(), is((ImmutableClassType) classType));
verify(lookup, times(1)).findAnnotationTypesByPattern(annotationName, false);
verifyNoMoreInteractions(lookup);
}
@Test
public void nonInitializedByInterfaceAnnotation() {
String className = "*";
String annotationName = "info.novatec.MyAnnotation";
when(methodSensorAssignment.getClassName()).thenReturn(className);
when(methodSensorAssignment.isInterf()).thenReturn(false);
when(methodSensorAssignment.isSuperclass()).thenReturn(false);
when(methodSensorAssignment.getAnnotation()).thenReturn(annotationName);
AnnotationType annotationType = new AnnotationType(annotationName);
InterfaceType interfaceType = new InterfaceType("interface");
interfaceType.addAnnotation(annotationType);
ClassType classType = new ClassType("non-initialized");
classType.addInterface(interfaceType);
doReturn(Collections.singleton(annotationType)).when(lookup).findAnnotationTypesByPattern(eq(annotationName), anyBoolean());
Collection<? extends ImmutableClassType> result = narrower.narrowByClassSensorAssignment(classCache, methodSensorAssignment);
assertThat(result, is(empty()));
verify(lookup, times(1)).findAnnotationTypesByPattern(annotationName, false);
verifyNoMoreInteractions(lookup);
}
@Test
public void initializedByMethodAnnotation() {
String className = "*";
String annotationName = "info.novatec.MyAnnotation";
when(methodSensorAssignment.getClassName()).thenReturn(className);
when(methodSensorAssignment.isInterf()).thenReturn(false);
when(methodSensorAssignment.isSuperclass()).thenReturn(false);
when(methodSensorAssignment.getAnnotation()).thenReturn(annotationName);
AnnotationType annotationType = new AnnotationType(annotationName);
MethodType methodType = new MethodType();
methodType.addAnnotation(annotationType);
ClassType classType = new ClassType("initialized", "hash", 0);
classType.addMethod(methodType);
doReturn(Collections.singleton(annotationType)).when(lookup).findAnnotationTypesByPattern(eq(annotationName), anyBoolean());
Collection<? extends ImmutableClassType> result = narrower.narrowByClassSensorAssignment(classCache, methodSensorAssignment);
assertThat(result, hasSize(1));
assertThat(result.iterator().next(), is((ImmutableClassType) classType));
verify(lookup, times(1)).findAnnotationTypesByPattern(annotationName, false);
verifyNoMoreInteractions(lookup);
}
@Test
public void nonInitializedByMethodAnnotation() {
String className = "*";
String annotationName = "info.novatec.MyAnnotation";
when(methodSensorAssignment.getClassName()).thenReturn(className);
when(methodSensorAssignment.isInterf()).thenReturn(false);
when(methodSensorAssignment.isSuperclass()).thenReturn(false);
when(methodSensorAssignment.getAnnotation()).thenReturn(annotationName);
AnnotationType annotationType = new AnnotationType(annotationName);
MethodType methodType = new MethodType();
methodType.addAnnotation(annotationType);
ClassType classType = new ClassType("non-initialized");
classType.addMethod(methodType);
doReturn(Collections.singleton(annotationType)).when(lookup).findAnnotationTypesByPattern(eq(annotationName), anyBoolean());
Collection<? extends ImmutableClassType> result = narrower.narrowByClassSensorAssignment(classCache, methodSensorAssignment);
assertThat(result, is(empty()));
verify(lookup, times(1)).findAnnotationTypesByPattern(annotationName, false);
verifyNoMoreInteractions(lookup);
}
}
}