blob: 8a7a125d39830decc3f0a955709faff23413fe92 [file] [log] [blame]
package leakcanary
import java.io.File
import leakcanary.HeapDumpStorageStrategy.DeleteOnHeapDumpClose
import leakcanary.HeapDumpStorageStrategy.KeepHeapDumps
import leakcanary.HeapDumpStorageStrategy.KeepHeapDumpsOnObjectsGrowing
import leakcanary.HeapDumpStorageStrategy.KeepZippedHeapDumpsOnObjectsGrowing
import org.assertj.core.api.Assertions.assertThat
import org.assertj.core.api.Assertions.assertThatThrownBy
import org.junit.Rule
import org.junit.Test
import org.junit.rules.TemporaryFolder
import shark.GcRoot
import shark.GcRootReference
import shark.JvmObjectGrowthReferenceMatchers
import shark.ObjectGrowthDetector
import shark.OpenJdkReferenceReaderFactory
import shark.dump
import shark.forJvmHeap
class DumpingRepeatingScenarioObjectGrowthDetectorTest {
@get:Rule
val tempFolder = TemporaryFolder()
@Test
fun `DeleteOnHeapDumpClose deletes heap dump on indexing failure`() {
val heapDumpDirectory = tempFolder.newFolder()
DeleteOnHeapDumpClose().triggerIndexingFailure(heapDumpDirectory)
assertThat(heapDumpDirectory.listFiles()).isEmpty()
}
@Test
fun `DeleteOnHeapDumpClose deletes heap dump on traversal failure`() {
val heapDumpDirectory = tempFolder.newFolder()
DeleteOnHeapDumpClose().triggerTraversalFailure(heapDumpDirectory)
assertThat(heapDumpDirectory.listFiles()).isEmpty()
}
@Test
fun `KeepHeapDumps keeps heap dump on indexing failure`() {
val heapDumpDirectory = tempFolder.newFolder()
KeepHeapDumps.triggerIndexingFailure(heapDumpDirectory)
assertThat(heapDumpDirectory.listFiles()).containsExactly(
File(heapDumpDirectory, "dump-1.hprof")
)
}
@Test
fun `KeepHeapDumps keeps heap dump on traversal failure`() {
val heapDumpDirectory = tempFolder.newFolder()
KeepHeapDumps.triggerTraversalFailure(heapDumpDirectory)
assertThat(heapDumpDirectory.listFiles()).containsExactly(
File(heapDumpDirectory, "dump-1.hprof")
)
}
@Test
fun `KeepHeapDumpsOnObjectsGrowing keeps heap dump on indexing failure`() {
val heapDumpDirectory = tempFolder.newFolder()
KeepHeapDumpsOnObjectsGrowing().triggerIndexingFailure(heapDumpDirectory)
assertThat(heapDumpDirectory.listFiles()).containsExactly(
File(heapDumpDirectory, "dump-1.hprof")
)
}
@Test
fun `KeepHeapDumpsOnObjectsGrowing keeps heap dump on traversal failure`() {
val heapDumpDirectory = tempFolder.newFolder()
KeepHeapDumpsOnObjectsGrowing().triggerTraversalFailure(heapDumpDirectory)
assertThat(heapDumpDirectory.listFiles()).containsExactly(
File(heapDumpDirectory, "dump-1.hprof")
)
}
@Test
fun `KeepZippedHeapDumpsOnObjectsGrowing keeps zipped heap dump on indexing failure`() {
val heapDumpDirectory = tempFolder.newFolder()
KeepZippedHeapDumpsOnObjectsGrowing().triggerIndexingFailure(heapDumpDirectory)
assertThat(heapDumpDirectory.listFiles()).containsExactly(
File(heapDumpDirectory, "dump-1.zip")
)
}
@Test
fun `KeepZippedHeapDumpsOnObjectsGrowing keeps zipped heap dump on traversal failure`() {
val heapDumpDirectory = tempFolder.newFolder()
KeepZippedHeapDumpsOnObjectsGrowing().triggerTraversalFailure(heapDumpDirectory)
assertThat(heapDumpDirectory.listFiles()).containsExactly(
File(heapDumpDirectory, "dump-1.zip")
)
}
private fun HeapDumpStorageStrategy.triggerIndexingFailure(heapDumpDirectory: File) {
val heapDumpFiles = generateSequence(1) {
it + 1
}.map { File(heapDumpDirectory, "dump-$it.hprof") }.iterator()
val detector = DumpingRepeatingScenarioObjectGrowthDetector(
objectGrowthDetector = ObjectGrowthDetector.forJvmHeap(),
heapDumpFileProvider = {
heapDumpFiles.next()
},
heapDumper = {
// bad heap dump
it.writeText("I like turtles")
},
heapDumpStorageStrategy = this,
)
try {
detector.findRepeatedlyGrowingObjects {
}
} catch (ignored: Throwable) {
}
}
private fun HeapDumpStorageStrategy.triggerTraversalFailure(heapDumpDirectory: File) {
val unknownObjectId = 42L
val heapDumpFiles = generateSequence(1) {
it + 1
}.map { File(heapDumpDirectory, "dump-$it.hprof") }.iterator()
val referenceMatchers = JvmObjectGrowthReferenceMatchers.defaults
val detector = DumpingRepeatingScenarioObjectGrowthDetector(
objectGrowthDetector = ObjectGrowthDetector(
gcRootProvider = {
// Fake GC Root
sequenceOf(GcRootReference(GcRoot.StickyClass(unknownObjectId), false, null))
},
referenceReaderFactory = OpenJdkReferenceReaderFactory(referenceMatchers)
),
heapDumpFileProvider = {
heapDumpFiles.next()
},
heapDumper = {
// bad heap dump
it.dump { }
},
heapDumpStorageStrategy = this,
)
assertThatThrownBy {
detector.findRepeatedlyGrowingObjects {
}
}.hasMessageContaining(unknownObjectId.toString())
}
}