1 /* 2 * Copyright (C) 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 android.tools.device.traces.monitors 18 19 import android.app.Instrumentation 20 import android.support.test.uiautomator.UiDevice 21 import android.tools.common.io.RunStatus 22 import android.tools.common.io.TraceType 23 import android.tools.common.traces.DeviceTraceDump 24 import android.tools.device.traces.TRACE_CONFIG_REQUIRE_CHANGES 25 import android.tools.device.traces.deleteIfExists 26 import android.tools.device.traces.io.ResultReader 27 import android.tools.device.traces.parsers.DeviceDumpParser 28 import android.tools.newTestResultWriter 29 import android.tools.outputFileName 30 import android.tools.rules.CleanFlickerEnvironmentRule 31 import androidx.test.platform.app.InstrumentationRegistry 32 import com.google.common.truth.Truth 33 import org.junit.After 34 import org.junit.Before 35 import org.junit.ClassRule 36 import org.junit.Test 37 38 abstract class TraceMonitorTest<T : TraceMonitor> { getMonitornull39 abstract fun getMonitor(): T 40 abstract fun assertTrace(traceData: ByteArray) 41 abstract val traceType: TraceType 42 43 protected val instrumentation: Instrumentation = InstrumentationRegistry.getInstrumentation() 44 protected val device: UiDevice = UiDevice.getInstance(instrumentation) 45 private val traceMonitor by lazy { getMonitor() } 46 47 @Before beforenull48 fun before() { 49 Truth.assertWithMessage("Trace already enabled before starting test") 50 .that(traceMonitor.isEnabled) 51 .isFalse() 52 } 53 54 @After teardownnull55 fun teardown() { 56 device.pressHome() 57 if (traceMonitor.isEnabled) { 58 traceMonitor.stop(newTestResultWriter()) 59 } 60 outputFileName(RunStatus.RUN_EXECUTED).deleteIfExists() 61 Truth.assertWithMessage("Failed to disable trace at end of test") 62 .that(traceMonitor.isEnabled) 63 .isFalse() 64 } 65 66 @Test 67 @Throws(Exception::class) canStartTracenull68 fun canStartTrace() { 69 traceMonitor.start() 70 Truth.assertThat(traceMonitor.isEnabled).isTrue() 71 } 72 73 @Test 74 @Throws(Exception::class) canStopTracenull75 fun canStopTrace() { 76 traceMonitor.start() 77 Truth.assertThat(traceMonitor.isEnabled).isTrue() 78 traceMonitor.stop(newTestResultWriter()) 79 Truth.assertThat(traceMonitor.isEnabled).isFalse() 80 } 81 82 @Test 83 @Throws(Exception::class) captureTracenull84 fun captureTrace() { 85 traceMonitor.start() 86 val writer = newTestResultWriter() 87 traceMonitor.stop(writer) 88 val result = writer.write() 89 val reader = ResultReader(result, TRACE_CONFIG_REQUIRE_CHANGES) 90 Truth.assertWithMessage("Trace file exists ${traceMonitor.traceType}") 91 .that(reader.hasTraceFile(traceMonitor.traceType)) 92 .isTrue() 93 94 val trace = 95 reader.readBytes(traceMonitor.traceType) 96 ?: error("Missing trace file ${traceMonitor.traceType}") 97 Truth.assertWithMessage("Trace file has data").that(trace.size).isGreaterThan(0) 98 assertTrace(trace) 99 } 100 validateTracenull101 private fun validateTrace(dump: DeviceTraceDump) { 102 Truth.assertWithMessage("Could not obtain SF trace") 103 .that(dump.layersTrace?.entries ?: emptyArray()) 104 .asList() 105 .isNotEmpty() 106 Truth.assertWithMessage("Could not obtain WM trace") 107 .that(dump.wmTrace?.entries ?: emptyArray()) 108 .asList() 109 .isNotEmpty() 110 } 111 112 @Test withTracingnull113 fun withTracing() { 114 val trace = withTracing { 115 device.pressHome() 116 device.pressRecentApps() 117 } 118 119 this.validateTrace(trace) 120 } 121 122 @Test recordTracesnull123 fun recordTraces() { 124 val trace = recordTraces { 125 device.pressHome() 126 device.pressRecentApps() 127 } 128 129 val dump = DeviceDumpParser.fromTrace(trace.first, trace.second, clearCache = true) 130 this.validateTrace(dump) 131 } 132 133 companion object { 134 @ClassRule @JvmField val ENV_CLEANUP = CleanFlickerEnvironmentRule() 135 } 136 } 137