1 /* 2 * Copyright 2022 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package androidx.baselineprofile.gradle.producer 18 19 import androidx.baselineprofile.gradle.utils.BaselineProfileProjectSetupRule 20 import androidx.baselineprofile.gradle.utils.TestAgpVersion 21 import androidx.baselineprofile.gradle.utils.TestAgpVersion.TEST_AGP_VERSION_8_1_1 22 import androidx.baselineprofile.gradle.utils.TestAgpVersion.TEST_AGP_VERSION_8_2_0 23 import androidx.baselineprofile.gradle.utils.TestAgpVersion.TEST_AGP_VERSION_8_3_1 24 import androidx.baselineprofile.gradle.utils.TestAgpVersion.TEST_AGP_VERSION_8_4_2 25 import androidx.baselineprofile.gradle.utils.VariantProfile 26 import androidx.baselineprofile.gradle.utils.build 27 import androidx.baselineprofile.gradle.utils.buildAndAssertThatOutput 28 import androidx.baselineprofile.gradle.utils.buildAndFailAndAssertThatOutput 29 import androidx.baselineprofile.gradle.utils.require 30 import com.google.common.truth.StringSubject 31 import com.google.common.truth.Truth.assertThat 32 import org.junit.Rule 33 import org.junit.Test 34 import org.junit.runner.RunWith 35 import org.junit.runners.Parameterized 36 37 private val GRADLE_PRINT_ARGS_TASK = 38 """ 39 abstract class PrintArgsTask extends DefaultTask { 40 @Input abstract MapProperty<String, String> getProperties() 41 @TaskAction void exec() { 42 for (Map.Entry<String, String> e : getProperties().get().entrySet()) { 43 println(e.key + "=" + e.value) 44 } 45 } 46 } 47 androidComponents { 48 onVariants(selector()) { variant -> 49 tasks.register(variant.name + "Arguments", PrintArgsTask) { t -> 50 t.properties.set(variant.instrumentationRunnerArguments) 51 } 52 } 53 } 54 """ 55 .trimIndent() 56 57 @RunWith(Parameterized::class) 58 class BaselineProfileProducerPluginTest(agpVersion: TestAgpVersion) { 59 60 companion object { 61 @Parameterized.Parameters(name = "agpVersion={0}") 62 @JvmStatic parametersnull63 fun parameters() = TestAgpVersion.values() 64 } 65 66 @get:Rule 67 val projectSetup = BaselineProfileProjectSetupRule(forceAgpVersion = agpVersion.versionString) 68 69 private val emptyReleaseVariantProfile = 70 VariantProfile(flavor = null, buildType = "release", profileFileLines = mapOf()) 71 72 @Test 73 fun verifyTasksWithAndroidTestPlugin() { 74 projectSetup.appTarget.setup() 75 projectSetup.producer.setup( 76 variantProfiles = listOf(emptyReleaseVariantProfile), 77 targetProject = projectSetup.appTarget 78 ) 79 80 projectSetup.producer.gradleRunner.build("tasks") { 81 val notFound = 82 it.lines() 83 .require( 84 "connectedNonMinifiedReleaseAndroidTest - ", 85 "collectNonMinifiedReleaseBaselineProfile - " 86 ) 87 assertThat(notFound).isEmpty() 88 } 89 } 90 91 @Test nonExistingManagedDeviceShouldThrowErrornull92 fun nonExistingManagedDeviceShouldThrowError() { 93 projectSetup.appTarget.setup() 94 projectSetup.producer.setup( 95 variantProfiles = listOf(emptyReleaseVariantProfile), 96 targetProject = projectSetup.appTarget, 97 managedDevices = listOf(), 98 baselineProfileBlock = 99 """ 100 managedDevices = ["nonExisting"] 101 """ 102 .trimIndent() 103 ) 104 105 projectSetup.producer.gradleRunner.buildAndFailAndAssertThatOutput("tasks") { 106 contains("No managed device named `nonExisting` was found.") 107 } 108 } 109 110 @Test existingManagedDeviceShouldCreateCollectTaskDependingOnManagedDeviceTasknull111 fun existingManagedDeviceShouldCreateCollectTaskDependingOnManagedDeviceTask() { 112 projectSetup.appTarget.setup() 113 projectSetup.producer.setup( 114 variantProfiles = listOf(emptyReleaseVariantProfile), 115 targetProject = projectSetup.appTarget, 116 managedDevices = listOf("somePixelDevice"), 117 baselineProfileBlock = 118 """ 119 managedDevices = ["somePixelDevice"] 120 """ 121 .trimIndent() 122 ) 123 124 projectSetup.producer.gradleRunner.build( 125 "collectNonMinifiedReleaseBaselineProfile", 126 "--dry-run" 127 ) { 128 val appTargetName = projectSetup.appTarget.name 129 val producerName = projectSetup.producer.name 130 val notFound = 131 it.lines() 132 .require( 133 ":$appTargetName:packageNonMinifiedRelease", 134 ":$producerName:somePixelDeviceNonMinifiedReleaseAndroidTest", 135 ":$producerName:connectedNonMinifiedReleaseAndroidTest", 136 ":$producerName:collectNonMinifiedReleaseBaselineProfile" 137 ) 138 assertThat(notFound).isEmpty() 139 } 140 } 141 142 @Test skipGenerationPropertyShouldDisableTestTasksnull143 fun skipGenerationPropertyShouldDisableTestTasks() { 144 projectSetup.appTarget.setup() 145 projectSetup.producer.setup( 146 variantProfiles = listOf(emptyReleaseVariantProfile), 147 targetProject = projectSetup.appTarget, 148 managedDevices = listOf("somePixelDevice"), 149 baselineProfileBlock = 150 """ 151 managedDevices = ["somePixelDevice"] 152 """ 153 .trimIndent(), 154 additionalGradleCodeBlock = 155 """ 156 afterEvaluate { 157 for (String taskName : [ 158 "somePixelDeviceNonMinifiedReleaseAndroidTest", 159 "collectNonMinifiedReleaseBaselineProfile"]) { 160 def task = tasks.getByName(taskName) 161 println(taskName + "=" + task.enabled) 162 } 163 } 164 """ 165 .trimIndent() 166 ) 167 168 // Execute any task and check the expected output. 169 // Note that executing `somePixelDeviceSetup` will fail for `LicenseNotAcceptedException`. 170 projectSetup.producer.gradleRunner.build( 171 "tasks", 172 "-Pandroidx.baselineprofile.skipgeneration" 173 ) { 174 val notFound = 175 it.lines() 176 .require( 177 "somePixelDeviceNonMinifiedReleaseAndroidTest=false", 178 "collectNonMinifiedReleaseBaselineProfile=false" 179 ) 180 assertThat(notFound).isEmpty() 181 } 182 } 183 184 @Test whenUseOnlyConnectedDevicesShouldOverrideDslnull185 fun whenUseOnlyConnectedDevicesShouldOverrideDsl() { 186 projectSetup.appTarget.setup() 187 projectSetup.producer.setup( 188 variantProfiles = listOf(emptyReleaseVariantProfile), 189 targetProject = projectSetup.appTarget, 190 managedDevices = listOf("somePixelDevice"), 191 baselineProfileBlock = 192 """ 193 managedDevices = ["somePixelDevice"] 194 useConnectedDevices = false 195 """ 196 .trimIndent() 197 ) 198 199 // Execute any task and check the expected output. 200 // Note that executing `somePixelDeviceSetup` will fail for `LicenseNotAcceptedException`. 201 projectSetup.producer.gradleRunner.buildAndAssertThatOutput( 202 "collectNonMinifiedReleaseBaselineProfile", 203 "--dry-run", 204 "-Pandroidx.baselineprofile.forceonlyconnecteddevices" 205 ) { 206 contains("connectedNonMinifiedReleaseAndroidTest") 207 doesNotContain("somePixelDeviceNonMinifiedReleaseAndroidTest") 208 } 209 } 210 211 @Test whenNotUseOnlyConnectedDevicesShouldOverrideDslnull212 fun whenNotUseOnlyConnectedDevicesShouldOverrideDsl() { 213 projectSetup.appTarget.setup() 214 projectSetup.producer.setup( 215 variantProfiles = listOf(emptyReleaseVariantProfile), 216 targetProject = projectSetup.appTarget, 217 managedDevices = listOf("somePixelDevice"), 218 baselineProfileBlock = 219 """ 220 managedDevices = ["somePixelDevice"] 221 useConnectedDevices = false 222 """ 223 .trimIndent() 224 ) 225 226 // Execute any task and check the expected output. 227 // Note that executing `somePixelDeviceSetup` will fail for `LicenseNotAcceptedException`. 228 projectSetup.producer.gradleRunner.buildAndAssertThatOutput( 229 "collectNonMinifiedReleaseBaselineProfile", 230 "--dry-run", 231 ) { 232 doesNotContain("connectedNonMinifiedReleaseAndroidTest") 233 contains("somePixelDeviceNonMinifiedReleaseAndroidTest") 234 } 235 } 236 } 237 238 @RunWith(Parameterized::class) 239 class BaselineProfileProducerPluginTestWithAgp81AndAbove(agpVersion: TestAgpVersion) { 240 241 companion object { 242 @Parameterized.Parameters(name = "agpVersion={0}") 243 @JvmStatic parametersnull244 fun parameters() = TestAgpVersion.atLeast(TEST_AGP_VERSION_8_1_1) 245 } 246 247 @get:Rule 248 val projectSetup = BaselineProfileProjectSetupRule(forceAgpVersion = agpVersion.versionString) 249 250 private val emptyReleaseVariantProfile = 251 VariantProfile(flavor = null, buildType = "release", profileFileLines = mapOf()) 252 253 @Test 254 fun verifyTasksWithAndroidTestPlugin() { 255 projectSetup.appTarget.setup() 256 projectSetup.producer.setup( 257 variantProfiles = listOf(emptyReleaseVariantProfile), 258 targetProject = projectSetup.appTarget 259 ) 260 261 projectSetup.producer.gradleRunner.build("tasks") { 262 val notFound = 263 it.lines() 264 .require( 265 "connectedNonMinifiedReleaseAndroidTest - ", 266 "connectedBenchmarkReleaseAndroidTest - ", 267 "collectNonMinifiedReleaseBaselineProfile - " 268 ) 269 assertThat(notFound).isEmpty() 270 } 271 } 272 } 273 274 @RunWith(Parameterized::class) 275 class BaselineProfileProducerPluginTestWithAgp82AndAbove(agpVersion: TestAgpVersion) { 276 277 companion object { 278 @Parameterized.Parameters(name = "agpVersion={0}") 279 @JvmStatic parametersnull280 fun parameters() = TestAgpVersion.atLeast(TEST_AGP_VERSION_8_2_0) 281 } 282 283 @get:Rule 284 val projectSetup = BaselineProfileProjectSetupRule(forceAgpVersion = agpVersion.versionString) 285 286 private val emptyReleaseVariantProfile = 287 VariantProfile(flavor = null, buildType = "release", profileFileLines = mapOf()) 288 289 @Test 290 fun verifyInstrumentationRunnerArgumentsAreSet() { 291 projectSetup.appTarget.setup() 292 projectSetup.producer.setup( 293 variantProfiles = listOf(emptyReleaseVariantProfile), 294 targetProject = projectSetup.appTarget, 295 additionalGradleCodeBlock = GRADLE_PRINT_ARGS_TASK 296 ) 297 298 data class AssertData( 299 val taskName: String, 300 val applyProp: Boolean, 301 val assertBlock: StringSubject.() -> (Unit) 302 ) 303 304 arrayOf( 305 AssertData("benchmarkReleaseArguments", false) { 306 contains("androidx.benchmark.enabledRules=macrobenchmark") 307 contains("androidx.benchmark.skipOnEmulator=true") 308 }, 309 AssertData("nonMinifiedReleaseArguments", false) { 310 contains("androidx.benchmark.enabledRules=baselineprofile") 311 }, 312 AssertData("benchmarkReleaseArguments", true) { 313 doesNotContain("androidx.benchmark.enabledRules=macrobenchmark") 314 contains("androidx.benchmark.skipOnEmulator=true") 315 }, 316 AssertData("nonMinifiedReleaseArguments", true) { 317 doesNotContain("androidx.benchmark.enabledRules=baselineprofile") 318 }, 319 ) 320 .forEach { 321 projectSetup.producer.gradleRunner.buildAndAssertThatOutput( 322 arguments = 323 listOfNotNull( 324 it.taskName, 325 if (it.applyProp) "-Pandroidx.baselineprofile.dontdisablerules" 326 else null 327 ) 328 .toTypedArray(), 329 assertBlock = it.assertBlock 330 ) 331 } 332 } 333 334 @Test runWhenInstrumentationRunnerArgumentsAreSetManuallynull335 fun runWhenInstrumentationRunnerArgumentsAreSetManually() { 336 projectSetup.appTarget.setup() 337 projectSetup.producer.setup( 338 variantProfiles = listOf(emptyReleaseVariantProfile), 339 targetProject = projectSetup.appTarget 340 ) 341 342 val enabledRuleProp = 343 "-Pandroid.testInstrumentationRunnerArguments.androidx.benchmark.enabledRules" 344 projectSetup.producer.gradleRunner.build( 345 "connectedBenchmarkReleaseAndroidTest", 346 "$enabledRuleProp=Macrobenchmark" 347 ) { 348 // This should not fail. 349 } 350 351 projectSetup.producer.gradleRunner.build( 352 "connectedNonMinifiedReleaseAndroidTest", 353 "$enabledRuleProp=BaselineProfile" 354 ) { 355 // This should not fail. 356 } 357 } 358 } 359 360 @RunWith(Parameterized::class) 361 class BaselineProfileProducerPluginTestWithAgp83AndAbove(agpVersion: TestAgpVersion) { 362 363 companion object { 364 @Parameterized.Parameters(name = "agpVersion={0}") 365 @JvmStatic parametersnull366 fun parameters() = TestAgpVersion.atLeast(TEST_AGP_VERSION_8_3_1) 367 } 368 369 @get:Rule 370 val projectSetup = BaselineProfileProjectSetupRule(forceAgpVersion = agpVersion.versionString) 371 372 private val emptyReleaseVariantProfile = 373 VariantProfile(flavor = null, buildType = "release", profileFileLines = mapOf()) 374 375 @Test 376 fun verifyTargetPackageNamePassedAsInstrumentationRunnerArgumentWithOverride() { 377 projectSetup.appTarget.setup() 378 projectSetup.producer.setup( 379 variantProfiles = listOf(emptyReleaseVariantProfile), 380 targetProject = projectSetup.appTarget, 381 additionalGradleCodeBlock = GRADLE_PRINT_ARGS_TASK 382 ) 383 384 val prop = 385 "-Pandroid.testInstrumentationRunnerArguments.androidx.benchmark.targetPackageName" 386 arrayOf( 387 arrayOf( 388 "benchmarkReleaseArguments", 389 "$prop=com.someotherpackage1", 390 "androidx.benchmark.targetPackageName=com.someotherpackage1" 391 ), 392 arrayOf( 393 "nonMinifiedReleaseArguments", 394 "$prop=com.someotherpackage2", 395 "androidx.benchmark.targetPackageName=com.someotherpackage2" 396 ), 397 ) 398 .forEach { 399 projectSetup.producer.gradleRunner.buildAndAssertThatOutput(it[0], it[1]) { 400 // Note that if the targetPackageName argument is overridden from CLI 401 // then it shouldn't be in the runner arguments map at this stage, as it's 402 // added later by the test plugin. 403 doesNotContain(it[2]) 404 } 405 } 406 } 407 } 408 409 @RunWith(Parameterized::class) 410 class BaselineProfileProducerPluginTestWithAgp84AndAbove(agpVersion: TestAgpVersion) { 411 412 companion object { 413 @Parameterized.Parameters(name = "agpVersion={0}") 414 @JvmStatic parametersnull415 fun parameters() = TestAgpVersion.atLeast(TEST_AGP_VERSION_8_4_2) 416 } 417 418 @get:Rule 419 val projectSetup = BaselineProfileProjectSetupRule(forceAgpVersion = agpVersion.versionString) 420 421 private val emptyReleaseVariantProfile = 422 VariantProfile(flavor = null, buildType = "release", profileFileLines = mapOf()) 423 424 @Test 425 fun verifyTargetPackageNamePassedAsInstrumentationRunnerArgument() { 426 projectSetup.appTarget.setup() 427 projectSetup.producer.setup( 428 variantProfiles = listOf(emptyReleaseVariantProfile), 429 targetProject = projectSetup.appTarget, 430 additionalGradleCodeBlock = GRADLE_PRINT_ARGS_TASK 431 ) 432 arrayOf( 433 Pair( 434 "benchmarkReleaseArguments", 435 "androidx.benchmark.targetPackageName=com.example.namespace" 436 ), 437 Pair( 438 "nonMinifiedReleaseArguments", 439 "androidx.benchmark.targetPackageName=com.example.namespace" 440 ), 441 ) 442 .forEach { 443 projectSetup.producer.gradleRunner.buildAndAssertThatOutput(it.first) { 444 contains(it.second) 445 } 446 } 447 } 448 } 449