Test for tracing at app startup
Bug: 283786690
Test: TrivialStartupBenchmark
Change-Id: I670cfd34a490a2e51d2ee3a10fcb84f6bab47c9c
diff --git a/benchmark/benchmark-common/src/main/java/androidx/benchmark/Arguments.kt b/benchmark/benchmark-common/src/main/java/androidx/benchmark/Arguments.kt
index 50b3f6b..47a2342 100644
--- a/benchmark/benchmark-common/src/main/java/androidx/benchmark/Arguments.kt
+++ b/benchmark/benchmark-common/src/main/java/androidx/benchmark/Arguments.kt
@@ -50,7 +50,14 @@
*
* Currently internal/experimental
*/
- val fullTracingEnable: Boolean
+ private val _fullTracingEnable: Boolean
+ val fullTracingEnable: Boolean get() = fullTracingEnableOverride ?: _fullTracingEnable
+
+ /**
+ * Allows tests to override whether full tracing is enabled
+ */
+ @VisibleForTesting
+ var fullTracingEnableOverride: Boolean? = null
val enabledRules: Set<RuleType>
@@ -121,7 +128,7 @@
iterations =
arguments.getBenchmarkArgument("iterations")?.toInt()
- fullTracingEnable =
+ _fullTracingEnable =
(arguments.getBenchmarkArgument("fullTracing.enable")?.toBoolean() ?: false)
// Transform comma-delimited list into set of suppressed errors
diff --git a/compose/integration-tests/macrobenchmark-target/src/main/AndroidManifest.xml b/compose/integration-tests/macrobenchmark-target/src/main/AndroidManifest.xml
index 39a5d41..1b763e5 100644
--- a/compose/integration-tests/macrobenchmark-target/src/main/AndroidManifest.xml
+++ b/compose/integration-tests/macrobenchmark-target/src/main/AndroidManifest.xml
@@ -47,6 +47,19 @@
</intent-filter>
</activity>
<activity
+ android:name=".TrivialStartupTracingActivity"
+ android:label="C TrivialTracing"
+ android:exported="true">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ <intent-filter>
+ <action android:name="androidx.compose.integration.macrobenchmark.target.TRIVIAL_STARTUP_TRACING_ACTIVITY" />
+ <category android:name="android.intent.category.DEFAULT" />
+ </intent-filter>
+ </activity>
+ <activity
android:name=".FullyDrawnStartupActivity"
android:exported="true">
<intent-filter>
diff --git a/compose/integration-tests/macrobenchmark-target/src/main/java/androidx/compose/integration/macrobenchmark/target/TrivialStartupTracingActivity.kt b/compose/integration-tests/macrobenchmark-target/src/main/java/androidx/compose/integration/macrobenchmark/target/TrivialStartupTracingActivity.kt
new file mode 100644
index 0000000..a3f9cbc
--- /dev/null
+++ b/compose/integration-tests/macrobenchmark-target/src/main/java/androidx/compose/integration/macrobenchmark/target/TrivialStartupTracingActivity.kt
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.compose.integration.macrobenchmark.target
+
+import android.os.Bundle
+import androidx.activity.ComponentActivity
+import androidx.activity.compose.setContent
+import androidx.compose.material.Text
+import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableIntStateOf
+import androidx.compose.runtime.remember
+import androidx.compose.runtime.setValue
+
+class TrivialStartupTracingActivity : ComponentActivity() {
+ private var incrementActivityResumedCount = {}
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+
+ setContent {
+ var resumedCount by remember { mutableIntStateOf(0) }
+ incrementActivityResumedCount = { ++resumedCount }
+ Text("Compose Macrobenchmark Target (resumed $resumedCount times)")
+ }
+ }
+
+ override fun onResume() {
+ super.onResume()
+ incrementActivityResumedCount()
+ }
+}
diff --git a/compose/integration-tests/macrobenchmark/src/main/java/androidx/compose/integration/macrobenchmark/TrivialStartupTracingBenchmark.kt b/compose/integration-tests/macrobenchmark/src/main/java/androidx/compose/integration/macrobenchmark/TrivialStartupTracingBenchmark.kt
new file mode 100644
index 0000000..47cbb44
--- /dev/null
+++ b/compose/integration-tests/macrobenchmark/src/main/java/androidx/compose/integration/macrobenchmark/TrivialStartupTracingBenchmark.kt
@@ -0,0 +1,91 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.compose.integration.macrobenchmark
+
+import androidx.benchmark.Arguments
+import androidx.benchmark.macro.CompilationMode
+import androidx.benchmark.macro.ExperimentalMetricApi
+import androidx.benchmark.macro.StartupMode
+import androidx.benchmark.macro.TraceSectionMetric
+import androidx.benchmark.macro.junit4.MacrobenchmarkRule
+import androidx.test.filters.LargeTest
+import androidx.testutils.measureStartup
+import org.hamcrest.CoreMatchers.`is`
+import org.hamcrest.MatcherAssert.assertThat
+import org.junit.Ignore
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.Parameterized
+
+@OptIn(ExperimentalMetricApi::class)
+@LargeTest
+@RunWith(Parameterized::class)
+class TrivialStartupTracingBenchmark(
+ private val startupMode: StartupMode,
+ private val compilationMode: CompilationMode,
+ private val isFullTracingEnabled: Boolean
+) {
+ @get:Rule
+ val benchmarkRule = MacrobenchmarkRule()
+
+ // TODO(283953019): enable alongside StartupTracingInitializer (pending performance testing)
+ @Ignore
+ @Test
+ fun startup() = try {
+ Arguments.fullTracingEnableOverride = isFullTracingEnabled
+ assertThat(Arguments.fullTracingEnable, `is`(isFullTracingEnabled))
+
+ try {
+ val perfettoSdkTraceSection = TraceSectionMetric(
+ "androidx.compose.integration.macrobenchmark.target." +
+ "TrivialStartupTracingActivity.onCreate.<anonymous>" +
+ " (TrivialStartupTracingActivity.kt:33)"
+ )
+ benchmarkRule.measureStartup(
+ compilationMode = compilationMode,
+ startupMode = startupMode,
+ iterations = 1, // we are only verifying presence of entries (not the timing data)
+ metrics = listOf(perfettoSdkTraceSection),
+ packageName = "androidx.compose.integration.macrobenchmark.target"
+ ) {
+ action = "androidx.compose.integration.macrobenchmark.target." +
+ "TRIVIAL_STARTUP_TRACING_ACTIVITY"
+ }
+ } catch (e: IllegalArgumentException) {
+ if (!isFullTracingEnabled &&
+ e.message?.contains("Unable to read any metrics during benchmark") == true
+ ) {
+ // this is expected, we don't expect Perfetto SDK Tracing section present
+ // when full tracing is disabled
+ } else throw e // this is a legitimate failure
+ }
+ } finally {
+ Arguments.fullTracingEnableOverride = null
+ }
+
+ companion object {
+ @Parameterized.Parameters(name = "startup={0},compilation={1},fullTracing={2}")
+ @JvmStatic
+ fun parameters() = listOf(
+ arrayOf(StartupMode.COLD, CompilationMode.DEFAULT, /* fullTracing = */ true),
+ arrayOf(StartupMode.COLD, CompilationMode.DEFAULT, /* fullTracing = */ false),
+ arrayOf(StartupMode.WARM, CompilationMode.DEFAULT, /* fullTracing = */ true),
+ arrayOf(StartupMode.WARM, CompilationMode.DEFAULT, /* fullTracing = */ false),
+ )
+ }
+}