Wrap parametrized tests with muteWithDatabase

Cause: should correctly run muted tests in database (KTI-216)
This commit is contained in:
Yunir Salimzyanov
2020-05-27 20:41:33 +03:00
parent 8d51b027ed
commit 4e732b7ba2
2 changed files with 42 additions and 24 deletions
@@ -6,12 +6,13 @@
package org.jetbrains.kotlin.test package org.jetbrains.kotlin.test
import junit.framework.TestCase import junit.framework.TestCase
import org.junit.internal.runners.statements.InvokeMethod
import org.junit.runner.Runner import org.junit.runner.Runner
import org.junit.runner.notification.Failure import org.junit.runner.notification.Failure
import org.junit.runner.notification.RunListener import org.junit.runner.notification.RunListener
import org.junit.runner.notification.RunNotifier import org.junit.runner.notification.RunNotifier
import org.junit.runners.BlockJUnit4ClassRunner
import org.junit.runners.model.FrameworkMethod import org.junit.runners.model.FrameworkMethod
import org.junit.runners.model.Statement
import org.junit.runners.parameterized.BlockJUnit4ClassRunnerWithParameters import org.junit.runners.parameterized.BlockJUnit4ClassRunnerWithParameters
import org.junit.runners.parameterized.ParametersRunnerFactory import org.junit.runners.parameterized.ParametersRunnerFactory
import org.junit.runners.parameterized.TestWithParameters import org.junit.runners.parameterized.TestWithParameters
@@ -158,20 +159,20 @@ private val mutedSet by lazy {
) )
} }
internal fun isMutedInDatabase(testCase: TestCase): Boolean { private fun isMutedInDatabase(testCase: TestCase): Boolean {
return isMutedInDatabase(testCase.javaClass, testCase.name) return isMutedInDatabase(testCase.javaClass, testCase.name)
} }
fun isMutedInDatabase(testClass: Class<*>, methodKey: String): Boolean { private fun isMutedInDatabase(testClass: Class<*>, methodKey: String): Boolean {
val mutedTest = mutedSet.mutedTest(testClass, methodKey) val mutedTest = mutedSet.mutedTest(testClass, methodKey)
return mutedTest != null && (if (SKIP_MUTED_TESTS) !mutedTest.hasFailFile else mutedTest.isFlaky) return mutedTest != null && (if (SKIP_MUTED_TESTS) !mutedTest.hasFailFile else mutedTest.isFlaky)
} }
private fun getMutedTestOrNull(testCase: TestCase): MutedTest? { private fun getMutedTest(testCase: TestCase): MutedTest? {
return getMutedTestOrNull(testCase.javaClass, testCase.name) return getMutedTest(testCase.javaClass, testCase.name)
} }
private fun getMutedTestOrNull(testClass: Class<*>, methodKey: String): MutedTest? { private fun getMutedTest(testClass: Class<*>, methodKey: String): MutedTest? {
return mutedSet.mutedTest(testClass, methodKey) return mutedSet.mutedTest(testClass, methodKey)
} }
@@ -182,22 +183,11 @@ internal fun wrapWithMuteInDatabase(testCase: TestCase, f: () -> Unit): (() -> U
} }
} }
val mutedTest = getMutedTestOrNull(testCase) val mutedTest = getMutedTest(testCase)
if (mutedTest != null && !mutedTest.hasFailFile) { if (mutedTest != null && !mutedTest.hasFailFile) {
val testKey = testKey(testCase)
return { return {
var isTestGreen = true val testKey = testKey(testCase)
try { invertMutedTestResultWithLog(f, testKey)
f()
} catch (e: Throwable) {
println("MUTED TEST STILL FAILS: $testKey")
isTestGreen = false
}
if (isTestGreen) {
System.err.println("SUCCESS RESULT OF MUTED TEST: $testKey")
throw Exception("Muted non-flaky test $testKey finished successfully. Please remove it from csv file")
}
} }
} else { } else {
val doAutoMute = DO_AUTO_MUTE ?: return null val doAutoMute = DO_AUTO_MUTE ?: return null
@@ -220,8 +210,8 @@ private fun testKey(klass: Class<*>, methodKey: String) = "${klass.canonicalName
private fun testKey(testCase: TestCase) = testKey(testCase::class.java, testCase.name) private fun testKey(testCase: TestCase) = testKey(testCase::class.java, testCase.name)
class RunnerFactoryWithMuteInDatabase : ParametersRunnerFactory { class RunnerFactoryWithMuteInDatabase : ParametersRunnerFactory {
override fun createRunnerForTestWithParameters(test: TestWithParameters?): Runner { override fun createRunnerForTestWithParameters(testWithParameters: TestWithParameters?): Runner {
return object : BlockJUnit4ClassRunnerWithParameters(test) { return object : BlockJUnit4ClassRunnerWithParameters(testWithParameters) {
override fun isIgnored(child: FrameworkMethod): Boolean { override fun isIgnored(child: FrameworkMethod): Boolean {
return super.isIgnored(child) || isIgnoredInDatabaseWithLog(child, name) return super.isIgnored(child) || isIgnoredInDatabaseWithLog(child, name)
} }
@@ -231,10 +221,40 @@ class RunnerFactoryWithMuteInDatabase : ParametersRunnerFactory {
super.runChild(method, notifier) super.runChild(method, notifier)
} }
} }
override fun methodInvoker(method: FrameworkMethod, test: Any?): Statement {
return object : InvokeMethod(method, test) {
override fun evaluate() {
val methodClass = method.declaringClass
val methodKey = parametrizedMethodKey(method, name)
val mutedTest = getMutedTest(methodClass, methodKey) ?: getMutedTest(methodClass, method.method.name)
if (mutedTest != null && !mutedTest.hasFailFile) {
val testKey = testKey(methodClass, methodKey)
invertMutedTestResultWithLog({ super.evaluate() }, testKey)
return
}
super.evaluate()
}
}
}
} }
} }
} }
private fun invertMutedTestResultWithLog(f: () -> Unit, testKey: String) {
var isTestGreen = true
try {
f()
} catch (e: Throwable) {
println("MUTED TEST STILL FAILS: $testKey")
isTestGreen = false
}
if (isTestGreen) {
System.err.println("SUCCESS RESULT OF MUTED TEST: $testKey")
throw Exception("Muted non-flaky test $testKey finished successfully. Please remove it from csv file")
}
}
private fun parametrizedMethodKey(child: FrameworkMethod, parametersName: String): String { private fun parametrizedMethodKey(child: FrameworkMethod, parametersName: String): String {
return child.method.name + parametersName return child.method.name + parametersName
} }
@@ -270,7 +290,6 @@ fun isIgnoredInDatabaseWithLog(child: FrameworkMethod): Boolean {
System.err.println(mutedMessage(testKey(child.declaringClass, child.name))) System.err.println(mutedMessage(testKey(child.declaringClass, child.name)))
return true return true
} }
return false return false
} }
@@ -30,7 +30,6 @@ import org.junit.runners.Parameterized.Parameters
import java.io.File import java.io.File
@RunWith(value = JUnitParameterizedWithIdeaConfigurationRunner::class) @RunWith(value = JUnitParameterizedWithIdeaConfigurationRunner::class)
@Parameterized.UseParametersRunnerFactory(RunnerFactoryWithMuteInDatabase::class)
class GradleKtsImportTest : GradleImportingTestCase() { class GradleKtsImportTest : GradleImportingTestCase() {
companion object { companion object {
@JvmStatic @JvmStatic