From 71e81aa30e20e36694528d90acb7fead9421c945 Mon Sep 17 00:00:00 2001 From: "Nataliya.Valtman" Date: Wed, 3 May 2023 17:22:11 +0200 Subject: [PATCH] Fix build reports when no kotlin task is executed #KT-58313: Fixed --- .../statistics/file/FileReportService.kt | 2 +- .../jetbrains/kotlin/gradle/BuildReportsIT.kt | 87 +++++++++++-------- .../kotlin/gradle/FusStatisticsIT.kt | 11 +-- .../kotlin/gradle/testbase/pathHelpers.kt | 13 +++ 4 files changed, 65 insertions(+), 48 deletions(-) diff --git a/compiler/build-tools/kotlin-build-statistics/src/org/jetbrains/kotlin/build/report/statistics/file/FileReportService.kt b/compiler/build-tools/kotlin-build-statistics/src/org/jetbrains/kotlin/build/report/statistics/file/FileReportService.kt index ecd1331344b..f10eec27c74 100644 --- a/compiler/build-tools/kotlin-build-statistics/src/org/jetbrains/kotlin/build/report/statistics/file/FileReportService.kt +++ b/compiler/build-tools/kotlin-build-statistics/src/org/jetbrains/kotlin/build/report/statistics/file/FileReportService.kt @@ -78,7 +78,7 @@ class FileReportService( // a bit unfamiliar. // TODO: If it is confusing, consider renaming "tasks" to "build operations" in this class. printBuildInfo(startParameters, failureMessages) - if (printMetrics) { + if (printMetrics && statisticsData.isNotEmpty()) { printMetrics( statisticsData.map { it.buildTimesMetrics }.reduce { agg, value -> (agg.keys + value.keys).associateWith { (agg[it] ?: 0) + (value[it] ?: 0) } diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/BuildReportsIT.kt b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/BuildReportsIT.kt index 4211f4c1043..94250088da4 100644 --- a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/BuildReportsIT.kt +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/BuildReportsIT.kt @@ -12,9 +12,8 @@ import org.jetbrains.kotlin.gradle.report.BuildReportType import org.jetbrains.kotlin.gradle.testbase.* import org.junit.jupiter.api.DisplayName import java.io.ObjectInputStream +import java.nio.file.Path import kotlin.io.path.* -import kotlin.test.assertEquals -import kotlin.test.assertNotNull import kotlin.test.assertTrue @DisplayName("Build reports") @@ -25,6 +24,9 @@ class BuildReportsIT : KGPBaseTest() { buildReport = listOf(BuildReportType.FILE) ) + private val GradleProject.reportFile: Path + get() = projectPath.getSingleFileInDir("build/reports/kotlin-build") + @DisplayName("Build report is created") @GradleTest fun testBuildReportSmokeTest(gradleVersion: GradleVersion) { @@ -56,26 +58,23 @@ class BuildReportsIT : KGPBaseTest() { build("assemble") { assertBuildReportPathIsPrinted() } - val reportFolder = projectPath.resolve("build/reports/kotlin-build").toFile() - val reports = reportFolder.listFiles() - assertNotNull(reports) - assertEquals(1, reports.size) - val report = reports[0].readText() - //Should contains build metrics for all compile kotlin tasks - assertTrue { report.contains("Time metrics:") } - assertTrue { report.contains("Run compilation:") } - assertTrue { report.contains("Incremental compilation in daemon:") } - assertTrue { report.contains("Size metrics:") } - assertTrue { report.contains("Total size of the cache directory:") } - assertTrue { report.contains("Total compiler iteration:") } - assertTrue { report.contains("ABI snapshot size:") } - //for non-incremental builds - assertTrue { report.contains("Build attributes:") } - assertTrue { report.contains("REBUILD_REASON:") } - //gc metrics - assertTrue {report.contains("GC count:")} - assertTrue {report.contains("GC time:")} + assertFileContains( + reportFile, + "Time metrics:", + "Run compilation:", + "Incremental compilation in daemon:", + "Size metrics:", + "Total size of the cache directory:", + "Total compiler iteration:", + "ABI snapshot size:", + //for non-incremental builds + "Build attributes:", + "REBUILD_REASON:", + //gc metrics + "GC count:", + "GC time:", + ) } } @@ -86,14 +85,26 @@ class BuildReportsIT : KGPBaseTest() { build("assemble") { assertBuildReportPathIsPrinted() } - val reportFolder = projectPath.resolve("build/reports/kotlin-build").toFile() - val reports = reportFolder.listFiles() - assertNotNull(reports) - assertEquals(1, reports.size) - val report = reports[0].readText() - assertTrue { report.contains("Compiler code analysis:") } - assertTrue { report.contains("Compiler code generation:") } - assertTrue { report.contains("Compiler initialization time:") } + assertFileContains( + reportFile, + "Compiler code analysis:", + "Compiler code generation:", + "Compiler initialization time:", + ) + } + } + + @DisplayName("with no kotlin task executed") + @GradleTest + fun testFileReportWithoutKotlinTask(gradleVersion: GradleVersion) { + project("simpleProject", gradleVersion) { + build("assemble", "--dry-run") { + assertBuildReportPathIsPrinted() + } + assertFileContains( + reportFile, + "No Kotlin task was run", + ) } } @@ -180,18 +191,20 @@ class BuildReportsIT : KGPBaseTest() { project("simpleProject", gradleVersion) { val lookupsTab = projectPath.resolve("build/kotlin/compileKotlin/cacheable/caches-jvm/lookups/lookups.tab") - buildGradle.appendText(""" - tasks.named("compileKotlin") { - doLast { - new File("${lookupsTab.toUri().path}").write("Invalid contents") + buildGradle.appendText( + """ + tasks.named("compileKotlin") { + doLast { + new File("${lookupsTab.toUri().path}").write("Invalid contents") + } } - } - """.trimIndent()) + """.trimIndent() + ) build("compileKotlin") { assertTrue { projectPath.resolve(kotlinErrorPath).listDirectoryEntries().isEmpty() } } val kotlinFile = kotlinSourcesDir().resolve("helloWorld.kt") - kotlinFile.modify { it.replace("ArrayList","skjfghsjk") } + kotlinFile.modify { it.replace("ArrayList", "skjfghsjk") } buildAndFail("compileKotlin") { val buildErrorDir = projectPath.resolve(kotlinErrorPath).toFile() val files = buildErrorDir.listFiles() @@ -219,7 +232,7 @@ class BuildReportsIT : KGPBaseTest() { assertTrue { projectPath.resolve(kotlinErrorPath).listDirectoryEntries().isEmpty() } } val kotlinFile = kotlinSourcesDir().resolve("helloWorld.kt") - kotlinFile.modify { it.replace("ArrayList","skjfghsjk") } + kotlinFile.modify { it.replace("ArrayList", "skjfghsjk") } buildAndFail("compileKotlin") { assertTrue { projectPath.resolve(kotlinErrorPath).listDirectoryEntries().isEmpty() } } diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/FusStatisticsIT.kt b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/FusStatisticsIT.kt index a53999319e1..73e849dd82d 100644 --- a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/FusStatisticsIT.kt +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/FusStatisticsIT.kt @@ -10,10 +10,7 @@ import org.jetbrains.kotlin.gradle.testbase.GradleTest import org.junit.jupiter.api.DisplayName import org.jetbrains.kotlin.gradle.testbase.* import org.jetbrains.kotlin.gradle.util.replaceText -import org.jetbrains.kotlin.test.KtAssert.fail -import java.nio.file.Files import java.nio.file.Path -import kotlin.streams.asSequence @DisplayName("FUS statistic") class FusStatisticsIT : KGPBaseTest() { @@ -62,13 +59,7 @@ class FusStatisticsIT : KGPBaseTest() { } private val GradleProject.fusStatisticsPath: Path - get() { - val statisticsDir = projectPath.resolve("kotlin-profile") - return Files.list(statisticsDir).use { - val files = it.asSequence().toList() - files.singleOrNull() ?: fail("The directory must contain a single statistics file, but got: $files") - } - } + get() = projectPath.getSingleFileInDir("kotlin-profile") @DisplayName("general fields") @GradleTest diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/testbase/pathHelpers.kt b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/testbase/pathHelpers.kt index 8f6b0d17e50..b9b6136b50f 100644 --- a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/testbase/pathHelpers.kt +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/testbase/pathHelpers.kt @@ -11,6 +11,7 @@ import java.nio.file.attribute.BasicFileAttributes import kotlin.io.path.* import kotlin.streams.asSequence import kotlin.streams.toList +import kotlin.test.fail /** * Find the file with given [name] in current [Path]. @@ -128,3 +129,15 @@ fun TestProject.sourceFilesRelativeToProject( it.relativeTo(projectPath) } } + +/** + * Returns a single file located in the [relativePath] subdirectory. If no file or more than one file is found an assertion error will be thrown. + */ +fun Path.getSingleFileInDir(relativePath: String): Path { + val path = resolve(relativePath) + return Files.list(path).use { + val files = it.asSequence().toList() + files.singleOrNull() ?: fail("The directory must contain a single file, but got: $files") + } +} +