41 lines
3.3 KiB
C#
41 lines
3.3 KiB
C#
using System.Reflection;
|
|
using System.Security.Cryptography;
|
|
using Newtonsoft.Json;
|
|
|
|
var root=Path.GetFullPath(Path.Combine("CodexOutput/upserver/KVGameplayLoopTests/runs",Guid.NewGuid().ToString("N")));
|
|
Directory.CreateDirectory(root);
|
|
int assertions=0;
|
|
void Check(bool yes,string why){assertions++;if(!yes)throw new Exception(why);}
|
|
try {
|
|
var type=Assembly.GetExecutingAssembly().GetType("game.PlayerDataStorage.PlayerKVLoopPermit");
|
|
Check(type!=null,"Missing approved loop permit validation");
|
|
object Load(string file)=>type.GetMethod("Read",BindingFlags.Static|BindingFlags.NonPublic).Invoke(null,new object[]{file});
|
|
void Reject(string file,string why){bool bad=false;try{Load(file);}catch(TargetInvocationException e){bad=e.InnerException is InvalidOperationException;}Check(bad,why);}
|
|
var backup=Path.Combine(root,"backup.json");File.WriteAllText(backup,JsonConvert.SerializeObject(new{playerId="101",api="http://s101.local:18080/",data=new Dictionary<string,string>{{"NewPlayerDataDic","{}"},{"k","v"}}}));
|
|
var digest=Convert.ToHexString(SHA256.HashData(File.ReadAllBytes(backup)));
|
|
var permit=Path.Combine(root,"permit.json");
|
|
void Put(string id="101",string api="http://s101.local:18080/",string hash=null,string[] keys=null)=>File.WriteAllText(permit,JsonConvert.SerializeObject(new{Version=1,Enabled=true,PlayerId=id,Api=api,BackupPath=backup,BackupSha256=hash??digest,AllowedKeys=keys??new[]{"NewPlayerDataDic","k"}}));
|
|
Put();var value=Load(permit);Check(value!=null,"valid explicit permit");
|
|
Put(id:"102");Reject(permit,"backup account must match");
|
|
Put(id:"103");Reject(permit,"outside user-selected accounts");
|
|
Put(api:"http://elsewhere.invalid/");Reject(permit,"fixed formal API");
|
|
Put(hash:new string('0',64));Reject(permit,"backup integrity");
|
|
Put(keys:Array.Empty<string>());Reject(permit,"no empty permission");
|
|
Put(keys:new[]{"k"});Reject(permit,"core whole-save permission required");
|
|
Put(keys:new[]{"NewPlayerDataDic","new-unbacked-key"});Reject(permit,"no keys absent from backup without new reviewed fixture");
|
|
Put(keys:new[]{"NewPlayerDataDic","NewPlayerDataDic"});Reject(permit,"duplicate key permission rejected");
|
|
var originalBackup=File.ReadAllBytes(backup);
|
|
File.WriteAllText(backup,JsonConvert.SerializeObject(new{playerId="101",api="http://s101.local:18080/",data=new Dictionary<string,string>()}));
|
|
digest=Convert.ToHexString(SHA256.HashData(File.ReadAllBytes(backup)));
|
|
Put(keys:new[]{"NewPlayerDataDic"});Reject(permit,"actual empty existing save cannot enable loop");
|
|
File.WriteAllBytes(backup,originalBackup);digest=Convert.ToHexString(SHA256.HashData(originalBackup));
|
|
Put();value=Load(permit);
|
|
var claim=type.GetMethod("Claim",BindingFlags.Static|BindingFlags.NonPublic);
|
|
string Claim(string instance)=>(string)claim.Invoke(null,new object[]{root,instance});
|
|
var marker=Claim("process-1");Check(File.Exists(marker),"durable claim");
|
|
bool denied=false;try{Claim("process-1");}catch(TargetInvocationException e){denied=e.InnerException is IOException;}Check(denied,"same process and reload rejected");
|
|
Check(File.Exists(Claim("process-2")),"new process can claim");
|
|
Check(File.Exists(marker),"old process mark retained");
|
|
Console.WriteLine($"PASS permit-and-process-claim assertions={assertions} root={root}");return 0;
|
|
}catch(Exception e){Console.WriteLine($"FAIL assertions={assertions} {e}");return 1;}
|