From c2e81052e8fd2588b911d5a56eeac37dd74804b4 Mon Sep 17 00:00:00 2001 From: tianyifeng Date: Wed, 28 Aug 2024 07:13:31 -0700 Subject: [PATCH] Fix flakiness in ExoPlayerTest In the flaky test `ExoPlayerTest.loading_withLargeAllocationCausingOom_playsRemainingMediaAndThenThrows`, it is indeterministic that when the message `MSG_IO_EXCEPTION` from the loader thread will arrive on the playback looper. If it arrives after `MSG_PERIOD_PREPARED`, then the period can continue loading and get the three samples written to the `SampleQueue` before the intentional OOM surfacing to the `ExoPlayerImplInternal`, otherwise, the OOM will be detected by `ExoPlayerImplInternal` very early and the player disallows to load three samples, which will cause the assertion to fail. As we are expecting the three samples to play until the playback fails, we should assume that the `Loader` encounters the OOM after those samples loaded, thus we need to put this trigger a bit later until the `SampleStreamItem`s are handled by the `FakeSampleStream`. This could be checked by the return value of `FakeMediaPeriod.continueLoading` (super class implementation). However, `FakeMediaPeriod.continueLoading` originally always returns `true`, which is not aligned with the javadoc of `MediaPeriod.continueLoading`: "return `true` if progress was made, meaning that `getNextLoadPositionUs()` will return a different value than prior to the call, `false` otherwise." then we should also modify that logic. PiperOrigin-RevId: 668438316 --- .../test/java/androidx/media3/exoplayer/ExoPlayerTest.java | 4 ++-- .../main/java/androidx/media3/test/utils/FakeMediaPeriod.java | 4 +++- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/libraries/exoplayer/src/test/java/androidx/media3/exoplayer/ExoPlayerTest.java b/libraries/exoplayer/src/test/java/androidx/media3/exoplayer/ExoPlayerTest.java index 2984802526..751fbd8cf2 100644 --- a/libraries/exoplayer/src/test/java/androidx/media3/exoplayer/ExoPlayerTest.java +++ b/libraries/exoplayer/src/test/java/androidx/media3/exoplayer/ExoPlayerTest.java @@ -9449,8 +9449,8 @@ public class ExoPlayerTest { @Override public boolean continueLoading(LoadingInfo loadingInfo) { - super.continueLoading(loadingInfo); - if (!loader.isLoading()) { + boolean progressMade = super.continueLoading(loadingInfo); + if (progressMade && !loader.isLoading()) { loader.startLoading( loadable, new FakeLoaderCallback(), /* defaultMinRetryCount= */ 1); } diff --git a/libraries/test_utils/src/main/java/androidx/media3/test/utils/FakeMediaPeriod.java b/libraries/test_utils/src/main/java/androidx/media3/test/utils/FakeMediaPeriod.java index 79e64fda5b..a8b9c06b5f 100644 --- a/libraries/test_utils/src/main/java/androidx/media3/test/utils/FakeMediaPeriod.java +++ b/libraries/test_utils/src/main/java/androidx/media3/test/utils/FakeMediaPeriod.java @@ -363,10 +363,12 @@ public class FakeMediaPeriod implements MediaPeriod { @Override public boolean continueLoading(LoadingInfo loadingInfo) { + boolean progressMade = false; for (FakeSampleStream sampleStream : sampleStreams) { sampleStream.writeData(loadingInfo.playbackPositionUs); + progressMade = true; } - return true; + return progressMade; } @Override