test(upserver): 归档存档迁移与玩法闭环回归工具

This commit is contained in:
Liubing\LB
2026-09-28 18:16:14 +08:00
parent c4ae02def9
commit a6f5e107f8
232 changed files with 12903 additions and 0 deletions

View File

@@ -0,0 +1,8 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType><TargetFramework>net9.0</TargetFramework><ImplicitUsings>enable</ImplicitUsings>
<EnableDefaultCompileItems>false</EnableDefaultCompileItems><UseAppHost>false</UseAppHost><DefineConstants>UNITY_EDITOR</DefineConstants>
<RestoreConfigFile>$(MSBuildThisFileDirectory)../../MinimalLoginTests/NuGet.Config</RestoreConfigFile>
</PropertyGroup>
<ItemGroup><Compile Include="Program.cs.txt"/><Compile Include="../../../../Client/Assets/Scripts/Stages/QuitAct.cs"/></ItemGroup>
</Project>

View File

@@ -0,0 +1,50 @@
using game;
using game.PlayerDataStorage;
int assertions=0, failures=0;
void Check(bool ok,string message){assertions++; if(!ok) throw new Exception(message);}
foreach(bool enabled in new[]{false,true}) foreach(var status in Enum.GetValues<PlayerKVShutdownStatus>())
{
try
{
PlayerKVGameplayLoop.Enabled=enabled; PlayerKVShutdownRegistry.Process.Status=status;
UnityEditor.EditorApplication.isPlaying=true; UnityEditor.EditorApplication.StopCount=0; RootCtx.DestroyCount=0;
var act=new Probe{DestoryRoot=Array.Empty<string>()}; act.Started();
Check(RootCtx.DestroyCount==1 && act.BaseStarted,"original cleanup and base callback kept");
#if UNITY_EDITOR && !SERVICE_HOST
if(enabled)
{
Check(act.Invoked==null,"test exit must not schedule Unload/PreBoot");
Check(UnityEditor.EditorApplication.StopCount==(status==PlayerKVShutdownStatus.Ready?1:0),"stop only after registry Ready");
Check(PlayerKVShutdownRegistry.Process.Status==status && PlayerKVGameplayLoop.Enabled,"barrier and once-per-process state retained");
}
else
#endif
{
Check(act.Invoked=="Unload" && act.Delay==2f,"ordinary exit preserves delayed Unload");
Check(UnityEditor.EditorApplication.StopCount==0,"ordinary exit never stops editor");
}
Console.WriteLine($"PASS enabled={enabled} status={status}");
}
catch(Exception e){failures++; Console.WriteLine($"FAIL enabled={enabled} status={status}: {e.Message}");}
}
Console.WriteLine($"RESULT actual-QuitAct groups=10 assertions={assertions} failures={failures} requests=0");
return failures==0?0:1;
class Probe:QuitAct { public void Started()=>base.OnStarted(); }
namespace game.PlayerDataStorage {
public enum PlayerKVShutdownStatus {Ready,Pending,Failed,Cancelled,Input}
public class PlayerKVShutdownRegistry {public static PlayerKVShutdownRegistry Process=new();public PlayerKVShutdownStatus Status;public Task<PlayerKVShutdownStatus> ObserveAsync(int ms)=>Task.FromResult(Status);}
public static class PlayerKVGameplayLoop {public static bool Enabled;public static Task CloseAsync()=>Task.CompletedTask;}
}
namespace UnityEditor {public static class EditorApplication {static bool playing;public static int StopCount;public static bool isPlaying{get=>playing;set{playing=value;if(!value)StopCount++;}}}}
namespace asap.core {public class InjectAttribute:Attribute{}public interface IConfig{void Rest();}}
namespace game {public interface IUserService{void Logout();}public class PlayFabUserService:IUserService {public void Logout(){} public Task CloseKVForValidationAsync()=>Task.CompletedTask;public Task ObserveKVQuitAsync()=>Task.CompletedTask;}public static class QuitStage{public static bool Logout;}}
namespace Game {public class AGameAct {public bool BaseStarted;public string Invoked;public float Delay;protected virtual void OnDestroy(){}protected virtual void OnStarted(){BaseStarted=true;}public virtual Task<bool> StartAsync()=>Task.FromResult(true);public void Invoke(string s,float n){Invoked=s;Delay=n;}}}
namespace GameCore {public static class Timer{public static void CancelAllRegisteredTimers(){}public static void Destroy(){}}}
namespace UnityEngine {public class GameObject{public static void Destroy(object x){}public static void DestroyImmediate(object x){}public static GameObject Find(string x)=>null;}public static class Debug{public static void LogException(Exception e){}public static void Log(object message){}}}
public interface IRTService{Task ReleaseAsync();}public interface IAdsService{void Release();}
public class SoundMgr{public void Release(){}}
public static class LoadingScreen{public static void Hide(){}}
public class UIManager{public static UIManager Instance=new();public UnityEngine.GameObject gameObject=new();}
public class GameEventMgr{public static GameEventMgr Instance=new();public void Clear(){}}
public class RedPointManager{public static RedPointManager Instance=new();public void Init(){}}
public static class RootCtx{public static int DestroyCount;public static void DestoryRootCtx(){DestroyCount++;}}