(UnusedSymbolInspection) Added support for typing per inspection tests
relates to #KT-38653
This commit is contained in:
+55
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.idea.perf
|
||||
|
||||
import com.intellij.codeInsight.daemon.impl.HighlightInfo
|
||||
import com.intellij.testFramework.UsefulTestCase
|
||||
import org.jetbrains.kotlin.idea.perf.util.ExternalProject
|
||||
import org.jetbrains.kotlin.idea.perf.util.lastPathSegment
|
||||
import org.jetbrains.kotlin.idea.perf.util.suite
|
||||
import org.jetbrains.kotlin.test.JUnit3RunnerWithInners
|
||||
import org.junit.runner.RunWith
|
||||
|
||||
/**
|
||||
* Run the only specified exceptions on the selected files in Kotling project.
|
||||
* Used for 'The Kotlin sources: kt files heavy inspections' graph.
|
||||
* @TODO Should be run before typing tests as the testing project becomes unusable afterwards.
|
||||
*/
|
||||
@RunWith(JUnit3RunnerWithInners::class)
|
||||
class AHeavyInspectionsPerformanceTest : UsefulTestCase() {
|
||||
val listOfFiles = arrayOf(
|
||||
"libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/NewMultiplatformIT.kt",
|
||||
"idea/idea-analysis/src/org/jetbrains/kotlin/idea/util/PsiPrecedences.kt",
|
||||
"compiler/psi/src/org/jetbrains/kotlin/psi/KtElement.kt",
|
||||
"compiler/psi/src/org/jetbrains/kotlin/psi/KtFile.kt",
|
||||
"compiler/psi/src/org/jetbrains/kotlin/psi/KtImportInfo.kt"
|
||||
)
|
||||
val listOfInspections = arrayOf(
|
||||
"UnusedSymbol",
|
||||
"MemberVisibilityCanBePrivate"
|
||||
)
|
||||
|
||||
fun testLocalInspection() {
|
||||
suite {
|
||||
app {
|
||||
project(ExternalProject.KOTLIN_GRADLE) {
|
||||
for (inspection in listOfInspections) {
|
||||
enableSingleInspection(inspection)
|
||||
for (file in listOfFiles) {
|
||||
val editorFile = editor(file)
|
||||
|
||||
measure<List<HighlightInfo>>(inspection, file.lastPathSegment()) {
|
||||
test = {
|
||||
highlight(editorFile)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -5,6 +5,8 @@
|
||||
|
||||
package org.jetbrains.kotlin.idea.perf
|
||||
|
||||
import org.jetbrains.kotlin.idea.perf.profilers.ProfilerConfig
|
||||
|
||||
class PerfTestBuilder<SV, TV> {
|
||||
private lateinit var stats: Stats
|
||||
private lateinit var name: String
|
||||
@@ -15,6 +17,7 @@ class PerfTestBuilder<SV, TV> {
|
||||
private var tearDown: (TestData<SV, TV>) -> Unit = { }
|
||||
private var profilerEnabled: Boolean = false
|
||||
private var checkStability: Boolean = true
|
||||
private var profilerConfig: ProfilerConfig = ProfilerConfig()
|
||||
|
||||
internal fun run() {
|
||||
stats.perfTest(
|
||||
@@ -61,6 +64,10 @@ class PerfTestBuilder<SV, TV> {
|
||||
this.profilerEnabled = profilerEnabled
|
||||
}
|
||||
|
||||
fun profilerConfig(profilerConfig: ProfilerConfig) {
|
||||
this.profilerConfig = profilerConfig
|
||||
}
|
||||
|
||||
fun checkStability(checkStability: Boolean) {
|
||||
this.checkStability = checkStability
|
||||
}
|
||||
|
||||
@@ -22,6 +22,7 @@ typealias StatInfos = Map<String, Any>?
|
||||
|
||||
class Stats(
|
||||
val name: String = "",
|
||||
private val profilerConfig: ProfilerConfig = ProfilerConfig(),
|
||||
private val header: Array<String> = arrayOf("Name", "ValueMS", "StdDev"),
|
||||
private val acceptanceStabilityLevel: Int = 25
|
||||
) : Closeable {
|
||||
@@ -266,7 +267,7 @@ class Stats(
|
||||
testData.reset()
|
||||
triggerGC(attempt)
|
||||
|
||||
val phaseProfiler = createPhaseProfiler(phaseData, phaseName, attempt)
|
||||
val phaseProfiler = createPhaseProfiler(phaseData, phaseName, attempt, profilerConfig)
|
||||
|
||||
val setUpMillis = measureTimeMillis { phaseData.setUp(testData) }
|
||||
val attemptName = "${phaseData.testName} #$attempt"
|
||||
@@ -316,7 +317,8 @@ class Stats(
|
||||
private fun <K, T> createPhaseProfiler(
|
||||
phaseData: PhaseData<K, T>,
|
||||
phaseName: String,
|
||||
attempt: Int
|
||||
attempt: Int,
|
||||
profilerConfig: ProfilerConfig
|
||||
): PhaseProfiler {
|
||||
val profilerHandler = if (phaseData.profilerEnabled) ProfilerHandler.getInstance() else DummyProfilerHandler
|
||||
|
||||
@@ -325,7 +327,7 @@ class Stats(
|
||||
check(with(File(profilerPath)) { exists() || mkdirs() }) { "unable to mkdirs $profilerPath for ${phaseData.testName}" }
|
||||
val activityName = "${phaseData.testName}-${if (phaseName.isEmpty()) "" else "$phaseName-"}$attempt"
|
||||
|
||||
ActualPhaseProfiler(activityName, profilerPath, profilerHandler)
|
||||
ActualPhaseProfiler(activityName, profilerPath, profilerHandler, profilerConfig)
|
||||
} else {
|
||||
DummyPhaseProfiler
|
||||
}
|
||||
|
||||
+7
-4
@@ -19,14 +19,17 @@ object DummyPhaseProfiler : PhaseProfiler {
|
||||
class ActualPhaseProfiler(
|
||||
private val activityName: String,
|
||||
private val profilerPath: String,
|
||||
private val profilerHandler: ProfilerHandler
|
||||
private val profilerHandler: ProfilerHandler,
|
||||
private val config: ProfilerConfig = ProfilerConfig()
|
||||
) :
|
||||
PhaseProfiler {
|
||||
override fun start() {
|
||||
profilerHandler.startProfiling(activityName)
|
||||
profilerHandler.startProfiling(activityName, config)
|
||||
}
|
||||
|
||||
override fun stop() {
|
||||
profilerHandler.stopProfiling(profilerPath, activityName)
|
||||
profilerHandler.stopProfiling(profilerPath, activityName, config)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
data class ProfilerConfig(var tracing: Boolean = false, var options: List<String> = emptyList())
|
||||
+4
-4
@@ -10,9 +10,9 @@ import org.jetbrains.kotlin.idea.perf.profilers.yk.YKProfilerHandler
|
||||
import org.jetbrains.kotlin.idea.perf.util.logMessage
|
||||
|
||||
interface ProfilerHandler {
|
||||
fun startProfiling(activityName: String, options: List<String> = emptyList())
|
||||
fun startProfiling(activityName: String, config: ProfilerConfig)
|
||||
|
||||
fun stopProfiling(snapshotsPath: String, activityName: String, options: List<String> = emptyList())
|
||||
fun stopProfiling(snapshotsPath: String, activityName: String, config: ProfilerConfig)
|
||||
|
||||
companion object {
|
||||
private var instance: ProfilerHandler? = null
|
||||
@@ -32,9 +32,9 @@ interface ProfilerHandler {
|
||||
}
|
||||
|
||||
object DummyProfilerHandler : ProfilerHandler {
|
||||
override fun startProfiling(activityName: String, options: List<String>) {}
|
||||
override fun startProfiling(activityName: String, config: ProfilerConfig) {}
|
||||
|
||||
override fun stopProfiling(snapshotsPath: String, activityName: String, options: List<String>) {}
|
||||
override fun stopProfiling(snapshotsPath: String, activityName: String, config: ProfilerConfig) {}
|
||||
}
|
||||
|
||||
internal fun <T> doOrLog(message: String, block: () -> T?): T? {
|
||||
|
||||
+6
-5
@@ -8,6 +8,7 @@ package org.jetbrains.kotlin.idea.perf.profilers.async
|
||||
import com.intellij.openapi.util.SystemInfo
|
||||
import com.intellij.openapi.util.io.FileUtil
|
||||
import com.intellij.util.containers.ContainerUtil
|
||||
import org.jetbrains.kotlin.idea.perf.profilers.ProfilerConfig
|
||||
import org.jetbrains.kotlin.idea.perf.profilers.ProfilerHandler
|
||||
import org.jetbrains.kotlin.idea.perf.profilers.doOrThrow
|
||||
import org.jetbrains.kotlin.idea.perf.util.logMessage
|
||||
@@ -47,18 +48,18 @@ internal class AsyncProfilerHandler : ProfilerHandler {
|
||||
executeMethod.invoke(asyncProfiler, command)
|
||||
}
|
||||
|
||||
override fun startProfiling(activityName: String, options: List<String>) {
|
||||
override fun startProfiling(activityName: String, config: ProfilerConfig) {
|
||||
try {
|
||||
profilingOptions = options
|
||||
execute(AsyncProfilerCommandBuilder.buildStartCommand(options))
|
||||
profilingOptions = config.options
|
||||
execute(AsyncProfilerCommandBuilder.buildStartCommand(config.options))
|
||||
profilingStarted = true
|
||||
} catch (e: Exception) {
|
||||
throw RuntimeException(e)
|
||||
}
|
||||
}
|
||||
|
||||
override fun stopProfiling(snapshotsPath: String, activityName: String, options: List<String>) {
|
||||
val combinedOptions = ArrayList(options)
|
||||
override fun stopProfiling(snapshotsPath: String, activityName: String, config: ProfilerConfig) {
|
||||
val combinedOptions = ArrayList(config.options)
|
||||
val commandBuilder = AsyncProfilerCommandBuilder(snapshotsPath)
|
||||
val name = activityName.replace(' ', '_').replace('/', '_')
|
||||
val stopAndDumpCommands = commandBuilder.buildStopAndDumpCommands(name, combinedOptions)
|
||||
|
||||
+18
-4
@@ -5,6 +5,7 @@
|
||||
|
||||
package org.jetbrains.kotlin.idea.perf.profilers.yk
|
||||
|
||||
import org.jetbrains.kotlin.idea.perf.profilers.ProfilerConfig
|
||||
import org.jetbrains.kotlin.idea.perf.profilers.ProfilerHandler
|
||||
import org.jetbrains.kotlin.idea.perf.profilers.doOrThrow
|
||||
import org.jetbrains.kotlin.idea.perf.util.logMessage
|
||||
@@ -32,15 +33,18 @@ class YKProfilerHandler : ProfilerHandler {
|
||||
}
|
||||
}
|
||||
|
||||
override fun startProfiling(activityName: String, options: List<String>) {
|
||||
startCPUSamplingMethod.invoke(controller, null)
|
||||
override fun startProfiling(activityName: String, config: ProfilerConfig) {
|
||||
if (config.tracing)
|
||||
startTracingMethod.invoke(controller, null)
|
||||
else
|
||||
startCPUSamplingMethod.invoke(controller, null)
|
||||
}
|
||||
|
||||
override fun stopProfiling(snapshotsPath: String, activityName: String, options: List<String>) {
|
||||
override fun stopProfiling(snapshotsPath: String, activityName: String, config: ProfilerConfig) {
|
||||
val dumpPath = captureSnapshotMethod.invoke(controller, SNAPSHOT_WITHOUT_HEAP) as String
|
||||
stopCPUProfilingMethod.invoke(controller)
|
||||
val path = Paths.get(dumpPath)
|
||||
val target = path.parent.resolve(snapshotsPath)
|
||||
val target = path.parent.resolve(snapshotsPath).resolve(activityName)
|
||||
logMessage { "dump is moved to $target" }
|
||||
Files.move(path, target)
|
||||
}
|
||||
@@ -57,6 +61,12 @@ class YKProfilerHandler : ProfilerHandler {
|
||||
String::class.java
|
||||
)
|
||||
}
|
||||
private val startTracingMethod: Method = doOrThrow("com.yourkit.api.Controller#startTracing(String) not found") {
|
||||
ykLibClass.getMethod(
|
||||
"startTracing",
|
||||
String::class.java
|
||||
)
|
||||
}
|
||||
private val captureSnapshotMethod: Method = doOrThrow("com.yourkit.api.Controller#captureSnapshot(long) not found") {
|
||||
ykLibClass.getMethod(
|
||||
"captureSnapshot",
|
||||
@@ -64,6 +74,10 @@ class YKProfilerHandler : ProfilerHandler {
|
||||
)
|
||||
}
|
||||
|
||||
private val capturePerformanceSnapshotMethod: Method = doOrThrow("com.yourkit.api.Controller#capturePerformanceSnapshot() not found") {
|
||||
ykLibClass.getMethod("capturePerformanceSnapshot")
|
||||
}
|
||||
|
||||
private val stopCPUProfilingMethod: Method = doOrThrow("com.yourkit.api.Controller#stopCPUProfiling() not found") {
|
||||
ykLibClass.getMethod("stopCPUProfiling")
|
||||
}
|
||||
|
||||
@@ -34,6 +34,7 @@ import org.jetbrains.kotlin.idea.perf.ProjectBuilder
|
||||
import org.jetbrains.kotlin.idea.perf.Stats
|
||||
import org.jetbrains.kotlin.idea.perf.Stats.Companion.runAndMeasure
|
||||
import org.jetbrains.kotlin.idea.perf.performanceTest
|
||||
import org.jetbrains.kotlin.idea.perf.profilers.ProfilerConfig
|
||||
import org.jetbrains.kotlin.idea.perf.util.ProfileTools.Companion.disableAllInspections
|
||||
import org.jetbrains.kotlin.idea.perf.util.ProfileTools.Companion.enableAllInspections
|
||||
import org.jetbrains.kotlin.idea.perf.util.ProfileTools.Companion.enableInspections
|
||||
@@ -139,6 +140,7 @@ class PerformanceSuite {
|
||||
after?.invoke()
|
||||
}
|
||||
profilerEnabled(config.profile)
|
||||
profilerConfig(config.profilerConfig)
|
||||
}
|
||||
return value
|
||||
}
|
||||
@@ -178,7 +180,7 @@ class PerformanceSuite {
|
||||
}
|
||||
|
||||
override fun close() {
|
||||
application?.setDataProvider(null)
|
||||
application.setDataProvider(null)
|
||||
}
|
||||
|
||||
companion object {
|
||||
@@ -214,7 +216,7 @@ class PerformanceSuite {
|
||||
}
|
||||
|
||||
|
||||
class StatsScopeConfig(var name: String? = null, var warmup: Int = 2, var iterations: Int = 5, var profile: Boolean = false)
|
||||
class StatsScopeConfig(var name: String? = null, var warmup: Int = 2, var iterations: Int = 5, var profile: Boolean = false, var profilerConfig: ProfilerConfig = ProfilerConfig())
|
||||
|
||||
class ProjectScopeConfig(val path: String, val openWith: ProjectOpenAction, val refresh: Boolean = false) {
|
||||
val name: String = path.lastPathSegment()
|
||||
@@ -329,8 +331,8 @@ class PerformanceSuite {
|
||||
override fun close() {
|
||||
RunAll(
|
||||
ThrowableRunnable {
|
||||
project?.let { prj ->
|
||||
app.application?.closeProject(prj)
|
||||
project.let { prj ->
|
||||
app.application.closeProject(prj)
|
||||
}
|
||||
}).run()
|
||||
}
|
||||
@@ -407,7 +409,7 @@ fun UsefulTestCase.suite(
|
||||
) {
|
||||
PerformanceSuite.suite(
|
||||
suiteName ?: this.javaClass.name,
|
||||
PerformanceSuite.StatsScope(config, Stats(config.name ?: suiteName ?: name), testRootDisposable),
|
||||
PerformanceSuite.StatsScope(config, Stats(config.name ?: suiteName ?: name, config.profilerConfig), testRootDisposable),
|
||||
block
|
||||
)
|
||||
}
|
||||
@@ -13,6 +13,8 @@ class ExternalProject(val path: String, val openWith: ProjectOpenAction) {
|
||||
|
||||
val KOTLIN_GRADLE = ExternalProject(KOTLIN_PROJECT_PATH, ProjectOpenAction.GRADLE_PROJECT)
|
||||
val KOTLIN_JPS = ExternalProject(KOTLIN_PROJECT_PATH, ProjectOpenAction.EXISTING_IDEA_PROJECT)
|
||||
|
||||
// not intended for using in unit tests, only for local verification
|
||||
val KOTLIN_AUTO = ExternalProject(KOTLIN_PROJECT_PATH, autoOpenAction(KOTLIN_PROJECT_PATH))
|
||||
|
||||
fun autoOpenAction(path: String): ProjectOpenAction {
|
||||
|
||||
Reference in New Issue
Block a user