xref: /aosp_15_r20/external/leakcanary2/shark-graph/src/test/java/shark/HprofIndexParsingTest.kt (revision d9e8da70d8c9df9a41d7848ae506fb3115cae6e6)

<lambda>null1 package shark
2 
3 import org.assertj.core.api.Assertions.assertThat
4 import org.junit.Test
5 import shark.GcRoot.StickyClass
6 import shark.HprofHeapGraph.Companion.openHeapGraph
7 import shark.HprofRecord.HeapDumpRecord.GcRootRecord
8 import shark.HprofRecord.HeapDumpRecord.ObjectRecord.ClassDumpRecord
9 import shark.HprofRecord.LoadClassRecord
10 import shark.HprofRecord.StringRecord
11 
12 class HprofIndexParsingTest {
13 
14   private var lastId = 0L
15   private val id: Long
16     get() = ++lastId
17 
18   @Test fun `duplicated StickyClass GC roots are deduplicated`() {
19     val className = StringRecord(id, "com.example.VeryStickyClass")
20     val loadClassRecord = LoadClassRecord(1, id, 1, className.id)
21     val classDump = ClassDumpRecord(
22       id = loadClassRecord.id,
23       stackTraceSerialNumber = 1,
24       superclassId = 0,
25       classLoaderId = 0,
26       signersId = 0,
27       protectionDomainId = 0,
28       instanceSize = 0,
29       staticFields = emptyList(),
30       fields = emptyList()
31     )
32     val stickyClassRecords = (1..5).map { GcRootRecord(StickyClass(loadClassRecord.id)) }
33     val bytes = (listOf(className, loadClassRecord, classDump) + stickyClassRecords).asHprofBytes()
34 
35     val stickyClassRoots = bytes.openHeapGraph().use { graph: HeapGraph ->
36       graph.gcRoots.filterIsInstance(StickyClass::class.java)
37     }
38 
39     assertThat(stickyClassRoots).hasSize(1)
40     assertThat(stickyClassRoots.first().id).isEqualTo(loadClassRecord.id)
41   }
42 
43   @Test fun `heap dump index is computed based on position in heap dump`() {
44     val bytes = dump {
45       instance(clazz("com.example.MyClass1"))
46       instance(clazz("com.example.MyClass2"))
47     }
48 
49     bytes.openHeapGraph().use { graph ->
50       val class1 = graph.findClassByName("com.example.MyClass1")!!
51       val class1Index = graph.findHeapDumpIndex(class1.objectId)
52       val instance1 = class1.instances.single()
53       val instance1Index = graph.findHeapDumpIndex(instance1.objectId)
54 
55       val class2 = graph.findClassByName("com.example.MyClass2")!!
56       val class2Index = graph.findHeapDumpIndex(class2.objectId)
57       val instance2 = class2.instances.single()
58       val instance2Index = graph.findHeapDumpIndex(instance2.objectId)
59 
60       assertThat(instance1Index).isEqualTo(class1Index + 1)
61       assertThat(class2Index).isEqualTo(instance1Index + 1)
62       assertThat(instance2Index).isEqualTo(class2Index + 1)
63     }
64   }
65 }
66