Add a status checker for activity on top
Check that activity on top is the home launcher and not
some left over activity from previous tests.
Test: unit tests
Bug: 64713262
Change-Id: Iafd34881370a3f5104439598c89f466d22351bd1
diff --git a/src/com/android/tradefed/suite/checker/ActivityStatusChecker.java b/src/com/android/tradefed/suite/checker/ActivityStatusChecker.java
new file mode 100644
index 0000000..4a66304
--- /dev/null
+++ b/src/com/android/tradefed/suite/checker/ActivityStatusChecker.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.tradefed.suite.checker;
+
+import com.android.tradefed.device.DeviceNotAvailableException;
+import com.android.tradefed.device.ITestDevice;
+import com.android.tradefed.log.ITestLogger;
+import com.android.tradefed.log.LogUtil.CLog;
+import com.android.tradefed.result.ITestLoggerReceiver;
+import com.android.tradefed.result.InputStreamSource;
+import com.android.tradefed.result.LogDataType;
+import com.android.tradefed.util.StreamUtil;
+
+/** Status checker for left over activities running at the end of a module. */
+public class ActivityStatusChecker implements ISystemStatusChecker, ITestLoggerReceiver {
+
+ private ITestLogger mLogger;
+
+ @Override
+ public boolean postExecutionCheck(ITestDevice device) throws DeviceNotAvailableException {
+ return isFrontActivityLauncher(device);
+ }
+
+ private boolean isFrontActivityLauncher(ITestDevice device) throws DeviceNotAvailableException {
+ String output =
+ device.executeShellCommand(
+ "dumpsys window windows | grep -E 'mCurrentFocus|mFocusedApp'");
+ CLog.d("dumpsys window windows: %s", output);
+ if (output.contains("Launcher")) {
+ return true;
+ } else {
+ InputStreamSource screen = device.getScreenshot("JPEG");
+ try {
+ mLogger.testLog("status_checker_front_activity", LogDataType.JPEG, screen);
+ } finally {
+ StreamUtil.cancel(screen);
+ }
+ // TODO: Add a step to return to home page, or refresh the device (reboot?)
+ return false;
+ }
+ }
+
+ @Override
+ public void setTestLogger(ITestLogger testLogger) {
+ mLogger = testLogger;
+ }
+}
diff --git a/src/com/android/tradefed/testtype/suite/ITestSuite.java b/src/com/android/tradefed/testtype/suite/ITestSuite.java
index 7949afb..45db8cf 100644
--- a/src/com/android/tradefed/testtype/suite/ITestSuite.java
+++ b/src/com/android/tradefed/testtype/suite/ITestSuite.java
@@ -26,6 +26,7 @@
import com.android.tradefed.invoker.IInvocationContext;
import com.android.tradefed.log.LogUtil.CLog;
import com.android.tradefed.result.ITestInvocationListener;
+import com.android.tradefed.result.ITestLoggerReceiver;
import com.android.tradefed.result.InputStreamSource;
import com.android.tradefed.result.LogDataType;
import com.android.tradefed.suite.checker.ISystemStatusChecker;
@@ -193,6 +194,13 @@
return;
}
+ // Allow checkers to log files for easier debbuging.
+ for (ISystemStatusChecker checker : mSystemStatusCheckers) {
+ if (checker instanceof ITestLoggerReceiver) {
+ ((ITestLoggerReceiver) checker).setTestLogger(listener);
+ }
+ }
+
/** Setup a special listener to take actions on test failures. */
TestFailureListener failureListener =
new TestFailureListener(
diff --git a/tests/src/com/android/tradefed/UnitTests.java b/tests/src/com/android/tradefed/UnitTests.java
index 7c52eb3..4d88011 100644
--- a/tests/src/com/android/tradefed/UnitTests.java
+++ b/tests/src/com/android/tradefed/UnitTests.java
@@ -99,6 +99,7 @@
import com.android.tradefed.sandbox.SandboxConfigDumpTest;
import com.android.tradefed.sandbox.SandboxConfigUtilTest;
import com.android.tradefed.sandbox.TradefedSandboxTest;
+import com.android.tradefed.suite.checker.ActivityStatusCheckerTest;
import com.android.tradefed.suite.checker.KeyguardStatusCheckerTest;
import com.android.tradefed.suite.checker.SystemServerFileDescriptorCheckerTest;
import com.android.tradefed.suite.checker.SystemServerStatusCheckerTest;
@@ -371,6 +372,7 @@
TradefedSandboxTest.class,
// suite/checker
+ ActivityStatusCheckerTest.class,
KeyguardStatusCheckerTest.class,
SystemServerFileDescriptorCheckerTest.class,
SystemServerStatusCheckerTest.class,
diff --git a/tests/src/com/android/tradefed/suite/checker/ActivityStatusCheckerTest.java b/tests/src/com/android/tradefed/suite/checker/ActivityStatusCheckerTest.java
new file mode 100644
index 0000000..cf7a085
--- /dev/null
+++ b/tests/src/com/android/tradefed/suite/checker/ActivityStatusCheckerTest.java
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.tradefed.suite.checker;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import com.android.tradefed.device.ITestDevice;
+import com.android.tradefed.log.ITestLogger;
+import com.android.tradefed.result.ByteArrayInputStreamSource;
+import com.android.tradefed.result.InputStreamSource;
+import com.android.tradefed.result.LogDataType;
+
+import org.easymock.EasyMock;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+/** Unit tests for {@link ActivityStatusChecker}. */
+@RunWith(JUnit4.class)
+public class ActivityStatusCheckerTest {
+ private ActivityStatusChecker mChecker;
+ private ITestLogger mMockLogger;
+ private ITestDevice mMockDevice;
+
+ @Before
+ public void setUp() {
+ mMockLogger = EasyMock.createStrictMock(ITestLogger.class);
+ mChecker = new ActivityStatusChecker();
+ mChecker.setTestLogger(mMockLogger);
+ mMockDevice = EasyMock.createStrictMock(ITestDevice.class);
+ }
+
+ /** Test that the status checker is a success if the home/launcher activity is on top. */
+ @Test
+ public void testCheckerLauncherHomeScreen() throws Exception {
+ EasyMock.expect(mMockDevice.executeShellCommand(EasyMock.anyObject()))
+ .andReturn(
+ " mCurrentFocus=Window{46dd15 u0 com.google.android.apps.nexuslauncher/"
+ + "com.google.android.apps.nexuslauncher.NexusLauncherActivity}\n"
+ + " mFocusedApp=AppWindowToken{37e3c39 token=Token{312ce85 ActivityRecord{a9437fc "
+ + "u0 com.google.android.apps.nexuslauncher/.NexusLauncherActivity t2}}}");
+ EasyMock.replay(mMockLogger, mMockDevice);
+ assertTrue(mChecker.postExecutionCheck(mMockDevice));
+ EasyMock.verify(mMockLogger, mMockDevice);
+ }
+
+ /** Test that if another activity is on top, then we fail the checker and take a screenshot. */
+ @Test
+ public void testCheckerOtherActivity() throws Exception {
+ EasyMock.expect(mMockDevice.executeShellCommand(EasyMock.anyObject()))
+ .andReturn(
+ "mCurrentFocus=Window{52b89df u0 com.android.chrome/org.chromium.chrome."
+ + "browser.ChromeTabbedActivity}\n"
+ + " mFocusedApp=AppWindowToken{955b485 token=Token{6bebd1b ActivityRecord{fd30b2a "
+ + "u0 com.android.chrome/org.chromium.chrome.browser.ChromeTabbedActivity t7}}}");
+ InputStreamSource fake = new ByteArrayInputStreamSource("fakedata".getBytes());
+ EasyMock.expect(mMockDevice.getScreenshot(EasyMock.anyObject())).andReturn(fake);
+ mMockLogger.testLog("status_checker_front_activity", LogDataType.JPEG, fake);
+ EasyMock.replay(mMockLogger, mMockDevice);
+ assertFalse(mChecker.postExecutionCheck(mMockDevice));
+ EasyMock.verify(mMockLogger, mMockDevice);
+ }
+}
diff --git a/tests/src/com/android/tradefed/targetprep/InstallAllTestZipAppsSetupTest.java b/tests/src/com/android/tradefed/targetprep/InstallAllTestZipAppsSetupTest.java
index daf3174..b1a50b2 100644
--- a/tests/src/com/android/tradefed/targetprep/InstallAllTestZipAppsSetupTest.java
+++ b/tests/src/com/android/tradefed/targetprep/InstallAllTestZipAppsSetupTest.java
@@ -96,7 +96,7 @@
}
@Test
- public void testGetZipFile() throws DeviceNotAvailableException, TargetSetupError {
+ public void testGetZipFile() throws TargetSetupError {
String zip = "zip";
mPrep.setTestZipName(zip);
File file = new File(zip);
@@ -108,7 +108,7 @@
}
@Test
- public void testGetZipFileDoesntExist() throws DeviceNotAvailableException, TargetSetupError {
+ public void testGetZipFileDoesntExist() throws TargetSetupError {
String zip = "zip";
mPrep.setTestZipName(zip);
EasyMock.expect(mMockBuildInfo.getFile(zip)).andReturn(null);
diff --git a/tests/src/com/android/tradefed/testtype/suite/ITestSuiteTest.java b/tests/src/com/android/tradefed/testtype/suite/ITestSuiteTest.java
index f16714a..9eaadf3 100644
--- a/tests/src/com/android/tradefed/testtype/suite/ITestSuiteTest.java
+++ b/tests/src/com/android/tradefed/testtype/suite/ITestSuiteTest.java
@@ -257,6 +257,9 @@
*/
@Test
public void testRun_rebootBeforeModule() throws Exception {
+ List<ISystemStatusChecker> sysChecker = new ArrayList<ISystemStatusChecker>();
+ sysChecker.add(mMockSysChecker);
+ mTestSuite.setSystemStatusChecker(sysChecker);
OptionSetter setter = new OptionSetter(mTestSuite);
setter.setOptionValue("skip-all-system-status-check", "true");
setter.setOptionValue("reboot-per-module", "true");
@@ -275,6 +278,8 @@
*/
@Test
public void testRun_unresponsiveDevice() throws Exception {
+ List<ISystemStatusChecker> sysChecker = new ArrayList<ISystemStatusChecker>();
+ sysChecker.add(mMockSysChecker);
mTestSuite =
new TestSuiteImpl() {
@Override
@@ -297,6 +302,7 @@
mTestSuite.setDevice(mMockDevice);
mTestSuite.setBuild(mMockBuildInfo);
mTestSuite.setInvocationContext(mContext);
+ mTestSuite.setSystemStatusChecker(sysChecker);
OptionSetter setter = new OptionSetter(mTestSuite);
setter.setOptionValue("skip-all-system-status-check", "true");
setter.setOptionValue("reboot-per-module", "true");
@@ -317,6 +323,8 @@
*/
@Test
public void testRun_runtimeException() throws Exception {
+ List<ISystemStatusChecker> sysChecker = new ArrayList<ISystemStatusChecker>();
+ sysChecker.add(mMockSysChecker);
mTestSuite =
new TestSuiteImpl() {
@Override
@@ -336,6 +344,7 @@
return testConfig;
}
};
+ mTestSuite.setSystemStatusChecker(sysChecker);
mTestSuite.setDevice(mMockDevice);
mTestSuite.setBuild(mMockBuildInfo);
mTestSuite.setInvocationContext(mContext);