Parse compiler configuration for android tests using new test infrastructure

This commit is contained in:
Dmitriy Novozhilov
2021-02-09 16:34:16 +03:00
committed by TeamCityServer
parent a0007bf244
commit 3ee5665746
3 changed files with 106 additions and 25 deletions
+6
View File
@@ -19,6 +19,10 @@ dependencies {
testCompile(project(":kotlin-reflect")) testCompile(project(":kotlin-reflect"))
testCompile(projectTests(":compiler:tests-common")) testCompile(projectTests(":compiler:tests-common"))
testCompile(commonDep("junit:junit")) testCompile(commonDep("junit:junit"))
testApi(projectTests(":compiler:test-infrastructure"))
testApi(projectTests(":compiler:test-infrastructure-utils"))
testApi(projectTests(":compiler:tests-compiler-utils"))
testApi(projectTests(":compiler:tests-common-new"))
testCompile(projectTests(":jps-plugin")) testCompile(projectTests(":jps-plugin"))
testCompile(commonDep("junit:junit")) testCompile(commonDep("junit:junit"))
@@ -37,6 +41,8 @@ dependencies {
testCompile(intellijPluginDep("java")) { includeJars("jps-builders") } testCompile(intellijPluginDep("java")) { includeJars("jps-builders") }
testCompile(jpsStandalone()) { includeJars("jps-model") } testCompile(jpsStandalone()) { includeJars("jps-model") }
testCompile(jpsBuildTest()) testCompile(jpsBuildTest())
testCompile("org.junit.platform:junit-platform-launcher:${commonVer("org.junit.platform", "")}")
} }
sourceSets { sourceSets {
@@ -20,7 +20,9 @@ import com.intellij.openapi.util.Ref
import org.jetbrains.kotlin.load.kotlin.PackagePartClassUtils import org.jetbrains.kotlin.load.kotlin.PackagePartClassUtils
import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.test.KotlinBaseTest import org.jetbrains.kotlin.test.model.TestModule
import org.jetbrains.kotlin.test.services.TestServices
import org.jetbrains.kotlin.test.services.sourceFileProvider
import java.io.File import java.io.File
import java.util.regex.Pattern import java.util.regex.Pattern
@@ -34,28 +36,24 @@ private data class OldPackageAndNew(val oldFqName: FqName, val newFqName: FqName
internal fun patchFilesAndAddTest( internal fun patchFilesAndAddTest(
testFile: File, testFile: File,
testFiles: List<KotlinBaseTest.TestFile>, module: TestModule,
services: TestServices,
filesHolder: CodegenTestsOnAndroidGenerator.FilesWriter filesHolder: CodegenTestsOnAndroidGenerator.FilesWriter
): FqName? { ): FqName {
if (testFiles.any { it.name.endsWith(".java") }) {
//TODO support java files
return null
}
val ktFiles = testFiles.filter { it.name.endsWith(".kt") }
if (ktFiles.isEmpty()) return null
val newPackagePrefix = testFile.path.replace("\\\\|-|\\.|/".toRegex(), "_") val newPackagePrefix = testFile.path.replace("\\\\|-|\\.|/".toRegex(), "_")
val oldPackage = Ref<FqName>() val oldPackage = Ref<FqName>()
val isJvmName = Ref<Boolean>(false) val isJvmName = Ref<Boolean>(false)
val testFiles = module.files
val isSingle = testFiles.size == 1 val isSingle = testFiles.size == 1
val resultFiles = testFiles.map { val resultFiles = testFiles.map {
val fileName = if (isSingle) it.name else testFile.name.substringBeforeLast(".kt") + "/" + it.name val fileName = if (isSingle) it.name else testFile.name.substringBeforeLast(".kt") + "/" + it.name
val content = services.sourceFileProvider.getContentOfSourceFile(it)
TestClassInfo( TestClassInfo(
fileName, fileName,
changePackage(newPackagePrefix, it.content, oldPackage, isJvmName), changePackage(newPackagePrefix, content, oldPackage, isJvmName),
oldPackage.get(), oldPackage.get(),
isJvmName.get(), isJvmName.get(),
getGeneratedClassName(File(fileName), it.content, newPackagePrefix, oldPackage.get()) getGeneratedClassName(File(fileName), content, newPackagePrefix, oldPackage.get())
) )
} }
val packages = val packages =
@@ -16,12 +16,25 @@ import org.jetbrains.kotlin.codegen.CodegenTestCase
import org.jetbrains.kotlin.codegen.CodegenTestFiles import org.jetbrains.kotlin.codegen.CodegenTestFiles
import org.jetbrains.kotlin.codegen.GenerationUtils import org.jetbrains.kotlin.codegen.GenerationUtils
import org.jetbrains.kotlin.codegen.forTestCompile.ForTestCompileRuntime import org.jetbrains.kotlin.codegen.forTestCompile.ForTestCompileRuntime
import org.jetbrains.kotlin.config.CommonConfigurationKeys import org.jetbrains.kotlin.config.*
import org.jetbrains.kotlin.config.CompilerConfiguration
import org.jetbrains.kotlin.config.JvmTarget
import org.jetbrains.kotlin.idea.KotlinFileType import org.jetbrains.kotlin.idea.KotlinFileType
import org.jetbrains.kotlin.platform.jvm.JvmPlatforms
import org.jetbrains.kotlin.psi.KtFile import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.test.* import org.jetbrains.kotlin.test.*
import org.jetbrains.kotlin.test.builders.TestConfigurationBuilder
import org.jetbrains.kotlin.test.directives.JvmEnvironmentConfigurationDirectives
import org.jetbrains.kotlin.test.directives.model.singleOrZeroValue
import org.jetbrains.kotlin.test.model.DependencyKind
import org.jetbrains.kotlin.test.model.FrontendKinds
import org.jetbrains.kotlin.test.runners.AbstractKotlinCompilerTest
import org.jetbrains.kotlin.test.services.*
import org.jetbrains.kotlin.test.services.configuration.CommonEnvironmentConfigurator
import org.jetbrains.kotlin.test.services.configuration.JvmEnvironmentConfigurator
import org.jetbrains.kotlin.test.services.impl.BackendKindExtractorImpl
import org.jetbrains.kotlin.test.services.impl.TemporaryDirectoryManagerImpl
import org.jetbrains.kotlin.test.services.sourceProviders.AdditionalDiagnosticsSourceFilesProvider
import org.jetbrains.kotlin.test.services.sourceProviders.CodegenHelpersSourceFilesProvider
import org.jetbrains.kotlin.test.services.sourceProviders.CoroutineHelpersSourceFilesProvider
import org.jetbrains.kotlin.test.util.KtTestUtil import org.jetbrains.kotlin.test.util.KtTestUtil
import org.junit.Assert import org.junit.Assert
import java.io.File import java.io.File
@@ -237,6 +250,7 @@ class CodegenTestsOnAndroidGenerator private constructor(private val pathManager
} }
} }
@OptIn(TestInfrastructureInternals::class)
@Throws(IOException::class) @Throws(IOException::class)
private fun processFiles( private fun processFiles(
files: Array<File>, files: Array<File>,
@@ -290,29 +304,92 @@ class CodegenTestsOnAndroidGenerator private constructor(private val pathManager
if (fullFileText.contains("// SKIP_JDK6")) continue if (fullFileText.contains("// SKIP_JDK6")) continue
if (hasBoxMethod(fullFileText)) { if (hasBoxMethod(fullFileText)) {
val testFiles = createTestFiles(file, fullFileText) val testConfiguration = createTestConfiguration(file)
val kind = KotlinBaseTest.extractConfigurationKind(testFiles) val services = testConfiguration.testServices
val jdkKind = KotlinBaseTest.getTestJdkKind(testFiles)
val moduleStructure = try {
testConfiguration.moduleStructureExtractor.splitTestDataByModules(
file.path,
testConfiguration.directives,
).also {
services.register(TestModuleStructure::class, it)
}
} catch (e: ExceptionFromModuleStructureTransformer) {
continue
}
val module = moduleStructure.modules.singleOrNull() ?: continue
if (module.files.any { it.isJavaFile || it.isKtsFile }) continue
if (module.files.isEmpty()) continue
services.registerDependencyProvider(DependencyProviderImpl(services, moduleStructure.modules))
val keyConfiguration = CompilerConfiguration() val keyConfiguration = CompilerConfiguration()
KotlinBaseTest.updateConfigurationByDirectivesInTestFiles(testFiles, keyConfiguration) module.directives.singleOrZeroValue(JvmEnvironmentConfigurationDirectives.JVM_TARGET)?.let {
keyConfiguration.put(JVMConfigurationKeys.JVM_TARGET, it)
}
val configuratorForFlags = JvmEnvironmentConfigurator(services)
with(configuratorForFlags) {
val extractor = DirectiveToConfigurationKeyExtractor()
extractor.provideConfigurationKeys()
extractor.configure(keyConfiguration, module.directives)
}
val kind = configuratorForFlags.extractConfigurationKind(module.directives)
val jdkKind = configuratorForFlags.extractJdkKind(module.directives)
keyConfiguration.languageVersionSettings = module.languageVersionSettings
val key = ConfigurationKey(kind, jdkKind, keyConfiguration.toString()) val key = ConfigurationKey(kind, jdkKind, keyConfiguration.toString())
val compiler = if (kind.withReflection) REFLECT else COMMON val compiler = if (kind.withReflection) REFLECT else COMMON
val compilerConfigurationProvider = services.compilerConfigurationProvider as CompilerConfigurationProviderImpl
val filesHolder = holders.getOrPut(key) { val filesHolder = holders.getOrPut(key) {
FilesWriter(compiler, KotlinTestUtils.newConfiguration(kind, jdkKind, FilesWriter(compiler, compilerConfigurationProvider.createCompilerConfiguration(module)).also {
KtTestUtil.getAnnotationsJar()
).apply {
println("Creating new configuration by $key") println("Creating new configuration by $key")
KotlinBaseTest.updateConfigurationByDirectivesInTestFiles(testFiles, this) }
})
} }
patchFilesAndAddTest(file, testFiles, filesHolder) patchFilesAndAddTest(file, module, services, filesHolder)
} }
} }
} }
} }
private fun createTestConfiguration(testDataFile: File): TestConfiguration {
return TestConfigurationBuilder().apply {
testConfiguration()
testInfo = KotlinTestInfo(
"org.jetbrains.kotlin.android.tests.AndroidRunner",
"test${testDataFile.nameWithoutExtension.capitalize()}",
emptySet()
)
}.build(testDataFile.path)
}
private val testConfiguration: TestConfigurationBuilder.() -> Unit = {
globalDefaults {
frontend = FrontendKinds.ClassicFrontend
targetBackend = TargetBackend.ANDROID
targetPlatform = JvmPlatforms.defaultJvmPlatform
dependencyKind = DependencyKind.Binary
}
useConfigurators(
::CommonEnvironmentConfigurator,
::JvmEnvironmentConfigurator
)
useAdditionalSourceProviders(
::AdditionalDiagnosticsSourceFilesProvider,
::CoroutineHelpersSourceFilesProvider,
::CodegenHelpersSourceFilesProvider,
)
assertions = JUnit5Assertions
useAdditionalService<TemporaryDirectoryManager>(::TemporaryDirectoryManagerImpl)
useAdditionalService<BackendKindExtractor>(::BackendKindExtractorImpl)
useSourcePreprocessor(*AbstractKotlinCompilerTest.defaultPreprocessors.toTypedArray())
useDirectives(*AbstractKotlinCompilerTest.defaultDirectiveContainers.toTypedArray())
}
private fun createTestFiles(file: File, expectedText: String): List<KotlinBaseTest.TestFile> = private fun createTestFiles(file: File, expectedText: String): List<KotlinBaseTest.TestFile> =
CodegenTestCase.createTestFilesFromFile(file, expectedText, false, TargetBackend.JVM) CodegenTestCase.createTestFilesFromFile(file, expectedText, false, TargetBackend.JVM)