1 /* <lambda>null2 * Copyright 2023 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.apptarget 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.build 23 import androidx.baselineprofile.gradle.utils.buildAndAssertThatOutput 24 import androidx.baselineprofile.gradle.utils.containsOnly 25 import com.google.common.truth.Truth.assertThat 26 import java.io.File 27 import org.junit.Rule 28 import org.junit.Test 29 import org.junit.runner.RunWith 30 import org.junit.runners.Parameterized 31 32 private fun createBuildGradle(overrideExtendedBuildTypesForRelease: Boolean = false) = 33 """ 34 import static com.android.build.gradle.internal.ProguardFileType.EXPLICIT; 35 36 plugins { 37 id("com.android.application") 38 id("androidx.baselineprofile.apptarget") 39 } 40 41 android { 42 namespace 'com.example.namespace' 43 buildTypes { 44 45 ${ 46 if (overrideExtendedBuildTypesForRelease) """ 47 48 benchmarkRelease { 49 initWith(release) 50 profileable true 51 } 52 nonMinifiedRelease { 53 initWith(release) 54 } 55 56 """.trimIndent() else "" 57 } 58 59 anotherRelease { 60 initWith(release) 61 minifyEnabled true 62 postprocessing { 63 proguardFile("proguard-rules1.pro") 64 } 65 } 66 myCustomRelease { 67 initWith(release) 68 minifyEnabled false 69 proguardFiles "proguard-rules2.pro" 70 } 71 benchmarkMyCustomRelease { 72 initWith(myCustomRelease) 73 74 // These are the opposite of default ensure the plugin doesn't modify them 75 minifyEnabled false 76 shrinkResources false 77 } 78 nonMinifiedMyCustomRelease { 79 initWith(myCustomRelease) 80 81 // These are the opposite of default ensure the plugin does modify them 82 debuggable true 83 minifyEnabled true 84 shrinkResources true 85 profileable false 86 } 87 } 88 } 89 90 def printVariantsTaskProvider = tasks.register("printVariants", PrintTask) { t -> 91 t.text.set("") 92 } 93 94 androidComponents { 95 onVariants(selector()) { variant -> 96 printVariantsTaskProvider.configure { t -> 97 t.text.set(t.text.get() + "\n" + "print-variant:" + variant.name) 98 } 99 tasks.register(variant.name + "BuildProperties", PrintTask) { t -> 100 def buildType = android.buildTypes[variant.buildType] 101 def text = "minifyEnabled=" + buildType.minifyEnabled.toString() + "\n" 102 text += "testCoverageEnabled=" + buildType.testCoverageEnabled.toString() + "\n" 103 text += "debuggable=" + buildType.debuggable.toString() + "\n" 104 text += "profileable=" + buildType.profileable.toString() + "\n" 105 text += "proguardFiles=" + buildType.proguardFiles.toString() + "\n" 106 text += "postProcessingProguardFiles=" + buildType.postprocessing.getProguardFiles(EXPLICIT) + "\n" 107 t.text.set(text) 108 } 109 tasks.register(variant.name + "JavaSources", DisplaySourceSets) { t -> 110 t.srcs.set(variant.sources.java.all) 111 } 112 tasks.register(variant.name + "KotlinSources", DisplaySourceSets) { t -> 113 t.srcs.set(variant.sources.kotlin.all) 114 } 115 } 116 } 117 """ 118 .trimIndent() 119 120 @RunWith(Parameterized::class) 121 class BaselineProfileAppTargetPluginTestWithAgp81AndAbove(agpVersion: TestAgpVersion) { 122 123 companion object { 124 @Parameterized.Parameters(name = "agpVersion={0}") 125 @JvmStatic parametersnull126 fun parameters() = TestAgpVersion.atLeast(TEST_AGP_VERSION_8_1_1) 127 } 128 129 @get:Rule 130 val projectSetup = BaselineProfileProjectSetupRule(forceAgpVersion = agpVersion.versionString) 131 132 private val buildGradle = createBuildGradle() 133 134 @Test 135 fun additionalBuildTypesShouldNotBeCreatedForExistingNonMinifiedAndBenchmarkBuildTypes() = 136 arrayOf( 137 true, 138 false, 139 ) 140 .forEach { overrideExtendedBuildTypesForRelease -> 141 projectSetup.appTarget.setBuildGradle( 142 buildGradleContent = 143 createBuildGradle( 144 overrideExtendedBuildTypesForRelease = 145 overrideExtendedBuildTypesForRelease, 146 ) 147 ) 148 projectSetup.appTarget.gradleRunner.build("printVariants") { 149 val variants = 150 it.lines() 151 .filter { l -> l.startsWith("print-variant:") } 152 .map { l -> l.substringAfter("print-variant:").trim() } 153 .toSet() 154 .toList() 155 156 assertThat( 157 variants.containsOnly( 158 "debug", 159 "release", 160 "benchmarkRelease", 161 "nonMinifiedRelease", 162 "anotherRelease", 163 "nonMinifiedAnotherRelease", 164 "benchmarkAnotherRelease", 165 "myCustomRelease", 166 "nonMinifiedMyCustomRelease", 167 "benchmarkMyCustomRelease", 168 ) 169 ) 170 .isTrue() 171 } 172 } 173 174 @Test verifyUnitTestDisablednull175 fun verifyUnitTestDisabled() { 176 projectSetup.appTarget.setBuildGradle(buildGradle) 177 projectSetup.appTarget.gradleRunner.buildAndAssertThatOutput("test", "--dry-run") { 178 contains(":testDebugUnitTest ") 179 contains(":testReleaseUnitTest ") 180 contains(":testAnotherReleaseUnitTest ") 181 doesNotContain(":testNonMinifiedReleaseUnitTest ") 182 doesNotContain(":testBenchmarkReleaseUnitTest ") 183 doesNotContain(":testNonMinifiedAnotherReleaseUnitTest ") 184 doesNotContain(":testBenchmarkAnotherReleaseUnitTest ") 185 } 186 } 187 188 @Test verifyNewBuildTypesnull189 fun verifyNewBuildTypes() { 190 projectSetup.appTarget.setBuildGradle(buildGradle) 191 192 // Assert properties of the benchmark build types 193 projectSetup.appTarget.gradleRunner.buildAndAssertThatOutput( 194 "benchmarkReleaseBuildProperties" 195 ) { 196 contains("testCoverageEnabled=false") 197 contains("debuggable=false") 198 contains("profileable=true") 199 200 // This value is false for `release` so it should be copied over. 201 contains("minifyEnabled=false") 202 } 203 204 projectSetup.appTarget.gradleRunner.buildAndAssertThatOutput( 205 "benchmarkAnotherReleaseBuildProperties" 206 ) { 207 contains("testCoverageEnabled=false") 208 contains("debuggable=false") 209 contains("profileable=true") 210 211 // This value is true for `release` so it should be copied over. 212 contains("minifyEnabled=true") 213 } 214 215 // Assert properties of the baseline profile build types. 216 arrayOf("nonMinifiedReleaseBuildProperties", "nonMinifiedAnotherReleaseBuildProperties") 217 .forEach { taskName -> 218 projectSetup.appTarget.gradleRunner.buildAndAssertThatOutput(taskName) { 219 contains("minifyEnabled=false") 220 contains("testCoverageEnabled=false") 221 contains("debuggable=false") 222 contains("profileable=true") 223 } 224 } 225 } 226 227 @Test verifyOverrideBuildTypesnull228 fun verifyOverrideBuildTypes() { 229 projectSetup.appTarget.setBuildGradle(buildGradle) 230 231 projectSetup.appTarget.gradleRunner.buildAndAssertThatOutput( 232 "benchmarkMyCustomReleaseBuildProperties" 233 ) { 234 235 // Should be overridden 236 contains("testCoverageEnabled=false") 237 contains("debuggable=false") 238 contains("profileable=true") 239 240 // Should not be overridden 241 contains("minifyEnabled=false") 242 } 243 244 projectSetup.appTarget.gradleRunner.buildAndAssertThatOutput( 245 "nonMinifiedMyCustomReleaseBuildProperties" 246 ) { 247 248 // Should all be overridden 249 contains("minifyEnabled=false") 250 contains("testCoverageEnabled=false") 251 contains("debuggable=false") 252 contains("profileable=true") 253 } 254 } 255 256 @Test verifyProguardFilesAreCopiedInExtendedBuildTypesnull257 fun verifyProguardFilesAreCopiedInExtendedBuildTypes() { 258 projectSetup.appTarget.setBuildGradle(buildGradle) 259 260 data class TaskAndExpected( 261 val benchmarkBuildType: String, 262 val baselineProfileBuildType: String, 263 val expectedProguardFile: String?, 264 val expectedPostProcessingProguardFile: String? 265 ) 266 267 arrayOf( 268 TaskAndExpected( 269 benchmarkBuildType = "benchmarkRelease", 270 baselineProfileBuildType = "nonMinifiedRelease", 271 expectedProguardFile = null, 272 expectedPostProcessingProguardFile = null, 273 ), 274 TaskAndExpected( 275 benchmarkBuildType = "benchmarkAnotherRelease", 276 baselineProfileBuildType = "nonMinifiedAnotherRelease", 277 expectedProguardFile = null, 278 expectedPostProcessingProguardFile = "proguard-rules1.pro", 279 ), 280 TaskAndExpected( 281 benchmarkBuildType = "benchmarkMyCustomRelease", 282 baselineProfileBuildType = "nonMinifiedMyCustomRelease", 283 expectedProguardFile = "proguard-rules2.pro", 284 expectedPostProcessingProguardFile = null, 285 ), 286 ) 287 .forEach { 288 projectSetup.appTarget.gradleRunner.buildAndAssertThatOutput( 289 "${it.benchmarkBuildType}BuildProperties" 290 ) { 291 if (it.expectedProguardFile != null) { 292 contains( 293 "proguardFiles=[${ 294 File( 295 projectSetup.appTarget.rootDir.canonicalFile, 296 it.expectedProguardFile 297 ) 298 }]" 299 ) 300 } 301 if (it.expectedPostProcessingProguardFile != null) { 302 containsMatch( 303 "postProcessingProguardFiles=\\[[^,]+, ${ 304 File( 305 projectSetup.appTarget.rootDir.canonicalFile, 306 it.expectedPostProcessingProguardFile 307 ) 308 }" 309 ) 310 } 311 } 312 projectSetup.appTarget.gradleRunner.buildAndAssertThatOutput( 313 "${it.baselineProfileBuildType}BuildProperties" 314 ) { 315 if (it.expectedProguardFile != null) { 316 contains( 317 "proguardFiles=[${ 318 File( 319 projectSetup.appTarget.rootDir.canonicalFile, 320 it.expectedProguardFile 321 ) 322 }]" 323 ) 324 } 325 if (it.expectedPostProcessingProguardFile != null) { 326 containsMatch( 327 "postProcessingProguardFiles=\\[[^,]+, ${ 328 File( 329 projectSetup.appTarget.rootDir.canonicalFile, 330 it.expectedPostProcessingProguardFile 331 ) 332 }" 333 ) 334 } 335 } 336 } 337 } 338 } 339 340 @RunWith(Parameterized::class) 341 class BaselineProfileAppTargetPluginTestWithAgp80AndAbove(agpVersion: TestAgpVersion) { 342 343 companion object { 344 @Parameterized.Parameters(name = "agpVersion={0}") 345 @JvmStatic parametersnull346 fun parameters() = TestAgpVersion.atLeast(TEST_AGP_VERSION_8_1_1) 347 } 348 349 @get:Rule 350 val projectSetup = BaselineProfileProjectSetupRule(forceAgpVersion = agpVersion.versionString) 351 352 private val buildGradle = createBuildGradle() 353 354 @Test 355 fun testSrcSetAreAddedToVariantsForApplications() { 356 projectSetup.appTarget.setBuildGradle(buildGradle) 357 358 data class TaskAndExpected(val taskName: String, val expectedDirs: List<String>) 359 360 arrayOf( 361 TaskAndExpected( 362 taskName = "nonMinifiedAnotherReleaseJavaSources", 363 expectedDirs = 364 listOf( 365 "src/main/java", 366 "src/anotherRelease/java", 367 "src/nonMinifiedAnotherRelease/java", 368 ) 369 ), 370 TaskAndExpected( 371 taskName = "nonMinifiedReleaseJavaSources", 372 expectedDirs = 373 listOf( 374 "src/main/java", 375 "src/release/java", 376 "src/nonMinifiedRelease/java", 377 ) 378 ), 379 TaskAndExpected( 380 taskName = "nonMinifiedAnotherReleaseKotlinSources", 381 expectedDirs = 382 listOf( 383 "src/main/kotlin", 384 "src/anotherRelease/kotlin", 385 "src/nonMinifiedAnotherRelease/kotlin", 386 ) 387 ), 388 TaskAndExpected( 389 taskName = "nonMinifiedReleaseKotlinSources", 390 expectedDirs = 391 listOf( 392 "src/main/kotlin", 393 "src/release/kotlin", 394 "src/nonMinifiedRelease/kotlin", 395 ) 396 ) 397 ) 398 .forEach { t -> 399 400 // Runs the task and assert 401 projectSetup.appTarget.gradleRunner.buildAndAssertThatOutput(t.taskName) { 402 t.expectedDirs 403 .map { File(projectSetup.appTarget.rootDir, it) } 404 .forEach { e -> contains(e.absolutePath) } 405 } 406 } 407 } 408 409 @Test additionalBuildTypesShouldNotBeCreatedForExistingNonMinifiedAndBenchmarkBuildTypesnull410 fun additionalBuildTypesShouldNotBeCreatedForExistingNonMinifiedAndBenchmarkBuildTypes() = 411 arrayOf( 412 true, 413 false, 414 ) 415 .forEach { overrideExtendedBuildTypesForRelease -> 416 projectSetup.appTarget.setBuildGradle( 417 buildGradleContent = 418 createBuildGradle( 419 overrideExtendedBuildTypesForRelease = 420 overrideExtendedBuildTypesForRelease, 421 ) 422 ) 423 424 projectSetup.appTarget.gradleRunner.build("printVariants") { 425 val variants = 426 it.lines() 427 .filter { l -> l.startsWith("print-variant:") } 428 .map { l -> l.substringAfter("print-variant:").trim() } 429 .toSet() 430 .toList() 431 432 assertThat( 433 variants.containsOnly( 434 "debug", 435 "release", 436 "nonMinifiedRelease", 437 "anotherRelease", 438 "nonMinifiedAnotherRelease", 439 "myCustomRelease", 440 "nonMinifiedMyCustomRelease", 441 ) 442 ) 443 .isTrue() 444 } 445 } 446 } 447