1 /*
2  * Copyright (C) 2024 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.flicker.legacy
18 
19 import android.annotation.SuppressLint
20 import android.tools.CleanFlickerEnvironmentRuleWithDataStore
21 import android.tools.ScenarioBuilder
22 import android.tools.flicker.assertions.FlickerTest
23 import android.tools.flicker.datastore.CachedResultReader
24 import android.tools.flicker.datastore.DataStore
25 import android.tools.io.TraceType
26 import android.tools.newTestCachedResultWriter
27 import android.tools.traces.TRACE_CONFIG_REQUIRE_CHANGES
28 import android.tools.traces.io.ResultReader
29 import android.tools.utils.TEST_SCENARIO
30 import android.tools.utils.TestTraces
31 import android.tools.utils.assertExceptionMessage
32 import android.tools.utils.assertThrows
33 import com.google.common.truth.Truth
34 import java.io.File
35 import kotlin.io.path.name
36 import org.junit.Before
37 import org.junit.Rule
38 import org.junit.Test
39 
40 /** Tests for [FlickerTest] */
41 @SuppressLint("VisibleForTests")
42 class LegacyFlickerTestTest {
43     private var executionCount = 0
44     @Rule @JvmField val envCleanup = CleanFlickerEnvironmentRuleWithDataStore()
45 
46     @Before
setupnull47     fun setup() {
48         executionCount = 0
49     }
50 
51     @Test
failsWithoutScenarionull52     fun failsWithoutScenario() {
53         val actual = LegacyFlickerTest()
54         val failure =
55             assertThrows<IllegalArgumentException> { actual.assertLayers { executionCount++ } }
56         assertExceptionMessage(failure, "Scenario shouldn't be empty")
57         Truth.assertWithMessage("Executed").that(executionCount).isEqualTo(0)
58     }
59 
60     @Test
executesLayersnull61     fun executesLayers() {
62         val predicate: (FlickerTest) -> Unit = { it.assertLayers { executionCount++ } }
63         doWriteTraceExecuteAssertionAndVerify(
64             TraceType.SF,
65             predicate,
66             TestTraces.LayerTrace.FILE,
67             expectedExecutionCount = 2
68         )
69     }
70 
71     @Test
executesLayerStartnull72     fun executesLayerStart() {
73         val predicate: (FlickerTest) -> Unit = { it.assertLayersStart { executionCount++ } }
74         doWriteTraceExecuteAssertionAndVerify(
75             TraceType.SF,
76             predicate,
77             TestTraces.LayerTrace.FILE,
78             expectedExecutionCount = 2
79         )
80     }
81 
82     @Test
executesLayerEndnull83     fun executesLayerEnd() {
84         val predicate: (FlickerTest) -> Unit = { it.assertLayersEnd { executionCount++ } }
85         doWriteTraceExecuteAssertionAndVerify(
86             TraceType.SF,
87             predicate,
88             TestTraces.LayerTrace.FILE,
89             expectedExecutionCount = 2
90         )
91     }
92 
93     @Test
doesNotExecuteLayersWithoutTracenull94     fun doesNotExecuteLayersWithoutTrace() {
95         val predicate: (FlickerTest) -> Unit = { it.assertLayers { executionCount++ } }
96         doExecuteAssertionWithoutTraceAndVerifyNotExecuted(TraceType.SF, predicate)
97     }
98 
99     @Test
doesNotExecuteLayersStartWithoutTracenull100     fun doesNotExecuteLayersStartWithoutTrace() {
101         val predicate: (FlickerTest) -> Unit = { it.assertLayersStart { executionCount++ } }
102         doExecuteAssertionWithoutTraceAndVerifyNotExecuted(TraceType.SF, predicate)
103     }
104 
105     @Test
doesNotExecuteLayersEndWithoutTracenull106     fun doesNotExecuteLayersEndWithoutTrace() {
107         val predicate: (FlickerTest) -> Unit = { it.assertLayersEnd { executionCount++ } }
108         doExecuteAssertionWithoutTraceAndVerifyNotExecuted(TraceType.SF, predicate)
109     }
110 
111     @Test
doesNotExecuteLayerTagWithoutTagnull112     fun doesNotExecuteLayerTagWithoutTag() {
113         val predicate: (FlickerTest) -> Unit = { it.assertLayersTag("tag") { executionCount++ } }
114         doExecuteAssertionWithoutTraceAndVerifyNotExecuted(TraceType.SF, predicate)
115     }
116 
117     @Test
executesWmnull118     fun executesWm() {
119         val predicate: (FlickerTest) -> Unit = { it.assertWm { executionCount++ } }
120         doWriteTraceExecuteAssertionAndVerify(
121             TraceType.WM,
122             predicate,
123             TestTraces.WMTrace.FILE,
124             expectedExecutionCount = 2
125         )
126     }
127 
128     @Test
executesWmStartnull129     fun executesWmStart() {
130         val predicate: (FlickerTest) -> Unit = { it.assertWmStart { executionCount++ } }
131         doWriteTraceExecuteAssertionAndVerify(
132             TraceType.WM,
133             predicate,
134             TestTraces.WMTrace.FILE,
135             expectedExecutionCount = 2
136         )
137     }
138 
139     @Test
executesWmEndnull140     fun executesWmEnd() {
141         val predicate: (FlickerTest) -> Unit = { it.assertWmEnd { executionCount++ } }
142         doWriteTraceExecuteAssertionAndVerify(
143             TraceType.WM,
144             predicate,
145             TestTraces.WMTrace.FILE,
146             expectedExecutionCount = 2
147         )
148     }
149 
150     @Test
doesNotExecuteWmWithoutTracenull151     fun doesNotExecuteWmWithoutTrace() {
152         val predicate: (FlickerTest) -> Unit = { it.assertWm { executionCount++ } }
153         doExecuteAssertionWithoutTraceAndVerifyNotExecuted(TraceType.WM, predicate)
154     }
155 
156     @Test
doesNotExecuteWmStartWithoutTracenull157     fun doesNotExecuteWmStartWithoutTrace() {
158         val predicate: (FlickerTest) -> Unit = { it.assertWmStart { executionCount++ } }
159         doExecuteAssertionWithoutTraceAndVerifyNotExecuted(TraceType.WM, predicate)
160     }
161 
162     @Test
doesNotExecuteWmEndWithoutTracenull163     fun doesNotExecuteWmEndWithoutTrace() {
164         val predicate: (FlickerTest) -> Unit = { it.assertWmEnd { executionCount++ } }
165         doExecuteAssertionWithoutTraceAndVerifyNotExecuted(TraceType.WM, predicate)
166     }
167 
168     @Test
doesNotExecuteWmTagWithoutTagnull169     fun doesNotExecuteWmTagWithoutTag() {
170         val predicate: (FlickerTest) -> Unit = { it.assertWmTag("tag") { executionCount++ } }
171         doWriteTraceExecuteAssertionAndVerify(
172             TraceType.WM,
173             predicate,
174             TestTraces.WMTrace.FILE,
175             expectedExecutionCount = 0
176         )
177     }
178 
179     @Test
executesEventLognull180     fun executesEventLog() {
181         val predicate: (FlickerTest) -> Unit = { it.assertEventLog { executionCount++ } }
182         doWriteTraceExecuteAssertionAndVerify(
183             TraceType.EVENT_LOG,
184             predicate,
185             TestTraces.EventLog.FILE,
186             expectedExecutionCount = 2
187         )
188     }
189 
190     @Test
doesNotExecuteEventLogWithoutEventLognull191     fun doesNotExecuteEventLogWithoutEventLog() {
192         val predicate: (FlickerTest) -> Unit = { it.assertEventLog { executionCount++ } }
193         val scenarioName = kotlin.io.path.createTempFile().name
194         val scenario = ScenarioBuilder().forClass(scenarioName).build()
195         newTestCachedResultWriter(scenario).write()
196         val flickerWrapper = LegacyFlickerTest()
197         flickerWrapper.initialize(scenarioName)
198         // Each assertion is executed independently and not cached, only Flicker as a Service
199         // assertions are cached
200         predicate.invoke(flickerWrapper)
201         predicate.invoke(flickerWrapper)
202 
203         Truth.assertWithMessage("Executed").that(executionCount).isEqualTo(0)
204     }
205 
doExecuteAssertionWithoutTraceAndVerifyNotExecutednull206     private fun doExecuteAssertionWithoutTraceAndVerifyNotExecuted(
207         traceType: TraceType,
208         predicate: (FlickerTest) -> Unit
209     ) =
210         doWriteTraceExecuteAssertionAndVerify(
211             traceType,
212             predicate,
213             file = null,
214             expectedExecutionCount = 0
215         )
216 
217     private fun doWriteTraceExecuteAssertionAndVerify(
218         traceType: TraceType,
219         predicate: (FlickerTest) -> Unit,
220         file: File?,
221         expectedExecutionCount: Int
222     ) {
223         val writer = newTestCachedResultWriter()
224         if (file != null) {
225             writer.addTraceResult(traceType, file)
226         }
227         writer.write()
228         val flickerWrapper =
229             LegacyFlickerTest(
230                 resultReaderProvider = {
231                     android.tools.flicker.datastore.CachedResultReader(
232                         it,
233                         TRACE_CONFIG_REQUIRE_CHANGES,
234                         reader =
235                             ResultReader(
236                                 android.tools.flicker.datastore.DataStore.getResult(it),
237                                 TRACE_CONFIG_REQUIRE_CHANGES
238                             )
239                     )
240                 }
241             )
242         flickerWrapper.initialize(TEST_SCENARIO.testClass)
243         // Each assertion is executed independently and not cached, only Flicker as a Service
244         // assertions are cached
245         predicate.invoke(flickerWrapper)
246         predicate.invoke(flickerWrapper)
247 
248         Truth.assertWithMessage("Executed").that(executionCount).isEqualTo(expectedExecutionCount)
249     }
250 }
251