mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-19 00:05:36 +00:00
Bug 1465480 - Add @IgnoreCrash to GeckoSessionTestRule r=jchen
This allows a test to declare that crashes should not be considered fatal. It does not, however, assert that a crash will occur. That responsibility is left with the test itself. MozReview-Commit-ID: 4DB6xs5jlEZ
This commit is contained in:
parent
2a505d2d75
commit
4f1fa4bc6e
@ -26,6 +26,7 @@ import kotlin.reflect.KClass
|
||||
open class BaseSessionTest(noErrorCollector: Boolean = false) {
|
||||
companion object {
|
||||
const val CLICK_TO_RELOAD_HTML_PATH = "/assets/www/clickToReload.html"
|
||||
const val CONTENT_CRASH_URL = "about:crashcontent"
|
||||
const val DOWNLOAD_HTML_PATH = "/assets/www/download.html"
|
||||
const val HELLO_HTML_PATH = "/assets/www/hello.html"
|
||||
const val HELLO2_HTML_PATH = "/assets/www/hello2.html"
|
||||
|
@ -8,8 +8,10 @@ import org.mozilla.geckoview.GeckoSession
|
||||
import org.mozilla.geckoview.GeckoSessionSettings
|
||||
import org.mozilla.geckoview.test.rule.GeckoSessionTestRule.AssertCalled
|
||||
import org.mozilla.geckoview.test.rule.GeckoSessionTestRule.ClosedSessionAtStart
|
||||
import org.mozilla.geckoview.test.rule.GeckoSessionTestRule.IgnoreCrash
|
||||
import org.mozilla.geckoview.test.rule.GeckoSessionTestRule.NullDelegate
|
||||
import org.mozilla.geckoview.test.rule.GeckoSessionTestRule.RejectedPromiseException
|
||||
import org.mozilla.geckoview.test.rule.GeckoSessionTestRule.ReuseSession
|
||||
import org.mozilla.geckoview.test.rule.GeckoSessionTestRule.Setting
|
||||
import org.mozilla.geckoview.test.rule.GeckoSessionTestRule.TimeoutException
|
||||
import org.mozilla.geckoview.test.rule.GeckoSessionTestRule.TimeoutMillis
|
||||
@ -1604,31 +1606,56 @@ class GeckoSessionTestRuleTest : BaseSessionTest(noErrorCollector = true) {
|
||||
val unregister = { _: TestDelegate -> delegate = null }
|
||||
|
||||
sessionRule.addExternalDelegateDuringNextWait(TestDelegate::class, register, unregister,
|
||||
object : TestDelegate {
|
||||
@AssertCalled(count = 1)
|
||||
override fun onDelegate(foo: String, bar: String): Int {
|
||||
return 24
|
||||
}
|
||||
})
|
||||
object : TestDelegate {
|
||||
@AssertCalled(count = 1)
|
||||
override fun onDelegate(foo: String, bar: String): Int {
|
||||
return 24
|
||||
}
|
||||
})
|
||||
|
||||
sessionRule.addExternalDelegateUntilTestEnd(TestDelegate::class, register, unregister,
|
||||
object : TestDelegate {
|
||||
@AssertCalled(count = 1)
|
||||
override fun onDelegate(foo: String, bar: String): Int {
|
||||
return 42
|
||||
}
|
||||
})
|
||||
object : TestDelegate {
|
||||
@AssertCalled(count = 1)
|
||||
override fun onDelegate(foo: String, bar: String): Int {
|
||||
return 42
|
||||
}
|
||||
})
|
||||
|
||||
assertThat("Wait delegate should be registered", delegate, notNullValue())
|
||||
assertThat("Wait delegate return value should be correct",
|
||||
delegate?.onDelegate("", ""), equalTo(24))
|
||||
delegate?.onDelegate("", ""), equalTo(24))
|
||||
|
||||
mainSession.reload()
|
||||
mainSession.waitForPageStop()
|
||||
|
||||
assertThat("Test delegate should still be registered", delegate, notNullValue())
|
||||
assertThat("Test delegate return value should be correct",
|
||||
delegate?.onDelegate("", ""), equalTo(42))
|
||||
delegate?.onDelegate("", ""), equalTo(42))
|
||||
sessionRule.performTestEndCheck()
|
||||
}
|
||||
|
||||
@IgnoreCrash
|
||||
@ReuseSession(false)
|
||||
@Test fun contentCrashIgnored() {
|
||||
assumeThat(sessionRule.env.isMultiprocess, equalTo(true))
|
||||
|
||||
// This test has some kind of strange race on ARM emulators
|
||||
assumeThat(!(sessionRule.env.isEmulator && sessionRule.env.cpuArch.contains("arm")),
|
||||
equalTo(true))
|
||||
|
||||
sessionRule.session.loadUri(CONTENT_CRASH_URL)
|
||||
sessionRule.waitUntilCalled(object : Callbacks.ContentDelegate {
|
||||
@AssertCalled(count = 1)
|
||||
override fun onCrash(session: GeckoSession) = Unit
|
||||
})
|
||||
}
|
||||
|
||||
@Test(expected = RuntimeException::class)
|
||||
@ReuseSession(false)
|
||||
fun contentCrashFails() {
|
||||
assumeThat(sessionRule.env.isMultiprocess, equalTo(true))
|
||||
|
||||
sessionRule.session.loadUri(CONTENT_CRASH_URL)
|
||||
sessionRule.waitForPageStop()
|
||||
}
|
||||
}
|
||||
|
@ -97,6 +97,7 @@ public class GeckoSessionTestRule extends UiThreadTestRule {
|
||||
private static final Method sGetNextMessage;
|
||||
private static final Method sOnPageStop;
|
||||
private static final Method sOnNewSession;
|
||||
private static final Method sOnCrash;
|
||||
|
||||
static {
|
||||
try {
|
||||
@ -106,6 +107,8 @@ public class GeckoSessionTestRule extends UiThreadTestRule {
|
||||
"onPageStop", GeckoSession.class, boolean.class);
|
||||
sOnNewSession = GeckoSession.NavigationDelegate.class.getMethod(
|
||||
"onNewSession", GeckoSession.class, String.class, GeckoResponse.class);
|
||||
sOnCrash = GeckoSession.ContentDelegate.class.getMethod(
|
||||
"onCrash", GeckoSession.class);
|
||||
} catch (final NoSuchMethodException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
@ -315,6 +318,20 @@ public class GeckoSessionTestRule extends UiThreadTestRule {
|
||||
void invoke(T delegate) throws Throwable;
|
||||
}
|
||||
|
||||
/*
|
||||
* If the value here is true, content crashes will be ignored. If false, the test will
|
||||
* be failed immediately if a content crash occurs. This is also the case when
|
||||
* {@link IgnoreCrash} is not present.
|
||||
*/
|
||||
@Target(ElementType.METHOD)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface IgnoreCrash {
|
||||
/**
|
||||
* @return True if content crashes should be ignored, false otherwise. Default is true.
|
||||
*/
|
||||
boolean value() default true;
|
||||
}
|
||||
|
||||
public static class TimeoutException extends RuntimeException {
|
||||
public TimeoutException(final String detailMessage) {
|
||||
super(detailMessage);
|
||||
@ -904,6 +921,7 @@ public class GeckoSessionTestRule extends UiThreadTestRule {
|
||||
protected Map<GeckoSession, Tab> mRDPTabs;
|
||||
protected Tab mRDPChromeProcess;
|
||||
protected boolean mReuseSession;
|
||||
protected boolean mIgnoreCrash;
|
||||
|
||||
public GeckoSessionTestRule() {
|
||||
mDefaultSettings = new GeckoSessionSettings();
|
||||
@ -1076,6 +1094,8 @@ public class GeckoSessionTestRule extends UiThreadTestRule {
|
||||
mWithDevTools = ((WithDevToolsAPI) annotation).value();
|
||||
} else if (ReuseSession.class.equals(annotation.annotationType())) {
|
||||
mReuseSession = ((ReuseSession) annotation).value();
|
||||
} else if (IgnoreCrash.class.equals(annotation.annotationType())) {
|
||||
mIgnoreCrash = ((IgnoreCrash) annotation).value();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1144,8 +1164,13 @@ public class GeckoSessionTestRule extends UiThreadTestRule {
|
||||
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()));
|
||||
|
Loading…
Reference in New Issue
Block a user