1 /* 2 * Copyright (C) 2018 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 com.android.server.wm.flicker; 18 19 import static com.google.common.truth.Truth.assertThat; 20 21 import static org.mockito.Mockito.doReturn; 22 import static org.mockito.Mockito.inOrder; 23 import static org.mockito.Mockito.times; 24 import static org.mockito.Mockito.verify; 25 import static org.mockito.Mockito.verifyNoMoreInteractions; 26 27 import android.os.Environment; 28 29 import androidx.test.runner.AndroidJUnit4; 30 31 import com.android.server.wm.flicker.TransitionRunner.TransitionBuilder; 32 import com.android.server.wm.flicker.TransitionRunner.TransitionResult; 33 import com.android.server.wm.flicker.monitor.LayersTraceMonitor; 34 import com.android.server.wm.flicker.monitor.ScreenRecorder; 35 import com.android.server.wm.flicker.monitor.WindowAnimationFrameStatsMonitor; 36 import com.android.server.wm.flicker.monitor.WindowManagerTraceMonitor; 37 38 import org.junit.Before; 39 import org.junit.FixMethodOrder; 40 import org.junit.Test; 41 import org.junit.runner.RunWith; 42 import org.junit.runners.MethodSorters; 43 import org.mockito.InOrder; 44 import org.mockito.InjectMocks; 45 import org.mockito.Mock; 46 import org.mockito.MockitoAnnotations; 47 48 import java.nio.file.Paths; 49 import java.util.List; 50 51 /** Contains {@link TransitionRunner} tests. {@code atest FlickerLibTest:TransitionRunnerTest} */ 52 @RunWith(AndroidJUnit4.class) 53 @FixMethodOrder(MethodSorters.NAME_ASCENDING) 54 public class TransitionRunnerTest { 55 @Mock private SimpleUiTransitions mTransitionsMock; 56 @Mock private ScreenRecorder mScreenRecorderMock; 57 @Mock private WindowManagerTraceMonitor mWindowManagerTraceMonitorMock; 58 @Mock private LayersTraceMonitor mLayersTraceMonitorMock; 59 @Mock private WindowAnimationFrameStatsMonitor mWindowAnimationFrameStatsMonitor; 60 @InjectMocks private TransitionBuilder mTransitionBuilder = TransitionRunner.newBuilder(); 61 62 @Before init()63 public void init() { 64 MockitoAnnotations.initMocks(this); 65 } 66 67 @Test transitionsRunInOrder()68 public void transitionsRunInOrder() { 69 TransitionRunner.newBuilder() 70 .runBeforeAll(mTransitionsMock::turnOnDevice) 71 .runBefore(mTransitionsMock::openApp) 72 .run(mTransitionsMock::performMagic) 73 .runAfter(mTransitionsMock::closeApp) 74 .runAfterAll(mTransitionsMock::cleanUpTracks) 75 .skipLayersTrace() 76 .skipWindowManagerTrace() 77 .build() 78 .run(); 79 80 InOrder orderVerifier = inOrder(mTransitionsMock); 81 orderVerifier.verify(mTransitionsMock).turnOnDevice(); 82 orderVerifier.verify(mTransitionsMock).openApp(); 83 orderVerifier.verify(mTransitionsMock).performMagic(); 84 orderVerifier.verify(mTransitionsMock).closeApp(); 85 orderVerifier.verify(mTransitionsMock).cleanUpTracks(); 86 } 87 88 @Test canCombineTransitions()89 public void canCombineTransitions() { 90 TransitionRunner.newBuilder() 91 .runBeforeAll(mTransitionsMock::turnOnDevice) 92 .runBeforeAll(mTransitionsMock::turnOnDevice) 93 .runBefore(mTransitionsMock::openApp) 94 .runBefore(mTransitionsMock::openApp) 95 .run(mTransitionsMock::performMagic) 96 .run(mTransitionsMock::performMagic) 97 .runAfter(mTransitionsMock::closeApp) 98 .runAfter(mTransitionsMock::closeApp) 99 .runAfterAll(mTransitionsMock::cleanUpTracks) 100 .runAfterAll(mTransitionsMock::cleanUpTracks) 101 .skipLayersTrace() 102 .skipWindowManagerTrace() 103 .build() 104 .run(); 105 106 final int wantedNumberOfInvocations = 2; 107 verify(mTransitionsMock, times(wantedNumberOfInvocations)).turnOnDevice(); 108 verify(mTransitionsMock, times(wantedNumberOfInvocations)).openApp(); 109 verify(mTransitionsMock, times(wantedNumberOfInvocations)).performMagic(); 110 verify(mTransitionsMock, times(wantedNumberOfInvocations)).closeApp(); 111 verify(mTransitionsMock, times(wantedNumberOfInvocations)).cleanUpTracks(); 112 } 113 114 @Test emptyTransitionPasses()115 public void emptyTransitionPasses() { 116 List<TransitionResult> results = 117 TransitionRunner.newBuilder() 118 .skipLayersTrace() 119 .skipWindowManagerTrace() 120 .build() 121 .run() 122 .getResults(); 123 assertThat(results).hasSize(1); 124 assertThat(results.get(0).layersTraceExists()).isFalse(); 125 assertThat(results.get(0).windowManagerTraceExists()).isFalse(); 126 assertThat(results.get(0).screenCaptureVideoExists()).isFalse(); 127 } 128 129 @Test canRepeatTransitions()130 public void canRepeatTransitions() { 131 final int wantedNumberOfInvocations = 10; 132 TransitionRunner.newBuilder() 133 .runBeforeAll(mTransitionsMock::turnOnDevice) 134 .runBefore(mTransitionsMock::openApp) 135 .run(mTransitionsMock::performMagic) 136 .runAfter(mTransitionsMock::closeApp) 137 .runAfterAll(mTransitionsMock::cleanUpTracks) 138 .repeat(wantedNumberOfInvocations) 139 .skipLayersTrace() 140 .skipWindowManagerTrace() 141 .build() 142 .run(); 143 verify(mTransitionsMock).turnOnDevice(); 144 verify(mTransitionsMock, times(wantedNumberOfInvocations)).openApp(); 145 verify(mTransitionsMock, times(wantedNumberOfInvocations)).performMagic(); 146 verify(mTransitionsMock, times(wantedNumberOfInvocations)).closeApp(); 147 verify(mTransitionsMock).cleanUpTracks(); 148 } 149 emptyTask()150 private void emptyTask() {} 151 152 @Test canCaptureWindowManagerTrace()153 public void canCaptureWindowManagerTrace() { 154 mTransitionBuilder 155 .run(this::emptyTask) 156 .includeJankyRuns() 157 .skipLayersTrace() 158 .withTag("mCaptureWmTraceTransitionRunner") 159 .build() 160 .run(); 161 InOrder orderVerifier = inOrder(mWindowManagerTraceMonitorMock); 162 orderVerifier.verify(mWindowManagerTraceMonitorMock).start(); 163 orderVerifier.verify(mWindowManagerTraceMonitorMock).stop(); 164 orderVerifier 165 .verify(mWindowManagerTraceMonitorMock) 166 .save("mCaptureWmTraceTransitionRunner", 0); 167 orderVerifier.verify(mWindowManagerTraceMonitorMock).getChecksum(); 168 verifyNoMoreInteractions(mWindowManagerTraceMonitorMock); 169 } 170 171 @Test canCaptureLayersTrace()172 public void canCaptureLayersTrace() { 173 mTransitionBuilder 174 .run(this::emptyTask) 175 .includeJankyRuns() 176 .skipWindowManagerTrace() 177 .withTag("mCaptureLayersTraceTransitionRunner") 178 .build() 179 .run(); 180 InOrder orderVerifier = inOrder(mLayersTraceMonitorMock); 181 orderVerifier.verify(mLayersTraceMonitorMock).start(); 182 orderVerifier.verify(mLayersTraceMonitorMock).stop(); 183 orderVerifier 184 .verify(mLayersTraceMonitorMock) 185 .save("mCaptureLayersTraceTransitionRunner", 0); 186 orderVerifier.verify(mLayersTraceMonitorMock).getChecksum(); 187 verifyNoMoreInteractions(mLayersTraceMonitorMock); 188 } 189 190 @Test canRecordEachRun()191 public void canRecordEachRun() { 192 mTransitionBuilder 193 .run(this::emptyTask) 194 .withTag("mRecordEachRun") 195 .recordEachRun() 196 .includeJankyRuns() 197 .skipLayersTrace() 198 .skipWindowManagerTrace() 199 .repeat(2) 200 .build() 201 .run(); 202 InOrder orderVerifier = inOrder(mScreenRecorderMock); 203 orderVerifier.verify(mScreenRecorderMock).start(); 204 orderVerifier.verify(mScreenRecorderMock).stop(); 205 orderVerifier.verify(mScreenRecorderMock).save("mRecordEachRun", 0); 206 orderVerifier.verify(mScreenRecorderMock).getChecksum(); 207 orderVerifier.verify(mScreenRecorderMock).start(); 208 orderVerifier.verify(mScreenRecorderMock).stop(); 209 orderVerifier.verify(mScreenRecorderMock).save("mRecordEachRun", 1); 210 orderVerifier.verify(mScreenRecorderMock).getChecksum(); 211 verifyNoMoreInteractions(mScreenRecorderMock); 212 } 213 214 @Test canRecordAllRuns()215 public void canRecordAllRuns() { 216 doReturn( 217 Paths.get( 218 Environment.getExternalStorageDirectory().getAbsolutePath(), 219 "mRecordAllRuns.mp4")) 220 .when(mScreenRecorderMock) 221 .save("mRecordAllRuns"); 222 mTransitionBuilder 223 .run(this::emptyTask) 224 .recordAllRuns() 225 .includeJankyRuns() 226 .skipLayersTrace() 227 .skipWindowManagerTrace() 228 .withTag("mRecordAllRuns") 229 .repeat(2) 230 .build() 231 .run(); 232 InOrder orderVerifier = inOrder(mScreenRecorderMock); 233 orderVerifier.verify(mScreenRecorderMock).start(); 234 orderVerifier.verify(mScreenRecorderMock).stop(); 235 orderVerifier.verify(mScreenRecorderMock).save("mRecordAllRuns"); 236 verifyNoMoreInteractions(mScreenRecorderMock); 237 } 238 239 @Test canSkipJankyRuns()240 public void canSkipJankyRuns() { 241 doReturn(false) 242 .doReturn(true) 243 .doReturn(false) 244 .when(mWindowAnimationFrameStatsMonitor) 245 .jankyFramesDetected(); 246 List<TransitionResult> results = 247 mTransitionBuilder 248 .run(this::emptyTask) 249 .skipLayersTrace() 250 .skipWindowManagerTrace() 251 .repeat(3) 252 .build() 253 .run() 254 .getResults(); 255 assertThat(results).hasSize(2); 256 } 257 258 public static class SimpleUiTransitions { turnOnDevice()259 public void turnOnDevice() {} 260 openApp()261 public void openApp() {} 262 performMagic()263 public void performMagic() {} 264 closeApp()265 public void closeApp() {} 266 cleanUpTracks()267 public void cleanUpTracks() {} 268 } 269 } 270