mirror of
https://github.com/samsonjs/media.git
synced 2026-03-29 10:05:48 +00:00
Move Robolectric-related test utils methods to robolectricutils module
This moves TestUtil#runMainLooperUntil and TestUtil#createRobolectricConditionVariable to a new RobolectricUtil class. Also move testutil classes that use Robolectric-related utils classes (e.g. TestPlayerRunHelper, TestDownloadManagerListener). PiperOrigin-RevId: 336864959
This commit is contained in:
parent
9e1c6321ee
commit
d700627ec2
14 changed files with 137 additions and 144 deletions
|
|
@ -15,14 +15,14 @@
|
|||
*/
|
||||
package com.google.android.exoplayer2;
|
||||
|
||||
import static com.google.android.exoplayer2.robolectric.RobolectricUtil.runMainLooperUntil;
|
||||
import static com.google.android.exoplayer2.robolectric.TestPlayerRunHelper.playUntilStartOfWindow;
|
||||
import static com.google.android.exoplayer2.robolectric.TestPlayerRunHelper.runUntilPlaybackState;
|
||||
import static com.google.android.exoplayer2.robolectric.TestPlayerRunHelper.runUntilReceiveOffloadSchedulingEnabledNewState;
|
||||
import static com.google.android.exoplayer2.robolectric.TestPlayerRunHelper.runUntilSleepingForOffload;
|
||||
import static com.google.android.exoplayer2.robolectric.TestPlayerRunHelper.runUntilTimelineChanged;
|
||||
import static com.google.android.exoplayer2.testutil.FakeSampleStream.FakeSampleStreamItem.END_OF_STREAM_ITEM;
|
||||
import static com.google.android.exoplayer2.testutil.FakeSampleStream.FakeSampleStreamItem.oneByteSample;
|
||||
import static com.google.android.exoplayer2.testutil.TestPlayerRunHelper.playUntilStartOfWindow;
|
||||
import static com.google.android.exoplayer2.testutil.TestPlayerRunHelper.runUntilPlaybackState;
|
||||
import static com.google.android.exoplayer2.testutil.TestPlayerRunHelper.runUntilReceiveOffloadSchedulingEnabledNewState;
|
||||
import static com.google.android.exoplayer2.testutil.TestPlayerRunHelper.runUntilSleepingForOffload;
|
||||
import static com.google.android.exoplayer2.testutil.TestPlayerRunHelper.runUntilTimelineChanged;
|
||||
import static com.google.android.exoplayer2.testutil.TestUtil.runMainLooperUntil;
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
import static org.junit.Assert.assertArrayEquals;
|
||||
import static org.junit.Assert.assertThrows;
|
||||
|
|
@ -58,6 +58,7 @@ import com.google.android.exoplayer2.drm.DrmSessionEventListener;
|
|||
import com.google.android.exoplayer2.drm.DrmSessionManager;
|
||||
import com.google.android.exoplayer2.metadata.Metadata;
|
||||
import com.google.android.exoplayer2.metadata.id3.TextInformationFrame;
|
||||
import com.google.android.exoplayer2.robolectric.TestPlayerRunHelper;
|
||||
import com.google.android.exoplayer2.source.ClippingMediaSource;
|
||||
import com.google.android.exoplayer2.source.CompositeMediaSource;
|
||||
import com.google.android.exoplayer2.source.ConcatenatingMediaSource;
|
||||
|
|
@ -97,7 +98,6 @@ import com.google.android.exoplayer2.testutil.FakeTrackSelection;
|
|||
import com.google.android.exoplayer2.testutil.FakeTrackSelector;
|
||||
import com.google.android.exoplayer2.testutil.NoUidTimeline;
|
||||
import com.google.android.exoplayer2.testutil.TestExoPlayerBuilder;
|
||||
import com.google.android.exoplayer2.testutil.TestPlayerRunHelper;
|
||||
import com.google.android.exoplayer2.trackselection.DefaultTrackSelector;
|
||||
import com.google.android.exoplayer2.trackselection.TrackSelection;
|
||||
import com.google.android.exoplayer2.trackselection.TrackSelectionArray;
|
||||
|
|
|
|||
|
|
@ -27,8 +27,8 @@ import com.google.android.exoplayer2.MediaItem;
|
|||
import com.google.android.exoplayer2.Player;
|
||||
import com.google.android.exoplayer2.SimpleExoPlayer;
|
||||
import com.google.android.exoplayer2.robolectric.RandomizedMp3Decoder;
|
||||
import com.google.android.exoplayer2.robolectric.TestPlayerRunHelper;
|
||||
import com.google.android.exoplayer2.testutil.AutoAdvancingFakeClock;
|
||||
import com.google.android.exoplayer2.testutil.TestPlayerRunHelper;
|
||||
import com.google.android.exoplayer2.util.Assertions;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.primitives.Bytes;
|
||||
|
|
|
|||
|
|
@ -25,9 +25,9 @@ import com.google.android.exoplayer2.Player;
|
|||
import com.google.android.exoplayer2.SimpleExoPlayer;
|
||||
import com.google.android.exoplayer2.robolectric.PlaybackOutput;
|
||||
import com.google.android.exoplayer2.robolectric.ShadowMediaCodecConfig;
|
||||
import com.google.android.exoplayer2.robolectric.TestPlayerRunHelper;
|
||||
import com.google.android.exoplayer2.testutil.AutoAdvancingFakeClock;
|
||||
import com.google.android.exoplayer2.testutil.DumpFileAsserts;
|
||||
import com.google.android.exoplayer2.testutil.TestPlayerRunHelper;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
|
|
|||
|
|
@ -23,9 +23,9 @@ import com.google.android.exoplayer2.Player;
|
|||
import com.google.android.exoplayer2.SimpleExoPlayer;
|
||||
import com.google.android.exoplayer2.robolectric.PlaybackOutput;
|
||||
import com.google.android.exoplayer2.robolectric.ShadowMediaCodecConfig;
|
||||
import com.google.android.exoplayer2.robolectric.TestPlayerRunHelper;
|
||||
import com.google.android.exoplayer2.testutil.AutoAdvancingFakeClock;
|
||||
import com.google.android.exoplayer2.testutil.DumpFileAsserts;
|
||||
import com.google.android.exoplayer2.testutil.TestPlayerRunHelper;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@
|
|||
*/
|
||||
package com.google.android.exoplayer2.offline;
|
||||
|
||||
import static com.google.android.exoplayer2.robolectric.RobolectricUtil.createRobolectricConditionVariable;
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
import static java.util.Arrays.asList;
|
||||
|
||||
|
|
@ -24,11 +25,11 @@ import androidx.annotation.Nullable;
|
|||
import androidx.test.core.app.ApplicationProvider;
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4;
|
||||
import com.google.android.exoplayer2.C;
|
||||
import com.google.android.exoplayer2.robolectric.TestDownloadManagerListener;
|
||||
import com.google.android.exoplayer2.scheduler.Requirements;
|
||||
import com.google.android.exoplayer2.testutil.DownloadBuilder;
|
||||
import com.google.android.exoplayer2.testutil.DummyMainThread;
|
||||
import com.google.android.exoplayer2.testutil.DummyMainThread.TestRunnable;
|
||||
import com.google.android.exoplayer2.testutil.TestDownloadManagerListener;
|
||||
import com.google.android.exoplayer2.testutil.TestUtil;
|
||||
import com.google.android.exoplayer2.util.Assertions;
|
||||
import com.google.android.exoplayer2.util.ConditionVariable;
|
||||
|
|
@ -834,10 +835,10 @@ public class DownloadManagerTest {
|
|||
|
||||
private FakeDownloader(DownloadRequest request) {
|
||||
this.request = request;
|
||||
downloadStarted = TestUtil.createRobolectricConditionVariable();
|
||||
removeStarted = TestUtil.createRobolectricConditionVariable();
|
||||
finished = TestUtil.createRobolectricConditionVariable();
|
||||
blocker = TestUtil.createRobolectricConditionVariable();
|
||||
downloadStarted = createRobolectricConditionVariable();
|
||||
removeStarted = createRobolectricConditionVariable();
|
||||
finished = createRobolectricConditionVariable();
|
||||
blocker = createRobolectricConditionVariable();
|
||||
startCount = new AtomicInteger();
|
||||
bytesDownloaded = new AtomicInteger();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@
|
|||
*/
|
||||
package com.google.android.exoplayer2.source;
|
||||
|
||||
import static com.google.android.exoplayer2.testutil.TestUtil.runMainLooperUntil;
|
||||
import static com.google.android.exoplayer2.robolectric.RobolectricUtil.runMainLooperUntil;
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import android.net.Uri;
|
||||
|
|
|
|||
|
|
@ -26,9 +26,9 @@ import com.google.android.exoplayer2.Player;
|
|||
import com.google.android.exoplayer2.SimpleExoPlayer;
|
||||
import com.google.android.exoplayer2.robolectric.PlaybackOutput;
|
||||
import com.google.android.exoplayer2.robolectric.ShadowMediaCodecConfig;
|
||||
import com.google.android.exoplayer2.robolectric.TestPlayerRunHelper;
|
||||
import com.google.android.exoplayer2.testutil.AutoAdvancingFakeClock;
|
||||
import com.google.android.exoplayer2.testutil.DumpFileAsserts;
|
||||
import com.google.android.exoplayer2.testutil.TestPlayerRunHelper;
|
||||
import com.google.android.exoplayer2.trackselection.DefaultTrackSelector;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
|
|
|
|||
|
|
@ -31,13 +31,13 @@ import com.google.android.exoplayer2.offline.DefaultDownloaderFactory;
|
|||
import com.google.android.exoplayer2.offline.DownloadManager;
|
||||
import com.google.android.exoplayer2.offline.DownloadRequest;
|
||||
import com.google.android.exoplayer2.offline.StreamKey;
|
||||
import com.google.android.exoplayer2.robolectric.TestDownloadManagerListener;
|
||||
import com.google.android.exoplayer2.scheduler.Requirements;
|
||||
import com.google.android.exoplayer2.testutil.CacheAsserts.RequestSet;
|
||||
import com.google.android.exoplayer2.testutil.DummyMainThread;
|
||||
import com.google.android.exoplayer2.testutil.DummyMainThread.TestRunnable;
|
||||
import com.google.android.exoplayer2.testutil.FakeDataSet;
|
||||
import com.google.android.exoplayer2.testutil.FakeDataSource;
|
||||
import com.google.android.exoplayer2.testutil.TestDownloadManagerListener;
|
||||
import com.google.android.exoplayer2.testutil.TestUtil;
|
||||
import com.google.android.exoplayer2.upstream.DataSource.Factory;
|
||||
import com.google.android.exoplayer2.upstream.cache.CacheDataSource;
|
||||
|
|
|
|||
|
|
@ -34,11 +34,11 @@ import com.google.android.exoplayer2.offline.DownloadManager;
|
|||
import com.google.android.exoplayer2.offline.DownloadRequest;
|
||||
import com.google.android.exoplayer2.offline.DownloadService;
|
||||
import com.google.android.exoplayer2.offline.StreamKey;
|
||||
import com.google.android.exoplayer2.robolectric.TestDownloadManagerListener;
|
||||
import com.google.android.exoplayer2.scheduler.Scheduler;
|
||||
import com.google.android.exoplayer2.testutil.DummyMainThread;
|
||||
import com.google.android.exoplayer2.testutil.FakeDataSet;
|
||||
import com.google.android.exoplayer2.testutil.FakeDataSource;
|
||||
import com.google.android.exoplayer2.testutil.TestDownloadManagerListener;
|
||||
import com.google.android.exoplayer2.testutil.TestUtil;
|
||||
import com.google.android.exoplayer2.upstream.DataSource;
|
||||
import com.google.android.exoplayer2.upstream.cache.CacheDataSource;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,90 @@
|
|||
/*
|
||||
* Copyright (C) 2020 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.google.android.exoplayer2.robolectric;
|
||||
|
||||
import android.os.Looper;
|
||||
import com.google.android.exoplayer2.util.Clock;
|
||||
import com.google.android.exoplayer2.util.ConditionVariable;
|
||||
import com.google.android.exoplayer2.util.SystemClock;
|
||||
import com.google.common.base.Supplier;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
import org.robolectric.shadows.ShadowLooper;
|
||||
|
||||
/** Utility methods for Robolectric-based tests. */
|
||||
public final class RobolectricUtil {
|
||||
|
||||
private RobolectricUtil() {}
|
||||
|
||||
/**
|
||||
* The default timeout applied when calling {@link #runMainLooperUntil(Supplier)}. This timeout
|
||||
* should be sufficient for any condition using a Robolectric test.
|
||||
*/
|
||||
public static final long DEFAULT_TIMEOUT_MS = 10_000;
|
||||
|
||||
/**
|
||||
* Creates a {@link ConditionVariable} whose {@link ConditionVariable#block(long)} method times
|
||||
* out according to wallclock time when used in Robolectric tests.
|
||||
*/
|
||||
public static ConditionVariable createRobolectricConditionVariable() {
|
||||
return new ConditionVariable(
|
||||
new SystemClock() {
|
||||
@Override
|
||||
public long elapsedRealtime() {
|
||||
// elapsedRealtime() does not advance during Robolectric test execution, so use
|
||||
// currentTimeMillis() instead. This is technically unsafe because this clock is not
|
||||
// guaranteed to be monotonic, but in practice it will work provided the clock of the
|
||||
// host machine does not change during test execution.
|
||||
return Clock.DEFAULT.currentTimeMillis();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs tasks of the main Robolectric {@link Looper} until the {@code condition} returns {@code
|
||||
* true}.
|
||||
*
|
||||
* <p>Must be called on the main test thread.
|
||||
*
|
||||
* @param condition The condition.
|
||||
* @throws TimeoutException If the {@link #DEFAULT_TIMEOUT_MS} is exceeded.
|
||||
*/
|
||||
public static void runMainLooperUntil(Supplier<Boolean> condition) throws TimeoutException {
|
||||
runMainLooperUntil(condition, DEFAULT_TIMEOUT_MS, Clock.DEFAULT);
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs tasks of the main Robolectric {@link Looper} until the {@code condition} returns {@code
|
||||
* true}.
|
||||
*
|
||||
* @param condition The condition.
|
||||
* @param timeoutMs The timeout in milliseconds.
|
||||
* @param clock The {@link Clock} to measure the timeout.
|
||||
* @throws TimeoutException If the {@code timeoutMs timeout} is exceeded.
|
||||
*/
|
||||
public static void runMainLooperUntil(Supplier<Boolean> condition, long timeoutMs, Clock clock)
|
||||
throws TimeoutException {
|
||||
if (Looper.myLooper() != Looper.getMainLooper()) {
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
long timeoutTimeMs = clock.currentTimeMillis() + timeoutMs;
|
||||
while (!condition.get()) {
|
||||
if (clock.currentTimeMillis() >= timeoutTimeMs) {
|
||||
throw new TimeoutException();
|
||||
}
|
||||
ShadowLooper.runMainLooperOneTask();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -13,8 +13,9 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.google.android.exoplayer2.testutil;
|
||||
package com.google.android.exoplayer2.robolectric;
|
||||
|
||||
import static com.google.android.exoplayer2.robolectric.RobolectricUtil.createRobolectricConditionVariable;
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
import static java.util.concurrent.TimeUnit.MILLISECONDS;
|
||||
import static org.junit.Assert.fail;
|
||||
|
|
@ -46,8 +47,8 @@ public final class TestDownloadManagerListener implements DownloadManager.Listen
|
|||
public TestDownloadManagerListener(DownloadManager downloadManager) {
|
||||
this.downloadManager = downloadManager;
|
||||
downloadStates = new HashMap<>();
|
||||
initializedCondition = TestUtil.createRobolectricConditionVariable();
|
||||
idleCondition = TestUtil.createRobolectricConditionVariable();
|
||||
initializedCondition = createRobolectricConditionVariable();
|
||||
idleCondition = createRobolectricConditionVariable();
|
||||
downloadManager.addListener(this);
|
||||
}
|
||||
|
||||
|
|
@ -61,7 +62,7 @@ public final class TestDownloadManagerListener implements DownloadManager.Listen
|
|||
idleCondition.close();
|
||||
// If the manager is already idle the condition will be opened by the code immediately below.
|
||||
// Else it will be opened by onIdle().
|
||||
ConditionVariable checkedOnMainThread = TestUtil.createRobolectricConditionVariable();
|
||||
ConditionVariable checkedOnMainThread = createRobolectricConditionVariable();
|
||||
new Handler(downloadManager.getApplicationLooper())
|
||||
.post(
|
||||
() -> {
|
||||
|
|
@ -14,9 +14,9 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.google.android.exoplayer2.testutil;
|
||||
package com.google.android.exoplayer2.robolectric;
|
||||
|
||||
import static com.google.android.exoplayer2.testutil.TestUtil.runMainLooperUntil;
|
||||
import static com.google.android.exoplayer2.robolectric.RobolectricUtil.runMainLooperUntil;
|
||||
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
|
|
@ -48,7 +48,7 @@ public class TestPlayerRunHelper {
|
|||
*
|
||||
* @param player The {@link Player}.
|
||||
* @param expectedState The expected {@link Player.State}.
|
||||
* @throws TimeoutException If the {@link TestUtil#DEFAULT_TIMEOUT_MS default timeout} is
|
||||
* @throws TimeoutException If the {@link RobolectricUtil#DEFAULT_TIMEOUT_MS default timeout} is
|
||||
* exceeded.
|
||||
*/
|
||||
public static void runUntilPlaybackState(Player player, @Player.State int expectedState)
|
||||
|
|
@ -78,7 +78,7 @@ public class TestPlayerRunHelper {
|
|||
*
|
||||
* @param player The {@link Player}.
|
||||
* @param expectedPlayWhenReady The expected value for {@link Player#getPlayWhenReady()}.
|
||||
* @throws TimeoutException If the {@link TestUtil#DEFAULT_TIMEOUT_MS default timeout} is
|
||||
* @throws TimeoutException If the {@link RobolectricUtil#DEFAULT_TIMEOUT_MS default timeout} is
|
||||
* exceeded.
|
||||
*/
|
||||
public static void runUntilPlayWhenReady(Player player, boolean expectedPlayWhenReady)
|
||||
|
|
@ -108,7 +108,7 @@ public class TestPlayerRunHelper {
|
|||
*
|
||||
* @param player The {@link Player}.
|
||||
* @param expectedTimeline The expected {@link Timeline}.
|
||||
* @throws TimeoutException If the {@link TestUtil#DEFAULT_TIMEOUT_MS default timeout} is
|
||||
* @throws TimeoutException If the {@link RobolectricUtil#DEFAULT_TIMEOUT_MS default timeout} is
|
||||
* exceeded.
|
||||
*/
|
||||
public static void runUntilTimelineChanged(Player player, Timeline expectedTimeline)
|
||||
|
|
@ -137,7 +137,7 @@ public class TestPlayerRunHelper {
|
|||
*
|
||||
* @param player The {@link Player}.
|
||||
* @return The new {@link Timeline}.
|
||||
* @throws TimeoutException If the {@link TestUtil#DEFAULT_TIMEOUT_MS default timeout} is
|
||||
* @throws TimeoutException If the {@link RobolectricUtil#DEFAULT_TIMEOUT_MS default timeout} is
|
||||
* exceeded.
|
||||
*/
|
||||
public static Timeline runUntilTimelineChanged(Player player) throws TimeoutException {
|
||||
|
|
@ -163,7 +163,7 @@ public class TestPlayerRunHelper {
|
|||
*
|
||||
* @param player The {@link Player}.
|
||||
* @param expectedReason The expected {@link Player.DiscontinuityReason}.
|
||||
* @throws TimeoutException If the {@link TestUtil#DEFAULT_TIMEOUT_MS default timeout} is
|
||||
* @throws TimeoutException If the {@link RobolectricUtil#DEFAULT_TIMEOUT_MS default timeout} is
|
||||
* exceeded.
|
||||
*/
|
||||
public static void runUntilPositionDiscontinuity(
|
||||
|
|
@ -189,7 +189,7 @@ public class TestPlayerRunHelper {
|
|||
*
|
||||
* @param player The {@link Player}.
|
||||
* @return The raised {@link ExoPlaybackException}.
|
||||
* @throws TimeoutException If the {@link TestUtil#DEFAULT_TIMEOUT_MS default timeout} is
|
||||
* @throws TimeoutException If the {@link RobolectricUtil#DEFAULT_TIMEOUT_MS default timeout} is
|
||||
* exceeded.
|
||||
*/
|
||||
public static ExoPlaybackException runUntilError(Player player) throws TimeoutException {
|
||||
|
|
@ -214,7 +214,7 @@ public class TestPlayerRunHelper {
|
|||
*
|
||||
* @param player The {@link Player}.
|
||||
* @return The new offloadSchedulingEnabled state.
|
||||
* @throws TimeoutException If the {@link TestUtil#DEFAULT_TIMEOUT_MS default timeout} is
|
||||
* @throws TimeoutException If the {@link RobolectricUtil#DEFAULT_TIMEOUT_MS default timeout} is
|
||||
* exceeded.
|
||||
*/
|
||||
public static boolean runUntilReceiveOffloadSchedulingEnabledNewState(Player player)
|
||||
|
|
@ -241,7 +241,7 @@ public class TestPlayerRunHelper {
|
|||
*
|
||||
* @param player The {@link Player}.
|
||||
* @param expectedSleepForOffload The expected sleep of offload state.
|
||||
* @throws TimeoutException If the {@link TestUtil#DEFAULT_TIMEOUT_MS default timeout} is
|
||||
* @throws TimeoutException If the {@link RobolectricUtil#DEFAULT_TIMEOUT_MS default timeout} is
|
||||
* exceeded.
|
||||
*/
|
||||
public static void runUntilSleepingForOffload(Player player, boolean expectedSleepForOffload)
|
||||
|
|
@ -266,7 +266,7 @@ public class TestPlayerRunHelper {
|
|||
* callback has been called.
|
||||
*
|
||||
* @param player The {@link Player}.
|
||||
* @throws TimeoutException If the {@link TestUtil#DEFAULT_TIMEOUT_MS default timeout} is
|
||||
* @throws TimeoutException If the {@link RobolectricUtil#DEFAULT_TIMEOUT_MS default timeout} is
|
||||
* exceeded.
|
||||
*/
|
||||
public static void runUntilRenderedFirstFrame(SimpleExoPlayer player) throws TimeoutException {
|
||||
|
|
@ -291,7 +291,7 @@ public class TestPlayerRunHelper {
|
|||
* @param player The {@link Player}.
|
||||
* @param windowIndex The window.
|
||||
* @param positionMs The position within the window, in milliseconds.
|
||||
* @throws TimeoutException If the {@link TestUtil#DEFAULT_TIMEOUT_MS default timeout} is
|
||||
* @throws TimeoutException If the {@link RobolectricUtil#DEFAULT_TIMEOUT_MS default timeout} is
|
||||
* exceeded.
|
||||
*/
|
||||
public static void playUntilPosition(ExoPlayer player, int windowIndex, long positionMs)
|
||||
|
|
@ -329,7 +329,7 @@ public class TestPlayerRunHelper {
|
|||
*
|
||||
* @param player The {@link Player}.
|
||||
* @param windowIndex The window.
|
||||
* @throws TimeoutException If the {@link TestUtil#DEFAULT_TIMEOUT_MS default timeout} is
|
||||
* @throws TimeoutException If the {@link RobolectricUtil#DEFAULT_TIMEOUT_MS default timeout} is
|
||||
* exceeded.
|
||||
*/
|
||||
public static void playUntilStartOfWindow(ExoPlayer player, int windowIndex)
|
||||
|
|
@ -342,7 +342,7 @@ public class TestPlayerRunHelper {
|
|||
* commands on the internal playback thread.
|
||||
*
|
||||
* @param player The {@link Player}.
|
||||
* @throws TimeoutException If the {@link TestUtil#DEFAULT_TIMEOUT_MS default timeout} is
|
||||
* @throws TimeoutException If the {@link RobolectricUtil#DEFAULT_TIMEOUT_MS default timeout} is
|
||||
* exceeded.
|
||||
*/
|
||||
public static void runUntilPendingCommandsAreFullyHandled(ExoPlayer player)
|
||||
|
|
@ -13,7 +13,7 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.google.android.exoplayer2.testutil;
|
||||
package com.google.android.exoplayer2.robolectric;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
import static org.junit.Assert.assertThrows;
|
||||
|
|
@ -31,14 +31,13 @@ import java.util.concurrent.TimeoutException;
|
|||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
/** Unit test for {@link TestUtil}. */
|
||||
/** Unit test for {@link RobolectricUtil}. */
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
public class TestUtilTest {
|
||||
|
||||
public class RobolectricUtilTest {
|
||||
@Test
|
||||
public void createRobolectricConditionVariable_blockWithTimeout_timesOut()
|
||||
throws InterruptedException {
|
||||
ConditionVariable conditionVariable = TestUtil.createRobolectricConditionVariable();
|
||||
ConditionVariable conditionVariable = RobolectricUtil.createRobolectricConditionVariable();
|
||||
assertThat(conditionVariable.block(/* timeoutMs= */ 1)).isFalse();
|
||||
assertThat(conditionVariable.isOpen()).isFalse();
|
||||
}
|
||||
|
|
@ -46,7 +45,7 @@ public class TestUtilTest {
|
|||
@Test
|
||||
public void createRobolectricConditionVariable_blockWithTimeout_blocksForAtLeastTimeout()
|
||||
throws InterruptedException {
|
||||
ConditionVariable conditionVariable = TestUtil.createRobolectricConditionVariable();
|
||||
ConditionVariable conditionVariable = RobolectricUtil.createRobolectricConditionVariable();
|
||||
long startTimeMs = System.currentTimeMillis();
|
||||
assertThat(conditionVariable.block(/* timeoutMs= */ 500)).isFalse();
|
||||
long endTimeMs = System.currentTimeMillis();
|
||||
|
|
@ -57,7 +56,7 @@ public class TestUtilTest {
|
|||
public void runMainLooperUntil_withConditionAlreadyTrue_returnsImmediately() throws Exception {
|
||||
Clock mockClock = mock(Clock.class);
|
||||
|
||||
TestUtil.runMainLooperUntil(() -> true, /* timeoutMs= */ 0, mockClock);
|
||||
RobolectricUtil.runMainLooperUntil(() -> true, /* timeoutMs= */ 0, mockClock);
|
||||
|
||||
verify(mockClock, atMost(1)).currentTimeMillis();
|
||||
}
|
||||
|
|
@ -69,7 +68,7 @@ public class TestUtilTest {
|
|||
|
||||
assertThrows(
|
||||
TimeoutException.class,
|
||||
() -> TestUtil.runMainLooperUntil(() -> false, /* timeoutMs= */ 42, mockClock));
|
||||
() -> RobolectricUtil.runMainLooperUntil(() -> false, /* timeoutMs= */ 42, mockClock));
|
||||
|
||||
verify(mockClock, times(3)).currentTimeMillis();
|
||||
}
|
||||
|
|
@ -87,7 +86,7 @@ public class TestUtilTest {
|
|||
.thenReturn(false)
|
||||
.thenReturn(true);
|
||||
|
||||
TestUtil.runMainLooperUntil(mockCondition, /* timeoutMs= */ 5674, mock(Clock.class));
|
||||
RobolectricUtil.runMainLooperUntil(mockCondition, /* timeoutMs= */ 5674, mock(Clock.class));
|
||||
|
||||
verify(mockCondition, times(5)).get();
|
||||
}
|
||||
|
|
@ -25,7 +25,6 @@ import android.graphics.BitmapFactory;
|
|||
import android.graphics.Color;
|
||||
import android.media.MediaCodec;
|
||||
import android.net.Uri;
|
||||
import android.os.Looper;
|
||||
import com.google.android.exoplayer2.C;
|
||||
import com.google.android.exoplayer2.database.DatabaseProvider;
|
||||
import com.google.android.exoplayer2.database.DefaultDatabaseProvider;
|
||||
|
|
@ -38,41 +37,21 @@ import com.google.android.exoplayer2.metadata.MetadataInputBuffer;
|
|||
import com.google.android.exoplayer2.upstream.DataSource;
|
||||
import com.google.android.exoplayer2.upstream.DataSpec;
|
||||
import com.google.android.exoplayer2.util.Assertions;
|
||||
import com.google.android.exoplayer2.util.Clock;
|
||||
import com.google.android.exoplayer2.util.ConditionVariable;
|
||||
import com.google.android.exoplayer2.util.SystemClock;
|
||||
import com.google.android.exoplayer2.util.Util;
|
||||
import com.google.common.base.Supplier;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.primitives.Bytes;
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.Random;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
import org.checkerframework.checker.nullness.qual.EnsuresNonNull;
|
||||
import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
||||
|
||||
/**
|
||||
* Utility methods for tests.
|
||||
*/
|
||||
public class TestUtil {
|
||||
|
||||
/**
|
||||
* The default timeout applied when calling {@link #runMainLooperUntil(Supplier)}. This timeout
|
||||
* should be sufficient for any condition using a Robolectric test.
|
||||
*/
|
||||
public static final long DEFAULT_TIMEOUT_MS = 10_000;
|
||||
|
||||
/** Reflectively loaded Robolectric ShadowLooper#runOneTask. */
|
||||
private static @MonotonicNonNull Object shadowLooper;
|
||||
|
||||
private static @MonotonicNonNull Method runOneTaskMethod;
|
||||
|
||||
private TestUtil() {}
|
||||
|
||||
/**
|
||||
|
|
@ -457,81 +436,4 @@ public class TestUtil {
|
|||
return buffer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a {@link ConditionVariable} whose {@link ConditionVariable#block(long)} method times
|
||||
* out according to wallclock time when used in Robolectric tests.
|
||||
*/
|
||||
public static ConditionVariable createRobolectricConditionVariable() {
|
||||
return new ConditionVariable(
|
||||
new SystemClock() {
|
||||
@Override
|
||||
public long elapsedRealtime() {
|
||||
// elapsedRealtime() does not advance during Robolectric test execution, so use
|
||||
// currentTimeMillis() instead. This is technically unsafe because this clock is not
|
||||
// guaranteed to be monotonic, but in practice it will work provided the clock of the
|
||||
// host machine does not change during test execution.
|
||||
return Clock.DEFAULT.currentTimeMillis();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs tasks of the main Robolectric {@link Looper} until the {@code condition} returns {@code
|
||||
* true}.
|
||||
*
|
||||
* <p>Must be called on the main test thread.
|
||||
*
|
||||
* @param condition The condition.
|
||||
* @throws TimeoutException If the {@link #DEFAULT_TIMEOUT_MS} is exceeded.
|
||||
*/
|
||||
public static void runMainLooperUntil(Supplier<Boolean> condition) throws TimeoutException {
|
||||
runMainLooperUntil(condition, DEFAULT_TIMEOUT_MS, Clock.DEFAULT);
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs tasks of the main Robolectric {@link Looper} until the {@code condition} returns {@code
|
||||
* true}.
|
||||
*
|
||||
* @param condition The condition.
|
||||
* @param timeoutMs The timeout in milliseconds.
|
||||
* @param clock The {@link Clock} to measure the timeout.
|
||||
* @throws TimeoutException If the {@code timeoutMs timeout} is exceeded.
|
||||
*/
|
||||
public static void runMainLooperUntil(Supplier<Boolean> condition, long timeoutMs, Clock clock)
|
||||
throws TimeoutException {
|
||||
if (Looper.myLooper() != Looper.getMainLooper()) {
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
maybeInitShadowLooperAndRunOneTaskMethod();
|
||||
try {
|
||||
long timeoutTimeMs = clock.currentTimeMillis() + timeoutMs;
|
||||
while (!condition.get()) {
|
||||
if (clock.currentTimeMillis() >= timeoutTimeMs) {
|
||||
throw new TimeoutException();
|
||||
}
|
||||
runOneTaskMethod.invoke(shadowLooper);
|
||||
}
|
||||
} catch (IllegalAccessException e) {
|
||||
throw new IllegalStateException(e);
|
||||
} catch (InvocationTargetException e) {
|
||||
throw new IllegalStateException(e.getCause());
|
||||
}
|
||||
}
|
||||
|
||||
@EnsuresNonNull({"shadowLooper", "runOneTaskMethod"})
|
||||
private static void maybeInitShadowLooperAndRunOneTaskMethod() {
|
||||
if (shadowLooper != null && runOneTaskMethod != null) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
Class<?> clazz = Class.forName("org.robolectric.Shadows");
|
||||
Method shadowOfMethod =
|
||||
Assertions.checkNotNull(clazz.getDeclaredMethod("shadowOf", Looper.class));
|
||||
shadowLooper =
|
||||
Assertions.checkNotNull(shadowOfMethod.invoke(new Object(), Looper.getMainLooper()));
|
||||
runOneTaskMethod = shadowLooper.getClass().getDeclaredMethod("runOneTask");
|
||||
} catch (Exception e) {
|
||||
throw new IllegalStateException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue