Fix @Test(timeout) so it still runs tests on the main sandbox thread.
diff --git a/junit/src/main/java/org/robolectric/internal/SandboxTestRunner.java b/junit/src/main/java/org/robolectric/internal/SandboxTestRunner.java
index 1ffefbb..bc38f07 100644
--- a/junit/src/main/java/org/robolectric/internal/SandboxTestRunner.java
+++ b/junit/src/main/java/org/robolectric/internal/SandboxTestRunner.java
@@ -13,6 +13,8 @@
import javax.annotation.Nonnull;
import org.junit.AfterClass;
import org.junit.BeforeClass;
+import org.junit.Test;
+import org.junit.internal.runners.statements.FailOnTimeout;
import org.junit.runner.notification.RunNotifier;
import org.junit.runners.BlockJUnit4ClassRunner;
import org.junit.runners.model.FrameworkMethod;
@@ -196,7 +198,7 @@
}
@Override protected Statement methodBlock(final FrameworkMethod method) {
- return withPotentialTimeoutAroundSandboxThread(method, null, new Statement() {
+ return new Statement() {
@Override
public void evaluate() throws Throwable {
PerfStatsCollector perfStatsCollector = PerfStatsCollector.getInstance();
@@ -212,57 +214,56 @@
// not available once we install the Robolectric class loader.
configureSandbox(sandbox, method);
- final ClassLoader priorContextClassLoader = Thread.currentThread().getContextClassLoader();
- Thread.currentThread().setContextClassLoader(sandbox.getRobolectricClassLoader());
-
- Class bootstrappedTestClass = sandbox.bootstrappedClass(getTestClass().getJavaClass());
- HelperTestRunner helperTestRunner = getHelperTestRunner(bootstrappedTestClass);
- helperTestRunner.frameworkMethod = method;
-
- final Method bootstrappedMethod;
- try {
- //noinspection unchecked
- bootstrappedMethod = bootstrappedTestClass.getMethod(method.getMethod().getName());
- } catch (NoSuchMethodException e) {
- throw new RuntimeException(e);
- }
-
sandbox.runOnMainThread(() -> {
+ ClassLoader priorContextClassLoader = Thread.currentThread().getContextClassLoader();
+ Thread.currentThread().setContextClassLoader(sandbox.getRobolectricClassLoader());
+
+ Class bootstrappedTestClass =
+ sandbox.bootstrappedClass(getTestClass().getJavaClass());
+ HelperTestRunner helperTestRunner = getHelperTestRunner(bootstrappedTestClass);
+ helperTestRunner.frameworkMethod = method;
+
+ final Method bootstrappedMethod;
try {
+ //noinspection unchecked
+ bootstrappedMethod = bootstrappedTestClass.getMethod(method.getMethod().getName());
+ } catch (NoSuchMethodException e) {
+ throw new RuntimeException(e);
+ }
+
+ try {
+ // Only invoke @BeforeClass once per class
+ invokeBeforeClass(bootstrappedTestClass);
+
+ beforeTest(sandbox, method, bootstrappedMethod);
+
+ initialization.finished();
+
+ Statement statement =
+ helperTestRunner.methodBlock(new FrameworkMethod(bootstrappedMethod));
+
+ // todo: this try/finally probably isn't right -- should mimic RunAfters? [xw]
try {
- // Only invoke @BeforeClass once per class
- invokeBeforeClass(bootstrappedTestClass);
-
- beforeTest(sandbox, method, bootstrappedMethod);
-
- initialization.finished();
-
- final Statement statement = helperTestRunner.methodBlock(new FrameworkMethod(bootstrappedMethod));
-
- // todo: this try/finally probably isn't right -- should mimic RunAfters? [xw]
- try {
- statement.evaluate();
- } finally {
- afterTest(method, bootstrappedMethod);
- }
+ statement.evaluate();
} finally {
- Thread.currentThread().setContextClassLoader(priorContextClassLoader);
-
- try {
- finallyAfterTest(method);
- } catch (Exception e) {
- e.printStackTrace();
- }
+ afterTest(method, bootstrappedMethod);
}
} catch (Throwable throwable) {
UnsafeAccess.throwException(throwable);
+ } finally {
+ Thread.currentThread().setContextClassLoader(priorContextClassLoader);
+ try {
+ finallyAfterTest(method);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
}
});
reportPerfStats(perfStatsCollector);
perfStatsCollector.reset();
}
- });
+ };
}
private void reportPerfStats(PerfStatsCollector perfStatsCollector) {
@@ -306,21 +307,47 @@
super(klass);
}
- // cuz accessibility
+ // for visibility from SandboxTestRunner.methodBlock()
@Override
protected Statement methodBlock(FrameworkMethod method) {
return super.methodBlock(method);
}
/**
+ * For tests with a timeout, we need to wrap the test method execution (but not befores or
+ * afters) in a {@link TimeLimitedStatement}. We can't use JUnit's built-in
+ * {@link FailOnTimeout} statement because it causes the test to be run on a new thread, but
+ * tests should be run on the sandbox's main thread in all cases.
+ */
+ @Override
+ protected Statement methodInvoker(FrameworkMethod method, Object test) {
+ Statement delegate = super.methodInvoker(method, test);
+ long timeout = getTimeout(method.getAnnotation(Test.class));
+
+ if (timeout == 0) {
+ return delegate;
+ } else {
+ return new TimeLimitedStatement(timeout, delegate);
+ }
+ }
+
+ /**
* Disables JUnit's normal timeout mode.
*
- * @see #withPotentialTimeoutAroundSandboxThread(FrameworkMethod, Object, Statement)
+ * @see TimeLimitedStatement
*/
@Override
protected Statement withPotentialTimeout(FrameworkMethod method, Object test, Statement next) {
return next;
}
+
+ private long getTimeout(Test annotation) {
+ if (annotation == null) {
+ return 0;
+ }
+ return annotation.timeout();
+ }
+
}
@Nonnull
@@ -347,19 +374,9 @@
}
/**
- * For tests with a timeout, we need to wrap the test execution in a FailOnTimeout statement
- * *before* we switch to the sandbox main thread, otherwise tests will be running on
- * FailOnTimeout's thread instead of the sandbox main thread.
- */
- protected Statement withPotentialTimeoutAroundSandboxThread(FrameworkMethod method,
- Object test, Statement next) {
- return super.withPotentialTimeout(method, test, next);
- }
-
- /**
* Disables JUnit's normal timeout mode.
*
- * @see #withPotentialTimeoutAroundSandboxThread(FrameworkMethod, Object, Statement)
+ * @see TimeLimitedStatement
*/
protected Statement withPotentialTimeout(FrameworkMethod method, Object test, Statement next) {
return next;
diff --git a/junit/src/main/java/org/robolectric/internal/TimeLimitedStatement.java b/junit/src/main/java/org/robolectric/internal/TimeLimitedStatement.java
new file mode 100644
index 0000000..53cdf98
--- /dev/null
+++ b/junit/src/main/java/org/robolectric/internal/TimeLimitedStatement.java
@@ -0,0 +1,48 @@
+package org.robolectric.internal;
+
+import java.util.concurrent.TimeUnit;
+import org.junit.runners.model.Statement;
+import org.junit.runners.model.TestTimedOutException;
+
+/**
+ * Similar to JUnit's {@link org.junit.internal.runners.statements.FailOnTimeout}, but runs the
+ * test on the current thread (with a timer on a new thread) rather than the other way around.
+ */
+class TimeLimitedStatement extends Statement {
+
+ private final long timeout;
+ private final Statement delegate;
+
+ public TimeLimitedStatement(long timeout, Statement delegate) {
+ this.timeout = timeout;
+ this.delegate = delegate;
+ }
+
+ @Override
+ public void evaluate() throws Throwable {
+ Thread testThread = Thread.currentThread();
+ Thread timeoutThread =
+ new Thread(
+ () -> {
+ try {
+ Thread.sleep(timeout);
+ testThread.interrupt();
+ } catch (InterruptedException e) {
+ // ok
+ }
+ },
+ "Robolectric time-limited test");
+ timeoutThread.start();
+
+ try {
+ delegate.evaluate();
+ } catch (InterruptedException e) {
+ Exception e2 = new TestTimedOutException(timeout, TimeUnit.MILLISECONDS);
+ e2.setStackTrace(e.getStackTrace());
+ throw e2;
+ } finally {
+ timeoutThread.interrupt();
+ timeoutThread.join();
+ }
+ }
+}
diff --git a/robolectric/src/main/java/org/robolectric/RobolectricTestRunner.java b/robolectric/src/main/java/org/robolectric/RobolectricTestRunner.java
index 802ebe8..254be7e 100644
--- a/robolectric/src/main/java/org/robolectric/RobolectricTestRunner.java
+++ b/robolectric/src/main/java/org/robolectric/RobolectricTestRunner.java
@@ -541,17 +541,17 @@
/**
* Fields in this class must be serializable using [XStream](https://x-stream.github.io/).
*/
- static class RobolectricFrameworkMethod extends FrameworkMethod {
+ static final class RobolectricFrameworkMethod extends FrameworkMethod {
private static final AtomicInteger NEXT_ID = new AtomicInteger();
private static final Map<Integer, TestExecutionContext> CONTEXT = new HashMap<>();
private final int id;
- private final @Nonnull AndroidManifest appManifest;
- private final @Nonnull Configuration configuration;
- private final @Nonnull ResourcesMode resourcesMode;
- private final @Nonnull ResModeStrategy defaultResModeStrategy;
+ @Nonnull private final AndroidManifest appManifest;
+ @Nonnull private final Configuration configuration;
+ @Nonnull private final ResourcesMode resourcesMode;
+ @Nonnull private final ResModeStrategy defaultResModeStrategy;
private final boolean alwaysIncludeVariantMarkersInName;
private boolean includeVariantMarkersInTestName = true;
@@ -620,7 +620,8 @@
}
Environment getEnvironment() {
- return getContext().environment;
+ TestExecutionContext context = getContext();
+ return context == null ? null : context.environment;
}
public boolean isLegacy() {
diff --git a/robolectric/src/main/java/org/robolectric/android/internal/AndroidEnvironment.java b/robolectric/src/main/java/org/robolectric/android/internal/AndroidEnvironment.java
old mode 100755
new mode 100644
index c50609d..d284d9c
--- a/robolectric/src/main/java/org/robolectric/android/internal/AndroidEnvironment.java
+++ b/robolectric/src/main/java/org/robolectric/android/internal/AndroidEnvironment.java
@@ -87,8 +87,8 @@
private final int apiLevel;
private boolean loggingInitialized = false;
- private Path sdkJarPath;
- private ApkLoader apkLoader;
+ private final Path sdkJarPath;
+ private final ApkLoader apkLoader;
private PackageResourceTable systemResourceTable;
public AndroidEnvironment(
@@ -394,7 +394,9 @@
static String getTestApplicationName(String applicationName) {
int lastDot = applicationName.lastIndexOf('.');
if (lastDot > -1) {
- return applicationName.substring(0, lastDot) + ".Test" + applicationName.substring(lastDot + 1);
+ return applicationName.substring(0, lastDot)
+ + ".Test"
+ + applicationName.substring(lastDot + 1);
} else {
return "Test" + applicationName;
}
@@ -424,7 +426,9 @@
* Create a file system safe directory path name for the current test.
*/
private String createTestDataDirRootPath(Method method) {
- return method.getClass().getSimpleName() + "_" + method.getName().replaceAll("[^a-zA-Z0-9.-]", "_");
+ return method.getClass().getSimpleName()
+ + "_"
+ + method.getName().replaceAll("[^a-zA-Z0-9.-]", "_");
}
@Override
diff --git a/robolectric/src/main/java/org/robolectric/internal/AndroidSandbox.java b/robolectric/src/main/java/org/robolectric/internal/AndroidSandbox.java
old mode 100755
new mode 100644
diff --git a/robolectric/src/main/java/org/robolectric/internal/SandboxFactory.java b/robolectric/src/main/java/org/robolectric/internal/SandboxFactory.java
index e0e178a..f483429 100644
--- a/robolectric/src/main/java/org/robolectric/internal/SandboxFactory.java
+++ b/robolectric/src/main/java/org/robolectric/internal/SandboxFactory.java
@@ -129,7 +129,7 @@
if (this == o) {
return true;
}
- if (o == null || getClass() != o.getClass()) {
+ if (!(o instanceof SandboxKey)) {
return false;
}
SandboxKey that = (SandboxKey) o;
diff --git a/robolectric/src/test/java/org/robolectric/BootstrapDeferringRobolectricTestRunner.java b/robolectric/src/test/java/org/robolectric/BootstrapDeferringRobolectricTestRunner.java
index abfffc2..4b039f0 100644
--- a/robolectric/src/test/java/org/robolectric/BootstrapDeferringRobolectricTestRunner.java
+++ b/robolectric/src/test/java/org/robolectric/BootstrapDeferringRobolectricTestRunner.java
@@ -143,6 +143,7 @@
return wrapped;
}
+ @Override
public void callSetUpApplicationState() {
wrapped.setUpApplicationState(method, config, appManifest);
}
diff --git a/robolectric/src/test/java/org/robolectric/android/internal/AndroidEnvironmentCreateApplicationTest.java b/robolectric/src/test/java/org/robolectric/android/internal/AndroidEnvironmentCreateApplicationTest.java
index 0281fbd..65a8cc9 100644
--- a/robolectric/src/test/java/org/robolectric/android/internal/AndroidEnvironmentCreateApplicationTest.java
+++ b/robolectric/src/test/java/org/robolectric/android/internal/AndroidEnvironmentCreateApplicationTest.java
@@ -32,27 +32,33 @@
@Test(expected = RuntimeException.class)
public void shouldThrowWhenManifestContainsBadApplicationClassName() throws Exception {
AndroidEnvironment.createApplication(
- newConfigWith("<application android:name=\"org.robolectric.BogusTestApplication\"/>)"), null);
+ newConfigWith("<application android:name=\"org.robolectric.BogusTestApplication\"/>)"),
+ null);
}
@Test
- public void shouldReturnDefaultAndroidApplicationWhenManifestDeclaresNoAppName() throws Exception {
- assertThat(AndroidEnvironment.createApplication(newConfigWith(""), null))
- .isInstanceOf(Application.class);
+ public void shouldReturnDefaultAndroidApplicationWhenManifestDeclaresNoAppName()
+ throws Exception {
+ Application application = AndroidEnvironment.createApplication(newConfigWith(""), null);
+ assertThat(application.getClass()).isEqualTo(Application.class);
}
@Test
public void shouldReturnSpecifiedApplicationWhenManifestDeclaresAppName() throws Exception {
- assertThat(AndroidEnvironment.createApplication(
- newConfigWith("<application android:name=\"org.robolectric.shadows.testing.TestApplication\"/>"), null))
- .isInstanceOf(TestApplication.class);
+ Application application =
+ AndroidEnvironment.createApplication(
+ newConfigWith(
+ "<application android:name=\"org.robolectric.shadows.testing.TestApplication\"/>"),
+ null);
+ assertThat(application.getClass()).isEqualTo(TestApplication.class);
}
- @Test public void shouldAssignThePackageNameFromTheManifest() throws Exception {
+ @Test
+ public void shouldAssignThePackageNameFromTheManifest() throws Exception {
Application application = ApplicationProvider.getApplicationContext();
assertThat(application.getPackageName()).isEqualTo("org.robolectric");
- assertThat(application).isInstanceOf(TestApplication.class);
+ assertThat(application.getClass()).isEqualTo(TestApplication.class);
}
@Test
@@ -62,51 +68,65 @@
.getRegisteredReceivers()
.clear();
- AndroidManifest appManifest = newConfigWith(
- "<application>"
- + " <receiver android:name=\"org.robolectric.fakes.ConfigTestReceiver\">"
- + " <intent-filter>\n"
- + " <action android:name=\"org.robolectric.ACTION_SUPERSET_PACKAGE\"/>\n"
- + " </intent-filter>"
- + " </receiver>"
- + "</application>");
+ AndroidManifest appManifest =
+ newConfigWith(
+ "<application>"
+ + " <receiver android:name=\"org.robolectric.fakes.ConfigTestReceiver\">"
+ + " <intent-filter>\n"
+ + " <action android:name=\"org.robolectric.ACTION_SUPERSET_PACKAGE\"/>\n"
+ + " </intent-filter>"
+ + " </receiver>"
+ + "</application>");
Application application = AndroidEnvironment.createApplication(appManifest, null);
shadowOf(application).callAttach(RuntimeEnvironment.systemContext);
registerBroadcastReceivers(application, appManifest);
List<ShadowApplication.Wrapper> receivers = shadowOf(application).getRegisteredReceivers();
assertThat(receivers).hasSize(1);
- assertThat(receivers.get(0).intentFilter.matchAction("org.robolectric.ACTION_SUPERSET_PACKAGE")).isTrue();
+ assertThat(receivers.get(0).intentFilter.matchAction("org.robolectric.ACTION_SUPERSET_PACKAGE"))
+ .isTrue();
}
- @Test public void shouldDoTestApplicationNameTransform() throws Exception {
- assertThat(AndroidEnvironment.getTestApplicationName(".Applicationz")).isEqualTo(".TestApplicationz");
- assertThat(AndroidEnvironment.getTestApplicationName("Applicationz")).isEqualTo("TestApplicationz");
- assertThat(AndroidEnvironment.getTestApplicationName("com.foo.Applicationz")).isEqualTo("com.foo.TestApplicationz");
+ @Test
+ public void shouldDoTestApplicationNameTransform() throws Exception {
+ assertThat(AndroidEnvironment.getTestApplicationName(".Applicationz"))
+ .isEqualTo(".TestApplicationz");
+ assertThat(AndroidEnvironment.getTestApplicationName("Applicationz"))
+ .isEqualTo("TestApplicationz");
+ assertThat(AndroidEnvironment.getTestApplicationName("com.foo.Applicationz"))
+ .isEqualTo("com.foo.TestApplicationz");
}
- @Test public void shouldLoadConfigApplicationIfSpecified() throws Exception {
- Application application = AndroidEnvironment.createApplication(
- newConfigWith("<application android:name=\"" + "ClassNameToIgnore" + "\"/>"),
- new Config.Builder().setApplication(TestFakeApp.class).build());
- assertThat(application).isInstanceOf(TestFakeApp.class);
+ @Test
+ public void shouldLoadConfigApplicationIfSpecified() throws Exception {
+ Application application =
+ AndroidEnvironment.createApplication(
+ newConfigWith("<application android:name=\"" + "ClassNameToIgnore" + "\"/>"),
+ new Config.Builder().setApplication(TestFakeApp.class).build());
+ assertThat(application.getClass()).isEqualTo(TestFakeApp.class);
}
- @Test public void shouldLoadConfigInnerClassApplication() throws Exception {
- Application application = AndroidEnvironment.createApplication(
- newConfigWith("<application android:name=\"" + "ClassNameToIgnore" + "\"/>"),
- new Config.Builder().setApplication(TestFakeAppInner.class).build());
- assertThat(application).isInstanceOf(TestFakeAppInner.class);
+ @Test
+ public void shouldLoadConfigInnerClassApplication() throws Exception {
+ Application application =
+ AndroidEnvironment.createApplication(
+ newConfigWith("<application android:name=\"" + "ClassNameToIgnore" + "\"/>"),
+ new Config.Builder().setApplication(TestFakeAppInner.class).build());
+ assertThat(application.getClass()).isEqualTo(TestFakeAppInner.class);
}
- @Test public void shouldLoadTestApplicationIfClassIsPresent() throws Exception {
- Application application = AndroidEnvironment.createApplication(
- newConfigWith("<application android:name=\"" + FakeApp.class.getName() + "\"/>"), null);
- assertThat(application).isInstanceOf(TestFakeApp.class);
+ @Test
+ public void shouldLoadTestApplicationIfClassIsPresent() throws Exception {
+ Application application =
+ AndroidEnvironment.createApplication(
+ newConfigWith("<application android:name=\"" + FakeApp.class.getName() + "\"/>"), null);
+ assertThat(application.getClass()).isEqualTo(TestFakeApp.class);
}
- @Test public void whenNoAppManifestPresent_shouldCreateGenericApplication() throws Exception {
- assertThat(AndroidEnvironment.createApplication(null, null)).isInstanceOf(Application.class);
+ @Test
+ public void whenNoAppManifestPresent_shouldCreateGenericApplication() throws Exception {
+ Application application = AndroidEnvironment.createApplication(null, null);
+ assertThat(application.getClass()).isEqualTo(Application.class);
}
/////////////////////////////
@@ -116,16 +136,21 @@
}
private AndroidManifest newConfigWith(String packageName, String contents) throws IOException {
- String fileContents = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n" +
- "<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n" +
- " package=\"" + packageName + "\">\n" +
- " " + contents + "\n" +
- "</manifest>\n";
+ String fileContents =
+ "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"
+ + "<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n"
+ + " package=\""
+ + packageName
+ + "\">\n"
+ + " "
+ + contents
+ + "\n"
+ + "</manifest>\n";
File f = temporaryFolder.newFile("whatever.xml");
Files.asCharSink(f, Charsets.UTF_8).write(fileContents);
return new AndroidManifest(f.toPath(), null, null);
}
- public static class TestFakeAppInner extends Application { }
+ public static class TestFakeAppInner extends Application {}
}
diff --git a/robolectric/src/test/java/org/robolectric/android/internal/AndroidEnvironmentTest.java b/robolectric/src/test/java/org/robolectric/android/internal/AndroidEnvironmentTest.java
index c759f2e..15bfe90 100644
--- a/robolectric/src/test/java/org/robolectric/android/internal/AndroidEnvironmentTest.java
+++ b/robolectric/src/test/java/org/robolectric/android/internal/AndroidEnvironmentTest.java
@@ -4,8 +4,6 @@
import static com.google.common.truth.Truth.assertThat;
import static org.junit.Assert.fail;
import static org.junit.Assume.assumeTrue;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
import android.app.Application;
import android.content.pm.ApplicationInfo;
@@ -16,6 +14,8 @@
import java.io.File;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
+import java.util.ArrayList;
+import java.util.List;
import java.util.Locale;
import java.util.concurrent.atomic.AtomicBoolean;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
@@ -94,7 +94,7 @@
res.set(RuntimeEnvironment.isMainThread());
});
t.start();
- t.join(0);
+ t.join();
assertThat(res.get()).isTrue();
assertThat(RuntimeEnvironment.isMainThread()).isFalse();
}
@@ -165,9 +165,17 @@
@Test
public void tearDownApplication_invokesOnTerminate() {
- RuntimeEnvironment.application = mock(Application.class);
+ List<String> events = new ArrayList<>();
+ RuntimeEnvironment.application =
+ new Application() {
+ @Override
+ public void onTerminate() {
+ super.onTerminate();
+ events.add("terminated");
+ }
+ };
bootstrapWrapper.tearDownApplication();
- verify(RuntimeEnvironment.application).onTerminate();
+ assertThat(events).containsExactly("terminated");
}
@Test
diff --git a/sandbox/src/main/java/org/robolectric/internal/bytecode/Sandbox.java b/sandbox/src/main/java/org/robolectric/internal/bytecode/Sandbox.java
index e09d92d..2de6db0 100644
--- a/sandbox/src/main/java/org/robolectric/internal/bytecode/Sandbox.java
+++ b/sandbox/src/main/java/org/robolectric/internal/bytecode/Sandbox.java
@@ -8,6 +8,7 @@
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
import java.util.concurrent.ThreadFactory;
import org.robolectric.shadow.api.Shadow;
import org.robolectric.util.reflector.UnsafeAccess;
@@ -76,23 +77,22 @@
}
public void runOnMainThread(Runnable runnable) {
- try {
- executorService.submit(runnable).get();
- } catch (InterruptedException e) {
- throw new RuntimeException(e);
- } catch (ExecutionException e) {
- UnsafeAccess.throwException(e.getCause());
- }
+ runOnMainThread(() -> {
+ runnable.run();
+ return null;
+ });
}
public <T> T runOnMainThread(Callable<T> callable) {
+ Future<T> future = executorService.submit(callable);
try {
- return executorService.submit(callable).get();
+ return future.get();
} catch (InterruptedException e) {
+ future.cancel(true);
throw new RuntimeException(e);
} catch (ExecutionException e) {
UnsafeAccess.throwException(e.getCause());
- throw new IllegalStateException("we shouldn't get here");
+ throw new IllegalStateException("we won't get here");
}
}
}
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowPackageManager.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowPackageManager.java
index 180288c..834baa4 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowPackageManager.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowPackageManager.java
@@ -1495,7 +1495,7 @@
/** Set value to be returned by {@link PackageManager#isSafeMode}. */
public void setSafeMode(boolean safeMode) {
- this.safeMode = safeMode;
+ ShadowPackageManager.safeMode = safeMode;
}
@Resetter