refactored CommandLineArguments assertions functions

#KT-51553 In Progress
This commit is contained in:
Dmitrii Krasnov
2023-05-12 11:44:17 +02:00
committed by Space Team
parent c3ac2e44a0
commit 958b0e6ebc
4 changed files with 53 additions and 49 deletions
@@ -8,7 +8,6 @@ package org.jetbrains.kotlin.gradle
import org.gradle.api.logging.LogLevel import org.gradle.api.logging.LogLevel
import org.gradle.util.GradleVersion import org.gradle.util.GradleVersion
import org.jetbrains.kotlin.gradle.testbase.* import org.jetbrains.kotlin.gradle.testbase.*
import org.jetbrains.kotlin.gradle.util.AGPVersion
import org.jetbrains.kotlin.konan.target.HostManager import org.jetbrains.kotlin.konan.target.HostManager
import org.jetbrains.kotlin.konan.target.KonanTarget import org.jetbrains.kotlin.konan.target.KonanTarget
import org.junit.jupiter.api.DisplayName import org.junit.jupiter.api.DisplayName
@@ -142,8 +141,8 @@ class ExplicitApiIT : KGPBaseTest() {
if (nativeTaskName != null) { if (nativeTaskName != null) {
build(nativeTaskName) { build(nativeTaskName) {
assertTasksExecuted(nativeTaskName) assertTasksExecuted(nativeTaskName)
assertNativeTasksCommandLineArguments(nativeTaskName) { extractNativeTasksCommandLineArgumentsFromOutput(nativeTaskName) {
assertCommandLineArgumentsContain("-Xexplicit-api=warning", commandLineArguments = it) assertCommandLineArgumentsContain("-Xexplicit-api=warning")
} }
} }
} }
@@ -156,7 +155,7 @@ class ExplicitApiIT : KGPBaseTest() {
fun explicitApiAndroid( fun explicitApiAndroid(
gradleVersion: GradleVersion, gradleVersion: GradleVersion,
agpVersion: String, agpVersion: String,
jdkVersion: JdkVersions.ProvidedJdk jdkVersion: JdkVersions.ProvidedJdk,
) { ) {
project( project(
"AndroidSimpleApp", "AndroidSimpleApp",
@@ -66,9 +66,9 @@ class NativeLibraryDslIT : KGPBaseTest() {
assertTasksNotExecuted( assertTasksNotExecuted(
":lib:compileKotlinLinuxX64" ":lib:compileKotlinLinuxX64"
) )
assertNativeTasksCommandLineArguments(":shared:assembleMylibDebugSharedLibraryLinuxX64") { extractNativeTasksCommandLineArgumentsFromOutput(":shared:assembleMylibDebugSharedLibraryLinuxX64") {
assertCommandLineArgumentsDoNotContain("-Xfoo=bar", "-Xbaz=qux", commandLineArguments = it) assertCommandLineArgumentsDoNotContain("-Xfoo=bar", "-Xbaz=qux")
assertCommandLineArgumentsContain("-Xmen=pool", commandLineArguments = it) assertCommandLineArgumentsContain("-Xmen=pool")
} }
assertFileInProjectExists("shared/build/out/dynamic/linux_x64/debug/libmylib.so") assertFileInProjectExists("shared/build/out/dynamic/linux_x64/debug/libmylib.so")
assertFileInProjectExists("shared/build/out/dynamic/linux_x64/debug/libmylib_api.h") assertFileInProjectExists("shared/build/out/dynamic/linux_x64/debug/libmylib_api.h")
@@ -89,8 +89,8 @@ class NativeLibraryDslIT : KGPBaseTest() {
assertTasksNotExecuted( assertTasksNotExecuted(
":lib:compileKotlinLinuxX64" ":lib:compileKotlinLinuxX64"
) )
assertNativeTasksCommandLineArguments(":shared:assembleMylibDebugSharedLibraryLinuxX64") { extractNativeTasksCommandLineArgumentsFromOutput(":shared:assembleMylibDebugSharedLibraryLinuxX64") {
assertCommandLineArgumentsContain("-Xfoo=bar", "-Xbaz=qux", "-Xmen=pool", commandLineArguments = it) assertCommandLineArgumentsContain("-Xfoo=bar", "-Xbaz=qux", "-Xmen=pool")
} }
assertFileInProjectExists("shared/build/out/dynamic/linux_x64/debug/libmylib.so") assertFileInProjectExists("shared/build/out/dynamic/linux_x64/debug/libmylib.so")
assertFileInProjectExists("shared/build/out/dynamic/linux_x64/debug/libmylib_api.h") assertFileInProjectExists("shared/build/out/dynamic/linux_x64/debug/libmylib_api.h")
@@ -5,7 +5,6 @@
package org.jetbrains.kotlin.gradle.testbase package org.jetbrains.kotlin.gradle.testbase
import org.gradle.api.logging.LogLevel
import org.gradle.api.logging.configuration.WarningMode import org.gradle.api.logging.configuration.WarningMode
import org.gradle.testkit.runner.BuildResult import org.gradle.testkit.runner.BuildResult
@@ -14,7 +13,7 @@ import org.gradle.testkit.runner.BuildResult
*/ */
fun BuildResult.assertOutputContains( fun BuildResult.assertOutputContains(
expectedSubString: String, expectedSubString: String,
message: String = "Build output does not contain \"$expectedSubString\"" message: String = "Build output does not contain \"$expectedSubString\"",
) { ) {
assert(output.contains(expectedSubString)) { assert(output.contains(expectedSubString)) {
printBuildOutput() printBuildOutput()
@@ -26,7 +25,7 @@ fun BuildResult.assertOutputContains(
* Asserts Gradle output contains any of [expectedSubString] strings. * Asserts Gradle output contains any of [expectedSubString] strings.
*/ */
fun BuildResult.assertOutputContainsAny( fun BuildResult.assertOutputContainsAny(
vararg expectedSubStrings: String vararg expectedSubStrings: String,
) { ) {
assert(expectedSubStrings.any { output.contains(it) }) { assert(expectedSubStrings.any { output.contains(it) }) {
printBuildOutput() printBuildOutput()
@@ -39,7 +38,7 @@ fun BuildResult.assertOutputContainsAny(
*/ */
fun BuildResult.assertOutputContainsExactTimes( fun BuildResult.assertOutputContainsExactTimes(
expectedSubString: String, expectedSubString: String,
expectedRepetitionTimes: Int = 1 expectedRepetitionTimes: Int = 1,
) { ) {
var currentOffset = 0 var currentOffset = 0
var count = 0 var count = 0
@@ -103,7 +102,7 @@ fun BuildResult.assertOutputDoesNotContain(
* Assert build output contains one or more strings matching [expected] regex. * Assert build output contains one or more strings matching [expected] regex.
*/ */
fun BuildResult.assertOutputContains( fun BuildResult.assertOutputContains(
expected: Regex expected: Regex,
) { ) {
assert(output.contains(expected)) { assert(output.contains(expected)) {
printBuildOutput() printBuildOutput()
@@ -116,7 +115,7 @@ fun BuildResult.assertOutputContains(
* Asserts build output does not contain any lines matching [regexToCheck] regex. * Asserts build output does not contain any lines matching [regexToCheck] regex.
*/ */
fun BuildResult.assertOutputDoesNotContain( fun BuildResult.assertOutputDoesNotContain(
regexToCheck: Regex regexToCheck: Regex,
) { ) {
assert(!output.contains(regexToCheck)) { assert(!output.contains(regexToCheck)) {
printBuildOutput() printBuildOutput()
@@ -134,14 +133,14 @@ fun BuildResult.assertOutputDoesNotContain(
*/ */
fun BuildResult.assertOutputContainsExactlyTimes( fun BuildResult.assertOutputContainsExactlyTimes(
expected: String, expected: String,
expectedCount: Int = 1 expectedCount: Int = 1,
) { ) {
assertOutputContainsExactlyTimes(expected.toRegex(RegexOption.LITERAL), expectedCount) assertOutputContainsExactlyTimes(expected.toRegex(RegexOption.LITERAL), expectedCount)
} }
fun BuildResult.assertOutputContainsExactlyTimes( fun BuildResult.assertOutputContainsExactlyTimes(
expected: Regex, expected: Regex,
expectedCount: Int = 1 expectedCount: Int = 1,
) { ) {
val occurrenceCount = expected.findAll(output).count() val occurrenceCount = expected.findAll(output).count()
assert(occurrenceCount == expectedCount) { assert(occurrenceCount == expectedCount) {
@@ -155,7 +154,7 @@ fun BuildResult.assertOutputContainsExactlyTimes(
* Assert build contains no warnings. * Assert build contains no warnings.
*/ */
fun BuildResult.assertNoBuildWarnings( fun BuildResult.assertNoBuildWarnings(
expectedWarnings: Set<String> = emptySet() expectedWarnings: Set<String> = emptySet(),
) { ) {
val cleanedOutput = expectedWarnings.fold(output) { acc, s -> val cleanedOutput = expectedWarnings.fold(output) { acc, s ->
acc.replace(s, "") acc.replace(s, "")
@@ -176,7 +175,7 @@ fun BuildResult.assertNoBuildWarnings(
* Asserts compilation is running via Kotlin daemon with given jvm arguments. * Asserts compilation is running via Kotlin daemon with given jvm arguments.
*/ */
fun BuildResult.assertKotlinDaemonJvmOptions( fun BuildResult.assertKotlinDaemonJvmOptions(
expectedJvmArgs: List<String> expectedJvmArgs: List<String>,
) { ) {
val jvmArgsCommonMessage = "Kotlin compile daemon JVM options: " val jvmArgsCommonMessage = "Kotlin compile daemon JVM options: "
assertOutputContains(jvmArgsCommonMessage) assertOutputContains(jvmArgsCommonMessage)
@@ -270,38 +269,19 @@ fun BuildResult.assertNoCompilerArgument(
} }
} }
/**
* Asserts command line arguments of the given K/N compiler for given tasks' paths
*
* Note: Log level of output must be set to [LogLevel.DEBUG].
*
* @param tasksPaths tasks' paths, for which command line arguments should be checked with give assertions
* @param toolName name of build tool
* @param assertions assertions, with will be applied to each command line arguments of each given task
*/
fun BuildResult.assertNativeTasksCommandLineArguments(
vararg tasksPaths: String,
toolName: NativeToolKind = NativeToolKind.KONANC,
assertions: (List<String>) -> Unit
) = tasksPaths.forEach { taskPath ->
assertions(extractNativeCompilerCommandLineArguments(getOutputForTask(taskPath), toolName))
}
/** /**
* Asserts that the given list of command line arguments does not contain any of the expected arguments. * Asserts that the given list of command line arguments does not contain any of the expected arguments.
* *
* @param expectedArgs the list of expected arguments * @param expectedArgs the list of expected arguments
* @param commandLineArguments the list of actual command line arguments
* @throws AssertionError if any of the expected arguments are found in the actual arguments list * @throws AssertionError if any of the expected arguments are found in the actual arguments list
*/ */
fun BuildResult.assertCommandLineArgumentsDoNotContain( fun CommandLineArguments.assertCommandLineArgumentsDoNotContain(
vararg expectedArgs: String, vararg expectedArgs: String,
commandLineArguments: List<String>
) { ) {
expectedArgs.forEach { expectedArgs.forEach {
assert(!commandLineArguments.contains(it)) { assert(!args.contains(it)) {
printBuildOutput() this.buildResult.printBuildOutput()
"There is unexpected ${it} in actual command line arguments are: ${commandLineArguments}" "There is unexpected ${it} in actual command line arguments are: ${args}"
} }
} }
} }
@@ -310,17 +290,15 @@ fun BuildResult.assertCommandLineArgumentsDoNotContain(
* Asserts that the given list of command line arguments contains all the expected arguments. * Asserts that the given list of command line arguments contains all the expected arguments.
* *
* @param expectedArgs the list of expected arguments * @param expectedArgs the list of expected arguments
* @param commandLineArguments the list of actual command line arguments
* @throws AssertionError if any of the expected arguments are missing from the actual arguments list * @throws AssertionError if any of the expected arguments are missing from the actual arguments list
*/ */
fun BuildResult.assertCommandLineArgumentsContain( fun CommandLineArguments.assertCommandLineArgumentsContain(
vararg expectedArgs: String, vararg expectedArgs: String,
commandLineArguments: List<String>
) { ) {
expectedArgs.forEach { expectedArgs.forEach {
assert(commandLineArguments.contains(it)) { assert(args.contains(it)) {
printBuildOutput() this.buildResult.printBuildOutput()
"There is no ${it} in actual command line arguments are: ${commandLineArguments}" "There is no ${it} in actual command line arguments are: ${args}"
} }
} }
} }
@@ -11,7 +11,7 @@ import org.intellij.lang.annotations.Language
@Language("RegExp") @Language("RegExp")
private fun taskOutputRegex( private fun taskOutputRegex(
taskName: String taskName: String,
) = """ ) = """
\[org\.gradle\.internal\.operations\.DefaultBuildOperationRunner] Build operation 'Task $taskName' started \[org\.gradle\.internal\.operations\.DefaultBuildOperationRunner] Build operation 'Task $taskName' started
([\s\S]+?) ([\s\S]+?)
@@ -36,3 +36,30 @@ fun getOutputForTask(taskPath: String, output: String): String = taskOutputRegex
.find(output) .find(output)
?.let { it.groupValues[1] } ?.let { it.groupValues[1] }
?: error("Could not find output for task $taskPath") ?: error("Could not find output for task $taskPath")
class CommandLineArguments(
val args: List<String>,
val buildResult: BuildResult,
)
/**
* Asserts the command line arguments of the given Kotlin/Native (K/N) compiler for the specified tasks' paths.
*
* Note: The log level of the output must be set to [LogLevel.DEBUG].
*
* @param tasksPaths The paths of the tasks for which the command line arguments should be checked against the provided assertions.
* @param toolName The name of the build tool used.
* @param assertions The assertions to be applied to each command line argument of each given task.
* These assertions validate the expected properties of the command line arguments.
*/
fun BuildResult.extractNativeTasksCommandLineArgumentsFromOutput(
vararg tasksPaths: String,
toolName: NativeToolKind = NativeToolKind.KONANC,
assertions: CommandLineArguments.() -> Unit,
) = tasksPaths.forEach { taskPath ->
val taskOutput = getOutputForTask(taskPath)
val commandLineArguments = extractNativeCompilerCommandLineArguments(taskOutput, toolName)
assertions(
CommandLineArguments(commandLineArguments, this)
)
}