Wait for both convoy cargo phases and use actual magazine stock. Resolve empty primary weapon ammunition from muzzle metadata and recover cleanly from failed initial settings saves. Update native fixtures, scoped cleanup guards, packaging evidence and validation documentation. Make reviewed fixture tests checkout-relative. All repository checks pass against the isolated staged tree; native resupply completion and multiplayer qualification remain outstanding.
92 lines
5.6 KiB
Python
92 lines
5.6 KiB
Python
"""Actual native-fixture startup/deadline gate, engine boundaries doubled."""
|
|
import os,sys,re
|
|
from pathlib import Path
|
|
REPO=Path(os.environ.get('ERR_REPO', Path(__file__).resolve().parents[1]))
|
|
sys.path.insert(0,str(REPO/'tests'))
|
|
from policy_harness import body,run
|
|
p=Path(os.environ.get('ERR_MEMORY_PROBE_SOURCE',REPO/'addons/core/Scripts/Game/ERR/40_Chat/ERR_NativeHQMemoryProbe.c'))
|
|
s=body(p,'int Tick(ERR_HQ hq, float now)')
|
|
# Execute the unchanged deadline/startup prefix; payload/native radio assertions
|
|
# after this gate remain the full fixture's responsibility.
|
|
s=s[:s.index(' if (!m_ValueChecked)')]+ ' }\n return 1;\n }'
|
|
s=s.replace('ERR_HQ hq','ERR_HQ* hq').replace('hq.','hq->')
|
|
run(r'''
|
|
#include <cassert>
|
|
#include <string>
|
|
using string = std::string;
|
|
struct CLI {string outcome="hq-memory"; void GetCLIParam(string,string& value){value=outcome;}} System;
|
|
struct ERR_HQ{bool ready=true;bool ERR_ProbeSquadsReady(){return ready;}};
|
|
struct Probe{bool enabled=true,m_Mode=true,m_Failed=false,m_AutoChecked=false;int m_Step=0,automatic=0,checks=0;float m_Deadline=0;bool Enabled(){return enabled;}void Check(bool,std::string){checks++;m_Failed=true;}int AutomaticConvoy(ERR_HQ*){if(automatic==1)m_AutoChecked=true;return automatic;}
|
|
METHOD
|
|
};
|
|
int main(){ERR_HQ hq;
|
|
Probe p;assert(p.Tick(&hq,1000)==0&&p.m_Deadline==151000);assert(p.Tick(&hq,130000)==0&&p.m_Deadline==151000);p.automatic=1;assert(p.Tick(&hq,145000)==1&&p.m_Deadline==265000);assert(p.Tick(&hq,200000)==1&&p.m_Deadline==265000);assert(p.Tick(&hq,265000)==1);assert(p.Tick(&hq,265001)==-1&&p.checks==1);
|
|
Probe missing;assert(missing.Tick(&hq,0)==0);assert(missing.Tick(&hq,150001)==-1&&missing.checks==1);
|
|
Probe refused;refused.Tick(&hq,0);refused.automatic=-1;assert(refused.Tick(&hq,40000)==-1&&refused.m_Deadline==150000&&!refused.m_AutoChecked);
|
|
Probe unavailable;hq.ready=false;assert(unavailable.Tick(&hq,0)==0);assert(unavailable.Tick(&hq,150001)==-1);hq.ready=true;
|
|
System.outcome="hq-awareness"; hq.ready=false; Probe awareness; assert(awareness.Tick(&hq,1000)==1 && !awareness.m_AutoChecked && awareness.m_Deadline==151000); assert(awareness.Tick(&hq,151001)==-1);
|
|
Probe invalid;invalid.enabled=false;assert(invalid.Tick(&hq,0)==-1&&invalid.m_Deadline==0);
|
|
}
|
|
'''.replace('METHOD',s))
|
|
smoke=Path(os.environ.get('ERR_SMOKE_SOURCE',REPO/'addons/core/Scripts/Game/ERR/40_Chat/ERR_NativeSmoke.c')).read_text()
|
|
assert 'if (m_ERRTestHQMemory) m_ERRSmokeDeadline = GetWorld().GetWorldTime() + 360000;' in smoke
|
|
assert 'if (m_ERRTestHQBody) m_ERRSmokeDeadline = GetWorld().GetWorldTime() + 240000;' in smoke
|
|
# Execute the actual startup selector, so enlarged full-route budgets cannot
|
|
# accidentally extend a death/radio test or shorten an existing specialized run.
|
|
start=smoke.index('m_ERRTestLostHelicopter = System.GetCLIParam(')
|
|
end=smoke.index('OnStop().Insert(ERR_StopHQPatrol);',start)
|
|
selector=smoke[start:end].replace('System.GetCLIParam("errSmokeOutcome", outcome) && ', '')
|
|
selector=selector.replace('GetWorld().GetWorldTime()', 'now').replace('ERR_NativeConvoyCoverProbe.Enabled()', 'cover')
|
|
flags=sorted(set(re.findall(r'\bm_ERRTest\w+',selector)))
|
|
run(r'''
|
|
#include <cassert>
|
|
#include <string>
|
|
using string = std::string;
|
|
float deadline(string outcome,float now,bool cover=false){
|
|
[[maybe_unused]] bool DECLARATIONS;
|
|
float m_ERRSmokeDeadline=0;
|
|
SELECTOR
|
|
return m_ERRSmokeDeadline;
|
|
}
|
|
int main(){
|
|
for(float now : {0.0f, 42000.0f}) {
|
|
for(string outcome : {"", "victory", "lost-helicopter"}) assert(deadline(outcome,now)==now+300000);
|
|
for(string outcome : {"escape-route", "player-death", "radio-network", "hq-response", "map-ownership"}) assert(deadline(outcome,now)==now+150000);
|
|
assert(deadline("hq-memory",now)==now+360000);
|
|
assert(deadline("hq-body",now)==now+240000);
|
|
assert(deadline("convoy",now)==now+540000);
|
|
assert(deadline("supply-convoys",now)==now+840000);
|
|
assert(deadline("convoy",now,true)==now+840000);
|
|
}
|
|
}
|
|
'''.replace('DECLARATIONS', ','.join(flag+'=false' for flag in flags)).replace('SELECTOR',selector))
|
|
print('PASS: bounded HQ startup/memory windows and outcome-specific full-route deadlines')
|
|
|
|
# The new route diagnostic must leave the original administrator/reroll stress
|
|
# intact and may skip only those extras, never clue or radio progression gates.
|
|
route=body(Path(os.environ.get('ERR_SMOKE_SOURCE',REPO/'addons/core/Scripts/Game/ERR/40_Chat/ERR_NativeSmoke.c')), 'bool ERR_CheckRouteExtras(float now)')
|
|
run(r'''
|
|
#include <cassert>
|
|
#include <string>
|
|
struct Probe {
|
|
bool m_ERRTestEscapeRoute=false,rerollReady=false;
|
|
int adminResult=0,adminCalls=0,rerollCalls=0,failures=0;
|
|
int ERR_ProbeAdminMenu(float){adminCalls++;return adminResult;}
|
|
bool ERR_Check(bool result,std::string){if(!result)failures++;return result;}
|
|
bool ERR_CheckIntelReroll(float){rerollCalls++;return rerollReady;}
|
|
METHOD
|
|
};
|
|
int main(){
|
|
Probe route;route.m_ERRTestEscapeRoute=true;assert(route.ERR_CheckRouteExtras(100));
|
|
assert(route.adminCalls==0&&route.rerollCalls==0&&route.failures==0);
|
|
Probe full;assert(!full.ERR_CheckRouteExtras(100)&&full.adminCalls==1&&full.rerollCalls==0);
|
|
full.adminResult=-1;assert(!full.ERR_CheckRouteExtras(200)&&full.failures==1&&full.rerollCalls==0);
|
|
full.adminResult=1;assert(!full.ERR_CheckRouteExtras(300)&&full.rerollCalls==1);
|
|
full.rerollReady=true;assert(full.ERR_CheckRouteExtras(400)&&full.rerollCalls==2);
|
|
}
|
|
'''.replace('METHOD',route))
|
|
assert 'if (!ERR_CheckRouteExtras(now)) return;' in smoke
|
|
assert 'if (!ERR_Check(m_ERRSmokeRadio.Knowledge() == 2,' in smoke
|
|
assert 'if (!ERR_Check(Phase() == ERR_Phase.EXTRACTION,' in smoke
|
|
print('PASS: explicit escape-route skips only administrator stress, preserving original full-fixture wait/failure paths')
|