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.monitors
18 
19 import android.app.Instrumentation
20 import android.tools.Tag
21 import android.tools.io.RunStatus
22 import android.tools.io.TraceType
23 import android.tools.traces.TRACE_CONFIG_REQUIRE_CHANGES
24 import android.tools.traces.deleteIfExists
25 import android.tools.traces.io.ResultReader
26 import android.tools.traces.monitors.TraceMonitor
27 import android.tools.utils.CleanFlickerEnvironmentRule
28 import android.tools.utils.newTestResultWriter
29 import android.tools.utils.outputFileName
30 import androidx.test.platform.app.InstrumentationRegistry
31 import androidx.test.uiautomator.UiDevice
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 open val tag = Tag.ALL
44     protected val instrumentation: Instrumentation = InstrumentationRegistry.getInstrumentation()
45     protected val device: UiDevice = UiDevice.getInstance(instrumentation)
46     protected val traceMonitor by lazy { getMonitor() }
47 
48     @Before
beforenull49     fun before() {
50         Truth.assertWithMessage("Trace already enabled before starting test")
51             .that(traceMonitor.isEnabled)
52             .isFalse()
53     }
54 
55     @After
teardownnull56     fun teardown() {
57         device.pressHome()
58         if (traceMonitor.isEnabled) {
59             traceMonitor.stop(newTestResultWriter())
60         }
61         outputFileName(RunStatus.RUN_EXECUTED).deleteIfExists()
62         Truth.assertWithMessage("Failed to disable trace at end of test")
63             .that(traceMonitor.isEnabled)
64             .isFalse()
65     }
66 
67     @Test
68     @Throws(Exception::class)
canStartTracenull69     fun canStartTrace() {
70         traceMonitor.start()
71         Truth.assertThat(traceMonitor.isEnabled).isTrue()
72     }
73 
74     @Test
75     @Throws(Exception::class)
canStopTracenull76     fun canStopTrace() {
77         traceMonitor.start()
78         Truth.assertThat(traceMonitor.isEnabled).isTrue()
79         traceMonitor.stop(newTestResultWriter())
80         Truth.assertThat(traceMonitor.isEnabled).isFalse()
81     }
82 
83     @Test
84     @Throws(Exception::class)
captureTracenull85     open fun captureTrace() {
86         traceMonitor.start()
87         device.pressHome()
88         device.pressRecentApps()
89         val writer = newTestResultWriter()
90         traceMonitor.stop(writer)
91         val result = writer.write()
92         val reader = ResultReader(result, TRACE_CONFIG_REQUIRE_CHANGES)
93         Truth.assertWithMessage("Trace file exists ${traceMonitor.traceType}")
94             .that(reader.hasTraceFile(traceMonitor.traceType, tag))
95             .isTrue()
96 
97         val trace =
98             reader.readBytes(traceMonitor.traceType, tag)
99                 ?: error("Missing trace file ${traceMonitor.traceType}")
100         Truth.assertWithMessage("Trace file size").that(trace.size).isGreaterThan(0)
101         assertTrace(trace)
102     }
103 
104     @Test
withTracingnull105     open fun withTracing() {
106         val trace =
107             traceMonitor.withTracing(tag) {
108                 device.pressHome()
109                 device.pressRecentApps()
110             }
111 
112         assertTrace(trace)
113     }
114 
115     companion object {
116         @ClassRule @JvmField val ENV_CLEANUP = CleanFlickerEnvironmentRule()
117     }
118 }
119