Ticket #4242: rejointest_alpha20.patch

File rejointest_alpha20.patch, 13.4 KB (added by elexis, 8 years ago)

Same patch for alpha 20 (for debugging purposes only)

  • source/main.cpp

     
    459459        MountMods(paths, GetMods(args, INIT_MODS));
    460460
    461461        {
    462462            CReplayPlayer replay;
    463463            replay.Load(replayFile);
    464             replay.Replay(args.Has("serializationtest"), args.Has("ooslog"));
     464            replay.Replay(
     465                args.Has("serializationtest"),
     466                args.Has("rejointest") ? args.Get("rejointest").ToInt() : -1,
     467                args.Has("ooslog"));
    465468        }
    466469
    467470        g_VFS.reset();
    468471
    469472        CXeromyces::Terminate();
  • source/ps/GameSetup/Config.cpp

     
    171171    if (args.Has("ooslog"))
    172172        g_ConfigDB.SetValueString(CFG_COMMAND, "ooslog", "true");
    173173
    174174    if (args.Has("serializationtest"))
    175175        g_ConfigDB.SetValueString(CFG_COMMAND, "serializationtest", "true");
     176
     177    if (args.Has("rejointest"))
     178        g_ConfigDB.SetValueString(CFG_COMMAND, "rejointest", args.Get("rejointest"));
    176179}
    177180
    178181
    179182void CONFIG_Init(const CmdLineArgs& args)
    180183{
  • source/ps/Replay.cpp

     
    122122
    123123    m_Stream = new std::ifstream(path.c_str());
    124124    ENSURE(m_Stream->good());
    125125}
    126126
    127 void CReplayPlayer::Replay(bool serializationtest, bool ooslog)
     127void CReplayPlayer::Replay(bool serializationtest, int rejointestturn, bool ooslog)
    128128{
    129129    ENSURE(m_Stream);
    130130
    131131    new CProfileViewer;
    132132    new CProfileManager;
     
    138138    g_ScriptRuntime = ScriptInterface::CreateRuntime(shared_ptr<ScriptRuntime>(), runtimeSize, heapGrowthBytesGCTrigger);
    139139
    140140    g_Game = new CGame(true, false);
    141141    if (serializationtest)
    142142        g_Game->GetSimulation2()->EnableSerializationTest();
     143    if (rejointestturn > 0)
     144        g_Game->GetSimulation2()->EnableRejoinTest(rejointestturn);
    143145    if (ooslog)
    144146        g_Game->GetSimulation2()->EnableOOSLog();
    145147
    146148    // Need some stuff for terrain movement costs:
    147149    // (TODO: this ought to be independent of any graphics code)
  • source/ps/Replay.h

     
    1 /* Copyright (C) 2015 Wildfire Games.
     1/* Copyright (C) 2016 Wildfire Games.
    22 * This file is part of 0 A.D.
    33 *
    44 * 0 A.D. is free software: you can redistribute it and/or modify
    55 * it under the terms of the GNU General Public License as published by
    66 * the Free Software Foundation, either version 2 of the License, or
     
    9595public:
    9696    CReplayPlayer();
    9797    ~CReplayPlayer();
    9898
    9999    void Load(const std::string& path);
    100     void Replay(bool serializationtest, bool ooslog);
     100    void Replay(bool serializationtest, int rejointestturn, bool ooslog);
    101101
    102102private:
    103103    std::istream* m_Stream;
    104104};
    105105
  • source/simulation2/Simulation2.cpp

     
    5858class CSimulation2Impl
    5959{
    6060public:
    6161    CSimulation2Impl(CUnitManager* unitManager, shared_ptr<ScriptRuntime> rt, CTerrain* terrain) :
    6262        m_SimContext(), m_ComponentManager(m_SimContext, rt),
    63         m_EnableOOSLog(false), m_EnableSerializationTest(false),
     63        m_EnableOOSLog(false), m_EnableSerializationTest(false), m_RejoinTestTurn(-1), m_TestingRejoin(false),
     64        m_SecondaryTerrain(nullptr), m_SecondaryContext(nullptr), m_SecondaryComponentManager(nullptr), m_SecondaryLoadedScripts(nullptr),
    6465        m_MapSettings(rt->m_rt), m_InitAttributes(rt->m_rt)
    6566    {
    6667        m_SimContext.m_UnitManager = unitManager;
    6768        m_SimContext.m_Terrain = terrain;
    6869        m_ComponentManager.LoadComponentTypes();
     
    7273        // Tests won't have config initialised
    7374        if (CConfigDB::IsInitialised())
    7475        {
    7576            CFG_GET_VAL("ooslog", m_EnableOOSLog);
    7677            CFG_GET_VAL("serializationtest", m_EnableSerializationTest);
     78            CFG_GET_VAL("rejointest", m_RejoinTestTurn);
     79            if (m_RejoinTestTurn <= 0) // Handle bogus values of the arg
     80                m_RejoinTestTurn = -1;
    7781        }
    7882
    7983        m_OOSLogPath = getDateIndexSubdirectory(psLogDir() / "oos_logs");
    8084
    8185        if (m_EnableOOSLog)
    8286            debug_printf("Writing ooslogs to %s\n", m_OOSLogPath.string8().c_str());
    8387    }
    8488
    8589    ~CSimulation2Impl()
    8690    {
     91        delete m_SecondaryTerrain;
     92        delete m_SecondaryContext;
     93        delete m_SecondaryComponentManager;
     94        delete m_SecondaryLoadedScripts;
     95
    8796        UnregisterFileReloadFunc(ReloadChangedFileCB, this);
    8897    }
    8998
    9099    void ResetState(bool skipScriptedComponents, bool skipAI)
    91100    {
     
    136145    OsPath m_OOSLogPath;
    137146
    138147    // Functions and data for the serialization test mode: (see Update() for relevant comments)
    139148
    140149    bool m_EnableSerializationTest;
     150    int m_RejoinTestTurn;
     151    bool m_TestingRejoin;
     152
     153    // Secondary simulation
     154    CTerrain* m_SecondaryTerrain;
     155    CSimContext* m_SecondaryContext;
     156    CComponentManager* m_SecondaryComponentManager;
     157    std::set<VfsPath>* m_SecondaryLoadedScripts;
    141158
    142159    struct SerializationTestState
    143160    {
    144161        std::stringstream state;
    145162        std::stringstream debug;
     
    338355     * We serialize that again and compare to the original serialization (to check that
    339356     * serialize->deserialize->serialize is equivalent to serialize).
    340357     * Then we run the update on the secondary context, and check that its new serialized
    341358     * state matches the primary context after the update (to check that the simulation doesn't depend
    342359     * on anything that's not serialized).
     360     *
     361     * In rejoin test mode, the secondary simulation is initialized from serialized data at turn N, then both
     362     * simulations run independantly while comparing their states each turn. This is way faster than a
     363     * complete serialization test and allows us to reproduce OOSes on rejoin.
    343364     */
    344365
    345366    const bool serializationTestDebugDump = false; // set true to save human-readable state dumps before an error is detected, for debugging (but slow)
    346367    const bool serializationTestHash = true; // set true to save and compare hash of state
    347368
    348369    SerializationTestState primaryStateBefore;
    349370    ScriptInterface& scriptInterface = m_ComponentManager.GetScriptInterface();
    350371
    351     if (m_EnableSerializationTest)
     372    if ((int64_t) m_RejoinTestTurn == m_TurnNumber)
     373        m_TestingRejoin = true;
     374
     375    if (m_EnableSerializationTest || m_TestingRejoin)
    352376    {
    353377        ENSURE(m_ComponentManager.SerializeState(primaryStateBefore.state));
    354378        if (serializationTestDebugDump)
    355379            ENSURE(m_ComponentManager.DumpDebugState(primaryStateBefore.debug, false));
    356380        if (serializationTestHash)
    357381            ENSURE(m_ComponentManager.ComputeStateHash(primaryStateBefore.hash, false));
    358382    }
    359383
    360384    UpdateComponents(m_SimContext, turnLengthFixed, commands);
    361385
    362 
    363     if (m_EnableSerializationTest)
     386    if (m_EnableSerializationTest || (int64_t) m_RejoinTestTurn == m_TurnNumber)
    364387    {
    365         // Initialise the secondary simulation
    366         CTerrain secondaryTerrain;
    367         CSimContext secondaryContext;
    368         secondaryContext.m_Terrain = &secondaryTerrain;
    369         CComponentManager secondaryComponentManager(secondaryContext, scriptInterface.GetRuntime());
    370         secondaryComponentManager.LoadComponentTypes();
    371         std::set<VfsPath> secondaryLoadedScripts;
    372         ENSURE(LoadDefaultScripts(secondaryComponentManager, &secondaryLoadedScripts));
    373         ResetComponentState(secondaryComponentManager, false, false);
     388        // Initialize the secondary simulation
     389        delete m_SecondaryTerrain;
     390        m_SecondaryTerrain = new CTerrain();
     391
     392        delete m_SecondaryContext;
     393        m_SecondaryContext = new CSimContext();
     394        m_SecondaryContext->m_Terrain = m_SecondaryTerrain;
     395
     396        delete m_SecondaryComponentManager;
     397        m_SecondaryComponentManager = new CComponentManager(*m_SecondaryContext, scriptInterface.GetRuntime());
     398        m_SecondaryComponentManager->LoadComponentTypes();
     399
     400        delete m_SecondaryLoadedScripts;
     401        m_SecondaryLoadedScripts = new std::set<VfsPath>();
     402        ENSURE(LoadDefaultScripts(*m_SecondaryComponentManager, m_SecondaryLoadedScripts));
     403        ResetComponentState(*m_SecondaryComponentManager, false, false);
    374404
    375405        // Load the trigger scripts after we have loaded the simulation.
    376406        {
    377             JSContext* cx2 = secondaryComponentManager.GetScriptInterface().GetContext();
     407            JSContext* cx2 = m_SecondaryComponentManager->GetScriptInterface().GetContext();
    378408            JSAutoRequest rq2(cx2);
    379409            JS::RootedValue mapSettingsCloned(cx2,
    380                 secondaryComponentManager.GetScriptInterface().CloneValueFromOtherContext(
     410                m_SecondaryComponentManager->GetScriptInterface().CloneValueFromOtherContext(
    381411                    scriptInterface, m_MapSettings));
    382             ENSURE(LoadTriggerScripts(secondaryComponentManager, mapSettingsCloned, &secondaryLoadedScripts));
     412            ENSURE(LoadTriggerScripts(*m_SecondaryComponentManager, mapSettingsCloned, m_SecondaryLoadedScripts));
    383413        }
    384414
    385415        // Load the map into the secondary simulation
    386416
    387417        LDR_BeginRegistering();
     
    399429            std::wstring mapFile;
    400430            scriptInterface.GetProperty(m_InitAttributes, "map", mapFile);
    401431
    402432            VfsPath mapfilename = VfsPath(mapFile).ChangeExtension(L".pmp");
    403433            mapReader->LoadMap(mapfilename, scriptInterface.GetJSRuntime(), JS::UndefinedHandleValue,
    404                 &secondaryTerrain, NULL, NULL, NULL, NULL, NULL, NULL,
    405                 NULL, NULL, &secondaryContext, INVALID_PLAYER, true); // throws exception on failure
     434                m_SecondaryTerrain, NULL, NULL, NULL, NULL, NULL, NULL,
     435                NULL, NULL, m_SecondaryContext, INVALID_PLAYER, true); // throws exception on failure
    406436        }
    407437
    408438        LDR_EndRegistering();
    409439        ENSURE(LDR_NonprogressiveLoad() == INFO::OK);
     440        ENSURE(m_SecondaryComponentManager->DeserializeState(primaryStateBefore.state));
     441    }
    410442
    411         ENSURE(secondaryComponentManager.DeserializeState(primaryStateBefore.state));
    412 
     443    if (m_EnableSerializationTest || m_TestingRejoin)
     444    {
    413445        SerializationTestState secondaryStateBefore;
    414         ENSURE(secondaryComponentManager.SerializeState(secondaryStateBefore.state));
     446        ENSURE(m_SecondaryComponentManager->SerializeState(secondaryStateBefore.state));
    415447        if (serializationTestDebugDump)
    416             ENSURE(secondaryComponentManager.DumpDebugState(secondaryStateBefore.debug, false));
     448            ENSURE(m_SecondaryComponentManager->DumpDebugState(secondaryStateBefore.debug, false));
    417449        if (serializationTestHash)
    418             ENSURE(secondaryComponentManager.ComputeStateHash(secondaryStateBefore.hash, false));
     450            ENSURE(m_SecondaryComponentManager->ComputeStateHash(secondaryStateBefore.hash, false));
    419451
    420452        if (primaryStateBefore.state.str() != secondaryStateBefore.state.str() ||
    421453            primaryStateBefore.hash != secondaryStateBefore.hash)
    422454        {
    423455            ReportSerializationFailure(&primaryStateBefore, NULL, &secondaryStateBefore, NULL);
     
    426458        SerializationTestState primaryStateAfter;
    427459        ENSURE(m_ComponentManager.SerializeState(primaryStateAfter.state));
    428460        if (serializationTestHash)
    429461            ENSURE(m_ComponentManager.ComputeStateHash(primaryStateAfter.hash, false));
    430462
    431         UpdateComponents(secondaryContext, turnLengthFixed,
    432             CloneCommandsFromOtherContext(scriptInterface, secondaryComponentManager.GetScriptInterface(), commands));
     463        UpdateComponents(*m_SecondaryContext, turnLengthFixed,
     464            CloneCommandsFromOtherContext(scriptInterface, m_SecondaryComponentManager->GetScriptInterface(), commands));
    433465        SerializationTestState secondaryStateAfter;
    434         ENSURE(secondaryComponentManager.SerializeState(secondaryStateAfter.state));
     466        ENSURE(m_SecondaryComponentManager->SerializeState(secondaryStateAfter.state));
    435467        if (serializationTestHash)
    436             ENSURE(secondaryComponentManager.ComputeStateHash(secondaryStateAfter.hash, false));
     468            ENSURE(m_SecondaryComponentManager->ComputeStateHash(secondaryStateAfter.hash, false));
    437469
    438470        if (primaryStateAfter.state.str() != secondaryStateAfter.state.str() ||
    439471            primaryStateAfter.hash != secondaryStateAfter.hash)
    440472        {
    441473            // Only do the (slow) dumping now we know we're going to need to report it
    442474            ENSURE(m_ComponentManager.DumpDebugState(primaryStateAfter.debug, false));
    443             ENSURE(secondaryComponentManager.DumpDebugState(secondaryStateAfter.debug, false));
     475            ENSURE(m_SecondaryComponentManager->DumpDebugState(secondaryStateAfter.debug, false));
    444476
    445477            ReportSerializationFailure(&primaryStateBefore, &primaryStateAfter, &secondaryStateBefore, &secondaryStateAfter);
    446478        }
    447479    }
    448480
     
    582614    delete m;
    583615}
    584616
    585617// Forward all method calls to the appropriate CSimulation2Impl/CComponentManager methods:
    586618
     619void CSimulation2::EnableSerializationTest()
     620{
     621    m->m_EnableSerializationTest = true;
     622}
     623
     624void CSimulation2::EnableRejoinTest(int rejoinTestTurn)
     625{
     626    m->m_RejoinTestTurn = rejoinTestTurn;
     627}
     628
    587629void CSimulation2::EnableOOSLog()
    588630{
    589631    if (m->m_EnableOOSLog)
    590632        return;
    591633
    592634    m->m_EnableOOSLog = true;
    593635    debug_printf("Writing ooslogs to %s\n", m->m_OOSLogPath.string8().c_str());
    594636}
    595637
    596 void CSimulation2::EnableSerializationTest()
    597 {
    598     m->m_EnableSerializationTest = true;
    599 }
    600 
    601638void CSimulation2::SetCurrentDisplayedPlayer(int playerID)
    602639{
    603640    m->m_SimContext.SetCurrentDisplayedPlayer(playerID);
    604641}
    605642
  • source/simulation2/Simulation2.h

     
    5454    CSimulation2(CUnitManager* unitManager, shared_ptr<ScriptRuntime> rt, CTerrain* terrain);
    5555    ~CSimulation2();
    5656
    5757    void EnableOOSLog();
    5858    void EnableSerializationTest();
    59 
     59    void EnableRejoinTest(int rejoinTestTurn);
    6060    void SetCurrentDisplayedPlayer(int playerID);
    6161
    6262    /**
    6363     * Load all scripts in the specified directory (non-recursively),
    6464     * so they can register new component types and functions. This