Skip to content

Commit

Permalink
Merge pull request #256 from DataDog/nogorodnikov/rum-4292/solve-comp…
Browse files Browse the repository at this point in the history
…atibility-of-upload-task-with-configuration-cache

RUM-4292: Mark upload task as not compatible with configuration cache
  • Loading branch information
0xnm committed May 6, 2024
2 parents 46ee416 + c7360f4 commit db3ff0d
Show file tree
Hide file tree
Showing 3 changed files with 132 additions and 53 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,13 @@ class DdAndroidGradlePlugin @Inject constructor(
GitRepositoryDetector(execOps)
).apply {
configure { uploadTask ->
@Suppress("MagicNumber")
if (DdTaskUtils.isGradleAbove(target, 7, 5)) {
uploadTask.notCompatibleWithConfigurationCache(
"Datadog Upload Mapping task is not" +
" compatible with configuration cache yet."
)
}
val extensionConfiguration = resolveExtensionConfiguration(extension, variant)
configureVariantTask(uploadTask, apiKey, variant.flavorName, extensionConfiguration, variant)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,15 +29,23 @@ internal object DdTaskUtils {
return null
}

@Suppress("MagicNumber", "ReturnCount")
fun isAgpAbove(major: Int, minor: Int, patch: Int): Boolean {
val version = Version.ANDROID_GRADLE_PLUGIN_VERSION
val groups = version.split(".")
if (groups.size < 3) return false
val currentMajor = groups[0].toIntOrNull()
val currentMinor = groups[1].toIntOrNull()
val currentPatch = groups[2].substringBefore("-").toIntOrNull()
if (currentMajor == null || currentMinor == null || currentPatch == null) return false
return isVersionAbove(Version.ANDROID_GRADLE_PLUGIN_VERSION, major, minor, patch)
}

// Gradle version may not have patch version
fun isGradleAbove(project: Project, major: Int, minor: Int, patch: Int = 0): Boolean {
return isVersionAbove(project.gradle.gradleVersion, major, minor, patch)
}

@Suppress("MagicNumber", "ReturnCount")
private fun isVersionAbove(refVersion: String, major: Int, minor: Int, patch: Int): Boolean {
val groups = refVersion.split(".")
// should be at least major and minor versions
if (groups.size < 2) return false
val currentMajor = groups[0].toIntOrNull() ?: 0
val currentMinor = groups[1].toIntOrNull() ?: 0
val currentPatch = groups.getOrNull(2)?.substringBefore("-")?.toIntOrNull() ?: 0
return currentMajor >= major && currentMinor >= minor && currentPatch >= patch
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -109,19 +109,7 @@ internal class DdAndroidGradlePluginFunctionalTest {
stubFile(sampleApplicationClassFile, APPLICATION_CLASS_CONTENT)
stubFile(javaPlaceholderClassFile, JAVA_CLASS_CONTENT)
stubFile(appManifestFile, APP_MANIFEST_FILE_CONTENT)
stubFile(
gradlePropertiesFile,
GRADLE_PROPERTIES_FILE_CONTENT.format(
Locale.US,
buildVersionConfig.agpVersion,
buildVersionConfig.buildToolsVersion,
buildVersionConfig.targetSdkVersion,
buildVersionConfig.kotlinVersion,
PluginUnderTestMetadataReading.readImplementationClasspath()
.joinToString(",") { it.absolutePath },
buildVersionConfig.jvmTarget
)
)
stubGradlePropertiesFile(buildVersionConfig)
stubFile(libModulePlaceholderFile, LIB_MODULE_PLACEHOLDER_CLASS_CONTENT)
stubFile(libModuleManifestFile, LIB_MODULE_MANIFEST_FILE_CONTENT)
stubGradleBuildFromResourceFile(
Expand Down Expand Up @@ -260,25 +248,18 @@ internal class DdAndroidGradlePluginFunctionalTest {
assertThat(result).hasSuccessfulTaskOutcome(":samples:app:assembleDebug")
}

@Disabled(
"This test is ignored for now because of these tasks: " +
"collect[Flavour1][Flavour2]ReleaseDependencies. This is caused under the hood" +
"by this task: PerModuleReportDependenciesTask which accesses the project object" +
"inside the action method. " +
"There is already an opened issue here: https://github.com/gradle/gradle/issues/12871"
)
@Test
fun `M success W assembleRelease { configuration cache, checkProjectDependencies enabled }`() {
// TODO: https://datadoghq.atlassian.net/browse/RUMM-1894

// Given
// depends on https://github.com/gradle/gradle/issues/12871, which was released only with Gradle 7.5
stubGradlePropertiesFile(LATEST_VERSIONS_TEST_CONFIGURATION)
stubGradleBuildFromResourceFile(
"build_with_datadog_dep.gradle",
appBuildGradleFile
)

// When
val result = gradleRunner {
val result = gradleRunner(gradleVersion = LATEST_VERSIONS_TEST_CONFIGURATION.gradleVersion) {
withArguments(
"--configuration-cache",
"--stacktrace",
Expand Down Expand Up @@ -340,25 +321,18 @@ internal class DdAndroidGradlePluginFunctionalTest {
assertThat(result).hasSuccessfulTaskOutcome(":samples:app:assembleDebug")
}

@Disabled(
"This test is ignored for now because of these tasks: " +
"collect[Flavour1][Flavour2]ReleaseDependencies. This is caused under the hood" +
"by this task: PerModuleReportDependenciesTask which accesses the project object" +
"inside the action method. " +
"There is already an opened issue here: https://github.com/gradle/gradle/issues/12871"
)
@Test
fun `M success W assembleRelease { configuration cache, checkDependencies disabled }`() {
// TODO: https://datadoghq.atlassian.net/browse/RUMM-1894

// Given
// depends on https://github.com/gradle/gradle/issues/12871, which was released only with Gradle 7.5
stubGradlePropertiesFile(LATEST_VERSIONS_TEST_CONFIGURATION)
stubGradleBuildFromResourceFile(
"build_with_check_deps_disabled.gradle",
appBuildGradleFile
)

// When
val result = gradleRunner {
val result = gradleRunner(gradleVersion = LATEST_VERSIONS_TEST_CONFIGURATION.gradleVersion) {
withArguments(
"--configuration-cache",
"--stacktrace",
Expand Down Expand Up @@ -928,6 +902,73 @@ internal class DdAndroidGradlePluginFunctionalTest {
)
}

@Test
fun `M be compatible with configuration cache W assemble finalized by upload`(forge: Forge) {
// Given
// this test is using Task.notCompatibleWithConfigurationCache, which appeared only in Gradle 7.5,
// and moreover configuration cache support in Gradle is still ongoing work
stubGradlePropertiesFile(LATEST_VERSIONS_TEST_CONFIGURATION)
stubGradleBuildFromResourceFile(
"build_with_datadog_dep.gradle",
appBuildGradleFile
)
val color = forge.anElementFrom(colors)
val version = forge.anElementFrom(versions)
val variantVersionName = version.lowercase()
val variant = "${version.lowercase()}$color"

appBuildGradleFile.appendText(
"""
tasks.configureEach {
if (name == "minify${variant.capitalize()}ReleaseWithR8") {
finalizedBy(tasks.getByName("uploadMapping${variant.capitalize()}Release"))
}
}
""".trimIndent()
)

val result = gradleRunner(gradleVersion = LATEST_VERSIONS_TEST_CONFIGURATION.gradleVersion) {
withArguments(
"--info",
":samples:app:assemble${variant.capitalize()}Release",
"--stacktrace",
"-PDD_API_KEY=fakekey",
"-Pdd-emulate-upload-call",
"--configuration-cache"
)
}
.build()

// Then
assertThat(result).containsInOutput("Creating request with GZIP encoding.")

val buildIdInOriginFile = testProjectDir.findBuildIdInOriginFile(variant)
val buildIdInApk = testProjectDir.findBuildIdInApk(variant)
assertThat(buildIdInApk).isEqualTo(buildIdInOriginFile)

assertThat(result).containsInOutput(
"Uploading file jvm_mapping with tags " +
"`service:com.example.variants.$variantVersionName`, " +
"`version:1.0-$variantVersionName`, " +
"`version_code:1`, " +
"`variant:$variant`, " +
"`build_id:$buildIdInOriginFile` (site=datadoghq.com):"
)
assertThat(result).containsInOutput(
"""
Detected repository:
{
"files": [
"src/main/java/Placeholder.java",
"src/main/kotlin/SampleApplication.kt"
],
"repository_url": "$fakeRemoteUrl",
"hash": "${headHash(appRootDir)}"
}
""".trimIndent()
)
}

@Test
fun `M not contain any uploadTasks W minifyNotEnabled`() {
// Given
Expand Down Expand Up @@ -1146,8 +1187,10 @@ internal class DdAndroidGradlePluginFunctionalTest {

// region Internal

private fun resolveMappingUploadTask(variantName: String) = "uploadMapping${variantName}Release"
private fun resolveNdkSymbolUploadTask(variantName: String) = "uploadNdkSymbolFiles${variantName}Release"
private fun resolveMappingUploadTask(variantName: String) = "uploadMapping${variantName.capitalize()}Release"
private fun resolveNdkSymbolUploadTask(
variantName: String
) = "uploadNdkSymbolFiles${variantName.capitalize()}Release"

private fun stubFile(destination: File, content: String) {
with(destination.outputStream()) {
Expand All @@ -1170,9 +1213,28 @@ internal class DdAndroidGradlePluginFunctionalTest {
stubFile(cppPlaceholderFile!!, CPP_FILE_CONTENT)
}

private fun gradleRunner(configure: GradleRunner.() -> Unit): GradleRunner {
private fun stubGradlePropertiesFile(buildVersionConfig: BuildVersionConfig) {
stubFile(
gradlePropertiesFile,
GRADLE_PROPERTIES_FILE_CONTENT.format(
Locale.US,
buildVersionConfig.agpVersion,
buildVersionConfig.buildToolsVersion,
buildVersionConfig.targetSdkVersion,
buildVersionConfig.kotlinVersion,
PluginUnderTestMetadataReading.readImplementationClasspath()
.joinToString(",") { it.absolutePath },
buildVersionConfig.jvmTarget
)
)
}

private fun gradleRunner(
gradleVersion: String? = null,
configure: GradleRunner.() -> Unit
): GradleRunner {
return GradleRunner.create()
.withGradleVersion(buildVersionConfig.gradleVersion)
.withGradleVersion(gradleVersion ?: buildVersionConfig.gradleVersion)
.withProjectDir(testProjectDir)
// https://github.com/gradle/gradle/issues/22466
// for now the workaround will be to manually inject necessary files into plugin classpath
Expand Down Expand Up @@ -1363,6 +1425,15 @@ internal class DdAndroidGradlePluginFunctionalTest {
const val LATEST_GRADLE_VERSION = "8.7"
const val LATEST_AGP_VERSION = "8.4.0"

val LATEST_VERSIONS_TEST_CONFIGURATION = BuildVersionConfig(
agpVersion = LATEST_AGP_VERSION,
gradleVersion = LATEST_GRADLE_VERSION,
buildToolsVersion = "34.0.0",
targetSdkVersion = "34",
kotlinVersion = "1.9.23",
jvmTarget = JavaVersion.VERSION_17.toString()
)

// NB: starting from AGP 7.x, Gradle should have the same major version.
// While work with Gradle with higher major version is possible, it is not guaranteed.
val TESTED_CONFIGURATIONS = listOf(
Expand All @@ -1374,14 +1445,7 @@ internal class DdAndroidGradlePluginFunctionalTest {
kotlinVersion = "1.6.10",
jvmTarget = JavaVersion.VERSION_11.toString()
),
BuildVersionConfig(
agpVersion = LATEST_AGP_VERSION,
gradleVersion = LATEST_GRADLE_VERSION,
buildToolsVersion = "34.0.0",
targetSdkVersion = "34",
kotlinVersion = "1.9.23",
jvmTarget = JavaVersion.VERSION_17.toString()
)
LATEST_VERSIONS_TEST_CONFIGURATION
)

const val BUILD_ID_FILE_PATH_APK = "assets/datadog.buildId"
Expand Down

0 comments on commit db3ff0d

Please sign in to comment.