<lambda>null1 package shark
2
3 import java.io.File
4 import okio.Buffer
5 import org.assertj.core.api.Assertions.assertThat
6 import org.junit.Rule
7 import org.junit.Test
8 import org.junit.rules.TemporaryFolder
9 import shark.HeapObject.HeapPrimitiveArray
10 import shark.HprofHeapGraph.Companion.openHeapGraph
11 import shark.HprofRecord.HeapDumpRecord.ObjectRecord.PrimitiveArrayDumpRecord.BooleanArrayDump
12 import shark.HprofRecord.HeapDumpRecord.ObjectRecord.PrimitiveArrayDumpRecord.CharArrayDump
13 import shark.PrimitiveType.BOOLEAN
14 import shark.PrimitiveType.CHAR
15
16 class HprofPrimitiveArrayStripperTest {
17
18 @get:Rule
19 var testFolder = TemporaryFolder()
20
21 private var lastId = 0L
22 private val id: Long
23 get() = ++lastId
24
25 @Test
26 fun stripHprof() {
27 val booleanArray = BooleanArrayDump(id, 1, booleanArrayOf(true, false, true, true))
28 val charArray = CharArrayDump(id, 1, "Hello World!".toCharArray())
29 val hprofBytes = listOf(booleanArray, charArray).asHprofBytes()
30
31 val stripper = HprofPrimitiveArrayStripper()
32
33 val strippedBuffer = Buffer()
34 stripper.stripPrimitiveArrays(hprofBytes, strippedBuffer)
35
36 val strippedSource = ByteArraySourceProvider(strippedBuffer.readByteArray())
37
38 strippedSource.openHeapGraph().use { graph ->
39 val booleanArrays = graph.objects
40 .filter { it is HeapPrimitiveArray && it.primitiveType == BOOLEAN }
41 .map { it.readRecord() as BooleanArrayDump }
42 .toList()
43 assertThat(booleanArrays).hasSize(1)
44 assertThat(booleanArrays[0].id).isEqualTo(booleanArray.id)
45 assertThat(booleanArrays[0].array).isEqualTo(booleanArrayOf(false, false, false, false))
46
47 val charArrays = graph.objects
48 .filter { it is HeapPrimitiveArray && it.primitiveType == CHAR }
49 .map { it.readRecord() as CharArrayDump }
50 .toList()
51 assertThat(charArrays).hasSize(1)
52 assertThat(charArrays[0].id).isEqualTo(charArray.id)
53 assertThat(charArrays[0].array).isEqualTo("????????????".toCharArray())
54 }
55 }
56
57 @Test
58 fun `ByteArray based String content is replaced with question marks`() {
59 val hprofFolder = testFolder.newFolder()
60 val hprofFile = File(hprofFolder, "jvm_heap.hprof")
61 val stringSavedToDump = "Yo!"
62 hold(TestStringHolder(stringSavedToDump)) {
63 JvmTestHeapDumper.dumpHeap(hprofFile.absolutePath)
64 }
65
66 val strippedFile = HprofPrimitiveArrayStripper().stripPrimitiveArrays(hprofFile)
67
68 val initialString = hprofFile.readHolderString()
69 val strippedString = strippedFile.readHolderString()
70 assertThat(initialString).isEqualTo(stringSavedToDump)
71 assertThat(strippedString).isEqualTo("?".repeat(stringSavedToDump.length))
72 }
73
74 private class TestStringHolder(val string: String)
75
76 private fun File.readHolderString() = openHeapGraph().use { graph ->
77 val className = "shark.HprofPrimitiveArrayStripperTest\$TestStringHolder"
78 val holderClass = graph.findClassByName(className)!!
79 val holderInstance = holderClass.instances.single()
80 holderInstance[className, "string"]!!.value.readAsJavaString()!!
81 }
82
83 private fun hold(held: Any, block: () -> Unit) {
84 try {
85 block()
86 } finally {
87 if (System.identityHashCode(held) * 0 > 0f) {
88 error("this will never happen")
89 }
90 }
91 }
92 }
93