Ticket #4242: rejointest_alpha20.patch
File rejointest_alpha20.patch, 13.4 KB (added by , 8 years ago) |
---|
-
source/main.cpp
459 459 MountMods(paths, GetMods(args, INIT_MODS)); 460 460 461 461 { 462 462 CReplayPlayer replay; 463 463 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")); 465 468 } 466 469 467 470 g_VFS.reset(); 468 471 469 472 CXeromyces::Terminate(); -
source/ps/GameSetup/Config.cpp
171 171 if (args.Has("ooslog")) 172 172 g_ConfigDB.SetValueString(CFG_COMMAND, "ooslog", "true"); 173 173 174 174 if (args.Has("serializationtest")) 175 175 g_ConfigDB.SetValueString(CFG_COMMAND, "serializationtest", "true"); 176 177 if (args.Has("rejointest")) 178 g_ConfigDB.SetValueString(CFG_COMMAND, "rejointest", args.Get("rejointest")); 176 179 } 177 180 178 181 179 182 void CONFIG_Init(const CmdLineArgs& args) 180 183 { -
source/ps/Replay.cpp
122 122 123 123 m_Stream = new std::ifstream(path.c_str()); 124 124 ENSURE(m_Stream->good()); 125 125 } 126 126 127 void CReplayPlayer::Replay(bool serializationtest, bool ooslog)127 void CReplayPlayer::Replay(bool serializationtest, int rejointestturn, bool ooslog) 128 128 { 129 129 ENSURE(m_Stream); 130 130 131 131 new CProfileViewer; 132 132 new CProfileManager; … … 138 138 g_ScriptRuntime = ScriptInterface::CreateRuntime(shared_ptr<ScriptRuntime>(), runtimeSize, heapGrowthBytesGCTrigger); 139 139 140 140 g_Game = new CGame(true, false); 141 141 if (serializationtest) 142 142 g_Game->GetSimulation2()->EnableSerializationTest(); 143 if (rejointestturn > 0) 144 g_Game->GetSimulation2()->EnableRejoinTest(rejointestturn); 143 145 if (ooslog) 144 146 g_Game->GetSimulation2()->EnableOOSLog(); 145 147 146 148 // Need some stuff for terrain movement costs: 147 149 // (TODO: this ought to be independent of any graphics code) -
source/ps/Replay.h
1 /* Copyright (C) 201 5Wildfire Games.1 /* Copyright (C) 2016 Wildfire Games. 2 2 * This file is part of 0 A.D. 3 3 * 4 4 * 0 A.D. is free software: you can redistribute it and/or modify 5 5 * it under the terms of the GNU General Public License as published by 6 6 * the Free Software Foundation, either version 2 of the License, or … … 95 95 public: 96 96 CReplayPlayer(); 97 97 ~CReplayPlayer(); 98 98 99 99 void Load(const std::string& path); 100 void Replay(bool serializationtest, bool ooslog);100 void Replay(bool serializationtest, int rejointestturn, bool ooslog); 101 101 102 102 private: 103 103 std::istream* m_Stream; 104 104 }; 105 105 -
source/simulation2/Simulation2.cpp
58 58 class CSimulation2Impl 59 59 { 60 60 public: 61 61 CSimulation2Impl(CUnitManager* unitManager, shared_ptr<ScriptRuntime> rt, CTerrain* terrain) : 62 62 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), 64 65 m_MapSettings(rt->m_rt), m_InitAttributes(rt->m_rt) 65 66 { 66 67 m_SimContext.m_UnitManager = unitManager; 67 68 m_SimContext.m_Terrain = terrain; 68 69 m_ComponentManager.LoadComponentTypes(); … … 72 73 // Tests won't have config initialised 73 74 if (CConfigDB::IsInitialised()) 74 75 { 75 76 CFG_GET_VAL("ooslog", m_EnableOOSLog); 76 77 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; 77 81 } 78 82 79 83 m_OOSLogPath = getDateIndexSubdirectory(psLogDir() / "oos_logs"); 80 84 81 85 if (m_EnableOOSLog) 82 86 debug_printf("Writing ooslogs to %s\n", m_OOSLogPath.string8().c_str()); 83 87 } 84 88 85 89 ~CSimulation2Impl() 86 90 { 91 delete m_SecondaryTerrain; 92 delete m_SecondaryContext; 93 delete m_SecondaryComponentManager; 94 delete m_SecondaryLoadedScripts; 95 87 96 UnregisterFileReloadFunc(ReloadChangedFileCB, this); 88 97 } 89 98 90 99 void ResetState(bool skipScriptedComponents, bool skipAI) 91 100 { … … 136 145 OsPath m_OOSLogPath; 137 146 138 147 // Functions and data for the serialization test mode: (see Update() for relevant comments) 139 148 140 149 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; 141 158 142 159 struct SerializationTestState 143 160 { 144 161 std::stringstream state; 145 162 std::stringstream debug; … … 338 355 * We serialize that again and compare to the original serialization (to check that 339 356 * serialize->deserialize->serialize is equivalent to serialize). 340 357 * Then we run the update on the secondary context, and check that its new serialized 341 358 * state matches the primary context after the update (to check that the simulation doesn't depend 342 359 * 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. 343 364 */ 344 365 345 366 const bool serializationTestDebugDump = false; // set true to save human-readable state dumps before an error is detected, for debugging (but slow) 346 367 const bool serializationTestHash = true; // set true to save and compare hash of state 347 368 348 369 SerializationTestState primaryStateBefore; 349 370 ScriptInterface& scriptInterface = m_ComponentManager.GetScriptInterface(); 350 371 351 if (m_EnableSerializationTest) 372 if ((int64_t) m_RejoinTestTurn == m_TurnNumber) 373 m_TestingRejoin = true; 374 375 if (m_EnableSerializationTest || m_TestingRejoin) 352 376 { 353 377 ENSURE(m_ComponentManager.SerializeState(primaryStateBefore.state)); 354 378 if (serializationTestDebugDump) 355 379 ENSURE(m_ComponentManager.DumpDebugState(primaryStateBefore.debug, false)); 356 380 if (serializationTestHash) 357 381 ENSURE(m_ComponentManager.ComputeStateHash(primaryStateBefore.hash, false)); 358 382 } 359 383 360 384 UpdateComponents(m_SimContext, turnLengthFixed, commands); 361 385 362 363 if (m_EnableSerializationTest) 386 if (m_EnableSerializationTest || (int64_t) m_RejoinTestTurn == m_TurnNumber) 364 387 { 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); 374 404 375 405 // Load the trigger scripts after we have loaded the simulation. 376 406 { 377 JSContext* cx2 = secondaryComponentManager.GetScriptInterface().GetContext();407 JSContext* cx2 = m_SecondaryComponentManager->GetScriptInterface().GetContext(); 378 408 JSAutoRequest rq2(cx2); 379 409 JS::RootedValue mapSettingsCloned(cx2, 380 secondaryComponentManager.GetScriptInterface().CloneValueFromOtherContext(410 m_SecondaryComponentManager->GetScriptInterface().CloneValueFromOtherContext( 381 411 scriptInterface, m_MapSettings)); 382 ENSURE(LoadTriggerScripts( secondaryComponentManager, mapSettingsCloned, &secondaryLoadedScripts));412 ENSURE(LoadTriggerScripts(*m_SecondaryComponentManager, mapSettingsCloned, m_SecondaryLoadedScripts)); 383 413 } 384 414 385 415 // Load the map into the secondary simulation 386 416 387 417 LDR_BeginRegistering(); … … 399 429 std::wstring mapFile; 400 430 scriptInterface.GetProperty(m_InitAttributes, "map", mapFile); 401 431 402 432 VfsPath mapfilename = VfsPath(mapFile).ChangeExtension(L".pmp"); 403 433 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 failure434 m_SecondaryTerrain, NULL, NULL, NULL, NULL, NULL, NULL, 435 NULL, NULL, m_SecondaryContext, INVALID_PLAYER, true); // throws exception on failure 406 436 } 407 437 408 438 LDR_EndRegistering(); 409 439 ENSURE(LDR_NonprogressiveLoad() == INFO::OK); 440 ENSURE(m_SecondaryComponentManager->DeserializeState(primaryStateBefore.state)); 441 } 410 442 411 ENSURE(secondaryComponentManager.DeserializeState(primaryStateBefore.state));412 443 if (m_EnableSerializationTest || m_TestingRejoin) 444 { 413 445 SerializationTestState secondaryStateBefore; 414 ENSURE( secondaryComponentManager.SerializeState(secondaryStateBefore.state));446 ENSURE(m_SecondaryComponentManager->SerializeState(secondaryStateBefore.state)); 415 447 if (serializationTestDebugDump) 416 ENSURE( secondaryComponentManager.DumpDebugState(secondaryStateBefore.debug, false));448 ENSURE(m_SecondaryComponentManager->DumpDebugState(secondaryStateBefore.debug, false)); 417 449 if (serializationTestHash) 418 ENSURE( secondaryComponentManager.ComputeStateHash(secondaryStateBefore.hash, false));450 ENSURE(m_SecondaryComponentManager->ComputeStateHash(secondaryStateBefore.hash, false)); 419 451 420 452 if (primaryStateBefore.state.str() != secondaryStateBefore.state.str() || 421 453 primaryStateBefore.hash != secondaryStateBefore.hash) 422 454 { 423 455 ReportSerializationFailure(&primaryStateBefore, NULL, &secondaryStateBefore, NULL); … … 426 458 SerializationTestState primaryStateAfter; 427 459 ENSURE(m_ComponentManager.SerializeState(primaryStateAfter.state)); 428 460 if (serializationTestHash) 429 461 ENSURE(m_ComponentManager.ComputeStateHash(primaryStateAfter.hash, false)); 430 462 431 UpdateComponents( secondaryContext, turnLengthFixed,432 CloneCommandsFromOtherContext(scriptInterface, secondaryComponentManager.GetScriptInterface(), commands));463 UpdateComponents(*m_SecondaryContext, turnLengthFixed, 464 CloneCommandsFromOtherContext(scriptInterface, m_SecondaryComponentManager->GetScriptInterface(), commands)); 433 465 SerializationTestState secondaryStateAfter; 434 ENSURE( secondaryComponentManager.SerializeState(secondaryStateAfter.state));466 ENSURE(m_SecondaryComponentManager->SerializeState(secondaryStateAfter.state)); 435 467 if (serializationTestHash) 436 ENSURE( secondaryComponentManager.ComputeStateHash(secondaryStateAfter.hash, false));468 ENSURE(m_SecondaryComponentManager->ComputeStateHash(secondaryStateAfter.hash, false)); 437 469 438 470 if (primaryStateAfter.state.str() != secondaryStateAfter.state.str() || 439 471 primaryStateAfter.hash != secondaryStateAfter.hash) 440 472 { 441 473 // Only do the (slow) dumping now we know we're going to need to report it 442 474 ENSURE(m_ComponentManager.DumpDebugState(primaryStateAfter.debug, false)); 443 ENSURE( secondaryComponentManager.DumpDebugState(secondaryStateAfter.debug, false));475 ENSURE(m_SecondaryComponentManager->DumpDebugState(secondaryStateAfter.debug, false)); 444 476 445 477 ReportSerializationFailure(&primaryStateBefore, &primaryStateAfter, &secondaryStateBefore, &secondaryStateAfter); 446 478 } 447 479 } 448 480 … … 582 614 delete m; 583 615 } 584 616 585 617 // Forward all method calls to the appropriate CSimulation2Impl/CComponentManager methods: 586 618 619 void CSimulation2::EnableSerializationTest() 620 { 621 m->m_EnableSerializationTest = true; 622 } 623 624 void CSimulation2::EnableRejoinTest(int rejoinTestTurn) 625 { 626 m->m_RejoinTestTurn = rejoinTestTurn; 627 } 628 587 629 void CSimulation2::EnableOOSLog() 588 630 { 589 631 if (m->m_EnableOOSLog) 590 632 return; 591 633 592 634 m->m_EnableOOSLog = true; 593 635 debug_printf("Writing ooslogs to %s\n", m->m_OOSLogPath.string8().c_str()); 594 636 } 595 637 596 void CSimulation2::EnableSerializationTest()597 {598 m->m_EnableSerializationTest = true;599 }600 601 638 void CSimulation2::SetCurrentDisplayedPlayer(int playerID) 602 639 { 603 640 m->m_SimContext.SetCurrentDisplayedPlayer(playerID); 604 641 } 605 642 -
source/simulation2/Simulation2.h
54 54 CSimulation2(CUnitManager* unitManager, shared_ptr<ScriptRuntime> rt, CTerrain* terrain); 55 55 ~CSimulation2(); 56 56 57 57 void EnableOOSLog(); 58 58 void EnableSerializationTest(); 59 59 void EnableRejoinTest(int rejoinTestTurn); 60 60 void SetCurrentDisplayedPlayer(int playerID); 61 61 62 62 /** 63 63 * Load all scripts in the specified directory (non-recursively), 64 64 * so they can register new component types and functions. This