test(upserver): 归档存档迁移与玩法闭环回归工具
This commit is contained in:
59
CodexOutput/upserver/NetworkTransportTests/Program.cs
Normal file
59
CodexOutput/upserver/NetworkTransportTests/Program.cs
Normal file
@@ -0,0 +1,59 @@
|
||||
using System.Text.Json;
|
||||
using game.Account;
|
||||
using Microsoft.AspNetCore.SignalR.Client;
|
||||
var endpoint = new Uri(JsonDocument.Parse(File.ReadAllText("CodexOutput/upserver/network-proxy-address.json")).RootElement.GetProperty("url").GetString());
|
||||
if(endpoint.Host!="127.0.0.1")throw new Exception("Non-loopback fixture");
|
||||
using var control = new HttpClient { Timeout=TimeSpan.FromSeconds(10) };
|
||||
void Check(bool ok,string text){if(!ok)throw new Exception(text);}
|
||||
async Task<JsonElement> Stats()=>JsonDocument.Parse(await control.GetStringAsync(new Uri(endpoint,"__status"))).RootElement;
|
||||
using (var session = new S101AccountSession(endpoint))
|
||||
{
|
||||
foreach(var mode in new[]{"401","reset","timeout"})
|
||||
{
|
||||
await control.GetStringAsync(new Uri(endpoint,"__control?mode="+mode));
|
||||
var started=DateTime.UtcNow;
|
||||
var failed=await session.LoginAsync("102");
|
||||
var elapsed=(DateTime.UtcNow-started).TotalSeconds;
|
||||
var expected=mode=="401"?AccountLoginError.Http:mode=="reset"?AccountLoginError.Network:AccountLoginError.Timeout;
|
||||
Check(failed.Error==expected&&!session.IsAuthenticated&&session.PlayerId==null&&session.InternalId==0,"Failure isolation "+mode+"/"+failed.Error);
|
||||
Check(mode!="401"||failed.StatusCode==401,"Expected status401");
|
||||
Check(mode!="timeout"||elapsed>=14,"Production timeout not reached");
|
||||
var recovered=await session.LoginAsync("102");
|
||||
Check(recovered.Success&&session.IsAuthenticated&&session.PlayerId=="102","Login recovery "+recovered.Error);
|
||||
Check((await session.CheckAuthorizationAsync()).Success,"Recovery cookie rejected");
|
||||
Console.WriteLine($"PASS real HTTP {mode}: {failed.Error}; seconds={elapsed:F1}; retry+authorized readonly Get=OK");
|
||||
}
|
||||
}
|
||||
using var account=new S101AccountSession(endpoint);
|
||||
var mgr=new CustomServerMgr(new Config(endpoint.AbsoluteUri));
|
||||
var rt=new SignalRService(mgr,null);
|
||||
try{
|
||||
Check((await account.LoginAsync("102")).Success,"Hub account login");
|
||||
mgr.UseAccountSession(account);
|
||||
await rt.Connect();
|
||||
Check(rt.IsConnected&&await rt.Publish("Test","acceptance","before")=="OK","Initial hub RPC");
|
||||
var before=await Stats();
|
||||
await control.GetStringAsync(new Uri(endpoint,"__control?mode=drop"));
|
||||
bool observed=false;
|
||||
var deadline=DateTime.UtcNow.AddSeconds(35);
|
||||
while(DateTime.UtcNow<deadline){
|
||||
if(!rt.IsConnected)observed=true;
|
||||
if(observed&&rt.IsConnected)break;
|
||||
await Task.Delay(50);
|
||||
}
|
||||
Check(observed&&rt.IsConnected,"Real socket automatic reconnect");
|
||||
Check(await rt.Publish("Test","acceptance","after")=="OK","Post-reconnect RPC");
|
||||
var after=await Stats();
|
||||
Check(after.GetProperty("upgrades").GetInt32()>before.GetProperty("upgrades").GetInt32(),"No new real websocket upgrade");
|
||||
Check(after.GetProperty("negotiate").GetInt32()==0,"Unexpected negotiate request");
|
||||
Console.WriteLine("PASS real WebSocket dropped, disconnected observed, automatically recovered, Test=OK, negotiate=0");
|
||||
await rt.ReleaseAsync();
|
||||
await Task.Delay(500);
|
||||
var released=await Stats();
|
||||
await Task.Delay(2500);
|
||||
var stable=await Stats();
|
||||
Check(!rt.IsConnected&&stable.GetProperty("active").GetInt32()==0&&stable.GetProperty("upgrades").GetInt32()==released.GetProperty("upgrades").GetInt32(),"Release leaked or reconnected");
|
||||
Console.WriteLine("PASS ReleaseAsync: active sockets=0, no late reconnect");
|
||||
Console.WriteLine("SignalR DLL="+typeof(HubConnection).Assembly.GetName().Version);
|
||||
Console.WriteLine("Fixture counters="+stable.GetRawText());
|
||||
}finally{await rt.ReleaseAsync();mgr.ClearAccountSession();}
|
||||
Reference in New Issue
Block a user