Bug 1465480 - Throw away cached session if there was a crash r=jchen
If a content process crashes during a test, throw away the cached
session since it may be in an inconsistent state.
MozReview-Commit-ID: 9bqWNeJjYd5
--- a/mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/rule/GeckoSessionTestRule.java
+++ b/mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/rule/GeckoSessionTestRule.java
@@ -1127,16 +1127,17 @@ public class GeckoSessionTestRule extend
protected void prepareStatement(final Description description) throws Throwable {
final GeckoSessionSettings settings = new GeckoSessionSettings(mDefaultSettings);
mTimeoutMillis = getDefaultTimeoutMillis();
mNullDelegates = new HashSet<>();
mClosedSession = false;
mWithDevTools = false;
mReuseSession = true;
+ mIgnoreCrash = false;
applyAnnotations(Arrays.asList(description.getTestClass().getAnnotations()), settings);
applyAnnotations(description.getAnnotations(), settings);
final List<CallRecord> records = new ArrayList<>();
final CallbackDelegates waitDelegates = new CallbackDelegates();
final CallbackDelegates testDelegates = new CallbackDelegates();
mCallRecords = records;
@@ -1159,20 +1160,16 @@ public class GeckoSessionTestRule extend
case "toString":
return "Call Recorder";
}
ignore = true;
} else if (mCallRecordHandler != null) {
ignore = mCallRecordHandler.handleCall(method, args);
}
- if (!mIgnoreCrash && sOnCrash.equals(method)) {
- throw new RuntimeException("Content process crashed");
- }
-
final boolean isExternalDelegate =
!DEFAULT_DELEGATES.contains(method.getDeclaringClass());
if (!ignore) {
assertThat("Callbacks must be on UI thread",
Looper.myLooper(), equalTo(Looper.getMainLooper()));
final GeckoSession session;
@@ -1180,16 +1177,21 @@ public class GeckoSessionTestRule extend
session = null;
} else {
assertThat("Callback first argument must be session object",
args, arrayWithSize(greaterThan(0)));
assertThat("Callback first argument must be session object",
args[0], instanceOf(GeckoSession.class));
session = (GeckoSession) args[0];
}
+
+ if (sOnCrash.equals(method) && !mIgnoreCrash && isUsingSession(session)) {
+ throw new RuntimeException("Content process crashed");
+ }
+
records.add(new CallRecord(session, method, args));
call = waitDelegates.prepareMethodCall(session, method);
if (call == null) {
call = testDelegates.prepareMethodCall(session, method);
}
if (isExternalDelegate) {
@@ -1244,16 +1246,20 @@ public class GeckoSessionTestRule extend
.javaCrashReportingEnabled(true)
.remoteDebuggingEnabled(true);
sRuntime = GeckoRuntime.create(
InstrumentationRegistry.getTargetContext(),
runtimeSettingsBuilder.build());
}
+ if (sCachedSession != null && !sCachedSession.isOpen()) {
+ sCachedSession = null;
+ }
+
final boolean useDefaultSession = !mClosedSession && mDefaultSettings.equals(settings);
if (useDefaultSession && mReuseSession && sCachedSession != null) {
mMainSession = sCachedSession;
} else {
mMainSession = new GeckoSession(settings);
}
prepareSession(mMainSession);
@@ -1359,33 +1365,45 @@ public class GeckoSessionTestRule extend
public void performTestEndCheck() {
mWaitScopeDelegates.clearAndAssert();
mTestScopeDelegates.clearAndAssert();
}
protected void cleanupSession(final GeckoSession session) {
final Tab tab = (mRDPTabs != null) ? mRDPTabs.get(session) : null;
if (tab != null) {
- tab.getPromises().detach();
- tab.detach();
+ if (session.isOpen()) {
+ tab.getPromises().detach();
+ tab.detach();
+ }
+
mRDPTabs.remove(session);
}
if (session.isOpen()) {
session.close();
}
}
+ protected boolean isUsingSession(final GeckoSession session) {
+ return session.equals(mMainSession) || mSubSessions.contains(session);
+ }
+
protected void cleanupStatement() throws Throwable {
mWaitScopeDelegates.clear();
mTestScopeDelegates.clear();
for (final GeckoSession session : mSubSessions) {
cleanupSession(session);
}
- if (mMainSession.equals(sCachedSession)) {
+
+ if (sCachedSession != null && mReuseSession && !mIgnoreCrash) {
+ assertThat("Cached session should be open", sCachedSession.isOpen(), equalTo(true));
+ }
+
+ if (mMainSession.isOpen() && mMainSession.equals(sCachedSession)) {
// We have to detach the Promises object, but keep the Tab itself.
sCachedRDPTab.getPromises().detach();
} else {
cleanupSession(mMainSession);
}
if (mDisplay != null) {
mDisplay.surfaceDestroyed();