From 137f5b62accb622bc3ff50bf7ed84c35dc35197f Mon Sep 17 00:00:00 2001 From: vadimt Date: Mon, 4 Nov 2019 14:50:22 -0800 Subject: [PATCH] Improve diags when system errors cause failing Launcher tests Now, for example, we won't diagnose a locked phone as a "home button not showing in 3-button mode", even though it's technically correct. Change-Id: Ibdfa0741af7ff8545a811f6702dda74dc6c31c2e --- .../quickstep/FallbackRecentsTest.java | 7 ++-- .../quickstep/NavigationModeSwitchRule.java | 3 +- .../launcher3/ui/AbstractLauncherUiTest.java | 8 ++--- .../ui/widget/AddConfigWidgetTest.java | 4 +-- .../ui/widget/RequestPinItemTest.java | 10 +++--- .../src/com/android/launcher3/util/Wait.java | 11 +++++-- .../tapl/LauncherInstrumentation.java | 32 +++++++++++-------- 7 files changed, 43 insertions(+), 32 deletions(-) diff --git a/quickstep/tests/src/com/android/quickstep/FallbackRecentsTest.java b/quickstep/tests/src/com/android/quickstep/FallbackRecentsTest.java index 13731b69c4..ca813434a4 100644 --- a/quickstep/tests/src/com/android/quickstep/FallbackRecentsTest.java +++ b/quickstep/tests/src/com/android/quickstep/FallbackRecentsTest.java @@ -175,7 +175,7 @@ public class FallbackRecentsTest { } result[0] = f.apply(activity); return true; - }).get(), DEFAULT_UI_TIMEOUT); + }).get(), DEFAULT_UI_TIMEOUT, mLauncher); return (T) result[0]; } @@ -196,7 +196,7 @@ public class FallbackRecentsTest { startAppFastAndWaitForRecentTask(resolveSystemApp(Intent.CATEGORY_APP_CALCULATOR)); startTestActivity(2); Wait.atMost("Expected three apps in the task list", - () -> mLauncher.getRecentTasks().size() >= 3, DEFAULT_ACTIVITY_TIMEOUT); + () -> mLauncher.getRecentTasks().size() >= 3, DEFAULT_ACTIVITY_TIMEOUT, mLauncher); BaseOverview overview = mLauncher.getBackground().switchToOverview(); executeOnRecents(recents -> @@ -255,7 +255,8 @@ public class FallbackRecentsTest { private void startAppFastAndWaitForRecentTask(String packageName) { startAppFast(packageName); Wait.atMost("Expected app in task list", - () -> containsRecentTaskWithPackage(packageName), DEFAULT_ACTIVITY_TIMEOUT); + () -> containsRecentTaskWithPackage(packageName), DEFAULT_ACTIVITY_TIMEOUT, + mLauncher); } private boolean containsRecentTaskWithPackage(String packageName) { diff --git a/quickstep/tests/src/com/android/quickstep/NavigationModeSwitchRule.java b/quickstep/tests/src/com/android/quickstep/NavigationModeSwitchRule.java index c2197ab709..5158939383 100644 --- a/quickstep/tests/src/com/android/quickstep/NavigationModeSwitchRule.java +++ b/quickstep/tests/src/com/android/quickstep/NavigationModeSwitchRule.java @@ -80,7 +80,8 @@ public class NavigationModeSwitchRule implements TestRule { Mode mode = description.getAnnotation(NavigationModeSwitch.class).mode(); return new Statement() { private void assertTrue(String message, boolean condition) { - if(!condition) { + mLauncher.checkForAnomaly(); + if (!condition) { final AssertionError assertionError = new AssertionError(message); FailureWatcher.onError(mLauncher.getDevice(), description, assertionError); throw assertionError; diff --git a/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java b/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java index 76b5d28756..bb19515dd0 100644 --- a/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java +++ b/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java @@ -26,8 +26,6 @@ import static org.junit.Assert.assertTrue; import static java.lang.System.exit; -import static androidx.test.InstrumentationRegistry.getInstrumentation; - import android.content.BroadcastReceiver; import android.content.ComponentName; import android.content.ContentResolver; @@ -306,7 +304,7 @@ public abstract class AbstractLauncherUiTest { protected void waitForLauncherCondition( String message, Function condition, long timeout) { if (!TestHelpers.isInLauncherProcess()) return; - Wait.atMost(message, () -> getFromLauncher(condition), timeout); + Wait.atMost(message, () -> getFromLauncher(condition), timeout, mLauncher); } // Cannot be used in TaplTests after injecting any gesture using Tapl because this can hide @@ -319,7 +317,7 @@ public abstract class AbstractLauncherUiTest { final Object fromLauncher = getFromLauncher(f); output[0] = fromLauncher; return fromLauncher != null; - }, timeout); + }, timeout, mLauncher); return (T) output[0]; } @@ -333,7 +331,7 @@ public abstract class AbstractLauncherUiTest { Wait.atMost(message, () -> { testThreadAction.run(); return getFromLauncher(condition); - }, timeout); + }, timeout, mLauncher); } protected LauncherActivityInfo getSettingsApp() { diff --git a/tests/src/com/android/launcher3/ui/widget/AddConfigWidgetTest.java b/tests/src/com/android/launcher3/ui/widget/AddConfigWidgetTest.java index e1b3edeb5a..0472ce1c6f 100644 --- a/tests/src/com/android/launcher3/ui/widget/AddConfigWidgetTest.java +++ b/tests/src/com/android/launcher3/ui/widget/AddConfigWidgetTest.java @@ -103,12 +103,12 @@ public class AddConfigWidgetTest extends AbstractLauncherUiTest { setResult(acceptConfig); if (acceptConfig) { - Wait.atMost(null, new WidgetSearchCondition(), DEFAULT_ACTIVITY_TIMEOUT); + Wait.atMost(null, new WidgetSearchCondition(), DEFAULT_ACTIVITY_TIMEOUT, mLauncher); assertNotNull(mAppWidgetManager.getAppWidgetInfo(mWidgetId)); } else { // Verify that the widget id is deleted. Wait.atMost(null, () -> mAppWidgetManager.getAppWidgetInfo(mWidgetId) == null, - DEFAULT_ACTIVITY_TIMEOUT); + DEFAULT_ACTIVITY_TIMEOUT, mLauncher); } } diff --git a/tests/src/com/android/launcher3/ui/widget/RequestPinItemTest.java b/tests/src/com/android/launcher3/ui/widget/RequestPinItemTest.java index 07129ddd95..d909ad7158 100644 --- a/tests/src/com/android/launcher3/ui/widget/RequestPinItemTest.java +++ b/tests/src/com/android/launcher3/ui/widget/RequestPinItemTest.java @@ -59,7 +59,8 @@ import java.util.UUID; @RunWith(AndroidJUnit4.class) public class RequestPinItemTest extends AbstractLauncherUiTest { - @Rule public ShellCommandRule mGrantWidgetRule = ShellCommandRule.grantWidgetBind(); + @Rule + public ShellCommandRule mGrantWidgetRule = ShellCommandRule.grantWidgetBind(); private String mCallbackAction; private String mShortcutId; @@ -84,10 +85,10 @@ public class RequestPinItemTest extends AbstractLauncherUiTest { .equals(AppWidgetNoConfig.class.getName())); } - @Test + @Test public void testPinWidgetNoConfig_customPreview() throws Throwable { // Command to set custom preview - Intent command = RequestPinItemActivity.getCommandIntent( + Intent command = RequestPinItemActivity.getCommandIntent( RequestPinItemActivity.class, "setRemoteViewColor").putExtra( RequestPinItemActivity.EXTRA_PARAM + "0", Color.RED); @@ -169,7 +170,8 @@ public class RequestPinItemTest extends AbstractLauncherUiTest { // Go back to home mLauncher.pressHome(); - Wait.atMost(null, new ItemSearchCondition(itemMatcher), DEFAULT_ACTIVITY_TIMEOUT); + Wait.atMost(null, new ItemSearchCondition(itemMatcher), DEFAULT_ACTIVITY_TIMEOUT, + mLauncher); } /** diff --git a/tests/src/com/android/launcher3/util/Wait.java b/tests/src/com/android/launcher3/util/Wait.java index 899686bd61..2663d02760 100644 --- a/tests/src/com/android/launcher3/util/Wait.java +++ b/tests/src/com/android/launcher3/util/Wait.java @@ -3,6 +3,8 @@ package com.android.launcher3.util; import android.os.SystemClock; import android.util.Log; +import com.android.launcher3.tapl.LauncherInstrumentation; + import org.junit.Assert; /** @@ -12,11 +14,13 @@ public class Wait { private static final long DEFAULT_SLEEP_MS = 200; - public static void atMost(String message, Condition condition, long timeout) { - atMost(message, condition, timeout, DEFAULT_SLEEP_MS); + public static void atMost(String message, Condition condition, long timeout, + LauncherInstrumentation launcher) { + atMost(message, condition, timeout, DEFAULT_SLEEP_MS, launcher); } - public static void atMost(String message, Condition condition, long timeout, long sleepMillis) { + public static void atMost(String message, Condition condition, long timeout, long sleepMillis, + LauncherInstrumentation launcher) { final long startTime = SystemClock.uptimeMillis(); long endTime = startTime + timeout; Log.d("Wait", "atMost: " + startTime + " - " + endTime); @@ -40,6 +44,7 @@ public class Wait { throw new RuntimeException(t); } Log.d("Wait", "atMost: timed out: " + SystemClock.uptimeMillis()); + launcher.checkForAnomaly(); Assert.fail(message); } } diff --git a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java index 3713c1485f..1c851f4ed7 100644 --- a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java +++ b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java @@ -64,10 +64,12 @@ import com.android.launcher3.ResourceUtils; import com.android.launcher3.testing.TestProtocol; import com.android.systemui.shared.system.QuickStepContract; -import java.util.ArrayList; +import org.junit.Assert; + import java.io.ByteArrayOutputStream; import java.io.IOException; import java.lang.ref.WeakReference; +import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.Deque; @@ -77,8 +79,6 @@ import java.util.concurrent.TimeoutException; import java.util.function.Consumer; import java.util.function.Function; -import org.junit.Assert; - /** * The main tapl object. The only object that can be explicitly constructed by the using code. It * produces all other objects. @@ -298,6 +298,14 @@ public final class LauncherInstrumentation { return null; } + public void checkForAnomaly() { + final String anomalyMessage = getAnomalyMessage(); + if (anomalyMessage != null) { + failWithSystemHealth( + "Tests are broken by a non-Launcher system error: " + anomalyMessage); + } + } + private String getVisibleStateMessage() { if (hasLauncherObject(WIDGETS_RES_ID)) return "Widgets"; if (hasLauncherObject(OVERVIEW_RES_ID)) return "Overview"; @@ -331,20 +339,17 @@ public final class LauncherInstrumentation { } private void fail(String message) { - message = "http://go/tapl : " + getContextDescription() + message; + checkForAnomaly(); - final String anomaly = getAnomalyMessage(); - if (anomaly != null) { - message = anomaly + ", which causes:\n" + message; - } else { - message = message + " (visible state: " + getVisibleStateMessage() + ")"; - } + failWithSystemHealth("http://go/tapl : " + getContextDescription() + message + + " (visible state: " + getVisibleStateMessage() + ")"); + } + private void failWithSystemHealth(String message) { final String systemHealth = getSystemHealthMessage(); if (systemHealth != null) { message = message - + ", which might be a consequence of system health " - + "problems:\n<<<<<<<<<<<<<<<<<<\n" + + ", perhaps because of system health problems:\n<<<<<<<<<<<<<<<<<<\n" + systemHealth + "\n>>>>>>>>>>>>>>>>>>"; } @@ -531,8 +536,7 @@ public final class LauncherInstrumentation { // accessibility events prior to pressing Home. final String action; if (getNavigationModel() == NavigationModel.ZERO_BUTTON) { - final String anomaly = getAnomalyMessage(); - if (anomaly != null) fail("Can't swipe up to Home: " + anomaly); + checkForAnomaly(); final Point displaySize = getRealDisplaySize();