1
0
Fork 0

SelfTests are registered and executed after logging framework init.

Fixes #2228.
This commit is contained in:
Mattes D 2015-06-11 22:20:04 +02:00
parent d436a71cbc
commit d390214929
11 changed files with 198 additions and 33 deletions

View File

@ -5,6 +5,7 @@
#include "Globals.h"
#include "BoundingBox.h"
#include "Defines.h"
#include "SelfTests.h"
@ -17,6 +18,11 @@ static class SelfTest_BoundingBox
{
public:
SelfTest_BoundingBox(void)
{
cSelfTests::Get().Register(cSelfTests::SelfTestFunction(&Test), "Bounding box intersections");
}
static void Test(void)
{
Vector3d Min(1, 1, 1);
Vector3d Max(2, 2, 2);
@ -41,7 +47,7 @@ public:
bool res = cBoundingBox::CalcLineIntersection(Min, Max, Line1, Line2, LineCoeff, Face);
if (res != Results[i])
{
fprintf(stderr, "LineIntersection({%.02f, %.02f, %.02f}, {%.02f, %.02f, %.02f}) -> %d, %.05f, %d\n",
LOGERROR("LineIntersection({%.02f, %.02f, %.02f}, {%.02f, %.02f, %.02f}) -> %d, %.05f, %d",
Line1.x, Line1.y, Line1.z,
Line2.x, Line2.y, Line2.z,
res ? 1 : 0, LineCoeff, Face
@ -52,7 +58,7 @@ public:
{
if (LineCoeff != LineCoeffs[i])
{
fprintf(stderr, "LineIntersection({%.02f, %.02f, %.02f}, {%.02f, %.02f, %.02f}) -> %d, %.05f, %d\n",
LOGERROR("LineIntersection({%.02f, %.02f, %.02f}, {%.02f, %.02f, %.02f}) -> %d, %.05f, %d",
Line1.x, Line1.y, Line1.z,
Line2.x, Line2.y, Line2.z,
res ? 1 : 0, LineCoeff, Face
@ -61,9 +67,8 @@ public:
}
}
} // for i - LineDefs[]
fprintf(stderr, "BoundingBox selftest complete.\n");
}
} gTest;
} g_BoundingBoxTest;
#endif

View File

@ -8,6 +8,7 @@
#include "ByteBuffer.h"
#include "Endianness.h"
#include "OSSupport/IsThread.h"
#include "SelfTests.h"
@ -55,18 +56,18 @@ Unfortunately it is very slow, so it is disabled even for regular DEBUG builds.
#ifdef SELF_TEST
/// Self-test of the VarInt-reading and writing code
/** Self-test of the VarInt-reading and writing code */
static class cByteBufferSelfTest
{
public:
cByteBufferSelfTest(void)
{
TestRead();
TestWrite();
TestWrap();
cSelfTests::Get().Register(cSelfTests::SelfTestFunction(&TestRead), "ByteBuffer read");
cSelfTests::Get().Register(cSelfTests::SelfTestFunction(&TestWrite), "ByteBuffer write");
cSelfTests::Get().Register(cSelfTests::SelfTestFunction(&TestWrap), "ByteBuffer wraparound");
}
void TestRead(void)
static void TestRead(void)
{
cByteBuffer buf(50);
buf.Write("\x05\xac\x02\x00", 4);
@ -78,7 +79,7 @@ public:
assert_test(buf.ReadVarInt(v3) && (v3 == 0));
}
void TestWrite(void)
static void TestWrite(void)
{
cByteBuffer buf(50);
buf.WriteVarInt32(5);
@ -90,7 +91,7 @@ public:
assert_test(memcmp(All.data(), "\x05\xac\x02\x00", All.size()) == 0);
}
void TestWrap(void)
static void TestWrap(void)
{
cByteBuffer buf(3);
for (int i = 0; i < 1000; i++)

View File

@ -61,6 +61,7 @@ SET (SRCS
RCONServer.cpp
Root.cpp
Scoreboard.cpp
SelfTests.cpp
Server.cpp
SetChunkData.cpp
SpawnPrepare.cpp
@ -134,6 +135,7 @@ SET (HDRS
RCONServer.h
Root.h
Scoreboard.h
SelfTests.h
Server.h
SetChunkData.h
SettingsRepositoryInterface.h

View File

@ -6,6 +6,7 @@
#include "Globals.h"
#include "CompositeChat.h"
#include "ClientHandle.h"
#include "SelfTests.h"
@ -19,16 +20,14 @@ class SelfTest_CompositeChat
public:
SelfTest_CompositeChat(void)
{
fprintf(stderr, "cCompositeChat self test...\n");
TestParser1();
TestParser2();
TestParser3();
TestParser4();
TestParser5();
fprintf(stderr, "cCompositeChat self test finished.\n");
cSelfTests::Get().Register(cSelfTests::SelfTestFunction(&TestParser1), "CompositeChat parser test 1");
cSelfTests::Get().Register(cSelfTests::SelfTestFunction(&TestParser2), "CompositeChat parser test 2");
cSelfTests::Get().Register(cSelfTests::SelfTestFunction(&TestParser3), "CompositeChat parser test 3");
cSelfTests::Get().Register(cSelfTests::SelfTestFunction(&TestParser4), "CompositeChat parser test 4");
cSelfTests::Get().Register(cSelfTests::SelfTestFunction(&TestParser5), "CompositeChat parser test 5");
}
void TestParser1(void)
static void TestParser1(void)
{
cCompositeChat Msg;
Msg.ParseText("Testing @2color codes and http://links parser");
@ -44,7 +43,7 @@ public:
assert_test(Parts[3]->m_Style == "@2");
}
void TestParser2(void)
static void TestParser2(void)
{
cCompositeChat Msg;
Msg.ParseText("@3Advanced stuff: @5overriding color codes and http://links.with/@4color-in-them handling");
@ -60,7 +59,7 @@ public:
assert_test(Parts[3]->m_Style == "@5");
}
void TestParser3(void)
static void TestParser3(void)
{
cCompositeChat Msg;
Msg.ParseText("http://links.starting the text");
@ -72,7 +71,7 @@ public:
assert_test(Parts[1]->m_Style == "");
}
void TestParser4(void)
static void TestParser4(void)
{
cCompositeChat Msg;
Msg.ParseText("links finishing the text: http://some.server");
@ -84,7 +83,7 @@ public:
assert_test(Parts[1]->m_Style == "");
}
void TestParser5(void)
static void TestParser5(void)
{
cCompositeChat Msg;
Msg.ParseText("http://only.links");

View File

@ -6,6 +6,7 @@
#include "Globals.h"
#include "PieceGenerator.h"
#include "../SelfTests.h"
@ -21,6 +22,11 @@ static class cPieceGeneratorSelfTest :
{
public:
cPieceGeneratorSelfTest(void)
{
cSelfTests::Get().Register(std::bind(&cPieceGeneratorSelfTest::Test, this), "PieceGenerator");
}
void Test(void)
{
// Prepare the internal state:
InitializePieces();
@ -31,14 +37,14 @@ public:
Gen.PlacePieces(500, 50, 500, 3, OutPieces);
// Print out the pieces:
printf("OutPieces.size() = " SIZE_T_FMT "\n", OutPieces.size());
LOG("OutPieces.size() = " SIZE_T_FMT, OutPieces.size());
size_t idx = 0;
for (cPlacedPieces::const_iterator itr = OutPieces.begin(), end = OutPieces.end(); itr != end; ++itr, ++idx)
{
const Vector3i & Coords = (*itr)->GetCoords();
cCuboid Hitbox = (*itr)->GetHitBox();
Hitbox.Sort();
printf(SIZE_T_FMT ": {%d, %d, %d}, rot %d, hitbox {%d, %d, %d} - {%d, %d, %d} (%d * %d * %d)\n", idx,
LOG(SIZE_T_FMT ": {%d, %d, %d}, rot %d, hitbox {%d, %d, %d} - {%d, %d, %d} (%d * %d * %d)", idx,
Coords.x, Coords.y, Coords.z,
(*itr)->GetNumCCWRotations(),
Hitbox.p1.x, Hitbox.p1.y, Hitbox.p1.z,
@ -46,7 +52,7 @@ public:
Hitbox.DifX() + 1, Hitbox.DifY() + 1, Hitbox.DifZ() + 1
);
} // itr - OutPieces[]
printf("Done.\n");
LOG("Done.");
// Free the placed pieces properly:
Gen.FreePieces(OutPieces);

View File

@ -6,6 +6,8 @@
#include "Globals.h"
#include "Network.h"
#include "event2/util.h"
#include "../SelfTests.h"
#ifdef _WIN32
#include <IPHlpApi.h>
#pragma comment(lib, "IPHLPAPI.lib")
@ -27,13 +29,18 @@ static class cEnumIPAddressTest
public:
cEnumIPAddressTest(void)
{
printf("Enumerating all IP addresses...\n");
cSelfTests::Get().Register(std::function<void(void)>(&Test), "Network IP enumeration");
}
static void Test(void)
{
LOG("Enumerating all IP addresses...");
auto IPs = cNetwork::EnumLocalIPAddresses();
for (auto & ip: IPs)
{
printf(" %s\n", ip.c_str());
LOG(" %s", ip.c_str());
}
printf("Done.\n");
LOG("Done.");
}
} g_EnumIPAddressTest;

View File

@ -21,6 +21,7 @@
#include "IniFile.h"
#include "SettingsRepositoryInterface.h"
#include "OverridesSettingsRepository.h"
#include "SelfTests.h"
#ifdef _WIN32
#include <conio.h>
@ -111,11 +112,16 @@ void cRoot::Start(std::unique_ptr<cSettingsRepositoryInterface> overridesRepo)
cLogger::GetInstance().AttachListener(consoleLogListener);
cLogger::GetInstance().AttachListener(fileLogListener);
LOG("--- Started Log ---\n");
LOG("--- Started Log ---");
#ifdef BUILD_ID
LOG("MCServer " BUILD_SERIES_NAME " build id: " BUILD_ID);
LOG("from commit id: " BUILD_COMMIT_ID " built at: " BUILD_DATETIME);
LOG("MCServer " BUILD_SERIES_NAME " build id: " BUILD_ID);
LOG("from commit id: " BUILD_COMMIT_ID " built at: " BUILD_DATETIME);
#endif
// Run the self-tests registered previously via cSelfTests::Register():
#if SELF_TEST
cSelfTests::ExecuteAll();
#endif
cDeadlockDetect dd;
@ -869,3 +875,8 @@ int cRoot::GetFurnaceFuelBurnTime(const cItem & a_Fuel)
cFurnaceRecipe * FR = Get()->GetFurnaceRecipe();
return FR->GetBurnTime(a_Fuel);
}

View File

@ -38,7 +38,7 @@ namespace Json
/// The root of the object hierarchy
/** The root of the object hierarchy */
// tolua_begin
class cRoot
{
@ -217,6 +217,7 @@ private:
bool m_bRestart;
void LoadGlobalSettings();
/// Loads the worlds from settings.ini, creates the worldmap
@ -238,3 +239,8 @@ private:
static void InputThread(cRoot & a_Params);
}; // tolua_export

71
src/SelfTests.cpp Normal file
View File

@ -0,0 +1,71 @@
// SelfTests.h
// Implements the cSelfTests class representing the singleton used for registering self-tests
// This class is only declared if SELF_TEST macro is defined.
#include "Globals.h"
#include "SelfTests.h"
#if SELF_TEST
cSelfTests::cSelfTests(void):
m_AllowRegistering(true)
{
}
cSelfTests & cSelfTests::Get(void)
{
static cSelfTests singleton;
return singleton;
}
void cSelfTests::Register(cSelfTests::SelfTestFunction a_FnToExecute, const AString & a_TestName)
{
ASSERT(Get().m_AllowRegistering);
Get().m_SelfTests.push_back(std::make_pair(a_FnToExecute, a_TestName));
}
void cSelfTests::ExecuteAll(void)
{
Get().m_AllowRegistering = false;
LOG("--- Performing self-tests ---");
for (auto & test: Get().m_SelfTests)
{
LOG("Performing self-test: %s", test.second.c_str());
try
{
test.first();
}
catch (const std::exception & exc)
{
LOGWARNING("Exception in test %s: %s", test.second.c_str(), exc.what());
}
catch (...)
{
LOGWARNING("Unknown exception in test %s", test.second.c_str());
}
} // for test - m_SelfTests[]
LOG("--- Self-tests finished ---");
}
#endif // SELF_TEST

51
src/SelfTests.h Normal file
View File

@ -0,0 +1,51 @@
// SelfTests.h
// Declares the cSelfTests class representing the singleton used for registering self-tests
// This class is only declared if SELF_TEST macro is defined.
#pragma once
#ifdef SELF_TEST
/** Singleton containing registered self-tests.
Used to schedule self-tests to run after the logging framework is initialized (#2228). */
class cSelfTests
{
public:
/** Returns the singleton instance of this class. */
static cSelfTests & Get(void);
// typedef void (* SelfTestFunction)(void);
typedef std::function<void(void)> SelfTestFunction;
/** Registers a self-test to be executed once the logging framework is initialized. */
static void Register(SelfTestFunction a_FnToExecute, const AString & a_TestName);
/** Executes all the registered self-tests. */
static void ExecuteAll(void);
protected:
typedef std::vector<std::pair<SelfTestFunction, AString>> SelfTestFunctions;
/** Functions (registered self-tests) to call once the logging framework is initialized. */
SelfTestFunctions m_SelfTests;
/** If true, tests may be registered. Set to false once the tests are executed, to detect tests that are registered too late. */
bool m_AllowRegistering;
cSelfTests(void);
};
#endif // SELF_TEST

View File

@ -9,6 +9,7 @@
#include "FastNBT.h"
#include "SchematicFileSerializer.h"
#include "../StringCompression.h"
#include "../SelfTests.h"
@ -20,6 +21,11 @@ static class cSchematicStringSelfTest
{
public:
cSchematicStringSelfTest(void)
{
cSelfTests::Get().Register(cSelfTests::SelfTestFunction(&Test), "Schematic-to-string serialization");
}
static void Test(void)
{
cBlockArea ba;
ba.Create(21, 256, 21);