diff --git a/dd-sdk-android-gradle-plugin/src/main/kotlin/com/datadog/gradle/plugin/DdCheckSdkDepsTask.kt b/dd-sdk-android-gradle-plugin/src/main/kotlin/com/datadog/gradle/plugin/CheckSdkDepsTask.kt similarity index 97% rename from dd-sdk-android-gradle-plugin/src/main/kotlin/com/datadog/gradle/plugin/DdCheckSdkDepsTask.kt rename to dd-sdk-android-gradle-plugin/src/main/kotlin/com/datadog/gradle/plugin/CheckSdkDepsTask.kt index 5d61f096..7768e55f 100644 --- a/dd-sdk-android-gradle-plugin/src/main/kotlin/com/datadog/gradle/plugin/DdCheckSdkDepsTask.kt +++ b/dd-sdk-android-gradle-plugin/src/main/kotlin/com/datadog/gradle/plugin/CheckSdkDepsTask.kt @@ -21,7 +21,7 @@ import java.util.Queue /** * A Gradle task to check the Datadog SDK throughout the variant dependencies. */ -abstract class DdCheckSdkDepsTask : DefaultTask() { +abstract class CheckSdkDepsTask : DefaultTask() { /** * The sdkCheckLevel: NONE, WARN, FAIL. @@ -47,7 +47,7 @@ abstract class DdCheckSdkDepsTask : DefaultTask() { init { group = DdAndroidGradlePlugin.DATADOG_TASK_GROUP description = "Checks for the Datadog SDK into your variant dependencies." - outputs.upToDateWhen { it is DdCheckSdkDepsTask && it.isLastRunSuccessful } + outputs.upToDateWhen { it is CheckSdkDepsTask && it.isLastRunSuccessful } } /** 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 2280c659..ef72b55c 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 @@ -6,16 +6,20 @@ package com.datadog.gradle.plugin +import com.android.build.api.variant.ApplicationAndroidComponentsExtension import com.android.build.gradle.AppExtension -import com.android.build.gradle.api.ApplicationVariant import com.datadog.gradle.plugin.internal.ApiKey import com.datadog.gradle.plugin.internal.ApiKeySource import com.datadog.gradle.plugin.internal.GitRepositoryDetector import com.datadog.gradle.plugin.internal.VariantIterator +import com.datadog.gradle.plugin.internal.variant.AppVariant +import com.datadog.gradle.plugin.internal.variant.NewApiAppVariant import org.gradle.api.Plugin import org.gradle.api.Project import org.gradle.api.Task +import org.gradle.api.file.RegularFile import org.gradle.api.logging.Logging +import org.gradle.api.provider.Provider import org.gradle.api.provider.ProviderFactory import org.gradle.api.tasks.TaskContainer import org.gradle.api.tasks.TaskProvider @@ -43,17 +47,30 @@ class DdAndroidGradlePlugin @Inject constructor( // need to use withPlugin instead of afterEvaluate, because otherwise generated assets // folder with buildId is not picked by AGP by some reason target.pluginManager.withPlugin("com.android.application") { - val androidExtension = target.androidApplicationExtension ?: return@withPlugin - androidExtension.applicationVariants.all { variant -> - if (extension.enabled) { + // can work probably even with lower versions, but legacy Variant API is working fine there as well + @Suppress("MagicNumber") + if (TaskUtils.isAgpAbove(8, 4, 0)) { + val androidComponentsExtension = target.androidApplicationComponentExtension ?: return@withPlugin + androidComponentsExtension.onVariants { variant -> configureTasksForVariant( target, - androidExtension, extension, - variant, + AppVariant.create(variant, target, providerFactory), apiKey ) } + } else { + val androidExtension = target.androidApplicationExtension ?: return@withPlugin + androidExtension.applicationVariants.all { variant -> + if (extension.enabled) { + configureTasksForVariant( + target, + extension, + AppVariant.create(variant, androidExtension, target, providerFactory), + apiKey + ) + } + } } } @@ -73,17 +90,16 @@ class DdAndroidGradlePlugin @Inject constructor( internal fun configureTasksForVariant( target: Project, - androidExtension: AppExtension, datadogExtension: DdExtension, - variant: ApplicationVariant, + variant: AppVariant, apiKey: ApiKey ) { val isObfuscationEnabled = isObfuscationEnabled(variant, datadogExtension) - val isNativeBuildRequired = variant.externalNativeBuildProviders.isNotEmpty() + val isNativeBuildRequired = variant.nativeBuildEnabled if (isObfuscationEnabled || isNativeBuildRequired) { val buildIdGenerationTask = - configureBuildIdGenerationTask(target, androidExtension, variant) + configureBuildIdGenerationTask(target, variant) if (isObfuscationEnabled) { configureVariantForUploadTask( @@ -112,7 +128,15 @@ class DdAndroidGradlePlugin @Inject constructor( ) } } - configureVariantForSdkCheck(target, variant, datadogExtension) + + if (variant is NewApiAppVariant) { + // need to run this in afterEvaluate, because with new Variant API tasks won't be created yet at this point + target.afterEvaluate { + configureVariantForSdkCheck(target, variant, datadogExtension) + } + } else { + configureVariantForSdkCheck(target, variant, datadogExtension) + } } @Suppress("ReturnCount") @@ -128,16 +152,16 @@ class DdAndroidGradlePlugin @Inject constructor( return apiKey ?: ApiKey.NONE } - internal fun configureNdkSymbolUploadTask( + private fun configureNdkSymbolUploadTask( target: Project, extension: DdExtension, - variant: ApplicationVariant, + variant: AppVariant, buildIdTask: TaskProvider, apiKey: ApiKey - ): TaskProvider { + ): TaskProvider { val extensionConfiguration = resolveExtensionConfiguration(extension, variant) - val uploadTask = DdNdkSymbolFileUploadTask.register( + val uploadTask = NdkSymbolFileUploadTask.register( target, variant, buildIdTask, @@ -151,59 +175,34 @@ class DdAndroidGradlePlugin @Inject constructor( } @Suppress("StringLiteralDuplication") - internal fun configureBuildIdGenerationTask( + private fun configureBuildIdGenerationTask( target: Project, - appExtension: AppExtension, - variant: ApplicationVariant + variant: AppVariant ): TaskProvider { val buildIdDirectory = target.layout.buildDirectory .dir(Path("generated", "datadog", "buildId", variant.name).toString()) val buildIdGenerationTask = GenerateBuildIdTask.register(target, variant, buildIdDirectory) - // we could generate buildIdDirectory inside GenerateBuildIdTask and read it here as - // property using flatMap, but when Gradle sync is done inside Android Studio there is an error - // Querying the mapped value of provider (java.util.Set) before task ... has completed is - // not supported, which doesn't happen when Android Studio is not used (pure Gradle build) - // so applying such workaround - // TODO RUM-0000 use new AndroidComponents API to inject generated stuff, it is more friendly - appExtension.sourceSets.getByName(variant.name).assets.srcDir(buildIdDirectory) - - val variantName = variant.name.capitalize() - listOf( - "package${variantName}Bundle", - "build${variantName}PreBundle", - "lintVitalAnalyze$variantName", - "lintVitalReport$variantName", - "generate${variantName}LintVitalReportModel" - ).forEach { - target.tasks.findByName(it)?.dependsOn(buildIdGenerationTask) - } - - // don't merge these 2 into list to call forEach, because common superclass for them - // is different between AGP versions, which may cause ClassCastException - variant.mergeAssetsProvider.configure { it.dependsOn(buildIdGenerationTask) } - variant.packageApplicationProvider.configure { it.dependsOn(buildIdGenerationTask) } - return buildIdGenerationTask } @Suppress("DefaultLocale", "ReturnCount") internal fun configureVariantForUploadTask( target: Project, - variant: ApplicationVariant, + variant: AppVariant, buildIdGenerationTask: TaskProvider, apiKey: ApiKey, extension: DdExtension - ): TaskProvider { + ): TaskProvider { val uploadTaskName = UPLOAD_TASK_NAME + variant.name.capitalize() val uploadTask = target.tasks.register( uploadTaskName, - DdMappingFileUploadTask::class.java, + MappingFileUploadTask::class.java, GitRepositoryDetector(execOps) ).apply { configure { uploadTask -> @Suppress("MagicNumber") - if (DdTaskUtils.isGradleAbove(target, 7, 5)) { + if (TaskUtils.isGradleAbove(target, 7, 5)) { uploadTask.notCompatibleWithConfigurationCache( "Datadog Upload Mapping task is not" + " compatible with configuration cache yet." @@ -216,38 +215,24 @@ class DdAndroidGradlePlugin @Inject constructor( // because upload task may be triggered after assemble task and we don't want to re-generate // build ID, because it will be different then from the one which is already embedded in // the application package - uploadTask.buildId = buildIdGenerationTask.flatMap { - it.buildIdFile.flatMap { - providerFactory.provider { it.asFile.readText().trim() } + uploadTask.buildId.set( + buildIdGenerationTask.flatMap { + it.buildIdFile.flatMap { + providerFactory.provider { it.asFile.readText().trim() } + } } - } - uploadTask.mappingFilePath = resolveMappingFilePath(extensionConfiguration, target, variant) - uploadTask.mappingFilePackagesAliases = - filterMappingFileReplacements( - extensionConfiguration.mappingFilePackageAliases, - variant.applicationId - ) + ) + + uploadTask.applicationId.set(variant.applicationId) + uploadTask.mappingFile.set(resolveMappingFile(extensionConfiguration, target, variant)) + uploadTask.mappingFilePackagesAliases = extensionConfiguration.mappingFilePackageAliases uploadTask.mappingFileTrimIndents = extensionConfiguration.mappingFileTrimIndents if (!extensionConfiguration.ignoreDatadogCiFileConfig) { - uploadTask.datadogCiFile = DdTaskUtils.findDatadogCiFile(target.projectDir) + uploadTask.datadogCiFile = TaskUtils.findDatadogCiFile(target.projectDir) } - uploadTask.repositoryFile = DdTaskUtils.resolveDatadogRepositoryFile(target) - - val roots = mutableListOf() - variant.sourceSets.forEach { - roots.addAll(it.javaDirectories) - @Suppress("MagicNumber") - if (DdTaskUtils.isAgpAbove(7, 0, 0)) { - roots.addAll(it.kotlinDirectories) - } - } - - // it can be an overlap between java and kotlin directories and since File doesn't override - // equals for set comparison, we will remove duplicates manually - uploadTask.sourceSetRoots = roots.map { it.absolutePath } - .distinct() - .map { File(it) } + uploadTask.repositoryFile = TaskUtils.resolveDatadogRepositoryFile(target) + uploadTask.sourceSetRoots.set(variant.collectJavaAndKotlinSourceDirectories()) } } @@ -257,9 +242,9 @@ class DdAndroidGradlePlugin @Inject constructor( @Suppress("ReturnCount") internal fun configureVariantForSdkCheck( target: Project, - variant: ApplicationVariant, + variant: AppVariant, extension: DdExtension - ): TaskProvider? { + ): TaskProvider? { if (!extension.enabled) { LOGGER.info("Extension disabled for variant ${variant.name}, no sdk check task created") return null @@ -289,7 +274,7 @@ class DdAndroidGradlePlugin @Inject constructor( extensionConfiguration.checkProjectDependencies ?: SdkCheckLevel.FAIL val checkDepsTaskProvider = target.tasks.register( checkDepsTaskName, - DdCheckSdkDepsTask::class.java + CheckSdkDepsTask::class.java ) { it.configurationName.set(variant.compileConfiguration.name) it.sdkCheckLevel.set(resolvedCheckDependencyFlag) @@ -303,7 +288,7 @@ class DdAndroidGradlePlugin @Inject constructor( @Suppress("DefaultLocale") private fun findCompilationTask( taskContainer: TaskContainer, - appVariant: ApplicationVariant + appVariant: AppVariant ): Task? { // variants will have name like proDebug, but compile task will have a name like // compileProDebugSources. It can be other tasks like compileProDebugAndroidTestSources @@ -318,69 +303,54 @@ class DdAndroidGradlePlugin @Inject constructor( ?: taskContainer.findByName("compile${appVariant.name.capitalize()}Sources") } - private fun resolveMappingFilePath( + private fun resolveMappingFile( extensionConfiguration: DdExtensionConfiguration, target: Project, - variant: ApplicationVariant - ): String { + variant: AppVariant + ): Provider { val customPath = extensionConfiguration.mappingFilePath return if (customPath != null) { - customPath + target.objects.fileProperty().fileValue(File(customPath)) } else { - val outputsDir = File(target.buildDir, "outputs") - val mappingDir = File(outputsDir, "mapping") - val flavorDir = File(mappingDir, variant.name) - File(flavorDir, "mapping.txt").path - } - } - - private fun filterMappingFileReplacements( - replacements: Map, - applicationId: String - ): Map { - return replacements.filter { - // not necessarily applicationId == package attribute from the Manifest, but it is - // best and cheapest effort to avoid wrong renaming (otherwise we may loose Git - // integration feature). - if (applicationId.startsWith(it.key)) { - LOGGER.warn( - "Renaming of package prefix=${it.key} will be skipped, because" + - " it belongs to the application package." - ) - false - } else { - true - } + variant.mappingFile } } private fun configureVariantTask( - uploadTask: DdMappingFileUploadTask, + uploadTask: MappingFileUploadTask, apiKey: ApiKey, flavorName: String, extensionConfiguration: DdExtensionConfiguration, - variant: ApplicationVariant + variant: AppVariant ) { uploadTask.apiKey = apiKey.value uploadTask.apiKeySource = apiKey.source uploadTask.variantName = flavorName uploadTask.site = extensionConfiguration.site ?: "" - uploadTask.versionName = extensionConfiguration.versionName ?: variant.versionName - uploadTask.versionCode = providerFactory.provider { variant.versionCode } - uploadTask.serviceName = extensionConfiguration.serviceName ?: variant.applicationId + if (extensionConfiguration.versionName != null) { + uploadTask.versionName.set(extensionConfiguration.versionName) + } else { + uploadTask.versionName.set(variant.versionName) + } + uploadTask.versionCode.set(variant.versionCode) + if (extensionConfiguration.serviceName != null) { + uploadTask.serviceName.set(extensionConfiguration.serviceName) + } else { + uploadTask.serviceName.set(variant.applicationId) + } uploadTask.remoteRepositoryUrl = extensionConfiguration.remoteRepositoryUrl ?: "" } internal fun resolveExtensionConfiguration( extension: DdExtension, - variant: ApplicationVariant + variant: AppVariant ): DdExtensionConfiguration { val configuration = DdExtensionConfiguration() configuration.updateWith(extension) - val flavors = variant.productFlavors.map { it.name } - val buildType = variant.buildType.name + val flavors = variant.flavors + val buildType = variant.buildTypeName val iterator = VariantIterator(flavors + buildType) iterator.forEach { val config = extension.variants.findByName(it) @@ -396,11 +366,11 @@ class DdAndroidGradlePlugin @Inject constructor( } private fun isObfuscationEnabled( - variant: ApplicationVariant, + variant: AppVariant, extension: DdExtension ): Boolean { val extensionConfiguration = resolveExtensionConfiguration(extension, variant) - val isDefaultObfuscationEnabled = variant.buildType.isMinifyEnabled + val isDefaultObfuscationEnabled = variant.isMinifyEnabled val isNonDefaultObfuscationEnabled = extensionConfiguration.nonDefaultObfuscation return isDefaultObfuscationEnabled || isNonDefaultObfuscationEnabled } @@ -408,6 +378,9 @@ class DdAndroidGradlePlugin @Inject constructor( private val Project.androidApplicationExtension: AppExtension? get() = extensions.findByType(AppExtension::class.java) + private val Project.androidApplicationComponentExtension: ApplicationAndroidComponentsExtension? + get() = extensions.findByType(ApplicationAndroidComponentsExtension::class.java) + // endregion companion object { diff --git a/dd-sdk-android-gradle-plugin/src/main/kotlin/com/datadog/gradle/plugin/DdFileUploadTask.kt b/dd-sdk-android-gradle-plugin/src/main/kotlin/com/datadog/gradle/plugin/FileUploadTask.kt similarity index 88% rename from dd-sdk-android-gradle-plugin/src/main/kotlin/com/datadog/gradle/plugin/DdFileUploadTask.kt rename to dd-sdk-android-gradle-plugin/src/main/kotlin/com/datadog/gradle/plugin/FileUploadTask.kt index 39d6e60a..a4025c94 100644 --- a/dd-sdk-android-gradle-plugin/src/main/kotlin/com/datadog/gradle/plugin/DdFileUploadTask.kt +++ b/dd-sdk-android-gradle-plugin/src/main/kotlin/com/datadog/gradle/plugin/FileUploadTask.kt @@ -1,13 +1,15 @@ package com.datadog.gradle.plugin -import com.android.build.gradle.api.ApplicationVariant import com.datadog.gradle.plugin.internal.ApiKey import com.datadog.gradle.plugin.internal.ApiKeySource import com.datadog.gradle.plugin.internal.DdAppIdentifier import com.datadog.gradle.plugin.internal.OkHttpUploader import com.datadog.gradle.plugin.internal.Uploader +import com.datadog.gradle.plugin.internal.variant.AppVariant import org.gradle.api.DefaultTask import org.gradle.api.logging.Logging +import org.gradle.api.provider.ListProperty +import org.gradle.api.provider.Property import org.gradle.api.provider.Provider import org.gradle.api.provider.ProviderFactory import org.gradle.api.tasks.Input @@ -27,10 +29,11 @@ import javax.inject.Inject * A Gradle task to upload symbolication files to Datadog servers (NDK symbol files, * Proguard/R8 files, etc.).. */ -abstract class DdFileUploadTask @Inject constructor( - private val providerFactory: ProviderFactory, +abstract class FileUploadTask @Inject constructor( + providerFactory: ProviderFactory, @get:Internal internal val repositoryDetector: RepositoryDetector ) : DefaultTask() { + @get:Internal internal var uploader: Uploader = OkHttpUploader() @@ -63,20 +66,20 @@ abstract class DdFileUploadTask @Inject constructor( * The version name of the application. */ @get:Input - var versionName: String = "" + abstract val versionName: Property /** * The version code of the application. Need to be a provider, because resolution during * configuration phase may cause incompatibility with other plugins if legacy Variant API is used. */ @get:Input - var versionCode: Provider = providerFactory.provider { 0 } + abstract val versionCode: Property /** * The service name of the application (by default, it is your app's package name). */ @get:Input - var serviceName: String = "" + abstract val serviceName: Property /** * The Datadog site to upload to (one of "US1", "EU1", "US1_FED"). @@ -94,7 +97,7 @@ abstract class DdFileUploadTask @Inject constructor( * Build ID which will be used for mapping file matching. */ @get:Input - var buildId: Provider = providerFactory.provider { "" } + abstract val buildId: Property /** * datadog-ci.json file, if found or applicable for the particular task. @@ -107,7 +110,7 @@ abstract class DdFileUploadTask @Inject constructor( * The sourceSet root folders. */ @get:InputFiles - var sourceSetRoots: List = emptyList() + abstract val sourceSetRoots: ListProperty /** * The file containing the repository description. @@ -121,14 +124,11 @@ abstract class DdFileUploadTask @Inject constructor( outputs.upToDateWhen { false } } - @Internal - internal abstract fun getFilesList(): List - /** * Uploads the files retrieved from `getFilesList` to Datadog. */ @TaskAction - @Suppress("TooGenericExceptionCaught") + @Suppress("TooGenericExceptionCaught", "LongMethod") fun applyTask() { datadogCiFile?.let { applyDatadogCiConfig(it) @@ -147,8 +147,15 @@ abstract class DdFileUploadTask @Inject constructor( val mappingFiles = getFilesList() if (mappingFiles.isEmpty()) return + // it can be an overlap between java and kotlin directories and since File doesn't override + // equals for set comparison, we will remove duplicates manually + val uniqueSourceSetRoots = sourceSetRoots.get() + .map { it.absolutePath } + .distinct() + .map { File(it) } + val repositories = repositoryDetector.detectRepositories( - sourceSetRoots, + uniqueSourceSetRoots, remoteRepositoryUrl ) @@ -167,8 +174,8 @@ abstract class DdFileUploadTask @Inject constructor( if (repositories.isEmpty()) null else repositoryFile, apiKey, DdAppIdentifier( - serviceName = serviceName, - version = versionName, + serviceName = serviceName.get(), + version = versionName.get(), versionCode = versionCode.get(), variant = variantName, buildId = buildId.get() @@ -195,22 +202,37 @@ abstract class DdFileUploadTask @Inject constructor( } } + // region Internal + + @Internal + internal abstract fun getFilesList(): List + internal fun configureWith( apiKey: ApiKey, extensionConfiguration: DdExtensionConfiguration, - variant: ApplicationVariant + variant: AppVariant ) { this.apiKey = apiKey.value apiKeySource = apiKey.source site = extensionConfiguration.site ?: "" - versionName = variant.versionName ?: "" - versionCode = providerFactory.provider { variant.versionCode } - serviceName = extensionConfiguration.serviceName ?: variant.applicationId + versionName.set(variant.versionName) + versionCode.set(variant.versionCode) + + if (extensionConfiguration.serviceName != null) { + serviceName.set(extensionConfiguration.serviceName) + } else { + serviceName.set(variant.applicationId) + } + variantName = variant.flavorName remoteRepositoryUrl = extensionConfiguration.remoteRepositoryUrl ?: "" } + // endregion + + // region Private + private fun applySiteFromEnvironment() { val environmentSite = System.getenv(DATADOG_SITE) if (!environmentSite.isNullOrEmpty()) { @@ -310,6 +332,8 @@ abstract class DdFileUploadTask @Inject constructor( repositoryFile.writeText(jsonObject.toString(0)) } + // endregion + internal companion object { private const val REPOSITORY_FILE_VERSION = 1 private const val INDENT = 4 diff --git a/dd-sdk-android-gradle-plugin/src/main/kotlin/com/datadog/gradle/plugin/GenerateBuildIdTask.kt b/dd-sdk-android-gradle-plugin/src/main/kotlin/com/datadog/gradle/plugin/GenerateBuildIdTask.kt index b232ccab..eb014e58 100644 --- a/dd-sdk-android-gradle-plugin/src/main/kotlin/com/datadog/gradle/plugin/GenerateBuildIdTask.kt +++ b/dd-sdk-android-gradle-plugin/src/main/kotlin/com/datadog/gradle/plugin/GenerateBuildIdTask.kt @@ -1,6 +1,6 @@ package com.datadog.gradle.plugin -import com.android.build.gradle.api.ApplicationVariant +import com.datadog.gradle.plugin.internal.variant.AppVariant import org.gradle.api.DefaultTask import org.gradle.api.Project import org.gradle.api.file.Directory @@ -57,8 +57,8 @@ abstract class GenerateBuildIdTask : DefaultTask() { .writeText(buildId) } - companion object { - internal const val TASK_NAME = "generateBuildId" + internal companion object { + private const val TASK_NAME = "generateBuildId" /** * Name of the file containing build ID information. @@ -66,11 +66,11 @@ abstract class GenerateBuildIdTask : DefaultTask() { const val BUILD_ID_FILE_NAME = "datadog.buildId" /** - * Registers a new instance of [GenerateBuildIdTask] specific for the given [ApplicationVariant]. + * Registers a new instance of [GenerateBuildIdTask] specific for the given [AppVariant]. */ fun register( target: Project, - variant: ApplicationVariant, + variant: AppVariant, buildIdDirectory: Provider ): TaskProvider { val generateBuildIdTask = target.tasks.register( @@ -80,6 +80,7 @@ abstract class GenerateBuildIdTask : DefaultTask() { it.buildIdDirectory.set(buildIdDirectory) it.variantName.set(variant.name) } + variant.bindWith(generateBuildIdTask) return generateBuildIdTask } diff --git a/dd-sdk-android-gradle-plugin/src/main/kotlin/com/datadog/gradle/plugin/DdMappingFileUploadTask.kt b/dd-sdk-android-gradle-plugin/src/main/kotlin/com/datadog/gradle/plugin/MappingFileUploadTask.kt similarity index 73% rename from dd-sdk-android-gradle-plugin/src/main/kotlin/com/datadog/gradle/plugin/DdMappingFileUploadTask.kt rename to dd-sdk-android-gradle-plugin/src/main/kotlin/com/datadog/gradle/plugin/MappingFileUploadTask.kt index 62ce55d9..0f977ca8 100644 --- a/dd-sdk-android-gradle-plugin/src/main/kotlin/com/datadog/gradle/plugin/DdMappingFileUploadTask.kt +++ b/dd-sdk-android-gradle-plugin/src/main/kotlin/com/datadog/gradle/plugin/MappingFileUploadTask.kt @@ -6,27 +6,29 @@ package com.datadog.gradle.plugin -import com.datadog.gradle.plugin.DdAndroidGradlePlugin.Companion.LOGGER import com.datadog.gradle.plugin.internal.Uploader +import org.gradle.api.file.RegularFileProperty +import org.gradle.api.provider.Property import org.gradle.api.provider.ProviderFactory import org.gradle.api.tasks.Input +import org.gradle.api.tasks.InputFile import java.io.File import javax.inject.Inject /** * A Gradle task to upload a Proguard/R8 mapping file to Datadog servers. */ -open class DdMappingFileUploadTask +abstract class MappingFileUploadTask @Inject constructor( providerFactory: ProviderFactory, repositoryDetector: RepositoryDetector -) : DdFileUploadTask(providerFactory, repositoryDetector) { +) : FileUploadTask(providerFactory, repositoryDetector) { /** * The path to the mapping file to upload. */ - @get:Input - var mappingFilePath: String = "" + @get:InputFile + abstract val mappingFile: RegularFileProperty /** * Replacements for the source prefixes in the mapping file. @@ -40,6 +42,9 @@ open class DdMappingFileUploadTask @get:Input var mappingFileTrimIndents: Boolean = false + @get:Input + abstract val applicationId: Property + init { group = DdAndroidGradlePlugin.DATADOG_TASK_GROUP description = "Uploads the Proguard/R8 mapping file to Datadog" @@ -48,7 +53,7 @@ open class DdMappingFileUploadTask } override fun getFilesList(): List { - var mappingFile = File(mappingFilePath) + var mappingFile = mappingFile.get().asFile if (!validateMappingFile(mappingFile)) return emptyList() mappingFile = shrinkMappingFile(mappingFile) @@ -67,13 +72,13 @@ open class DdMappingFileUploadTask @Suppress("CheckInternal") private fun validateMappingFile(mappingFile: File): Boolean { if (!mappingFile.exists()) { - println("There's no mapping file $mappingFilePath, nothing to upload") + println("There's no mapping file ${mappingFile.absolutePath}, nothing to upload") return false } - check(mappingFile.isFile) { "Expected $mappingFilePath to be a file" } + check(mappingFile.isFile) { "Expected ${mappingFile.absolutePath} to be a file" } - check(mappingFile.canRead()) { "Cannot read file $mappingFilePath" } + check(mappingFile.canRead()) { "Cannot read file ${mappingFile.absolutePath}" } return true } @@ -92,12 +97,28 @@ open class DdMappingFileUploadTask if (shrinkedFile.exists()) { shrinkedFile.delete() } - // sort is needed to have predictable replacement in the following case: - // imagine there are 2 keys - "androidx.work" and "androidx.work.Job", and the latter - // occurs much more often than the rest under "androidx.work.*". So for the more efficient - // compression we need first to process the replacement of "androidx.work.Job" and only - // after that any possible prefix (which has a smaller length). - val replacements = mappingFilePackagesAliases.entries + + val replacements = mappingFilePackagesAliases + .filter { + // not necessarily applicationId == package attribute from the Manifest, but it is + // best and cheapest effort to avoid wrong renaming (otherwise we may loose Git + // integration feature). + if (applicationId.get().startsWith(it.key)) { + DdAndroidGradlePlugin.LOGGER.warn( + "Renaming of package prefix=${it.key} will be skipped, because" + + " it belongs to the application package." + ) + false + } else { + true + } + } + .entries + // sort is needed to have predictable replacement in the following case: + // imagine there are 2 keys - "androidx.work" and "androidx.work.Job", and the latter + // occurs much more often than the rest under "androidx.work.*". So for the more efficient + // compression we need first to process the replacement of "androidx.work.Job" and only + // after that any possible prefix (which has a smaller length). .sortedByDescending { it.key.length } .map { Regex("(?<=^|\\W)${it.key}(?=\\W)") to it.value diff --git a/dd-sdk-android-gradle-plugin/src/main/kotlin/com/datadog/gradle/plugin/DdNdkSymbolFileUploadTask.kt b/dd-sdk-android-gradle-plugin/src/main/kotlin/com/datadog/gradle/plugin/NdkSymbolFileUploadTask.kt similarity index 58% rename from dd-sdk-android-gradle-plugin/src/main/kotlin/com/datadog/gradle/plugin/DdNdkSymbolFileUploadTask.kt rename to dd-sdk-android-gradle-plugin/src/main/kotlin/com/datadog/gradle/plugin/NdkSymbolFileUploadTask.kt index eeb1b8ef..4ddcbe5a 100644 --- a/dd-sdk-android-gradle-plugin/src/main/kotlin/com/datadog/gradle/plugin/DdNdkSymbolFileUploadTask.kt +++ b/dd-sdk-android-gradle-plugin/src/main/kotlin/com/datadog/gradle/plugin/NdkSymbolFileUploadTask.kt @@ -1,29 +1,25 @@ package com.datadog.gradle.plugin -import com.android.build.gradle.api.ApplicationVariant -import com.android.build.gradle.tasks.ExternalNativeBuildTask import com.datadog.gradle.plugin.internal.ApiKey import com.datadog.gradle.plugin.internal.Uploader +import com.datadog.gradle.plugin.internal.variant.AppVariant import org.gradle.api.Project import org.gradle.api.file.ConfigurableFileCollection -import org.gradle.api.file.DirectoryProperty import org.gradle.api.model.ObjectFactory -import org.gradle.api.provider.Provider import org.gradle.api.provider.ProviderFactory import org.gradle.api.tasks.InputFiles import org.gradle.api.tasks.TaskProvider import java.io.File import javax.inject.Inject -import kotlin.reflect.full.memberProperties /** * A Gradle task to upload NDK symbol files to Datadog servers. */ -internal abstract class DdNdkSymbolFileUploadTask @Inject constructor( +internal abstract class NdkSymbolFileUploadTask @Inject constructor( objectFactory: ObjectFactory, providerFactory: ProviderFactory, repositoryDetector: RepositoryDetector -) : DdFileUploadTask(providerFactory, repositoryDetector) { +) : FileUploadTask(providerFactory, repositoryDetector) { @get:InputFiles val searchDirectories: ConfigurableFileCollection = objectFactory.fileCollection() @@ -88,75 +84,41 @@ internal abstract class DdNdkSymbolFileUploadTask @Inject constructor( SupportedArchitectureMapping("x86_64", "x64") ) - private fun getSearchDirs( - buildTask: TaskProvider, - providerFactory: ProviderFactory - ): Provider { - return buildTask.flatMap { task -> - // var soFolder: `Provider - @Suppress("MagicNumber") - if (DdTaskUtils.isAgpAbove(8, 0, 0)) { - task.soFolder.map { it.asFile } - } else { - val soFolder = ExternalNativeBuildTask::class.memberProperties.find { - it.name == "objFolder" - }?.get(task) - when (soFolder) { - is File -> providerFactory.provider { soFolder } - is DirectoryProperty -> soFolder.map { it.asFile } - else -> providerFactory.provider { null } - } - } - } - } - @Suppress("LongParameterList", "ReturnCount") fun register( project: Project, - variant: ApplicationVariant, + variant: AppVariant, buildIdTask: TaskProvider, providerFactory: ProviderFactory, apiKey: ApiKey, extensionConfiguration: DdExtensionConfiguration, repositoryDetector: RepositoryDetector - ): TaskProvider { + ): TaskProvider { return project.tasks.register( TASK_NAME + variant.name.capitalize(), - DdNdkSymbolFileUploadTask::class.java, + NdkSymbolFileUploadTask::class.java, repositoryDetector ).apply { configure { task -> - val roots = mutableListOf() - variant.sourceSets.forEach { - roots.addAll(it.javaDirectories) - @Suppress("MagicNumber") - if (DdTaskUtils.isAgpAbove(7, 0, 0)) { - roots.addAll(it.kotlinDirectories) - } - } - task.sourceSetRoots = roots - - val nativeBuildProviders = variant.externalNativeBuildProviders - nativeBuildProviders.forEach { buildTask -> - val searchFiles = getSearchDirs(buildTask, providerFactory) + task.sourceSetRoots.set(variant.collectJavaAndKotlinSourceDirectories()) - task.searchDirectories.from(searchFiles) - task.dependsOn(buildTask) - } + variant.bindWith(task) - task.datadogCiFile = DdTaskUtils.findDatadogCiFile(project.rootDir) - task.repositoryFile = DdTaskUtils.resolveDatadogRepositoryFile(project) + task.datadogCiFile = TaskUtils.findDatadogCiFile(project.rootDir) + task.repositoryFile = TaskUtils.resolveDatadogRepositoryFile(project) task.configureWith( apiKey, extensionConfiguration, variant ) - task.buildId = buildIdTask.flatMap { - it.buildIdFile.flatMap { - providerFactory.provider { it.asFile.readText().trim() } + task.buildId.set( + buildIdTask.flatMap { + it.buildIdFile.flatMap { + providerFactory.provider { it.asFile.readText().trim() } + } } - } + ) } } } diff --git a/dd-sdk-android-gradle-plugin/src/main/kotlin/com/datadog/gradle/plugin/DdTaskUtils.kt b/dd-sdk-android-gradle-plugin/src/main/kotlin/com/datadog/gradle/plugin/TaskUtils.kt similarity index 98% rename from dd-sdk-android-gradle-plugin/src/main/kotlin/com/datadog/gradle/plugin/DdTaskUtils.kt rename to dd-sdk-android-gradle-plugin/src/main/kotlin/com/datadog/gradle/plugin/TaskUtils.kt index c5fcf601..b2d8fa1b 100644 --- a/dd-sdk-android-gradle-plugin/src/main/kotlin/com/datadog/gradle/plugin/DdTaskUtils.kt +++ b/dd-sdk-android-gradle-plugin/src/main/kotlin/com/datadog/gradle/plugin/TaskUtils.kt @@ -4,7 +4,8 @@ import com.android.builder.model.Version import org.gradle.api.Project import java.io.File -internal object DdTaskUtils { +internal object TaskUtils { + private const val MAX_DATADOG_CI_FILE_LOOKUP_LEVELS = 4 @Suppress("StringLiteralDuplication") diff --git a/dd-sdk-android-gradle-plugin/src/main/kotlin/com/datadog/gradle/plugin/internal/TaskExt.kt b/dd-sdk-android-gradle-plugin/src/main/kotlin/com/datadog/gradle/plugin/internal/TaskExt.kt new file mode 100644 index 00000000..da7c5d26 --- /dev/null +++ b/dd-sdk-android-gradle-plugin/src/main/kotlin/com/datadog/gradle/plugin/internal/TaskExt.kt @@ -0,0 +1,37 @@ +/* + * Unless explicitly stated otherwise all files in this repository are licensed under the Apache License Version 2.0. + * This product includes software developed at Datadog (https://www.datadoghq.com/). + * Copyright 2020-Present Datadog, Inc. + */ + +package com.datadog.gradle.plugin.internal + +import com.android.build.gradle.tasks.ExternalNativeBuildTask +import com.datadog.gradle.plugin.TaskUtils +import org.gradle.api.file.DirectoryProperty +import org.gradle.api.provider.Provider +import org.gradle.api.provider.ProviderFactory +import org.gradle.api.tasks.TaskProvider +import java.io.File +import kotlin.reflect.full.memberProperties + +internal fun TaskProvider.getSearchObjDirs(providerFactory: ProviderFactory): Provider { + return flatMap { task -> task.getSearchObjDirs(providerFactory) } +} + +internal fun ExternalNativeBuildTask.getSearchObjDirs(providerFactory: ProviderFactory): Provider { + // var soFolder: `Provider + @Suppress("MagicNumber") + return if (TaskUtils.isAgpAbove(8, 0, 0)) { + soFolder.map { it.asFile } + } else { + val soFolder = ExternalNativeBuildTask::class.memberProperties.find { + it.name == "objFolder" + }?.get(this) + when (soFolder) { + is File -> providerFactory.provider { soFolder } + is DirectoryProperty -> soFolder.map { it.asFile } + else -> providerFactory.provider { null } + } + } +} diff --git a/dd-sdk-android-gradle-plugin/src/main/kotlin/com/datadog/gradle/plugin/internal/variant/AppVariant.kt b/dd-sdk-android-gradle-plugin/src/main/kotlin/com/datadog/gradle/plugin/internal/variant/AppVariant.kt new file mode 100644 index 00000000..8ad5d1f8 --- /dev/null +++ b/dd-sdk-android-gradle-plugin/src/main/kotlin/com/datadog/gradle/plugin/internal/variant/AppVariant.kt @@ -0,0 +1,67 @@ +/* + * Unless explicitly stated otherwise all files in this repository are licensed under the Apache License Version 2.0. + * This product includes software developed at Datadog (https://www.datadoghq.com/). + * Copyright 2020-Present Datadog, Inc. + */ + +package com.datadog.gradle.plugin.internal.variant + +import com.android.build.gradle.AppExtension +import com.datadog.gradle.plugin.GenerateBuildIdTask +import com.datadog.gradle.plugin.NdkSymbolFileUploadTask +import org.gradle.api.Project +import org.gradle.api.artifacts.Configuration +import org.gradle.api.file.RegularFile +import org.gradle.api.provider.Provider +import org.gradle.api.provider.ProviderFactory +import org.gradle.api.tasks.TaskProvider +import java.io.File +import com.android.build.api.variant.ApplicationVariant as NewApplicationVariant +import com.android.build.gradle.api.ApplicationVariant as LegacyApplicationVariant + +internal interface AppVariant { + + val name: String + + val applicationId: Provider + + val flavorName: String + + val versionCode: Provider + + val versionName: Provider + + val compileConfiguration: Configuration + + val nativeBuildEnabled: Boolean + + val isMinifyEnabled: Boolean + + val buildTypeName: String + + val flavors: List + + val mappingFile: Provider + + fun collectJavaAndKotlinSourceDirectories(): Provider> + + fun bindWith(ndkUploadTask: NdkSymbolFileUploadTask) + + // new variant API doesn't allow to run addGeneratedSourceDirectory from inside Task#configure, thus this + fun bindWith(generateBuildIdTask: TaskProvider) + + companion object { + fun create( + variant: NewApplicationVariant, + target: Project, + providerFactory: ProviderFactory + ): AppVariant = NewApiAppVariant(variant, target, providerFactory) + + fun create( + variant: LegacyApplicationVariant, + appExtension: AppExtension, + target: Project, + providerFactory: ProviderFactory + ): AppVariant = LegacyApiAppVariant(variant, appExtension, target, providerFactory) + } +} diff --git a/dd-sdk-android-gradle-plugin/src/main/kotlin/com/datadog/gradle/plugin/internal/variant/LegacyApiAppVariant.kt b/dd-sdk-android-gradle-plugin/src/main/kotlin/com/datadog/gradle/plugin/internal/variant/LegacyApiAppVariant.kt new file mode 100644 index 00000000..f7778418 --- /dev/null +++ b/dd-sdk-android-gradle-plugin/src/main/kotlin/com/datadog/gradle/plugin/internal/variant/LegacyApiAppVariant.kt @@ -0,0 +1,92 @@ +/* + * Unless explicitly stated otherwise all files in this repository are licensed under the Apache License Version 2.0. + * This product includes software developed at Datadog (https://www.datadoghq.com/). + * Copyright 2020-Present Datadog, Inc. + */ + +package com.datadog.gradle.plugin.internal.variant + +import com.android.build.gradle.AppExtension +import com.android.build.gradle.api.ApplicationVariant +import com.datadog.gradle.plugin.GenerateBuildIdTask +import com.datadog.gradle.plugin.NdkSymbolFileUploadTask +import com.datadog.gradle.plugin.TaskUtils +import com.datadog.gradle.plugin.internal.getSearchObjDirs +import org.gradle.api.Project +import org.gradle.api.artifacts.Configuration +import org.gradle.api.file.RegularFile +import org.gradle.api.provider.Provider +import org.gradle.api.provider.ProviderFactory +import org.gradle.api.tasks.TaskProvider +import java.io.File +import java.nio.file.Paths + +internal class LegacyApiAppVariant( + private val variant: ApplicationVariant, + private val appExtension: AppExtension, + private val target: Project, + private val providerFactory: ProviderFactory +) : AppVariant { + + override val name: String = variant.name + override val applicationId: Provider = providerFactory.provider { variant.applicationId } + override val flavorName: String = variant.flavorName + override val versionCode: Provider = providerFactory.provider { variant.versionCode } + override val versionName: Provider = providerFactory.provider { variant.versionName.orEmpty() } + override val compileConfiguration: Configuration = variant.compileConfiguration + override val nativeBuildEnabled: Boolean = variant.externalNativeBuildProviders.isNotEmpty() + override val isMinifyEnabled: Boolean = variant.buildType.isMinifyEnabled + override val buildTypeName: String = variant.buildType.name + override val flavors: List = variant.productFlavors.map { it.name } + override val mappingFile: Provider = target.layout.buildDirectory.file( + Paths.get("outputs", "mapping", variant.name, "mapping.txt").toString() + ) + + override fun collectJavaAndKotlinSourceDirectories(): Provider> { + val roots = mutableListOf() + variant.sourceSets.forEach { + roots.addAll(it.javaDirectories) + @Suppress("MagicNumber") + if (TaskUtils.isAgpAbove(7, 0, 0)) { + roots.addAll(it.kotlinDirectories) + } + } + return providerFactory.provider { roots } + } + + override fun bindWith(ndkUploadTask: NdkSymbolFileUploadTask) { + val nativeBuildProviders = variant.externalNativeBuildProviders + nativeBuildProviders.forEach { buildTask -> + val searchFiles = buildTask.getSearchObjDirs(providerFactory) + + ndkUploadTask.searchDirectories.from(searchFiles) + ndkUploadTask.dependsOn(buildTask) + } + } + + override fun bindWith(generateBuildIdTask: TaskProvider) { + // we could generate buildIdDirectory inside GenerateBuildIdTask and read it here as + // property using flatMap, but when Gradle sync is done inside Android Studio there is an error + // Querying the mapped value of provider (java.util.Set) before task ... has completed is + // not supported, which doesn't happen when Android Studio is not used (pure Gradle build) + // so applying such workaround + // TODO RUM-0000 use new AndroidComponents API to inject generated stuff, it is more friendly + appExtension.sourceSets.getByName(variant.name).assets.srcDir(generateBuildIdTask.get().buildIdDirectory) + + val variantName = variant.name.capitalize() + listOf( + "package${variantName}Bundle", + "build${variantName}PreBundle", + "lintVitalAnalyze$variantName", + "lintVitalReport$variantName", + "generate${variantName}LintVitalReportModel" + ).forEach { + target.tasks.findByName(it)?.dependsOn(generateBuildIdTask) + } + + // don't merge these 2 into list to call forEach, because common superclass for them + // is different between AGP versions, which may cause ClassCastException + variant.mergeAssetsProvider.configure { it.dependsOn(generateBuildIdTask) } + variant.packageApplicationProvider.configure { it.dependsOn(generateBuildIdTask) } + } +} diff --git a/dd-sdk-android-gradle-plugin/src/main/kotlin/com/datadog/gradle/plugin/internal/variant/NewApiAppVariant.kt b/dd-sdk-android-gradle-plugin/src/main/kotlin/com/datadog/gradle/plugin/internal/variant/NewApiAppVariant.kt new file mode 100644 index 00000000..4fc451d8 --- /dev/null +++ b/dd-sdk-android-gradle-plugin/src/main/kotlin/com/datadog/gradle/plugin/internal/variant/NewApiAppVariant.kt @@ -0,0 +1,88 @@ +/* + * Unless explicitly stated otherwise all files in this repository are licensed under the Apache License Version 2.0. + * This product includes software developed at Datadog (https://www.datadoghq.com/). + * Copyright 2020-Present Datadog, Inc. + */ + +package com.datadog.gradle.plugin.internal.variant + +import com.android.build.api.artifact.SingleArtifact +import com.android.build.api.variant.ApplicationVariant +import com.android.build.api.variant.VariantOutput +import com.android.build.gradle.tasks.ExternalNativeBuildTask +import com.datadog.gradle.plugin.GenerateBuildIdTask +import com.datadog.gradle.plugin.NdkSymbolFileUploadTask +import com.datadog.gradle.plugin.internal.getSearchObjDirs +import org.gradle.api.Project +import org.gradle.api.artifacts.Configuration +import org.gradle.api.file.Directory +import org.gradle.api.file.RegularFile +import org.gradle.api.provider.Provider +import org.gradle.api.provider.ProviderFactory +import org.gradle.api.tasks.TaskProvider +import java.io.File + +internal class NewApiAppVariant( + private val variant: ApplicationVariant, + private val target: Project, + private val providerFactory: ProviderFactory +) : AppVariant { + + override val name: String = variant.name + override val applicationId: Provider = variant.applicationId + override val flavorName: String = variant.flavorName.orEmpty() + override val versionCode: Provider = + providerFactory.provider { variant.mainOutput?.versionCode?.get() ?: 1 } + override val versionName: Provider = + providerFactory.provider { variant.mainOutput?.versionName?.get().orEmpty() } + override val compileConfiguration: Configuration = variant.compileConfiguration + override val nativeBuildEnabled: Boolean = variant.externalNativeBuild != null + + @Suppress("UnstableApiUsage") + override val isMinifyEnabled: Boolean = variant.isMinifyEnabled + override val buildTypeName: String = variant.buildType.orEmpty() + override val flavors: List = variant.productFlavors.map { it.second } + override val mappingFile: Provider = + variant.artifacts.get(SingleArtifact.OBFUSCATION_MAPPING_FILE) + + override fun collectJavaAndKotlinSourceDirectories(): Provider> { + val allJava = variant.sources.java?.all + + @Suppress("UnstableApiUsage") + val allKotlin = variant.sources.kotlin?.all + return if (allJava != null) { + if (allKotlin != null) { + allJava.zip(allKotlin) { java, kotlin -> java + kotlin }.asFileCollectionProvider() + } else { + allJava.asFileCollectionProvider() + } + } else { + allKotlin?.asFileCollectionProvider() ?: providerFactory.provider { emptyList() } + } + } + + override fun bindWith(ndkUploadTask: NdkSymbolFileUploadTask) { + target.tasks.withType(ExternalNativeBuildTask::class.java).forEach { + val searchFiles = it.getSearchObjDirs(providerFactory) + ndkUploadTask.searchDirectories.from(searchFiles) + ndkUploadTask.dependsOn(it) + } + } + + override fun bindWith(generateBuildIdTask: TaskProvider) { + variant.sources.assets?.addGeneratedSourceDirectory(generateBuildIdTask) { + it.buildIdDirectory + } + } + + // region Private + + private fun Provider>.asFileCollectionProvider() = + map { collection -> collection.map { it.asFile } } + + // may not be precise, but we need this info only for metadata anyway + private val ApplicationVariant.mainOutput: VariantOutput? + get() = outputs.firstOrNull { it.enabled.get() && it.versionCode.isPresent } + + // endregion +} diff --git a/dd-sdk-android-gradle-plugin/src/test/kotlin/com/datadog/gradle/plugin/DdCheckSdkDepsTaskTest.kt b/dd-sdk-android-gradle-plugin/src/test/kotlin/com/datadog/gradle/plugin/CheckSdkDepsTaskTest.kt similarity index 95% rename from dd-sdk-android-gradle-plugin/src/test/kotlin/com/datadog/gradle/plugin/DdCheckSdkDepsTaskTest.kt rename to dd-sdk-android-gradle-plugin/src/test/kotlin/com/datadog/gradle/plugin/CheckSdkDepsTaskTest.kt index fd9e31a1..1240372a 100644 --- a/dd-sdk-android-gradle-plugin/src/test/kotlin/com/datadog/gradle/plugin/DdCheckSdkDepsTaskTest.kt +++ b/dd-sdk-android-gradle-plugin/src/test/kotlin/com/datadog/gradle/plugin/CheckSdkDepsTaskTest.kt @@ -7,6 +7,7 @@ package com.datadog.gradle.plugin import com.datadog.gradle.plugin.internal.MissingSdkException +import com.datadog.gradle.plugin.utils.forge.Configurator import com.datadog.gradle.plugin.utils.setStaticValue import fr.xgouchet.elmyr.Forge import fr.xgouchet.elmyr.ForgeryException @@ -51,8 +52,8 @@ import java.io.UncheckedIOException ) @MockitoSettings(strictness = Strictness.LENIENT) @ForgeConfiguration(Configurator::class) -internal class DdCheckSdkDepsTaskTest { - lateinit var testedTask: DdCheckSdkDepsTask +internal class CheckSdkDepsTaskTest { + lateinit var testedTask: CheckSdkDepsTask lateinit var fakeSdkCheckLevel: SdkCheckLevel @@ -80,8 +81,8 @@ internal class DdCheckSdkDepsTaskTest { @BeforeEach fun `set up`(forge: Forge) { - originalLogger = DdCheckSdkDepsTask.LOGGER - DdCheckSdkDepsTask::class.java.setStaticValue("LOGGER", mockLogger) + originalLogger = CheckSdkDepsTask.LOGGER + CheckSdkDepsTask::class.java.setStaticValue("LOGGER", mockLogger) whenever(mockConfiguration.name).thenReturn(fakeConfigurationName) whenever(mockConfiguration.resolvedConfiguration).thenReturn(mockResolvedConfiguration) @@ -95,7 +96,7 @@ internal class DdCheckSdkDepsTaskTest { testedTask = fakeProject.tasks.create( "DdCheckDepsTask", - DdCheckSdkDepsTask::class.java + CheckSdkDepsTask::class.java ) { it.configurationName.set(fakeConfigurationName) it.sdkCheckLevel.set(fakeSdkCheckLevel) @@ -105,7 +106,7 @@ internal class DdCheckSdkDepsTaskTest { @AfterEach fun `tear down`() { - DdCheckSdkDepsTask::class.java.setStaticValue("LOGGER", originalLogger) + CheckSdkDepsTask::class.java.setStaticValue("LOGGER", originalLogger) } // region taskAction @@ -120,7 +121,7 @@ internal class DdCheckSdkDepsTaskTest { // THEN verify(mockLogger).info( - DdCheckSdkDepsTask.CANNOT_FIND_CONFIGURATION_MESSAGE + CheckSdkDepsTask.CANNOT_FIND_CONFIGURATION_MESSAGE .format(fakeConfigurationName, fakeVariantName) ) } @@ -206,7 +207,7 @@ internal class DdCheckSdkDepsTaskTest { testedTask.applyTask() // THEN - verify(mockLogger).warn(DdCheckSdkDepsTask.MISSING_DD_SDK_MESSAGE.format(fakeVariantName)) + verify(mockLogger).warn(CheckSdkDepsTask.MISSING_DD_SDK_MESSAGE.format(fakeVariantName)) assertThat(testedTask.isLastRunSuccessful).isFalse() } 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 90312bf2..417c1325 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 @@ -7,6 +7,7 @@ package com.datadog.gradle.plugin import com.datadog.gradle.plugin.utils.assertj.BuildResultAssert.Companion.assertThat +import com.datadog.gradle.plugin.utils.forge.Configurator import com.datadog.gradle.plugin.utils.headHash import com.datadog.gradle.plugin.utils.initializeGit import fr.xgouchet.elmyr.Forge @@ -37,6 +38,7 @@ import kotlin.io.path.Path ) @ForgeConfiguration(value = Configurator::class) internal class DdAndroidGradlePluginFunctionalTest { + @TempDir lateinit var testProjectDir: File private lateinit var appRootDir: File @@ -853,7 +855,7 @@ internal class DdAndroidGradlePluginFunctionalTest { "outputs", "mapping", "${variant}Release", - DdMappingFileUploadTask.MAPPING_OPTIMIZED_FILE_NAME + MappingFileUploadTask.MAPPING_OPTIMIZED_FILE_NAME ).toFile() assertThat(result).containsInOutput( "Size of optimized file is ${optimizedFile.length()} bytes" 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 0c05e8b0..5b589167 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 @@ -6,34 +6,29 @@ package com.datadog.gradle.plugin -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 import com.datadog.gradle.plugin.internal.ApiKeySource import com.datadog.gradle.plugin.internal.GitRepositoryDetector +import com.datadog.gradle.plugin.internal.variant.AppVariant import com.datadog.gradle.plugin.utils.capitalizeChar +import com.datadog.gradle.plugin.utils.forge.Configurator import fr.xgouchet.elmyr.Case import fr.xgouchet.elmyr.Forge import fr.xgouchet.elmyr.annotation.AdvancedForgery import fr.xgouchet.elmyr.annotation.BoolForgery import fr.xgouchet.elmyr.annotation.Forgery +import fr.xgouchet.elmyr.annotation.IntForgery import fr.xgouchet.elmyr.annotation.MapForgery import fr.xgouchet.elmyr.annotation.StringForgery import fr.xgouchet.elmyr.annotation.StringForgeryType import fr.xgouchet.elmyr.junit5.ForgeConfiguration import fr.xgouchet.elmyr.junit5.ForgeExtension import org.assertj.core.api.Assertions.assertThat -import org.gradle.api.NamedDomainObjectContainer import org.gradle.api.Project import org.gradle.api.Transformer import org.gradle.api.artifacts.Configuration +import org.gradle.api.file.RegularFile import org.gradle.api.provider.Provider -import org.gradle.api.provider.ProviderFactory import org.gradle.api.tasks.TaskProvider import org.gradle.testfixtures.ProjectBuilder import org.junit.jupiter.api.BeforeEach @@ -44,14 +39,14 @@ import org.mockito.Mock import org.mockito.junit.jupiter.MockitoExtension import org.mockito.junit.jupiter.MockitoSettings import org.mockito.kotlin.any -import org.mockito.kotlin.doAnswer import org.mockito.kotlin.doReturn import org.mockito.kotlin.mock +import org.mockito.kotlin.never +import org.mockito.kotlin.verify import org.mockito.kotlin.whenever import org.mockito.quality.Strictness import java.io.File import java.util.UUID -import java.util.concurrent.Callable @Extensions( ExtendWith(MockitoExtension::class), @@ -66,10 +61,7 @@ internal class DdAndroidGradlePluginTest { lateinit var fakeProject: Project @Mock - lateinit var mockVariant: ApplicationVariant - - @Mock - lateinit var mockBuildType: BuildType + lateinit var mockVariant: AppVariant lateinit var fakeBuildId: String @@ -93,14 +85,9 @@ internal class DdAndroidGradlePluginTest { fakeFlavorNames = fakeFlavorNames.take(5) // A D F G A♭ A A♭ G F fakeBuildId = forge.getForgery().toString() fakeProject = ProjectBuilder.builder().build() - val mockProviderFactory = mock() - whenever(mockProviderFactory.provider(any>())) doAnswer { - val argument = it.getArgument>(0) - fakeProject.provider(argument) - } testedPlugin = DdAndroidGradlePlugin( execOps = mock(), - providerFactory = mockProviderFactory + providerFactory = fakeProject.providers ) setEnv(DdAndroidGradlePlugin.DD_API_KEY, "") @@ -114,6 +101,7 @@ internal class DdAndroidGradlePluginTest { @StringForgery(case = Case.LOWER) flavorName: String, @StringForgery(case = Case.LOWER) buildTypeName: String, @StringForgery versionName: String, + @IntForgery(min = 1) versionCode: Int, @StringForgery packageName: String ) { // Given @@ -123,11 +111,12 @@ internal class DdAndroidGradlePluginTest { whenever(mockVariant.name) doReturn "$flavorName${buildTypeName.replaceFirstChar { capitalizeChar(it) }}" whenever(mockVariant.flavorName) doReturn flavorName - whenever(mockVariant.versionName) doReturn versionName - whenever(mockVariant.applicationId) doReturn packageName - whenever(mockVariant.buildType) doReturn mockBuildType - whenever(mockBuildType.isMinifyEnabled) doReturn true - whenever(mockBuildType.name) doReturn fakeBuildTypeName + whenever(mockVariant.versionCode) doReturn versionCode.asProvider() + whenever(mockVariant.versionName) doReturn versionName.asProvider() + whenever(mockVariant.applicationId) doReturn packageName.asProvider() + whenever(mockVariant.buildTypeName) doReturn fakeBuildTypeName + whenever(mockVariant.isMinifyEnabled) doReturn true + whenever(mockVariant.collectJavaAndKotlinSourceDirectories()) doReturn emptyList().asProvider() // When val task = testedPlugin.configureVariantForUploadTask( @@ -139,7 +128,7 @@ internal class DdAndroidGradlePluginTest { ).get() // Then - check(task is DdMappingFileUploadTask) + check(task is MappingFileUploadTask) assertThat(task.repositoryDetector).isInstanceOf(GitRepositoryDetector::class.java) assertThat(task.name).isEqualTo( "uploadMapping${variantName.replaceFirstChar { capitalizeChar(it) }}" @@ -147,11 +136,12 @@ internal class DdAndroidGradlePluginTest { assertThat(task.apiKey).isEqualTo(fakeApiKey.value) assertThat(task.apiKeySource).isEqualTo(fakeApiKey.source) assertThat(task.variantName).isEqualTo(flavorName) - assertThat(task.versionName).isEqualTo(versionName) - assertThat(task.serviceName).isEqualTo(packageName) + assertThat(task.versionName.get()).isEqualTo(versionName) + assertThat(task.serviceName.get()).isEqualTo(packageName) assertThat(task.site).isEqualTo(fakeExtension.site) assertThat(task.remoteRepositoryUrl).isEqualTo(fakeExtension.remoteRepositoryUrl) - assertThat(task.mappingFilePath).isEqualTo(fakeExtension.mappingFilePath) + assertThat(task.mappingFile.get().asFile) + .isEqualTo(File(fakeProject.projectDir, fakeExtension.mappingFilePath)) assertThat(task.mappingFilePackagesAliases) .isEqualTo(fakeExtension.mappingFilePackageAliases) assertThat(task.datadogCiFile).isNull() @@ -163,17 +153,19 @@ internal class DdAndroidGradlePluginTest { @StringForgery(case = Case.LOWER) flavorName: String, @StringForgery(case = Case.LOWER) buildTypeName: String, @StringForgery versionName: String, + @IntForgery(min = 1) versionCode: Int, @StringForgery packageName: String ) { // Given 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(mockBuildType.isMinifyEnabled) doReturn true - whenever(mockBuildType.name) doReturn fakeBuildTypeName + whenever(mockVariant.versionCode) doReturn versionCode.asProvider() + whenever(mockVariant.versionName) doReturn versionName.asProvider() + whenever(mockVariant.applicationId) doReturn packageName.asProvider() + whenever(mockVariant.buildTypeName) doReturn fakeBuildTypeName + whenever(mockVariant.isMinifyEnabled) doReturn true + whenever(mockVariant.collectJavaAndKotlinSourceDirectories()) doReturn emptyList().asProvider() // When val task = testedPlugin.configureVariantForUploadTask( @@ -185,7 +177,7 @@ internal class DdAndroidGradlePluginTest { ).get() // Then - check(task is DdMappingFileUploadTask) + check(task is MappingFileUploadTask) assertThat(task.repositoryDetector).isInstanceOf(GitRepositoryDetector::class.java) assertThat(task.name).isEqualTo( "uploadMapping${variantName.replaceFirstChar { capitalizeChar(it) }}" @@ -193,11 +185,12 @@ internal class DdAndroidGradlePluginTest { assertThat(task.apiKey).isEqualTo(fakeApiKey.value) assertThat(task.apiKeySource).isEqualTo(fakeApiKey.source) assertThat(task.variantName).isEqualTo(flavorName) - assertThat(task.versionName).isEqualTo(fakeExtension.versionName) - assertThat(task.serviceName).isEqualTo(fakeExtension.serviceName) + assertThat(task.versionName.get()).isEqualTo(fakeExtension.versionName) + assertThat(task.serviceName.get()).isEqualTo(fakeExtension.serviceName) assertThat(task.site).isEqualTo(fakeExtension.site) assertThat(task.remoteRepositoryUrl).isEqualTo(fakeExtension.remoteRepositoryUrl) - assertThat(task.mappingFilePath).isEqualTo(fakeExtension.mappingFilePath) + assertThat(task.mappingFile.get().asFile) + .isEqualTo(File(fakeProject.projectDir, fakeExtension.mappingFilePath)) assertThat(task.mappingFilePackagesAliases) .isEqualTo(fakeExtension.mappingFilePackageAliases) assertThat(task.mappingFileTrimIndents) @@ -211,6 +204,7 @@ internal class DdAndroidGradlePluginTest { @StringForgery(case = Case.LOWER) flavorName: String, @StringForgery(case = Case.LOWER) buildTypeName: String, @StringForgery versionName: String, + @IntForgery(min = 1) versionCode: Int, @StringForgery packageName: String, forge: Forge ) { @@ -218,11 +212,12 @@ internal class DdAndroidGradlePluginTest { 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(mockBuildType.isMinifyEnabled) doReturn true - whenever(mockBuildType.name) doReturn fakeBuildTypeName + whenever(mockVariant.versionCode) doReturn versionCode.asProvider() + whenever(mockVariant.versionName) doReturn versionName.asProvider() + whenever(mockVariant.applicationId) doReturn packageName.asProvider() + whenever(mockVariant.buildTypeName) doReturn fakeBuildTypeName + whenever(mockVariant.isMinifyEnabled) doReturn true + whenever(mockVariant.collectJavaAndKotlinSourceDirectories()) doReturn emptyList().asProvider() val aliasToFilterOut = packageName.substring(0, forge.anInt(min = 1, max = packageName.length + 1)) to @@ -243,7 +238,7 @@ internal class DdAndroidGradlePluginTest { ).get() // Then - check(task is DdMappingFileUploadTask) + check(task is MappingFileUploadTask) assertThat(task.repositoryDetector).isInstanceOf(GitRepositoryDetector::class.java) assertThat(task.name).isEqualTo( "uploadMapping${variantName.replaceFirstChar { capitalizeChar(it) }}" @@ -251,11 +246,12 @@ internal class DdAndroidGradlePluginTest { assertThat(task.apiKey).isEqualTo(fakeApiKey.value) assertThat(task.apiKeySource).isEqualTo(fakeApiKey.source) assertThat(task.variantName).isEqualTo(flavorName) - assertThat(task.versionName).isEqualTo(fakeExtension.versionName) - assertThat(task.serviceName).isEqualTo(fakeExtension.serviceName) + assertThat(task.versionName.get()).isEqualTo(fakeExtension.versionName) + assertThat(task.serviceName.get()).isEqualTo(fakeExtension.serviceName) assertThat(task.site).isEqualTo(fakeExtension.site) assertThat(task.remoteRepositoryUrl).isEqualTo(fakeExtension.remoteRepositoryUrl) - assertThat(task.mappingFilePath).isEqualTo(fakeExtension.mappingFilePath) + assertThat(task.mappingFile.get().asFile) + .isEqualTo(File(fakeProject.projectDir, fakeExtension.mappingFilePath)) assertThat(task.mappingFilePackagesAliases) .isEqualTo(fakeExtension.mappingFilePackageAliases.minus(aliasToFilterOut.first)) assertThat(task.mappingFileTrimIndents) @@ -269,6 +265,7 @@ internal class DdAndroidGradlePluginTest { @StringForgery(case = Case.LOWER) flavorName: String, @StringForgery(case = Case.LOWER) buildTypeName: String, @StringForgery versionName: String, + @IntForgery(min = 1) versionCode: Int, @StringForgery packageName: String ) { // Given @@ -283,11 +280,13 @@ internal class DdAndroidGradlePluginTest { val fakeMappingFilePath = "${fakeProject.buildDir}/outputs/mapping/$variantName/mapping.txt" 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(mockBuildType.isMinifyEnabled) doReturn true - whenever(mockBuildType.name) doReturn fakeBuildTypeName + whenever(mockVariant.versionCode) doReturn versionCode.asProvider() + whenever(mockVariant.versionName) doReturn versionName.asProvider() + whenever(mockVariant.applicationId) doReturn packageName.asProvider() + whenever(mockVariant.buildTypeName) doReturn fakeBuildTypeName + whenever(mockVariant.isMinifyEnabled) doReturn true + whenever(mockVariant.mappingFile) doReturn fakeMappingFilePath.asFileProvider() + whenever(mockVariant.collectJavaAndKotlinSourceDirectories()) doReturn emptyList().asProvider() // When val task = testedPlugin.configureVariantForUploadTask( @@ -299,7 +298,7 @@ internal class DdAndroidGradlePluginTest { ).get() // Then - check(task is DdMappingFileUploadTask) + check(task is MappingFileUploadTask) assertThat(task.repositoryDetector).isInstanceOf(GitRepositoryDetector::class.java) assertThat(task.name).isEqualTo( "uploadMapping${variantName.replaceFirstChar { capitalizeChar(it) }}" @@ -307,11 +306,11 @@ internal class DdAndroidGradlePluginTest { assertThat(task.apiKey).isEqualTo(fakeApiKey.value) assertThat(task.apiKeySource).isEqualTo(fakeApiKey.source) assertThat(task.variantName).isEqualTo(flavorName) - assertThat(task.versionName).isEqualTo(versionName) - assertThat(task.serviceName).isEqualTo(packageName) + assertThat(task.versionName.get()).isEqualTo(versionName) + assertThat(task.serviceName.get()).isEqualTo(packageName) assertThat(task.remoteRepositoryUrl).isEmpty() assertThat(task.site).isEqualTo("") - assertThat(task.mappingFilePath).isEqualTo(fakeMappingFilePath) + assertThat(task.mappingFile.get().asFile.path).isEqualTo(fakeMappingFilePath) assertThat(task.mappingFilePackagesAliases).isEmpty() assertThat(task.mappingFileTrimIndents).isFalse assertThat(task.datadogCiFile).isNull() @@ -323,6 +322,7 @@ internal class DdAndroidGradlePluginTest { @StringForgery(case = Case.LOWER) flavorName: String, @StringForgery(case = Case.LOWER) buildTypeName: String, @StringForgery versionName: String, + @IntForgery(min = 1) versionCode: Int, @StringForgery packageName: String ) { // Given @@ -338,11 +338,13 @@ internal class DdAndroidGradlePluginTest { val fakeMappingFilePath = "${fakeProject.buildDir}/outputs/mapping/$variantName/mapping.txt" 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(mockBuildType.isMinifyEnabled) doReturn true - whenever(mockBuildType.name) doReturn fakeBuildTypeName + whenever(mockVariant.versionCode) doReturn versionCode.asProvider() + whenever(mockVariant.versionName) doReturn versionName.asProvider() + whenever(mockVariant.applicationId) doReturn packageName.asProvider() + whenever(mockVariant.buildTypeName) doReturn fakeBuildTypeName + whenever(mockVariant.isMinifyEnabled) doReturn true + whenever(mockVariant.mappingFile) doReturn fakeMappingFilePath.asFileProvider() + whenever(mockVariant.collectJavaAndKotlinSourceDirectories()) doReturn emptyList().asProvider() val fakeDatadogCiFile = File(fakeProject.projectDir, "datadog-ci.json") fakeDatadogCiFile.createNewFile() @@ -357,7 +359,7 @@ internal class DdAndroidGradlePluginTest { ).get() // Then - check(task is DdMappingFileUploadTask) + check(task is MappingFileUploadTask) assertThat(task.repositoryDetector).isInstanceOf(GitRepositoryDetector::class.java) assertThat(task.name).isEqualTo( "uploadMapping${variantName.replaceFirstChar { capitalizeChar(it) }}" @@ -365,11 +367,11 @@ internal class DdAndroidGradlePluginTest { assertThat(task.apiKey).isEqualTo(fakeApiKey.value) assertThat(task.apiKeySource).isEqualTo(fakeApiKey.source) assertThat(task.variantName).isEqualTo(flavorName) - assertThat(task.versionName).isEqualTo(versionName) - assertThat(task.serviceName).isEqualTo(packageName) + assertThat(task.versionName.get()).isEqualTo(versionName) + assertThat(task.serviceName.get()).isEqualTo(packageName) assertThat(task.remoteRepositoryUrl).isEmpty() assertThat(task.site).isEqualTo("") - assertThat(task.mappingFilePath).isEqualTo(fakeMappingFilePath) + assertThat(task.mappingFile.get().asFile.path).isEqualTo(fakeMappingFilePath) assertThat(task.mappingFilePackagesAliases).isEmpty() assertThat(task.mappingFileTrimIndents).isFalse assertThat(task.datadogCiFile).isEqualTo(fakeDatadogCiFile) @@ -381,6 +383,7 @@ internal class DdAndroidGradlePluginTest { @StringForgery(case = Case.LOWER) flavorName: String, @StringForgery(case = Case.LOWER) buildTypeName: String, @StringForgery versionName: String, + @IntForgery(min = 1) versionCode: Int, @StringForgery packageName: String ) { // Given @@ -396,11 +399,13 @@ internal class DdAndroidGradlePluginTest { val fakeMappingFilePath = "${fakeProject.buildDir}/outputs/mapping/$variantName/mapping.txt" 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(mockBuildType.isMinifyEnabled) doReturn true - whenever(mockBuildType.name) doReturn fakeBuildTypeName + whenever(mockVariant.versionCode) doReturn versionCode.asProvider() + whenever(mockVariant.versionName) doReturn versionName.asProvider() + whenever(mockVariant.applicationId) doReturn packageName.asProvider() + whenever(mockVariant.buildTypeName) doReturn fakeBuildTypeName + whenever(mockVariant.isMinifyEnabled) doReturn true + whenever(mockVariant.mappingFile) doReturn fakeMappingFilePath.asFileProvider() + whenever(mockVariant.collectJavaAndKotlinSourceDirectories()) doReturn emptyList().asProvider() val fakeDatadogCiFile = File(fakeProject.projectDir, "datadog-ci.json") fakeDatadogCiFile.createNewFile() @@ -415,7 +420,7 @@ internal class DdAndroidGradlePluginTest { ).get() // Then - check(task is DdMappingFileUploadTask) + check(task is MappingFileUploadTask) assertThat(task.repositoryDetector).isInstanceOf(GitRepositoryDetector::class.java) assertThat(task.name).isEqualTo( "uploadMapping${variantName.replaceFirstChar { capitalizeChar(it) }}" @@ -423,11 +428,11 @@ internal class DdAndroidGradlePluginTest { assertThat(task.apiKey).isEqualTo(fakeApiKey.value) assertThat(task.apiKeySource).isEqualTo(fakeApiKey.source) assertThat(task.variantName).isEqualTo(flavorName) - assertThat(task.versionName).isEqualTo(versionName) - assertThat(task.serviceName).isEqualTo(packageName) + assertThat(task.versionName.get()).isEqualTo(versionName) + assertThat(task.serviceName.get()).isEqualTo(packageName) assertThat(task.remoteRepositoryUrl).isEmpty() assertThat(task.site).isEqualTo("") - assertThat(task.mappingFilePath).isEqualTo(fakeMappingFilePath) + assertThat(task.mappingFile.get().asFile.path).isEqualTo(fakeMappingFilePath) assertThat(task.mappingFilePackagesAliases).isEmpty() assertThat(task.mappingFileTrimIndents).isFalse assertThat(task.datadogCiFile).isNull() @@ -435,29 +440,21 @@ internal class DdAndroidGradlePluginTest { } @Test - fun `M not create buildId task W configureTasksForVariant() { no deobfuscation, no native build providers }`( + fun `M not create buildId task W configureTasksForVariant() { no deobfuscation, no native build enabled }`( @StringForgery(case = Case.LOWER) flavorName: String, - @StringForgery(case = Case.LOWER) buildTypeName: String, - @StringForgery versionName: String, - @StringForgery packageName: String + @StringForgery(case = Case.LOWER) buildTypeName: 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.isMinifyEnabled) doReturn false + whenever(mockVariant.nativeBuildEnabled) doReturn false + whenever(mockVariant.flavors) doReturn fakeFlavorNames + whenever(mockVariant.buildTypeName) doReturn fakeBuildTypeName // When testedPlugin.configureTasksForVariant( fakeProject, - mockAppExtension, fakeExtension, mockVariant, fakeApiKey @@ -466,39 +463,33 @@ internal class DdAndroidGradlePluginTest { // Then val allTasks = fakeProject.tasks.map { it.name } assertThat(allTasks).doesNotContain("generateBuildId${variantName.replaceFirstChar { capitalizeChar(it) }}") + verify(mockVariant, never()).bindWith(any>()) } @Test - fun `M create uploadSymbol task W configureTasksForVariant() { native build providers }`( + fun `M create uploadNdkSymbolFiles task W configureTasksForVariant() { native build providers }`( @StringForgery(case = Case.LOWER) flavorName: String, @StringForgery(case = Case.LOWER) buildTypeName: String, + @IntForgery(min = 0) versionCode: Int, @StringForgery versionName: String, @StringForgery packageName: String ) { // Given - val mockAppExtension = mockAppExtension() - val variantName = "$flavorName${buildTypeName.replaceFirstChar { capitalizeChar(it) }}" whenever(mockVariant.name) doReturn variantName + whenever(mockVariant.isMinifyEnabled) doReturn true + whenever(mockVariant.nativeBuildEnabled) doReturn true + whenever(mockVariant.versionCode) doReturn versionCode.asProvider() + whenever(mockVariant.versionName) doReturn versionName.asProvider() + whenever(mockVariant.flavors) doReturn fakeFlavorNames + whenever(mockVariant.buildTypeName) doReturn fakeBuildTypeName 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 + whenever(mockVariant.applicationId) doReturn packageName.asProvider() + whenever(mockVariant.collectJavaAndKotlinSourceDirectories()) doReturn emptyList().asProvider() // When testedPlugin.configureTasksForVariant( fakeProject, - mockAppExtension, fakeExtension, mockVariant, fakeApiKey @@ -507,34 +498,33 @@ internal class DdAndroidGradlePluginTest { // Then val allTasks = fakeProject.tasks.map { it.name } assertThat(allTasks).contains("uploadNdkSymbolFiles${variantName.replaceFirstChar { capitalizeChar(it) }}") + verify(mockVariant).bindWith(any()) } @Test - fun `M not create uploadSymbol task W configureTasksForVariant() { no native build providers }`( + fun `M not create uploadNdkSymbolFiles task W configureTasksForVariant() { no native build providers }`( @StringForgery(case = Case.LOWER) flavorName: String, @StringForgery(case = Case.LOWER) buildTypeName: String, + @IntForgery(min = 0) versionCode: Int, @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() + whenever(mockVariant.isMinifyEnabled) doReturn true + whenever(mockVariant.nativeBuildEnabled) doReturn false + whenever(mockVariant.versionCode) doReturn versionCode.asProvider() + whenever(mockVariant.versionName) doReturn versionName.asProvider() + whenever(mockVariant.flavors) doReturn fakeFlavorNames + whenever(mockVariant.buildTypeName) doReturn fakeBuildTypeName + whenever(mockVariant.applicationId) doReturn packageName.asProvider() + whenever(mockVariant.collectJavaAndKotlinSourceDirectories()) doReturn emptyList().asProvider() // When testedPlugin.configureTasksForVariant( fakeProject, - mockAppExtension, fakeExtension, mockVariant, fakeApiKey @@ -543,33 +533,30 @@ internal class DdAndroidGradlePluginTest { // Then val allTasks = fakeProject.tasks.map { it.name } assertThat(allTasks).allMatch { !it.startsWith("uploadNdkSymbolFiles") } + verify(mockVariant, never()).bindWith(any()) } @Test fun `M not create mapping upload task W configureTasksForVariant() { no deobfuscation }`( @StringForgery(case = Case.LOWER) flavorName: String, @StringForgery(case = Case.LOWER) buildTypeName: String, - @StringForgery versionName: String, - @StringForgery packageName: String + @IntForgery(min = 0) versionCode: Int, + @StringForgery versionName: 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(mockBuildType.name) doReturn fakeBuildTypeName - whenever(mockVariant.mergeAssetsProvider) doReturn mock() - whenever(mockVariant.packageApplicationProvider) doReturn mock() - whenever(mockBuildType.name) doReturn fakeBuildTypeName + whenever(mockVariant.versionCode) doReturn versionCode.asProvider() + whenever(mockVariant.versionName) doReturn versionName.asProvider() + whenever(mockVariant.isMinifyEnabled) doReturn false + whenever(mockVariant.nativeBuildEnabled) doReturn true + whenever(mockVariant.flavors) doReturn fakeFlavorNames + whenever(mockVariant.buildTypeName) doReturn fakeBuildTypeName + whenever(mockVariant.collectJavaAndKotlinSourceDirectories()) doReturn emptyList().asProvider() // When testedPlugin.configureTasksForVariant( fakeProject, - mockAppExtension, fakeExtension, mockVariant, fakeApiKey @@ -585,6 +572,7 @@ internal class DdAndroidGradlePluginTest { @StringForgery(case = Case.LOWER) flavorName: String, @StringForgery(case = Case.LOWER) buildTypeName: String, @StringForgery versionName: String, + @IntForgery(min = 1) versionCode: Int, @StringForgery packageName: String ) { // Given @@ -592,11 +580,12 @@ internal class DdAndroidGradlePluginTest { 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(mockBuildType.isMinifyEnabled) doReturn false - whenever(mockBuildType.name) doReturn fakeBuildTypeName + whenever(mockVariant.versionCode) doReturn versionCode.asProvider() + whenever(mockVariant.versionName) doReturn versionName.asProvider() + whenever(mockVariant.applicationId) doReturn packageName.asProvider() + whenever(mockVariant.buildTypeName) doReturn fakeBuildTypeName + whenever(mockVariant.isMinifyEnabled) doReturn false + whenever(mockVariant.collectJavaAndKotlinSourceDirectories()) doReturn emptyList().asProvider() // When val task = testedPlugin.configureVariantForUploadTask( @@ -608,7 +597,7 @@ internal class DdAndroidGradlePluginTest { ).get() // Then - check(task is DdMappingFileUploadTask) + check(task is MappingFileUploadTask) assertThat(task.repositoryDetector).isInstanceOf(GitRepositoryDetector::class.java) assertThat(task.name).isEqualTo( "uploadMapping${variantName.replaceFirstChar { capitalizeChar(it) }}" @@ -616,11 +605,12 @@ internal class DdAndroidGradlePluginTest { assertThat(task.apiKey).isEqualTo(fakeApiKey.value) assertThat(task.apiKeySource).isEqualTo(fakeApiKey.source) assertThat(task.variantName).isEqualTo(flavorName) - assertThat(task.versionName).isEqualTo(fakeExtension.versionName) - assertThat(task.serviceName).isEqualTo(fakeExtension.serviceName) + assertThat(task.versionName.get()).isEqualTo(fakeExtension.versionName) + assertThat(task.serviceName.get()).isEqualTo(fakeExtension.serviceName) assertThat(task.site).isEqualTo(fakeExtension.site) assertThat(task.remoteRepositoryUrl).isEqualTo(fakeExtension.remoteRepositoryUrl) - assertThat(task.mappingFilePath).isEqualTo(fakeExtension.mappingFilePath) + assertThat(task.mappingFile.get().asFile) + .isEqualTo(File(fakeProject.projectDir, fakeExtension.mappingFilePath)) assertThat(task.mappingFilePackagesAliases) .isEqualTo(fakeExtension.mappingFilePackageAliases) assertThat(task.mappingFileTrimIndents) @@ -704,8 +694,11 @@ internal class DdAndroidGradlePluginTest { @Test fun `M return default config W resolveExtensionConfiguration() {no variant config}`() { + // Given + whenever(mockVariant.buildTypeName) doReturn fakeBuildTypeName + whenever(mockVariant.flavors) doReturn fakeFlavorNames + // When - mockVariant.mockFlavors(fakeFlavorNames, fakeBuildTypeName) val config = testedPlugin.resolveExtensionConfiguration(fakeExtension, mockVariant) // Then @@ -728,8 +721,10 @@ internal class DdAndroidGradlePluginTest { fun `M return config W resolveExtensionConfiguration() { variant w full config }`( @Forgery variantConfig: DdExtensionConfiguration ) { + // Given val variantName = fakeFlavorNames.variantName() - mockVariant.mockFlavors(fakeFlavorNames, fakeBuildTypeName) + whenever(mockVariant.buildTypeName) doReturn fakeBuildTypeName + whenever(mockVariant.flavors) doReturn fakeFlavorNames whenever(fakeExtension.variants.findByName(variantName)) doReturn variantConfig // When @@ -755,8 +750,10 @@ internal class DdAndroidGradlePluginTest { fun `M return combined config W resolveExtensionConfiguration() { variant w version only }`( @StringForgery versionName: String ) { + // Given val variantName = fakeFlavorNames.variantName() - mockVariant.mockFlavors(fakeFlavorNames, fakeBuildTypeName) + whenever(mockVariant.buildTypeName) doReturn fakeBuildTypeName + whenever(mockVariant.flavors) doReturn fakeFlavorNames val incompleteConfig = DdExtensionConfiguration().apply { this.versionName = versionName } @@ -782,8 +779,10 @@ internal class DdAndroidGradlePluginTest { fun `M return combined config W resolveExtensionConfiguration() { variant w service only }`( @StringForgery serviceName: String ) { + // Given val variantName = fakeFlavorNames.variantName() - mockVariant.mockFlavors(fakeFlavorNames, fakeBuildTypeName) + whenever(mockVariant.buildTypeName) doReturn fakeBuildTypeName + whenever(mockVariant.flavors) doReturn fakeFlavorNames val incompleteConfig = DdExtensionConfiguration().apply { this.serviceName = serviceName } @@ -809,8 +808,10 @@ internal class DdAndroidGradlePluginTest { fun `M return combined config W resolveExtensionConfiguration() { variant w mappingPath }`( @StringForgery(regex = "/([a-z]+)/([a-z]+)/([a-z]+)/mapping.txt") mappingFilePath: String ) { + // Given val variantName = fakeFlavorNames.variantName() - mockVariant.mockFlavors(fakeFlavorNames, fakeBuildTypeName) + whenever(mockVariant.buildTypeName) doReturn fakeBuildTypeName + whenever(mockVariant.flavors) doReturn fakeFlavorNames val incompleteConfig = DdExtensionConfiguration().apply { this.mappingFilePath = mappingFilePath } @@ -841,8 +842,10 @@ internal class DdAndroidGradlePluginTest { value = AdvancedForgery(string = [StringForgery(StringForgeryType.ALPHABETICAL)]) ) mappingFilePackageAliases: Map ) { + // Given val variantName = fakeFlavorNames.variantName() - mockVariant.mockFlavors(fakeFlavorNames, fakeBuildTypeName) + whenever(mockVariant.buildTypeName) doReturn fakeBuildTypeName + whenever(mockVariant.flavors) doReturn fakeFlavorNames val incompleteConfig = DdExtensionConfiguration().apply { this.mappingFilePackageAliases = mappingFilePackageAliases } @@ -869,8 +872,10 @@ internal class DdAndroidGradlePluginTest { fun `M return config W resolveExtensionConfiguration() { variant+mappingFileTrimIndents }`( @BoolForgery mappingFileTrimIndents: Boolean ) { + // Given val variantName = fakeFlavorNames.variantName() - mockVariant.mockFlavors(fakeFlavorNames, fakeBuildTypeName) + whenever(mockVariant.buildTypeName) doReturn fakeBuildTypeName + whenever(mockVariant.flavors) doReturn fakeFlavorNames val incompleteConfig = DdExtensionConfiguration().apply { this.mappingFileTrimIndents = mappingFileTrimIndents } @@ -898,8 +903,10 @@ internal class DdAndroidGradlePluginTest { fun `M return combined config W resolveExtensionConfiguration() { variant w site only }`( @Forgery site: DatadogSite ) { + // Given val variantName = fakeFlavorNames.variantName() - mockVariant.mockFlavors(fakeFlavorNames, fakeBuildTypeName) + whenever(mockVariant.buildTypeName) doReturn fakeBuildTypeName + whenever(mockVariant.flavors) doReturn fakeFlavorNames val incompleteConfig = DdExtensionConfiguration().apply { this.site = site.name } @@ -926,8 +933,10 @@ internal class DdAndroidGradlePluginTest { fun `M return combined config W resolveExtensionConfiguration() { variant w sdkCheck only }`( @Forgery sdkCheckLevel: SdkCheckLevel ) { + // Given val variantName = fakeFlavorNames.variantName() - mockVariant.mockFlavors(fakeFlavorNames, fakeBuildTypeName) + whenever(mockVariant.buildTypeName) doReturn fakeBuildTypeName + whenever(mockVariant.flavors) doReturn fakeFlavorNames val incompleteConfig = DdExtensionConfiguration().apply { this.checkProjectDependencies = sdkCheckLevel } @@ -952,8 +961,10 @@ internal class DdAndroidGradlePluginTest { fun `M return combined config W resolveExtensionConfiguration() { variant w remoteUrl only }`( @Forgery fakeConfig: DdExtensionConfiguration ) { + // Given val variantName = fakeFlavorNames.variantName() - mockVariant.mockFlavors(fakeFlavorNames, fakeBuildTypeName) + whenever(mockVariant.buildTypeName) doReturn fakeBuildTypeName + whenever(mockVariant.flavors) doReturn fakeFlavorNames val incompleteConfig = DdExtensionConfiguration().apply { this.remoteRepositoryUrl = fakeConfig.remoteRepositoryUrl } @@ -980,8 +991,10 @@ internal class DdAndroidGradlePluginTest { fun `M return combined config W resolveExtensionConfiguration() { variant + ignoreDdConfig }`( @Forgery fakeConfig: DdExtensionConfiguration ) { + // Given val variantName = fakeFlavorNames.variantName() - mockVariant.mockFlavors(fakeFlavorNames, fakeBuildTypeName) + whenever(mockVariant.buildTypeName) doReturn fakeBuildTypeName + whenever(mockVariant.flavors) doReturn fakeFlavorNames val incompleteConfig = DdExtensionConfiguration().apply { this.ignoreDatadogCiFileConfig = fakeConfig.ignoreDatadogCiFileConfig } @@ -1014,6 +1027,7 @@ internal class DdAndroidGradlePluginTest { @Forgery variantConfigB: DdExtensionConfiguration, @Forgery variantConfigC: DdExtensionConfiguration ) { + // Given val flavorNames = listOf(flavorA, flavorB, flavorC) variantConfigA.apply { versionName = null @@ -1024,7 +1038,8 @@ internal class DdAndroidGradlePluginTest { checkProjectDependencies = null } variantConfigC.apply { site = null } - mockVariant.mockFlavors(flavorNames, fakeBuildTypeName) + whenever(mockVariant.buildTypeName) doReturn fakeBuildTypeName + whenever(mockVariant.flavors) doReturn flavorNames whenever(fakeExtension.variants.findByName(flavorA)) doReturn variantConfigA whenever(fakeExtension.variants.findByName(flavorB)) doReturn variantConfigB whenever(fakeExtension.variants.findByName(flavorC)) doReturn variantConfigC @@ -1057,12 +1072,14 @@ internal class DdAndroidGradlePluginTest { @Forgery variantConfigAC: DdExtensionConfiguration, @Forgery variantConfigBC: DdExtensionConfiguration ) { + // Given val flavorNames = listOf(flavorA, flavorB, flavorC) variantConfigAB.apply { versionName = null } variantConfigAC.apply { serviceName = null } variantConfigBC.apply { site = null } variantConfigBC.apply { checkProjectDependencies = null } - mockVariant.mockFlavors(flavorNames, fakeBuildTypeName) + whenever(mockVariant.buildTypeName) doReturn fakeBuildTypeName + whenever(mockVariant.flavors) doReturn flavorNames whenever( fakeExtension.variants.findByName( flavorA + flavorB.replaceFirstChar { capitalizeChar(it) } @@ -1105,9 +1122,11 @@ internal class DdAndroidGradlePluginTest { fun `M return combined config W resolveExtensionConfiguration() { variant w build type }`( @Forgery configuration: DdExtensionConfiguration ) { + // Given val variantName = fakeFlavorNames.variantName() + fakeBuildTypeName.replaceFirstChar { capitalizeChar(it) } - mockVariant.mockFlavors(fakeFlavorNames, fakeBuildTypeName) + whenever(mockVariant.buildTypeName) doReturn fakeBuildTypeName + whenever(mockVariant.flavors) doReturn fakeFlavorNames whenever(fakeExtension.variants.findByName(variantName)) doReturn configuration // When @@ -1139,6 +1158,7 @@ internal class DdAndroidGradlePluginTest { @StringForgery(case = Case.LOWER) flavorName: String, @StringForgery(case = Case.LOWER) buildTypeName: String, @StringForgery versionName: String, + @IntForgery(min = 1) versionCode: Int, @StringForgery packageName: String, @StringForgery configurationName: String ) { @@ -1147,10 +1167,10 @@ internal class DdAndroidGradlePluginTest { 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(mockBuildType.name) doReturn fakeBuildTypeName + whenever(mockVariant.versionCode) doReturn versionCode.asProvider() + whenever(mockVariant.versionName) doReturn versionName.asProvider() + whenever(mockVariant.applicationId) doReturn packageName.asProvider() + whenever(mockVariant.buildTypeName) doReturn fakeBuildTypeName fakeProject.task("compile${variantName.replaceFirstChar { capitalizeChar(it) }}Sources") @@ -1159,13 +1179,14 @@ internal class DdAndroidGradlePluginTest { whenever(mockVariant.compileConfiguration) doReturn mockConfiguration - // When + Then + // When val checkSdkDepsTaskProvider = testedPlugin.configureVariantForSdkCheck( fakeProject, mockVariant, fakeExtension ) + // Then assertThat(checkSdkDepsTaskProvider).isNull() } @@ -1174,6 +1195,7 @@ internal class DdAndroidGradlePluginTest { @StringForgery(case = Case.LOWER) flavorName: String, @StringForgery(case = Case.LOWER) buildTypeName: String, @StringForgery versionName: String, + @IntForgery(min = 1) versionCode: Int, @StringForgery packageName: String ) { // Given @@ -1181,10 +1203,10 @@ internal class DdAndroidGradlePluginTest { 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(mockBuildType.name) doReturn fakeBuildTypeName + whenever(mockVariant.versionCode) doReturn versionCode.asProvider() + whenever(mockVariant.versionName) doReturn versionName.asProvider() + whenever(mockVariant.applicationId) doReturn packageName.asProvider() + whenever(mockVariant.buildTypeName) doReturn fakeBuildTypeName fakeProject.task("compile${variantName.replaceFirstChar { capitalizeChar(it) }}Sources") @@ -1241,45 +1263,20 @@ internal class DdAndroidGradlePluginTest { return first() + drop(1).joinToString("") { it.replaceFirstChar { capitalizeChar(it) } } } - private fun ApplicationVariant.mockFlavors( - flavorNames: List, - buildTypeName: String - ) { - val mockFlavors: MutableList = mutableListOf() - for (flavorName in flavorNames) { - mockFlavors.add( - mock().apply { - whenever(this.name) doReturn flavorName - } - ) - } - val mockBuildType: BuildType = mock() - whenever(mockBuildType.name) doReturn buildTypeName - - whenever(productFlavors) doReturn mockFlavors - whenever(buildType) doReturn mockBuildType - } - private fun mockBuildIdGenerationTask(buildId: String): TaskProvider { return mock>().apply { - val mockBuildIdProvider = mock>().apply { - whenever(get()) doReturn buildId - } whenever( flatMap(any, GenerateBuildIdTask>>()) - ) doReturn mockBuildIdProvider + ) doReturn buildId.asProvider() } } - private fun mockAppExtension(): AppExtension { - val mockAppExtension: AppExtension = mock() - val mockSoureSetsContainer: NamedDomainObjectContainer = mock() - val mockSoureSets: AndroidSourceSet = mock() - val mockAssets: AndroidSourceDirectorySet = mock() - whenever(mockAppExtension.sourceSets).thenReturn(mockSoureSetsContainer) - whenever(mockSoureSetsContainer.getByName(any())).thenReturn(mockSoureSets) - whenever(mockSoureSets.assets).thenReturn(mockAssets) - return mockAppExtension + private fun T.asProvider(): Provider { + return fakeProject.provider { this } + } + + private fun String.asFileProvider(): Provider { + return fakeProject.objects.fileProperty().value { File(this) } } // endregion diff --git a/dd-sdk-android-gradle-plugin/src/test/kotlin/com/datadog/gradle/plugin/DdMappingFileUploadTaskTest.kt b/dd-sdk-android-gradle-plugin/src/test/kotlin/com/datadog/gradle/plugin/MappingFileUploadTaskTest.kt similarity index 85% rename from dd-sdk-android-gradle-plugin/src/test/kotlin/com/datadog/gradle/plugin/DdMappingFileUploadTaskTest.kt rename to dd-sdk-android-gradle-plugin/src/test/kotlin/com/datadog/gradle/plugin/MappingFileUploadTaskTest.kt index 8681dd18..08e783ef 100644 --- a/dd-sdk-android-gradle-plugin/src/test/kotlin/com/datadog/gradle/plugin/DdMappingFileUploadTaskTest.kt +++ b/dd-sdk-android-gradle-plugin/src/test/kotlin/com/datadog/gradle/plugin/MappingFileUploadTaskTest.kt @@ -10,6 +10,7 @@ import com.datadog.gradle.plugin.internal.ApiKey import com.datadog.gradle.plugin.internal.ApiKeySource import com.datadog.gradle.plugin.internal.DdAppIdentifier import com.datadog.gradle.plugin.internal.Uploader +import com.datadog.gradle.plugin.utils.forge.Configurator import fr.xgouchet.elmyr.Forge import fr.xgouchet.elmyr.annotation.Forgery import fr.xgouchet.elmyr.annotation.IntForgery @@ -17,7 +18,7 @@ import fr.xgouchet.elmyr.annotation.StringForgery import fr.xgouchet.elmyr.junit5.ForgeConfiguration import fr.xgouchet.elmyr.junit5.ForgeExtension import org.assertj.core.api.Assertions.assertThat -import org.gradle.api.provider.Provider +import org.gradle.api.Project import org.gradle.testfixtures.ProjectBuilder import org.json.JSONArray import org.json.JSONObject @@ -36,7 +37,6 @@ import org.mockito.kotlin.any import org.mockito.kotlin.argumentCaptor import org.mockito.kotlin.doReturn import org.mockito.kotlin.eq -import org.mockito.kotlin.mock import org.mockito.kotlin.verify import org.mockito.kotlin.verifyNoInteractions import org.mockito.kotlin.whenever @@ -50,9 +50,11 @@ import java.util.UUID ) @MockitoSettings(strictness = Strictness.LENIENT) @ForgeConfiguration(Configurator::class) -internal class DdMappingFileUploadTaskTest { +internal class MappingFileUploadTaskTest { - private lateinit var testedTask: DdMappingFileUploadTask + private lateinit var testedTask: MappingFileUploadTask + + private lateinit var fakeProject: Project @TempDir lateinit var tempDir: File @@ -99,13 +101,13 @@ internal class DdMappingFileUploadTaskTest { @BeforeEach fun `set up`(forge: Forge) { - val fakeProject = ProjectBuilder.builder() + fakeProject = ProjectBuilder.builder() .withProjectDir(tempDir) .build() testedTask = fakeProject.tasks.create( "DdMappingFileUploadTask", - DdMappingFileUploadTask::class.java, + MappingFileUploadTask::class.java, mockRepositoryDetector ) @@ -118,22 +120,18 @@ internal class DdMappingFileUploadTaskTest { testedTask.apiKey = fakeApiKey.value testedTask.apiKeySource = fakeApiKey.source testedTask.variantName = fakeVariant - testedTask.versionName = fakeVersion - testedTask.versionCode = mock>().apply { - whenever(get()) doReturn fakeVersionCode - } - testedTask.serviceName = fakeService + testedTask.versionName.set(fakeVersion) + testedTask.versionCode.set(fakeVersionCode) + testedTask.serviceName.set(fakeService) testedTask.site = fakeSite.name - testedTask.buildId = mock>().apply { - whenever(isPresent) doReturn true - whenever(get()) doReturn fakeBuildId - } - setEnv(DdFileUploadTask.DATADOG_SITE, "") + testedTask.buildId.set(fakeBuildId) + testedTask.mappingFile.set(fakeProject.objects.fileProperty().fileValue(File(tempDir, fakeMappingFileName))) + setEnv(FileUploadTask.DATADOG_SITE, "") } @AfterEach fun `tear down`() { - removeEnv(DdFileUploadTask.DATADOG_SITE) + removeEnv(FileUploadTask.DATADOG_SITE) } @Test @@ -141,7 +139,7 @@ internal class DdMappingFileUploadTaskTest { // Given val fakeMappingFile = File(tempDir, fakeMappingFileName) fakeMappingFile.writeText(fakeMappingFileContent) - testedTask.mappingFilePath = fakeMappingFile.path + testedTask.mappingFile.set(fakeProject.objects.fileProperty().fileValue(File(fakeMappingFile.path))) val fakeRepositoryFile = File(tempDir, fakeRepositoryFileName) testedTask.repositoryFile = fakeRepositoryFile whenever(mockRepositoryDetector.detectRepositories(any(), eq(""))) @@ -154,11 +152,11 @@ internal class DdMappingFileUploadTaskTest { verify(mockUploader).upload( fakeSite, Uploader.UploadFileInfo( - fileKey = DdMappingFileUploadTask.KEY_JVM_MAPPING_FILE, + fileKey = MappingFileUploadTask.KEY_JVM_MAPPING_FILE, file = fakeMappingFile, - encoding = DdMappingFileUploadTask.MEDIA_TYPE_TXT, - fileType = DdMappingFileUploadTask.TYPE_JVM_MAPPING_FILE, - fileName = DdMappingFileUploadTask.KEY_JVM_MAPPING_FILE_NAME + encoding = MappingFileUploadTask.MEDIA_TYPE_TXT, + fileType = MappingFileUploadTask.TYPE_JVM_MAPPING_FILE, + fileName = MappingFileUploadTask.KEY_JVM_MAPPING_FILE_NAME ), fakeRepositoryFile, fakeApiKey.value, @@ -180,8 +178,11 @@ internal class DdMappingFileUploadTaskTest { } @Test - fun `M upload file W applyTask() { short aliases requested }`() { + fun `M upload file W applyTask() { short aliases requested }`( + @StringForgery fakeApplicationId: String + ) { // Given + testedTask.applicationId.set(fakeApplicationId) testedTask.mappingFilePackagesAliases = mapOf( "androidx.fragment.app" to "axfraga", "androidx.activity" to "axact", @@ -194,7 +195,7 @@ internal class DdMappingFileUploadTaskTest { val fakeMappingFile = File(tempDir, fakeMappingFileName) fileFromResourcesPath("mapping.txt").copyTo(fakeMappingFile) - testedTask.mappingFilePath = fakeMappingFile.path + testedTask.mappingFile.set(fakeProject.objects.fileProperty().fileValue(File(fakeMappingFile.path))) val fakeRepositoryFile = File(tempDir, fakeRepositoryFileName) testedTask.repositoryFile = fakeRepositoryFile whenever(mockRepositoryDetector.detectRepositories(any(), eq(""))) @@ -246,7 +247,7 @@ internal class DdMappingFileUploadTaskTest { ) testedTask.mappingFileTrimIndents = true - testedTask.mappingFilePath = fakeMappingFile.path + testedTask.mappingFile.set(fakeProject.objects.fileProperty().fileValue(File(fakeMappingFile.path))) val fakeRepositoryFile = File(tempDir, fakeRepositoryFileName) testedTask.repositoryFile = fakeRepositoryFile whenever(mockRepositoryDetector.detectRepositories(any(), eq(""))) @@ -296,14 +297,14 @@ internal class DdMappingFileUploadTaskTest { ) testedTask.mappingFileTrimIndents = true - testedTask.mappingFilePath = fakeMappingFile.path + testedTask.mappingFile.set(fakeProject.objects.fileProperty().fileValue(File(fakeMappingFile.path))) val fakeRepositoryFile = File(tempDir, fakeRepositoryFileName) testedTask.repositoryFile = fakeRepositoryFile whenever(mockRepositoryDetector.detectRepositories(any(), eq(""))) .doReturn(listOf(fakeRepoInfo)) val oldShrinkedMappingFile = File( fakeMappingFile.parent, - DdMappingFileUploadTask.MAPPING_OPTIMIZED_FILE_NAME + MappingFileUploadTask.MAPPING_OPTIMIZED_FILE_NAME ) oldShrinkedMappingFile.createNewFile() oldShrinkedMappingFile.writeText(forge.aString()) @@ -340,7 +341,7 @@ internal class DdMappingFileUploadTaskTest { // Given val fakeMappingFile = File(tempDir, fakeMappingFileName) fakeMappingFile.writeText(fakeMappingFileContent) - testedTask.mappingFilePath = fakeMappingFile.path + testedTask.mappingFile.set(fakeProject.objects.fileProperty().fileValue(File(fakeMappingFile.path))) testedTask.remoteRepositoryUrl = fakeRemoteUrl val fakeRepositoryFile = File(tempDir, fakeRepositoryFileName) testedTask.repositoryFile = fakeRepositoryFile @@ -354,11 +355,11 @@ internal class DdMappingFileUploadTaskTest { verify(mockUploader).upload( fakeSite, Uploader.UploadFileInfo( - fileKey = DdMappingFileUploadTask.KEY_JVM_MAPPING_FILE, + fileKey = MappingFileUploadTask.KEY_JVM_MAPPING_FILE, file = fakeMappingFile, - encoding = DdMappingFileUploadTask.MEDIA_TYPE_TXT, - fileType = DdMappingFileUploadTask.TYPE_JVM_MAPPING_FILE, - fileName = DdMappingFileUploadTask.KEY_JVM_MAPPING_FILE_NAME + encoding = MappingFileUploadTask.MEDIA_TYPE_TXT, + fileType = MappingFileUploadTask.TYPE_JVM_MAPPING_FILE, + fileName = MappingFileUploadTask.KEY_JVM_MAPPING_FILE_NAME ), fakeRepositoryFile, fakeApiKey.value, @@ -384,7 +385,7 @@ internal class DdMappingFileUploadTaskTest { // Given val fakeMappingFile = File(tempDir, fakeMappingFileName) fakeMappingFile.writeText(fakeMappingFileContent) - testedTask.mappingFilePath = fakeMappingFile.path + testedTask.mappingFile.set(fakeProject.objects.fileProperty().fileValue(File(fakeMappingFile.path))) val fakeRepositoryFile = File(tempDir, fakeRepositoryFileName) testedTask.repositoryFile = fakeRepositoryFile whenever(mockRepositoryDetector.detectRepositories(any(), eq(""))) @@ -397,11 +398,11 @@ internal class DdMappingFileUploadTaskTest { verify(mockUploader).upload( fakeSite, Uploader.UploadFileInfo( - fileKey = DdMappingFileUploadTask.KEY_JVM_MAPPING_FILE, + fileKey = MappingFileUploadTask.KEY_JVM_MAPPING_FILE, file = fakeMappingFile, - encoding = DdMappingFileUploadTask.MEDIA_TYPE_TXT, - fileType = DdMappingFileUploadTask.TYPE_JVM_MAPPING_FILE, - fileName = DdMappingFileUploadTask.KEY_JVM_MAPPING_FILE_NAME + encoding = MappingFileUploadTask.MEDIA_TYPE_TXT, + fileType = MappingFileUploadTask.TYPE_JVM_MAPPING_FILE, + fileName = MappingFileUploadTask.KEY_JVM_MAPPING_FILE_NAME ), null, fakeApiKey.value, @@ -423,7 +424,7 @@ internal class DdMappingFileUploadTaskTest { // Given val fakeMappingFile = File(tempDir, fakeMappingFileName) fakeMappingFile.writeText(fakeMappingFileContent) - testedTask.mappingFilePath = fakeMappingFile.path + testedTask.mappingFile.set(fakeProject.objects.fileProperty().fileValue(File(fakeMappingFile.path))) testedTask.apiKey = "" testedTask.apiKeySource = ApiKeySource.NONE @@ -433,7 +434,7 @@ internal class DdMappingFileUploadTaskTest { } // Then - assertThat(exception.message).isEqualTo(DdMappingFileUploadTask.API_KEY_MISSING_ERROR) + assertThat(exception.message).isEqualTo(MappingFileUploadTask.API_KEY_MISSING_ERROR) verifyNoInteractions(mockUploader) } @@ -444,7 +445,7 @@ internal class DdMappingFileUploadTaskTest { // Given val fakeMappingFile = File(tempDir, fakeMappingFileName) fakeMappingFile.writeText(fakeMappingFileContent) - testedTask.mappingFilePath = fakeMappingFile.path + testedTask.mappingFile.set(fakeProject.objects.fileProperty().fileValue(File(fakeMappingFile.path))) testedTask.apiKey = forge.anAlphaNumericalString().let { val splitIndex = forge.anInt(min = 0, max = it.length) + 1 it.substring(0, splitIndex) + @@ -460,7 +461,7 @@ internal class DdMappingFileUploadTaskTest { // Then assertThat(exception.message) - .isEqualTo(DdMappingFileUploadTask.INVALID_API_KEY_FORMAT_ERROR) + .isEqualTo(MappingFileUploadTask.INVALID_API_KEY_FORMAT_ERROR) verifyNoInteractions(mockUploader) } @@ -469,8 +470,8 @@ internal class DdMappingFileUploadTaskTest { // Given val fakeMappingFile = File(tempDir, fakeMappingFileName) fakeMappingFile.writeText(fakeMappingFileContent) - testedTask.mappingFilePath = fakeMappingFile.path - whenever(testedTask.buildId.isPresent) doReturn false + testedTask.mappingFile.set(fakeProject.objects.fileProperty().fileValue(File(fakeMappingFile.path))) + testedTask.buildId.set(null as String?) // When val exception = assertThrows { @@ -478,7 +479,7 @@ internal class DdMappingFileUploadTaskTest { } // Then - assertThat(exception.message).isEqualTo(DdMappingFileUploadTask.MISSING_BUILD_ID_ERROR) + assertThat(exception.message).isEqualTo(MappingFileUploadTask.MISSING_BUILD_ID_ERROR) verifyNoInteractions(mockUploader) } @@ -487,9 +488,8 @@ internal class DdMappingFileUploadTaskTest { // Given val fakeMappingFile = File(tempDir, fakeMappingFileName) fakeMappingFile.writeText(fakeMappingFileContent) - testedTask.mappingFilePath = fakeMappingFile.path - whenever(testedTask.buildId.isPresent) doReturn true - whenever(testedTask.buildId.get()) doReturn "" + testedTask.mappingFile.set(fakeProject.objects.fileProperty().fileValue(File(fakeMappingFile.path))) + testedTask.buildId.set("") // When val exception = assertThrows { @@ -497,7 +497,7 @@ internal class DdMappingFileUploadTaskTest { } // Then - assertThat(exception.message).isEqualTo(DdMappingFileUploadTask.MISSING_BUILD_ID_ERROR) + assertThat(exception.message).isEqualTo(MappingFileUploadTask.MISSING_BUILD_ID_ERROR) verifyNoInteractions(mockUploader) } @@ -510,7 +510,7 @@ internal class DdMappingFileUploadTaskTest { // Given val fakeMappingFile = File(tempDir, fakeMappingFileName) fakeMappingFile.writeText(fakeMappingFileContent) - testedTask.mappingFilePath = fakeMappingFile.path + testedTask.mappingFile.set(fakeProject.objects.fileProperty().fileValue(File(fakeMappingFile.path))) testedTask.site = siteName // When @@ -527,7 +527,7 @@ internal class DdMappingFileUploadTaskTest { // Given val fakeMappingFile = File(tempDir, fakeMappingFileName) fakeMappingFile.writeText(fakeMappingFileContent) - testedTask.mappingFilePath = fakeMappingFile.path + testedTask.mappingFile.set(fakeProject.objects.fileProperty().fileValue(File(fakeMappingFile.path))) val fakeRepositoryFile = File(tempDir, fakeRepositoryFileName) testedTask.repositoryFile = fakeRepositoryFile testedTask.site = "" @@ -541,11 +541,11 @@ internal class DdMappingFileUploadTaskTest { verify(mockUploader).upload( DatadogSite.US1, Uploader.UploadFileInfo( - fileKey = DdMappingFileUploadTask.KEY_JVM_MAPPING_FILE, + fileKey = MappingFileUploadTask.KEY_JVM_MAPPING_FILE, file = fakeMappingFile, - encoding = DdMappingFileUploadTask.MEDIA_TYPE_TXT, - fileType = DdMappingFileUploadTask.TYPE_JVM_MAPPING_FILE, - fileName = DdMappingFileUploadTask.KEY_JVM_MAPPING_FILE_NAME + encoding = MappingFileUploadTask.MEDIA_TYPE_TXT, + fileType = MappingFileUploadTask.TYPE_JVM_MAPPING_FILE, + fileName = MappingFileUploadTask.KEY_JVM_MAPPING_FILE_NAME ), fakeRepositoryFile, fakeApiKey.value, @@ -570,7 +570,7 @@ internal class DdMappingFileUploadTaskTest { fun `M do nothing W applyTask() {no mapping file}`() { // Given val fakeMappingFile = File(tempDir, fakeMappingFileName) - testedTask.mappingFilePath = fakeMappingFile.path + testedTask.mappingFile.set(fakeProject.objects.fileProperty().fileValue(File(fakeMappingFile.path))) // When testedTask.applyTask() @@ -584,7 +584,7 @@ internal class DdMappingFileUploadTaskTest { // Given val fakeMappingFile = File(tempDir, fakeMappingFileName) fakeMappingFile.mkdirs() - testedTask.mappingFilePath = fakeMappingFile.path + testedTask.mappingFile.set(fakeProject.objects.fileProperty().fileValue(File(fakeMappingFile.path))) // When assertThrows { @@ -759,7 +759,7 @@ internal class DdMappingFileUploadTaskTest { fun `M read site from environment variable W applyTask() {site is not set}`(forge: Forge) { // Given val fakeDatadogEnvDomain = forge.aValueFrom(DatadogSite::class.java).domain - setEnv(DdFileUploadTask.DATADOG_SITE, fakeDatadogEnvDomain) + setEnv(FileUploadTask.DATADOG_SITE, fakeDatadogEnvDomain) testedTask.site = "" // When diff --git a/dd-sdk-android-gradle-plugin/src/test/kotlin/com/datadog/gradle/plugin/DdNdkSymbolFileUploadTaskTest.kt b/dd-sdk-android-gradle-plugin/src/test/kotlin/com/datadog/gradle/plugin/NdkSymbolFileUploadTaskTest.kt similarity index 89% rename from dd-sdk-android-gradle-plugin/src/test/kotlin/com/datadog/gradle/plugin/DdNdkSymbolFileUploadTaskTest.kt rename to dd-sdk-android-gradle-plugin/src/test/kotlin/com/datadog/gradle/plugin/NdkSymbolFileUploadTaskTest.kt index fe5abbc2..f444184a 100644 --- a/dd-sdk-android-gradle-plugin/src/test/kotlin/com/datadog/gradle/plugin/DdNdkSymbolFileUploadTaskTest.kt +++ b/dd-sdk-android-gradle-plugin/src/test/kotlin/com/datadog/gradle/plugin/NdkSymbolFileUploadTaskTest.kt @@ -1,10 +1,11 @@ package com.datadog.gradle.plugin -import com.android.build.gradle.api.ApplicationVariant import com.datadog.gradle.plugin.internal.ApiKey import com.datadog.gradle.plugin.internal.ApiKeySource import com.datadog.gradle.plugin.internal.DdAppIdentifier import com.datadog.gradle.plugin.internal.Uploader +import com.datadog.gradle.plugin.internal.variant.AppVariant +import com.datadog.gradle.plugin.utils.forge.Configurator import fr.xgouchet.elmyr.Forge import fr.xgouchet.elmyr.annotation.Forgery import fr.xgouchet.elmyr.annotation.IntForgery @@ -13,7 +14,6 @@ import fr.xgouchet.elmyr.junit5.ForgeConfiguration import fr.xgouchet.elmyr.junit5.ForgeExtension import org.assertj.core.api.Assertions import org.assertj.core.api.Assertions.assertThat -import org.gradle.api.provider.Provider import org.gradle.internal.impldep.org.junit.Assume.assumeTrue import org.gradle.testfixtures.ProjectBuilder import org.json.JSONArray @@ -31,7 +31,6 @@ import org.mockito.junit.jupiter.MockitoSettings import org.mockito.kotlin.any import org.mockito.kotlin.doReturn import org.mockito.kotlin.eq -import org.mockito.kotlin.mock import org.mockito.kotlin.verify import org.mockito.kotlin.verifyNoInteractions import org.mockito.kotlin.whenever @@ -45,8 +44,9 @@ import java.util.UUID ) @MockitoSettings(strictness = Strictness.LENIENT) @ForgeConfiguration(Configurator::class) -internal class DdNdkSymbolFileUploadTaskTest { - private lateinit var testedTask: DdNdkSymbolFileUploadTask +internal class NdkSymbolFileUploadTaskTest { + + private lateinit var testedTask: NdkSymbolFileUploadTask @TempDir lateinit var tempDir: File @@ -55,7 +55,7 @@ internal class DdNdkSymbolFileUploadTaskTest { lateinit var mockUploader: Uploader @Mock - lateinit var mockVariant: ApplicationVariant + lateinit var mockVariant: AppVariant @Mock lateinit var mockRepositoryDetector: RepositoryDetector @@ -91,12 +91,12 @@ internal class DdNdkSymbolFileUploadTaskTest { .withProjectDir(tempDir) .build() whenever(mockVariant.flavorName).thenReturn(fakeVariantName) - whenever(mockVariant.versionName).thenReturn(fakeVersion) - whenever(mockVariant.versionCode).thenReturn(fakeVersionCode) + whenever(mockVariant.versionName).thenReturn(fakeProject.provider { fakeVersion }) + whenever(mockVariant.versionCode).thenReturn(fakeProject.provider { fakeVersionCode }) testedTask = fakeProject.tasks.create( "DdSymbolFileUploadTask", - DdNdkSymbolFileUploadTask::class.java, + NdkSymbolFileUploadTask::class.java, mockRepositoryDetector ) testedTask.uploader = mockUploader @@ -107,10 +107,7 @@ internal class DdNdkSymbolFileUploadTaskTest { fakeBuildId = forge.getForgery().toString() testedTask.searchDirectories.from(tempDir) - testedTask.buildId = mock>().apply { - whenever(isPresent) doReturn true - whenever(get()) doReturn fakeBuildId - } + testedTask.buildId.set(fakeBuildId) val fakeConfiguration = with(DdExtensionConfiguration()) { versionName = fakeVersion @@ -123,12 +120,12 @@ internal class DdNdkSymbolFileUploadTaskTest { fakeConfiguration, mockVariant ) - setEnv(DdFileUploadTask.DATADOG_SITE, "") + setEnv(FileUploadTask.DATADOG_SITE, "") } @AfterEach fun `tear down`() { - removeEnv(DdFileUploadTask.DATADOG_SITE) + removeEnv(FileUploadTask.DATADOG_SITE) } @Test @@ -147,10 +144,10 @@ internal class DdNdkSymbolFileUploadTaskTest { verify(mockUploader).upload( fakeSite, Uploader.UploadFileInfo( - fileKey = DdNdkSymbolFileUploadTask.KEY_NDK_SYMBOL_FILE, + fileKey = NdkSymbolFileUploadTask.KEY_NDK_SYMBOL_FILE, file = fakeSoFile, - encoding = DdNdkSymbolFileUploadTask.ENCODING, - fileType = DdNdkSymbolFileUploadTask.TYPE_NDK_SYMBOL_FILE, + encoding = NdkSymbolFileUploadTask.ENCODING, + fileType = NdkSymbolFileUploadTask.TYPE_NDK_SYMBOL_FILE, fileName = "libfake.so", extraAttributes = mapOf( "arch" to "arm64" @@ -191,10 +188,10 @@ internal class DdNdkSymbolFileUploadTaskTest { verify(mockUploader).upload( fakeSite, Uploader.UploadFileInfo( - fileKey = DdNdkSymbolFileUploadTask.KEY_NDK_SYMBOL_FILE, + fileKey = NdkSymbolFileUploadTask.KEY_NDK_SYMBOL_FILE, file = it.value, - encoding = DdNdkSymbolFileUploadTask.ENCODING, - fileType = DdNdkSymbolFileUploadTask.TYPE_NDK_SYMBOL_FILE, + encoding = NdkSymbolFileUploadTask.ENCODING, + fileType = NdkSymbolFileUploadTask.TYPE_NDK_SYMBOL_FILE, fileName = "libfake.so", extraAttributes = mapOf( "arch" to it.key @@ -236,10 +233,10 @@ internal class DdNdkSymbolFileUploadTaskTest { verify(mockUploader).upload( fakeSite, Uploader.UploadFileInfo( - fileKey = DdNdkSymbolFileUploadTask.KEY_NDK_SYMBOL_FILE, + fileKey = NdkSymbolFileUploadTask.KEY_NDK_SYMBOL_FILE, file = fakeSoFile, - encoding = DdNdkSymbolFileUploadTask.ENCODING, - fileType = DdNdkSymbolFileUploadTask.TYPE_NDK_SYMBOL_FILE, + encoding = NdkSymbolFileUploadTask.ENCODING, + fileType = NdkSymbolFileUploadTask.TYPE_NDK_SYMBOL_FILE, fileName = "libfake.so", extraAttributes = mapOf( "arch" to "arm64" @@ -280,10 +277,10 @@ internal class DdNdkSymbolFileUploadTaskTest { verify(mockUploader).upload( fakeSite, Uploader.UploadFileInfo( - fileKey = DdNdkSymbolFileUploadTask.KEY_NDK_SYMBOL_FILE, + fileKey = NdkSymbolFileUploadTask.KEY_NDK_SYMBOL_FILE, file = fakeSoFile, - encoding = DdNdkSymbolFileUploadTask.ENCODING, - fileType = DdNdkSymbolFileUploadTask.TYPE_NDK_SYMBOL_FILE, + encoding = NdkSymbolFileUploadTask.ENCODING, + fileType = NdkSymbolFileUploadTask.TYPE_NDK_SYMBOL_FILE, fileName = "libfake.so", extraAttributes = mapOf( "arch" to "arm64" @@ -317,7 +314,7 @@ internal class DdNdkSymbolFileUploadTaskTest { } // Then - assertThat(error.message).isEqualTo(DdFileUploadTask.API_KEY_MISSING_ERROR) + assertThat(error.message).isEqualTo(FileUploadTask.API_KEY_MISSING_ERROR) verifyNoInteractions(mockUploader) } @@ -341,14 +338,14 @@ internal class DdNdkSymbolFileUploadTaskTest { // Then assertThat(exception.message) - .isEqualTo(DdFileUploadTask.INVALID_API_KEY_FORMAT_ERROR) + .isEqualTo(FileUploadTask.INVALID_API_KEY_FORMAT_ERROR) verifyNoInteractions(mockUploader) } @Test fun `M throw error W applyTask() {buildId is missing}`() { // Given - whenever(testedTask.buildId.isPresent) doReturn false + testedTask.buildId.set(null as String?) writeFakeSoFile("arm64-v8a") // When @@ -357,15 +354,14 @@ internal class DdNdkSymbolFileUploadTaskTest { } // Then - assertThat(exception.message).isEqualTo(DdFileUploadTask.MISSING_BUILD_ID_ERROR) + assertThat(exception.message).isEqualTo(FileUploadTask.MISSING_BUILD_ID_ERROR) verifyNoInteractions(mockUploader) } @Test fun `M throw error W applyTask() {buildId is empty string}`() { // Given - whenever(testedTask.buildId.isPresent) doReturn true - whenever(testedTask.buildId.get()) doReturn "" + testedTask.buildId.set("") writeFakeSoFile("arm64-v8a") // When @@ -374,7 +370,7 @@ internal class DdNdkSymbolFileUploadTaskTest { } // Then - assertThat(exception.message).isEqualTo(DdFileUploadTask.MISSING_BUILD_ID_ERROR) + assertThat(exception.message).isEqualTo(FileUploadTask.MISSING_BUILD_ID_ERROR) verifyNoInteractions(mockUploader) } @@ -413,10 +409,10 @@ internal class DdNdkSymbolFileUploadTaskTest { verify(mockUploader).upload( DatadogSite.US1, Uploader.UploadFileInfo( - fileKey = DdNdkSymbolFileUploadTask.KEY_NDK_SYMBOL_FILE, + fileKey = NdkSymbolFileUploadTask.KEY_NDK_SYMBOL_FILE, file = fakeSoFile, - encoding = DdNdkSymbolFileUploadTask.ENCODING, - fileType = DdNdkSymbolFileUploadTask.TYPE_NDK_SYMBOL_FILE, + encoding = NdkSymbolFileUploadTask.ENCODING, + fileType = NdkSymbolFileUploadTask.TYPE_NDK_SYMBOL_FILE, fileName = "libfake.so", extraAttributes = mapOf( "arch" to "arm64" @@ -612,7 +608,7 @@ internal class DdNdkSymbolFileUploadTaskTest { fun `M read site from environment variable W applyTask() {site is not set}`(forge: Forge) { // Given val fakeDatadogEnvDomain = forge.aValueFrom(DatadogSite::class.java).domain - setEnv(DdFileUploadTask.DATADOG_SITE, fakeDatadogEnvDomain) + setEnv(FileUploadTask.DATADOG_SITE, fakeDatadogEnvDomain) testedTask.site = "" // When diff --git a/dd-sdk-android-gradle-plugin/src/test/kotlin/com/datadog/gradle/plugin/RepositoryInfoTest.kt b/dd-sdk-android-gradle-plugin/src/test/kotlin/com/datadog/gradle/plugin/RepositoryInfoTest.kt index 9a399a33..fb3615b1 100644 --- a/dd-sdk-android-gradle-plugin/src/test/kotlin/com/datadog/gradle/plugin/RepositoryInfoTest.kt +++ b/dd-sdk-android-gradle-plugin/src/test/kotlin/com/datadog/gradle/plugin/RepositoryInfoTest.kt @@ -6,6 +6,7 @@ package com.datadog.gradle.plugin +import com.datadog.gradle.plugin.utils.forge.Configurator import fr.xgouchet.elmyr.annotation.Forgery import fr.xgouchet.elmyr.junit5.ForgeConfiguration import fr.xgouchet.elmyr.junit5.ForgeExtension diff --git a/dd-sdk-android-gradle-plugin/src/test/kotlin/com/datadog/gradle/plugin/DdTaskUtilsTest.kt b/dd-sdk-android-gradle-plugin/src/test/kotlin/com/datadog/gradle/plugin/TaskUtilsTest.kt similarity index 88% rename from dd-sdk-android-gradle-plugin/src/test/kotlin/com/datadog/gradle/plugin/DdTaskUtilsTest.kt rename to dd-sdk-android-gradle-plugin/src/test/kotlin/com/datadog/gradle/plugin/TaskUtilsTest.kt index eb4a8ec3..cd2e5916 100644 --- a/dd-sdk-android-gradle-plugin/src/test/kotlin/com/datadog/gradle/plugin/DdTaskUtilsTest.kt +++ b/dd-sdk-android-gradle-plugin/src/test/kotlin/com/datadog/gradle/plugin/TaskUtilsTest.kt @@ -1,5 +1,6 @@ package com.datadog.gradle.plugin +import com.datadog.gradle.plugin.utils.forge.Configurator import fr.xgouchet.elmyr.Forge import fr.xgouchet.elmyr.junit5.ForgeConfiguration import fr.xgouchet.elmyr.junit5.ForgeExtension @@ -14,7 +15,8 @@ import java.io.File ExtendWith(ForgeExtension::class) ) @ForgeConfiguration(Configurator::class) -class DdTaskUtilsTest { +class TaskUtilsTest { + @Test fun `M find datadog-ci file W findDatadogCiFile()`( @TempDir rootDir: File, @@ -26,7 +28,7 @@ class DdTaskUtilsTest { File(tree[forge.anInt(0, tree.size)], "datadog-ci.json").createNewFile() // When - val ciFile = DdTaskUtils.findDatadogCiFile(tree.last()) + val ciFile = TaskUtils.findDatadogCiFile(tree.last()) // Then Assertions.assertThat(ciFile).isNotNull() @@ -41,7 +43,7 @@ class DdTaskUtilsTest { val tree = buildDirectoryTree(rootDir, maxDepth = 3, forge = forge) // When - val ciFile = DdTaskUtils.findDatadogCiFile(tree.last()) + val ciFile = TaskUtils.findDatadogCiFile(tree.last()) // Then Assertions.assertThat(ciFile).isNull() @@ -56,7 +58,7 @@ class DdTaskUtilsTest { val tree = buildDirectoryTree(rootDir, minDepth = 4, maxDepth = 7, forge = forge) // When - val ciFile = DdTaskUtils.findDatadogCiFile(tree.last()) + val ciFile = TaskUtils.findDatadogCiFile(tree.last()) // Then Assertions.assertThat(ciFile).isNull() diff --git a/dd-sdk-android-gradle-plugin/src/test/kotlin/com/datadog/gradle/plugin/internal/GitRepositoryDetectorTest.kt b/dd-sdk-android-gradle-plugin/src/test/kotlin/com/datadog/gradle/plugin/internal/GitRepositoryDetectorTest.kt index 1ee7fd2a..af8cc7fa 100644 --- a/dd-sdk-android-gradle-plugin/src/test/kotlin/com/datadog/gradle/plugin/internal/GitRepositoryDetectorTest.kt +++ b/dd-sdk-android-gradle-plugin/src/test/kotlin/com/datadog/gradle/plugin/internal/GitRepositoryDetectorTest.kt @@ -6,9 +6,9 @@ package com.datadog.gradle.plugin.internal -import com.datadog.gradle.plugin.Configurator import com.datadog.gradle.plugin.RepositoryDetector import com.datadog.gradle.plugin.internal.sanitizer.UrlSanitizer +import com.datadog.gradle.plugin.utils.forge.Configurator import com.datadog.gradle.plugin.utils.initializeGit import fr.xgouchet.elmyr.Forge import fr.xgouchet.elmyr.annotation.StringForgery diff --git a/dd-sdk-android-gradle-plugin/src/test/kotlin/com/datadog/gradle/plugin/internal/OkHttpUploaderTest.kt b/dd-sdk-android-gradle-plugin/src/test/kotlin/com/datadog/gradle/plugin/internal/OkHttpUploaderTest.kt index aac7b2e8..ae0c0ead 100644 --- a/dd-sdk-android-gradle-plugin/src/test/kotlin/com/datadog/gradle/plugin/internal/OkHttpUploaderTest.kt +++ b/dd-sdk-android-gradle-plugin/src/test/kotlin/com/datadog/gradle/plugin/internal/OkHttpUploaderTest.kt @@ -6,10 +6,10 @@ package com.datadog.gradle.plugin.internal -import com.datadog.gradle.plugin.Configurator import com.datadog.gradle.plugin.DatadogSite -import com.datadog.gradle.plugin.RecordedRequestAssert.Companion.assertThat import com.datadog.gradle.plugin.RepositoryInfo +import com.datadog.gradle.plugin.utils.assertj.RecordedRequestAssert.Companion.assertThat +import com.datadog.gradle.plugin.utils.forge.Configurator import fr.xgouchet.elmyr.Forge import fr.xgouchet.elmyr.annotation.Forgery import fr.xgouchet.elmyr.annotation.IntForgery diff --git a/dd-sdk-android-gradle-plugin/src/test/kotlin/com/datadog/gradle/plugin/internal/VariantIteratorTest.kt b/dd-sdk-android-gradle-plugin/src/test/kotlin/com/datadog/gradle/plugin/internal/VariantIteratorTest.kt index 5ab81e98..47068db9 100644 --- a/dd-sdk-android-gradle-plugin/src/test/kotlin/com/datadog/gradle/plugin/internal/VariantIteratorTest.kt +++ b/dd-sdk-android-gradle-plugin/src/test/kotlin/com/datadog/gradle/plugin/internal/VariantIteratorTest.kt @@ -6,8 +6,8 @@ package com.datadog.gradle.plugin.internal -import com.datadog.gradle.plugin.Configurator import com.datadog.gradle.plugin.utils.capitalizeChar +import com.datadog.gradle.plugin.utils.forge.Configurator import fr.xgouchet.elmyr.Case import fr.xgouchet.elmyr.annotation.StringForgery import fr.xgouchet.elmyr.junit5.ForgeConfiguration diff --git a/dd-sdk-android-gradle-plugin/src/test/kotlin/com/datadog/gradle/plugin/internal/sanitizer/GitRemoteUrlSanitizerTest.kt b/dd-sdk-android-gradle-plugin/src/test/kotlin/com/datadog/gradle/plugin/internal/sanitizer/GitRemoteUrlSanitizerTest.kt index 35962daf..d1d348d2 100644 --- a/dd-sdk-android-gradle-plugin/src/test/kotlin/com/datadog/gradle/plugin/internal/sanitizer/GitRemoteUrlSanitizerTest.kt +++ b/dd-sdk-android-gradle-plugin/src/test/kotlin/com/datadog/gradle/plugin/internal/sanitizer/GitRemoteUrlSanitizerTest.kt @@ -6,7 +6,7 @@ package com.datadog.gradle.plugin.internal.sanitizer -import com.datadog.gradle.plugin.Configurator +import com.datadog.gradle.plugin.utils.forge.Configurator import fr.xgouchet.elmyr.annotation.IntForgery import fr.xgouchet.elmyr.annotation.StringForgery import fr.xgouchet.elmyr.junit5.ForgeConfiguration diff --git a/dd-sdk-android-gradle-plugin/src/test/kotlin/com/datadog/gradle/plugin/utils/assertj/BuildResultAssert.kt b/dd-sdk-android-gradle-plugin/src/test/kotlin/com/datadog/gradle/plugin/utils/assertj/BuildResultAssert.kt index fe77d072..7065ba60 100644 --- a/dd-sdk-android-gradle-plugin/src/test/kotlin/com/datadog/gradle/plugin/utils/assertj/BuildResultAssert.kt +++ b/dd-sdk-android-gradle-plugin/src/test/kotlin/com/datadog/gradle/plugin/utils/assertj/BuildResultAssert.kt @@ -1,7 +1,7 @@ package com.datadog.gradle.plugin.utils.assertj import com.datadog.gradle.plugin.DdAndroidGradlePlugin -import com.datadog.gradle.plugin.DdNdkSymbolFileUploadTask +import com.datadog.gradle.plugin.NdkSymbolFileUploadTask import org.assertj.core.api.AbstractAssert import org.assertj.core.api.Assertions.assertThat import org.gradle.testkit.runner.BuildResult @@ -39,14 +39,14 @@ internal class BuildResultAssert(actual: BuildResult) : it.path.contains(DdAndroidGradlePlugin.UPLOAD_TASK_NAME) } assertThat(actual.tasks).noneMatch { - it.path.contains(DdNdkSymbolFileUploadTask.TASK_NAME) + it.path.contains(NdkSymbolFileUploadTask.TASK_NAME) } return this } fun hasNoNdkSymbolUploadTasks(): BuildResultAssert { assertThat(actual.tasks).noneMatch { - it.path.contains(DdNdkSymbolFileUploadTask.TASK_NAME) + it.path.contains(NdkSymbolFileUploadTask.TASK_NAME) } return this } diff --git a/dd-sdk-android-gradle-plugin/src/test/kotlin/com/datadog/gradle/plugin/RecordedRequestAssert.kt b/dd-sdk-android-gradle-plugin/src/test/kotlin/com/datadog/gradle/plugin/utils/assertj/RecordedRequestAssert.kt similarity index 98% rename from dd-sdk-android-gradle-plugin/src/test/kotlin/com/datadog/gradle/plugin/RecordedRequestAssert.kt rename to dd-sdk-android-gradle-plugin/src/test/kotlin/com/datadog/gradle/plugin/utils/assertj/RecordedRequestAssert.kt index be23dcbe..ed18dd66 100644 --- a/dd-sdk-android-gradle-plugin/src/test/kotlin/com/datadog/gradle/plugin/RecordedRequestAssert.kt +++ b/dd-sdk-android-gradle-plugin/src/test/kotlin/com/datadog/gradle/plugin/utils/assertj/RecordedRequestAssert.kt @@ -4,7 +4,7 @@ * Copyright 2020-Present Datadog, Inc. */ -package com.datadog.gradle.plugin +package com.datadog.gradle.plugin.utils.assertj import okhttp3.mockwebserver.RecordedRequest import okio.GzipSource diff --git a/dd-sdk-android-gradle-plugin/src/test/kotlin/com/datadog/gradle/plugin/Configurator.kt b/dd-sdk-android-gradle-plugin/src/test/kotlin/com/datadog/gradle/plugin/utils/forge/Configurator.kt similarity index 94% rename from dd-sdk-android-gradle-plugin/src/test/kotlin/com/datadog/gradle/plugin/Configurator.kt rename to dd-sdk-android-gradle-plugin/src/test/kotlin/com/datadog/gradle/plugin/utils/forge/Configurator.kt index 2e7549f5..8420c91b 100644 --- a/dd-sdk-android-gradle-plugin/src/test/kotlin/com/datadog/gradle/plugin/Configurator.kt +++ b/dd-sdk-android-gradle-plugin/src/test/kotlin/com/datadog/gradle/plugin/utils/forge/Configurator.kt @@ -4,7 +4,7 @@ * Copyright 2020-Present Datadog, Inc. */ -package com.datadog.gradle.plugin +package com.datadog.gradle.plugin.utils.forge import fr.xgouchet.elmyr.Forge import fr.xgouchet.elmyr.ForgeConfigurator diff --git a/dd-sdk-android-gradle-plugin/src/test/kotlin/com/datadog/gradle/plugin/DdExtensionConfigurationForgeryFactory.kt b/dd-sdk-android-gradle-plugin/src/test/kotlin/com/datadog/gradle/plugin/utils/forge/DdExtensionConfigurationForgeryFactory.kt similarity index 88% rename from dd-sdk-android-gradle-plugin/src/test/kotlin/com/datadog/gradle/plugin/DdExtensionConfigurationForgeryFactory.kt rename to dd-sdk-android-gradle-plugin/src/test/kotlin/com/datadog/gradle/plugin/utils/forge/DdExtensionConfigurationForgeryFactory.kt index 804d18cf..f6057182 100644 --- a/dd-sdk-android-gradle-plugin/src/test/kotlin/com/datadog/gradle/plugin/DdExtensionConfigurationForgeryFactory.kt +++ b/dd-sdk-android-gradle-plugin/src/test/kotlin/com/datadog/gradle/plugin/utils/forge/DdExtensionConfigurationForgeryFactory.kt @@ -4,8 +4,11 @@ * Copyright 2020-Present Datadog, Inc. */ -package com.datadog.gradle.plugin +package com.datadog.gradle.plugin.utils.forge +import com.datadog.gradle.plugin.DatadogSite +import com.datadog.gradle.plugin.DdExtensionConfiguration +import com.datadog.gradle.plugin.SdkCheckLevel import fr.xgouchet.elmyr.Forge import fr.xgouchet.elmyr.ForgeryFactory diff --git a/dd-sdk-android-gradle-plugin/src/test/kotlin/com/datadog/gradle/plugin/DdExtensionForgeryFactory.kt b/dd-sdk-android-gradle-plugin/src/test/kotlin/com/datadog/gradle/plugin/utils/forge/DdExtensionForgeryFactory.kt similarity index 90% rename from dd-sdk-android-gradle-plugin/src/test/kotlin/com/datadog/gradle/plugin/DdExtensionForgeryFactory.kt rename to dd-sdk-android-gradle-plugin/src/test/kotlin/com/datadog/gradle/plugin/utils/forge/DdExtensionForgeryFactory.kt index ff54cfb0..b4e9b318 100644 --- a/dd-sdk-android-gradle-plugin/src/test/kotlin/com/datadog/gradle/plugin/DdExtensionForgeryFactory.kt +++ b/dd-sdk-android-gradle-plugin/src/test/kotlin/com/datadog/gradle/plugin/utils/forge/DdExtensionForgeryFactory.kt @@ -4,8 +4,11 @@ * Copyright 2020-Present Datadog, Inc. */ -package com.datadog.gradle.plugin +package com.datadog.gradle.plugin.utils.forge +import com.datadog.gradle.plugin.DatadogSite +import com.datadog.gradle.plugin.DdExtension +import com.datadog.gradle.plugin.SdkCheckLevel import fr.xgouchet.elmyr.Forge import fr.xgouchet.elmyr.ForgeryFactory import org.gradle.api.model.ObjectFactory diff --git a/dd-sdk-android-gradle-plugin/src/test/kotlin/com/datadog/gradle/plugin/IdentifierForgeryFactory.kt b/dd-sdk-android-gradle-plugin/src/test/kotlin/com/datadog/gradle/plugin/utils/forge/IdentifierForgeryFactory.kt similarity index 95% rename from dd-sdk-android-gradle-plugin/src/test/kotlin/com/datadog/gradle/plugin/IdentifierForgeryFactory.kt rename to dd-sdk-android-gradle-plugin/src/test/kotlin/com/datadog/gradle/plugin/utils/forge/IdentifierForgeryFactory.kt index 2cd388cb..2b185caf 100644 --- a/dd-sdk-android-gradle-plugin/src/test/kotlin/com/datadog/gradle/plugin/IdentifierForgeryFactory.kt +++ b/dd-sdk-android-gradle-plugin/src/test/kotlin/com/datadog/gradle/plugin/utils/forge/IdentifierForgeryFactory.kt @@ -4,7 +4,7 @@ * Copyright 2020-Present Datadog, Inc. */ -package com.datadog.gradle.plugin +package com.datadog.gradle.plugin.utils.forge import com.datadog.gradle.plugin.internal.DdAppIdentifier import fr.xgouchet.elmyr.Forge diff --git a/dd-sdk-android-gradle-plugin/src/test/kotlin/com/datadog/gradle/plugin/RepositoryInfoForgeryFactory.kt b/dd-sdk-android-gradle-plugin/src/test/kotlin/com/datadog/gradle/plugin/utils/forge/RepositoryInfoForgeryFactory.kt similarity index 89% rename from dd-sdk-android-gradle-plugin/src/test/kotlin/com/datadog/gradle/plugin/RepositoryInfoForgeryFactory.kt rename to dd-sdk-android-gradle-plugin/src/test/kotlin/com/datadog/gradle/plugin/utils/forge/RepositoryInfoForgeryFactory.kt index 26f445f9..c90710ba 100644 --- a/dd-sdk-android-gradle-plugin/src/test/kotlin/com/datadog/gradle/plugin/RepositoryInfoForgeryFactory.kt +++ b/dd-sdk-android-gradle-plugin/src/test/kotlin/com/datadog/gradle/plugin/utils/forge/RepositoryInfoForgeryFactory.kt @@ -4,8 +4,9 @@ * Copyright 2020-Present Datadog, Inc. */ -package com.datadog.gradle.plugin +package com.datadog.gradle.plugin.utils.forge +import com.datadog.gradle.plugin.RepositoryInfo import fr.xgouchet.elmyr.Case import fr.xgouchet.elmyr.Forge import fr.xgouchet.elmyr.ForgeryFactory diff --git a/samples/basic/src/main/AndroidManifest.xml b/samples/basic/src/main/AndroidManifest.xml index 61ce2fbc..76549b15 100644 --- a/samples/basic/src/main/AndroidManifest.xml +++ b/samples/basic/src/main/AndroidManifest.xml @@ -5,8 +5,7 @@ ~ Copyright 2020-Present Datadog, Inc. --> - + - + - +