Browse Source

Improve demo test error message

Example:

```
file "game" is different at byte 54251:
Expected: ... 00 00 00 00 00 00 00 00 30 00 00 00 50 00 00 00 ...
  Actual: ... FF FF FF FF 00 00 00 00 30 00 00 00 50 00 00 00 ...
```
pull/5128/head
Gleb Mazovetskiy 4 years ago committed by Anders Jenbo
parent
commit
7c0b72abc0
  1. 4
      Source/engine/demomode.cpp
  2. 37
      Source/pfile.cpp
  3. 12
      Source/pfile.h
  4. 3
      test/timedemo_test.cpp

4
Source/engine/demomode.cpp

@ -280,7 +280,7 @@ void NotifyGameLoopEnd()
gbRunGame = false; gbRunGame = false;
HeroCompareResult compareResult = pfile_compare_hero_demo(DemoNumber); HeroCompareResult compareResult = pfile_compare_hero_demo(DemoNumber);
switch (compareResult) { switch (compareResult.status) {
case HeroCompareResult::ReferenceNotFound: case HeroCompareResult::ReferenceNotFound:
SDL_Log("Timedemo: No final comparision cause reference is not present."); SDL_Log("Timedemo: No final comparision cause reference is not present.");
break; break;
@ -288,7 +288,7 @@ void NotifyGameLoopEnd()
SDL_Log("Timedemo: Same outcome as inital run. :)"); SDL_Log("Timedemo: Same outcome as inital run. :)");
break; break;
case HeroCompareResult::Difference: case HeroCompareResult::Difference:
SDL_Log("Timedemo: Different outcome then inital run. ;("); Log("Timedemo: Different outcome then inital run. ;(\n{}", compareResult.message);
break; break;
} }
} }

37
Source/pfile.cpp

@ -21,6 +21,7 @@
#include "utils/file_util.h" #include "utils/file_util.h"
#include "utils/language.h" #include "utils/language.h"
#include "utils/paths.h" #include "utils/paths.h"
#include "utils/stdcompat/abs.hpp"
#include "utils/stdcompat/string_view.hpp" #include "utils/stdcompat/string_view.hpp"
#include "utils/str_cat.hpp" #include "utils/str_cat.hpp"
#include "utils/utf8.hpp" #include "utils/utf8.hpp"
@ -187,7 +188,7 @@ bool ArchiveContainsGame(MpqArchive &hsArchive)
return IsHeaderValid(hdr); return IsHeaderValid(hdr);
} }
bool CompareSaves(const std::string &actualSavePath, const std::string &referenceSavePath) HeroCompareResult CompareSaves(const std::string &actualSavePath, const std::string &referenceSavePath)
{ {
std::vector<std::string> possibleFileNamesToCheck; std::vector<std::string> possibleFileNamesToCheck;
possibleFileNamesToCheck.emplace_back("hero"); possibleFileNamesToCheck.emplace_back("hero");
@ -202,7 +203,6 @@ bool CompareSaves(const std::string &actualSavePath, const std::string &referenc
auto actualArchive = *MpqArchive::Open(actualSavePath.c_str(), error); auto actualArchive = *MpqArchive::Open(actualSavePath.c_str(), error);
auto referenceArchive = *MpqArchive::Open(referenceSavePath.c_str(), error); auto referenceArchive = *MpqArchive::Open(referenceSavePath.c_str(), error);
bool compareResult = true;
for (const auto &fileName : possibleFileNamesToCheck) { for (const auto &fileName : possibleFileNamesToCheck) {
size_t fileSizeActual; size_t fileSizeActual;
auto fileDataActual = ReadArchive(actualArchive, fileName.c_str(), &fileSizeActual); auto fileDataActual = ReadArchive(actualArchive, fileName.c_str(), &fileSizeActual);
@ -212,15 +212,31 @@ bool CompareSaves(const std::string &actualSavePath, const std::string &referenc
continue; continue;
} }
if (fileSizeActual != fileSizeReference) { if (fileSizeActual != fileSizeReference) {
compareResult = false; return { HeroCompareResult::Difference, StrCat("file \"", fileName, "\" is different size. Expected: ", fileSizeReference, "Actual: ", fileSizeActual) };
break;
} }
if (memcmp(fileDataReference.get(), fileDataActual.get(), fileSizeActual) != 0) {
compareResult = false; const byte *reference = fileDataReference.get();
break; const byte *referenceEnd = reference + fileSizeActual;
const byte *actual = fileDataActual.get();
while (reference != referenceEnd) {
if (*reference != *actual) {
const size_t diffSize = std::min<size_t>(16, referenceEnd - reference);
return {
HeroCompareResult::Difference,
fmt::format(
"file \"{}\" is different at byte {}:\n"
"Expected: ... {:02X} ...\n"
" Actual: ... {:02X} ...",
fileName, reference - fileDataReference.get(),
fmt::join(reference, reference + diffSize, " "),
fmt::join(actual, actual + diffSize, " "))
};
}
++reference;
++actual;
} }
} }
return compareResult; return { HeroCompareResult::Same, {} };
} }
void pfile_write_hero(MpqWriter &saveWriter, bool writeGameData) void pfile_write_hero(MpqWriter &saveWriter, bool writeGameData)
@ -298,7 +314,7 @@ HeroCompareResult pfile_compare_hero_demo(int demo)
std::string referenceSavePath = GetSavePath(gSaveNumber, StrCat("demo_", demo, "_reference_")); std::string referenceSavePath = GetSavePath(gSaveNumber, StrCat("demo_", demo, "_reference_"));
if (!FileExists(referenceSavePath.c_str())) if (!FileExists(referenceSavePath.c_str()))
return HeroCompareResult::ReferenceNotFound; return { HeroCompareResult::ReferenceNotFound, {} };
std::string actualSavePath = GetSavePath(gSaveNumber, StrCat("demo_", demo, "_actual_")); std::string actualSavePath = GetSavePath(gSaveNumber, StrCat("demo_", demo, "_actual_"));
{ {
@ -306,8 +322,7 @@ HeroCompareResult pfile_compare_hero_demo(int demo)
pfile_write_hero(saveWriter, true); pfile_write_hero(saveWriter, true);
} }
bool compareResult = CompareSaves(actualSavePath, referenceSavePath); return CompareSaves(actualSavePath, referenceSavePath);
return compareResult ? HeroCompareResult::Same : HeroCompareResult::Difference;
} }
void sfile_write_stash() void sfile_write_stash()

12
Source/pfile.h

@ -17,10 +17,14 @@ extern bool gbValidSaveFile;
/** /**
* @brief Comparsion result of pfile_compare_hero_demo * @brief Comparsion result of pfile_compare_hero_demo
*/ */
enum class HeroCompareResult { struct HeroCompareResult {
ReferenceNotFound, enum Status {
Same, ReferenceNotFound,
Difference, Same,
Difference,
};
Status status;
std::string message;
}; };
std::optional<MpqArchive> OpenSaveArchive(uint32_t saveNum); std::optional<MpqArchive> OpenSaveArchive(uint32_t saveNum);

3
test/timedemo_test.cpp

@ -52,7 +52,8 @@ void RunTimedemo(std::string timedemoFolderName)
StartGame(false, true); StartGame(false, true);
ASSERT_EQ(pfile_compare_hero_demo(demoNumber), HeroCompareResult::Same); HeroCompareResult result = pfile_compare_hero_demo(demoNumber);
ASSERT_EQ(result.status, HeroCompareResult::Same) << result.message;
ASSERT_FALSE(gbRunGame); ASSERT_FALSE(gbRunGame);
gbRunGame = false; gbRunGame = false;
init_cleanup(); init_cleanup();

Loading…
Cancel
Save