Add add-imports performance tests

Add missed auto generated perf tests
This commit is contained in:
Vladimir Dolzhenko
2019-06-28 18:12:41 +03:00
parent 57a732c247
commit 2029d16062
10 changed files with 591 additions and 59 deletions
@@ -1190,6 +1190,11 @@ fun main(args: Array<String>) {
model("highlighter", testMethod = "doPerfTest")
}
testClass<AbstractPerformanceAddImportTest> {
model("addImport", testMethod = "doPerfTest", pattern = KT_WITHOUT_DOTS_IN_NAME)
}
}
testGroup("idea/performanceTests", "idea/idea-completion/testData") {
@@ -0,0 +1,68 @@
/*
* Copyright 2010-2019 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.psi.PsiDocumentManager
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.idea.caches.resolve.resolveImportReference
import org.jetbrains.kotlin.idea.util.ImportDescriptorResult
import org.jetbrains.kotlin.idea.util.ImportInsertHelper
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.renderer.DescriptorRenderer
import org.junit.AfterClass
/**
* inspired by @see org.jetbrains.kotlin.addImport.AbstractAddImportTest
*/
abstract class AbstractPerformanceAddImportTest : AbstractPerformanceImportTest() {
companion object {
@JvmStatic
val stats: Stats = Stats("add-import")
@AfterClass
@JvmStatic
fun teardown() {
stats.close()
}
}
override fun stats(): Stats = stats
override fun perfTestCore(
file: KtFile,
fqName: FqName,
filter: (DeclarationDescriptor) -> Boolean,
descriptorName: String,
importInsertHelper: ImportInsertHelper,
psiDocumentManager: PsiDocumentManager
): String? {
val resolveImportReference = file.resolveImportReference(fqName)
val descriptors = resolveImportReference.filter(filter)
return when {
descriptors.isEmpty() -> error("No descriptor $descriptorName found")
descriptors.size > 1 ->
error(
"Multiple descriptors found:\n " +
descriptors.joinToString("\n ") { DescriptorRenderer.FQ_NAMES_IN_TYPES.render(it) }
)
else -> {
val success =
importInsertHelper.importDescriptor(file, descriptors.single()) != ImportDescriptorResult.FAIL
if (!success) {
val document = psiDocumentManager.getDocument(file)!!
document.replaceString(0, document.textLength, "Failed to add import")
psiDocumentManager.commitAllDocuments()
}
null
}
}
}
}
@@ -133,14 +133,7 @@ abstract class AbstractPerformanceCompletionHandlerTests(
setUpFixture(testPath)
},
test = {
fixture.complete(completionType, time)
if (lookupString != null || itemText != null || tailText != null) {
val item = getExistentLookupElement(lookupString, itemText, tailText)
if (item != null) {
selectItem(item, completionChar)
}
}
perfTestCore(completionType, time, lookupString, itemText, tailText, completionChar)
},
tearDown = {
assertNotNull(it)
@@ -151,6 +144,24 @@ abstract class AbstractPerformanceCompletionHandlerTests(
})
}
private fun perfTestCore(
completionType: CompletionType,
time: Int,
lookupString: String?,
itemText: String?,
tailText: String?,
completionChar: Char
) {
fixture.complete(completionType, time)
if (lookupString != null || itemText != null || tailText != null) {
val item = getExistentLookupElement(lookupString, itemText, tailText)
if (item != null) {
selectItem(item, completionChar)
}
}
}
protected open fun setUpFixture(testPath: String) {
fixture.configureWithExtraFile(testPath, ".dependency", ".dependency.1", ".dependency.2")
}
@@ -103,7 +103,7 @@ abstract class AbstractPerformanceCompletionIncrementalResolveTest : KotlinLight
stats.perfTest(
testName = name,
setUp = setUpBody,
test = { myFixture.complete(CompletionType.BASIC) },
test = { perfTestCore() },
tearDown = {
// no reasons to validate output as it is a performance test
assertNotNull(it)
@@ -117,4 +117,6 @@ abstract class AbstractPerformanceCompletionIncrementalResolveTest : KotlinLight
CompletionBindingContextProvider.ENABLED = false
}
}
private fun perfTestCore() = myFixture.complete(CompletionType.BASIC)
}
@@ -5,6 +5,7 @@
package org.jetbrains.kotlin.idea.perf
import com.intellij.codeInsight.daemon.impl.HighlightInfo
import com.intellij.openapi.fileEditor.FileDocumentManager
import com.intellij.testFramework.fixtures.impl.CodeInsightTestFixtureImpl.ensureIndexesUpToDate
import org.jetbrains.kotlin.idea.KotlinFileType
@@ -74,7 +75,7 @@ abstract class AbstractPerformanceHighlightingTest : KotlinLightCodeInsightFixtu
stats.perfTest(
testName = name,
setUp = { setUpBody() },
test = { myFixture.doHighlighting() },
test = { perfTestCore() },
tearDown = {
assertNotNull("no reasons to validate output as it is a performance test", it)
@@ -85,4 +86,6 @@ abstract class AbstractPerformanceHighlightingTest : KotlinLightCodeInsightFixtu
)
}
private fun perfTestCore(): MutableList<HighlightInfo> = myFixture.doHighlighting()
}
@@ -0,0 +1,131 @@
/*
* Copyright 2010-2019 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.application.options.CodeStyle
import com.intellij.openapi.fileEditor.FileDocumentManager
import com.intellij.psi.PsiDocumentManager
import com.intellij.psi.codeStyle.PackageEntry
import com.intellij.testFramework.LightProjectDescriptor
import junit.framework.TestCase
import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.idea.core.formatter.KotlinCodeStyleSettings
import org.jetbrains.kotlin.idea.test.KotlinLightCodeInsightFixtureTestCase
import org.jetbrains.kotlin.idea.test.KotlinWithJdkAndRuntimeLightProjectDescriptor
import org.jetbrains.kotlin.idea.util.ImportInsertHelper
import org.jetbrains.kotlin.idea.util.application.executeWriteCommand
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.test.InTextDirectivesUtils
import org.jetbrains.kotlin.test.KotlinTestUtils
import java.io.File
abstract class AbstractPerformanceImportTest : KotlinLightCodeInsightFixtureTestCase() {
override fun getTestDataPath() = KotlinTestUtils.getHomeDirectory()
override fun getProjectDescriptor(): LightProjectDescriptor = KotlinWithJdkAndRuntimeLightProjectDescriptor.INSTANCE
protected abstract fun stats(): Stats
protected fun doPerfTest(testPath: String) {
val testName = getTestName(false)
CodeStyle.setTemporarySettings(project, CodeStyle.getSettings(project).clone())
val codeStyleSettings = KotlinCodeStyleSettings.getInstance(project)
try {
val fixture = myFixture
val dependencySuffixes = listOf(".dependency.kt", ".dependency.java", ".dependency1.kt", ".dependency2.kt")
for (suffix in dependencySuffixes) {
val dependencyPath = testPath.replace(".kt", suffix)
if (File(dependencyPath).exists()) {
fixture.configureByFile(dependencyPath)
}
}
fixture.configureByFile(testPath)
var file = fixture.file as KtFile
var fileText = file.text
codeStyleSettings.NAME_COUNT_TO_USE_STAR_IMPORT =
InTextDirectivesUtils.getPrefixedInt(fileText, "// NAME_COUNT_TO_USE_STAR_IMPORT:") ?: nameCountToUseStarImportDefault
codeStyleSettings.NAME_COUNT_TO_USE_STAR_IMPORT_FOR_MEMBERS =
InTextDirectivesUtils.getPrefixedInt(fileText, "// NAME_COUNT_TO_USE_STAR_IMPORT_FOR_MEMBERS:")
?: nameCountToUseStarImportForMembersDefault
codeStyleSettings.IMPORT_NESTED_CLASSES =
InTextDirectivesUtils.getPrefixedBoolean(fileText, "// IMPORT_NESTED_CLASSES:") ?: false
InTextDirectivesUtils.findLinesWithPrefixesRemoved(fileText, "// PACKAGE_TO_USE_STAR_IMPORTS:").forEach {
codeStyleSettings.PACKAGES_TO_USE_STAR_IMPORTS.addEntry(PackageEntry(false, it.trim(), false))
}
InTextDirectivesUtils.findLinesWithPrefixesRemoved(fileText, "// PACKAGES_TO_USE_STAR_IMPORTS:").forEach {
codeStyleSettings.PACKAGES_TO_USE_STAR_IMPORTS.addEntry(PackageEntry(false, it.trim(), true))
}
var descriptorName = InTextDirectivesUtils.findStringWithPrefixes(file.text, "// IMPORT:")
?: error("No IMPORT directive defined")
var filter: (DeclarationDescriptor) -> Boolean = { true }
if (descriptorName.startsWith("class:")) {
filter = { it is ClassDescriptor }
descriptorName = descriptorName.substring("class:".length).trim()
}
val fqName = FqName(descriptorName)
val importInsertHelper = ImportInsertHelper.getInstance(project)
val psiDocumentManager = PsiDocumentManager.getInstance(project)
stats().perfTest(
testName = testName,
setUp = {
fixture.configureByFile(testPath)
file = fixture.file as KtFile
fileText = file.text
},
test = {
project.executeWriteCommand<String?>("") {
perfTestCore(file, fqName, filter, descriptorName, importInsertHelper, psiDocumentManager)
}
},
tearDown = { log: String? ->
KotlinTestUtils.assertEqualsToFile(File("$testPath.after"), fixture.file.text)
if (log != null) {
val logFile = File("$testPath.log")
if (log.isNotEmpty()) {
KotlinTestUtils.assertEqualsToFile(logFile, log)
} else {
TestCase.assertFalse(logFile.exists())
}
}
commitAllDocuments()
FileDocumentManager.getInstance().reloadFromDisk(editor.document)
})
} finally {
CodeStyle.dropTemporarySettings(project)
}
}
abstract fun perfTestCore(
file: KtFile,
fqName: FqName,
filter: (DeclarationDescriptor) -> Boolean,
descriptorName: String,
importInsertHelper: ImportInsertHelper,
psiDocumentManager: PsiDocumentManager
): String?
protected open val nameCountToUseStarImportDefault: Int
get() = 1
protected open val nameCountToUseStarImportForMembersDefault: Int
get() = 3
}
@@ -99,7 +99,7 @@ abstract class AbstractPerformanceJavaToKotlinCopyPasteConversionTest(private va
ConvertJavaCopyPasteProcessor.conversionPerformed = false
},
test = {
myFixture.performEditorAction(IdeActions.ACTION_PASTE)
perfTestCore()
},
tearDown = {
commitAllDocuments()
@@ -110,6 +110,10 @@ abstract class AbstractPerformanceJavaToKotlinCopyPasteConversionTest(private va
)
}
private fun perfTestCore() {
myFixture.performEditorAction(IdeActions.ACTION_PASTE)
}
private fun stats() = stats[j2kIndex()]
open fun validate(path: String, noConversionExpected: Boolean) {
@@ -0,0 +1,271 @@
/*
* Copyright 2010-2019 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.testFramework.TestDataPath;
import org.jetbrains.kotlin.test.JUnit3RunnerWithInners;
import org.jetbrains.kotlin.test.KotlinTestUtils;
import org.jetbrains.kotlin.test.TargetBackend;
import org.jetbrains.kotlin.test.TestMetadata;
import org.junit.runner.RunWith;
import java.io.File;
import java.util.regex.Pattern;
/** This class is generated by {@link org.jetbrains.kotlin.generators.tests.TestsPackage}. DO NOT MODIFY MANUALLY */
@SuppressWarnings("all")
@TestMetadata("idea/testData/addImport")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
public class PerformanceAddImportTestGenerated extends AbstractPerformanceAddImportTest {
private void runTest(String testDataFilePath) throws Exception {
KotlinTestUtils.runTest(this::doPerfTest, TargetBackend.ANY, testDataFilePath);
}
public void testAllFilesPresentInAddImport() throws Exception {
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/addImport"), Pattern.compile("^([^.]+)\\.kt$"), TargetBackend.ANY, true);
}
@TestMetadata("CannotImportClass1.kt")
public void testCannotImportClass1() throws Exception {
runTest("idea/testData/addImport/CannotImportClass1.kt");
}
@TestMetadata("CannotImportClass2.kt")
public void testCannotImportClass2() throws Exception {
runTest("idea/testData/addImport/CannotImportClass2.kt");
}
@TestMetadata("ClassAlreadyImported1.kt")
public void testClassAlreadyImported1() throws Exception {
runTest("idea/testData/addImport/ClassAlreadyImported1.kt");
}
@TestMetadata("ClassAlreadyImported2.kt")
public void testClassAlreadyImported2() throws Exception {
runTest("idea/testData/addImport/ClassAlreadyImported2.kt");
}
@TestMetadata("Comments.kt")
public void testComments() throws Exception {
runTest("idea/testData/addImport/Comments.kt");
}
@TestMetadata("CommentsNoPackageDirective.kt")
public void testCommentsNoPackageDirective() throws Exception {
runTest("idea/testData/addImport/CommentsNoPackageDirective.kt");
}
@TestMetadata("ConflictingLocalRef.kt")
public void testConflictingLocalRef() throws Exception {
runTest("idea/testData/addImport/ConflictingLocalRef.kt");
}
@TestMetadata("ConflictingNameAppearsAndHasUsage1.kt")
public void testConflictingNameAppearsAndHasUsage1() throws Exception {
runTest("idea/testData/addImport/ConflictingNameAppearsAndHasUsage1.kt");
}
@TestMetadata("ConflictingNameAppearsAndHasUsage2.kt")
public void testConflictingNameAppearsAndHasUsage2() throws Exception {
runTest("idea/testData/addImport/ConflictingNameAppearsAndHasUsage2.kt");
}
@TestMetadata("ConflictingNameAppearsAndHasUsage3.kt")
public void testConflictingNameAppearsAndHasUsage3() throws Exception {
runTest("idea/testData/addImport/ConflictingNameAppearsAndHasUsage3.kt");
}
@TestMetadata("ConflictingNameAppearsAndHasUsage4.kt")
public void testConflictingNameAppearsAndHasUsage4() throws Exception {
runTest("idea/testData/addImport/ConflictingNameAppearsAndHasUsage4.kt");
}
@TestMetadata("ConflictingNameAppearsAndHasUsage5.kt")
public void testConflictingNameAppearsAndHasUsage5() throws Exception {
runTest("idea/testData/addImport/ConflictingNameAppearsAndHasUsage5.kt");
}
@TestMetadata("ConflictingNameAppearsAndHasUsage6.kt")
public void testConflictingNameAppearsAndHasUsage6() throws Exception {
runTest("idea/testData/addImport/ConflictingNameAppearsAndHasUsage6.kt");
}
@TestMetadata("ConflictingNameAppearsAndHasUsage7.kt")
public void testConflictingNameAppearsAndHasUsage7() throws Exception {
runTest("idea/testData/addImport/ConflictingNameAppearsAndHasUsage7.kt");
}
@TestMetadata("ConflictingNameAppearsButUsageIsQualified.kt")
public void testConflictingNameAppearsButUsageIsQualified() throws Exception {
runTest("idea/testData/addImport/ConflictingNameAppearsButUsageIsQualified.kt");
}
@TestMetadata("ConflictingNameAppearsFalseUsage.kt")
public void testConflictingNameAppearsFalseUsage() throws Exception {
runTest("idea/testData/addImport/ConflictingNameAppearsFalseUsage.kt");
}
@TestMetadata("ConflictingNameAppearsFalseUsage2.kt")
public void testConflictingNameAppearsFalseUsage2() throws Exception {
runTest("idea/testData/addImport/ConflictingNameAppearsFalseUsage2.kt");
}
@TestMetadata("ConflictingNameAppearsNoUsage.kt")
public void testConflictingNameAppearsNoUsage() throws Exception {
runTest("idea/testData/addImport/ConflictingNameAppearsNoUsage.kt");
}
@TestMetadata("ConflictingNameHasExplicitImportAlready.kt")
public void testConflictingNameHasExplicitImportAlready() throws Exception {
runTest("idea/testData/addImport/ConflictingNameHasExplicitImportAlready.kt");
}
@TestMetadata("ConflictingNameNoAllUnderImport.kt")
public void testConflictingNameNoAllUnderImport() throws Exception {
runTest("idea/testData/addImport/ConflictingNameNoAllUnderImport.kt");
}
@TestMetadata("ConflictingNameNoAllUnderImport2.kt")
public void testConflictingNameNoAllUnderImport2() throws Exception {
runTest("idea/testData/addImport/ConflictingNameNoAllUnderImport2.kt");
}
@TestMetadata("ConflictingNameNoAllUnderImport3.kt")
public void testConflictingNameNoAllUnderImport3() throws Exception {
runTest("idea/testData/addImport/ConflictingNameNoAllUnderImport3.kt");
}
@TestMetadata("ConflictsExtensions.kt")
public void testConflictsExtensions() throws Exception {
runTest("idea/testData/addImport/ConflictsExtensions.kt");
}
@TestMetadata("ConflictsExtensions1.kt")
public void testConflictsExtensions1() throws Exception {
runTest("idea/testData/addImport/ConflictsExtensions1.kt");
}
@TestMetadata("DoNotDropConflictingOnStar.kt")
public void testDoNotDropConflictingOnStar() throws Exception {
runTest("idea/testData/addImport/DoNotDropConflictingOnStar.kt");
}
@TestMetadata("DropExplicitImports.kt")
public void testDropExplicitImports() throws Exception {
runTest("idea/testData/addImport/DropExplicitImports.kt");
}
@TestMetadata("DropExplicitImports2.kt")
public void testDropExplicitImports2() throws Exception {
runTest("idea/testData/addImport/DropExplicitImports2.kt");
}
@TestMetadata("FunctionAlreadyImported1.kt")
public void testFunctionAlreadyImported1() throws Exception {
runTest("idea/testData/addImport/FunctionAlreadyImported1.kt");
}
@TestMetadata("FunctionAlreadyImported2.kt")
public void testFunctionAlreadyImported2() throws Exception {
runTest("idea/testData/addImport/FunctionAlreadyImported2.kt");
}
@TestMetadata("ImportClassSimple.kt")
public void testImportClassSimple() throws Exception {
runTest("idea/testData/addImport/ImportClassSimple.kt");
}
@TestMetadata("ImportClassWhenFunctionImported.kt")
public void testImportClassWhenFunctionImported() throws Exception {
runTest("idea/testData/addImport/ImportClassWhenFunctionImported.kt");
}
@TestMetadata("ImportEnumMember1.kt")
public void testImportEnumMember1() throws Exception {
runTest("idea/testData/addImport/ImportEnumMember1.kt");
}
@TestMetadata("ImportEnumMember2.kt")
public void testImportEnumMember2() throws Exception {
runTest("idea/testData/addImport/ImportEnumMember2.kt");
}
@TestMetadata("ImportFromObject.kt")
public void testImportFromObject() throws Exception {
runTest("idea/testData/addImport/ImportFromObject.kt");
}
@TestMetadata("ImportFromRoot.kt")
public void testImportFromRoot() throws Exception {
runTest("idea/testData/addImport/ImportFromRoot.kt");
}
@TestMetadata("ImportFunctionBug.kt")
public void testImportFunctionBug() throws Exception {
runTest("idea/testData/addImport/ImportFunctionBug.kt");
}
@TestMetadata("ImportNestedClass.kt")
public void testImportNestedClass() throws Exception {
runTest("idea/testData/addImport/ImportNestedClass.kt");
}
@TestMetadata("ImportSecondFunction.kt")
public void testImportSecondFunction() throws Exception {
runTest("idea/testData/addImport/ImportSecondFunction.kt");
}
@TestMetadata("KeywordNames.kt")
public void testKeywordNames() throws Exception {
runTest("idea/testData/addImport/KeywordNames.kt");
}
@TestMetadata("NameCountForStarNotReached.kt")
public void testNameCountForStarNotReached() throws Exception {
runTest("idea/testData/addImport/NameCountForStarNotReached.kt");
}
@TestMetadata("NameCountForStarReached.kt")
public void testNameCountForStarReached() throws Exception {
runTest("idea/testData/addImport/NameCountForStarReached.kt");
}
@TestMetadata("NoConflictingNameForInaccessibleClass1.kt")
public void testNoConflictingNameForInaccessibleClass1() throws Exception {
runTest("idea/testData/addImport/NoConflictingNameForInaccessibleClass1.kt");
}
@TestMetadata("NoConflictingNameForInaccessibleClass2.kt")
public void testNoConflictingNameForInaccessibleClass2() throws Exception {
runTest("idea/testData/addImport/NoConflictingNameForInaccessibleClass2.kt");
}
@TestMetadata("NoNeedToImportStandardClass.kt")
public void testNoNeedToImportStandardClass() throws Exception {
runTest("idea/testData/addImport/NoNeedToImportStandardClass.kt");
}
@TestMetadata("PackageDoesNotConflictWithClass.kt")
public void testPackageDoesNotConflictWithClass() throws Exception {
runTest("idea/testData/addImport/PackageDoesNotConflictWithClass.kt");
}
@TestMetadata("PropertyAlreadyImported1.kt")
public void testPropertyAlreadyImported1() throws Exception {
runTest("idea/testData/addImport/PropertyAlreadyImported1.kt");
}
@TestMetadata("PropertyAlreadyImported2.kt")
public void testPropertyAlreadyImported2() throws Exception {
runTest("idea/testData/addImport/PropertyAlreadyImported2.kt");
}
@TestMetadata("StdlibImportsLast.kt")
public void testStdlibImportsLast() throws Exception {
runTest("idea/testData/addImport/StdlibImportsLast.kt");
}
}
@@ -410,6 +410,21 @@ public class PerformanceBasicCompletionHandlerTestGenerated extends AbstractPerf
runTest("idea/idea-completion/testData/handlers/basic/highOrderFunctions/ReplaceByLambdaTemplateNoClosingParenth.kt");
}
@TestMetadata("SameTypeParameters.kt")
public void testSameTypeParameters() throws Exception {
runTest("idea/idea-completion/testData/handlers/basic/highOrderFunctions/SameTypeParameters.kt");
}
@TestMetadata("SameTypeParameters2.kt")
public void testSameTypeParameters2() throws Exception {
runTest("idea/idea-completion/testData/handlers/basic/highOrderFunctions/SameTypeParameters2.kt");
}
@TestMetadata("SameTypeParameters3.kt")
public void testSameTypeParameters3() throws Exception {
runTest("idea/idea-completion/testData/handlers/basic/highOrderFunctions/SameTypeParameters3.kt");
}
@TestMetadata("WithArgsEmptyLambdaAfter.kt")
public void testWithArgsEmptyLambdaAfter() throws Exception {
runTest("idea/idea-completion/testData/handlers/basic/highOrderFunctions/WithArgsEmptyLambdaAfter.kt");
@@ -50,55 +50,9 @@ class Stats(val name: String = "", val header: Array<String> = arrayOf("Name", "
val errors = Array<Throwable?>(iterations, init = { null })
tcSuite(namePrefix) {
for (attempt in 0 until warmUpIterations) {
val n = "$namePrefix warm-up #$attempt"
println("##teamcity[testStarted name='$n' captureStandardOutput='true']")
try {
val setupValue: T? = setUp()
var value: K? = null
var spentNs: Long = 0
try {
spentNs = measureNanoTime {
value = test(setupValue)
}
} catch (t: Throwable) {
println("error at $n:")
tcPrintErrors(n, listOf(t))
} finally {
tearDown(value)
}
val spentMs = spentNs.nsToMs
println("##teamcity[buildStatisticValue key='$n' value='$spentMs']")
println("##teamcity[testFinished name='$n' duration='$spentMs']")
} catch (t: Throwable) {
println("error at $n:")
tcPrintErrors(n, listOf(t))
throw t
}
}
try {
for (attempt in 0 until iterations) {
val setupValue: T? = setUp()
var value: K? = null
try {
val spentNs = measureNanoTime {
value = test(setupValue)
}
timingsNs[attempt] = spentNs
} catch (t: Throwable) {
println("error at $namePrefix #$attempt:")
errors[attempt] = t
} finally {
tearDown(value)
}
}
} catch (t: Throwable) {
println("error at $namePrefix:")
tcPrintErrors(namePrefix, listOf(t))
}
warmUpPhase<K, T>(warmUpIterations, namePrefix, setUp, test, tearDown)
mainPhase<K, T>(iterations, setUp, test, timingsNs, namePrefix, errors, tearDown)
val meanNs = timingsNs.average()
val meanMs = meanNs.toLong().nsToMs
@@ -125,6 +79,74 @@ class Stats(val name: String = "", val header: Array<String> = arrayOf("Name", "
}
}
private fun <K, T> mainPhase(
iterations: Int,
setUp: () -> T?,
test: (t: T?) -> K,
timingsNs: LongArray,
namePrefix: String,
errors: Array<Throwable?>,
tearDown: (t: K?) -> Unit
) {
try {
for (attempt in 0 until iterations) {
val setupValue: T? = setUp()
var value: K? = null
try {
val spentNs = measureNanoTime {
value = test(setupValue)
}
timingsNs[attempt] = spentNs
} catch (t: Throwable) {
println("error at $namePrefix #$attempt:")
errors[attempt] = t
} finally {
tearDown(value)
}
}
} catch (t: Throwable) {
println("error at $namePrefix:")
tcPrintErrors(namePrefix, listOf(t))
}
}
private fun <K, T> warmUpPhase(
warmUpIterations: Int,
namePrefix: String,
setUp: () -> T?,
test: (t: T?) -> K,
tearDown: (t: K?) -> Unit
) {
for (attempt in 0 until warmUpIterations) {
val n = "$namePrefix warm-up #$attempt"
println("##teamcity[testStarted name='$n' captureStandardOutput='true']")
try {
val setupValue: T? = setUp()
var value: K? = null
var spentNs: Long = 0
try {
spentNs = measureNanoTime {
value = test(setupValue)
}
} catch (t: Throwable) {
println("error at $n:")
tcPrintErrors(n, listOf(t))
} finally {
tearDown(value)
}
val spentMs = spentNs.nsToMs
println("##teamcity[buildStatisticValue key='$n' value='$spentMs']")
println("##teamcity[testFinished name='$n' duration='$spentMs']")
} catch (t: Throwable) {
println("##teamcity[testFinished name='$n']")
println("error at $n:")
tcPrintErrors(n, listOf(t))
throw t
}
}
}
override fun close() {
statsOutput.flush()
statsOutput.close()