• Home
  • History
  • Annotate
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.integration
18  
19  import android.app.Instrumentation
20  import android.graphics.Region
21  import android.platform.test.annotations.Presubmit
22  import android.tools.Scenario
23  import android.tools.device.apphelpers.MessagingAppHelper
24  import android.tools.flicker.annotation.FlickerServiceCompatible
25  import android.tools.flicker.junit.FlickerBuilderProvider
26  import android.tools.flicker.junit.FlickerParametersRunnerFactory
27  import android.tools.flicker.legacy.FlickerBuilder
28  import android.tools.flicker.legacy.LegacyFlickerTest
29  import android.tools.flicker.legacy.LegacyFlickerTestFactory
30  import android.tools.flicker.subject.FlickerSubject
31  import android.tools.flicker.subject.layers.LayersTraceSubject
32  import android.tools.flicker.subject.region.RegionSubject
33  import android.tools.flicker.subject.wm.WindowManagerTraceSubject
34  import android.tools.io.RunStatus
35  import android.tools.traces.parsers.WindowManagerStateHelper
36  import androidx.test.platform.app.InstrumentationRegistry
37  import com.android.launcher3.tapl.LauncherInstrumentation
38  import com.google.common.truth.Truth
39  import org.junit.Test
40  import org.junit.runner.RunWith
41  import org.junit.runners.Parameterized
42  
43  @FlickerServiceCompatible(expectedCujs = ["ENTIRE_TRACE"])
44  @RunWith(Parameterized::class)
45  @Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
46  class FullLegacyTestRun(private val flicker: LegacyFlickerTest) {
47      private val instrumentation: Instrumentation = InstrumentationRegistry.getInstrumentation()
48      private val testApp = MessagingAppHelper(instrumentation)
49      private val tapl: LauncherInstrumentation = LauncherInstrumentation()
50  
51      init {
52          flicker.scenario.setIsTablet(
53              WindowManagerStateHelper(instrumentation, clearCacheAfterParsing = false)
54                  .currentState
55                  .wmState
56                  .isTablet
57          )
58          tapl.setExpectedRotationCheckEnabled(true)
59      }
60  
61      /**
62       * Entry point for the test runner. It will use this method to initialize and cache flicker
63       * executions
64       */
65      @FlickerBuilderProvider
buildFlickernull66      fun buildFlicker(): FlickerBuilder {
67          return FlickerBuilder(instrumentation).apply {
68              setup { flicker.scenario.setIsTablet(wmHelper.currentState.wmState.isTablet) }
69              teardown { testApp.exit(wmHelper) }
70              transitions { testApp.launchViaIntent(wmHelper) }
71          }
72      }
73  
74      /**
75       * This is a shel test from the flicker infra to ensure the WM tracing pipeline executed
76       * entirely executed correctly
77       */
78      @Presubmit
79      @Test
internalWmChecknull80      fun internalWmCheck() {
81          var trace: WindowManagerTraceSubject? = null
82          var executionCount = 0
83          flicker.assertWm {
84              executionCount++
85              trace = this
86              this.isNotEmpty()
87          }
88          flicker.assertWm {
89              executionCount++
90              val failure: Result<Any> = runCatching { this.isEmpty() }
91              if (failure.isSuccess) {
92                  error("Should have thrown failure")
93              }
94          }
95          flicker.assertWmStart {
96              executionCount++
97              validateState(this, trace?.first())
98              validateVisibleRegion(this.visibleRegion(), trace?.first()?.visibleRegion())
99          }
100          flicker.assertWmEnd {
101              executionCount++
102              validateState(this, trace?.last())
103              validateVisibleRegion(this.visibleRegion(), trace?.last()?.visibleRegion())
104          }
105          Truth.assertWithMessage("Execution count").that(executionCount).isEqualTo(4)
106      }
107  
108      /**
109       * This is a shel test from the flicker infra to ensure the Layers tracing pipeline executed
110       * entirely executed correctly
111       */
112      @Presubmit
113      @Test
internalLayersChecknull114      fun internalLayersCheck() {
115          var trace: LayersTraceSubject? = null
116          var executionCount = 0
117          flicker.assertLayers {
118              executionCount++
119              trace = this
120              this.isNotEmpty()
121          }
122          flicker.assertLayers {
123              executionCount++
124              val failure: Result<Any> = runCatching { this.isEmpty() }
125              if (failure.isSuccess) {
126                  error("Should have thrown failure")
127              }
128          }
129          flicker.assertLayersStart {
130              executionCount++
131              validateState(this, trace?.first())
132              validateVisibleRegion(this.visibleRegion(), trace?.first()?.visibleRegion())
133          }
134          flicker.assertLayersEnd {
135              executionCount++
136              validateState(this, trace?.last())
137              validateVisibleRegion(this.visibleRegion(), trace?.last()?.visibleRegion())
138          }
139          Truth.assertWithMessage("Execution count").that(executionCount).isEqualTo(4)
140      }
141  
142      @Presubmit
143      @Test
exceptionMessageChecknull144      fun exceptionMessageCheck() {
145          val failure: Result<Any> = runCatching { flicker.assertLayers { this.isEmpty() } }
146          val exception = failure.exceptionOrNull() ?: error("Should have thrown failure")
147          Truth.assertWithMessage("Artifact path on exception")
148              .that(exception)
149              .hasMessageThat()
150              .contains(RunStatus.ASSERTION_FAILED.prefix)
151      }
152  
validateStatenull153      private fun validateState(actual: FlickerSubject?, expected: FlickerSubject?) {
154          Truth.assertWithMessage("Actual state").that(actual).isNotNull()
155          Truth.assertWithMessage("Expected state").that(expected).isNotNull()
156      }
157  
validateVisibleRegionnull158      private fun validateVisibleRegion(
159          actual: RegionSubject?,
160          expected: RegionSubject?,
161      ) {
162          Truth.assertWithMessage("Actual visible region").that(actual).isNotNull()
163          Truth.assertWithMessage("Expected visible region").that(expected).isNotNull()
164          actual?.coversExactly(expected?.region ?: Region())
165  
166          val failure: Result<Any?> = runCatching { actual?.isHigher(expected?.region ?: Region()) }
167          if (failure.isSuccess) {
168              error("Should have thrown failure")
169          }
170      }
171  
172      companion object {
173          /**
174           * Creates the test configurations.
175           *
176           * See [LegacyFlickerTestFactory.nonRotationTests] for configuring screen orientation and
177           * navigation modes.
178           */
179          @Parameterized.Parameters(name = "{0}")
180          @JvmStatic
getParamsnull181          fun getParams() =
182              LegacyFlickerTestFactory.nonRotationTests(
183                  extraArgs = mapOf(Scenario.FAAS_BLOCKING to true)
184              )
185      }
186  }
187