Start the serializationtest at a specivic turn

This enables to only test critical game sections.
This commit is contained in:
phosit 2025-09-18 16:12:41 +02:00
parent 843f39ba55
commit c042b3ca2c
No known key found for this signature in database
GPG key ID: C9430B600671C268
7 changed files with 48 additions and 18 deletions

View file

@ -77,7 +77,7 @@ Advanced / diagnostic:
-ooslog dumps simulation state in binary and ASCII representations each turn,
files created in sim_log within the game's log folder. NOTE: game will
run much slower with this option!
-serializationtest checks simulation state each turn for serialization errors; on test
-serializationtest=N checks simulation state for serialization errors starting at turn N; on test
failure, error is displayed and logs created in oos_log within the
game's log folder. NOTE: game will run much slower with this option!
-rejointest=N simulates a rejoin and checks simulation state each turn for serialization

View file

@ -659,8 +659,15 @@ static void RunGameOrAtlas(const std::span<const char* const> argv)
{
CReplayPlayer replay;
replay.Load(replayFile);
const int serializationTestTurn{[&] {
if (!args.Has("serializationtest"))
return -1;
const CStr str{args.Get("serializationtest")};
return str.empty() ? 0 : str.ToInt();
}()};
replay.Replay(
args.Has("serializationtest"),
serializationTestTurn,
args.Has("rejointest") ? args.Get("rejointest").ToInt() : -1,
args.Has("ooslog"),
!args.Has("hashtest-full") || args.Get("hashtest-full") == "true",

View file

@ -1,4 +1,4 @@
/* Copyright (C) 2025 Wildfire Games.
/* Copyright (C) 2026 Wildfire Games.
* This file is part of 0 A.D.
*
* 0 A.D. is free software: you can redistribute it and/or modify
@ -91,7 +91,10 @@ static void ProcessCommandLineArgs(const CmdLineArgs& args)
g_ConfigDB.SetValueString(CFG_COMMAND, "ooslog", "true");
if (args.Has("serializationtest"))
g_ConfigDB.SetValueString(CFG_COMMAND, "serializationtest", "true");
{
const CStr str{args.Get("serializationtest")};
g_ConfigDB.SetValueString(CFG_COMMAND, "serializationtest", str.empty() ? "0" : str);
}
if (args.Has("rejointest"))
g_ConfigDB.SetValueString(CFG_COMMAND, "rejointest", args.Get("rejointest"));

View file

@ -191,7 +191,8 @@ void CheckReplayMods(const std::vector<Mod::ModData>& replayMods)
}
} // anonymous namespace
void CReplayPlayer::Replay(const bool serializationtest, const int rejointestturn, const bool ooslog, const bool testHashFull, const bool testHashQuick)
void CReplayPlayer::Replay(const int serializationtestturn, const int rejointestturn, const bool ooslog,
const bool testHashFull, const bool testHashQuick)
{
ENSURE(m_Stream);
@ -249,12 +250,15 @@ void CReplayPlayer::Replay(const bool serializationtest, const int rejointesttur
MountMods(Paths(g_CmdLineArgs), g_Mods.GetEnabledMods());
}
if (serializationtest && rejointestturn >= 0)
if (serializationtestturn >= 0 && rejointestturn >= 0)
LOGERROR("serializationtest and rejointest can't be activ at the same time.");
SimulationDebugOptions debugOption{};
if (serializationtest)
debugOption.test = SimulationDebugOptions::SerializationTest{};
if (serializationtestturn >= 0)
{
debugOption.test =
SimulationDebugOptions::SerializationTest{serializationtestturn};
}
if (rejointestturn >= 0)
debugOption.test = SimulationDebugOptions::RejoinTest{rejointestturn};
if (ooslog)

View file

@ -1,4 +1,4 @@
/* Copyright (C) 2025 Wildfire Games.
/* Copyright (C) 2026 Wildfire Games.
* This file is part of 0 A.D.
*
* 0 A.D. is free software: you can redistribute it and/or modify
@ -114,7 +114,8 @@ public:
~CReplayPlayer();
void Load(const OsPath& path);
void Replay(const bool serializationtest, const int rejointestturn, const bool ooslog, const bool testHashFull, const bool testHashQuick);
void Replay(const int serializationtestturn, const int rejointestturn, const bool ooslog,
const bool testHashFull, const bool testHashQuick);
private:
std::istream* m_Stream;

View file

@ -82,10 +82,14 @@ public:
m_MapSettings{cx.GetGeneralJSContext()},
// Tests won't have config initialised
m_EnableOOSLog{debugOptions.oosLog || CConfigDB::GetIfInitialised("ooslog", false)},
m_EnableSerializationTest{
std::holds_alternative<SimulationDebugOptions::SerializationTest>(debugOptions.test) ||
CConfigDB::GetIfInitialised("serializationtest", false)},
// Handle bogus values of the arg
m_SerializationTestTurn{[&]
{
const auto* serializationTestOption{
std::get_if<SimulationDebugOptions::SerializationTest>(&debugOptions.test)};
return serializationTestOption ? serializationTestOption->turn :
std::max(CConfigDB::GetIfInitialised("serializationtest", -1), -1);
}()},
m_RejoinTestTurn{[&]() -> std::optional<int>
{
const auto* rejoinTestOption{
@ -164,6 +168,8 @@ public:
// Functions and data for the serialization test mode: (see Update() for relevant comments)
std::optional<int> m_SerializationTestTurn;
bool m_TestingSerialization{false};
bool m_EnableSerializationTest{false};
std::optional<int> m_RejoinTestTurn;
bool m_TestingRejoin{false};
@ -392,12 +398,16 @@ void CSimulation2Impl::Update(int turnLength, const std::vector<SimulationComman
SerializationTestState primaryStateBefore;
const ScriptInterface& scriptInterface = m_ComponentManager.GetScriptInterface();
const bool startSerializationTest = m_SerializationTestTurn.has_value() &&
std::cmp_equal(m_SerializationTestTurn.value(), m_TurnNumber);
if (startSerializationTest)
m_TestingSerialization = true;
const bool startRejoinTest = m_RejoinTestTurn.has_value() &&
static_cast<int64_t>(m_RejoinTestTurn.value()) == m_TurnNumber;
if (startRejoinTest)
m_TestingRejoin = true;
if (m_EnableSerializationTest || m_TestingRejoin)
if (m_TestingSerialization || m_TestingRejoin)
{
ENSURE(m_ComponentManager.SerializeState(primaryStateBefore.state));
if (serializationTestDebugDump)
@ -408,8 +418,10 @@ void CSimulation2Impl::Update(int turnLength, const std::vector<SimulationComman
UpdateComponents(m_SimContext, turnLengthFixed, commands);
if (m_EnableSerializationTest || startRejoinTest)
if (m_TestingSerialization || startRejoinTest)
{
if (startSerializationTest)
debug_printf("Starting serializationtest\n");
if (startRejoinTest)
debug_printf("Initializing the secondary simulation\n");
@ -469,7 +481,7 @@ void CSimulation2Impl::Update(int turnLength, const std::vector<SimulationComman
ENSURE(m_SecondaryComponentManager->DeserializeState(primaryStateBefore.state));
}
if (m_EnableSerializationTest || m_TestingRejoin)
if (m_TestingSerialization || m_TestingRejoin)
{
SerializationTestState secondaryStateBefore;
ENSURE(m_SecondaryComponentManager->SerializeState(secondaryStateBefore.state));

View file

@ -1,4 +1,4 @@
/* Copyright (C) 2025 Wildfire Games.
/* Copyright (C) 2026 Wildfire Games.
* This file is part of 0 A.D.
*
* 0 A.D. is free software: you can redistribute it and/or modify
@ -22,7 +22,10 @@
struct SimulationDebugOptions
{
struct SerializationTest {};
struct SerializationTest
{
int turn;
};
struct RejoinTest
{
int turn;