Files
EscapistsReintroduced/tests/test_community_statistics.py
T
2026-10-30 14:19:39 +01:00

79 lines
5.5 KiB
Python

"""Production map-response validation and delayed delivery, with engine JSON/UI doubled."""
from policy_harness import ROOT, body, run
base = ROOT/'addons/core/Scripts/Game/ERR/00_Core'
p = base/'ERR_CommunityStatistics.c'
valid = body(p, 'bool Valid(')
matches = body(p, 'bool Matches(').replace('server.', 'server->').replace('allServers.', 'allServers->')
callbacks = '\n'.join(body(base/'ERR_Telemetry.c', name) for name in ['protected void CommunityUnavailable(', 'protected void UpdateCommunity('])
for a,b in [
('protected ', ''), ('RestCallback callback','RestCallback* callback'), ('callback.', 'callback->'),
('JsonLoadContext sent = new JsonLoadContext()', 'Json sent'), ('JsonLoadContext reply = new JsonLoadContext()', 'Json reply'),
('ERR_CommunityStatistics community;', 'Community* community = nullptr;'), ('community.', 'community->'),
('m_Mode.ERR_PublishCommunityStatistics(', 'mode.Publish('), ('m_State.serverId','serverId'),
('GetGame().GetWorldFile()', 'world'),
]: callbacks=callbacks.replace(a,b)
run(r'''
#include <cassert>
#include <string>
struct string:std::string {using std::string::string;using std::string::operator=;bool IsEmpty()const{return empty();}int Length()const{return size();}};
struct Record {int wins=2,losses=1,completed=3,partialMissions=0;
'''+valid+r'''
};
struct Community {int schemaVersion=1;string serverId="server",missionId="mission",eventId="final",terrain="map",outcome="victory";Record local,global;Record* server=&local;Record* allServers=&global;
'''+matches+r'''
string Summary(){return "map record";}
} result;
struct Json {
string input;
bool LoadFromString(string v){input=v;return v=="old"||v=="final"||v=="response";}
bool ReadValue(string,string& value){value=input;return true;}
bool ReadValue(string,Community*& value){value=&result;return true;}
};
struct RestCallback {string data="response";string GetData(){return data;}};
struct Service {
bool m_Ended=true,current=true,m_CommunityReady=false;string m_FinalEventId="final",m_FinalOutcome="victory",m_InFlight="final",serverId="server",m_MissionId="mission",world="map";
struct Mode {int writes=0;string text;void Publish(string v){writes++;text=v;}} mode;
bool Current(){return current;}
'''+callbacks+r'''
};
int main(){
assert(result.Matches("server","mission","final","map","victory"));
assert(!result.Matches("other","mission","final","map","victory"));
assert(!result.Matches("server","old","final","map","victory"));
assert(!result.Matches("server","mission","old-event","map","victory"));
assert(!result.Matches("server","mission","final","another-map","victory"));
assert(!result.Matches("server","mission","final","map","defeat"));
result.schemaVersion=2;assert(!result.Matches("server","mission","final","map","victory"));result.schemaVersion=1;
result.global.wins=1;result.global.completed=2;assert(!result.Matches("server","mission","final","map","victory"));result.global=Record{};
result.local.wins=-1;assert(!result.local.Valid());result.local=Record{};
result.local.completed=4;assert(!result.local.Valid());result.local=Record{};
result.local.partialMissions=4;assert(!result.local.Valid());result.local=Record{};
Service service;RestCallback cb;
service.m_InFlight="old";service.UpdateCommunity(&cb);assert(service.mode.writes==0);
service.m_InFlight="final";service.current=false;service.UpdateCommunity(&cb);assert(service.mode.writes==0);
service.current=true;service.m_Ended=false;service.UpdateCommunity(&cb);assert(service.mode.writes==0);
service.m_Ended=true;service.UpdateCommunity(&cb);assert(service.mode.text=="map record");
int receivedWrites=service.mode.writes;service.CommunityUnavailable();assert(service.mode.writes==receivedWrites); // an older queued upload failing cannot erase confirmed totals
service.m_CommunityReady=false;
result.terrain="other-map";service.UpdateCommunity(&cb);assert(service.mode.text.find("unavailable")!=std::string::npos);result.terrain="map";
service.UpdateCommunity(&cb);assert(service.mode.text=="map record"); // later valid retry refreshes the fallback
service.m_CommunityReady=false;
cb.data="invalid-json";service.UpdateCommunity(&cb);assert(service.mode.text.find("unavailable")!=std::string::npos);
cb.data=string(8193,'x');service.UpdateCommunity(&cb);assert(service.mode.text.find("unavailable")!=std::string::npos);
cb.data="response";service.m_FinalOutcome="interrupted";int before=service.mode.writes;service.UpdateCommunity(&cb);assert(service.mode.writes==before);
service.m_FinalOutcome="defeat";result.outcome="defeat";service.UpdateCommunity(&cb);assert(service.mode.text=="map record");
service.m_CommunityReady=false;
result.local.losses=0;result.local.completed=2;service.UpdateCommunity(&cb);assert(service.mode.text.find("unavailable")!=std::string::npos);
}
''')
mode=(base/'ERR_RoundStatisticsLifecycle.c').read_text()
assert '[RplProp(onRplName: "ERR_OnRoundStatisticsReplicated")]\n protected string m_ERRCommunitySummary' in mode
publish=body(base/'ERR_RoundStatisticsLifecycle.c','void ERR_PublishCommunityStatistics(')
assert '!Replication.IsServer()' in publish and 'Replication.BumpMe(); ERR_OnRoundStatisticsReplicated();' in publish
assert 'm_ERRCommunitySummary + "\\n\\n" + m_ERRRoundSummary' in mode
sender=(base/'ERR_Telemetry.c').read_text()
assert 'm_State.pending.InsertAt(payload, 0);' in sender
assert 'GetGame().GetCallqueue().CallLater(Pulse, 1, false)' in sender
print('PASS: map/server/mission/event/outcome validation, bounded counters, stale delivery exclusion, current-round refresh and unavailable recovery')