Move Singleton lifetime + refactor logs

This commit is contained in:
2026-05-16 15:41:05 +02:00
parent e3c55cc359
commit 2c83dcc0bc
18 changed files with 258 additions and 220 deletions

View File

@@ -11,11 +11,9 @@
#include <Utils/Assert.hpp>
#if defined BIGFOOT_NOT_OPTIMIZED
#include <EASTL/utility.h>
#include <format>
#include <source_location>
#include <string_view>
namespace Bigfoot
{

View File

@@ -6,7 +6,7 @@
*********************************************************************/
#ifndef BIGFOOT_ENGINELOGGER_GENERATED_HPP
#define BIGFOOT_ENGINELOGGER_GENERATED_HPP
#include <Utils/Log/Log.hpp>
#include <Utils/Log/LogMacros.hpp>
#if defined BIGFOOT_NOT_OPTIMIZED

View File

@@ -11,11 +11,9 @@
#include <Utils/Assert.hpp>
#if defined BIGFOOT_NOT_OPTIMIZED
#include <EASTL/utility.h>
#include <format>
#include <source_location>
#include <string_view>
namespace Bigfoot
{

View File

@@ -6,7 +6,7 @@
*********************************************************************/
#ifndef BIGFOOT_SYSTEMLOGGER_GENERATED_HPP
#define BIGFOOT_SYSTEMLOGGER_GENERATED_HPP
#include <Utils/Log/Log.hpp>
#include <Utils/Log/LogMacros.hpp>
#if defined BIGFOOT_NOT_OPTIMIZED

View File

@@ -6,7 +6,7 @@
*********************************************************************/
#ifndef BIGFOOT_UTILS_ASSERT_HPP
#define BIGFOOT_UTILS_ASSERT_HPP
#include <Utils/Log/Log.hpp>
#include <Utils/Log/LogMacros.hpp>
#if defined BIGFOOT_NOT_OPTIMIZED

View File

@@ -10,7 +10,6 @@
#if defined BIGFOOT_NOT_OPTIMIZED
#include <Utils/Log/Log_generated.hpp>
#include <Utils/Singleton.hpp>
#include <EASTL/array.h>
@@ -92,96 +91,5 @@ class Log
eastl::array<std::shared_ptr<quill::Sink>, 1> m_sinks;
};
} // namespace Bigfoot
#define BIGFOOT_LOG_DEBUG(loggerName, fmt, ...) \
do \
{ \
if (quill::Logger* logger = Bigfoot::Singleton<Bigfoot::Log>::Instance().GetLogger(loggerName)) \
{ \
QUILL_LOG_DEBUG(logger, fmt __VA_OPT__(, ) __VA_ARGS__); \
} \
else \
{ \
QUILL_LOG_DEBUG(Bigfoot::Singleton<Bigfoot::Log>::Instance().RegisterLogger(loggerName), \
fmt __VA_OPT__(, ) __VA_ARGS__); \
} \
} while (0)
#define BIGFOOT_LOG_TRACE(loggerName, fmt, ...) \
do \
{ \
if (quill::Logger* logger = Bigfoot::Singleton<Bigfoot::Log>::Instance().GetLogger(loggerName)) \
{ \
QUILL_LOG_TRACE_L3(logger, fmt __VA_OPT__(, ) __VA_ARGS__); \
} \
else \
{ \
QUILL_LOG_TRACE_L3(Bigfoot::Singleton<Bigfoot::Log>::Instance().RegisterLogger(loggerName), \
fmt __VA_OPT__(, ) __VA_ARGS__); \
} \
} while (0)
#define BIGFOOT_LOG_INFO(loggerName, fmt, ...) \
do \
{ \
if (quill::Logger* logger = Bigfoot::Singleton<Bigfoot::Log>::Instance().GetLogger(loggerName)) \
{ \
QUILL_LOG_INFO(logger, fmt __VA_OPT__(, ) __VA_ARGS__); \
} \
else \
{ \
QUILL_LOG_INFO(Bigfoot::Singleton<Bigfoot::Log>::Instance().RegisterLogger(loggerName), \
fmt __VA_OPT__(, ) __VA_ARGS__); \
} \
} while (0)
#define BIGFOOT_LOG_WARN(loggerName, fmt, ...) \
do \
{ \
if (quill::Logger* logger = Bigfoot::Singleton<Bigfoot::Log>::Instance().GetLogger(loggerName)) \
{ \
QUILL_LOG_WARNING(logger, fmt __VA_OPT__(, ) __VA_ARGS__); \
} \
else \
{ \
QUILL_LOG_WARNING(Bigfoot::Singleton<Bigfoot::Log>::Instance().RegisterLogger(loggerName), \
fmt __VA_OPT__(, ) __VA_ARGS__); \
} \
} while (0)
#define BIGFOOT_LOG_ERROR(loggerName, fmt, ...) \
do \
{ \
if (quill::Logger* logger = Bigfoot::Singleton<Bigfoot::Log>::Instance().GetLogger(loggerName)) \
{ \
QUILL_LOG_ERROR(logger, fmt __VA_OPT__(, ) __VA_ARGS__); \
} \
else \
{ \
QUILL_LOG_ERROR(Bigfoot::Singleton<Bigfoot::Log>::Instance().RegisterLogger(loggerName), \
fmt __VA_OPT__(, ) __VA_ARGS__); \
} \
} while (0)
#define BIGFOOT_LOG_FATAL(loggerName, fmt, ...) \
do \
{ \
if (quill::Logger* logger = Bigfoot::Singleton<Bigfoot::Log>::Instance().GetLogger(loggerName)) \
{ \
QUILL_LOG_CRITICAL(logger, fmt __VA_OPT__(, ) __VA_ARGS__); \
} \
else \
{ \
QUILL_LOG_CRITICAL(Bigfoot::Singleton<Bigfoot::Log>::Instance().RegisterLogger(loggerName), \
fmt __VA_OPT__(, ) __VA_ARGS__); \
} \
} while (0)
#else
#define BIGFOOT_LOG_DEBUG(loggerName, fmt, ...)
#define BIGFOOT_LOG_TRACE(loggerName, fmt, ...)
#define BIGFOOT_LOG_INFO(loggerName, fmt, ...)
#define BIGFOOT_LOG_WARN(loggerName, fmt, ...)
#define BIGFOOT_LOG_ERROR(loggerName, fmt, ...)
#define BIGFOOT_LOG_FATAL(loggerName, fmt, ...)
#endif
#endif

View File

@@ -0,0 +1,104 @@
/*********************************************************************
* \file LogMacros.hpp
*
* \author Romain BOULLARD
* \date May 2026
*********************************************************************/
#ifndef BIGFOOT_UTILS_LOG_LOGMACROS_HPP
#define BIGFOOT_UTILS_LOG_LOGMACROS_HPP
#include <Utils/Log/Log.hpp>
#include <Utils/Singleton.hpp>
#if defined BIGFOOT_NOT_OPTIMIZED
#define BIGFOOT_LOG_DEBUG(loggerName, fmt, ...) \
do \
{ \
if (::quill::Logger* logger = ::Bigfoot::Singleton<::Bigfoot::Log>::Instance().GetLogger(loggerName)) \
{ \
QUILL_LOG_DEBUG(logger, fmt __VA_OPT__(, ) __VA_ARGS__); \
} \
else \
{ \
QUILL_LOG_DEBUG(::Bigfoot::Singleton<::Bigfoot::Log>::Instance().RegisterLogger(loggerName), \
fmt __VA_OPT__(, ) __VA_ARGS__); \
} \
} while (0)
#define BIGFOOT_LOG_TRACE(loggerName, fmt, ...) \
do \
{ \
if (::quill::Logger* logger = ::Bigfoot::Singleton<::Bigfoot::Log>::Instance().GetLogger(loggerName)) \
{ \
QUILL_LOG_TRACE_L3(logger, fmt __VA_OPT__(, ) __VA_ARGS__); \
} \
else \
{ \
QUILL_LOG_TRACE_L3(::Bigfoot::Singleton<::Bigfoot::Log>::Instance().RegisterLogger(loggerName), \
fmt __VA_OPT__(, ) __VA_ARGS__); \
} \
} while (0)
#define BIGFOOT_LOG_INFO(loggerName, fmt, ...) \
do \
{ \
if (::quill::Logger* logger = ::Bigfoot::Singleton<::Bigfoot::Log>::Instance().GetLogger(loggerName)) \
{ \
QUILL_LOG_INFO(logger, fmt __VA_OPT__(, ) __VA_ARGS__); \
} \
else \
{ \
QUILL_LOG_INFO(::Bigfoot::Singleton<::Bigfoot::Log>::Instance().RegisterLogger(loggerName), \
fmt __VA_OPT__(, ) __VA_ARGS__); \
} \
} while (0)
#define BIGFOOT_LOG_WARN(loggerName, fmt, ...) \
do \
{ \
if (::quill::Logger* logger = ::Bigfoot::Singleton<::Bigfoot::Log>::Instance().GetLogger(loggerName)) \
{ \
QUILL_LOG_WARNING(logger, fmt __VA_OPT__(, ) __VA_ARGS__); \
} \
else \
{ \
QUILL_LOG_WARNING(::Bigfoot::Singleton<::Bigfoot::Log>::Instance().RegisterLogger(loggerName), \
fmt __VA_OPT__(, ) __VA_ARGS__); \
} \
} while (0)
#define BIGFOOT_LOG_ERROR(loggerName, fmt, ...) \
do \
{ \
if (::quill::Logger* logger = ::Bigfoot::Singleton<::Bigfoot::Log>::Instance().GetLogger(loggerName)) \
{ \
QUILL_LOG_ERROR(logger, fmt __VA_OPT__(, ) __VA_ARGS__); \
} \
else \
{ \
QUILL_LOG_ERROR(::Bigfoot::Singleton<::Bigfoot::Log>::Instance().RegisterLogger(loggerName), \
fmt __VA_OPT__(, ) __VA_ARGS__); \
} \
} while (0)
#define BIGFOOT_LOG_FATAL(loggerName, fmt, ...) \
do \
{ \
if (::quill::Logger* logger = ::Bigfoot::Singleton<::Bigfoot::Log>::Instance().GetLogger(loggerName)) \
{ \
QUILL_LOG_CRITICAL(logger, fmt __VA_OPT__(, ) __VA_ARGS__); \
} \
else \
{ \
QUILL_LOG_CRITICAL(::Bigfoot::Singleton<::Bigfoot::Log>::Instance().RegisterLogger(loggerName), \
fmt __VA_OPT__(, ) __VA_ARGS__); \
} \
} while (0)
#else
#define BIGFOOT_LOG_DEBUG(loggerName, fmt, ...)
#define BIGFOOT_LOG_TRACE(loggerName, fmt, ...)
#define BIGFOOT_LOG_INFO(loggerName, fmt, ...)
#define BIGFOOT_LOG_WARN(loggerName, fmt, ...)
#define BIGFOOT_LOG_ERROR(loggerName, fmt, ...)
#define BIGFOOT_LOG_FATAL(loggerName, fmt, ...)
#endif
#endif

View File

@@ -6,7 +6,7 @@
*********************************************************************/
#ifndef BIGFOOT_@LOGGER_FILENAME_UPPER@_GENERATED_HPP
#define BIGFOOT_@LOGGER_FILENAME_UPPER@_GENERATED_HPP
#include <Utils/Log/Log.hpp>
#include <Utils/Log/LogMacros.hpp>
#if defined BIGFOOT_NOT_OPTIMIZED

View File

@@ -6,7 +6,6 @@
*********************************************************************/
#ifndef BIGFOOT_UTILS_SINGLETON_HPP
#define BIGFOOT_UTILS_SINGLETON_HPP
#include <EASTL/array.h>
#include <EASTL/bit.h>
#include <EASTL/optional.h>
@@ -52,6 +51,9 @@ class Singleton
/**
* Constructor.
*
* Initializes the singleton; this lifetime owns the instance and
* finalizes it on destruction.
*
* \param p_args Arguments for the singleton
*/
template<typename... ARGS>
@@ -60,16 +62,53 @@ class Singleton
Initialize(std::forward<ARGS>(p_args)...);
}
struct EmptyLifetime
{
};
static inline constexpr EmptyLifetime EMPTY_LIFETIME;
/**
* Non-owning constructor.
*
* Does not initialize the singleton and owns nothing. Such a lifetime
* only becomes an owner if it later receives ownership through move
* assignment.
*/
explicit Lifetime(EmptyLifetime) noexcept:
m_owner(false)
{
}
Lifetime(const Lifetime& p_lifetime) = delete;
Lifetime(Lifetime&& p_lifetime) = delete;
explicit Lifetime(Lifetime&& p_lifetime) noexcept:
m_owner(eastl::exchange(p_lifetime.m_owner, false))
{
}
~Lifetime()
{
Finalize();
if (m_owner)
{
Finalize();
}
}
Lifetime& operator=(const Lifetime& p_lifetime) = delete;
Lifetime& operator=(Lifetime&& p_lifetime) = delete;
Lifetime& operator=(Lifetime&& p_lifetime) noexcept
{
m_owner = eastl::exchange(p_lifetime.m_owner, false);
return *this;
}
private:
/**
* Whether this lifetime owns the singleton instance or not.
*/
bool m_owner = true;
};
Singleton& operator=(const Singleton& p_singleton) = delete;

View File

@@ -7,15 +7,12 @@
#ifndef BIGFOOT_UTILS_UTILSASSERTHANDLER_HPP
#define BIGFOOT_UTILS_UTILSASSERTHANDLER_HPP
#include <Utils/Assert.hpp>
#include <Utils/Log/Log.hpp>
#include <Utils/UtilsLogger_generated.hpp>
#if defined BIGFOOT_NOT_OPTIMIZED
#include <EASTL/utility.h>
#include <format>
#include <source_location>
#include <string_view>
namespace Bigfoot
{

View File

@@ -6,7 +6,7 @@
*********************************************************************/
#ifndef BIGFOOT_UTILSLOGGER_GENERATED_HPP
#define BIGFOOT_UTILSLOGGER_GENERATED_HPP
#include <Utils/Log/Log.hpp>
#include <Utils/Log/LogMacros.hpp>
#if defined BIGFOOT_NOT_OPTIMIZED

View File

@@ -6,10 +6,6 @@
*********************************************************************/
#include <Engine/Asset/Asset.hpp>
#include <Engine/EngineLogger_generated.hpp>
#include <Utils/Log/Log.hpp>
#include <Utils/Singleton.hpp>
#include <Utils/TargetMacros.h>
#include <EngineTests/Asset/AssetA.hpp>
@@ -23,12 +19,6 @@ namespace Bigfoot
class AssetFixture: public ::testing::Test
{
protected:
void SetUp() override
{
BIGFOOT_NOT_OPTIMIZED_ONLY(std::ignore = Singleton<Log>::Instance().RegisterLogger(ENGINE_LOGGER);)
}
BIGFOOT_NOT_OPTIMIZED_ONLY(Singleton<Log>::Lifetime m_loggerLifetime;)
};
/****************************************************************************************/

View File

@@ -6,15 +6,9 @@
*********************************************************************/
#include <Engine/BigFile/BigFile.hpp>
#include <Engine/EngineLogger_generated.hpp>
#include <System/Time/Time.hpp>
#include <System/UUID/UUID.hpp>
#include <Utils/Log/Log.hpp>
#include <Utils/Singleton.hpp>
#include <Utils/TargetMacros.h>
#include <EngineTests/BigFileInfo_generated.hpp>
#include <ankerl/unordered_dense.h>
@@ -35,12 +29,8 @@ class BigFileFixture: public ::testing::Test
deleteHeader.Execute();
deleteAsset.Execute();
m_bigFile.CommitTransaction();
BIGFOOT_NOT_OPTIMIZED_ONLY(std::ignore = Singleton<Log>::Instance().RegisterLogger(ENGINE_LOGGER);)
}
BIGFOOT_NOT_OPTIMIZED_ONLY(Singleton<Log>::Lifetime m_loggerLifetime;)
BigFile m_bigFile {File {BIGFILE_ENGINETESTS_LOCATION}};
};

View File

@@ -2,6 +2,4 @@ get_filename_component(PackageName ${CMAKE_CURRENT_SOURCE_DIR} NAME)
project(${PackageName}Tests)
bigfoot_create_package_tests(
"")
bigfoot_create_logger()
"")

View File

@@ -1,21 +0,0 @@
// AUTO-GENERATED DO NOT TOUCH
/*********************************************************************
* \file UtilsTestsLogger.generated.hpp
*
*********************************************************************/
#ifndef BIGFOOT_UTILSTESTSLOGGER_GENERATED_HPP
#define BIGFOOT_UTILSTESTSLOGGER_GENERATED_HPP
#include <Utils/Log/Log.hpp>
#if defined BIGFOOT_NOT_OPTIMIZED
namespace Bigfoot
{
/*
* Logger
*/
inline Log::LoggerInfo UTILSTESTS_LOGGER {"UTILSTESTS_LOGGER", Flat::LogLevel::Trace};
} // namespace Bigfoot
#endif
#endif

View File

@@ -6,10 +6,6 @@
*********************************************************************/
#include <Utils/Log/Log.hpp>
#include <Utils/Singleton.hpp>
#include <UtilsTests/UtilsTestsLogger_generated.hpp>
#if defined BIGFOOT_NOT_OPTIMIZED
#include <gtest/gtest.h>
@@ -19,11 +15,6 @@ namespace Bigfoot
class LogFixture: public ::testing::Test
{
protected:
void SetUp() override
{
UTILSTESTS_LOGGER = {"UTILSTESTS_LOGGER", Flat::LogLevel::Trace};
}
static constexpr Flat::LogLevel QuillLogLevelToLogLevel(const quill::LogLevel p_level)
{
switch (p_level)
@@ -48,24 +39,25 @@ class LogFixture: public ::testing::Test
}
Log m_log;
Log::LoggerInfo m_logger {"LOGGER", Flat::LogLevel::Trace};
};
/****************************************************************************************/
TEST_F(LogFixture, RegisterLogger_ShouldRegisterTheLogger)
{
const quill::Logger* logger = m_log.RegisterLogger(UTILSTESTS_LOGGER);
const quill::Logger* logger = m_log.RegisterLogger(m_logger);
EXPECT_TRUE(logger);
EXPECT_EQ(logger, m_log.GetLogger(UTILSTESTS_LOGGER));
EXPECT_EQ(logger->get_logger_name(), UTILSTESTS_LOGGER.m_name);
EXPECT_EQ(QuillLogLevelToLogLevel(logger->get_log_level()), UTILSTESTS_LOGGER.m_level);
EXPECT_EQ(logger, m_log.GetLogger(m_logger));
EXPECT_EQ(logger->get_logger_name(), m_logger.m_name);
EXPECT_EQ(QuillLogLevelToLogLevel(logger->get_log_level()), m_logger.m_level);
}
/****************************************************************************************/
TEST_F(LogFixture, GetLogger_ShouldReturnNullptrIfTheLoggerDoesNotExist)
{
EXPECT_FALSE(m_log.GetLogger(UTILSTESTS_LOGGER));
EXPECT_FALSE(m_log.GetLogger(m_logger));
}
/****************************************************************************************/
@@ -73,66 +65,18 @@ TEST_F(LogFixture, GetLogger_ShouldReturnNullptrIfTheLoggerDoesNotExist)
TEST_F(LogFixture, GetLogger_ShouldReturnTheLoggerIfItExists)
{
[[maybe_unused]]
const quill::Logger* logger = m_log.RegisterLogger(UTILSTESTS_LOGGER);
EXPECT_TRUE(m_log.GetLogger(UTILSTESTS_LOGGER));
const quill::Logger* logger = m_log.RegisterLogger(m_logger);
EXPECT_TRUE(m_log.GetLogger(m_logger));
}
/****************************************************************************************/
TEST_F(LogFixture, ChangeLoggerLogLevel_ShouldChangeTheLoggerLogLevel)
{
const quill::Logger* logger = m_log.RegisterLogger(UTILSTESTS_LOGGER);
const quill::Logger* logger = m_log.RegisterLogger(m_logger);
m_log.ChangeLoggerLogLevel(UTILSTESTS_LOGGER, Flat::LogLevel::Critical);
m_log.ChangeLoggerLogLevel(m_logger, Flat::LogLevel::Critical);
EXPECT_EQ(QuillLogLevelToLogLevel(logger->get_log_level()), Flat::LogLevel::Critical);
}
/****************************************************************************************/
TEST_F(LogFixture, LogDebug)
{
Singleton<Log>::Lifetime singletonLifetime;
BIGFOOT_LOG_DEBUG(UTILSTESTS_LOGGER, "Hello");
}
/****************************************************************************************/
TEST_F(LogFixture, LogTrace)
{
Singleton<Log>::Lifetime singletonLifetime;
BIGFOOT_LOG_TRACE(UTILSTESTS_LOGGER, "Hello");
}
/****************************************************************************************/
TEST_F(LogFixture, LogInfo)
{
Singleton<Log>::Lifetime singletonLifetime;
BIGFOOT_LOG_INFO(UTILSTESTS_LOGGER, "Hello");
}
/****************************************************************************************/
TEST_F(LogFixture, LogWarn)
{
Singleton<Log>::Lifetime singletonLifetime;
BIGFOOT_LOG_WARN(UTILSTESTS_LOGGER, "Hello");
}
/****************************************************************************************/
TEST_F(LogFixture, LogError)
{
Singleton<Log>::Lifetime singletonLifetime;
BIGFOOT_LOG_ERROR(UTILSTESTS_LOGGER, "Hello");
}
/****************************************************************************************/
TEST_F(LogFixture, LogFatal)
{
Singleton<Log>::Lifetime singletonLifetime;
BIGFOOT_LOG_FATAL(UTILSTESTS_LOGGER, "Hello");
}
} // namespace Bigfoot
#endif

View File

@@ -0,0 +1,64 @@
/*********************************************************************
* \file LogMacros.cpp
*
* \author Romain BOULLARD
* \date May 2026
*********************************************************************/
#include <Utils/Log/LogMacros.hpp>
#if defined BIGFOOT_NOT_OPTIMIZED
#include <gtest/gtest.h>
namespace Bigfoot
{
class LogMacrosFixture: public ::testing::Test
{
protected:
Singleton<Log>::Lifetime m_singletonLifetime;
Log::LoggerInfo m_logger {"LOGGER", Flat::LogLevel::Trace};
};
/****************************************************************************************/
TEST_F(LogMacrosFixture, LogDebug)
{
BIGFOOT_LOG_DEBUG(m_logger, "Hello");
}
/****************************************************************************************/
TEST_F(LogMacrosFixture, LogTrace)
{
BIGFOOT_LOG_TRACE(m_logger, "Hello");
}
/****************************************************************************************/
TEST_F(LogMacrosFixture, LogInfo)
{
BIGFOOT_LOG_INFO(m_logger, "Hello");
}
/****************************************************************************************/
TEST_F(LogMacrosFixture, LogWarn)
{
BIGFOOT_LOG_WARN(m_logger, "Hello");
}
/****************************************************************************************/
TEST_F(LogMacrosFixture, LogError)
{
BIGFOOT_LOG_ERROR(m_logger, "Hello");
}
/****************************************************************************************/
TEST_F(LogMacrosFixture, LogFatal)
{
BIGFOOT_LOG_FATAL(m_logger, "Hello");
}
} // namespace Bigfoot
#endif

View File

@@ -84,14 +84,43 @@ TEST_F(SingletonFixture, ConstructorAndDestructorShouldBeCalled)
{
::testing::InSequence seq;
EXPECT_CALL(*m_mock, Construct());
EXPECT_CALL(*m_mock, Destruct());
EXPECT_CALL(*m_mock, Construct()).Times(1);
EXPECT_CALL(*m_mock, Destruct()).Times(1);
Singleton<SingletonTest>::Lifetime singleton {42};
}
/****************************************************************************************/
TEST_F(SingletonFixture, ConstructorAndDestructorShouldNotBeCalledForEmptyLifetime)
{
::testing::InSequence seq;
EXPECT_CALL(*m_mock, Construct()).Times(0);
EXPECT_CALL(*m_mock, Destruct()).Times(0);
Singleton<SingletonTest>::Lifetime singleton {Singleton<SingletonTest>::Lifetime::EMPTY_LIFETIME};
}
/****************************************************************************************/
TEST_F(SingletonFixture, MovingALifetimeKeepsTheSIngletonAlive)
{
::testing::InSequence seq;
EXPECT_CALL(*m_mock, Construct()).Times(1);
EXPECT_CALL(*m_mock, Destruct()).Times(1);
Singleton<SingletonTest>::Lifetime emptyLifetime {Singleton<SingletonTest>::Lifetime::EMPTY_LIFETIME};
{
Singleton<SingletonTest>::Lifetime singleton {42};
emptyLifetime = std::move(singleton);
}
EXPECT_EQ(Singleton<SingletonTest>::Instance().Data(), 42);
}
/****************************************************************************************/
TEST_F(SingletonFixture, Instance_ShouldReturnTheInstance)
{
Singleton<SingletonTest>::Lifetime singleton {42};