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

<lambda>null1 package shark
2 
3 import java.io.File
4 import org.assertj.core.api.Assertions.assertThat
5 import org.junit.Before
6 import org.junit.Rule
7 import org.junit.Test
8 import org.junit.rules.TemporaryFolder
9 import shark.GcRoot.StickyClass
10 import shark.HprofHeapGraph.Companion.openHeapGraph
11 import shark.HprofRecord.HeapDumpRecord.GcRootRecord
12 import shark.HprofRecord.HeapDumpRecord.ObjectRecord.ClassDumpRecord
13 import shark.HprofRecord.LoadClassRecord
14 import shark.HprofRecord.StringRecord
15 
16 class HprofHeapGraphTest {
17 
18   @get:Rule
19   val testFolder = TemporaryFolder()
20 
21   private lateinit var hprofFile: File
22 
23   @Before
24   fun setUp() {
25     hprofFile = testFolder.newFile("temp.hprof")
26   }
27 
28   @Test
29   fun `non system class can be found`() {
30     val className = "com.example.SimpleClass"
31 
32     HprofWriter.openWriterFor(hprofFile).use { writer ->
33       val classNameRecord = StringRecord(1L, className)
34       writer.write(classNameRecord)
35       writer.writeClass(42, classNameRecord, rootClass = false)
36     }
37 
38     hprofFile.openHeapGraph().use { graph ->
39       assertThat(graph.findClassByName(className)).isNotNull
40     }
41   }
42 
43   @Test
44   fun `system class can be found`() {
45     val className = "com.example.SimpleClass"
46 
47     HprofWriter.openWriterFor(hprofFile).use { writer ->
48       val classNameRecord = StringRecord(1L, className)
49       writer.write(classNameRecord)
50       writer.writeClass(42, classNameRecord, rootClass = true)
51     }
52 
53     hprofFile.openHeapGraph().use { graph ->
54       assertThat(graph.findClassByName(className)).isNotNull
55     }
56   }
57 
58   @Test
59   fun `system class prioritized over non system class`() {
60     val className = "com.example.SimpleClass"
61 
62     HprofWriter.openWriterFor(hprofFile).use { writer ->
63       val classNameRecord = StringRecord(1L, className)
64       writer.write(classNameRecord)
65       writer.writeClass(24, classNameRecord, rootClass = false)
66       writer.writeClass(25, classNameRecord, rootClass = false)
67       writer.writeClass(42, classNameRecord, rootClass = true)
68       writer.writeClass(43, classNameRecord, rootClass = false)
69     }
70 
71     hprofFile.openHeapGraph().use { graph ->
72       val heapClass = graph.findClassByName(className)!!
73       assertThat(heapClass.objectId).isEqualTo(42)
74     }
75   }
76 
77   private fun HprofWriter.writeClass(
78     classId: Long,
79     classNameRecord: StringRecord,
80     rootClass: Boolean
81   ) {
82     val loadClass = LoadClassRecord(1, classId, 1, classNameRecord.id)
83     val classDump = ClassDumpRecord(
84       id = loadClass.id,
85       stackTraceSerialNumber = 1,
86       superclassId = 0,
87       classLoaderId = 0,
88       signersId = 0,
89       protectionDomainId = 0,
90       instanceSize = 0,
91       staticFields = emptyList(),
92       fields = emptyList()
93     )
94     write(loadClass)
95     if (rootClass) {
96       write(GcRootRecord(gcRoot = StickyClass(classId)))
97     }
98     write(classDump)
99   }
100 }
101