From f16059c0b89357c486075ad2f49d3ee280dea9d8 Mon Sep 17 00:00:00 2001 From: heinrich5991 Date: Thu, 28 Sep 2017 02:42:35 +0200 Subject: [PATCH] teehistorian: Add a couple of tests, fix uninitialized vars and asserts --- src/game/server/teehistorian.cpp | 11 ++- src/test/teehistorian.cpp | 156 +++++++++++++++++++++++++++++++ 2 files changed, 164 insertions(+), 3 deletions(-) diff --git a/src/game/server/teehistorian.cpp b/src/game/server/teehistorian.cpp index a2c89009e..c5be827c6 100644 --- a/src/game/server/teehistorian.cpp +++ b/src/game/server/teehistorian.cpp @@ -12,7 +12,7 @@ enum { TEEHISTORIAN_NONE, TEEHISTORIAN_FINISH, - TEEHISTORIAN_TICK, + TEEHISTORIAN_TICK_SKIP, TEEHISTORIAN_PLAYER_NEW, TEEHISTORIAN_PLAYER_OLD, TEEHISTORIAN_INPUT_DIFF, @@ -95,6 +95,9 @@ void CTeeHistorian::Reset(const CGameInfo *pGameInfo, WRITE_CALLBACK pfnWriteCal m_Tick = 0; m_LastWrittenTick = 0; + // `m_TickWritten` is initialized in `BeginTick` + m_MaxClientID = MAX_CLIENTS; + // `m_PrevMaxClientID` is initialized in `BeginTick` for(int i = 0; i < MAX_CLIENTS; i++) { m_aPrevPlayers[i].m_Alive = false; @@ -104,6 +107,8 @@ void CTeeHistorian::Reset(const CGameInfo *pGameInfo, WRITE_CALLBACK pfnWriteCal m_pWriteCallbackUserdata = pUser; WriteHeader(pGameInfo); + + m_State = STATE_START; } void CTeeHistorian::WriteHeader(const CGameInfo *pGameInfo) @@ -323,7 +328,7 @@ void CTeeHistorian::WriteTick() TickPacker.Reset(); int dt = m_Tick - m_LastWrittenTick - 1; - TickPacker.AddInt(-TEEHISTORIAN_TICK); + TickPacker.AddInt(-TEEHISTORIAN_TICK_SKIP); TickPacker.AddInt(dt); if(m_Debug) { @@ -494,7 +499,7 @@ void CTeeHistorian::EndTick() void CTeeHistorian::Finish() { - dbg_assert(m_State == STATE_START || m_State == STATE_INPUTS || m_State == STATE_BEFORE_ENDTICK, "invalid teehistorian state"); + dbg_assert(m_State == STATE_START || m_State == STATE_INPUTS || m_State == STATE_BEFORE_ENDTICK || m_State == STATE_BEFORE_TICK, "invalid teehistorian state"); if(m_State == STATE_INPUTS) { diff --git a/src/test/teehistorian.cpp b/src/test/teehistorian.cpp index 6136baf76..7607f41c3 100644 --- a/src/test/teehistorian.cpp +++ b/src/test/teehistorian.cpp @@ -14,6 +14,15 @@ protected: CPacker m_Buffer; + enum + { + STATE_NONE, + STATE_PLAYERS, + STATE_INPUTS, + }; + + int m_State; + TeeHistorian() { mem_zero(&m_Config, sizeof(m_Config)); @@ -55,6 +64,7 @@ protected: { m_Buffer.Reset(); m_TH.Reset(pGameInfo, Write, this); + m_State = STATE_NONE; } void Expect(const unsigned char *pOutput, int OutputSize) @@ -110,9 +120,155 @@ protected: ASSERT_EQ(m_Buffer.Size(), OutputSize); ASSERT_TRUE(mem_comp(m_Buffer.Data(), pOutput, OutputSize) == 0); } + + void Tick(int Tick) + { + if(m_State == STATE_PLAYERS) + { + Inputs(); + } + if(m_State == STATE_INPUTS) + { + m_TH.EndInputs(); + m_TH.EndTick(); + } + m_TH.BeginTick(Tick); + m_TH.BeginPlayers(); + m_State = STATE_PLAYERS; + } + void Inputs() + { + m_TH.EndPlayers(); + m_TH.BeginInputs(); + m_State = STATE_INPUTS; + } + void Finish() + { + if(m_State == STATE_PLAYERS) + { + Inputs(); + } + if(m_State == STATE_INPUTS) + { + m_TH.EndInputs(); + m_TH.EndTick(); + } + m_TH.Finish(); + } + void DeadPlayer(int ClientID) + { + m_TH.RecordDeadPlayer(ClientID); + } + void Player(int ClientID, int x, int y) + { + CNetObj_CharacterCore Char; + mem_zero(&Char, sizeof(Char)); + Char.m_X = x; + Char.m_Y = y; + m_TH.RecordPlayer(ClientID, &Char); + } }; TEST_F(TeeHistorian, Empty) { Expect((const unsigned char *)"", 0); } + +TEST_F(TeeHistorian, Finished) +{ + const unsigned char EXPECTED[] = {0x40}; // FINISH + m_TH.Finish(); + Expect(EXPECTED, sizeof(EXPECTED)); +} + +TEST_F(TeeHistorian, TickImplicitOneTick) +{ + const unsigned char EXPECTED[] = { + 0x42, 0x00, 0x01, 0x02, // PLAYERNEW cid=0 x=1 y=2 + 0x40, // FINISH + }; + Tick(1); Player(0, 1, 2); + Finish(); + Expect(EXPECTED, sizeof(EXPECTED)); +} + +TEST_F(TeeHistorian, TickImplicitTwoTicks) +{ + const unsigned char EXPECTED[] = { + 0x42, 0x00, 0x01, 0x02, // PLAYER_NEW cid=0 x=1 y=2 + 0x00, 0x01, 0x40, // PLAYER cid=0 dx=1 dy=-1 + 0x40, // FINISH + }; + Tick(1); Player(0, 1, 2); + Tick(2); Player(0, 2, 1); + Finish(); + Expect(EXPECTED, sizeof(EXPECTED)); +} + +TEST_F(TeeHistorian, TickImplicitDescendingClientID) +{ + const unsigned char EXPECTED[] = { + 0x42, 0x01, 0x02, 0x03, // PLAYER_NEW cid=1 x=2 y=3 + 0x42, 0x00, 0x04, 0x05, // PLAYER_NEW cid=0 x=4 y=5 + 0x40, // FINISH + }; + Tick(1); DeadPlayer(0); Player(1, 2, 3); + Tick(2); Player(0, 4, 5); Player(1, 2, 3); + Finish(); + Expect(EXPECTED, sizeof(EXPECTED)); +} + +TEST_F(TeeHistorian, TickExplicitAscendingClientID) +{ + const unsigned char EXPECTED[] = { + 0x42, 0x00, 0x04, 0x05, // PLAYER_NEW cid=0 x=4 y=5 + 0x41, 0x00, // TICK_SKIP dt=0 + 0x42, 0x01, 0x02, 0x03, // PLAYER_NEW cid=1 x=2 y=3 + 0x40, // FINISH + }; + Tick(1); Player(0, 4, 5); DeadPlayer(1); + Tick(2); Player(0, 4, 5); Player(1, 2, 3); + Finish(); + Expect(EXPECTED, sizeof(EXPECTED)); +} + +TEST_F(TeeHistorian, TickImplicitEmpty) +{ + const unsigned char EXPECTED[] = { + 0x40, // FINISH + }; + for(int i = 1; i < 500; i++) + { + Tick(i); + } + for(int i = 1000; i < 100000; i += 1000) + { + Tick(i); + } + Finish(); + Expect(EXPECTED, sizeof(EXPECTED)); +} + +TEST_F(TeeHistorian, TickExplicitStart) +{ + const unsigned char EXPECTED[] = { + 0x41, 0xb3, 0x07, // TICK_SKIP dt=499 + 0x42, 0x00, 0x40, 0x40, // PLAYER_NEW cid=0 x=-1 y=-1 + 0x40, // FINISH + }; + Tick(500); Player(0, -1, -1); + Finish(); + Expect(EXPECTED, sizeof(EXPECTED)); +} + +TEST_F(TeeHistorian, TickExplicitPlayerMessage) +{ + const unsigned char EXPECTED[] = { + 0x41, 0x00, // TICK_SKIP dt=0 + 0x46, 0x3f, 0x01, 0x00, // MESSAGE cid=63 msg="\0" + 0x40, // FINISH + }; + Tick(1); Inputs(); m_TH.RecordPlayerMessage(63, "", 1); + Finish(); + Expect(EXPECTED, sizeof(EXPECTED)); +}