Make Android codegen tests run as integration tests
This commit refactors the compiler/android-tests module,
streamlining its functionality to solely focus on generating the
Android project for compiler tests.
The tests are now executed as Gradle integration tests,
eliminating manual management of the emulator.
Instead, Gradle-managed Android virtual devices are utilized.
Some refactorings of the test project are done.
Necessary SDK tools versions are updated in dependencies/android-sdk,
with the emulator now being auto-downloaded by Android Gradle Tools.
^KT-66761 Fixed
diff --git a/compiler/android-tests/ReadMe.md b/compiler/android-tests/ReadMe.md
index 8aec6ad..5e1465c 100644
--- a/compiler/android-tests/ReadMe.md
+++ b/compiler/android-tests/ReadMe.md
@@ -1,15 +1,21 @@
-# Codegen tests on Android
+# Codegen Tests on Android
-This module runs codegen box tests (`compiler/testData/codegen/box`) on Android. It does so by compiling all of tests,
-except the excluded ones, in one big Android project and running it as an app on an emulator, which is downloaded during
-the first run of the tests. See which tests are excluded in `CodegenTestsOnAndroidGenerator`, but mainly those are the
-ones annotated with `// IGNORE_BACKEND: ANDROID`, those having Java source files, or using advanced Kotlin/JVM features.
+The module prepares codegen tests for running
+(`compiler/testData/codegen/box` and `compiler/testData/codegen/boxInline` directories) on an Android platform.
+It achieves this by compiling all tests, except those explicitly excluded, into a single Android project.
+The tests are then executed on an Android Virtual Device, leveraging the Kotlin Gradle Plugin integration tests
+(`libraries/tools/kotlin-gradle-plugin-integration-tests`).
+This testing environment is well-suited for building and running external Gradle projects.
+Exclusions in the `CodegenTestsOnAndroidGenerator` typically include tests marked with `// IGNORE_BACKEND: ANDROID`,
+tests that contain Java source files, or tests that use JVM features not supported by the Android Runtime.
-Run the tests via Gradle:
-
+To generate the project with tests, execute:
```
-./gradlew :compiler:android-tests:test
+./gradlew :compiler:android-tests:generateAndroidTests
```
-**Make sure your JAVA_HOME points to a JDK 1.8 installation**, otherwise, you'll get an exception, such as
-`java.lang.ClassNotFoundException: javax.xml.bind.annotation.XmlSchema`.
+Run the according Gradle integration tests by executing:
+
+```
+./gradlew :kotlin-gradle-plugin-integration-tests:kgpAndroidCodegenTests
+```
diff --git a/compiler/android-tests/android-module/build.gradle b/compiler/android-tests/android-module/build.gradle
deleted file mode 100644
index 7f4d024..0000000
--- a/compiler/android-tests/android-module/build.gradle
+++ /dev/null
@@ -1,132 +0,0 @@
-// Top-level build file where you can add configuration options common to all sub-projects/modules.
-buildscript {
- repositories {
- google()
- jcenter()
- }
- dependencies {
- classpath 'com.android.tools.build:gradle:4.1.2'
- }
-}
-apply plugin: 'com.android.application'
-
-repositories {
- google()
- jcenter()
-}
-
-android {
- compileSdkVersion 26
- buildToolsVersion "29.0.3"
-
- defaultConfig {
- applicationId "org.jetbrains.kotlin.android.tests"
- minSdkVersion 19
- targetSdkVersion 19
- versionCode 1
- versionName "1.0"
- testApplicationId "org.jetbrains.kotlin.android.tests.gradle"
- testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
- }
- buildTypes {
- debug {
- minifyEnabled false
- proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
- }
- }
-
- packagingOptions { exclude 'META-INF/build.txt' }
-
-
- dexOptions {
- dexInProcess false
- javaMaxHeapSize "1500m"
- maxProcessCount 4
- additionalParameters "--debug"
- }
-
- testOptions {
- resultsDir = "build/test/results"
- }
-
- compileOptions {
- sourceCompatibility = 1.8
- targetCompatibility = 1.8
- }
-
- flavorDimensions "box"
-
- productFlavors {
- common0 {
- dimension "box"
- }
-
- common1 {
- dimension "box"
- }
-
- common2 {
- dimension "box"
- }
-
- common3 {
- dimension "box"
- }
-
- reflect0 {
- dimension "box"
- }
-
- common_ir0 {
- dimension "box"
- }
-
- common_ir1 {
- dimension "box"
- }
-
- common_ir2 {
- dimension "box"
- }
-
- common_ir3 {
- dimension "box"
- }
-
- reflect_ir0 {
- dimension "box"
- }
- }
-
-}
-
-task jarTestFolders() {
- println "Jar folders..."
- new File("${projectDir}/libs/").listFiles().each { File file ->
- if (file.isDirectory()) {
- println "Jar '${file.name}' folder..."
- ant.jar(basedir: "libs/${file.name}/", destfile: "libs/" + file.name + ".jar")
- }
- }
-}
-
-tasks.withType(JavaCompile) {
- compileTask -> compileTask.dependsOn jarTestFolders
-}
-
-dependencies {
- implementation fileTree(dir: 'libs', include: ['kotlin-test.jar', 'kotlin-stdlib.jar'])
- androidTestImplementation 'junit:junit:4.13.2'
- androidTestImplementation 'com.android.support.test:runner:1.0.2'
-
- android.applicationVariants.all { variant ->
- variant.productFlavors.each {
- def configuration = configurations.getByName(it.name + 'Implementation').name
- add(configuration, project.fileTree(dir: 'libs', include: [it.name + ".jar"]))
-
- if (it.name.startsWith("reflect")) {
- add(configuration, project.fileTree(dir: 'libs', include: ['kotlin-reflect.jar']))
- }
- }
- }
-}
diff --git a/compiler/android-tests/android-module/gradle.properties b/compiler/android-tests/android-module/gradle.properties
deleted file mode 100644
index 2d32c80..0000000
--- a/compiler/android-tests/android-module/gradle.properties
+++ /dev/null
@@ -1,2 +0,0 @@
-#don't try to download android specific tools within gradle: licence acceptance will be required
-android.builder.sdkDownload=false
\ No newline at end of file
diff --git a/compiler/android-tests/android-module/local.properties b/compiler/android-tests/android-module/local.properties
deleted file mode 100644
index db64df6..0000000
--- a/compiler/android-tests/android-module/local.properties
+++ /dev/null
@@ -1,12 +0,0 @@
-# This file is automatically generated by Android Tools.
-# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
-#
-# This file must *NOT* be checked into Version Control Systems,
-# as it contains information specific to your local configuration.
-
-# location of the SDK. This is only used by Ant
-# For customization when using a Version Control System, please read the
-# header note.
-#sdk.dir=compiler/android-tests/android-module/android-sdk/android-sdk-windows
-sdk.dir=../../../dependencies/android.tests.dependencies/android-sdk
-
diff --git a/compiler/android-tests/android-module/proguard-project.txt b/compiler/android-tests/android-module/proguard-project.txt
deleted file mode 100644
index f2fe155..0000000
--- a/compiler/android-tests/android-module/proguard-project.txt
+++ /dev/null
@@ -1,20 +0,0 @@
-# To enable ProGuard in your project, edit project.properties
-# to define the proguard.config property as described in that file.
-#
-# Add project specific ProGuard rules here.
-# By default, the flags in this file are appended to flags specified
-# in ${sdk.dir}/tools/proguard/proguard-android.txt
-# You can edit the include path and order by changing the ProGuard
-# include property in project.properties.
-#
-# For more details, see
-# http://developer.android.com/guide/developing/tools/proguard.html
-
-# Add any project specific keep options here:
-
-# If your project uses WebView with JS, uncomment the following
-# and specify the fully qualified class name to the JavaScript interface
-# class:
-#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
-# public *;
-#}
diff --git a/compiler/android-tests/android-module/src/main/AndroidManifest.xml b/compiler/android-tests/android-module/src/main/AndroidManifest.xml
deleted file mode 100644
index 8b7f6ac..0000000
--- a/compiler/android-tests/android-module/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,9 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="org.jetbrains.kotlin.android.tests"
- android:versionCode="1"
- android:versionName="1.0">
- <application>
- <uses-library android:name="android.test.runner" />
- </application>
-</manifest>
diff --git a/compiler/android-tests/android-module/src/main/java/org/jetbrains/kotlin/android/tests/MyActivity.java b/compiler/android-tests/android-module/src/main/java/org/jetbrains/kotlin/android/tests/MyActivity.java
deleted file mode 100644
index 277753e..0000000
--- a/compiler/android-tests/android-module/src/main/java/org/jetbrains/kotlin/android/tests/MyActivity.java
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Copyright 2010-2015 JetBrains s.r.o.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.jetbrains.kotlin.android.tests;
-
-import android.app.Activity;
-import android.os.Bundle;
-
-public class MyActivity extends Activity {
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- System.out.println(R.string.app_name);
- }
-}
diff --git a/compiler/android-tests/android-module/src/main/res/values/strings.xml b/compiler/android-tests/android-module/src/main/res/values/strings.xml
deleted file mode 100644
index ab73ea8..0000000
--- a/compiler/android-tests/android-module/src/main/res/values/strings.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<resources>
- <string name="app_name">android1</string>
-</resources>
diff --git a/compiler/android-tests/build.gradle.kts b/compiler/android-tests/build.gradle.kts
index 88cb420..2689862 100644
--- a/compiler/android-tests/build.gradle.kts
+++ b/compiler/android-tests/build.gradle.kts
@@ -1,34 +1,20 @@
-import TaskUtils.useAndroidEmulator
-
plugins {
kotlin("jvm")
id("jps-compatible")
}
dependencies {
- testApi(project(":core:descriptors"))
- testApi(project(":core:descriptors.jvm"))
- testApi(project(":compiler:util"))
- testApi(project(":compiler:cli"))
- testApi(project(":compiler:frontend"))
- testApi(project(":compiler:backend"))
- testApi(project(":compiler:incremental-compilation-impl"))
- testApi(project(":compiler:frontend.java"))
-
testApi(kotlinStdlib())
- testApi(projectTests(":compiler:tests-common"))
- testImplementation(libs.junit4)
+ testApi(intellijCore())
+ testApi(project(":core:compiler.common"))
+ testApi(project(":compiler:config"))
+ testApi(project(":compiler:cli"))
+ testApi(project(":compiler:frontend.common.jvm"))
+ testApi(projectTests(":compiler:tests-compiler-utils"))
testApi(projectTests(":compiler:test-infrastructure"))
testApi(projectTests(":compiler:test-infrastructure-utils"))
- testApi(projectTests(":compiler:tests-compiler-utils"))
testApi(projectTests(":compiler:tests-common-new"))
-
- testApi(jpsModel())
-
- testRuntimeOnly(intellijCore())
- testRuntimeOnly(commonDependency("org.jetbrains.intellij.deps.jna:jna"))
-
- testImplementation(libs.junit.platform.launcher)
+ testApi(projectTests(":generators:test-generator"))
}
sourceSets {
@@ -36,27 +22,19 @@
"test" { projectDefault() }
}
-projectTest {
- dependsOn(":dist")
- val jdkHome = project.getToolchainJdkHomeFor(JdkMajorVersion.JDK_1_8)
- doFirst {
- environment("kotlin.tests.android.timeout", "45")
- environment("JAVA_HOME", jdkHome.get())
- }
-
- if (project.hasProperty("teamcity") || project.hasProperty("kotlin.test.android.teamcity")) {
- systemProperty("kotlin.test.android.teamcity", true)
- }
-
- project.findProperty("kotlin.test.android.path.filter")?.let {
- systemProperty("kotlin.test.android.path.filter", it.toString())
- }
-
- workingDir = rootDir
- useAndroidEmulator(this)
-}
-
val generateAndroidTests by generator("org.jetbrains.kotlin.android.tests.CodegenTestsOnAndroidGenerator") {
workingDir = rootDir
- dependsOn(rootProject.tasks.named("dist"))
+
+ val destinationDirectory =
+ rootProject.file("libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/codegen-tests").absolutePath
+
+ val testDataDirectories = arrayOf(
+ rootProject.file("compiler/testData/codegen/box").absolutePath,
+ rootProject.file("compiler/testData/codegen/boxInline").absolutePath,
+ )
+
+ args(destinationDirectory, *testDataDirectories)
+ dependsOn(":dist", ":createIdeaHomeForTests")
+ systemProperty("idea.home.path", ideaHomePathForTests().get().asFile.canonicalPath)
+ systemProperty("idea.use.native.fs.for.win", false)
}
diff --git a/compiler/android-tests/tests/org/jetbrains/kotlin/android/tests/AndroidRunner.java b/compiler/android-tests/tests/org/jetbrains/kotlin/android/tests/AndroidRunner.java
deleted file mode 100644
index 3d4b9c6..0000000
--- a/compiler/android-tests/tests/org/jetbrains/kotlin/android/tests/AndroidRunner.java
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Copyright 2010-2015 JetBrains s.r.o.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.jetbrains.kotlin.android.tests;
-
-import com.google.common.base.StandardSystemProperty;
-import com.intellij.openapi.util.io.FileUtil;
-import junit.framework.TestSuite;
-import org.jetbrains.annotations.NotNull;
-import org.junit.runner.RunWith;
-import org.junit.runners.AllTests;
-
-import java.io.File;
-import java.io.IOException;
-import java.nio.file.Files;
-import java.nio.file.Paths;
-import java.util.Objects;
-
-@RunWith(AllTests.class)
-public class AndroidRunner {
-
- private static PathManager pathManager;
-
- @NotNull
- public static PathManager getPathManager() throws IOException {
- if (pathManager == null) {
- File tmpFolder =
- Files.createTempDirectory(Paths.get(Objects.requireNonNull(StandardSystemProperty.JAVA_IO_TMPDIR.value())), null)
- .toFile();
- System.out.println("Created temporary folder for running android tests: " + tmpFolder.getAbsolutePath());
- File rootFolder = new File("");
- pathManager = new PathManager(rootFolder.getAbsolutePath(), tmpFolder.getAbsolutePath());
- }
- return pathManager;
- }
-
- public static TestSuite suite() throws Throwable {
- PathManager pathManager = getPathManager();
-
- CodegenTestsOnAndroidGenerator.generate(pathManager);
-
- System.out.println("Run tests on Android...");
- return CodegenTestsOnAndroidRunner.runTestsInEmulator(pathManager);
- }
-
- public void tearDown() throws Exception {
- // Clear tmp folder where we run android tests
- FileUtil.delete(new File(pathManager.getTmpFolder()));
- }
-}
diff --git a/compiler/android-tests/tests/org/jetbrains/kotlin/android/tests/AndroidTestGenerator.kt b/compiler/android-tests/tests/org/jetbrains/kotlin/android/tests/AndroidTestGenerator.kt
index 53a1f17..e38d646 100644
--- a/compiler/android-tests/tests/org/jetbrains/kotlin/android/tests/AndroidTestGenerator.kt
+++ b/compiler/android-tests/tests/org/jetbrains/kotlin/android/tests/AndroidTestGenerator.kt
@@ -16,7 +16,6 @@
package org.jetbrains.kotlin.android.tests
-import com.intellij.openapi.util.Ref
import org.jetbrains.kotlin.load.kotlin.PackagePartClassUtils
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name
@@ -40,20 +39,21 @@
services: TestServices,
filesHolder: CodegenTestsOnAndroidGenerator.FilesWriter
): FqName {
- val newPackagePrefix = testFile.path.replace("\\\\|-|\\.|/".toRegex(), "_")
- val oldPackage = Ref<FqName>()
- val isJvmName = Ref<Boolean>(false)
+ val newPackagePrefix = testFile.path.substringAfter("testData/").replace("""[\\\-./]""".toRegex(), "_")
val testFiles = module.files
val isSingle = testFiles.size == 1
val resultFiles = testFiles.map {
val fileName = if (isSingle) it.name else testFile.name.substringBeforeLast(".kt") + "/" + it.name
- val content = services.sourceFileProvider.getContentOfSourceFile(it)
+ val (textChangedPackage, oldPackage, isJvmName) = changePackage(
+ newPackagePrefix = newPackagePrefix,
+ text = services.sourceFileProvider.getContentOfSourceFile(it)
+ )
TestClassInfo(
fileName,
- changePackage(newPackagePrefix, content, oldPackage, isJvmName),
- oldPackage.get(),
- isJvmName.get(),
- getGeneratedClassName(File(fileName), content, newPackagePrefix, oldPackage.get())
+ textChangedPackage,
+ oldPackage,
+ isJvmName,
+ getGeneratedClassName(File(fileName), textChangedPackage, newPackagePrefix, oldPackage)
)
}
val packages =
@@ -111,7 +111,7 @@
}
}
- val boxFiles = resultFiles.filter { hasBoxMethod(it.content) }
+ val boxFiles = resultFiles.filter { it.content.contains("fun box()") }
if (boxFiles.size != 1) {
println("Several box methods in $testFile")
}
@@ -124,31 +124,25 @@
return boxFiles.last().newPackagePartClassId
}
-private fun hasBoxMethod(text: String): Boolean {
- return text.contains("fun box()")
-}
-
class TestClassInfo(val name: String, var content: String, val oldPackage: FqName, val isJvmName: Boolean, val newPackagePartClassId: FqName) {
val newPackage = newPackagePartClassId.parent()
}
+private data class ChangePackageResult(val text: String, val oldPackage: FqName, val isJvmName: Boolean)
-private fun changePackage(newPackagePrefix: String, text: String, oldPackage: Ref<FqName>, isJvmName: Ref<Boolean>): String {
+private fun changePackage(newPackagePrefix: String, text: String): ChangePackageResult {
val matcher = packagePattern.matcher(text)
if (matcher.find()) {
val oldPackageName = matcher.toMatchResult().group(1)
- oldPackage.set(FqName(oldPackageName))
- return matcher.replaceAll("package $newPackagePrefix.$oldPackageName")
+ return ChangePackageResult(matcher.replaceAll("package $newPackagePrefix.$oldPackageName"), FqName(oldPackageName), false)
} else {
- oldPackage.set(FqName.ROOT)
val packageDirective = "package $newPackagePrefix;\n"
if (text.contains("@file:")) {
val index = text.lastIndexOf("@file:")
val packageDirectiveIndex = text.indexOf("\n", index)
- isJvmName.set(true)
- return text.substring(0, packageDirectiveIndex + 1) + packageDirective + text.substring(packageDirectiveIndex + 1)
+ return ChangePackageResult(text.substring(0, packageDirectiveIndex + 1) + packageDirective + text.substring(packageDirectiveIndex + 1), FqName.ROOT, true)
} else {
- return packageDirective + text
+ return ChangePackageResult(packageDirective + text, FqName.ROOT, false)
}
}
}
diff --git a/compiler/android-tests/tests/org/jetbrains/kotlin/android/tests/CodegenTestsOnAndroidGenerator.kt b/compiler/android-tests/tests/org/jetbrains/kotlin/android/tests/CodegenTestsOnAndroidGenerator.kt
index b3b3b3b..e386be0 100644
--- a/compiler/android-tests/tests/org/jetbrains/kotlin/android/tests/CodegenTestsOnAndroidGenerator.kt
+++ b/compiler/android-tests/tests/org/jetbrains/kotlin/android/tests/CodegenTestsOnAndroidGenerator.kt
@@ -6,16 +6,13 @@
package org.jetbrains.kotlin.android.tests
import com.intellij.openapi.util.Disposer
-import com.intellij.openapi.util.SystemInfo
import com.intellij.openapi.util.io.FileUtil
import com.intellij.openapi.util.io.FileUtilRt
import org.jetbrains.kotlin.cli.common.output.writeAllTo
import org.jetbrains.kotlin.cli.jvm.compiler.EnvironmentConfigFiles
import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment
-import org.jetbrains.kotlin.cli.jvm.config.configureJdkClasspathRoots
import org.jetbrains.kotlin.codegen.CodegenTestFiles
import org.jetbrains.kotlin.codegen.GenerationUtils
-import org.jetbrains.kotlin.codegen.forTestCompile.ForTestCompileRuntime
import org.jetbrains.kotlin.config.CommonConfigurationKeys
import org.jetbrains.kotlin.config.CompilerConfiguration
import org.jetbrains.kotlin.config.JvmTarget
@@ -31,7 +28,6 @@
import org.jetbrains.kotlin.test.model.ResultingArtifact
import org.jetbrains.kotlin.test.model.TestFile
import org.jetbrains.kotlin.test.runners.AbstractKotlinCompilerTest
-import org.jetbrains.kotlin.test.utils.TransformersFunctions.Android
import org.jetbrains.kotlin.test.services.*
import org.jetbrains.kotlin.test.services.configuration.CommonEnvironmentConfigurator
import org.jetbrains.kotlin.test.services.configuration.JvmEnvironmentConfigurator
@@ -39,154 +35,76 @@
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.junit.Assert
+import org.jetbrains.kotlin.test.utils.TransformersFunctions.Android
import java.io.File
-import java.io.FileWriter
import java.io.IOException
-import kotlin.io.path.ExperimentalPathApi
-import kotlin.io.path.Path
-import kotlin.io.path.createTempDirectory
-import kotlin.test.assertTrue
-
-data class ConfigurationKey(val kind: ConfigurationKind, val jdkKind: TestJdkKind, val configuration: String)
class CodegenTestsOnAndroidGenerator private constructor(private val pathManager: PathManager) {
private var currentModuleIndex = 1
private val pathFilter: String? = System.getProperties().getProperty("kotlin.test.android.path.filter")
- private val pendingUnitTestGenerators = hashMapOf<String, UnitTestFileWriter>()
+ private val pendingTestSourceFileGenerators = hashMapOf<String, TestSourceFileGenerator>()
//keep it globally to avoid test grouping on TC
private val generatedTestNames = hashSetOf<String>()
- private val COMMON = FlavorConfig(TargetBackend.ANDROID,"common", 4)
- private val REFLECT = FlavorConfig(TargetBackend.ANDROID, "reflect", 1)
+ private val common = FlavorConfig(TargetBackend.ANDROID, "common", 4)
+ private val reflect = FlavorConfig(TargetBackend.ANDROID, "reflect")
+ private val commonIr = FlavorConfig(TargetBackend.ANDROID_IR, "common_ir", 4)
+ private val reflectIr = FlavorConfig(TargetBackend.ANDROID_IR, "reflect_ir")
- private val COMMON_IR = FlavorConfig(TargetBackend.ANDROID_IR, "common_ir", 4)
- private val REFLECT_IR = FlavorConfig(TargetBackend.ANDROID_IR,"reflect_ir", 1)
-
- class FlavorConfig(private val backend: TargetBackend, private val prefix: String, val limit: Int) {
-
+ class FlavorConfig(private val backend: TargetBackend, private val prefix: String, private val limit: Int = 1) {
private var writtenFilesCount = 0
fun printStatistics() {
println("FlavorTestCompiler for $backend: $prefix, generated file count: $writtenFilesCount")
}
- fun getFlavorForNewFiles(newFilesCount: Int): String {
+ fun getFlavorNameForNewFiles(newFilesCount: Int): String {
writtenFilesCount += newFilesCount
- //2500 files per folder that would be used by flavor to avoid multidex usage,
- // each folder would be jared by build.gradle script
+ // Allocating up to 2500 files per folder should be fine for each app flavor,
+ // thus avoiding the need for multidex, which is necessary when there are more than 64K methods.
+ // Each folder will be archived using build.gradle.kts.
val index = writtenFilesCount / 2500
-
- return getFlavorName(index, prefix).also {
- assertTrue("Please Add new flavor in build.gradle for $it") { index < limit }
- }
+ val name = "$prefix$index"
+ check(index < limit) { "Please add a new flavor in build.gradle for $name" }
+ return name
}
-
- private fun getFlavorName(index: Int, prefix: String): String {
- return prefix + index
- }
-
- }
-
- private fun prepareAndroidModuleAndGenerateTests(skipSdkDirWriting: Boolean) {
- prepareAndroidModule(skipSdkDirWriting)
- generateTestsAndFlavourSuites()
- }
-
- private fun prepareAndroidModule(skipSdkDirWriting: Boolean) {
- FileUtil.copyDir(File(pathManager.androidModuleRoot), File(pathManager.tmpFolder))
- if (!skipSdkDirWriting) {
- writeAndroidSkdToLocalProperties(pathManager)
- }
-
- println("Copying kotlin-stdlib.jar and kotlin-reflect.jar in android module...")
- copyKotlinRuntimeJars()
- copyGradleWrapperAndPatch()
- }
-
- private fun copyGradleWrapperAndPatch() {
- val projectRoot = File(pathManager.tmpFolder)
- val target = File(projectRoot, "gradle/wrapper")
- File("./gradle/wrapper/").copyRecursively(target)
- val gradlew = File(projectRoot, "gradlew")
- File("./gradlew").copyTo(gradlew).also {
- if (!SystemInfo.isWindows) {
- it.setExecutable(true)
- }
- }
- File("./gradlew.bat").copyTo(File(projectRoot, "gradlew.bat"))
- val file = File(target, "gradle-wrapper.properties")
- file.readLines().map {
- when {
- it.startsWith("distributionUrl") -> "distributionUrl=https\\://services.gradle.org/distributions/gradle-$GRADLE_VERSION-bin.zip"
- it.startsWith("distributionSha256Sum") -> "distributionSha256Sum=$GRADLE_SHA_256"
- else -> it
- }
- }.let { lines ->
- FileWriter(file).use { fw ->
- lines.forEach { line ->
- fw.write("$line\n")
- }
- }
- }
- }
-
-
- private fun copyKotlinRuntimeJars() {
- FileUtil.copy(
- ForTestCompileRuntime.runtimeJarForTests(),
- File(pathManager.libsFolderInAndroidTmpFolder + "/kotlin-stdlib.jar")
- )
- FileUtil.copy(
- ForTestCompileRuntime.reflectJarForTests(),
- File(pathManager.libsFolderInAndroidTmpFolder + "/kotlin-reflect.jar")
- )
-
- FileUtil.copy(
- ForTestCompileRuntime.kotlinTestJarForTests(),
- File(pathManager.libsFolderInAndroidTmpFolder + "/kotlin-test.jar")
- )
}
private fun generateTestsAndFlavourSuites() {
- println("Generating test files...")
-
- val folders = arrayOf(
- File("compiler/testData/codegen/box"),
- File("compiler/testData/codegen/boxInline")
- )
+ println("Clearing destination folder")
+ pathManager.prepareDestinationFolder()
+ println("Generating test files")
generateTestMethodsForDirectories(
TargetBackend.ANDROID,
- COMMON,
- REFLECT,
- *folders
+ common,
+ reflect,
+ pathManager.testDataDirectories
)
generateTestMethodsForDirectories(
TargetBackend.ANDROID_IR,
- COMMON_IR,
- REFLECT_IR,
- *folders
+ commonIr,
+ reflectIr,
+ pathManager.testDataDirectories
)
- pendingUnitTestGenerators.values.forEach { it.generate() }
+ pendingTestSourceFileGenerators.values.forEach { it.generate() }
}
private fun generateTestMethodsForDirectories(
backend: TargetBackend,
commonFlavor: FlavorConfig,
reflectionFlavor: FlavorConfig,
- vararg dirs: File
+ dirs: List<File>,
) {
val holders = mutableMapOf<ConfigurationKey, FilesWriter>()
for (dir in dirs) {
- val files = dir.listFiles() ?: error("Folder with testData is empty: ${dir.absolutePath}")
+ val files = dir.listFiles() ?: throw IOException("Cannot list files in $dir")
processFiles(files, holders, backend, commonFlavor, reflectionFlavor)
}
@@ -200,10 +118,10 @@
internal inner class FilesWriter(
private val flavorConfig: FlavorConfig,
- private val configuration: CompilerConfiguration
+ private val configuration: CompilerConfiguration,
) {
private val rawFiles = arrayListOf<TestClassInfo>()
- private val unitTestDescriptions = arrayListOf<TestInfo>()
+ private val testInfos = arrayListOf<TestInfo>()
private fun shouldWriteFilesOnDisk(): Boolean = rawFiles.size > 300
@@ -224,71 +142,62 @@
)
try {
- writeFiles(
+ compileAndWriteFiles(
rawFiles.map {
try {
CodegenTestFiles.create(it.name, it.content, environment.project).psiFile
} catch (e: Throwable) {
throw RuntimeException("Error on processing ${it.name}:\n${it.content}", e)
}
- }, environment, unitTestDescriptions
+ }, environment, testInfos
)
} finally {
rawFiles.clear()
- unitTestDescriptions.clear()
+ testInfos.clear()
Disposer.dispose(disposable)
}
}
- private fun writeFiles(
- filesToCompile: List<KtFile>,
+ private fun compileAndWriteFiles(
+ files: List<KtFile>,
environment: KotlinCoreEnvironment,
- unitTestDescriptions: ArrayList<TestInfo>
+ testInfos: List<TestInfo>
) {
- if (filesToCompile.isEmpty()) return
+ if (files.isEmpty()) return
- val flavorName = flavorConfig.getFlavorForNewFiles(filesToCompile.size)
+ val flavorName = flavorConfig.getFlavorNameForNewFiles(files.size)
- val outputDir = File(pathManager.getOutputForCompiledFiles(flavorName))
- println("Generating ${filesToCompile.size} files into ${outputDir.name}, configuration: '${environment.configuration}'...")
+ val outputDir = pathManager.prepareFlavorTestClassesDirectory(flavorName)
+ println("Generating ${files.size} files into ${outputDir.name}, configuration: '${environment.configuration}'...")
- val outputFiles = GenerationUtils.compileFiles(filesToCompile, environment).run { destroy(); factory }
-
- if (!outputDir.exists()) {
- outputDir.mkdirs()
+ val outputFiles = GenerationUtils.compileFiles(files, environment).run {
+ destroy()
+ factory
}
- Assert.assertTrue("Cannot create directory for compiled files", outputDir.exists())
- val unitTestFileWriter = pendingUnitTestGenerators.getOrPut(flavorName) {
- UnitTestFileWriter(
- getFlavorUnitTestFolder(flavorName),
+
+ val testSourceFileGenerator = pendingTestSourceFileGenerators.getOrPut(flavorName) {
+ TestSourceFileGenerator(
+ pathManager.prepareFlavorTestSourceDirectory(flavorName),
flavorName,
generatedTestNames
)
}
- unitTestFileWriter.addTests(unitTestDescriptions)
+ testSourceFileGenerator.addTests(testInfos)
outputFiles.writeAllTo(outputDir)
}
- private fun getFlavorUnitTestFolder(flavourName: String): String {
- return pathManager.srcFolderInAndroidTmpFolder +
- "/androidTest${flavourName.replaceFirstChar(Char::uppercaseChar)}/java/" +
- testClassPackage.replace(".", "/") + "/"
- }
-
- fun addTest(testFiles: List<TestClassInfo>, info: TestInfo) {
+ fun addTest(testFiles: Collection<TestClassInfo>, info: TestInfo) {
rawFiles.addAll(testFiles)
- unitTestDescriptions.add(info)
+ testInfos.add(info)
}
}
- @OptIn(TestInfrastructureInternals::class)
- @Throws(IOException::class)
private fun processFiles(
files: Array<File>,
holders: MutableMap<ConfigurationKey, FilesWriter>,
backend: TargetBackend,
commmonFlavor: FlavorConfig,
- reflectionFlavor: FlavorConfig
+ reflectionFlavor: FlavorConfig,
) {
holders.values.forEach {
it.writeFilesOnDiskIfNeeded()
@@ -296,10 +205,13 @@
for (file in files) {
if (file.isDirectory) {
- val listFiles = file.listFiles()
- if (listFiles != null) {
- processFiles(listFiles, holders, backend, commmonFlavor, reflectionFlavor)
- }
+ processFiles(
+ file.listFiles() ?: throw IOException("Cannot list files in $file"),
+ holders,
+ backend,
+ commmonFlavor,
+ reflectionFlavor
+ )
} else if (FileUtilRt.getExtension(file.name) != KotlinFileType.EXTENSION) {
// skip non kotlin files
} else {
@@ -324,64 +236,67 @@
//TODO support JvmPackageName
if (fullFileText.contains("@file:JvmPackageName(")) continue
+
// TODO: Support jvm assertions
if (fullFileText.contains("// ASSERTIONS_MODE: jvm")) continue
+
if (fullFileText.contains("// MODULE: ")) continue
+
+ // TODO: add && backend != TargetBackend.JVM_IR
if (fullFileText.contains("// IGNORE_BACKEND_K1")) continue
+
+ if (fullFileText.contains("// IGNORE_DEXING")) continue
val targets = InTextDirectivesUtils.findLinesWithPrefixesRemoved(fullFileText, "// JVM_TARGET:")
val isAtLeastJvm8Target = !targets.contains(JvmTarget.JVM_1_6.description)
- if (isAtLeastJvm8Target && fullFileText.contains("@Target(AnnotationTarget.TYPE)")) {
- //TODO: type annotations supported on sdk 26 emulator
- continue
- }
+ // TODO: type annotations are supported on Android SDK 26. A separate flavor can be created
+ if (isAtLeastJvm8Target && fullFileText.contains("@Target(AnnotationTarget.TYPE)")) continue
- // TODO: support SKIP_JDK6 on new platforms
+ // TODO: JDK 1.8 features are supported on Android SDK 26
if (fullFileText.contains("// SKIP_JDK6")) continue
- if (hasBoxMethod(fullFileText)) {
- val testConfiguration = createTestConfiguration(file, backend)
- val services = testConfiguration.testServices
+ if (!fullFileText.contains("fun box()")) continue
- val moduleStructure = try {
- testConfiguration.moduleStructureExtractor.splitTestDataByModules(
- file.path,
- testConfiguration.directives,
- ).also {
- services.register(TestModuleStructure::class, it)
- }
- } catch (e: ExceptionFromModuleStructureTransformer) {
- continue
+ val testConfiguration = createTestConfiguration(file, backend)
+ val services = testConfiguration.testServices
+
+ val moduleStructure = try {
+ testConfiguration.moduleStructureExtractor.splitTestDataByModules(
+ file.path,
+ testConfiguration.directives,
+ ).also {
+ services.register(TestModuleStructure::class, it)
}
- 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 configuratorForFlags = JvmEnvironmentConfigurator(services)
- with(configuratorForFlags) {
- val extractor = DirectiveToConfigurationKeyExtractor()
- extractor.provideConfigurationKeys()
- extractor.configure(keyConfiguration, module.directives)
- }
- val kind = JvmEnvironmentConfigurator.extractConfigurationKind(module.directives)
- val jdkKind = JvmEnvironmentConfigurator.extractJdkKind(module.directives)
-
- keyConfiguration.languageVersionSettings = module.languageVersionSettings
-
- val key = ConfigurationKey(kind, jdkKind, keyConfiguration.toString())
- val compiler = if (kind.withReflection) reflectionFlavor else commmonFlavor
- val compilerConfigurationProvider = services.compilerConfigurationProvider as CompilerConfigurationProviderImpl
- val filesHolder = holders.getOrPut(key) {
- FilesWriter(compiler, compilerConfigurationProvider.createCompilerConfiguration(module)).also {
- println("Creating new configuration by $key")
- }
- }
-
- patchFilesAndAddTest(file, module, services, filesHolder)
+ } 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 configuratorForFlags = JvmEnvironmentConfigurator(services)
+ with(configuratorForFlags) {
+ val extractor = DirectiveToConfigurationKeyExtractor()
+ extractor.provideConfigurationKeys()
+ extractor.configure(keyConfiguration, module.directives)
+ }
+ val kind = JvmEnvironmentConfigurator.extractConfigurationKind(module.directives)
+ val jdkKind = JvmEnvironmentConfigurator.extractJdkKind(module.directives)
+
+ keyConfiguration.languageVersionSettings = module.languageVersionSettings
+
+ val key = ConfigurationKey(kind, jdkKind, keyConfiguration.toString())
+ val compiler = if (kind.withReflection) reflectionFlavor else commmonFlavor
+ val compilerConfigurationProvider = services.compilerConfigurationProvider as CompilerConfigurationProviderImpl
+ val filesHolder = holders.getOrPut(key) {
+ println("Creating new configuration by $key")
+ FilesWriter(compiler, compilerConfigurationProvider.createCompilerConfiguration(module))
+ }
+
+ patchFilesAndAddTest(file, module, services, filesHolder)
}
}
}
@@ -433,42 +348,26 @@
}
companion object {
- const val GRADLE_VERSION = "6.8.1" // update GRADLE_SHA_256 on change
- const val GRADLE_SHA_256 = "fd591a34af7385730970399f473afabdb8b28d57fd97d6625c388d090039d6fd"
- const val testClassPackage = "org.jetbrains.kotlin.android.tests"
- const val testClassName = "CodegenTestCaseOnAndroid"
- const val baseTestClassPackage = "org.jetbrains.kotlin.android.tests"
- const val baseTestClassName = "AbstractCodegenTestCaseOnAndroid"
+ const val TEST_CLASS_PACKAGE = "org.jetbrains.kotlin.android.tests"
+ const val BASE_TEST_CLASS_PACKAGE = "org.jetbrains.kotlin.android.tests"
+ const val BASE_TEST_CLASS_NAME = "AbstractCodegenTestCaseOnAndroid"
-
- @JvmOverloads
- @JvmStatic
- @Throws(Throwable::class)
- fun generate(pathManager: PathManager, skipSdkDirWriting: Boolean = false) {
- CodegenTestsOnAndroidGenerator(pathManager).prepareAndroidModuleAndGenerateTests(skipSdkDirWriting)
- }
-
- private fun hasBoxMethod(text: String): Boolean {
- return text.contains("fun box()")
- }
-
- @Throws(IOException::class)
- internal fun writeAndroidSkdToLocalProperties(pathManager: PathManager) {
- val sdkRoot = KtTestUtil.getAndroidSdkSystemIndependentPath()
- println("Writing android sdk to local.properties: $sdkRoot")
- val file = File(pathManager.tmpFolder + "/local.properties")
- FileWriter(file).use { fw -> fw.write("sdk.dir=$sdkRoot") }
- }
-
- @OptIn(ExperimentalPathApi::class)
+ /**
+ * Generates Android test sources and classes.
+ *
+ * @param args The first argument is destination directory, the rest are test data directories to walk.
+ */
@JvmStatic
fun main(args: Array<String>) {
- val tmpFolder = createTempDirectory().toAbsolutePath().toString()
- println("Created temporary folder for android tests: $tmpFolder")
- val rootFolder = Path("").toAbsolutePath().toString()
- val pathManager = PathManager(rootFolder, tmpFolder)
- generate(pathManager, true)
- println("Android test project is generated into $tmpFolder folder")
+ val destinationDirectory = File(requireNotNull(args.getOrNull(0)) { "No destination directory provided" })
+ val testDataDirectories = args.drop(1).map(::File)
+ require(testDataDirectories.isNotEmpty()) { "No test data directories provided" }
+ val notTestData = testDataDirectories.filterNot { "testData" in it.path }
+ require(notTestData.isEmpty()) { "Directories unrelated to testData are provided: $notTestData" }
+ println("Generating Android te`st sources and classes to $destinationDirectory")
+ val pathManager = PathManager(destinationDirectory, testDataDirectories)
+ CodegenTestsOnAndroidGenerator(pathManager).generateTestsAndFlavourSuites()
+ println("Generated Android test sources and classes to $destinationDirectory")
}
}
}
diff --git a/compiler/android-tests/tests/org/jetbrains/kotlin/android/tests/CodegenTestsOnAndroidRunner.kt b/compiler/android-tests/tests/org/jetbrains/kotlin/android/tests/CodegenTestsOnAndroidRunner.kt
deleted file mode 100644
index 14562eb..0000000
--- a/compiler/android-tests/tests/org/jetbrains/kotlin/android/tests/CodegenTestsOnAndroidRunner.kt
+++ /dev/null
@@ -1,156 +0,0 @@
-/*
- * Copyright 2010-2015 JetBrains s.r.o.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.jetbrains.kotlin.android.tests
-
-import com.intellij.util.PlatformUtils
-import junit.framework.TestCase
-import junit.framework.TestSuite
-import org.jetbrains.kotlin.android.tests.emulator.Emulator
-import org.jetbrains.kotlin.android.tests.gradle.GradleRunner
-import org.junit.Assert
-import org.w3c.dom.Element
-import org.xml.sax.SAXException
-import java.io.File
-import java.io.IOException
-import javax.xml.parsers.DocumentBuilderFactory
-import javax.xml.parsers.ParserConfigurationException
-import kotlin.test.assertTrue
-
-class CodegenTestsOnAndroidRunner private constructor(private val pathManager: PathManager) {
-
- private val isTeamcity = System.getProperty("kotlin.test.android.teamcity") != null || System.getenv("TEAMCITY_VERSION") != null
-
- private fun runTestsInEmulator(): TestSuite {
- val rootSuite = TestSuite("Root")
-
- val emulatorType = if (isTeamcity) Emulator.ARM else Emulator.X86
- println("Using $emulatorType emulator!")
- val emulator = Emulator(pathManager, emulatorType)
- emulator.createEmulator()
-
- val gradleRunner = GradleRunner(pathManager)
- //old dex
- cleanAndBuildProject(gradleRunner)
-
- try {
- emulator.startEmulator()
-
- try {
- emulator.waitEmulatorStart()
-
- runTestsOnEmulator(gradleRunner, TestSuite("D8")).apply {
- rootSuite.addTest(this)
- }
- } catch (e: RuntimeException) {
- e.printStackTrace()
- throw e
- } finally {
- emulator.stopEmulator()
- }
- } catch (e: RuntimeException) {
- e.printStackTrace()
- throw e
- } finally {
- emulator.finishEmulatorProcesses()
- }
-
- return rootSuite
- }
-
- private fun processReport(rootSuite: TestSuite, resultOutput: String) {
- val reportFolder = File(flavorFolder())
- try {
- val folders = reportFolder.listFiles()
- assertTrue(folders != null && folders.isNotEmpty(), "No folders in ${reportFolder.path}")
-
- folders.forEach {
- assertTrue("${it.path} is not directory") { it.isDirectory }
- val isIr = it.name.contains("_ir")
- val testCases = parseSingleReportInFolder(it)
- testCases.forEach { aCase ->
- if (isIr) aCase.name += "_ir"
- rootSuite.addTest(aCase)
- }
- Assert.assertNotEquals("There is no test results in report", 0, testCases.size.toLong())
- }
- } catch (e: Throwable) {
- throw RuntimeException("Can't parse test results in $reportFolder\n$resultOutput", e)
- }
- }
-
-
- private fun flavorFolder() = pathManager.tmpFolder + "/build/test/results/connected/flavors"
-
- private fun runTestsOnEmulator(gradleRunner: GradleRunner, suite: TestSuite): TestSuite {
- val platformPrefixProperty = System.setProperty(PlatformUtils.PLATFORM_PREFIX_KEY, "Idea")
- try {
- val resultOutput = gradleRunner.connectedDebugAndroidTest()
- processReport(suite, resultOutput)
- return suite
- } finally {
- if (platformPrefixProperty != null) {
- System.setProperty(PlatformUtils.PLATFORM_PREFIX_KEY, platformPrefixProperty)
- } else {
- System.clearProperty(PlatformUtils.PLATFORM_PREFIX_KEY)
- }
- }
-
- }
-
- companion object {
-
- @JvmStatic
- fun runTestsInEmulator(pathManager: PathManager): TestSuite {
- return CodegenTestsOnAndroidRunner(pathManager).runTestsInEmulator()
- }
-
- private fun cleanAndBuildProject(gradleRunner: GradleRunner) {
- gradleRunner.clean()
- gradleRunner.assembleAndroidTest()
- }
-
- @Throws(IOException::class, SAXException::class, ParserConfigurationException::class)
- private fun parseSingleReportInFolder(folder: File): List<TestCase> {
- val files = folder.listFiles()!!
- assert(files.size == 1) {
- "Expecting one file but ${files.size}: ${files.joinToString { it.name }} in ${folder.path}"
- }
- val reportFile = files[0]
-
- val dbFactory = DocumentBuilderFactory.newInstance()
- val dBuilder = dbFactory.newDocumentBuilder()
- val doc = dBuilder.parse(reportFile)
- val root = doc.documentElement
- val testCases = root.getElementsByTagName("testcase")
-
- return (0 until testCases.length).map { i ->
- val item = testCases.item(i) as Element
- val failure = item.getElementsByTagName("failure").takeIf { it.length != 0 }?.item(0)
- val name = item.getAttribute("name")
-
- object : TestCase(name) {
- @Throws(Throwable::class)
- override fun runTest() {
- if (failure != null) {
- Assert.fail(failure.textContent)
- }
- }
- }
- }
- }
- }
-}
diff --git a/compiler/android-tests/tests/org/jetbrains/kotlin/android/tests/ConfigurationKey.kt b/compiler/android-tests/tests/org/jetbrains/kotlin/android/tests/ConfigurationKey.kt
new file mode 100644
index 0000000..4215274
--- /dev/null
+++ b/compiler/android-tests/tests/org/jetbrains/kotlin/android/tests/ConfigurationKey.kt
@@ -0,0 +1,11 @@
+/*
+ * Copyright 2010-2024 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.android.tests
+
+import org.jetbrains.kotlin.test.ConfigurationKind
+import org.jetbrains.kotlin.test.TestJdkKind
+
+data class ConfigurationKey(val kind: ConfigurationKind, val jdkKind: TestJdkKind, val configuration: String)
diff --git a/compiler/android-tests/tests/org/jetbrains/kotlin/android/tests/OutputUtils.java b/compiler/android-tests/tests/org/jetbrains/kotlin/android/tests/OutputUtils.java
deleted file mode 100644
index 69d2de3..0000000
--- a/compiler/android-tests/tests/org/jetbrains/kotlin/android/tests/OutputUtils.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Copyright 2010-2015 JetBrains s.r.o.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.jetbrains.kotlin.android.tests;
-
-import org.jetbrains.annotations.Nullable;
-import org.jetbrains.kotlin.android.tests.run.RunResult;
-
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-public class OutputUtils {
-
- private final static Pattern EMULATOR_PROCESS_PATTERN = Pattern.compile("\\w*[\\s]+([0-9]*) .* java .* emulator .*");
-
- public static boolean isBuildFailed(String output) {
- return output.contains("BUILD FAILED") || output.contains("Build failed");
- }
-
- public static void checkResult(RunResult result) {
- if (!result.getStatus()) {
- throw new RuntimeException(result.getOutput());
- }
- }
-
- @Nullable
- public static String getPidFromPsCommand(String output) {
- if (!output.isEmpty()) {
- Matcher matcher = EMULATOR_PROCESS_PATTERN.matcher(output);
- if (matcher.find()) {
- return matcher.group(1);
- }
- }
- return null;
- }
-
- private OutputUtils() {
- }
-}
diff --git a/compiler/android-tests/tests/org/jetbrains/kotlin/android/tests/PathManager.java b/compiler/android-tests/tests/org/jetbrains/kotlin/android/tests/PathManager.java
deleted file mode 100644
index 8c135fc..0000000
--- a/compiler/android-tests/tests/org/jetbrains/kotlin/android/tests/PathManager.java
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * Copyright 2010-2015 JetBrains s.r.o.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.jetbrains.kotlin.android.tests;
-
-import org.jetbrains.kotlin.test.util.KtTestUtil;
-
-import java.io.File;
-
-public class PathManager {
-
- private final String tmpFolder;
- private final String rootFolder;
-
- public PathManager(String rootFolder, String tmpFolder) {
- this.tmpFolder = tmpFolder;
- this.rootFolder = rootFolder;
- }
-
- public String getPlatformFolderInAndroidSdk() {
- return getAndroidSdkRoot() + "/platforms";
- }
-
- public String getAndroidAvdRoot() {
- String androidEmulatorRoot = getAndroidSdkRoot() + "/compiler_box_test_avd";
- new File(androidEmulatorRoot).mkdirs();
- return androidEmulatorRoot;
- }
-
- public String getPlatformToolsFolderInAndroidSdk() {
- return getAndroidSdkRoot() + "/platform-tools";
- }
-
- public String getToolsFolderInAndroidSdk() {
- return getAndroidSdkRoot() + "/tools";
- }
-
- public String getEmulatorFolderInAndroidSdk() {
- return getAndroidSdkRoot() + "/emulator";
- }
-
- public String getOutputForCompiledFiles(String flavor) {
- return tmpFolder + "/libs/" + flavor;
- }
-
- public String getLibsFolderInAndroidTmpFolder() {
- return tmpFolder + "/libs";
- }
-
- public String getSrcFolderInAndroidTmpFolder() {
- return tmpFolder + "/src";
- }
-
- public String getAndroidTmpFolder() {
- return tmpFolder;
- }
-
- public String getAndroidSdkRoot() {
- return KtTestUtil.getAndroidSdkSystemIndependentPath();
- }
-
- public String getAndroidModuleRoot() {
- return rootFolder + "/compiler/android-tests/android-module";
- }
-
- public String getTmpFolder() {
- return tmpFolder;
- }
-}
diff --git a/compiler/android-tests/tests/org/jetbrains/kotlin/android/tests/PathManager.kt b/compiler/android-tests/tests/org/jetbrains/kotlin/android/tests/PathManager.kt
new file mode 100644
index 0000000..6c191f7
--- /dev/null
+++ b/compiler/android-tests/tests/org/jetbrains/kotlin/android/tests/PathManager.kt
@@ -0,0 +1,64 @@
+/*
+ * Copyright 2010-2015 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jetbrains.kotlin.android.tests
+
+import java.io.File
+import java.io.IOException
+
+class PathManager(destinationDirectory: File, val testDataDirectories: List<File>) {
+ private val destinationTestClassesDirectory: File = destinationDirectory.resolve("test-classes")
+ private val destinationSrcDirectory: File = destinationDirectory.resolve("src")
+
+ fun prepareDestinationFolder() {
+ if (destinationTestClassesDirectory.isDirectory) {
+ destinationTestClassesDirectory.listFiles()!!
+ .forEach { it.deleteRecursively() }
+ } else if (!destinationTestClassesDirectory.mkdirs()) {
+ throw IOException("Unable to create directory for test classes: $destinationTestClassesDirectory")
+ }
+
+ if (destinationSrcDirectory.isDirectory) {
+ destinationSrcDirectory.listFiles()!!
+ .filter { it.name != "main" }
+ .forEach { it.deleteRecursively() }
+ } else if (!destinationSrcDirectory.mkdirs()) {
+ throw IOException("Unable to create directory for sources: $destinationSrcDirectory")
+ }
+ }
+
+ fun prepareFlavorTestClassesDirectory(flavor: String): File {
+ val directory = destinationTestClassesDirectory.resolve(flavor)
+
+ if (!directory.isDirectory && !directory.mkdirs()) {
+ throw IOException("Unable to create test output directory for flavor: $directory")
+ }
+
+ return directory
+ }
+
+ fun prepareFlavorTestSourceDirectory(flavorName: String): File {
+ val directory = destinationSrcDirectory.resolve(
+ "androidTest${flavorName.replaceFirstChar(Char::uppercaseChar)}/java/" +
+ CodegenTestsOnAndroidGenerator.TEST_CLASS_PACKAGE.replace(".", "/") + "/"
+ )
+
+ if (!directory.isDirectory && !directory.mkdirs()) {
+ throw IOException("Unable to create source directory for flavor: $directory")
+ }
+
+ return directory
+ }
+}
diff --git a/compiler/android-tests/tests/org/jetbrains/kotlin/android/tests/TestSourceFileGenerator.kt b/compiler/android-tests/tests/org/jetbrains/kotlin/android/tests/TestSourceFileGenerator.kt
new file mode 100644
index 0000000..843f0d8
--- /dev/null
+++ b/compiler/android-tests/tests/org/jetbrains/kotlin/android/tests/TestSourceFileGenerator.kt
@@ -0,0 +1,82 @@
+/*
+ * Copyright 2010-2019 JetBrains s.r.o. 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.android.tests
+
+import com.intellij.openapi.util.io.FileUtil
+import com.intellij.openapi.util.text.StringUtil
+import org.jetbrains.kotlin.generators.util.TestGeneratorUtil.getMainClassName
+import org.jetbrains.kotlin.name.FqName
+import org.jetbrains.kotlin.name.NameUtils
+import org.jetbrains.kotlin.utils.Printer
+import java.io.File
+
+class TestInfo(val name: String, val fqName: FqName, val file: File)
+
+class TestSourceFileGenerator(
+ private val flavorDirectory: File,
+ private val flavorName: String,
+ private val generatedTestNames: MutableSet<String>,
+) {
+ private val infos = arrayListOf<TestInfo>()
+
+ fun addTests(info: Collection<TestInfo>) {
+ infos.addAll(info)
+ }
+
+ fun generate() {
+ val sourceFile = flavorDirectory.resolve(flavorName.replaceFirstChar(Char::uppercaseChar) + ".java")
+ sourceFile.writer().use { suite ->
+ val p = Printer(suite)
+ p.println(
+ """package ${CodegenTestsOnAndroidGenerator.TEST_CLASS_PACKAGE};
+ |
+ |import ${CodegenTestsOnAndroidGenerator.BASE_TEST_CLASS_PACKAGE}.${CodegenTestsOnAndroidGenerator.BASE_TEST_CLASS_NAME};
+ |
+ |/* This class is generated by ${getMainClassName()}. DO NOT MODIFY MANUALLY */
+ |public class ${flavorName.replaceFirstChar(Char::uppercaseChar)} extends ${CodegenTestsOnAndroidGenerator.BASE_TEST_CLASS_NAME} {
+ |
+ """.trimMargin()
+ )
+ p.pushIndent()
+
+ for (info in infos) {
+ generateTestMethod(
+ p,
+ inventTestName(info.file.name),
+ info.fqName.asString(),
+ StringUtil.escapeStringCharacters(info.file.path)
+ )
+ }
+
+ p.popIndent()
+ p.println("}")
+ }
+ }
+
+ private fun inventTestName(fileName: String): String {
+ val baseName = NameUtils.sanitizeAsJavaIdentifier(FileUtil.getNameWithoutExtension(StringUtil.capitalize(fileName)))
+ var result = baseName
+ var i = 0
+
+ while (result in generatedTestNames) {
+ result = "${baseName}_${i}"
+ i++
+ }
+
+ generatedTestNames.add(result)
+ return result
+ }
+
+ private fun generateTestMethod(p: Printer, testName: String, className: String, filePath: String) {
+ p.println("public void test$testName() {")
+ p.pushIndent()
+ p.println("invokeBoxMethod($className.class, \"$filePath\", \"OK\");")
+ p.popIndent()
+ p.println("}")
+ p.println()
+ }
+
+}
\ No newline at end of file
diff --git a/compiler/android-tests/tests/org/jetbrains/kotlin/android/tests/UnitTestFileWriter.kt b/compiler/android-tests/tests/org/jetbrains/kotlin/android/tests/UnitTestFileWriter.kt
deleted file mode 100644
index c72304c..0000000
--- a/compiler/android-tests/tests/org/jetbrains/kotlin/android/tests/UnitTestFileWriter.kt
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * Copyright 2010-2019 JetBrains s.r.o. 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.android.tests
-
-import com.intellij.openapi.util.io.FileUtil
-import com.intellij.openapi.util.text.StringUtil
-import org.jetbrains.kotlin.generators.util.TestGeneratorUtil.getMainClassName
-import org.jetbrains.kotlin.name.FqName
-import org.jetbrains.kotlin.name.NameUtils
-import org.jetbrains.kotlin.utils.Printer
-import java.io.File
-import java.io.FileWriter
-
-class TestInfo(val name: String, val fqName: FqName, val file: File)
-
-class UnitTestFileWriter(
- private val flavourFolder: String,
- private val flavourName: String,
- private val generatedTestNames: MutableSet<String>
-) {
- private val infos = arrayListOf<TestInfo>()
-
- fun addTests(info: List<TestInfo>) {
- infos.addAll(info)
- }
-
- fun generate() {
- FileWriter(File(flavourFolder, flavourName.replaceFirstChar(Char::uppercaseChar) + ".java").also { it.parentFile.mkdirs() }).use { suite ->
- val p = Printer(suite)
- p.println(
- """package ${CodegenTestsOnAndroidGenerator.testClassPackage};
- |
- |import ${CodegenTestsOnAndroidGenerator.baseTestClassPackage}.${CodegenTestsOnAndroidGenerator.baseTestClassName};
- |
- |/* This class is generated by ${getMainClassName()}. DO NOT MODIFY MANUALLY */
- |public class ${flavourName.replaceFirstChar(Char::uppercaseChar)} extends ${CodegenTestsOnAndroidGenerator.baseTestClassName} {
- |
- """.trimMargin()
- )
- p.pushIndent()
-
- infos.forEach { info ->
- generateTestMethod(
- p,
- generateTestName(info.file.name),
- info.fqName.asString(),
- StringUtil.escapeStringCharacters(info.file.path)
- )
- }
-
- p.popIndent()
- p.println("}")
- }
- }
-
- private fun generateTestName(fileName: String): String {
- var result = NameUtils.sanitizeAsJavaIdentifier(FileUtil.getNameWithoutExtension(StringUtil.capitalize(fileName)))
-
- var i = 0
- while (generatedTestNames.contains(result)) {
- result += "_" + i++
- }
- generatedTestNames.add(result)
- return result
- }
-
- private fun generateTestMethod(p: Printer, testName: String, className: String, filePath: String) {
- p.println("public void test$testName() throws Exception {")
- p.pushIndent()
- p.println("invokeBoxMethod($className.class, \"$filePath\", \"OK\");")
- p.popIndent()
- p.println("}")
- p.println()
- }
-
-}
\ No newline at end of file
diff --git a/compiler/android-tests/tests/org/jetbrains/kotlin/android/tests/emulator/Emulator.java b/compiler/android-tests/tests/org/jetbrains/kotlin/android/tests/emulator/Emulator.java
deleted file mode 100644
index d14a7ca..0000000
--- a/compiler/android-tests/tests/org/jetbrains/kotlin/android/tests/emulator/Emulator.java
+++ /dev/null
@@ -1,276 +0,0 @@
-/*
- * Copyright 2010-2015 JetBrains s.r.o.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.jetbrains.kotlin.android.tests.emulator;
-
-import com.intellij.execution.configurations.GeneralCommandLine;
-import com.intellij.openapi.util.SystemInfo;
-import com.intellij.openapi.util.text.StringUtil;
-import org.jetbrains.annotations.Nullable;
-import org.jetbrains.kotlin.android.tests.OutputUtils;
-import org.jetbrains.kotlin.android.tests.PathManager;
-import org.jetbrains.kotlin.android.tests.run.RunResult;
-import org.jetbrains.kotlin.android.tests.run.RunUtils;
-import org.junit.Assert;
-
-import java.util.List;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-public class Emulator {
-
- public static final String ARM = "arm";
- public static final String X86 = "x86";
- private static final String AVD_NAME = "kotlin_box_test_avd";
-
- private final static Pattern EMULATOR_PATTERN = Pattern.compile("emulator-([0-9])*");
-
- private final PathManager pathManager;
- private final String platform;
-
- public Emulator(PathManager pathManager, String platform) {
- this.pathManager = pathManager;
- this.platform = platform;
- }
-
- private GeneralCommandLine getCreateCommand() {
- GeneralCommandLine commandLine = new GeneralCommandLine();
- String androidCmdName = SystemInfo.isWindows ? "avdmanager.bat" : "avdmanager";
- commandLine.setExePath(pathManager.getToolsFolderInAndroidSdk() + "/bin/" + androidCmdName);
- commandLine.addParameter("create");
- commandLine.addParameter("avd");
- commandLine.addParameter("--force");
- commandLine.addParameter("-n");
- commandLine.addParameter(AVD_NAME);
- commandLine.addParameter("-p");
- commandLine.addParameter(pathManager.getAndroidAvdRoot());
- commandLine.addParameter("-k");
- if (platform == X86) {
- commandLine.addParameter("system-images;android-19;default;x86");
- } else {
- commandLine.addParameter("system-images;android-19;default;armeabi-v7a");
- }
- return commandLine;
- }
-
- private GeneralCommandLine getStartCommand() {
- GeneralCommandLine commandLine = new GeneralCommandLine();
- commandLine.setExePath(pathManager.getEmulatorFolderInAndroidSdk() + "/" + "emulator");
- commandLine.addParameter("-avd");
- commandLine.addParameter(AVD_NAME);
- commandLine.addParameter("-no-audio");
- commandLine.addParameter("-no-window");
- return commandLine;
- }
-
- private GeneralCommandLine getWaitCommand() {
- GeneralCommandLine commandLine = createAdbCommand();
- commandLine.addParameter("wait-for-device");
- return commandLine;
- }
-
- private GeneralCommandLine getStopCommandForAdb() {
- GeneralCommandLine commandLine = createAdbCommand();
- commandLine.addParameter("kill-server");
- return commandLine;
- }
-
- @Nullable
- private GeneralCommandLine getStopCommand() {
- if (SystemInfo.isWindows) {
- GeneralCommandLine commandLine = new GeneralCommandLine();
- commandLine.setExePath("taskkill");
- commandLine.addParameter("/F");
- commandLine.addParameter("/IM");
- commandLine.addParameter("emulator-" + platform + ".exe");
- return commandLine;
- }
- return null;
- }
-
- public void createEmulator() {
- System.out.println("Creating emulator...");
- OutputUtils.checkResult(RunUtils.execute(new RunUtils.RunSettings(getCreateCommand(), "no", true, null, false)));
- }
-
- private GeneralCommandLine createAdbCommand() {
- GeneralCommandLine commandLine = new GeneralCommandLine();
- commandLine.setExePath(pathManager.getPlatformToolsFolderInAndroidSdk() + "/" + "adb");
- return commandLine;
- }
-
- public void startServer() {
- GeneralCommandLine commandLine = createAdbCommand();
- commandLine.addParameter("start-server");
- System.out.println("Start adb server...");
- OutputUtils.checkResult(RunUtils.execute(new RunUtils.RunSettings(commandLine, null, true, "ADB START:", true)));
- }
-
- public void startEmulator() {
- startServer();
- System.out.println("Starting emulator with ANDROID_HOME/ANDROID_SDK_ROOT: " + pathManager.getAndroidSdkRoot());
- GeneralCommandLine startCommand = getStartCommand();
- startCommand.withEnvironment("ANDROID_SDK_ROOT", pathManager.getAndroidSdkRoot());
- startCommand.withEnvironment("ANDROID_HOME", pathManager.getAndroidSdkRoot());
- RunUtils.executeOnSeparateThread(new RunUtils.RunSettings(startCommand, null, false, "START: ", true));
- printLog();
- }
-
- public void printLog() {
- GeneralCommandLine commandLine = createAdbCommand();
- commandLine.addParameter("logcat");
- commandLine.addParameter("-v");
- commandLine.addParameter("time");
- commandLine.addParameter("-s");
- commandLine.addParameter("dalvikvm:W");
- commandLine.addParameter("TestRunner:I");
- RunUtils.executeOnSeparateThread(new RunUtils.RunSettings(commandLine, null, false, "LOGCAT: ", true));
- }
-
- public void waitEmulatorStart() {
- System.out.println("Waiting for emulator start...");
- OutputUtils.checkResult(RunUtils.execute(getWaitCommand()));
- GeneralCommandLine bootCheckCommand = createAdbCommand();
- bootCheckCommand.addParameter("shell");
- bootCheckCommand.addParameter("getprop");
- bootCheckCommand.addParameter("sys.boot_completed");
-
- int counter = 0;
- RunResult execute = RunUtils.execute(bootCheckCommand);
- while (counter < 20) {
- String output = execute.getOutput();
- if (output.trim().endsWith("1")) {
- System.out.println("Emulator fully booted!");
- return;
- }
- System.out.println("Waiting for emulator boot (" + counter + ")...");
- try {
- Thread.sleep(10000);
- }
- catch (InterruptedException e) {
- e.printStackTrace();
- }
- counter++;
- execute = RunUtils.execute(bootCheckCommand);
- }
- Assert.fail("Can't find booted emulator: " + execute.getOutput());
- }
-
- public void stopEmulator() {
- System.out.println("Stopping emulator...");
-
- GeneralCommandLine command = createAdbCommand();
- command.addParameter("-s");
- command.addParameter("emulator-5554");
- command.addParameter("emu");
- command.addParameter("kill");
- RunUtils.execute(command);
-
- finishProcess("emulator64-" + platform);
- finishProcess("emulator-" + platform);
- }
-
- //Only for Unix
- private static void stopDdmsProcess() {
- if (SystemInfo.isUnix) {
- GeneralCommandLine listOfEmulatorProcess = new GeneralCommandLine();
- listOfEmulatorProcess.setExePath("sh");
- listOfEmulatorProcess.addParameter("-c");
- listOfEmulatorProcess.addParameter("ps aux | grep emulator");
- RunResult runResult = RunUtils.execute(listOfEmulatorProcess);
- OutputUtils.checkResult(runResult);
- String pidFromPsCommand = OutputUtils.getPidFromPsCommand(runResult.getOutput());
- if (pidFromPsCommand != null) {
- GeneralCommandLine killCommand = new GeneralCommandLine();
- killCommand.setExePath("kill");
- killCommand.addParameter(pidFromPsCommand);
- RunUtils.execute(killCommand);
- }
- }
- }
-
- public void finishEmulatorProcesses() {
- System.out.println("Stopping adb...");
- OutputUtils.checkResult(RunUtils.execute(getStopCommandForAdb()));
- finishProcess("adb");
- stopDdmsProcess();
- }
-
- //Only for Unix
- private static void finishProcess(String processName) {
- if (SystemInfo.isUnix) {
- GeneralCommandLine pidOfProcess = new GeneralCommandLine();
- pidOfProcess.setExePath("pidof");
- pidOfProcess.addParameter(processName);
- RunResult runResult = RunUtils.execute(pidOfProcess);
- String processIdsStr = runResult.getOutput().substring(("pidof " + processName).length());
- List<String> processIds = StringUtil.getWordsIn(processIdsStr);
- for (String pid : processIds) {
- GeneralCommandLine killCommand = new GeneralCommandLine();
- killCommand.setExePath("kill");
- killCommand.addParameter("-s");
- killCommand.addParameter("9");
- killCommand.addParameter(pid);
- RunUtils.execute(killCommand);
- }
- }
- }
-
- public String runTestsViaAdb() {
- System.out.println("Running tests via adb...");
- GeneralCommandLine adbCommand = createAdbCommand();
- //adb shell am instrument -w -r org.jetbrains.kotlin.android.tests/android.test.InstrumentationTestRunner
- adbCommand.addParameters("shell", "am", "instrument", "-w", "-r", "org.jetbrains.kotlin.android.tests/android.test.InstrumentationTestRunner");
- RunResult execute = RunUtils.execute(adbCommand);
- return execute.getOutput();
- }
-
- private void stopRedundantEmulators(PathManager pathManager) {
- GeneralCommandLine commandLineForListOfDevices = createAdbCommand();
- commandLineForListOfDevices.addParameter("devices");
- RunResult runResult = RunUtils.execute(commandLineForListOfDevices);
- OutputUtils.checkResult(runResult);
-
- Matcher matcher = EMULATOR_PATTERN.matcher(runResult.getOutput());
- boolean isDdmsStopped = false;
- while (matcher.find()) {
- System.out.println("Stopping redundant emulator...");
- GeneralCommandLine commandLineForStoppingEmulators = new GeneralCommandLine();
- if (SystemInfo.isWindows) {
- commandLineForStoppingEmulators.setExePath("taskkill");
- commandLineForStoppingEmulators.addParameter("/F");
- commandLineForStoppingEmulators.addParameter("/IM");
- commandLineForStoppingEmulators.addParameter("emulator-arm.exe");
- OutputUtils.checkResult(RunUtils.execute(commandLineForStoppingEmulators));
- break;
- }
- else {
- if (!isDdmsStopped && SystemInfo.isUnix) {
- stopEmulator();
- stopDdmsProcess();
- isDdmsStopped = true;
- }
- commandLineForStoppingEmulators.setExePath(pathManager.getPlatformToolsFolderInAndroidSdk() + "/adb");
- commandLineForStoppingEmulators.addParameter("-s");
- commandLineForStoppingEmulators.addParameter(matcher.group());
- commandLineForStoppingEmulators.addParameter("emu");
- commandLineForStoppingEmulators.addParameter("kill");
- OutputUtils.checkResult(RunUtils.execute(commandLineForStoppingEmulators));
- }
- }
- OutputUtils.checkResult(RunUtils.execute(commandLineForListOfDevices));
- }
-}
diff --git a/compiler/android-tests/tests/org/jetbrains/kotlin/android/tests/gradle/GradleRunner.java b/compiler/android-tests/tests/org/jetbrains/kotlin/android/tests/gradle/GradleRunner.java
deleted file mode 100644
index e773925..0000000
--- a/compiler/android-tests/tests/org/jetbrains/kotlin/android/tests/gradle/GradleRunner.java
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * Copyright 2010-2016 JetBrains s.r.o.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.jetbrains.kotlin.android.tests.gradle;
-
-import com.intellij.execution.configurations.GeneralCommandLine;
-import com.intellij.openapi.util.SystemInfo;
-import org.jetbrains.kotlin.android.tests.OutputUtils;
-import org.jetbrains.kotlin.android.tests.PathManager;
-import org.jetbrains.kotlin.android.tests.run.RunResult;
-import org.jetbrains.kotlin.android.tests.run.RunUtils;
-
-import java.util.ArrayList;
-import java.util.List;
-
-public class GradleRunner {
- private final List<String> listOfCommands;
-
- public GradleRunner(PathManager pathManager) {
- listOfCommands = new ArrayList<>();
- String cmdName = SystemInfo.isWindows ? "gradlew.bat" : "gradlew";
- listOfCommands.add(pathManager.getTmpFolder() + "/" + cmdName);
- listOfCommands.add("--no-daemon");
- listOfCommands.add("--build-file");
- listOfCommands.add(pathManager.getTmpFolder() + "/build.gradle");
- }
-
-
- public void clean() {
- System.out.println("Building gradle project...");
- RunResult result = RunUtils.execute(generateCommandLine("clean"));
- OutputUtils.checkResult(result);
- }
-
- public void assembleAndroidTest() {
- System.out.println("Building gradle project...");
- GeneralCommandLine build = generateCommandLine("assembleAndroidTest");
- build.addParameter("--stacktrace");
- build.addParameter("--warn");
- RunResult result = RunUtils.execute(build);
- OutputUtils.checkResult(result);
- }
-
- public void installDebugAndroidTest() {
- System.out.println("Install tests...");
- OutputUtils.checkResult(RunUtils.execute(generateCommandLine("installDebug")));
- OutputUtils.checkResult(RunUtils.execute(generateCommandLine("installDebugAndroidTest")));
- }
-
- public void uninstallDebugAndroidTest() {
- System.out.println("Uninstall tests...");
- RunUtils.execute(generateCommandLine("uninstallDebugAndroidTest"));
- RunUtils.execute(generateCommandLine("uninstallDebug"));
- }
-
- public String connectedDebugAndroidTest() {
- System.out.println("Starting tests...");
- GeneralCommandLine test = generateCommandLine("connectedAndroidTest");
- test.addParameters("--stacktrace");
- test.addParameters("--continue"); //run all flavors even if any fail
- return RunUtils.execute(test).getOutput();
- }
-
- private GeneralCommandLine generateCommandLine(String taskName) {
- GeneralCommandLine commandLine = new GeneralCommandLine(listOfCommands);
- commandLine.addParameter(taskName);
- return commandLine;
- }
-}
diff --git a/compiler/android-tests/tests/org/jetbrains/kotlin/android/tests/run/RunResult.java b/compiler/android-tests/tests/org/jetbrains/kotlin/android/tests/run/RunResult.java
deleted file mode 100644
index 6db84cd..0000000
--- a/compiler/android-tests/tests/org/jetbrains/kotlin/android/tests/run/RunResult.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright 2010-2015 JetBrains s.r.o.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.jetbrains.kotlin.android.tests.run;
-
-public class RunResult {
- private final boolean status;
- private final String output;
-
- public RunResult(boolean ok, String output) {
- this.status = ok;
- this.output = output;
- }
-
- //true - ok
- //false - fail
- public boolean getStatus() {
- return status;
- }
-
- public String getOutput() {
- return output;
- }
-}
diff --git a/compiler/android-tests/tests/org/jetbrains/kotlin/android/tests/run/RunUtils.java b/compiler/android-tests/tests/org/jetbrains/kotlin/android/tests/run/RunUtils.java
deleted file mode 100644
index 2169759..0000000
--- a/compiler/android-tests/tests/org/jetbrains/kotlin/android/tests/run/RunUtils.java
+++ /dev/null
@@ -1,221 +0,0 @@
-/*
- * Copyright 2010-2015 JetBrains s.r.o.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.jetbrains.kotlin.android.tests.run;
-
-import com.google.common.base.Charsets;
-import com.intellij.execution.ExecutionException;
-import com.intellij.execution.configurations.GeneralCommandLine;
-import com.intellij.execution.process.OSProcessHandler;
-import com.intellij.execution.process.ProcessAdapter;
-import com.intellij.execution.process.ProcessEvent;
-import com.intellij.execution.process.ProcessOutputTypes;
-import com.intellij.openapi.util.Key;
-import com.intellij.openapi.util.text.StringUtil;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-import org.jetbrains.kotlin.android.tests.OutputUtils;
-
-import java.io.Closeable;
-import java.io.IOException;
-import java.io.PrintWriter;
-import java.io.StringWriter;
-
-public class RunUtils {
- private RunUtils() {
- }
-
- public static class RunSettings {
- public final GeneralCommandLine commandLine;
- public final String input;
- public final boolean waitForEnd;
- public final String outputPrefix;
- public final boolean printOutputAtAppearance;
-
- public RunSettings(
- GeneralCommandLine commandLine,
- @Nullable String input,
- boolean waitForEnd,
- @Nullable String outputPrefix,
- boolean printOutputAtAppearance
- ) {
- this.commandLine = commandLine;
- this.input = input;
- this.waitForEnd = waitForEnd;
- this.outputPrefix = outputPrefix;
- this.printOutputAtAppearance = printOutputAtAppearance;
- }
-
- public RunSettings(GeneralCommandLine commandLine) {
- this.commandLine = commandLine;
- this.input = null;
- this.waitForEnd = true;
- this.outputPrefix = null;
- this.printOutputAtAppearance = false;
- }
-
- @Override
- public String toString() {
- return "commandLine=" + commandLine.getCommandLineString() + " " +
- "input=" + input + " " +
- "waitForEnd=" + waitForEnd + " " +
- "outputPrefix=" + outputPrefix + " " +
- "printOutputAtAppearance=" + printOutputAtAppearance + " ";
- }
- }
-
- public static RunResult execute(@NotNull GeneralCommandLine commandLine) {
- return run(new RunSettings(commandLine));
- }
-
- public static RunResult execute(@NotNull RunSettings settings) {
- assert settings.waitForEnd : "Use executeOnSeparateThread() instead";
- return run(settings);
- }
-
- public static void executeOnSeparateThread(@NotNull RunSettings settings) {
- assert !settings.waitForEnd : "Use execute() instead";
- new Thread(() -> run(settings)).start();
- }
-
- private static RunResult run(RunSettings settings) {
- System.out.println("RUN COMMAND: " + settings);
- StringBuilder stdOut = new StringBuilder();
- StringBuilder stdErr = new StringBuilder();
-
- OSProcessHandler handler;
- try {
- handler = new OSProcessHandler(settings.commandLine.createProcess(), settings.commandLine.getCommandLineString(), Charsets.UTF_8);
- if (settings.input != null) {
- handler.getProcessInput().write(settings.input.getBytes());
- }
- close(handler.getProcessInput());
- }
- catch (ExecutionException | IOException e) {
- return new RunResult(false, getStackTrace(e));
- }
-
- handler.addProcessListener(new ProcessAdapter() {
- @Override
- public void processTerminated(ProcessEvent event) {
- System.out.println("TERMINATED: " + settings.commandLine);
- super.processTerminated(event);
- }
-
- @Override
- public void onTextAvailable(ProcessEvent event, Key outputType) {
- String str = event.getText();
- if (outputType == ProcessOutputTypes.STDOUT || outputType == ProcessOutputTypes.SYSTEM) {
- appendToContent(stdOut, str);
- }
- else if (outputType == ProcessOutputTypes.STDERR) {
- appendToContent(stdErr, str);
- }
- }
-
- private synchronized void appendToContent(StringBuilder content, String line) {
- if (settings.printOutputAtAppearance) {
- System.out.println(getPrefixString() + StringUtil.trimTrailing(line));
- System.out.flush();
- }
- else {
- content.append(getPrefixString());
- content.append(StringUtil.trimTrailing(line));
- content.append("\n");
- }
- }
-
- private String getPrefixString() {
- return (settings.outputPrefix != null) ? settings.outputPrefix + " " : "";
- }
- });
-
- handler.startNotify();
-
- if (settings.waitForEnd) {
- String timeoutAsString = System.getenv("kotlin.tests.android.timeout");
- if (timeoutAsString == null) {
- timeoutAsString = "30";
- System.err.println("Default value for timeout used: timeout = 30 min. You can change it using 'kotlin.tests.android.timeout' environment variable");
- }
- int timeout;
- try {
- timeout = Integer.parseInt(timeoutAsString);
- }
- catch (NumberFormatException e) {
- timeout = 30;
- System.err.println("Timeout system property should be a number: " + timeoutAsString);
- }
- handler.waitFor(timeout * 60 * 1000);
-
- if (!handler.isProcessTerminated()) {
- System.out.println("Output before handler.isProcessTerminated() " + settings.commandLine);
- System.out.println(stdOut);
- System.err.println(stdErr);
- return new RunResult(false, "Timeout exception: execution was terminated after ~" + timeout + " min.");
- }
- }
- else {
- handler.waitFor();
- }
-
- int exitCode = handler.getProcess().exitValue();
-
- if (exitCode != 0) {
- return new RunResult(false, builderToString(stdOut) + builderToString(stdErr));
- }
- else {
- String output = builderToString(stdOut) + builderToString(stdErr);
- if (OutputUtils.isBuildFailed(output)) {
- return new RunResult(false, output);
- }
- if (!settings.commandLine.getCommandLineString().contains("install")) {
- System.out.print(output);
- }
- return new RunResult(true, output);
- }
- }
-
- private static String builderToString(StringBuilder builder) {
- return builder.length() > 0 ? builder.toString() : "";
- }
-
- public static void close(Closeable closeable) {
- try {
- if (closeable != null) {
- closeable.close();
- }
- }
- catch (IOException e) {
- throw new RuntimeException(e);
- }
- }
-
- public static String getStackTrace(Throwable t) {
- StringWriter writer = new StringWriter();
- PrintWriter printWriter = new PrintWriter(writer);
- try {
- printWriter.write(t.getMessage());
- printWriter.write("\n");
- t.printStackTrace(printWriter);
- }
- finally {
- close(printWriter);
- }
- return writer.toString();
- }
-
-}
diff --git a/compiler/testData/codegen/box/annotations/typeAnnotations/annotationOnSecondParameter.kt b/compiler/testData/codegen/box/annotations/typeAnnotations/annotationOnSecondParameter.kt
index d4933a8..eff4cae 100644
--- a/compiler/testData/codegen/box/annotations/typeAnnotations/annotationOnSecondParameter.kt
+++ b/compiler/testData/codegen/box/annotations/typeAnnotations/annotationOnSecondParameter.kt
@@ -1,6 +1,8 @@
// TARGET_BACKEND: JVM_IR
// WITH_STDLIB
// FULL_JDK
+// IGNORE_BACKEND: ANDROID
+// Android is ignored due to KT-66391
@Target(AnnotationTarget.TYPE_PARAMETER)
annotation class Ann(val value: String)
diff --git a/compiler/testData/codegen/box/polymorphicSignature/insideComplexExpression.kt b/compiler/testData/codegen/box/polymorphicSignature/insideComplexExpression.kt
index 1a8e30c..93749c9 100644
--- a/compiler/testData/codegen/box/polymorphicSignature/insideComplexExpression.kt
+++ b/compiler/testData/codegen/box/polymorphicSignature/insideComplexExpression.kt
@@ -1,6 +1,7 @@
// TARGET_BACKEND: JVM
// WITH_STDLIB
// FULL_JDK
+// SKIP_JDK6
import java.lang.invoke.MethodHandles
import java.lang.invoke.MethodType
diff --git a/compiler/testData/codegen/box/polymorphicSignature/insideIf.kt b/compiler/testData/codegen/box/polymorphicSignature/insideIf.kt
index 5f6385a..5cc6687 100644
--- a/compiler/testData/codegen/box/polymorphicSignature/insideIf.kt
+++ b/compiler/testData/codegen/box/polymorphicSignature/insideIf.kt
@@ -1,5 +1,6 @@
// TARGET_BACKEND: JVM
// WITH_STDLIB
+// SKIP_JDK6
// FULL_JDK
import java.lang.invoke.MethodHandles
diff --git a/compiler/testData/codegen/box/polymorphicSignature/insideTry.kt b/compiler/testData/codegen/box/polymorphicSignature/insideTry.kt
index eaa0244..4f76c77b 100644
--- a/compiler/testData/codegen/box/polymorphicSignature/insideTry.kt
+++ b/compiler/testData/codegen/box/polymorphicSignature/insideTry.kt
@@ -1,6 +1,7 @@
// TARGET_BACKEND: JVM
// WITH_STDLIB
// FULL_JDK
+// SKIP_JDK6
import java.lang.invoke.MethodHandles
import java.lang.invoke.MethodType
diff --git a/compiler/testData/codegen/box/polymorphicSignature/insideWhen.kt b/compiler/testData/codegen/box/polymorphicSignature/insideWhen.kt
index a2c83b1..90ecafb 100644
--- a/compiler/testData/codegen/box/polymorphicSignature/insideWhen.kt
+++ b/compiler/testData/codegen/box/polymorphicSignature/insideWhen.kt
@@ -1,4 +1,5 @@
// TARGET_BACKEND: JVM
+// SKIP_JDK6
// WITH_STDLIB
// FULL_JDK
diff --git a/compiler/testData/codegen/box/reflection/callBy/brokenDefaultParametersFromDifferentFunctionsJvmDefault.kt b/compiler/testData/codegen/box/reflection/callBy/brokenDefaultParametersFromDifferentFunctionsJvmDefault.kt
index 589eb46..7db0f2d 100644
--- a/compiler/testData/codegen/box/reflection/callBy/brokenDefaultParametersFromDifferentFunctionsJvmDefault.kt
+++ b/compiler/testData/codegen/box/reflection/callBy/brokenDefaultParametersFromDifferentFunctionsJvmDefault.kt
@@ -1,4 +1,6 @@
// TARGET_BACKEND: JVM_IR
+// KT-66789
+// IGNORE_BACKEND: ANDROID
// WITH_REFLECT
// LANGUAGE: +ValueClasses
// JVM_DEFAULT_MODE: all
diff --git a/compiler/testData/codegen/box/reflection/callBy/mfvcInterfaceJvmDefault.kt b/compiler/testData/codegen/box/reflection/callBy/mfvcInterfaceJvmDefault.kt
index a0c6ce2..98363b4 100644
--- a/compiler/testData/codegen/box/reflection/callBy/mfvcInterfaceJvmDefault.kt
+++ b/compiler/testData/codegen/box/reflection/callBy/mfvcInterfaceJvmDefault.kt
@@ -2,6 +2,8 @@
// WITH_REFLECT
// LANGUAGE: +ValueClasses
// JVM_DEFAULT_MODE: all
+// KT-66789
+// IGNORE_BACKEND: ANDROID
import kotlin.test.assertEquals
diff --git a/compiler/testData/codegen/box/reflection/classes/createInstance.kt b/compiler/testData/codegen/box/reflection/classes/createInstance.kt
index 9daba5a..233addd 100644
--- a/compiler/testData/codegen/box/reflection/classes/createInstance.kt
+++ b/compiler/testData/codegen/box/reflection/classes/createInstance.kt
@@ -1,5 +1,7 @@
// TARGET_BACKEND: JVM
+// IGNORE_BACKEND: ANDROID
// WITH_REFLECT
+// Android is ignored due to KT-66391
import kotlin.reflect.full.createInstance
import kotlin.test.assertTrue
diff --git a/compiler/testData/codegen/box/reflection/localClasses/localNestedClasses.jvm_abi.txt b/compiler/testData/codegen/box/reflection/localClasses/localNestedClasses.jvm_abi.txt
index 8dc8055..32ecf0e 100644
--- a/compiler/testData/codegen/box/reflection/localClasses/localNestedClasses.jvm_abi.txt
+++ b/compiler/testData/codegen/box/reflection/localClasses/localNestedClasses.jvm_abi.txt
@@ -1,12 +1,12 @@
MODULE main
- CLASS LocalNestedClassesKt$foo1$X$Y.class
+ CLASS test/LocalNestedClassesKt$foo1$X$Y.class
CLASS METADATA
Property: class.metadata.companionObject
K1
null
K2
Z
- CLASS LocalNestedClassesKt$foo2$X$Y.class
+ CLASS test/LocalNestedClassesKt$foo2$X$Y.class
CLASS METADATA
Property: class.metadata.companionObject
K1
diff --git a/compiler/testData/codegen/box/reflection/localClasses/localNestedClasses.kt b/compiler/testData/codegen/box/reflection/localClasses/localNestedClasses.kt
index 6868c17..9e798d5 100644
--- a/compiler/testData/codegen/box/reflection/localClasses/localNestedClasses.kt
+++ b/compiler/testData/codegen/box/reflection/localClasses/localNestedClasses.kt
@@ -2,10 +2,13 @@
// WITH_REFLECT
// JVM_ABI_K1_K2_DIFF: K2 names companion objects in metadata correctly
+package test
+
+import kotlin.reflect.KClass
import kotlin.reflect.KType
import kotlin.reflect.full.memberProperties
-val KType.str get() = classifier.toString()
+val KType.str get() = (classifier as KClass<*>).java.name
class A {
fun foo(): String {
@@ -131,14 +134,14 @@
}
fun box(): String {
- if (A().foo() != "class A\$foo\$Nested\$Inner") return "Fail 1"
- if (foo1() != "class LocalNestedClassesKt\$foo1\$X\$Y\$Z") return "Fail 2"
- if (foo2() != "class LocalNestedClassesKt\$foo2\$X\$Y\$Companion") return "Fail 3"
- if (foo3() != "class LocalNestedClassesKt\$foo3\$X\$Y\$prop\$1") return "Fail 4"
- if (foo4() != "class LocalNestedClassesKt\$foo4\$A\$B\$C\$bar\$D") return "Fail 5"
- if (foo5() != "class LocalNestedClassesKt\$foo5\$1\$bar\$1\$foo\$A\$B") return "Fail 6"
- if (foo6() != "class LocalNestedClassesKt\$foo6\$1\$bar\$A\$B\$C") return "Fail 7"
- if (foo7() != "class LocalNestedClassesKt\$foo7\$x\$1\$y\$1\$z\$1") return "Fail 8"
+ if (A().foo() != "test.A\$foo\$Nested\$Inner") return "Fail 1"
+ if (foo1() != "test.LocalNestedClassesKt\$foo1\$X\$Y\$Z") return "Fail 2"
+ if (foo2() != "test.LocalNestedClassesKt\$foo2\$X\$Y\$Companion") return "Fail 3"
+ if (foo3() != "test.LocalNestedClassesKt\$foo3\$X\$Y\$prop\$1") return "Fail 4"
+ if (foo4() != "test.LocalNestedClassesKt\$foo4\$A\$B\$C\$bar\$D") return "Fail 5"
+ if (foo5() != "test.LocalNestedClassesKt\$foo5\$1\$bar\$1\$foo\$A\$B") return "Fail 6"
+ if (foo6() != "test.LocalNestedClassesKt\$foo6\$1\$bar\$A\$B\$C") return "Fail 7"
+ if (foo7() != "test.LocalNestedClassesKt\$foo7\$x\$1\$y\$1\$z\$1") return "Fail 8"
return "OK"
}
\ No newline at end of file
diff --git a/dependencies/android-sdk/build.gradle.kts b/dependencies/android-sdk/build.gradle.kts
index c1d80bc..be747d59 100644
--- a/dependencies/android-sdk/build.gradle.kts
+++ b/dependencies/android-sdk/build.gradle.kts
@@ -25,9 +25,8 @@
}
val buildToolsVersion = "r29.0.3"
-val platformToolsVersion = "r28.0.1"
-val sdkToolsVersion = "4333796" /*26.1.1*/
-val emulatorVersion = "5264690"
+val platformToolsVersion = "r35.0.0"
+val sdkToolsVersion = "4333796" // 26.1.1
dependencies {
implicitDependencies("google:build-tools:$buildToolsVersion:linux@zip")
@@ -41,17 +40,12 @@
implicitDependencies("google:sdk-tools-linux:$sdkToolsVersion@zip")
implicitDependencies("google:sdk-tools-windows:$sdkToolsVersion@zip")
implicitDependencies("google:sdk-tools-darwin:$sdkToolsVersion@zip")
-
- implicitDependencies("google:emulator-linux:$emulatorVersion@zip")
- implicitDependencies("google:emulator-windows:$emulatorVersion@zip")
- implicitDependencies("google:emulator-darwin:$emulatorVersion@zip")
}
val androidSdk by configurations.creating
val androidJar by configurations.creating
val androidPlatform by configurations.creating
val buildTools by configurations.creating
-val androidEmulator by configurations.creating
val sdkDestDirName = "androidSdk"
@@ -150,8 +144,7 @@
unzipSdkTask("android_m2repository", "r44", "extras/android", "")
unzipSdkTask("platform-tools", platformToolsVersion, "", toolsOsDarwin)
unzipSdkTask("sdk-tools-$toolsOsDarwin", sdkToolsVersion, "", "")
-unzipSdkTask("build-tools", buildToolsVersion, "build-tools/29.0.3", toolsOs, buildTools, 1)
-unzipSdkTask("emulator-$toolsOsDarwin", emulatorVersion, "", "", prepareTask = prepareEmulator)
+unzipSdkTask("build-tools", buildToolsVersion, "build-tools/${buildToolsVersion.removePrefix("r")}", toolsOs, buildTools, 1)
unzipSdkTask("armeabi-v7a", "19", "system-images/android-19/default","r05", prepareTask = prepareEmulator)
unzipSdkTask("x86", "19", "system-images/android-19/default", "r06", prepareTask = prepareEmulator)
@@ -166,7 +159,3 @@
artifacts.add(androidJar.name, layout.buildDirectory.file("$sdkDestDirName/platforms/android-26/android.jar")) {
builtBy(preparePlatform)
}
-
-artifacts.add(androidEmulator.name, layout.buildDirectory.dir(sdkDestDirName)) {
- builtBy(prepareEmulator)
-}
\ No newline at end of file
diff --git a/gradle/verification-metadata.xml b/gradle/verification-metadata.xml
index 12684c4..4f7e4d9 100644
--- a/gradle/verification-metadata.xml
+++ b/gradle/verification-metadata.xml
@@ -1813,42 +1813,24 @@
<sha256 value="0ce606d5c46bf4cd0883e4f7078efeae314e41a96dd329c2c089d123cc8c2609" origin="Generated by Gradle"/>
</artifact>
</component>
- <component group="google" name="emulator-darwin" version="5264690">
- <artifact name="emulator-darwin-5264690.zip">
- <md5 value="ecb9c325d4d66e72fb3756b571ab0de0" origin="Generated by Gradle"/>
- <sha256 value="078d1444659a85c7940dc40ddf49288ab2a2ff27b01c8ebd852ca6c101906076" origin="Generated by Gradle"/>
- </artifact>
- </component>
- <component group="google" name="emulator-linux" version="5264690">
- <artifact name="emulator-linux-5264690.zip">
- <md5 value="f4c54782ea227094a4d069f64f8cf4a2" origin="Generated by Gradle"/>
- <sha256 value="6821047a6444e722c8f3d52a621bb6ecb2651be84bde6cd26b404f234f45fdc4" origin="Generated by Gradle"/>
- </artifact>
- </component>
- <component group="google" name="emulator-windows" version="5264690">
- <artifact name="emulator-windows-5264690.zip">
- <md5 value="78470340c52fe3782f4917aaa548c91b" origin="Generated by Gradle"/>
- <sha256 value="96673be93da220c1f719c7cc113819a032d528e9cd90ac2713fae945c37807c5" origin="Generated by Gradle"/>
- </artifact>
- </component>
<component group="google" name="platform" version="26_r02">
<artifact name="platform-26_r02.zip">
<md5 value="e0bd6d35c31c9f7ea2aa8931822fa5b3" origin="Generated by Gradle"/>
<sha256 value="2aafa7d19c5e9c4b643ee6ade3d85ef89dc2f79e8383efdb9baf7fddad74b52a" origin="Generated by Gradle"/>
</artifact>
</component>
- <component group="google" name="platform-tools" version="r28.0.1">
- <artifact name="platform-tools-r28.0.1-darwin.zip">
- <md5 value="1cde81b82e84c0751d5a8fcbe1d8ce56" origin="Generated by Gradle"/>
- <sha256 value="3bc833ae3f4bd831af03811f2d1be540c2eb2eb9a17de9398b0a06dc5af6fa84" origin="Generated by Gradle"/>
+ <component group="google" name="platform-tools" version="r35.0.0">
+ <artifact name="platform-tools-r35.0.0-darwin.zip">
+ <md5 value="51b47bb98d2791e84de925a53b609a0f" origin="Generated by Gradle"/>
+ <sha256 value="85c75ac31556dc95712cf1bdec592098e6c5067dc485356591d85932178bf8cd" origin="Generated by Gradle"/>
</artifact>
- <artifact name="platform-tools-r28.0.1-linux.zip">
- <md5 value="e322fcbfc59ff517e327ce310899fc0c" origin="Generated by Gradle"/>
- <sha256 value="3e11358a3a9b0dd43ad9ab8a621eadb41737ac0495b2059a94b995157bca7392" origin="Generated by Gradle"/>
+ <artifact name="platform-tools-r35.0.0-linux.zip">
+ <md5 value="8c054a42356820d29003be3ce33accd6" origin="Generated by Gradle"/>
+ <sha256 value="62fc977c1b7622ef8dbd6fe1312987d9b139aa8a0b06e88573c1b60129399d49" origin="Generated by Gradle"/>
</artifact>
- <artifact name="platform-tools-r28.0.1-windows.zip">
- <md5 value="5376bf9e941b12d99a4747d3caf4b209" origin="Generated by Gradle"/>
- <sha256 value="db78f726d5dc653706dcd15a462ab1b946c643f598df76906c4c1858411c54df" origin="Generated by Gradle"/>
+ <artifact name="platform-tools-r35.0.0-windows.zip">
+ <md5 value="e8a786dc533d91b1e6c3dc38722bbaba" origin="Generated by Gradle"/>
+ <sha256 value="7ab78a8f8b305ae4d0de647d99c43599744de61a0838d3a47bda0cdffefee87e" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="google" name="sdk-tools-darwin" version="4333796">
diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/build.gradle.kts b/libraries/tools/kotlin-gradle-plugin-integration-tests/build.gradle.kts
index f69eb02..5f62ff1 100644
--- a/libraries/tools/kotlin-gradle-plugin-integration-tests/build.gradle.kts
+++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/build.gradle.kts
@@ -332,12 +332,12 @@
val allParallelTestsTask = tasks.register<Test>("kgpAllParallelTests") {
group = KGP_TEST_TASKS_GROUP
- description = "Runs all tests for Kotlin Gradle plugins except daemon ones"
+ description = "Runs all tests for Kotlin Gradle plugins except daemon and codegen ones"
maxParallelForks = maxParallelTestForks
useJUnitPlatform {
- excludeTags("DaemonsKGP")
+ excludeTags("DaemonsKGP", "AndroidCodegen")
includeEngines("junit-jupiter")
}
}
@@ -348,7 +348,7 @@
maxParallelForks = maxParallelTestForks
useJUnitPlatform {
includeTags("JvmKGP")
- excludeTags("JsKGP", "NativeKGP", "DaemonsKGP", "OtherKGP", "MppKGP", "AndroidKGP", "SwiftExportKGP")
+ excludeTags("JsKGP", "NativeKGP", "DaemonsKGP", "OtherKGP", "MppKGP", "AndroidKGP", "AndroidCodegen", "SwiftExportKGP")
includeEngines("junit-jupiter")
}
}
@@ -359,7 +359,7 @@
maxParallelForks = maxParallelTestForks
useJUnitPlatform {
includeTags("SwiftExportKGP")
- excludeTags("JvmKGP", "JsKGP", "DaemonsKGP", "OtherKGP", "MppKGP", "AndroidKGP", "NativeKGP")
+ excludeTags("JvmKGP", "JsKGP", "DaemonsKGP", "OtherKGP", "MppKGP", "AndroidKGP", "AndroidCodegen", "NativeKGP")
includeEngines("junit-jupiter")
}
applyKotlinNativeFromCurrentBranchIfNeeded()
@@ -371,7 +371,7 @@
maxParallelForks = maxParallelTestForks
useJUnitPlatform {
includeTags("JsKGP")
- excludeTags("JvmKGP", "NativeKGP", "DaemonsKGP", "OtherKGP", "MppKGP", "AndroidKGP", "SwiftExportKGP")
+ excludeTags("JvmKGP", "NativeKGP", "DaemonsKGP", "OtherKGP", "MppKGP", "AndroidKGP", "AndroidCodegen", "SwiftExportKGP")
includeEngines("junit-jupiter")
}
}
@@ -382,7 +382,7 @@
maxParallelForks = maxParallelTestForks
useJUnitPlatform {
includeTags("NativeKGP")
- excludeTags("JvmKGP", "JsKGP", "DaemonsKGP", "OtherKGP", "MppKGP", "AndroidKGP", "SwiftExportKGP")
+ excludeTags("JvmKGP", "JsKGP", "DaemonsKGP", "OtherKGP", "MppKGP", "AndroidKGP", "AndroidCodegen", "SwiftExportKGP")
includeEngines("junit-jupiter")
}
applyKotlinNativeFromCurrentBranchIfNeeded()
@@ -396,7 +396,7 @@
useJUnitPlatform {
includeTags("DaemonsKGP")
- excludeTags("JvmKGP", "JsKGP", "NativeKGP", "OtherKGP", "MppKGP", "AndroidKGP", "SwiftExportKGP")
+ excludeTags("JvmKGP", "JsKGP", "NativeKGP", "OtherKGP", "MppKGP", "AndroidKGP", "AndroidCodegen", "SwiftExportKGP")
includeEngines("junit-jupiter")
}
}
@@ -407,7 +407,7 @@
maxParallelForks = maxParallelTestForks
useJUnitPlatform {
includeTags("OtherKGP")
- excludeTags("JvmKGP", "JsKGP", "NativeKGP", "DaemonsKGP", "MppKGP", "AndroidKGP", "SwiftExportKGP")
+ excludeTags("JvmKGP", "JsKGP", "NativeKGP", "DaemonsKGP", "MppKGP", "AndroidKGP", "AndroidCodegen", "SwiftExportKGP")
includeEngines("junit-jupiter")
}
applyKotlinNativeFromCurrentBranchIfNeeded()
@@ -419,7 +419,7 @@
maxParallelForks = maxParallelTestForks
useJUnitPlatform {
includeTags("MppKGP")
- excludeTags("JvmKGP", "JsKGP", "NativeKGP", "DaemonsKGP", "OtherKGP", "AndroidKGP", "SwiftExportKGP")
+ excludeTags("JvmKGP", "JsKGP", "NativeKGP", "DaemonsKGP", "OtherKGP", "AndroidKGP", "AndroidCodegen", "SwiftExportKGP")
includeEngines("junit-jupiter")
}
applyKotlinNativeFromCurrentBranchIfNeeded()
@@ -431,7 +431,18 @@
maxParallelForks = maxParallelTestForks
useJUnitPlatform {
includeTags("AndroidKGP")
- excludeTags("JvmKGP", "JsKGP", "NativeKGP", "DaemonsKGP", "OtherKGP", "MppKGP", "SwiftExportKGP")
+ excludeTags("JvmKGP", "JsKGP", "NativeKGP", "DaemonsKGP", "OtherKGP", "MppKGP", "AndroidCodegen", "SwiftExportKGP")
+ includeEngines("junit-jupiter")
+ }
+}
+
+val androidCodegenTestsTask = tasks.register<Test>("kgpAndroidCodegenTests") {
+ group = KGP_TEST_TASKS_GROUP
+ description = "Run Android codegen tests"
+ maxParallelForks = maxParallelTestForks
+ useJUnitPlatform {
+ includeTags("AndroidCodegen")
+ excludeTags("JvmKGP", "JsKGP", "NativeKGP", "DaemonsKGP", "OtherKGP", "MppKGP", "AndroidKGP", "SwiftExportKGP")
includeEngines("junit-jupiter")
}
}
@@ -502,7 +513,8 @@
daemonsTestsTask.name,
otherPluginsTestTask.name,
mppTestsTask.name,
- androidTestsTask.name
+ androidTestsTask.name,
+ androidCodegenTestsTask.name,
)
if (shouldApplyJunitPlatform) {
maxHeapSize = "512m"
diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/BaseGradleIT.kt b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/BaseGradleIT.kt
index 411e49a..29ac3cd 100644
--- a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/BaseGradleIT.kt
+++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/BaseGradleIT.kt
@@ -71,6 +71,7 @@
"24333f8a63b6825ea9c5514f83c2829b004d1fee",
)
val sdkPreviewLicense = "84831b9409646a918e30573bab4c9c91346d8abd"
+ val sdkArmDbtLicense = "859f317696f67ef3d7f30a50a5560e7834b43903"
val sdkLicenseFile = sdkLicensesDir.resolve("android-sdk-license")
if (!sdkLicenseFile.exists()) {
@@ -96,6 +97,15 @@
sdkPreviewLicenseFile.writeText(sdkPreviewLicense)
}
}
+
+ val sdkArmDbtLicenseFile = sdkLicensesDir.resolve("android-sdk-arm-dbt-license")
+ if (!sdkArmDbtLicenseFile.exists()) {
+ sdkArmDbtLicenseFile.writeText(sdkArmDbtLicense)
+ } else {
+ if (sdkArmDbtLicense != sdkArmDbtLicenseFile.readText().trim()) {
+ sdkArmDbtLicenseFile.writeText(sdkArmDbtLicense)
+ }
+ }
}
private object DaemonRegistry {
diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/android/AndroidCodegenIT.kt b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/android/AndroidCodegenIT.kt
new file mode 100644
index 0000000..79b3df7
--- /dev/null
+++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/android/AndroidCodegenIT.kt
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2010-2024 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.gradle.android
+
+import org.gradle.api.logging.LogLevel
+import org.gradle.util.GradleVersion
+import org.jetbrains.kotlin.gradle.testbase.*
+import org.junit.jupiter.api.DisplayName
+import org.junit.jupiter.api.condition.OS
+
+@DisplayName("codegen tests on android")
+@AndroidTestVersions(minVersion = TestVersions.AGP.AGP_84, maxVersion = TestVersions.AGP.AGP_84)
+/*
+ * Non-virtualized runners are necessary with current configuration.
+ * This build utilizes the Android Emulator to execute codegen tests,
+ * requiring a VM hypervisor for optimal performance.
+ * Nested virtualization on CI runners except physical Macs fails.
+ */
+@OsCondition(enabledOnCI = [OS.MAC])
+@AndroidCodegenTests
+class AndroidCodegenIT : KGPBaseTest() {
+ @GradleAndroidTest
+ fun testAndroidCodegen(
+ gradleVersion: GradleVersion,
+ agpVersion: String,
+ jdkVersion: JdkVersions.ProvidedJdk,
+ ) {
+ project(
+ "codegen-tests",
+ gradleVersion,
+ buildOptions = defaultBuildOptions.copy(
+ androidVersion = agpVersion,
+ freeArgs = listOf("-Pandroid.useAndroidX=true", "-Pandroid.experimental.testOptions.managedDevices.setupTimeoutMinutes=0"),
+ logLevel = LogLevel.LIFECYCLE
+ ),
+ enableGradleDebug = false,
+ buildJdk = jdkVersion.location
+ ) {
+ build("assembleAndroidTest", forceOutput = true, enableGradleDaemonMemoryLimitInMb = 6000)
+ build("nexusCheck", forceOutput = true, enableGradleDaemonMemoryLimitInMb = 6000)
+ }
+ }
+}
diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/testbase/tagsValidator.kt b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/testbase/tagsValidator.kt
index 5368ccb..4ddd696 100644
--- a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/testbase/tagsValidator.kt
+++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/testbase/tagsValidator.kt
@@ -58,6 +58,7 @@
it is NativeGradlePluginTests ||
it is MppGradlePluginTests ||
it is AndroidGradlePluginTests ||
+ it is AndroidCodegenTests ||
it is OtherGradlePluginTests ||
it is SwiftExportGradlePluginTests
}
diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/testbase/testTags.kt b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/testbase/testTags.kt
index 09ff9f8..8cf31589 100644
--- a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/testbase/testTags.kt
+++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/testbase/testTags.kt
@@ -92,6 +92,18 @@
annotation class AndroidGradlePluginTests
/**
+ * Add it to the tests running codegen tests with Android emulator.
+ *
+ * You could add tag onto test suite once, but then all tests
+ * in test suite should be for the related tag.
+ * Preferably add tag for each test.
+ */
+@Target(AnnotationTarget.CLASS, AnnotationTarget.ANNOTATION_CLASS, AnnotationTarget.FUNCTION)
+@Retention(AnnotationRetention.RUNTIME)
+@Tag("AndroidCodegen")
+annotation class AndroidCodegenTests
+
+/**
* Add it the tests that are not covered by tags above.
*
* Usually it would be tests for kapt, serialization plugins, etc...
diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/codegen-tests/.gitignore b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/codegen-tests/.gitignore
new file mode 100644
index 0000000..18a4178
--- /dev/null
+++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/codegen-tests/.gitignore
@@ -0,0 +1,3 @@
+test-classes/
+src/*
+!src/main/
diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/codegen-tests/build.gradle.kts b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/codegen-tests/build.gradle.kts
new file mode 100644
index 0000000..1373b73
--- /dev/null
+++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/codegen-tests/build.gradle.kts
@@ -0,0 +1,99 @@
+plugins {
+ id("com.android.application")
+}
+
+android {
+ namespace = "org.jetbrains.kotlin.android.tests"
+
+ defaultConfig {
+ applicationId = "org.jetbrains.kotlin.android.tests"
+ minSdk = 14
+ compileSdk = 34
+ targetSdk = 34
+ versionCode = 1
+ versionName = "1.0"
+ testApplicationId = "org.jetbrains.kotlin.android.tests.gradle"
+ testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
+ }
+
+ buildTypes {
+ debug {
+ isMinifyEnabled = false
+ proguardFiles(getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro")
+ }
+ }
+
+ flavorDimensions += "box"
+
+ productFlavors {
+ listOf(
+ "common0",
+ "common1",
+ "common2",
+ "common3",
+ "reflect0",
+ "common_ir0",
+ "common_ir1",
+ "common_ir2",
+ "common_ir3",
+ "reflect_ir0"
+ ).forEach {
+ create(it) {
+ dimension = "box"
+ }
+ }
+ }
+
+ testOptions.managedDevices.localDevices {
+ create("nexus") {
+ // A lower resolution device is used here for better emulator performance
+ device = "Nexus One"
+ apiLevel = 30
+ systemImageSource = "aosp-atd"
+ }
+ }
+}
+
+
+val jarTestFolders by tasks.registering {
+ inputs.dir("test-classes")
+ .withPropertyName("classDirectories")
+ .withPathSensitivity(PathSensitivity.RELATIVE)
+
+ val testClassesDirectories = file("test-classes").listFiles().filter { it.isDirectory }
+ val libsJars = testClassesDirectories.map { file("libs").resolve("${it.name}.jar") }
+ outputs.files(libsJars).withPropertyName("libsJars")
+
+ doLast {
+ testClassesDirectories.forEach { dir ->
+ logger.info("Jar {} folder", dir.name)
+ ant.withGroovyBuilder {
+ "jar"("basedir" to dir.path, "destfile" to "libs/${dir.name}.jar")
+ }
+ }
+ }
+}
+
+tasks.preBuild {
+ dependsOn(jarTestFolders)
+}
+
+val kotlin_version: String by project
+
+dependencies {
+ implementation(kotlin("stdlib", kotlin_version))
+ implementation(kotlin("test-junit", kotlin_version))
+ implementation("junit:junit:4.13.2")
+ androidTestImplementation("androidx.test:runner:1.5.2")
+ androidTestImplementation("androidx.test.ext:junit:1.1.5")
+
+ android.applicationVariants.configureEach {
+ productFlavors.forEach { flavor ->
+ val configuration = "${flavor.name}Implementation"
+ configuration(project.fileTree("libs") { include("${flavor.name}.jar") })
+ if (flavor.name.startsWith("reflect")) {
+ configuration(kotlin("reflect", kotlin_version))
+ }
+ }
+ }
+}
diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/codegen-tests/settings.gradle.kts b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/codegen-tests/settings.gradle.kts
new file mode 100644
index 0000000..9339a70
--- /dev/null
+++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/codegen-tests/settings.gradle.kts
@@ -0,0 +1,15 @@
+pluginManagement {
+ repositories {
+ mavenLocal()
+ mavenCentral()
+ google()
+ }
+
+ val test_fixes_version: String by settings
+ val android_tools_version: String by settings
+
+ plugins {
+ id("org.jetbrains.kotlin.test.fixes.android") version test_fixes_version
+ id ("com.android.application") version android_tools_version
+ }
+}
diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/codegen-tests/src/main/AndroidManifest.xml b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/codegen-tests/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..0710b01e
--- /dev/null
+++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/codegen-tests/src/main/AndroidManifest.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android">
+
+ <application>
+ <uses-library
+ android:name="android.test.runner"
+ android:required="false" />
+ </application>
+</manifest>
diff --git a/compiler/android-tests/android-module/src/main/java/org/jetbrains/kotlin/android/tests/AbstractCodegenTestCaseOnAndroid.java b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/codegen-tests/src/main/java/org/jetbrains/kotlin/android/tests/AbstractCodegenTestCaseOnAndroid.java
similarity index 78%
rename from compiler/android-tests/android-module/src/main/java/org/jetbrains/kotlin/android/tests/AbstractCodegenTestCaseOnAndroid.java
rename to libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/codegen-tests/src/main/java/org/jetbrains/kotlin/android/tests/AbstractCodegenTestCaseOnAndroid.java
index 91ee9e4..39248cd 100644
--- a/compiler/android-tests/android-module/src/main/java/org/jetbrains/kotlin/android/tests/AbstractCodegenTestCaseOnAndroid.java
+++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/codegen-tests/src/main/java/org/jetbrains/kotlin/android/tests/AbstractCodegenTestCaseOnAndroid.java
@@ -20,15 +20,14 @@
import java.lang.reflect.Method;
-public class AbstractCodegenTestCaseOnAndroid extends TestCase {
-
- protected void invokeBoxMethod(Class clazz, String filePath, String expectedResult) throws Exception {
+public abstract class AbstractCodegenTestCaseOnAndroid extends TestCase {
+ protected void invokeBoxMethod(Class<?> clazz, String filePath, String expectedResult) {
try {
Method method = clazz.getMethod("box");
assertEquals(expectedResult, method.invoke(null));
}
catch (Throwable e) {
- throw new RuntimeException("File: " + filePath, e);
+ throw new AssertionError("File: " + filePath, e);
}
}
}
diff --git a/repo/gradle-build-conventions/buildsrc-compat/src/main/kotlin/tasks.kt b/repo/gradle-build-conventions/buildsrc-compat/src/main/kotlin/tasks.kt
index 1af2619..537ef17 100644
--- a/repo/gradle-build-conventions/buildsrc-compat/src/main/kotlin/tasks.kt
+++ b/repo/gradle-build-conventions/buildsrc-compat/src/main/kotlin/tasks.kt
@@ -339,10 +339,6 @@
fun useAndroidJar(task: Task) {
task.useAndroidConfiguration(systemPropertyName = "android.jar", configName = "androidJar")
}
-
- fun useAndroidEmulator(task: Task) {
- task.useAndroidConfiguration(systemPropertyName = "android.sdk", configName = "androidEmulator")
- }
}
private fun Task.useAndroidConfiguration(systemPropertyName: String, configName: String) {