Fix intermittently failing unit test.
- This test fails if you haven't switched the phone screen on, which
can be very confusing if you don't know about it.
- This cl introduces acquiring and releasing the screen wake lock to
the integration test utils, and uses it to prevent this test failure.
Change-Id: I378b6effd56e912213eb0af81f8add5c3bba39f2
diff --git a/tests/src/com/android/contacts/interactions/ContactDeletionInteractionTest.java b/tests/src/com/android/contacts/interactions/ContactDeletionInteractionTest.java
index c1eefc0..fc3545b 100644
--- a/tests/src/com/android/contacts/interactions/ContactDeletionInteractionTest.java
+++ b/tests/src/com/android/contacts/interactions/ContactDeletionInteractionTest.java
@@ -27,6 +27,7 @@
import com.android.contacts.tests.mocks.MockAccountTypeManager;
import com.android.contacts.tests.mocks.MockContentProvider;
import com.android.contacts.tests.mocks.MockContentProvider.Query;
+import com.android.contacts.util.IntegrationTestUtils;
import android.content.ContentUris;
import android.net.Uri;
@@ -65,6 +66,7 @@
private ContactsMockContext mContext;
private MockContentProvider mContactsProvider;
private ContactDeletionInteraction mFragment;
+ private IntegrationTestUtils mUtils;
public ContactDeletionInteractionTest() {
super(FragmentTestActivity.class);
@@ -73,6 +75,10 @@
@Override
protected void setUp() throws Exception {
super.setUp();
+ // This test requires that the screen be turned on.
+ mUtils = new IntegrationTestUtils(getInstrumentation());
+ mUtils.acquireScreenWakeLock(getInstrumentation().getTargetContext());
+
mContext = new ContactsMockContext(getInstrumentation().getTargetContext());
InjectedServices services = new InjectedServices();
services.setContentResolver(mContext.getContentResolver());
@@ -94,6 +100,7 @@
@Override
protected void tearDown() throws Exception {
ContactsApplication.injectServices(null);
+ mUtils.releaseScreenWakeLock();
super.tearDown();
}
diff --git a/tests/src/com/android/contacts/util/IntegrationTestUtils.java b/tests/src/com/android/contacts/util/IntegrationTestUtils.java
index 9ce60a0..45dc981 100644
--- a/tests/src/com/android/contacts/util/IntegrationTestUtils.java
+++ b/tests/src/com/android/contacts/util/IntegrationTestUtils.java
@@ -16,8 +16,16 @@
package com.android.contacts.util;
+import static android.os.PowerManager.ACQUIRE_CAUSES_WAKEUP;
+import static android.os.PowerManager.FULL_WAKE_LOCK;
+import static android.os.PowerManager.ON_AFTER_RELEASE;
+
+import com.google.common.base.Preconditions;
+
import android.app.Activity;
import android.app.Instrumentation;
+import android.content.Context;
+import android.os.PowerManager;
import android.view.View;
import junit.framework.Assert;
@@ -26,9 +34,17 @@
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;
+import javax.annotation.concurrent.GuardedBy;
+import javax.annotation.concurrent.ThreadSafe;
+
/** Some utility methods for making integration testing smoother. */
+@ThreadSafe
public class IntegrationTestUtils {
+ private static final String TAG = "IntegrationTestUtils";
+
private final Instrumentation mInstrumentation;
+ private final Object mLock = new Object();
+ @GuardedBy("mLock") private PowerManager.WakeLock mWakeLock;
public IntegrationTestUtils(Instrumentation instrumentation) {
mInstrumentation = instrumentation;
@@ -70,4 +86,36 @@
throw e.getCause();
}
}
+
+ /**
+ * Wake up the screen, useful in tests that want or need the screen to be on.
+ * <p>
+ * This is usually called from setUp() for tests that require it. After calling this method,
+ * {@link #releaseScreenWakeLock()} must be called, this is usually done from tearDown().
+ */
+ public void acquireScreenWakeLock(Context context) {
+ synchronized (mLock) {
+ Preconditions.checkState(mWakeLock == null, "mWakeLock was already held");
+ mWakeLock = ((PowerManager) context.getSystemService(Context.POWER_SERVICE))
+ .newWakeLock(ACQUIRE_CAUSES_WAKEUP | ON_AFTER_RELEASE | FULL_WAKE_LOCK, TAG);
+ mWakeLock.acquire();
+ }
+ }
+
+ /** Release the wake lock previously acquired with {@link #acquireScreenWakeLock(Context)}. */
+ public void releaseScreenWakeLock() {
+ synchronized (mLock) {
+ // We don't use Preconditions to force you to have acquired before release.
+ // This is because we don't want unnecessary exceptions in tearDown() since they'll
+ // typically mask the actual exception that happened during the test.
+ // The other reason is that this method is most likely to be called from tearDown(),
+ // which is invoked within a finally block, so it's not infrequently the case that
+ // the setUp() method fails before getting the lock, at which point we don't want
+ // to fail in tearDown().
+ if (mWakeLock != null) {
+ mWakeLock.release();
+ mWakeLock = null;
+ }
+ }
+ }
}