refactor(Core/sLog): improve singleton management (#3801)

This commit is contained in:
Francesco Borzì
2020-12-06 15:59:08 +01:00
committed by GitHub
parent a06bfa6e5b
commit 9facd81e54
6 changed files with 214 additions and 92 deletions

127
src/common/Logging/ILog.h Normal file
View File

@@ -0,0 +1,127 @@
#ifndef AZEROTHCORE_ILOG_H
#define AZEROTHCORE_ILOG_H
class WorldPacket;
enum DebugLogFilters
{
LOG_FILTER_NONE = 0x00000000,
LOG_FILTER_UNITS = 0x00000001, // Anything related to units that doesn't fit in other categories. ie. creature formations
LOG_FILTER_PETS = 0x00000002,
LOG_FILTER_VEHICLES = 0x00000004,
LOG_FILTER_TSCR = 0x00000008, // C++ AI, instance scripts, etc.
LOG_FILTER_DATABASE_AI = 0x00000010, // SmartAI, EventAI, CreatureAI
LOG_FILTER_MAPSCRIPTS = 0x00000020,
LOG_FILTER_NETWORKIO = 0x00000040, // Anything packet/netcode related
LOG_FILTER_SPELLS_AURAS = 0x00000080,
LOG_FILTER_ACHIEVEMENTSYS = 0x00000100,
LOG_FILTER_CONDITIONSYS = 0x00000200,
LOG_FILTER_POOLSYS = 0x00000400,
LOG_FILTER_AUCTIONHOUSE = 0x00000800,
LOG_FILTER_BATTLEGROUND = 0x00001000, // Anything related to arena's and battlegrounds
LOG_FILTER_OUTDOORPVP = 0x00002000,
LOG_FILTER_CHATSYS = 0x00004000,
LOG_FILTER_LFG = 0x00008000,
LOG_FILTER_MAPS = 0x00010000, // Maps, instances, grids, cells, visibility
LOG_FILTER_PLAYER_LOADING = 0x00020000, // Debug output from Player::_Load functions
LOG_FILTER_PLAYER_ITEMS = 0x00040000, // Anything item related
LOG_FILTER_PLAYER_SKILLS = 0x00080000, // Skills related
LOG_FILTER_LOOT = 0x00100000, // Loot related
LOG_FILTER_GUILD = 0x00200000, // Guild related
LOG_FILTER_TRANSPORTS = 0x00400000, // Transport related
LOG_FILTER_WARDEN = 0x00800000, // Warden related
LOG_FILTER_BATTLEFIELD = 0x01000000, // Battlefield related
LOG_FILTER_MODULES = 0x02000000, // Modules debug
LOG_FILTER_CLOSE_SOCKET = 0x04000000, // Whenever KickPlayer() or CloseSocket() are called
};
enum LogTypes
{
LOG_TYPE_STRING = 0,
LOG_TYPE_ERROR = 1,
LOG_TYPE_BASIC = 2,
LOG_TYPE_DETAIL = 3,
LOG_TYPE_DEBUG = 4,
LOG_TYPE_CHAR = 5,
LOG_TYPE_WORLD = 6,
LOG_TYPE_RA = 7,
LOG_TYPE_GM = 8,
LOG_TYPE_CRASH = 9,
LOG_TYPE_CHAT = 10,
LOG_TYPE_PERF = 11,
LOG_TYPE_MULTITH = 12,
MAX_LOG_TYPES
};
enum LogLevel
{
LOGL_NORMAL = 0,
LOGL_BASIC,
LOGL_DETAIL,
LOGL_DEBUG
};
const int LogLevels = int(LOGL_DEBUG) + 1;
enum ColorTypes
{
BLACK,
RED,
GREEN,
BROWN,
BLUE,
MAGENTA,
CYAN,
GREY,
YELLOW,
LRED,
LGREEN,
LBLUE,
LMAGENTA,
LCYAN,
WHITE
};
const int Colors = int(WHITE) + 1;
class ILog
{
public:
virtual ~ILog() {}
virtual void Initialize() = 0;
virtual void ReloadConfig() = 0;
virtual void InitColors(const std::string& init_str) = 0;
virtual void SetColor(bool stdout_stream, ColorTypes color) = 0;
virtual void ResetColor(bool stdout_stream) = 0;
virtual void outDB(LogTypes type, const char* str) = 0;
virtual void outString(const char* str, ...) = 0;
virtual void outString() = 0;
virtual void outStringInLine(const char* str, ...) = 0;
virtual void outError(const char* err, ...) = 0;
virtual void outCrash(const char* err, ...) = 0;
virtual void outBasic(const char* str, ...) = 0;
virtual void outDetail(const char* str, ...) = 0;
virtual void outSQLDev(const char* str, ...) = 0;
virtual void outDebug(DebugLogFilters f, const char* str, ...) = 0;
virtual void outStaticDebug(const char* str, ...) = 0;
virtual void outErrorDb(const char* str, ...) = 0;
virtual void outChar(const char* str, ...) = 0;
virtual void outCommand(uint32 account, const char* str, ...) = 0;
virtual void outChat(const char* str, ...) = 0;
virtual void outRemote(const char* str, ...) = 0;
virtual void outSQLDriver(const char* str, ...) = 0;
virtual void outMisc(const char* str, ...) = 0;
virtual void outCharDump(const char* str, uint32 account_id, uint32 guid, const char* name) = 0;
virtual void SetLogLevel(char* Level) = 0;
virtual void SetLogFileLevel(char* Level) = 0;
virtual void SetSQLDriverQueryLogging(bool newStatus) = 0;
virtual void SetRealmID(uint32 id) = 0;
virtual bool IsOutDebug() const = 0;
virtual bool IsOutCharDump() const = 0;
virtual bool GetLogDB() const = 0;
virtual void SetLogDB(bool enable) = 0;
virtual bool GetSQLDriverQueryLogging() const = 0;
};
#endif //AZEROTHCORE_ILOG_H

View File

@@ -65,10 +65,11 @@ Log::~Log()
miscLogFile = NULL;
}
Log* Log::instance()
std::unique_ptr<ILog>& getLogInstance()
{
static Log instance;
return &instance;
static std::unique_ptr<ILog> instance = std::make_unique<Log>();
return instance;
}
void Log::SetLogLevel(char* Level)

View File

@@ -8,104 +8,20 @@
#define AZEROTHCORE_LOG_H
#include "Common.h"
#include "ILog.h"
#include <ace/Task.h>
class WorldPacket;
enum DebugLogFilters
{
LOG_FILTER_NONE = 0x00000000,
LOG_FILTER_UNITS = 0x00000001, // Anything related to units that doesn't fit in other categories. ie. creature formations
LOG_FILTER_PETS = 0x00000002,
LOG_FILTER_VEHICLES = 0x00000004,
LOG_FILTER_TSCR = 0x00000008, // C++ AI, instance scripts, etc.
LOG_FILTER_DATABASE_AI = 0x00000010, // SmartAI, EventAI, CreatureAI
LOG_FILTER_MAPSCRIPTS = 0x00000020,
LOG_FILTER_NETWORKIO = 0x00000040, // Anything packet/netcode related
LOG_FILTER_SPELLS_AURAS = 0x00000080,
LOG_FILTER_ACHIEVEMENTSYS = 0x00000100,
LOG_FILTER_CONDITIONSYS = 0x00000200,
LOG_FILTER_POOLSYS = 0x00000400,
LOG_FILTER_AUCTIONHOUSE = 0x00000800,
LOG_FILTER_BATTLEGROUND = 0x00001000, // Anything related to arena's and battlegrounds
LOG_FILTER_OUTDOORPVP = 0x00002000,
LOG_FILTER_CHATSYS = 0x00004000,
LOG_FILTER_LFG = 0x00008000,
LOG_FILTER_MAPS = 0x00010000, // Maps, instances, grids, cells, visibility
LOG_FILTER_PLAYER_LOADING = 0x00020000, // Debug output from Player::_Load functions
LOG_FILTER_PLAYER_ITEMS = 0x00040000, // Anything item related
LOG_FILTER_PLAYER_SKILLS = 0x00080000, // Skills related
LOG_FILTER_LOOT = 0x00100000, // Loot related
LOG_FILTER_GUILD = 0x00200000, // Guild related
LOG_FILTER_TRANSPORTS = 0x00400000, // Transport related
LOG_FILTER_WARDEN = 0x00800000, // Warden related
LOG_FILTER_BATTLEFIELD = 0x01000000, // Battlefield related
LOG_FILTER_MODULES = 0x02000000, // Modules debug
LOG_FILTER_CLOSE_SOCKET = 0x04000000, // Whenever KickPlayer() or CloseSocket() are called
};
enum LogTypes
{
LOG_TYPE_STRING = 0,
LOG_TYPE_ERROR = 1,
LOG_TYPE_BASIC = 2,
LOG_TYPE_DETAIL = 3,
LOG_TYPE_DEBUG = 4,
LOG_TYPE_CHAR = 5,
LOG_TYPE_WORLD = 6,
LOG_TYPE_RA = 7,
LOG_TYPE_GM = 8,
LOG_TYPE_CRASH = 9,
LOG_TYPE_CHAT = 10,
LOG_TYPE_PERF = 11,
LOG_TYPE_MULTITH = 12,
MAX_LOG_TYPES
};
enum LogLevel
{
LOGL_NORMAL = 0,
LOGL_BASIC,
LOGL_DETAIL,
LOGL_DEBUG
};
const int LogLevels = int(LOGL_DEBUG) + 1;
enum ColorTypes
{
BLACK,
RED,
GREEN,
BROWN,
BLUE,
MAGENTA,
CYAN,
GREY,
YELLOW,
LRED,
LGREEN,
LBLUE,
LMAGENTA,
LCYAN,
WHITE
};
const int Colors = int(WHITE) + 1;
class Log
class Log : public ILog
{
private:
Log();
~Log();
Log(Log const&) = delete;
Log(Log&&) = delete;
Log& operator=(Log const&) = delete;
Log& operator=(Log&&) = delete;
public:
static Log* instance();
Log();
~Log();
void Initialize();
void ReloadConfig();
@@ -197,7 +113,9 @@ private:
DebugLogFilters m_DebugLogMask;
};
#define sLog Log::instance()
std::unique_ptr<ILog>& getLogInstance();
#define sLog getLogInstance()
#endif

View File

@@ -3,6 +3,10 @@ CollectSourceFiles(
PRIVATE_SOURCES
)
include_directories(
"mocks"
)
add_executable(
unit_tests
${PRIVATE_SOURCES}
@@ -12,6 +16,7 @@ target_link_libraries(
unit_tests
game
gtest_main
gmock_main
game-interface
)

51
src/test/mocks/LogMock.h Normal file
View File

@@ -0,0 +1,51 @@
#ifndef AZEROTHCORE_LOGMOCK_H
#define AZEROTHCORE_LOGMOCK_H
#include "gmock/gmock.h"
#include "ILog.h"
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-parameter"
class LogMock: public ILog {
public:
~LogMock() override {}
MOCK_METHOD(void, outDB, (LogTypes type), (const char* str));
MOCK_METHOD(void, Initialize, ());
MOCK_METHOD(void, ReloadConfig, ());
MOCK_METHOD(void, InitColors, (const std::string& init_str));
void SetColor(bool stdout_stream, ColorTypes color) override {}
MOCK_METHOD(void, ResetColor, (bool stdout_stream));
MOCK_METHOD(void, outDB, (LogTypes type, const char* str));
void outString(const char* str, ...) override {}
MOCK_METHOD(void, outString, ());
void outStringInLine(const char* str, ...) override {}
MOCK_METHOD(void, outErrorMock, ()); // because outError has variadic type and cannot be directly mocked
void outError(const char* err, ...) override { outErrorMock(); }
void outCrash(const char* err, ...) override {}
void outBasic(const char* str, ...) override {}
void outDetail(const char* str, ...) override {}
void outSQLDev(const char* str, ...) override {}
void outDebug(DebugLogFilters f, const char* str, ...) override {}
void outStaticDebug(const char* str, ...) override {}
void outErrorDb(const char* str, ...) override {}
void outChar(const char* str, ...) override {}
void outCommand(uint32 account, const char* str, ...) override {}
void outChat(const char* str, ...) override {}
void outRemote(const char* str, ...) override {}
void outSQLDriver(const char* str, ...) override {}
void outMisc(const char* str, ...) override {}
void outCharDump(const char* str, uint32 account_id, uint32 guid, const char* name) override {}
MOCK_METHOD(void, SetLogLevel, (char* Level));
MOCK_METHOD(void, SetLogFileLevel, (char* Level));
MOCK_METHOD(void, SetSQLDriverQueryLogging, (bool newStatus));
MOCK_METHOD(void, SetRealmID, (uint32 id));
MOCK_METHOD(bool, IsOutDebug, (), (const));
MOCK_METHOD(bool, IsOutCharDump, (), (const));
MOCK_METHOD(bool, GetLogDB, (), (const));
MOCK_METHOD(void, SetLogDB, (bool enable));
MOCK_METHOD(bool, GetSQLDriverQueryLogging, (), (const));
};
#pragma GCC diagnostic pop
#endif //AZEROTHCORE_LOGMOCK_H

View File

@@ -1,6 +1,10 @@
#include "gtest/gtest.h"
#include "Formulas.h"
#include "SharedDefines.h"
#include "Log.h"
#include "LogMock.h"
LoginDatabaseWorkerPool LoginDatabase;
using namespace acore::Honor;
using namespace acore::XP;
@@ -69,3 +73,19 @@ TEST(FormulasTest, GetZeroDifference)
EXPECT_EQ(GetZeroDifference(60), 17);
EXPECT_EQ(GetZeroDifference(80), 17);
}
TEST(FormulasTest, BaseGain)
{
auto logMock = new LogMock();
sLog.reset(logMock);
EXPECT_EQ(BaseGain(60, 40, CONTENT_1_60), 0);
EXPECT_EQ(BaseGain(60, 60, CONTENT_1_60), 345);
EXPECT_EQ(BaseGain(50, 60, CONTENT_1_60), 354);
EXPECT_EQ(BaseGain(65, 66, CONTENT_61_70), 588);
EXPECT_EQ(BaseGain(79, 78, CONTENT_71_80), 917);
// check outError() has been called after passing an invalid ContentLevels content
EXPECT_CALL(*logMock, outErrorMock()).Times(1);
EXPECT_EQ(BaseGain(79, 1, ContentLevels(999)), 0);
}