Generate profile automatically with release builds

Change-Id: I2fef03733b7ea277a7747f7f0c2d179a69ba2d79
wk/baseline-profile-experiments
Wojtek Kaliciński 2 years ago
parent d0ba51efec
commit 2d56a80cb2

1
.gitignore vendored

@ -16,6 +16,7 @@ build/
# Local configuration file (sdk path, etc)
local.properties
secrets.properties
# Eclipse project files
.classpath

@ -1,3 +1,6 @@
import com.android.build.gradle.internal.component.ApkCreationConfig
import com.android.build.gradle.internal.tasks.factory.dependsOn
/*
* Copyright 2021 The Android Open Source Project
*
@ -118,4 +121,53 @@ configurations.configureEach {
// Temporary workaround for https://issuetracker.google.com/174733673
force("org.objenesis:objenesis:2.6")
}
}
configurations {
create("releaseBaselineProfile") {
isCanBeConsumed = false
isCanBeResolved = true
attributes {
attribute(Category.CATEGORY_ATTRIBUTE, objects.named(Category.LIBRARY))
attribute(Usage.USAGE_ATTRIBUTE, objects.named(Usage.JAVA_RUNTIME))
attribute(LibraryElements.LIBRARY_ELEMENTS_ATTRIBUTE, objects.named("baseline-profile"))
}
}
}
dependencies {
"releaseBaselineProfile"(project(":benchmark"))
}
val copyBpTask = tasks.register<GenerateBaselineProfTask>("copyBaselineProfile") {
inputArtifact.set(configurations.getByName("releaseBaselineProfile").incoming.artifacts.resolvedArtifacts.map {
layout.projectDirectory.file(it.single().file.absolutePath)
})
baselineProfTxt.set(layout.projectDirectory.file("src/main/baseline-prof.txt"))
}
afterEvaluate {
tasks.named("mergeDemoReleaseArtProfile").dependsOn(copyBpTask)
tasks.named("mergeProdReleaseArtProfile").dependsOn(copyBpTask)
}
abstract class GenerateBaselineProfTask : DefaultTask() {
@get:Inject
abstract val layout: ProjectLayout
@get:InputFile
abstract val inputArtifact: RegularFileProperty
@get:OutputFile
abstract val baselineProfTxt: RegularFileProperty
@TaskAction
fun execute() {
baselineProfTxt.asFile.get().delete()
inputArtifact.get().asFile.copyTo(baselineProfTxt.asFile.get())
}
}

File diff suppressed because it is too large Load Diff

@ -13,16 +13,19 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import com.android.build.api.dsl.ManagedVirtualDevice
import com.android.build.gradle.internal.tasks.factory.dependsOn
import com.google.samples.apps.nowinandroid.Flavor
import com.google.samples.apps.nowinandroid.FlavorDimension
import com.google.samples.apps.nowinandroid.configureFlavors
import org.jetbrains.kotlin.util.capitalizeDecapitalize.capitalizeAsciiOnly
plugins {
id("nowinandroid.android.test")
}
android {
namespace = "com.google.samples.apps.nowinandroid.benchmark"
namespace = "com.google.samples.apps.nowinandroid.benchmarking"
defaultConfig {
minSdk = 23
@ -44,14 +47,50 @@ android {
matchingFallbacks.add("release")
}
}
// Use the same flavor dimensions as the application to allow generating Baseline Profiles on prod,
// which is more close to what will be shipped to users (no fake data), but has ability to run the
// benchmarks on demo, so we benchmark on stable data.
configureFlavors(this)
flavorDimensions += "benchmark"
productFlavors {
create("macro") {
dimension = "benchmark"
testInstrumentationRunnerArguments["androidx.benchmark.enabledRules"] = "Macrobenchmark"
}
create("baseline") {
dimension = "benchmark"
testInstrumentationRunnerArguments["androidx.benchmark.enabledRules"] = "BaselineProfile"
}
}
targetProjectPath = ":app"
experimentalProperties["android.experimental.self-instrumenting"] = true
testOptions {
managedDevices {
devices {
create<ManagedVirtualDevice>("AospAtd30") {
// Use device profiles you typically see in Android Studio.
device = "Pixel 2"
// ATDs currently support only API level 30.
apiLevel = 31
// You can also specify "google-atd" if you require Google Play Services.
systemImageSource = "aosp"
}
create<ManagedVirtualDevice>("GoogleAtd30") {
// Use device profiles you typically see in Android Studio.
device = "Pixel 2"
// ATDs currently support only API level 30.
apiLevel = 30
// You can also specify "google-atd" if you require Google Play Services.
systemImageSource = "google-atd"
}
}
}
}
}
dependencies {
@ -69,4 +108,47 @@ androidComponents {
beforeVariants {
it.enable = it.buildType == "benchmark"
}
beforeVariants (selector()
.withBuildType("benchmark")
.withFlavor(Flavor.prod.dimension.name to Flavor.prod.name)
.withFlavor("benchmark" to "baseline")) {
val capitalName = it.name.capitalizeAsciiOnly()
val task = tasks.register<Copy>("baselineProfileFor${capitalName}") {
dependsOn("AospAtd30${capitalName}AndroidTest")
from(
buildDir.resolve("outputs/" +
"managed_device_android_test_additional_output/" +
"flavors/" +
"${it.flavorName}/" +
"AospAtd30/" +
"BaselineProfileGenerator_generate-baseline-prof.txt")
)
destinationDir = buildDir.resolve("outputs/baselineProfile")
rename {
"baseline-prof.txt"
}
}
configurations {
println("creating baselineProfile$capitalName")
create("baselineProfile$capitalName") {
isCanBeConsumed = true
isCanBeResolved = false
attributes {
attribute(Category.CATEGORY_ATTRIBUTE, objects.named(Category.LIBRARY))
attribute(Usage.USAGE_ATTRIBUTE, objects.named(Usage.JAVA_RUNTIME))
attribute(LibraryElements.LIBRARY_ELEMENTS_ATTRIBUTE, objects.named("baseline-profile"))
}
}
}
artifacts {
add("baselineProfile$capitalName", task.map {
it.outputs.files.singleFile.resolve("baseline-prof.txt")
}) {
builtBy(task)
}
}
}
}

@ -16,10 +16,14 @@
package com.google.samples.apps.nowinandroid
import com.google.samples.apps.nowinandroid.benchmark.BuildConfig
import com.google.samples.apps.nowinandroid.benchmarking.BuildConfig
/**
* Convenience parameter to use proper package name with regards to build type and build flavor.
*/
const val PACKAGE_NAME =
val PACKAGE_NAME = if (BuildConfig.FLAVOR_contentType == "demo") {
"com.google.samples.apps.nowinandroid.${BuildConfig.FLAVOR}.${BuildConfig.BUILD_TYPE}"
} else {
"com.google.samples.apps.nowinandroid.${BuildConfig.BUILD_TYPE}"
}

@ -47,26 +47,26 @@ class BaselineProfileGenerator {
startActivityAndWait()
// Scroll the feed critical user journey
forYouWaitForContent()
forYouSelectAuthors()
forYouScrollFeedDownUp()
// Navigate to saved screen
device.findObject(By.text("Saved")).click()
device.waitForIdle()
bookmarksScrollFeedDownUp()
// Navigate to interests screen
device.findObject(By.text("Interests")).click()
device.waitForIdle()
interestsScrollTopicsDownUp()
// Navigate to people tab
device.findObject(By.text("People")).click()
device.waitForIdle()
interestsScrollPeopleDownUp()
// forYouWaitForContent()
// forYouSelectAuthors()
// forYouScrollFeedDownUp()
//
// // Navigate to saved screen
// device.findObject(By.text("Saved")).click()
// device.waitForIdle()
//
// bookmarksScrollFeedDownUp()
//
// // Navigate to interests screen
// device.findObject(By.text("Interests")).click()
// device.waitForIdle()
//
// interestsScrollTopicsDownUp()
//
// // Navigate to people tab
// device.findObject(By.text("People")).click()
// device.waitForIdle()
//
// interestsScrollPeopleDownUp()
}
}

@ -27,16 +27,20 @@ fun MacrobenchmarkScope.forYouWaitForContent() {
}
fun MacrobenchmarkScope.forYouSelectAuthors() {
device.wait(Until.hasObject(By.res("forYou:authors")), 5_000)
val authors = device.findObject(By.res("forYou:authors"))
// select some authors to show some feed content
repeat(3) { index ->
val author = authors.children[index % authors.childCount]
author.click()
if (authors.childCount != 0) {
val author = authors.children[index % authors.childCount]
author.click()
}
device.waitForIdle()
}
}
fun MacrobenchmarkScope.forYouScrollFeedDownUp() {
device.wait(Until.hasObject(By.res("forYou:feed")), 5_000)
val feedList = device.findObject(By.res("forYou:feed"))
feedList.fling(Direction.DOWN)
device.waitForIdle()

@ -30,6 +30,7 @@ android {
}
secrets {
propertiesFileName = "secrets.properties"
defaultPropertiesFileName = "secrets.defaults.properties"
}

@ -1,7 +1,7 @@
[versions]
accompanist = "0.24.8-beta"
androidDesugarJdkLibs = "1.1.5"
androidGradlePlugin = "7.3.0"
androidGradlePlugin = "7.3.1"
androidxActivity = "1.6.0"
androidxAppCompat = "1.5.1"
androidxCompose = "1.3.0-beta02"
@ -16,7 +16,7 @@ androidxEspresso = "3.4.0"
androidxHiltNavigationCompose = "1.0.0"
# Skipping version 2.6.0-alpha02 due to https://issuetracker.google.com/249686765
androidxLifecycle = "2.6.0-alpha01"
androidxMacroBenchmark = "1.1.0"
androidxMacroBenchmark = "1.2.0-alpha05"
androidxNavigation = "2.5.2"
androidxMetrics = "1.0.0-alpha03"
androidxProfileinstaller = "1.2.0"

Loading…
Cancel
Save