Fix screen navigation test hijacking dummy request handler

In an upcoming change, I stumbled upon a test failure mode wherein tests
in `TestSceneScreenNavigation` would die on the following exception:

	2023-05-07 17:58:42 [error]: System.ObjectDisposedException: Cannot access a closed Realm.
	2023-05-07 17:58:42 [error]: Object name: 'Realms.Realm'.
	2023-05-07 17:58:42 [error]: at Realms.Realm.ThrowIfDisposed()
	2023-05-07 17:58:42 [error]: at Realms.Realm.All[T]()
	2023-05-07 17:58:42 [error]: at osu.Game.Beatmaps.BeatmapManager.<>c__DisplayClass25_0.<QueryBeatmap>b__0(Realm r) in D:\a\osu\osu\osu.Game\Beatmaps\BeatmapManager.cs:line 282
	2023-05-07 17:58:42 [error]: at osu.Game.Database.RealmAccess.Run[T](Func`2 action) in D:\a\osu\osu\osu.Game\Database\RealmAccess.cs:line 387
	2023-05-07 17:58:42 [error]: at osu.Game.Beatmaps.BeatmapManager.QueryBeatmap(Expression`1 query) in D:\a\osu\osu\osu.Game\Beatmaps\BeatmapManager.cs:line 282
	2023-05-07 17:58:42 [error]: at osu.Game.Tests.Visual.OnlinePlay.TestRoomRequestsHandler.<HandleRequest>g__createResponseBeatmaps|6_0(Int32[] beatmapIds, <>c__DisplayClass6_0& ) in D:\a\osu\osu\osu.Game\Tests\Visual\OnlinePlay\TestRoomRequestsHandler.cs:line 174
	2023-05-07 17:58:42 [error]: at osu.Game.Tests.Visual.OnlinePlay.TestRoomRequestsHandler.HandleRequest(APIRequest request, APIUser localUser, BeatmapManager beatmapManager) in D:\a\osu\osu\osu.Game\Tests\Visual\OnlinePlay\TestRoomRequestsHandler.cs:line 140
	2023-05-07 17:58:42 [error]: at osu.Game.Tests.Visual.TestMultiplayerComponents.<>c__DisplayClass18_0.<load>b__0(APIRequest request) in D:\a\osu\osu\osu.Game.Tests\Visual\TestMultiplayerComponents.cs:line 80
	2023-05-07 17:58:42 [error]: at osu.Game.Online.API.DummyAPIAccess.<>c__DisplayClass32_0.<Queue>b__0() in D:\a\osu\osu\osu.Game\Online\API\DummyAPIAccess.cs:line 74

Upon closer inspection, one of the tests in the scene instantiates a
`TestMultiplayerComponents` instance. `TestMultiplayerComponents`
registers a custom request handler onto `DummyAPIAccess`. Normally, this
is not an issue; however, because `TestSceneScreenNavigation` is an
`OsuGameTestScene`, and therefore has its storage recycled after every
test, this leads to the error above in the following scenario:

1. `TestPushMatchSubScreenAndPressBackButtonImmediately()` passes.
2. The test is cleaned up, and the test case's storage is recycled,
   including the test case's realm database.
3. In a subsequent test, a web request handled by the dummy API request
   handler is fired. The dummy API request handler subsequently attempts
   to access a realm that does not exist anymore.

As the usage of `TestMultiplayerComponents` is highly unorthodox in this
particular case, I'm opting for a localised fix which ensures that the
request handler is cleaned up appropriately.
This commit is contained in:
Bartłomiej Dach 2023-06-05 21:33:08 +02:00
parent 25d0f0f3da
commit 5c1abdc704
No known key found for this signature in database
1 changed files with 6 additions and 0 deletions

View File

@ -17,6 +17,7 @@
using osu.Game.Collections; using osu.Game.Collections;
using osu.Game.Configuration; using osu.Game.Configuration;
using osu.Game.Graphics.UserInterface; using osu.Game.Graphics.UserInterface;
using osu.Game.Online.API;
using osu.Game.Online.Leaderboards; using osu.Game.Online.Leaderboards;
using osu.Game.Overlays; using osu.Game.Overlays;
using osu.Game.Overlays.BeatmapListing; using osu.Game.Overlays.BeatmapListing;
@ -539,6 +540,11 @@ public void TestPushMatchSubScreenAndPressBackButtonImmediately()
AddStep("open room", () => multiplayerComponents.ChildrenOfType<LoungeSubScreen>().Single().Open()); AddStep("open room", () => multiplayerComponents.ChildrenOfType<LoungeSubScreen>().Single().Open());
AddStep("press back button", () => Game.ChildrenOfType<BackButton>().First().Action()); AddStep("press back button", () => Game.ChildrenOfType<BackButton>().First().Action());
AddWaitStep("wait two frames", 2); AddWaitStep("wait two frames", 2);
AddStep("exit lounge", () => Game.ScreenStack.Exit());
// `TestMultiplayerComponents` registers a request handler in its BDL, but never unregisters it.
// to prevent the handler living for longer than it should be, clean up manually.
AddStep("clean up multiplayer request handler", () => ((DummyAPIAccess)API).HandleRequest = null);
} }
[Test] [Test]