| import org.gradle.work.DisableCachingByDefault |
| |
| import static androidx.baselineprofile.gradle.utils.UtilsKt.camelCase |
| |
| // To trigger the baseline profile generation using the different modules the test will call |
| // the base generation task `generateBaselineProfile`. The `AssertEqualsAndCleanUpTask` asserts |
| // that the final output is the expected one and if there are no failures cleans up the |
| // generated baseline-prof.txt. |
| @DisableCachingByDefault(because = "Integration test task") |
| abstract class AssertEqualsAndCleanUpTask extends DefaultTask { |
| |
| @InputFile |
| @PathSensitive(PathSensitivity.NONE) |
| abstract RegularFileProperty getExpectedFile() |
| |
| // This property is passed as path and not as a file because it might not exist |
| @Input |
| abstract Property<String> getActualFilePath() |
| |
| @TaskAction |
| void exec() { |
| |
| File expectedFile = getExpectedFile().get().asFile |
| File actualFile = new File(actualFilePath.get()) |
| |
| if (!expectedFile.exists() && actualFile.exists()) { |
| throw new GradleException("No profile was expected in ${actualFile.absolutePath}.") |
| } |
| if (expectedFile.exists() && !actualFile.exists()) { |
| throw new GradleException("A profile was expected in ${actualFile.absolutePath}.") |
| } |
| |
| if (!actualFile.exists()) { |
| throw new GradleException( |
| "A profile was expected in ${actualFile.absolutePath}." |
| ) |
| } |
| |
| def expectedIter = expectedFile.text.lines().iterator() |
| def actualIter = actualFile.text.lines().iterator() |
| |
| def lineCounter = 0 |
| def diff = new ArrayList<String>() |
| while (expectedIter.hasNext() || actualIter.hasNext()) { |
| def expected = expectedIter.hasNext() ? expectedIter.next() : "" |
| def actual = actualIter.hasNext() ? actualIter.next() : "" |
| if (expected != actual) { |
| diff.add("Line: $lineCounter, Expected: `$expected`, Actual: `$actual`") |
| } |
| lineCounter++ |
| } |
| |
| if (!diff.isEmpty()) { |
| logger.error("Actual generated profile differs from expected one: \n\t" |
| + diff.join("\n\t")) |
| throw new GradleException("Actual generated profile differs from expected one.") |
| } |
| |
| // This deletes the actual file since it's a test artifact |
| actualFile.delete() |
| } |
| } |
| |
| // For each variant we expect `expected-baseline-prof.txt` and `baseline-prof.txt` to be |
| // present and have the same content. |
| def testTaskProviders = [] |
| |
| def registerAssertTask( |
| ArrayList<TaskProvider<Task>> testTaskProviders, |
| String variantName, |
| String taskName, |
| String expectedFilename, |
| String filename |
| ) { |
| |
| def expectedBaselineProfileSubDir = "generated/baselineProfiles" |
| |
| def expectedFile = project |
| .layout |
| .projectDirectory |
| .file("src/$variantName/$expectedBaselineProfileSubDir/${expectedFilename}.txt") |
| |
| // If there is no expected file then skip testing this variant. |
| if (!expectedFile.asFile.exists()) { |
| return |
| } |
| |
| def taskProvider = project.tasks.register( |
| camelCase("test", variantName, "${taskName}Generation"), |
| AssertEqualsAndCleanUpTask |
| ) { |
| it.expectedFile.set(expectedFile) |
| it.actualFilePath.set(project |
| .layout |
| .projectDirectory |
| .file("src/$variantName/$expectedBaselineProfileSubDir/${filename}.txt") |
| .getAsFile() |
| .absolutePath) |
| |
| // Depend on the main profile generation task |
| it.dependsOn(tasks.named(camelCase("generate", variantName, "baselineProfile"))) |
| } |
| |
| testTaskProviders.add(taskProvider) |
| } |
| |
| // An assert task is defined per variant |
| androidComponents { |
| onVariants(selector().all()) { variant -> |
| registerAssertTask( |
| testTaskProviders, |
| variant.name, |
| "baselineProfile", |
| "expected-baseline-prof", |
| "baseline-prof" |
| ) |
| registerAssertTask( |
| testTaskProviders, |
| variant.name, |
| "startupProfile", |
| "expected-startup-prof", |
| "startup-prof" |
| ) |
| } |
| } |
| |
| // Ensures that calling `testBaselineProfileGeneration` runs all the test tasks |
| afterEvaluate { |
| tasks.register("testBaselineProfileGeneration").configure { |
| it.dependsOn(testTaskProviders) |
| } |
| } |