diff options
Diffstat (limited to 'plugins/kotlin/jps/jps-plugin/tests/test/org/jetbrains/kotlin/jps/build/KotlinJpsBuildTest.kt')
-rw-r--r-- | plugins/kotlin/jps/jps-plugin/tests/test/org/jetbrains/kotlin/jps/build/KotlinJpsBuildTest.kt | 1055 |
1 files changed, 0 insertions, 1055 deletions
diff --git a/plugins/kotlin/jps/jps-plugin/tests/test/org/jetbrains/kotlin/jps/build/KotlinJpsBuildTest.kt b/plugins/kotlin/jps/jps-plugin/tests/test/org/jetbrains/kotlin/jps/build/KotlinJpsBuildTest.kt deleted file mode 100644 index bd05f9194ef3..000000000000 --- a/plugins/kotlin/jps/jps-plugin/tests/test/org/jetbrains/kotlin/jps/build/KotlinJpsBuildTest.kt +++ /dev/null @@ -1,1055 +0,0 @@ -// Copyright 2000-2021 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. - -package org.jetbrains.kotlin.jps.build - -import com.intellij.openapi.util.io.FileUtil -import com.intellij.openapi.util.io.FileUtil.toSystemIndependentName -import com.intellij.openapi.util.io.FileUtilRt -import com.intellij.openapi.util.text.StringUtil -import com.intellij.testFramework.LightVirtualFile -import com.intellij.testFramework.UsefulTestCase -import com.intellij.util.io.Decompressor -import com.intellij.util.io.ZipUtil -import org.jetbrains.jps.ModuleChunk -import org.jetbrains.jps.api.CanceledStatus -import org.jetbrains.jps.builders.BuildResult -import org.jetbrains.jps.builders.CompileScopeTestBuilder -import org.jetbrains.jps.builders.TestProjectBuilderLogger -import org.jetbrains.jps.builders.impl.BuildDataPathsImpl -import org.jetbrains.jps.builders.logging.BuildLoggingManager -import org.jetbrains.jps.cmdline.ProjectDescriptor -import org.jetbrains.jps.devkit.model.JpsPluginModuleType -import org.jetbrains.jps.incremental.BuilderRegistry -import org.jetbrains.jps.incremental.CompileContext -import org.jetbrains.jps.incremental.IncProjectBuilder -import org.jetbrains.jps.incremental.ModuleLevelBuilder -import org.jetbrains.jps.incremental.messages.BuildMessage -import org.jetbrains.jps.incremental.messages.CompilerMessage -import org.jetbrains.jps.model.JpsModuleRootModificationUtil -import org.jetbrains.jps.model.JpsProject -import org.jetbrains.jps.model.java.JavaSourceRootType -import org.jetbrains.jps.model.java.JpsJavaDependencyScope -import org.jetbrains.jps.model.java.JpsJavaExtensionService -import org.jetbrains.jps.model.module.JpsModule -import org.jetbrains.jps.util.JpsPathUtil -import org.jetbrains.kotlin.cli.common.Usage -import org.jetbrains.kotlin.cli.common.arguments.K2JVMCompilerArguments -import org.jetbrains.kotlin.cli.jvm.K2JVMCompiler -import org.jetbrains.kotlin.codegen.AsmUtil -import org.jetbrains.kotlin.codegen.JvmCodegenUtil -import org.jetbrains.kotlin.config.IncrementalCompilation -import org.jetbrains.kotlin.idea.artifacts.KotlinArtifacts -import org.jetbrains.kotlin.incremental.components.LookupTracker -import org.jetbrains.kotlin.jps.build.KotlinJpsBuildTestBase.LibraryDependency.* -import org.jetbrains.kotlin.jps.incremental.CacheAttributesDiff -import org.jetbrains.kotlin.jps.model.kotlinCommonCompilerArguments -import org.jetbrains.kotlin.jps.model.kotlinCompilerArguments -import org.jetbrains.kotlin.jps.targets.KotlinModuleBuildTarget -import org.jetbrains.kotlin.load.kotlin.PackagePartClassUtils -import org.jetbrains.kotlin.name.FqName -import org.jetbrains.kotlin.idea.test.KotlinCompilerStandalone -import org.jetbrains.kotlin.idea.test.KotlinTestUtils -import org.jetbrains.kotlin.utils.Printer -import org.jetbrains.org.objectweb.asm.ClassReader -import org.jetbrains.org.objectweb.asm.ClassVisitor -import org.jetbrains.org.objectweb.asm.MethodVisitor -import org.jetbrains.org.objectweb.asm.Opcodes -import org.junit.Assert -import java.io.File -import java.io.FileNotFoundException -import java.io.FileOutputStream -import java.io.IOException -import java.net.URLClassLoader -import java.util.* -import java.util.zip.ZipOutputStream - -open class KotlinJpsBuildTest : KotlinJpsBuildTestBase() { - companion object { - private const val ADDITIONAL_MODULE_NAME = "module2" - - private val EXCLUDE_FILES = arrayOf("Excluded.class", "YetAnotherExcluded.class") - private val NOTHING = arrayOf<String>() - private const val KOTLIN_JS_LIBRARY = "jslib-example" - private const val KOTLIN_JS_LIBRARY_JAR = "$KOTLIN_JS_LIBRARY.jar" - private val PATH_TO_KOTLIN_JS_LIBRARY = - TEST_DATA_PATH + "general/KotlinJavaScriptProjectWithDirectoryAsLibrary/" + KOTLIN_JS_LIBRARY - - private fun getMethodsOfClass(classFile: File): Set<String> { - val result = TreeSet<String>() - ClassReader(FileUtil.loadFileBytes(classFile)).accept(object : ClassVisitor(Opcodes.API_VERSION) { - override fun visitMethod( - access: Int, - name: String, - desc: String, - signature: String?, - exceptions: Array<String>? - ): MethodVisitor? { - result.add(name) - return null - } - }, 0) - return result - } - - @JvmStatic - protected fun klass(moduleName: String, classFqName: String): String { - val outputDirPrefix = "out/production/$moduleName/" - return outputDirPrefix + classFqName.replace('.', '/') + ".class" - } - - @JvmStatic - protected fun module(moduleName: String): String { - return "out/production/$moduleName/${JvmCodegenUtil.getMappingFileName(moduleName)}" - } - } - - protected fun doTest() { - initProject(JVM_MOCK_RUNTIME) - buildAllModules().assertSuccessful() - } - - protected fun doTestWithRuntime() { - initProject(JVM_FULL_RUNTIME) - buildAllModules().assertSuccessful() - } - - protected fun doTestWithKotlinJavaScriptLibrary() { - initProject(JS_STDLIB) - createKotlinJavaScriptLibraryArchive() - addDependency(KOTLIN_JS_LIBRARY, File(workDir, KOTLIN_JS_LIBRARY_JAR)) - buildAllModules().assertSuccessful() - } - - fun testKotlinProject() { - doTest() - - checkWhen(touch("src/test1.kt"), null, packageClasses("kotlinProject", "src/test1.kt", "Test1Kt")) - } - - fun testSourcePackagePrefix() { - doTest() - } - - fun testSourcePackageLongPrefix() { - initProject(JVM_MOCK_RUNTIME) - val buildResult = buildAllModules() - buildResult.assertSuccessful() - val warnings = buildResult.getMessages(BuildMessage.Kind.WARNING) - assertEquals("Warning about invalid package prefix in module 2 is expected: $warnings", 1, warnings.size) - assertEquals("Invalid package prefix name is ignored: invalid-prefix.test", warnings.first().messageText) - } - - fun testSourcePackagePrefixWithInnerClasses() { - initProject(JVM_MOCK_RUNTIME) - buildAllModules().assertSuccessful() - } - - fun testKotlinJavaScriptProject() { - initProject(JS_STDLIB) - buildAllModules().assertSuccessful() - - checkOutputFilesList() - checkWhen(touch("src/test1.kt"), null, pathsToDelete = k2jsOutput(PROJECT_NAME)) - } - - private fun k2jsOutput(vararg moduleNames: String): Array<String> { - val moduleNamesSet = moduleNames.toSet() - val list = mutableListOf<String>() - - myProject.modules.forEach { module -> - if (module.name in moduleNamesSet) { - val outputDir = module.productionBuildTarget.outputDir!! - list.add(toSystemIndependentName(File("$outputDir/${module.name}.js").relativeTo(workDir).path)) - list.add(toSystemIndependentName(File("$outputDir/${module.name}.meta.js").relativeTo(workDir).path)) - - val kjsmFiles = outputDir.walk().filter { it.isFile && it.extension.equals("kjsm", ignoreCase = true) } - - list.addAll(kjsmFiles.map { toSystemIndependentName(it.relativeTo(workDir).path) }) - } - } - - return list.toTypedArray() - } - - fun testKotlinJavaScriptProjectNewSourceRootTypes() { - initProject(JS_STDLIB) - buildAllModules().assertSuccessful() - - checkOutputFilesList() - } - - fun testKotlinJavaScriptProjectWithCustomOutputPaths() { - initProject(JS_STDLIB_WITHOUT_FACET) - buildAllModules().assertSuccessful() - - checkOutputFilesList(File(workDir, "target")) - } - - fun testKotlinJavaScriptProjectWithSourceMap() { - initProject(JS_STDLIB) - buildAllModules().assertSuccessful() - - val sourceMapContent = File(getOutputDir(PROJECT_NAME), "$PROJECT_NAME.js.map").readText() - val expectedPath = "prefix-dir/src/pkg/test1.kt" - assertTrue("Source map file should contain relative path ($expectedPath)", sourceMapContent.contains("\"$expectedPath\"")) - - val librarySourceMapFile = File(getOutputDir(PROJECT_NAME), "lib/kotlin.js.map") - assertTrue("Source map for stdlib should be copied to $librarySourceMapFile", librarySourceMapFile.exists()) - } - - fun testKotlinJavaScriptProjectWithSourceMapRelativePaths() { - initProject(JS_STDLIB) - buildAllModules().assertSuccessful() - - val sourceMapContent = File(getOutputDir(PROJECT_NAME), "$PROJECT_NAME.js.map").readText() - val expectedPath = "../../../src/pkg/test1.kt" - assertTrue("Source map file should contain relative path ($expectedPath)", sourceMapContent.contains("\"$expectedPath\"")) - - val librarySourceMapFile = File(getOutputDir(PROJECT_NAME), "lib/kotlin.js.map") - assertTrue("Source map for stdlib should be copied to $librarySourceMapFile", librarySourceMapFile.exists()) - } - - fun testKotlinJavaScriptProjectWithTwoModules() { - initProject(JS_STDLIB) - buildAllModules().assertSuccessful() - - checkOutputFilesList() - checkWhen(touch("src/test1.kt"), null, k2jsOutput(PROJECT_NAME)) - checkWhen(touch("module2/src/module2.kt"), null, k2jsOutput(ADDITIONAL_MODULE_NAME)) - checkWhen(arrayOf(touch("src/test1.kt"), touch("module2/src/module2.kt")), null, k2jsOutput(PROJECT_NAME, ADDITIONAL_MODULE_NAME)) - } - - @WorkingDir("KotlinJavaScriptProjectWithTwoModules") - fun testKotlinJavaScriptProjectWithTwoModulesAndWithLibrary() { - initProject() - createKotlinJavaScriptLibraryArchive() - addDependency(KOTLIN_JS_LIBRARY, File(workDir, KOTLIN_JS_LIBRARY_JAR)) - addKotlinJavaScriptStdlibDependency() - buildAllModules().assertSuccessful() - } - - fun testKotlinJavaScriptProjectWithDirectoryAsStdlib() { - initProject() - setupKotlinJSFacet() - val jslibJar = KotlinArtifacts.instance.kotlinStdlibJs - val jslibDir = File(workDir, "KotlinJavaScript") - try { - Decompressor.Zip(jslibJar).extract(jslibDir.toPath()) - } catch (ex: IOException) { - throw IllegalStateException(ex.message) - } - - addDependency("KotlinJavaScript", jslibDir) - buildAllModules().assertSuccessful() - - checkOutputFilesList() - checkWhen(touch("src/test1.kt"), null, k2jsOutput(PROJECT_NAME)) - } - - fun testKotlinJavaScriptProjectWithDirectoryAsLibrary() { - initProject(JS_STDLIB) - addDependency(KOTLIN_JS_LIBRARY, File(workDir, KOTLIN_JS_LIBRARY)) - buildAllModules().assertSuccessful() - - checkOutputFilesList() - checkWhen(touch("src/test1.kt"), null, k2jsOutput(PROJECT_NAME)) - } - - fun testKotlinJavaScriptProjectWithLibrary() { - doTestWithKotlinJavaScriptLibrary() - - checkOutputFilesList() - checkWhen(touch("src/test1.kt"), null, k2jsOutput(PROJECT_NAME)) - } - - fun testKotlinJavaScriptProjectWithLibraryCustomOutputDir() { - doTestWithKotlinJavaScriptLibrary() - - checkOutputFilesList() - checkWhen(touch("src/test1.kt"), null, k2jsOutput(PROJECT_NAME)) - } - - fun testKotlinJavaScriptProjectWithLibraryNoCopy() { - doTestWithKotlinJavaScriptLibrary() - - checkOutputFilesList() - checkWhen(touch("src/test1.kt"), null, k2jsOutput(PROJECT_NAME)) - } - - fun testKotlinJavaScriptProjectWithLibraryAndErrors() { - initProject(JS_STDLIB) - createKotlinJavaScriptLibraryArchive() - addDependency(KOTLIN_JS_LIBRARY, File(workDir, KOTLIN_JS_LIBRARY_JAR)) - buildAllModules().assertFailed() - - checkOutputFilesList() - } - - fun testKotlinJavaScriptProjectWithEmptyDependencies() { - initProject(JS_STDLIB) - buildAllModules().assertSuccessful() - } - - fun testKotlinJavaScriptInternalFromSpecialRelatedModule() { - initProject(JS_STDLIB) - buildAllModules().assertSuccessful() - } - - fun testKotlinJavaScriptProjectWithTests() { - initProject(JS_STDLIB) - buildAllModules().assertSuccessful() - } - - fun testKotlinJavaScriptProjectWithTestsAndSeparateTestAndSrcModuleDependencies() { - initProject(JS_STDLIB) - buildAllModules().assertSuccessful() - } - - fun testKotlinJavaScriptProjectWithTestsAndTestAndSrcModuleDependency() { - initProject(JS_STDLIB) - val buildResult = buildAllModules() - buildResult.assertSuccessful() - - val warnings = buildResult.getMessages(BuildMessage.Kind.WARNING) - assertEquals("Warning about duplicate module definition: $warnings", 0, warnings.size) - } - - fun testKotlinJavaScriptProjectWithTwoSrcModuleDependency() { - initProject(JS_STDLIB) - val buildResult = buildAllModules() - buildResult.assertSuccessful() - - val warnings = buildResult.getMessages(BuildMessage.Kind.WARNING) - assertEquals("Warning about duplicate module definition: $warnings", 0, warnings.size) - } - - fun testExcludeFolderInSourceRoot() { - doTest() - - val module = myProject.modules[0] - assertFilesExistInOutput(module, "Foo.class") - assertFilesNotExistInOutput(module, *EXCLUDE_FILES) - - checkWhen( - touch("src/foo.kt"), null, - arrayOf(klass("kotlinProject", "Foo"), module("kotlinProject")) - ) - } - - fun testExcludeModuleFolderInSourceRootOfAnotherModule() { - doTest() - - for (module in myProject.modules) { - assertFilesExistInOutput(module, "Foo.class") - } - - checkWhen( - touch("src/foo.kt"), null, - arrayOf(klass("kotlinProject", "Foo"), module("kotlinProject")) - ) - checkWhen( - touch("src/module2/src/foo.kt"), null, - arrayOf(klass("module2", "Foo"), module("module2")) - ) - } - - fun testExcludeFileUsingCompilerSettings() { - doTest() - - val module = myProject.modules[0] - assertFilesExistInOutput(module, "Foo.class", "Bar.class") - assertFilesNotExistInOutput(module, *EXCLUDE_FILES) - - if (IncrementalCompilation.isEnabledForJvm()) { - checkWhen(touch("src/foo.kt"), null, arrayOf(module("kotlinProject"), klass("kotlinProject", "Foo"))) - } else { - val allClasses = myProject.outputPaths() - checkWhen(touch("src/foo.kt"), null, allClasses) - } - - checkWhen(touch("src/Excluded.kt"), null, NOTHING) - checkWhen(touch("src/dir/YetAnotherExcluded.kt"), null, NOTHING) - } - - fun testExcludeFolderNonRecursivelyUsingCompilerSettings() { - doTest() - - val module = myProject.modules[0] - assertFilesExistInOutput(module, "Foo.class", "Bar.class") - assertFilesNotExistInOutput(module, *EXCLUDE_FILES) - - if (IncrementalCompilation.isEnabledForJvm()) { - checkWhen(touch("src/foo.kt"), null, arrayOf(module("kotlinProject"), klass("kotlinProject", "Foo"))) - checkWhen(touch("src/dir/subdir/bar.kt"), null, arrayOf(module("kotlinProject"), klass("kotlinProject", "Bar"))) - } else { - val allClasses = myProject.outputPaths() - checkWhen(touch("src/foo.kt"), null, allClasses) - checkWhen(touch("src/dir/subdir/bar.kt"), null, allClasses) - } - - checkWhen(touch("src/dir/Excluded.kt"), null, NOTHING) - checkWhen(touch("src/dir/subdir/YetAnotherExcluded.kt"), null, NOTHING) - } - - fun testExcludeFolderRecursivelyUsingCompilerSettings() { - doTest() - - val module = myProject.modules[0] - assertFilesExistInOutput(module, "Foo.class", "Bar.class") - assertFilesNotExistInOutput(module, *EXCLUDE_FILES) - - if (IncrementalCompilation.isEnabledForJvm()) { - checkWhen(touch("src/foo.kt"), null, arrayOf(module("kotlinProject"), klass("kotlinProject", "Foo"))) - } else { - val allClasses = myProject.outputPaths() - checkWhen(touch("src/foo.kt"), null, allClasses) - } - - checkWhen(touch("src/exclude/Excluded.kt"), null, NOTHING) - checkWhen(touch("src/exclude/YetAnotherExcluded.kt"), null, NOTHING) - checkWhen(touch("src/exclude/subdir/Excluded.kt"), null, NOTHING) - checkWhen(touch("src/exclude/subdir/YetAnotherExcluded.kt"), null, NOTHING) - } - - fun testKotlinProjectTwoFilesInOnePackage() { - doTest() - - if (IncrementalCompilation.isEnabledForJvm()) { - checkWhen(touch("src/test1.kt"), null, packageClasses("kotlinProject", "src/test1.kt", "_DefaultPackage")) - checkWhen(touch("src/test2.kt"), null, packageClasses("kotlinProject", "src/test2.kt", "_DefaultPackage")) - } else { - val allClasses = myProject.outputPaths() - checkWhen(touch("src/test1.kt"), null, allClasses) - checkWhen(touch("src/test2.kt"), null, allClasses) - } - - checkWhen( - arrayOf(del("src/test1.kt"), del("src/test2.kt")), NOTHING, - arrayOf( - packagePartClass("kotlinProject", "src/test1.kt", "_DefaultPackage"), - packagePartClass("kotlinProject", "src/test2.kt", "_DefaultPackage"), - module("kotlinProject") - ) - ) - - assertFilesNotExistInOutput(myProject.modules[0], "_DefaultPackage.class") - } - - fun testDefaultLanguageVersionCustomApiVersion() { - initProject(JVM_FULL_RUNTIME) - buildAllModules().assertFailed() - - assertEquals(1, myProject.modules.size) - val module = myProject.modules.first() - val args = module.kotlinCompilerArguments - args.apiVersion = "1.4" - myProject.kotlinCommonCompilerArguments = args - - buildAllModules().assertSuccessful() - } - - fun testKotlinJavaProject() { - doTestWithRuntime() - } - - fun testJKJProject() { - doTestWithRuntime() - } - - fun testKJKProject() { - doTestWithRuntime() - } - - fun testKJCircularProject() { - doTestWithRuntime() - } - - fun testJKJInheritanceProject() { - doTestWithRuntime() - } - - fun testKJKInheritanceProject() { - doTestWithRuntime() - } - - fun testCircularDependenciesNoKotlinFiles() { - doTest() - } - - fun testCircularDependenciesDifferentPackages() { - initProject(JVM_MOCK_RUNTIME) - val result = buildAllModules() - - // Check that outputs are located properly - assertFilesExistInOutput(findModule("module2"), "kt1/Kt1Kt.class") - assertFilesExistInOutput(findModule("kotlinProject"), "kt2/Kt2Kt.class") - - result.assertSuccessful() - - if (IncrementalCompilation.isEnabledForJvm()) { - checkWhen(touch("src/kt2.kt"), null, packageClasses("kotlinProject", "src/kt2.kt", "kt2.Kt2Kt")) - checkWhen(touch("module2/src/kt1.kt"), null, packageClasses("module2", "module2/src/kt1.kt", "kt1.Kt1Kt")) - } else { - val allClasses = myProject.outputPaths() - checkWhen(touch("src/kt2.kt"), null, allClasses) - checkWhen(touch("module2/src/kt1.kt"), null, allClasses) - } - } - - fun testCircularDependenciesSamePackage() { - initProject(JVM_MOCK_RUNTIME) - val result = buildAllModules() - result.assertSuccessful() - - // Check that outputs are located properly - val facadeWithA = findFileInOutputDir(findModule("module1"), "test/AKt.class") - val facadeWithB = findFileInOutputDir(findModule("module2"), "test/BKt.class") - UsefulTestCase.assertSameElements(getMethodsOfClass(facadeWithA), "<clinit>", "a", "getA") - UsefulTestCase.assertSameElements(getMethodsOfClass(facadeWithB), "<clinit>", "b", "getB", "setB") - - - if (IncrementalCompilation.isEnabledForJvm()) { - checkWhen(touch("module1/src/a.kt"), null, packageClasses("module1", "module1/src/a.kt", "test.TestPackage")) - checkWhen(touch("module2/src/b.kt"), null, packageClasses("module2", "module2/src/b.kt", "test.TestPackage")) - } else { - val allClasses = myProject.outputPaths() - checkWhen(touch("module1/src/a.kt"), null, allClasses) - checkWhen(touch("module2/src/b.kt"), null, allClasses) - } - } - - fun testCircularDependenciesSamePackageWithTests() { - initProject(JVM_MOCK_RUNTIME) - val result = buildAllModules() - result.assertSuccessful() - - // Check that outputs are located properly - val facadeWithA = findFileInOutputDir(findModule("module1"), "test/AKt.class") - val facadeWithB = findFileInOutputDir(findModule("module2"), "test/BKt.class") - UsefulTestCase.assertSameElements(getMethodsOfClass(facadeWithA), "<clinit>", "a", "funA", "getA") - UsefulTestCase.assertSameElements(getMethodsOfClass(facadeWithB), "<clinit>", "b", "funB", "getB", "setB") - - if (IncrementalCompilation.isEnabledForJvm()) { - checkWhen(touch("module1/src/a.kt"), null, packageClasses("module1", "module1/src/a.kt", "test.TestPackage")) - checkWhen(touch("module2/src/b.kt"), null, packageClasses("module2", "module2/src/b.kt", "test.TestPackage")) - } else { - val allProductionClasses = myProject.outputPaths(tests = false) - checkWhen(touch("module1/src/a.kt"), null, allProductionClasses) - checkWhen(touch("module2/src/b.kt"), null, allProductionClasses) - } - } - - fun testInternalFromAnotherModule() { - initProject(JVM_MOCK_RUNTIME) - val result = buildAllModules() - result.assertFailed() - result.checkErrors() - } - - fun testInternalFromSpecialRelatedModule() { - initProject(JVM_MOCK_RUNTIME) - buildAllModules().assertSuccessful() - - val classpath = listOf("out/production/module1", "out/test/module2").map { File(workDir, it).toURI().toURL() }.toTypedArray() - val clazz = URLClassLoader(classpath).loadClass("test2.BarKt") - clazz.getMethod("box").invoke(null) - } - - fun testCircularDependenciesInternalFromAnotherModule() { - initProject(JVM_MOCK_RUNTIME) - val result = buildAllModules() - result.assertFailed() - result.checkErrors() - } - - fun testCircularDependenciesWrongInternalFromTests() { - initProject(JVM_MOCK_RUNTIME) - val result = buildAllModules() - result.assertFailed() - result.checkErrors() - } - - fun testCircularDependencyWithReferenceToOldVersionLib() { - initProject(JVM_MOCK_RUNTIME) - - val sources = listOf(File(workDir, "oldModuleLib/src")) - val libraryJar = KotlinCompilerStandalone(sources).compile() - - addDependency( - JpsJavaDependencyScope.COMPILE, - listOf(findModule("module1"), findModule("module2")), - false, - "module-lib", - libraryJar, - ) - - val result = buildAllModules() - result.assertSuccessful() - } - - fun testDependencyToOldKotlinLib() { - initProject() - - val sources = listOf(File(workDir, "oldModuleLib/src")) - val libraryJar = KotlinCompilerStandalone(sources).compile() - - addDependency(JpsJavaDependencyScope.COMPILE, listOf(findModule("module")), false, "module-lib", libraryJar) - - addKotlinStdlibDependency() - - val result = buildAllModules() - result.assertSuccessful() - } - - fun testDevKitProject() { - initProject(JVM_MOCK_RUNTIME) - val module = myProject.modules.single() - assertEquals(module.moduleType, JpsPluginModuleType.INSTANCE) - buildAllModules().assertSuccessful() - assertFilesExistInOutput(module, "TestKt.class") - } - - fun testAccessToInternalInProductionFromTests() { - initProject(JVM_MOCK_RUNTIME) - val result = buildAllModules() - result.assertSuccessful() - } - - private fun createKotlinJavaScriptLibraryArchive() { - val jarFile = File(workDir, KOTLIN_JS_LIBRARY_JAR) - try { - val zip = ZipOutputStream(FileOutputStream(jarFile)) - ZipUtil.addDirToZipRecursively(zip, jarFile, File(PATH_TO_KOTLIN_JS_LIBRARY), "", null, null) - zip.close() - } catch (ex: FileNotFoundException) { - throw IllegalStateException(ex.message) - } catch (ex: IOException) { - throw IllegalStateException(ex.message) - } - - } - - protected fun checkOutputFilesList(outputDir: File = productionOutputDir) { - if (!expectedOutputFile.exists()) { - expectedOutputFile.writeText("") - throw IllegalStateException("$expectedOutputFile did not exist. Created empty file.") - } - - val sb = StringBuilder() - val p = Printer(sb, " ") - outputDir.printFilesRecursively(p) - - UsefulTestCase.assertSameLinesWithFile(expectedOutputFile.canonicalPath, sb.toString(), true) - } - - private fun File.printFilesRecursively(p: Printer) { - val files = listFiles() ?: return - - for (file in files.sortedBy { it.name }) { - when { - file.isFile -> { - p.println(file.name) - } - file.isDirectory -> { - p.println(file.name + "/") - p.pushIndent() - file.printFilesRecursively(p) - p.popIndent() - } - } - } - } - - private val productionOutputDir - get() = File(workDir, "out/production") - - private fun getOutputDir(moduleName: String): File = File(productionOutputDir, moduleName) - - fun testReexportedDependency() { - initProject() - addKotlinStdlibDependency(myProject.modules.filter { module -> module.name == "module2" }, true) - buildAllModules().assertSuccessful() - } - - fun testCheckIsCancelledIsCalledOftenEnough() { - val classCount = 30 - val methodCount = 30 - - fun generateFiles() { - val srcDir = File(workDir, "src") - srcDir.mkdirs() - - for (i in 0..classCount) { - val code = buildString { - appendLine("package foo") - appendLine("class Foo$i {") - for (j in 0..methodCount) { - appendLine(" fun get${j * j}(): Int = square($j)") - } - appendLine("}") - - } - File(srcDir, "Foo$i.kt").writeText(code) - } - } - - generateFiles() - initProject(JVM_MOCK_RUNTIME) - - var checkCancelledCalledCount = 0 - val countingCancelledStatus = CanceledStatus { - checkCancelledCalledCount++ - false - } - - val logger = TestProjectBuilderLogger() - val buildResult = BuildResult() - - buildCustom(countingCancelledStatus, logger, buildResult) - - buildResult.assertSuccessful() - assert(checkCancelledCalledCount > classCount) { - "isCancelled should be called at least once per class. Expected $classCount, but got $checkCancelledCalledCount" - } - } - - fun testCancelKotlinCompilation() { - initProject(JVM_MOCK_RUNTIME) - buildAllModules().assertSuccessful() - - val module = myProject.modules[0] - assertFilesExistInOutput(module, "foo/Bar.class") - - val buildResult = BuildResult() - val canceledStatus = object : CanceledStatus { - var checkFromIndex = 0 - - override fun isCanceled(): Boolean { - val messages = buildResult.getMessages(BuildMessage.Kind.INFO) - for (i in checkFromIndex until messages.size) { - if (messages[i].messageText.matches("kotlinc-jvm .+ \\(JRE .+\\)".toRegex())) { - return true - } - } - - checkFromIndex = messages.size - return false - } - } - - touch("src/Bar.kt").apply() - buildCustom(canceledStatus, TestProjectBuilderLogger(), buildResult) - assertCanceled(buildResult) - } - - fun testFileDoesNotExistWarning() { - fun absoluteFiles(vararg paths: String): Array<File> = - paths.map { File(it).absoluteFile }.toTypedArray() - - initProject(JVM_MOCK_RUNTIME) - - val filesToBeReported = absoluteFiles("badroot.jar", "some/test.class") - val otherFiles = absoluteFiles("test/other/file.xml", "some/other/baddir") - - addDependency( - JpsJavaDependencyScope.COMPILE, - listOf(findModule("module")), - false, - "LibraryWithBadRoots", - *(filesToBeReported + otherFiles), - ) - - val result = buildAllModules() - result.assertSuccessful() - - val actualWarnings = result.getMessages(BuildMessage.Kind.WARNING).map { it.messageText } - val expectedWarnings = filesToBeReported.map { "Classpath entry points to a non-existent location: $it" } - - val expectedText = expectedWarnings.sorted().joinToString("\n") - val actualText = actualWarnings.sorted().joinToString("\n") - - Assert.assertEquals(expectedText, actualText) - } - - fun testHelp() { - initProject() - - val result = buildAllModules() - result.assertSuccessful() - val warning = result.getMessages(BuildMessage.Kind.WARNING).single() - - val expectedText = StringUtil.convertLineSeparators(Usage.render(K2JVMCompiler(), K2JVMCompilerArguments())) - Assert.assertEquals(expectedText, warning.messageText) - } - - fun testWrongArgument() { - initProject() - - val result = buildAllModules() - result.assertFailed() - val errors = result.getMessages(BuildMessage.Kind.ERROR).joinToString("\n\n") { it.messageText } - - Assert.assertEquals("Invalid argument: -abcdefghij-invalid-argument", errors) - } - - fun testCodeInKotlinPackage() { - initProject(JVM_MOCK_RUNTIME) - - val result = buildAllModules() - result.assertFailed() - val errors = result.getMessages(BuildMessage.Kind.ERROR) - - Assert.assertEquals("Only the Kotlin standard library is allowed to use the 'kotlin' package", errors.single().messageText) - } - - fun testDoNotCreateUselessKotlinIncrementalCaches() { - initProject(JVM_MOCK_RUNTIME) - buildAllModules().assertSuccessful() - - val storageRoot = BuildDataPathsImpl(myDataStorageRoot).dataStorageRoot - assertFalse(File(storageRoot, "targets/java-test/kotlinProject/kotlin").exists()) - assertFalse(File(storageRoot, "targets/java-production/kotlinProject/kotlin").exists()) - } - - fun testDoNotCreateUselessKotlinIncrementalCachesForDependentTargets() { - initProject(JVM_MOCK_RUNTIME) - buildAllModules().assertSuccessful() - - if (IncrementalCompilation.isEnabledForJvm()) { - checkWhen(touch("src/utils.kt"), null, packageClasses("kotlinProject", "src/utils.kt", "_DefaultPackage")) - } else { - val allClasses = findModule("kotlinProject").outputFilesPaths() - checkWhen(touch("src/utils.kt"), null, allClasses.toTypedArray()) - } - - val storageRoot = BuildDataPathsImpl(myDataStorageRoot).dataStorageRoot - assertFalse(File(storageRoot, "targets/java-production/kotlinProject/kotlin").exists()) - assertFalse(File(storageRoot, "targets/java-production/module2/kotlin").exists()) - } - - fun testKotlinProjectWithEmptyProductionOutputDir() { - initProject(JVM_MOCK_RUNTIME) - val result = buildAllModules() - result.assertFailed() - result.checkErrors() - } - - fun testKotlinProjectWithEmptyTestOutputDir() { - doTest() - } - - fun testKotlinProjectWithEmptyProductionOutputDirWithoutSrcDir() { - doTest() - } - - fun testKotlinProjectWithEmptyOutputDirInSomeModules() { - doTest() - } - - fun testGetDependentTargets() { - fun addModuleWithSourceAndTestRoot(name: String): JpsModule { - return addModule(name, "src/").apply { - contentRootsList.addUrl(JpsPathUtil.pathToUrl("test/")) - addSourceRoot(JpsPathUtil.pathToUrl("test/"), JavaSourceRootType.TEST_SOURCE) - } - } - - // c -> b -exported-> a - // c2 -> b2 ------------^ - - val a = addModuleWithSourceAndTestRoot("a") - val b = addModuleWithSourceAndTestRoot("b") - val c = addModuleWithSourceAndTestRoot("c") - val b2 = addModuleWithSourceAndTestRoot("b2") - val c2 = addModuleWithSourceAndTestRoot("c2") - - JpsModuleRootModificationUtil.addDependency(b, a, JpsJavaDependencyScope.COMPILE, /*exported =*/ true) - JpsModuleRootModificationUtil.addDependency(c, b, JpsJavaDependencyScope.COMPILE, /*exported =*/ false) - JpsModuleRootModificationUtil.addDependency(b2, a, JpsJavaDependencyScope.COMPILE, /*exported =*/ false) - JpsModuleRootModificationUtil.addDependency(c2, b2, JpsJavaDependencyScope.COMPILE, /*exported =*/ false) - - val actual = StringBuilder() - buildCustom(CanceledStatus.NULL, TestProjectBuilderLogger(), BuildResult()) { - project.setTestingContext(TestingContext(LookupTracker.DO_NOTHING, object : TestingBuildLogger { - override fun chunkBuildStarted(context: CompileContext, chunk: ModuleChunk) { - actual.append("Targets dependent on ${chunk.targets.joinToString()}:\n") - val dependentRecursively = mutableSetOf<KotlinChunk>() - context.kotlin.getChunk(chunk)!!.collectDependentChunksRecursivelyExportedOnly(dependentRecursively) - dependentRecursively.asSequence().map { it.targets.joinToString() }.sorted().joinTo(actual, "\n") - actual.append("\n---------\n") - } - - override fun afterChunkBuildStarted(context: CompileContext, chunk: ModuleChunk) {} - override fun invalidOrUnusedCache( - chunk: KotlinChunk?, - target: KotlinModuleBuildTarget<*>?, - attributesDiff: CacheAttributesDiff<*> - ) { - } - - override fun addCustomMessage(message: String) {} - override fun buildFinished(exitCode: ModuleLevelBuilder.ExitCode) {} - override fun markedAsDirtyBeforeRound(files: Iterable<File>) {} - override fun markedAsDirtyAfterRound(files: Iterable<File>) {} - })) - } - - val expectedFile = File(getCurrentTestDataRoot(), "expected.txt") - - KotlinTestUtils.assertEqualsToFile(expectedFile, actual.toString()) - } - - fun testCustomDestination() { - loadProject(workDir.absolutePath + File.separator + PROJECT_NAME + ".ipr") - addKotlinStdlibDependency() - buildAllModules().apply { - assertSuccessful() - - val aClass = File(workDir, "customOut/A.class") - assert(aClass.exists()) { "$aClass does not exist!" } - - val warnings = getMessages(BuildMessage.Kind.WARNING) - assert(warnings.isEmpty()) { "Unexpected warnings: \n${warnings.joinToString("\n")}" } - } - } - - private fun BuildResult.checkErrors() { - val actualErrors = getMessages(BuildMessage.Kind.ERROR) - .map { it as CompilerMessage } - .map { "${it.messageText} at line ${it.line}, column ${it.column}" }.sorted().joinToString("\n") - val expectedFile = File(getCurrentTestDataRoot(), "errors.txt") - KotlinTestUtils.assertEqualsToFile(expectedFile, actualErrors) - } - - private fun getCurrentTestDataRoot() = File(TEST_DATA_PATH + "general/" + getTestName(false)) - - private fun buildCustom( - canceledStatus: CanceledStatus, - logger: TestProjectBuilderLogger, - buildResult: BuildResult, - setupProject: ProjectDescriptor.() -> Unit = {} - ) { - val scopeBuilder = CompileScopeTestBuilder.make().allModules() - val descriptor = this.createProjectDescriptor(BuildLoggingManager(logger)) - - descriptor.setupProject() - - try { - val builder = IncProjectBuilder(descriptor, BuilderRegistry.getInstance(), this.myBuildParams, canceledStatus, true) - builder.addMessageHandler(buildResult) - builder.build(scopeBuilder.build(), false) - } finally { - descriptor.dataManager.flush(false) - descriptor.release() - } - } - - private fun assertCanceled(buildResult: BuildResult) { - val list = buildResult.getMessages(BuildMessage.Kind.INFO) - assertTrue("The build has been canceled" == list.last().messageText) - } - - private fun findModule(name: String): JpsModule { - for (module in myProject.modules) { - if (module.name == name) { - return module - } - } - throw IllegalStateException("Couldn't find module $name") - } - - protected fun checkWhen(action: Action, pathsToCompile: Array<String>?, pathsToDelete: Array<String>?) { - checkWhen(arrayOf(action), pathsToCompile, pathsToDelete) - } - - protected fun checkWhen(actions: Array<Action>, pathsToCompile: Array<String>?, pathsToDelete: Array<String>?) { - for (action in actions) { - action.apply() - } - - buildAllModules().assertSuccessful() - - if (pathsToCompile != null) { - assertCompiled(KotlinBuilder.KOTLIN_BUILDER_NAME, *pathsToCompile) - } - - if (pathsToDelete != null) { - assertDeleted(*pathsToDelete) - } - } - - protected fun packageClasses(moduleName: String, fileName: String, packageClassFqName: String): Array<String> { - return arrayOf(module(moduleName), packagePartClass(moduleName, fileName, packageClassFqName)) - } - - protected fun packagePartClass(moduleName: String, fileName: String, packageClassFqName: String): String { - val path = FileUtilRt.toSystemIndependentName(File(workDir, fileName).absolutePath) - val fakeVirtualFile = object : LightVirtualFile(path.substringAfterLast('/')) { - override fun getPath(): String { - // strip extra "/" from the beginning - return path.substring(1) - } - } - - val packagePartFqName = PackagePartClassUtils.getDefaultPartFqName(FqName(packageClassFqName), fakeVirtualFile) - return klass(moduleName, AsmUtil.internalNameByFqNameWithoutInnerClasses(packagePartFqName)) - } - - private fun JpsProject.outputPaths(production: Boolean = true, tests: Boolean = true) = - modules.flatMap { it.outputFilesPaths(production = production, tests = tests) }.toTypedArray() - - private fun JpsModule.outputFilesPaths(production: Boolean = true, tests: Boolean = true): List<String> { - val outputFiles = arrayListOf<File>() - if (production) { - prodOut.walk().filterTo(outputFiles) { it.isFile } - } - if (tests) { - testsOut.walk().filterTo(outputFiles) { it.isFile } - } - return outputFiles.map { FileUtilRt.toSystemIndependentName(it.relativeTo(workDir).path) } - } - - private val JpsModule.prodOut: File - get() = outDir(forTests = false) - - private val JpsModule.testsOut: File - get() = outDir(forTests = true) - - private fun JpsModule.outDir(forTests: Boolean) = - JpsJavaExtensionService.getInstance().getOutputDirectory(this, forTests)!! - - protected enum class Operation { - CHANGE, - DELETE - } - - protected fun touch(path: String): Action = Action(Operation.CHANGE, path) - - protected fun del(path: String): Action = Action(Operation.DELETE, path) - - // TODO inline after KT-3974 will be fixed - protected fun touch(file: File): Unit = change(file.absolutePath) - - protected inner class Action constructor(private val operation: Operation, private val path: String) { - fun apply() { - val file = File(workDir, path) - when (operation) { - Operation.CHANGE -> - touch(file) - Operation.DELETE -> - assertTrue("Can not delete file \"" + file.absolutePath + "\"", file.delete()) - } - } - } -} - -private inline fun <R> withIC(enabled: Boolean = true, fn: () -> R): R { - val isEnabledBackup = IncrementalCompilation.isEnabledForJvm() - IncrementalCompilation.setIsEnabledForJvm(enabled) - - try { - return fn() - } finally { - IncrementalCompilation.setIsEnabledForJvm(isEnabledBackup) - } -}
\ No newline at end of file |