Skip to content

Commit

Permalink
refactoring and new test
Browse files Browse the repository at this point in the history
add test to measure performance of data as code approach
against common data in csv files

Remove unused ClassLoadedCounter.kt class.
Rename test sample classes.
Move memory dump creation logic to SimpleBaseTest.kt
  • Loading branch information
Dzmitry Sankouski committed Mar 13, 2022
1 parent a0b7229 commit 561a432
Show file tree
Hide file tree
Showing 10 changed files with 160 additions and 61 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@ import org.assertj.core.api.SoftAssertions
import org.netbeans.lib.profiler.heap.HeapFactory2
import org.netbeans.lib.profiler.heap.Instance
import org.netbeans.lib.profiler.heap.JavaClass
import org.testng.Reporter
import org.testng.annotations.Test
import org.testng.dataprovider.sample.issue2724.TestClass
import org.testng.dataprovider.sample.issue2724.TestDPUnloaded
import org.testng.dataprovider.sample.issue2724.*
import test.SimpleBaseTest
import java.io.File
import java.nio.file.Files
Expand All @@ -19,7 +19,7 @@ class DynamicDataProviderLoadingTest : SimpleBaseTest() {

@Test
fun testDynamicDataProviderPasses() {
val listener = run(TestClass::class.java)
val listener = run(SampleDynamicDP::class.java)
assertThat(listener.failedMethodNames).isEmpty()
assertThat(listener.succeedMethodNames).containsExactly(
"testDynamicDataProvider(Mike,34,student)",
Expand All @@ -33,13 +33,26 @@ class DynamicDataProviderLoadingTest : SimpleBaseTest() {
fun testDynamicDataProviderUnloaded() {
val tempDirectory = Files.createTempDirectory("temp-testng-")
val dumpPath = "%s/%s".format(tempDirectory.toAbsolutePath().toString(), "dump.hprof")
val dumpPathBeforeSample =
"%s/%s".format(tempDirectory.toAbsolutePath().toString(), "dump-before-sample.hprof")
System.setProperty("memdump.path", dumpPath)

run(TestDPUnloaded::class.java)
saveMemDump(dumpPathBeforeSample)
val heapDumpBeforeSampleFile = File(dumpPathBeforeSample)
assertThat(heapDumpBeforeSampleFile).exists()
var heap = HeapFactory2.createHeap(heapDumpBeforeSampleFile, null)
val beforeSampleDPClassDump: JavaClass? = heap.getJavaClassByName(CLASS_NAME_DP)
assertThat(beforeSampleDPClassDump)
.describedAs(
"Class $CLASS_NAME_DP shouldn't be loaded, before test sample started. "
)
.isNull()

run(SampleDPUnloaded::class.java)

val heapDumpFile = File(dumpPath)
assertThat(heapDumpFile).exists()
val heap = HeapFactory2.createHeap(heapDumpFile, null)
heap = HeapFactory2.createHeap(heapDumpFile, null)

with(SoftAssertions()) {
val dpLoaderClassDump: JavaClass? = heap.getJavaClassByName(CLASS_NAME_DP_LOADER)
Expand All @@ -52,15 +65,17 @@ class DynamicDataProviderLoadingTest : SimpleBaseTest() {
}

this.assertThat(dpLoaderClassDump?.instances)
.describedAs("""
.describedAs(
"""
All instances of class $CLASS_NAME_DP_LOADER should be garbage collected, but was not.
Path to GC root is:
$dpLoaderMessage
""".trimIndent()
)
.isEmpty()
this.assertThat(dpClassDump)
.describedAs("""
.describedAs(
"""
Class $CLASS_NAME_DP shouldn't be loaded, but it was.
Path to GC root is:
$dpMessage
Expand All @@ -71,15 +86,41 @@ class DynamicDataProviderLoadingTest : SimpleBaseTest() {
}
}

fun getGCPath(instance: Instance) : String {
@Test
fun comparePerformanceAgainstCsvFiles() {
val simpleDPSuite = create().apply {
setTestClasses(arrayOf(SampleSimpleDP::class.java))
setListenerClasses(listOf(TestTimeListener::class.java))
}
val csvSuite = create().apply {
setTestClasses(arrayOf(SampleWithCSVData::class.java))
setListenerClasses(listOf(TestTimeListener::class.java))
}
val dataAsCodeSuite = create().apply {
setTestClasses(arrayOf(SampleDynamicDP::class.java))
setListenerClasses(listOf(TestTimeListener::class.java))
}

Reporter.log("Test execution time:\n")
for (suite in listOf(
Pair("simple dataprovider", simpleDPSuite),
Pair("dataprovider as code", dataAsCodeSuite),
Pair("csv dataprovider", csvSuite),
)) {
run(false, suite.second)
Reporter.log(
"${suite.first} execution times: %d milliseconds."
.format(TestTimeListener.testRunTime),
true
)
}
}

fun getGCPath(instance: Instance): String {
var result = ""
if (!instance.isGCRoot) {
result += getGCPath(instance.nearestGCRootPointer)
}
return result + "${instance.javaClass.name}\n"
}

companion object {
var classLoadCount = 0
}
}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package org.testng.dataprovider.sample.issue2724

import jlibs.core.lang.RuntimeUtil
import org.testng.annotations.AfterClass
import org.testng.annotations.Test
import test.SimpleBaseTest

class SampleDPUnloaded {
@Suppress("UNUSED_PARAMETER")
@Test(
dataProviderDynamicClass = "org.testng.dataprovider.sample.issue2724.DataProviders",
dataProvider = "data"
)
fun testDynamicDataProvider(name: String, age: Int, status: String) {

}

@AfterClass
fun afterTest() {
RuntimeUtil.gc(10)
SimpleBaseTest.saveMemDump(System.getProperty("memdump.path"))
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ package org.testng.dataprovider.sample.issue2724

import org.testng.annotations.Test

class TestClass {
class SampleDynamicDP {

@Suppress("UNUSED")
@Suppress("UNUSED_PARAMETER")
@Test(
dataProviderDynamicClass = "org.testng.dataprovider.sample.issue2724.DataProviders",
dataProvider = "data"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package org.testng.dataprovider.sample.issue2724

import org.testng.annotations.DataProvider
import org.testng.annotations.Test

class SampleSimpleDP {
@Suppress("UNUSED_PARAMETER")
@Test(dataProvider = "data")
fun testDynamicDataProvider(name: String, age: Int, status: String) {

}

@DataProvider
fun data() : Array<Array<Any>> {
return arrayOf(
arrayOf("Mike", 34, "student"),
arrayOf("Mike", 23, "driver"),
arrayOf("Paul", 20, "director")
)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package org.testng.dataprovider.sample.issue2724

import org.testng.annotations.DataProvider
import org.testng.annotations.Test

class SampleWithCSVData {
@Suppress("UNUSED_PARAMETER")
@Test(dataProvider = "data")
fun testDynamicDataProvider(name: String, age: Int, status: String) {

}

@DataProvider
fun data() : Array<Array<Any>> {
val fileInputStream = this::class.java.classLoader
.getResourceAsStream("test/issue2724/data.csv")
return fileInputStream.reader().readLines().map {
it.split(",").toTypedArray<Any>()
}.toTypedArray()
}
}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package org.testng.dataprovider.sample.issue2724

import org.testng.ITestContext
import org.testng.ITestListener

class TestTimeListener : ITestListener {
private var startTime: Long = 0

override fun onStart(context: ITestContext?) {
startTime = System.currentTimeMillis()
}

override fun onFinish(context: ITestContext?) {
testRunTime = System.currentTimeMillis() - startTime
}

companion object {
var testRunTime: Long = 0
}
}
17 changes: 17 additions & 0 deletions testng-core/src/test/kotlin/test/SimpleBaseTest.kt
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package test

import com.sun.management.HotSpotDiagnosticMXBean
import org.assertj.core.api.Assertions.assertThat
import org.testng.*
import org.testng.annotations.ITestAnnotation
Expand All @@ -10,6 +11,7 @@ import org.testng.internal.annotations.JDK15AnnotationFinder
import org.testng.xml.*
import org.testng.xml.internal.Parser
import java.io.*
import java.lang.management.ManagementFactory
import java.nio.file.FileVisitResult
import java.nio.file.Files
import java.nio.file.Path
Expand Down Expand Up @@ -383,6 +385,21 @@ open class SimpleBaseTest {
.collect(Collectors.joining("\n"))
return "Failed methods should pass: \n $methods"
}

@JvmStatic
fun saveMemDump(path: String) {
try {
val server = ManagementFactory.getPlatformMBeanServer()
val mxBean = ManagementFactory.newPlatformMXBeanProxy(
server,
"com.sun.management:type=HotSpotDiagnostic",
HotSpotDiagnosticMXBean::class.java
)
mxBean.dumpHeap(path, true)
} catch (e: IOException) {
throw TestNGException("Failed to save memory dump", e)
}
}
}

class TestNGFileVisitor : SimpleFileVisitor<Path>() {
Expand Down
3 changes: 3 additions & 0 deletions testng-core/src/test/resources/test/issue2724/data.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Mike, 34, student
Mike, 23, driver
Paul, 20, director

0 comments on commit 561a432

Please sign in to comment.