mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
Fix ReactHostTest.testPreload() (#37980)
Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/37980 In this diff I'm fixing the ReactHostTest.testPreload test that was broken due to concurrency issues between a task submited in bolts that interacted with the UIThread and RobolectricTestRunner blocking on the UI Thread. I created an utility method to wait for completion of the task see: https://robolectric.org/blog/2019/06/04/paused-looper/ changelog: [internal] internal Reviewed By: fkgozali Differential Revision: D46812085 fbshipit-source-id: 1a8f9de8ef22071e708280720d0384b1562dd56b
This commit is contained in:
committed by
Facebook GitHub Bot
parent
9c646ec79a
commit
2c14a0cf41
+29
-4
@@ -7,6 +7,7 @@
|
||||
|
||||
package com.facebook.react.bridgeless;
|
||||
|
||||
import static android.os.Looper.getMainLooper;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.Mockito.doNothing;
|
||||
@@ -15,17 +16,21 @@ import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.MockitoAnnotations.initMocks;
|
||||
import static org.powermock.api.mockito.PowerMockito.whenNew;
|
||||
import static org.robolectric.Shadows.shadowOf;
|
||||
|
||||
import android.app.Activity;
|
||||
import com.facebook.react.MemoryPressureRouter;
|
||||
import com.facebook.react.bridge.JSBundleLoader;
|
||||
import com.facebook.react.bridge.MemoryPressureListener;
|
||||
import com.facebook.react.bridge.UIManager;
|
||||
import com.facebook.react.bridgeless.internal.bolts.Task;
|
||||
import com.facebook.react.bridgeless.internal.bolts.TaskCompletionSource;
|
||||
import com.facebook.react.devsupport.interfaces.PackagerStatusCallback;
|
||||
import com.facebook.react.fabric.ComponentFactory;
|
||||
import com.facebook.react.uimanager.events.BlackHoleEventDispatcher;
|
||||
import com.facebook.react.uimanager.events.EventDispatcher;
|
||||
import com.facebook.testutils.shadows.ShadowSoLoader;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import org.junit.Before;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Rule;
|
||||
@@ -38,8 +43,11 @@ import org.powermock.modules.junit4.rule.PowerMockRule;
|
||||
import org.robolectric.Robolectric;
|
||||
import org.robolectric.RobolectricTestRunner;
|
||||
import org.robolectric.android.controller.ActivityController;
|
||||
import org.robolectric.annotation.Config;
|
||||
import org.robolectric.annotation.LooperMode;
|
||||
|
||||
/** Tests {@linkcom.facebook.react.bridgeless.ReactHost} */
|
||||
@Ignore("Ignore for now as these tests fail in OSS only")
|
||||
@SuppressStaticInitializationFor("com.facebook.react.fabric.ComponentFactory")
|
||||
@RunWith(RobolectricTestRunner.class)
|
||||
@PowerMockIgnore({
|
||||
@@ -49,7 +57,8 @@ import org.robolectric.android.controller.ActivityController;
|
||||
"androidx.*",
|
||||
"javax.net.ssl.*"
|
||||
})
|
||||
@Ignore("Ignore for now as these tests fail in OSS only")
|
||||
@Config(shadows = ShadowSoLoader.class)
|
||||
@LooperMode(LooperMode.Mode.PAUSED)
|
||||
@PrepareForTest({ReactHost.class, ComponentFactory.class})
|
||||
public class ReactHostTest {
|
||||
|
||||
@@ -61,6 +70,7 @@ public class ReactHostTest {
|
||||
private ReactHost mReactHost;
|
||||
private ActivityController<Activity> mActivityController;
|
||||
private ComponentFactory mComponentFactory;
|
||||
private BridgelessReactContext mBridgelessReactContext;
|
||||
|
||||
@Rule public PowerMockRule rule = new PowerMockRule();
|
||||
|
||||
@@ -76,8 +86,10 @@ public class ReactHostTest {
|
||||
mDevSupportManager = mock(BridgelessDevSupportManager.class);
|
||||
mJSBundleLoader = mock(JSBundleLoader.class);
|
||||
mComponentFactory = mock(ComponentFactory.class);
|
||||
mBridgelessReactContext = mock(BridgelessReactContext.class);
|
||||
|
||||
whenNew(ReactInstance.class).withAnyArguments().thenReturn(mReactInstance);
|
||||
whenNew(BridgelessReactContext.class).withAnyArguments().thenReturn(mBridgelessReactContext);
|
||||
whenNew(MemoryPressureRouter.class).withAnyArguments().thenReturn(mMemoryPressureRouter);
|
||||
whenNew(BridgelessDevSupportManager.class).withAnyArguments().thenReturn(mDevSupportManager);
|
||||
|
||||
@@ -110,19 +122,32 @@ public class ReactHostTest {
|
||||
assertThat(mReactHost.getDevSupportManager()).isEqualTo(mDevSupportManager);
|
||||
}
|
||||
|
||||
@Ignore("waitForCompletion is locking the test thread making the entire venice tests to timeout")
|
||||
@Test
|
||||
public void testPreload() throws Exception {
|
||||
TaskCompletionSource<Boolean> taskCompletionSource = new TaskCompletionSource<>();
|
||||
taskCompletionSource.setResult(true);
|
||||
whenNew(TaskCompletionSource.class).withAnyArguments().thenReturn(taskCompletionSource);
|
||||
doNothing().when(mDevSupportManager).isPackagerRunning(any(PackagerStatusCallback.class));
|
||||
|
||||
assertThat(mReactHost.isInstanceInitialized()).isFalse();
|
||||
|
||||
mReactHost.start().waitForCompletion();
|
||||
waitForTaskUIThread(mReactHost.start());
|
||||
|
||||
assertThat(mReactHost.isInstanceInitialized()).isTrue();
|
||||
assertThat(mReactHost.getCurrentReactContext()).isNotNull();
|
||||
verify(mMemoryPressureRouter).addMemoryPressureListener((MemoryPressureListener) any());
|
||||
}
|
||||
|
||||
private static <T> void waitForTaskUIThread(Task<T> task) throws InterruptedException {
|
||||
boolean isTaskCompleted = false;
|
||||
while (!isTaskCompleted) {
|
||||
if (!task.waitForCompletion(4, TimeUnit.MILLISECONDS)) {
|
||||
shadowOf(getMainLooper()).idle();
|
||||
} else {
|
||||
if (task.isCancelled() || task.isFaulted()) {
|
||||
throw new RuntimeException("Task was cancelled or faulted. Error: " + task.getError());
|
||||
}
|
||||
isTaskCompleted = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user