Files
ft/CodexOutput/upserver/KVGameLoadTests/RegressionSupport/ExitProbe.cs

37 lines
2.0 KiB
C#

#if KV_EXIT_REGRESSION
namespace game
{
// Boundary double for the actual QuitAct. Real UserService is verified by the Unity service host.
public class PlayFabUserService : IUserService
{
internal int Revocations,Logouts;
internal readonly TaskCompletionSource<bool> Observing=new(TaskCreationOptions.RunContinuationsAsynchronously);
internal readonly TaskCompletionSource<bool> Observed=new(TaskCreationOptions.RunContinuationsAsynchronously);
public void Logout() { Logouts++; }
internal Task CloseKVForValidationAsync() { Revocations++; return Task.CompletedTask; }
internal Task ObserveKVQuitAsync() { Observing.TrySetResult(true); return Observed.Task; }
}
}
static class ControlledExitProbe
{
[System.Runtime.CompilerServices.ModuleInitializer]
internal static void Run()
{
foreach(bool logout in new[]{true,false})
{
GameCore.Timer.Reset();
var user=new game.PlayFabUserService(); var hub=new Hub(); var ads=new Ads();
var act=new game.QuitAct { userService=user,rtService=hub,config=new Config(),adsService=ads,soundMgr=new SoundMgr() };
game.QuitStage.Logout=logout;
// Module initialization cannot block on code executing in the same module on another thread.
// Complete the boundary doubles up front; the historical async Hub cases still run unchanged.
hub.Gate.TrySetResult(true); user.Observed.TrySetResult(true);
var task=act.StartAsync(); task.GetAwaiter().GetResult();
if(user.Revocations!=1 || user.Logouts!=(logout ? 1 : 0) || !user.Observing.Task.IsCompleted) throw new Exception("KV exit boundary was skipped.");
if(!ads.Released || GameCore.Timer.Destroyed!=1) throw new Exception("Scene exit must continue after observation.");
Console.WriteLine("PASS actual QuitAct controlled revoke / Hub / bounded-observer boundary, logout="+logout);
}
}
}
#endif