Merge "Improving tests to fix testBindNormalWidget_withoutConfig, and beyond" into ub-launcher3-master

This commit is contained in:
Vadim Tryshev 2018-10-10 02:03:39 +00:00 committed by Android (Google) Code Review
commit 514cd27850
10 changed files with 46 additions and 46 deletions

View File

@ -451,6 +451,11 @@ public class LauncherModel extends BroadcastReceiver
* @return true if the page could be bound synchronously.
*/
public boolean startLoader(int synchronousBindPage) {
if (com.android.launcher3.Utilities.IS_RUNNING_IN_TEST_HARNESS
&& com.android.launcher3.Utilities.IS_DEBUG_DEVICE) {
android.util.Log.d("b/117332845",
android.util.Log.getStackTraceString(new Throwable()));
}
// Enable queue before starting loader. It will get disabled in Launcher#finishBindingItems
InstallShortcutReceiver.enableInstallQueue(InstallShortcutReceiver.FLAG_LOADER_RUNNING);
synchronized (mLock) {

View File

@ -47,6 +47,7 @@ import androidx.test.uiautomator.Until;
import com.android.launcher3.Launcher;
import com.android.launcher3.LauncherAppState;
import com.android.launcher3.LauncherAppWidgetProviderInfo;
import com.android.launcher3.LauncherModel;
import com.android.launcher3.LauncherSettings;
import com.android.launcher3.LauncherState;
import com.android.launcher3.MainThreadExecutor;
@ -133,7 +134,8 @@ public abstract class AbstractLauncherUiTest {
try {
// Create launcher activity if necessary and bring it to the front.
mDevice.pressHome();
waitForLauncherCondition(launcher -> launcher != null);
waitForLauncherCondition("Launcher activity wasn't created",
launcher -> launcher != null);
executeOnLauncher(launcher ->
launcher.getRotationHelper().forceAllowRotationForTesting(true));
@ -170,7 +172,7 @@ public abstract class AbstractLauncherUiTest {
@After
public void tearDown() throws Exception {
// Limits UI tests affecting tests running after them.
resetLoaderState();
waitForModelLoaded();
}
protected void lockRotation(boolean naturalOrientation) throws RemoteException {
@ -320,8 +322,7 @@ public abstract class AbstractLauncherUiTest {
} catch (Throwable t) {
throw new IllegalArgumentException(t);
}
waitForLauncherCondition(launcher ->
LauncherAppState.getInstance(mTargetContext).getModel().isModelLoaded());
waitForModelLoaded();
if (com.android.launcher3.Utilities.IS_RUNNING_IN_TEST_HARNESS
&& com.android.launcher3.Utilities.IS_DEBUG_DEVICE) {
android.util.Log.d("b/117332845",
@ -329,6 +330,13 @@ public abstract class AbstractLauncherUiTest {
}
}
protected void waitForModelLoaded() {
waitForLauncherCondition("Launcher model didn't load", launcher -> {
final LauncherModel model = LauncherAppState.getInstance(mTargetContext).getModel();
return model.getCallback() == null || model.isModelLoaded();
});
}
/**
* Runs the callback on the UI thread and returns the result.
*/
@ -354,22 +362,23 @@ public abstract class AbstractLauncherUiTest {
// Cannot be used in TaplTests between a Tapl call injecting a gesture and a tapl call expecting
// the results of that gesture because the wait can hide flakeness.
protected boolean waitForState(LauncherState state) {
return waitForLauncherCondition(launcher -> launcher.getStateManager().getState() == state);
protected void waitForState(String message, LauncherState state) {
waitForLauncherCondition(message,
launcher -> launcher.getStateManager().getState() == state);
}
// Cannot be used in TaplTests after injecting any gesture using Tapl because this can hide
// flakiness.
protected boolean waitForLauncherCondition(Function<Launcher, Boolean> condition) {
return waitForLauncherCondition(condition, DEFAULT_ACTIVITY_TIMEOUT);
protected void waitForLauncherCondition(String message, Function<Launcher, Boolean> condition) {
waitForLauncherCondition(message, condition, DEFAULT_ACTIVITY_TIMEOUT);
}
// Cannot be used in TaplTests after injecting any gesture using Tapl because this can hide
// flakiness.
protected boolean waitForLauncherCondition(
Function<Launcher, Boolean> condition, long timeout) {
if (!TestHelpers.isInLauncherProcess()) return true;
return Wait.atMost(() -> getFromLauncher(condition), timeout);
protected void waitForLauncherCondition(
String message, Function<Launcher, Boolean> condition, long timeout) {
if (!TestHelpers.isInLauncherProcess()) return;
Wait.atMost(message, () -> getFromLauncher(condition), timeout);
}
/**

View File

@ -46,7 +46,7 @@ public class AllAppsIconToHomeTest extends AbstractLauncherUiTest {
// Open all apps and wait for load complete.
final UiObject2 appsContainer = openAllApps();
assertTrue(Wait.atMost(Condition.minChildCount(appsContainer, 2), DEFAULT_UI_TIMEOUT));
Wait.atMost(null, Condition.minChildCount(appsContainer, 2), DEFAULT_UI_TIMEOUT);
// Drag icon to homescreen.
UiObject2 icon = scrollAndFind(appsContainer, By.text(settingsApp.getLabel().toString()));

View File

@ -47,8 +47,7 @@ public class ShortcutsLaunchTest extends AbstractLauncherUiTest {
// Open all apps and wait for load complete
final UiObject2 appsContainer = openAllApps();
assertTrue(Wait.atMost(Condition.minChildCount(appsContainer, 2),
DEFAULT_UI_TIMEOUT));
Wait.atMost(null, Condition.minChildCount(appsContainer, 2), DEFAULT_UI_TIMEOUT);
// Find settings app and verify shortcuts appear when long pressed
UiObject2 icon = scrollAndFind(appsContainer, By.text(testApp.getLabel().toString()));

View File

@ -49,8 +49,7 @@ public class ShortcutsToHomeTest extends AbstractLauncherUiTest {
// Open all apps and wait for load complete.
final UiObject2 appsContainer = openAllApps();
assertTrue(Wait.atMost(Condition.minChildCount(appsContainer, 2),
DEFAULT_UI_TIMEOUT));
Wait.atMost(null, Condition.minChildCount(appsContainer, 2), DEFAULT_UI_TIMEOUT);
// Find the app and long press it to show shortcuts.
UiObject2 icon = scrollAndFind(appsContainer, By.text(testApp.getLabel().toString()));

View File

@ -106,7 +106,7 @@ public class AddConfigWidgetTest extends AbstractLauncherUiTest {
// Open widget tray and wait for load complete.
final UiObject2 widgetContainer = openWidgetsTray();
assertTrue(Wait.atMost(Condition.minChildCount(widgetContainer, 2), DEFAULT_UI_TIMEOUT));
Wait.atMost(null, Condition.minChildCount(widgetContainer, 2), DEFAULT_UI_TIMEOUT);
// Drag widget to homescreen
WidgetConfigStartupMonitor monitor = new WidgetConfigStartupMonitor();
@ -128,12 +128,12 @@ public class AddConfigWidgetTest extends AbstractLauncherUiTest {
setResult(acceptConfig);
if (acceptConfig) {
assertTrue(Wait.atMost(new WidgetSearchCondition(), DEFAULT_ACTIVITY_TIMEOUT));
Wait.atMost(null, new WidgetSearchCondition(), DEFAULT_ACTIVITY_TIMEOUT);
assertNotNull(mAppWidgetManager.getAppWidgetInfo(mWidgetId));
} else {
// Verify that the widget id is deleted.
assertTrue(Wait.atMost(() -> mAppWidgetManager.getAppWidgetInfo(mWidgetId) == null,
DEFAULT_ACTIVITY_TIMEOUT));
Wait.atMost(null, () -> mAppWidgetManager.getAppWidgetInfo(mWidgetId) == null,
DEFAULT_ACTIVITY_TIMEOUT);
}
}

View File

@ -70,7 +70,7 @@ public class AddWidgetTest extends AbstractLauncherUiTest {
// Open widget tray and wait for load complete.
final UiObject2 widgetContainer = openWidgetsTray();
assertTrue(Wait.atMost(Condition.minChildCount(widgetContainer, 2), DEFAULT_UI_TIMEOUT));
Wait.atMost(null, Condition.minChildCount(widgetContainer, 2), DEFAULT_UI_TIMEOUT);
// Drag widget to homescreen
UiObject2 widget = scrollAndFind(widgetContainer, By.clazz(WidgetCell.class)

View File

@ -141,7 +141,6 @@ public class BindWidgetTest extends AbstractLauncherUiTest {
// Since there is no widget to verify, just wait until the workspace is ready.
setupAndVerifyContents(item, Workspace.class, null);
waitUntilLoaderIdle();
// Item deleted from db
mCursor = mResolver.query(LauncherSettings.Favorites.getContentUri(item.id),
null, null, null, null, null);
@ -187,7 +186,6 @@ public class BindWidgetTest extends AbstractLauncherUiTest {
item.restoreStatus = LauncherAppWidgetInfo.FLAG_ID_NOT_VALID;
setupAndVerifyContents(item, PendingAppWidgetHostView.class, null);
waitUntilLoaderIdle();
// Item deleted from db
mCursor = mResolver.query(LauncherSettings.Favorites.getContentUri(item.id),
null, null, null, null, null);
@ -216,7 +214,6 @@ public class BindWidgetTest extends AbstractLauncherUiTest {
// The view does not exist
assertFalse(mDevice.findObject(
new UiSelector().className(PendingAppWidgetHostView.class)).exists());
waitUntilLoaderIdle();
// Item deleted from db
mCursor = mResolver.query(LauncherSettings.Favorites.getContentUri(item.id),
null, null, null, null, null);
@ -234,7 +231,6 @@ public class BindWidgetTest extends AbstractLauncherUiTest {
setupAndVerifyContents(item, PendingAppWidgetHostView.class, null);
// Verify item still exists in db
waitUntilLoaderIdle();
mCursor = mResolver.query(LauncherSettings.Favorites.getContentUri(item.id),
null, null, null, null, null);
assertEquals(1, mCursor.getCount());
@ -261,7 +257,6 @@ public class BindWidgetTest extends AbstractLauncherUiTest {
setupAndVerifyContents(item, PendingAppWidgetHostView.class, null);
// Verify item still exists in db
waitUntilLoaderIdle();
mCursor = mResolver.query(LauncherSettings.Favorites.getContentUri(item.id),
null, null, null, null, null);
assertEquals(1, mCursor.getCount());
@ -306,6 +301,8 @@ public class BindWidgetTest extends AbstractLauncherUiTest {
// Launch the home activity
mActivityMonitor.startLauncher();
waitForModelLoaded();
// Verify UI
UiSelector selector = new UiSelector().packageName(mTargetContext.getPackageName())
.className(widgetClass);
@ -390,15 +387,4 @@ public class BindWidgetTest extends AbstractLauncherUiTest {
item.container = LauncherSettings.Favorites.CONTAINER_DESKTOP;
return item;
}
/**
* Blocks the current thread until all the jobs in the main worker thread are complete.
*/
private void waitUntilLoaderIdle() throws Exception {
new LooperExecutor(LauncherModel.getWorkerLooper())
.submit(new Runnable() {
@Override
public void run() { }
}).get(DEFAULT_WORKER_TIMEOUT_SECS, TimeUnit.SECONDS);
}
}

View File

@ -152,7 +152,7 @@ public class RequestPinItemTest extends AbstractLauncherUiTest {
// Open all apps and wait for load complete
final UiObject2 appsContainer = openAllApps();
assertTrue(Wait.atMost(Condition.minChildCount(appsContainer, 2), DEFAULT_UI_TIMEOUT));
Wait.atMost(null, Condition.minChildCount(appsContainer, 2), DEFAULT_UI_TIMEOUT);
// Open Pin item activity
BlockingBroadcastReceiver openMonitor = new BlockingBroadcastReceiver(
@ -191,7 +191,7 @@ public class RequestPinItemTest extends AbstractLauncherUiTest {
// Go back to home
mActivityMonitor.returnToHome();
assertTrue(Wait.atMost(new ItemSearchCondition(itemMatcher), DEFAULT_ACTIVITY_TIMEOUT));
Wait.atMost(null, new ItemSearchCondition(itemMatcher), DEFAULT_ACTIVITY_TIMEOUT);
}
/**

View File

@ -2,6 +2,8 @@ package com.android.launcher3.util;
import android.os.SystemClock;
import org.junit.Assert;
/**
* A utility class for waiting for a condition to be true.
*/
@ -9,16 +11,16 @@ public class Wait {
private static final long DEFAULT_SLEEP_MS = 200;
public static boolean atMost(Condition condition, long timeout) {
return atMost(condition, timeout, DEFAULT_SLEEP_MS);
public static void atMost(String message, Condition condition, long timeout) {
atMost(message, condition, timeout, DEFAULT_SLEEP_MS);
}
public static boolean atMost(Condition condition, long timeout, long sleepMillis) {
public static void atMost(String message, Condition condition, long timeout, long sleepMillis) {
long endTime = SystemClock.uptimeMillis() + timeout;
while (SystemClock.uptimeMillis() < endTime) {
try {
if (condition.isTrue()) {
return true;
return;
}
} catch (Throwable t) {
// Ignore
@ -29,11 +31,11 @@ public class Wait {
// Check once more before returning false.
try {
if (condition.isTrue()) {
return true;
return;
}
} catch (Throwable t) {
// Ignore
}
return false;
Assert.fail(message);
}
}