in profilers-ui/testSrc/com/android/tools/profilers/memory/MemoryClassifierViewTest.java [595:778]
public void groupByStackTraceTest() {
final String CLASS_NAME_0 = "com.android.studio.Foo";
final String CLASS_NAME_1 = "com.google.Bar";
final String CLASS_NAME_2 = "int[]";
final String METHOD_NAME_0 = "fooMethod0";
final String METHOD_NAME_1 = "fooMethod1";
final String METHOD_NAME_2 = "fooMethod2";
final String METHOD_NAME_3 = "barMethod0";
final int LINE_NUMBER_0 = 5;
final int LINE_NUMBER_1 = 10;
final int LINE_NUMBER_2 = 15;
final int LINE_NUMBER_3 = 20;
final int LINE_NUMBER_4 = 25;
//noinspection ConstantConditions
AllocationStack callstack1 = AllocationStack.newBuilder()
.setFullStack(
AllocationStack.StackFrameWrapper.newBuilder()
.addFrames(
AllocationStack.StackFrame.newBuilder()
.setClassName(CLASS_NAME_0)
.setMethodName(METHOD_NAME_1)
.setLineNumber(LINE_NUMBER_1 + 1))
.addFrames(
AllocationStack.StackFrame.newBuilder()
.setClassName(CLASS_NAME_0)
.setMethodName(METHOD_NAME_0)
.setLineNumber(LINE_NUMBER_0 + 1)))
.build();
//noinspection ConstantConditions
AllocationStack callstack2 = AllocationStack.newBuilder()
.setFullStack(
AllocationStack.StackFrameWrapper.newBuilder()
.addFrames(
AllocationStack.StackFrame.newBuilder()
.setClassName(CLASS_NAME_0)
.setMethodName(METHOD_NAME_2)
.setLineNumber(LINE_NUMBER_2 + 1))
.addFrames(
AllocationStack.StackFrame.newBuilder()
.setClassName(CLASS_NAME_0)
.setMethodName(METHOD_NAME_0)
.setLineNumber(LINE_NUMBER_0 + 1)))
.build();
//noinspection ConstantConditions
AllocationStack callstack3 = AllocationStack.newBuilder()
.setFullStack(
AllocationStack.StackFrameWrapper.newBuilder()
.addFrames(
AllocationStack.StackFrame.newBuilder()
.setClassName(CLASS_NAME_1)
.setMethodName(METHOD_NAME_3)
.setLineNumber(LINE_NUMBER_3 + 1)))
.build();
// Check that callstacks only differs by line numbers are still grouped together in the same node.
//noinspection ConstantConditions
AllocationStack callstack4 = AllocationStack.newBuilder()
.setFullStack(
AllocationStack.StackFrameWrapper.newBuilder()
.addFrames(
AllocationStack.StackFrame.newBuilder()
.setClassName(CLASS_NAME_1)
.setMethodName(METHOD_NAME_3)
.setLineNumber(LINE_NUMBER_4 + 1)))
.build();
FakeCaptureObject captureObject = new FakeCaptureObject.Builder().build();
InstanceObject instance1 =
new FakeInstanceObject.Builder(captureObject, 0, CLASS_NAME_0).setName("instanceFoo1").setAllocationStack(callstack1)
.setDepth(2).setShallowSize(2).setRetainedSize(16).build();
InstanceObject instance2 =
new FakeInstanceObject.Builder(captureObject, 0, CLASS_NAME_0).setName("instanceFoo2").setAllocationStack(callstack1)
.setDepth(2).setShallowSize(2).setRetainedSize(24).build();
InstanceObject instance3 =
new FakeInstanceObject.Builder(captureObject, 0, CLASS_NAME_0).setName("instanceFoo3").setAllocationStack(callstack1)
.setDepth(2).setShallowSize(2).setRetainedSize(16).build();
InstanceObject instance4 =
new FakeInstanceObject.Builder(captureObject, 0, CLASS_NAME_0).setName("instanceFoo4").setAllocationStack(callstack2)
.setDepth(2).setShallowSize(2).setRetainedSize(16).build();
InstanceObject instance5 =
new FakeInstanceObject.Builder(captureObject, 0, CLASS_NAME_0).setName("instanceFoo5").setAllocationStack(callstack2)
.setDepth(2).setShallowSize(2).setRetainedSize(16).build();
InstanceObject instance6 =
new FakeInstanceObject.Builder(captureObject, 0, CLASS_NAME_0).setName("instanceFoo6").setAllocationStack(callstack3)
.setDepth(2).setShallowSize(2).setRetainedSize(16).build();
InstanceObject instance7 =
new FakeInstanceObject.Builder(captureObject, 1, CLASS_NAME_1).setName("instanceBar7").setAllocationStack(callstack3)
.setDepth(2).setShallowSize(2).setRetainedSize(16).build();
InstanceObject instance8 =
new FakeInstanceObject.Builder(captureObject, 2, CLASS_NAME_2).setName("instanceBar8").setDepth(0).setShallowSize(2)
.setRetainedSize(8).build();
InstanceObject instance9 =
new FakeInstanceObject.Builder(captureObject, 1, CLASS_NAME_1).setName("instanceBar9").setAllocationStack(callstack4)
.setDepth(2).setShallowSize(2).setRetainedSize(16).build();
Set<InstanceObject> instanceObjects =
new HashSet<>(Arrays.asList(instance1, instance2, instance3, instance4, instance5, instance6, instance7, instance8, instance9));
captureObject.addInstanceObjects(instanceObjects);
myStage
.selectCaptureDuration(new CaptureDurationData<>(1, false, false, new CaptureEntry<CaptureObject>(new Object(), () -> captureObject)),
null);
HeapSet heapSet = captureObject.getHeapSet(CaptureObject.DEFAULT_HEAP_ID);
assertThat(heapSet).isNotNull();
myStage.getCaptureSelection().selectHeapSet(heapSet);
assertThat(myStage.getCaptureSelection().getClassGrouping()).isEqualTo(ARRANGE_BY_CLASS);
assertThat(myStage.getCaptureSelection().getSelectedClassSet()).isNull();
TableColumnModel tableColumnModel = myClassifierView.getTableColumnModel();
assertThat(tableColumnModel.getColumn(0).getHeaderValue()).isEqualTo("Class Name");
JTree classifierTree = myClassifierView.getTree();
assertThat(classifierTree).isNotNull();
Object root = classifierTree.getModel().getRoot();
assertThat(root).isInstanceOf(MemoryObjectTreeNode.class);
assertThat(((MemoryObjectTreeNode)root).getAdapter()).isInstanceOf(HeapSet.class);
//noinspection unchecked
MemoryObjectTreeNode<ClassifierSet> rootNode = (MemoryObjectTreeNode<ClassifierSet>)root;
assertThat(rootNode.getChildCount()).isEqualTo(3);
myStage.getCaptureSelection().setClassGrouping(ARRANGE_BY_CALLSTACK);
tableColumnModel = myClassifierView.getTableColumnModel();
assertThat(tableColumnModel.getColumn(0).getHeaderValue()).isEqualTo("Callstack Name");
root = classifierTree.getModel().getRoot();
assertThat(root).isInstanceOf(MemoryObjectTreeNode.class);
assertThat(((MemoryObjectTreeNode)root).getAdapter()).isInstanceOf(HeapSet.class);
//noinspection unchecked
rootNode = (MemoryObjectTreeNode<ClassifierSet>)root;
assertThat(rootNode.getChildCount()).isEqualTo(3);
MemoryObjectTreeNode<? extends MemoryObject> methodSet1Node = findChildWithPredicate(
rootNode,
classifierSet -> classifierSet instanceof MethodSet && verifyMethodSet((MethodSet)classifierSet, CLASS_NAME_0, METHOD_NAME_0));
assertThat(methodSet1Node.getChildCount()).isEqualTo(2);
MemoryObjectTreeNode<? extends MemoryObject> methodSet2Node = findChildWithPredicate(
methodSet1Node,
classifierSet -> classifierSet instanceof MethodSet && verifyMethodSet((MethodSet)classifierSet, CLASS_NAME_0, METHOD_NAME_1));
ClassSet callstack1FooClassSet = findChildClassSetWithName((ClassifierSet)methodSet2Node.getAdapter(), CLASS_NAME_0);
assertThat(callstack1FooClassSet.findContainingClassifierSet(instance1)).isEqualTo(callstack1FooClassSet);
assertThat(callstack1FooClassSet.findContainingClassifierSet(instance2)).isEqualTo(callstack1FooClassSet);
assertThat(callstack1FooClassSet.findContainingClassifierSet(instance3)).isEqualTo(callstack1FooClassSet);
MemoryObjectTreeNode<? extends MemoryObject> methodSet3Node = findChildWithPredicate(
methodSet1Node,
classifierSet -> classifierSet instanceof MethodSet && verifyMethodSet((MethodSet)classifierSet, CLASS_NAME_0, METHOD_NAME_2));
ClassSet callstack2FooClassSet = findChildClassSetWithName((ClassifierSet)methodSet3Node.getAdapter(), CLASS_NAME_0);
assertThat(callstack2FooClassSet.findContainingClassifierSet(instance4)).isEqualTo(callstack2FooClassSet);
assertThat(callstack2FooClassSet.findContainingClassifierSet(instance5)).isEqualTo(callstack2FooClassSet);
MemoryObjectTreeNode<? extends MemoryObject> methodSet4Node = findChildWithPredicate(
rootNode,
classifierSet -> classifierSet instanceof MethodSet && verifyMethodSet((MethodSet)classifierSet, CLASS_NAME_1, METHOD_NAME_3));
assertThat(methodSet4Node.getChildCount()).isEqualTo(2);
ClassSet callstack3FooClassSet = findChildClassSetWithName((ClassifierSet)methodSet4Node.getAdapter(), CLASS_NAME_0);
assertThat(callstack3FooClassSet.findContainingClassifierSet(instance6)).isEqualTo(callstack3FooClassSet);
ClassSet callstack3BarClassSet = findChildClassSetWithName((ClassifierSet)methodSet4Node.getAdapter(), CLASS_NAME_1);
assertThat(callstack3BarClassSet.findContainingClassifierSet(instance7)).isEqualTo(callstack3BarClassSet);
assertThat(callstack3BarClassSet.findContainingClassifierSet(instance9)).isEqualTo(callstack3BarClassSet);
ClassSet noStackIntArrayClassSet = findChildClassSetWithName(rootNode.getAdapter(), CLASS_NAME_2);
assertThat(noStackIntArrayClassSet.getDeltaAllocationCount()).isEqualTo(1);
//noinspection unchecked
MemoryObjectTreeNode<? extends ClassifierSet> nodeToSelect =
findChildClassSetNodeWithClassName((MemoryObjectTreeNode<ClassifierSet>)methodSet4Node, CLASS_NAME_0);
classifierTree.setSelectionPath(new TreePath(new Object[]{root, methodSet4Node, nodeToSelect}));
myStage.getCaptureSelection().setClassGrouping(ARRANGE_BY_CLASS);
tableColumnModel = myClassifierView.getTableColumnModel();
assertThat(tableColumnModel.getColumn(0).getHeaderValue()).isEqualTo("Class Name");
assertThat(rootNode.getChildCount()).isEqualTo(3);
TreePath selectionPath = classifierTree.getSelectionPath();
assertThat(selectionPath).isNotNull();
Object selectedObject = selectionPath.getLastPathComponent();
assertThat(selectedObject).isInstanceOf(MemoryObjectTreeNode.class);
assertThat(((MemoryObjectTreeNode)selectedObject).getAdapter()).isInstanceOf(ClassSet.class);
//noinspection unchecked
Set<InstanceObject> instances = (nodeToSelect.getAdapter()).getInstancesStream().collect(Collectors.toSet());;
assertThat(((MemoryObjectTreeNode<ClassSet>)selectedObject).getAdapter().isSupersetOf(instances)).isTrue();
}