Files
Viano-Core/tests/clientless/test_browser_participants.py
T

54 lines
3.2 KiB
Python

"""Exercise real CPC admission with concrete participants and live config reloads."""
from pathlib import Path
import subprocess,tempfile
root=Path(__file__).resolve().parents[2]
stubs=r'''
#pragma once
#include <string>
#include <unordered_map>
struct ObjectGuid{unsigned id;};
struct WorldSession{bool bot=false,open=true,logout=false;bool IsClientless()const{return bot;}bool HasOpenRealmConnection()const{return open;}bool PlayerLogout()const{return logout;}};
struct Player{WorldSession session;WorldSession*GetSession()const{return const_cast<WorldSession*>(&session);}};
struct Config{std::unordered_map<std::string,bool> values;bool GetBoolDefault(std::string const&key,bool fallback){auto found=values.find(key);return found==values.end()?fallback:found->second;}};
inline Config config;inline Config*sConfigMgr=&config;
namespace ObjectAccessor{inline std::unordered_map<unsigned,Player*> players;inline Player*FindConnectedPlayer(ObjectGuid guid){auto found=players.find(guid.id);return found==players.end()?nullptr:found->second;}}
'''
code=r'''
#include "ClientlessBrowserPolicy.h"
#include <cassert>
int main(){
using namespace ClientlessBrowserPolicy;
Player bot{{true}},human{{false}},unrelated{{false}};
ObjectAccessor::players={{1,&bot},{2,&human},{3,&unrelated}};
assert(!CanMatch({{1}},Kind::Dungeon)); // unrelated waiting human cannot qualify
assert(CanMatch({{1},{2}},Kind::Dungeon));
human.session.open=false;
assert(!CanMatch({{1},{2}},Kind::Dungeon)); // still registered during network-disconnect grace
human.session.open=true;human.session.logout=true;
assert(!CanMatch({{1},{2}},Kind::Dungeon));human.session.logout=false;
ObjectAccessor::players.erase(2);
assert(!CanMatch({{1},{2}},Kind::Dungeon)); // last actual human disconnected
ObjectAccessor::players[2]=&human;
assert(!CanMatch({{1},{2}},Kind::Raid));assert(!CanMatch({{1},{2}},Kind::Battleground));
config.values["Clientless.Browser.Raid.JoinEnabled"]=true;
assert(CanMatch({{1},{2}},Kind::Raid));assert(!CanMatch({{1}},Kind::Raid));
config.values["Clientless.Browser.AllowBotOnlyTests"]=true;
assert(CanMatch({{1}},Kind::Raid));
config.values["Clientless.Browser.Raid.QueueEnabled"]=false;
assert(!CanMatch({{1}},Kind::Raid));assert(!CanMatch({{1},{2}},Kind::Raid));
assert(CanMatch({{2}},Kind::Raid)); // human-only behavior is independent of CPC switches
config.values["Clientless.Browser.Battleground.JoinEnabled"]=true;
assert(CanMatch({{1}},Kind::Battleground));
config.values["Clientless.Browser.AllowBotOnlyTests"]=false;
assert(!CanMatch({{1}},Kind::Battleground));assert(CanMatch({{1},{2}},Kind::Battleground));
assert(!CanMatch({},Kind::Battleground));
}
'''
with tempfile.TemporaryDirectory() as directory:
p=Path(directory);(p/'types.h').write_text(stubs)
for name in ['Config.h','ObjectAccessor.h','Player.h','WorldSession.h']:(p/name).write_text('#include "types.h"\n')
(p/'participants.cpp').write_text(code)
subprocess.run(['g++','-std=c++17','-I'+str(p),'-I'+str(root/'src/server/game/World'),str(p/'participants.cpp'),'-o',str(p/'participants')],check=True)
subprocess.run([str(p/'participants')],check=True)
print('Production participant gate: exact party, disconnect, live switches, bot-only tests and independent human groups passed.')