diff --git a/dd-sdk-android-gradle-plugin/src/main/kotlin/com/datadog/gradle/plugin/DdAndroidGradlePlugin.kt b/dd-sdk-android-gradle-plugin/src/main/kotlin/com/datadog/gradle/plugin/DdAndroidGradlePlugin.kt index 77cdeb3c..a3f7d609 100644 --- a/dd-sdk-android-gradle-plugin/src/main/kotlin/com/datadog/gradle/plugin/DdAndroidGradlePlugin.kt +++ b/dd-sdk-android-gradle-plugin/src/main/kotlin/com/datadog/gradle/plugin/DdAndroidGradlePlugin.kt @@ -93,12 +93,12 @@ class DdAndroidGradlePlugin @Inject constructor( } else { LOGGER.info("Minifying disabled for variant ${variant.name}, no upload task created") } -// configureNdkSymbolUploadTask( -// target, -// datadogExtension, -// variant, -// buildIdGenerationTask -// ) + configureNdkSymbolUploadTask( + target, + datadogExtension, + variant, + buildIdGenerationTask + ) configureVariantForSdkCheck(target, variant, datadogExtension) } diff --git a/dd-sdk-android-gradle-plugin/src/test/kotlin/com/datadog/gradle/plugin/DdAndroidGradlePluginFunctionalTest.kt b/dd-sdk-android-gradle-plugin/src/test/kotlin/com/datadog/gradle/plugin/DdAndroidGradlePluginFunctionalTest.kt index dcd985e9..0f429ed5 100644 --- a/dd-sdk-android-gradle-plugin/src/test/kotlin/com/datadog/gradle/plugin/DdAndroidGradlePluginFunctionalTest.kt +++ b/dd-sdk-android-gradle-plugin/src/test/kotlin/com/datadog/gradle/plugin/DdAndroidGradlePluginFunctionalTest.kt @@ -944,6 +944,123 @@ internal class DdAndroidGradlePluginFunctionalTest { // endregion + // region NDK Symbol Upload + + @Test + fun `M not try to upload the symbol file W no cmake dependencies { using a fake API_KEY }`() { + // Given + stubGradleBuildFromResourceFile( + "build_with_datadog_dep.gradle", + appBuildGradleFile + ) + stubNativeFiles() + + val result = gradleRunner { withArguments("--info", ":samples:app:assembleRelease") } + .build() + + // Then + assertThat(result).hasNoNdkSymbolUploadTasks() + } + + @Test + fun `M try to upload the symbol file W upload { using a fake API_KEY }`(forge: Forge) { + // Given + stubGradleBuildFromResourceFile( + "native_gradle_files/build_with_native_and_datadog_dep.gradle", + appBuildGradleFile + ) + stubNativeFiles() + + val color = forge.anElementFrom(colors) + val version = forge.anElementFrom(versions) + val variantVersionName = version.lowercase() + val variant = "${version.lowercase()}$color" + val taskName = resolveNdkSymbolUploadTask(variant) + + gradleRunner { withArguments("--info", ":samples:app:assembleRelease") } + .build() + + val result = gradleRunner { + withArguments( + taskName, + "--info", + "--stacktrace", + "-PDD_API_KEY=fakekey" + ) + } + .buildAndFail() + + // Then + val buildIdInOriginFile = testProjectDir.findBuildIdInOriginFile(variant) + + assertThat(result).containsInOutput("Creating request with GZIP encoding.") + + assertThat(result).containsInOutput("Uploading ndk_symbol_file file: ") + + assertThat(result).containsInOutput( + "Uploading file libplaceholder.so with tags " + + "`service:com.example.variants.$variantVersionName`, " + + "`version:1.0-$variantVersionName`, " + + "`version_code:1`, " + + "`variant:$variant`, " + + "`build_id:$buildIdInOriginFile` (site=datadoghq.com):" + ) + + for (arch in SUPPORTED_ABIS) { + assertThat(result).containsInOutput("extra attributes: {arch=$arch}") + } + } + + fun `M try to upload the symbol file W upload { using a fake API_KEY, gzip disabled }`(forge: Forge) { + // Given + stubGradleBuildFromResourceFile( + "native_gradle_files/build_with_native_and_datadog_dep.gradle", + appBuildGradleFile + ) + stubNativeFiles() + + val color = forge.anElementFrom(colors) + val version = forge.anElementFrom(versions) + val variantVersionName = version.lowercase() + val variant = "${version.lowercase()}$color" + val taskName = resolveNdkSymbolUploadTask(variant) + + gradleRunner { withArguments("--info", ":samples:app:assembleRelease") } + .build() + + val result = gradleRunner { + withArguments( + taskName, + "--info", + "--stacktrace", + "-PDD_API_KEY=fakekey" + ) + } + .buildAndFail() + + // Then + val buildIdInOriginFile = testProjectDir.findBuildIdInOriginFile(variant) + + assertThat(result).containsInOutput("Creating request without GZIP encoding.") + + assertThat(result).containsInOutput("Uploading ndk_symbol_file file: ") + + assertThat(result).containsInOutput( + "Uploading file libplaceholder.so with tags " + + "`service:com.example.variants.$variantVersionName`, " + + "`version:1.0-$variantVersionName`, " + + "`version_code:1`, " + + "`variant:$variant`, " + + "`build_id:$buildIdInOriginFile` (site=datadoghq.com):" + ) + + for (arch in SUPPORTED_ABIS) { + assertThat(result).containsInOutput("extra attributes: {arch=$arch}") + } + } + + // endregion + @Test fun `M try to upload the symbol file and mapping file W upload { using a fake API_KEY }`(forge: Forge) { // Given @@ -957,12 +1074,23 @@ internal class DdAndroidGradlePluginFunctionalTest { val version = forge.anElementFrom(versions) val variantVersionName = version.lowercase() val variant = "${version.lowercase()}$color" + val ndkSymbolUploadTaskName = resolveNdkSymbolUploadTask(variant) val mappingUploadTaskName = resolveMappingUploadTask(variant) // When gradleRunner { withArguments("--info", ":samples:app:assembleRelease") } .build() + val nativeResult = gradleRunner { + withArguments( + ndkSymbolUploadTaskName, + "--info", + "--stacktrace", + "-PDD_API_KEY=fakekey" + ) + } + .buildAndFail() + val mappingResult = gradleRunner { withArguments( mappingUploadTaskName, @@ -978,6 +1106,23 @@ internal class DdAndroidGradlePluginFunctionalTest { val buildIdInApk = testProjectDir.findBuildIdInApk(variant) assertThat(buildIdInApk).isEqualTo(buildIdInOriginFile) + assertThat(nativeResult).containsInOutput("Creating request with GZIP encoding.") + + assertThat(nativeResult).containsInOutput("Uploading ndk_symbol_file file: ") + + assertThat(nativeResult).containsInOutput( + "Uploading file libplaceholder.so with tags " + + "`service:com.example.variants.$variantVersionName`, " + + "`version:1.0-$variantVersionName`, " + + "`version_code:1`, " + + "`variant:$variant`, " + + "`build_id:$buildIdInOriginFile` (site=datadoghq.com):" + ) + + for (arch in SUPPORTED_ABIS) { + assertThat(nativeResult).containsInOutput("extra attributes: {arch=$arch}") + } + assertThat(mappingResult).containsInOutput("Creating request with GZIP encoding.") assertThat(mappingResult).containsInOutput( @@ -993,6 +1138,7 @@ internal class DdAndroidGradlePluginFunctionalTest { // region Internal private fun resolveMappingUploadTask(variantName: String) = "uploadMapping${variantName}Release" + private fun resolveNdkSymbolUploadTask(variantName: String) = "uploadNdkSymbolFiles${variantName}Release" private fun stubFile(destination: File, content: String) { with(destination.outputStream()) { diff --git a/dd-sdk-android-gradle-plugin/src/test/kotlin/com/datadog/gradle/plugin/DdAndroidGradlePluginTest.kt b/dd-sdk-android-gradle-plugin/src/test/kotlin/com/datadog/gradle/plugin/DdAndroidGradlePluginTest.kt index d285a321..49b677cd 100644 --- a/dd-sdk-android-gradle-plugin/src/test/kotlin/com/datadog/gradle/plugin/DdAndroidGradlePluginTest.kt +++ b/dd-sdk-android-gradle-plugin/src/test/kotlin/com/datadog/gradle/plugin/DdAndroidGradlePluginTest.kt @@ -10,6 +10,7 @@ import com.android.build.gradle.AppExtension import com.android.build.gradle.api.AndroidSourceDirectorySet import com.android.build.gradle.api.AndroidSourceSet import com.android.build.gradle.api.ApplicationVariant +import com.android.build.gradle.tasks.ExternalNativeBuildTask import com.android.builder.model.BuildType import com.android.builder.model.ProductFlavor import com.datadog.gradle.plugin.internal.ApiKey @@ -455,6 +456,83 @@ internal class DdAndroidGradlePluginTest { assertThat(allTasks).contains("generateBuildId${variantName.replaceFirstChar { capitalizeChar(it) }}") } + @Test + fun `M create uploadSymbol task W configureTasksForVariant() { native build providers }`( + @StringForgery(case = Case.LOWER) flavorName: String, + @StringForgery(case = Case.LOWER) buildTypeName: String, + @StringForgery versionName: String, + @StringForgery packageName: String + ) { + // Given + val mockAppExtension = mockAppExtension() + + val variantName = "$flavorName${buildTypeName.replaceFirstChar { capitalizeChar(it) }}" + whenever(mockVariant.name) doReturn variantName + whenever(mockVariant.flavorName) doReturn flavorName + whenever(mockVariant.versionName) doReturn versionName + whenever(mockVariant.applicationId) doReturn packageName + whenever(mockVariant.buildType) doReturn mockBuildType + whenever(mockVariant.mergeAssetsProvider) doReturn mock() + whenever(mockVariant.packageApplicationProvider) doReturn mock() + whenever(mockBuildType.name) doReturn fakeBuildTypeName + + val nativeBuildProviders = listOf( + mock>().apply { + whenever(flatMap(any, ExternalNativeBuildTask>>())) doReturn mock() + } + ) + whenever(mockVariant.externalNativeBuildProviders) doReturn nativeBuildProviders + + // When + testedPlugin.configureTasksForVariant( + fakeProject, + mockAppExtension, + fakeExtension, + mockVariant, + fakeApiKey + ) + + // Then + val allTasks = fakeProject.tasks.map { it.name } + assertThat(allTasks).contains("uploadNdkSymbolFiles${variantName.replaceFirstChar { capitalizeChar(it) }}") + } + + @Test + fun `M not create uploadSymbol task W configureTasksForVariant() { no native build providers }`( + @StringForgery(case = Case.LOWER) flavorName: String, + @StringForgery(case = Case.LOWER) buildTypeName: String, + @StringForgery versionName: String, + @StringForgery packageName: String + ) { + // Given + val mockAppExtension = mockAppExtension() + + val variantName = "$flavorName${buildTypeName.replaceFirstChar { capitalizeChar(it) }}" + whenever(mockVariant.name) doReturn variantName + whenever(mockVariant.flavorName) doReturn flavorName + whenever(mockVariant.versionName) doReturn versionName + whenever(mockVariant.applicationId) doReturn packageName + whenever(mockVariant.buildType) doReturn mockBuildType + whenever(mockVariant.mergeAssetsProvider) doReturn mock() + whenever(mockVariant.packageApplicationProvider) doReturn mock() + whenever(mockBuildType.name) doReturn fakeBuildTypeName + + whenever(mockVariant.externalNativeBuildProviders) doReturn listOf() + + // When + testedPlugin.configureTasksForVariant( + fakeProject, + mockAppExtension, + fakeExtension, + mockVariant, + fakeApiKey + ) + + // Then + val allTasks = fakeProject.tasks.map { it.name } + assertThat(allTasks).allMatch { !it.startsWith("uploadNdkSymbolFiles") } + } + @Test fun `M not create mapping upload task W configureTasksForVariant() { no deobfuscation }`( @StringForgery(case = Case.LOWER) flavorName: String,