JD2022-TU1/main/extern/UbiServices/custom/testsIntegration/testInstancesManager.cpp

586 lines
20 KiB
C++

////////////////////////////////////////////////////////////////////////////////
// (c) Copyright, Ubisoft Entertainment Inc. || Created by Harbour //
////////////////////////////////////////////////////////////////////////////////
#include "tests/config.h"
#include "tests/fixture/memoryCheckFixture.h"
#include <ubiservices/core/errors/errorDetails.h>
#include <ubiservices/facade.h>
#include <ubiservices/ubiservices.h>
#include <ubiservices/localizationHelper.h>
#include <ubiservices/loggingHelper.h>
#include <../private/ubiservices/localizationHelperPriv.h>
#include <../private/ubiservices/core/debug/systemChecker.h>
#include <../private/ubiservices/core/configs/environmentHelper.h>
#include <../private/ubiservices/core/helpers/facadesManager.h>
#include <../private/ubiservices/core/helpers/helpers.h>
#include <../private/ubiservices/core/helpers/instancesManager.h>
#include <usCommon/authenticationHelper.h>
#include <usCommon/firstPartyInit.h>
#include <usCommon/settings.h>
#include <usCommon/options.h>
#include <ealmem.h>
// it will be removed from ealmem.h in version 7.00.
// set as extern because we will want to continue using it in our tests even after the function will be removed from the eal API.
extern eal_u32 EalMemGetAllocated();
namespace US_NS {;
US_DEFINE_TEST(TestInstancesManager);
};
#if !defined US_DLL && (!defined(US_UNITY3D) && !defined(RETAIL))
namespace US_NS {;
typedef LeakCheckerNoInit INSTANCE_MANAGER;
/// @cond PRIVATE_API
namespace TestInstancesManager_BF
{
class SystemCheckerMock
{
public:
SystemCheckerMock()
{
m_hasAsserted = false;
SystemChecker::RegisterSystemCheckCallBack(&SystemCheckerMock::systemCheck);
}
~SystemCheckerMock()
{
SystemChecker::UnregisterSystemCheckCallBack();
}
bool hasAsserted() const
{
return m_hasAsserted;
}
void reset()
{
m_hasAsserted = false;
}
private:
static void systemCheck(const char* strExpression, const char* szFile, uint32 uiLine)
{
US_UNUSED(strExpression);
US_UNUSED(szFile);
US_UNUSED(uiLine);
m_hasAsserted = true;
}
static bool m_hasAsserted;
};
bool SystemCheckerMock::m_hasAsserted = false;
#if defined(US_TARGET_XONE)
const uint32 MAX_UNINIT_TIME_IN_MICRO = 85 * 1000; // Empiric value (found values between 42000 and 83000 in debug)
#else
const uint32 MAX_UNINIT_TIME_IN_MICRO = 35 * 1000; // Empiric value (32000 happened on the build farm)
#endif
}
/// @endcond
/// @test Validates that ASSERT occurs if the InstanceManager is accessed before calling configure.
#if !defined(US_SYSTEM_CHECK_ENABLED)
TEST_F(INSTANCE_MANAGER, DISABLED_LOCAL_GetInstanceManagerAsserts)
#else
TEST_F(INSTANCE_MANAGER, LOCAL_GetInstanceManagerAsserts)
#endif // US_RETAIL
{
TestInstancesManager_BF::SystemCheckerMock sysCheckMock;
initializeSdk();
EXPECT_TRUE(InstancesManager::getInstance() == NULL);
EXPECT_TRUE(sysCheckMock.hasAsserted());
sysCheckMock.reset();
configureSdk(GameConfig(
ApplicationId(NS_COMMON::Options::getApplicationId().c_str()),
NS_COMMON::Options::getApplicationBuildId().c_str()
#if defined(US_SDK_S2S)
, NS_COMMON::Options::environment()
#endif
, OnlineAccessContext::Standard
#if !defined(US_SDK_S2S)
, GameConfigEvent(US_SDK_VERSION_CONST_CHAR, US_TEST_NS::US_SDK_DUMMY_GAME_SKU, Vector<EventTypeInfo>())
#endif
#if defined(US_TARGET_PS4) || defined(US_TARGET_SWITCH) || defined(US_TARGET_XONE) || defined(US_TARGET_GGP) || defined(US_TARGET_KILI)
, GameConfigConsole(NS_COMMON::FIRSTPARTY_APP_ID)
#endif
));
EXPECT_FALSE(InstancesManager::getInstance() == NULL);
EXPECT_FALSE(sysCheckMock.hasAsserted());
US_TEST_NS::Helper::uninitializeSdk();
EXPECT_FALSE(sysCheckMock.hasAsserted());
EalLogLibInit();
EXPECT_TRUE(InstancesManager::getInstance() == NULL);
EXPECT_TRUE(sysCheckMock.hasAsserted());
EalLogLibShutdown();
}
/// @test Validates normal creation/destruction sequence.
#if !defined(US_SYSTEM_CHECK_ENABLED)
TEST_F(INSTANCE_MANAGER, DISABLED_LOCAL_NormalUsage) // TODO: Disabled in retail
#else
TEST_F(INSTANCE_MANAGER, LOCAL_NormalUsage)
#endif // US_RETAIL
{
initializeSdk();
TestInstancesManager_BF::SystemCheckerMock sysCheckMock;
{
configureSdk(GameConfig(
ApplicationId(NS_COMMON::Options::getApplicationId().c_str()),
NS_COMMON::Options::getApplicationBuildId().c_str()
#if defined(US_SDK_S2S)
, NS_COMMON::Options::environment()
#endif
, OnlineAccessContext::Standard
#if !defined(US_SDK_S2S)
, GameConfigEvent(US_SDK_VERSION_CONST_CHAR, US_TEST_NS::US_SDK_DUMMY_GAME_SKU, Vector<EventTypeInfo>())
#endif
#if defined(US_TARGET_PS4) || defined(US_TARGET_SWITCH) || defined(US_TARGET_XONE) || defined(US_TARGET_GGP) || defined(US_TARGET_KILI)
, GameConfigConsole(NS_COMMON::FIRSTPARTY_APP_ID)
#endif
));
{
Facade facade;
}
}
US_TEST_NS::Helper::uninitializeSdk();
EXPECT_FALSE(sysCheckMock.hasAsserted());
initializeSdk();
{
configureSdk(GameConfig(
ApplicationId(NS_COMMON::Options::getApplicationId().c_str()),
NS_COMMON::Options::getApplicationBuildId().c_str()
#if defined(US_SDK_S2S)
, NS_COMMON::Options::environment()
#endif
, OnlineAccessContext::Standard
#if !defined(US_SDK_S2S)
, GameConfigEvent(US_SDK_VERSION_CONST_CHAR, US_TEST_NS::US_SDK_DUMMY_GAME_SKU, Vector<EventTypeInfo>())
#endif
#if defined(US_TARGET_PS4) || defined(US_TARGET_SWITCH) || defined(US_TARGET_XONE) || defined(US_TARGET_GGP) || defined(US_TARGET_KILI)
, GameConfigConsole(NS_COMMON::FIRSTPARTY_APP_ID)
#endif
));
{
Facade facade1;
Facade facade2;
}
EXPECT_FALSE(sysCheckMock.hasAsserted());
{
Facade facade;
}
}
US_TEST_NS::Helper::uninitializeSdk();
EXPECT_FALSE(sysCheckMock.hasAsserted());
}
/// @test Validates that ASSERT occurs if the facade is created before
/// the InstanceManager. Validation for facade destruction is done
/// in an other test case.
#if !defined(US_SYSTEM_CHECK_ENABLED)
TEST_F(INSTANCE_MANAGER, DISABLED_LOCAL_FacadeBeforeInit) // TODO: Disabled in retail
#else
TEST_F(INSTANCE_MANAGER, LOCAL_FacadeBeforeInit)
#endif // US_RETAIL
{
TestInstancesManager_BF::SystemCheckerMock sysCheckMock;
Facade facade;
EXPECT_TRUE(sysCheckMock.hasAsserted());
sysCheckMock.reset();
}
/// @test Validates that memory is actually released when uninitialize is called
#if !defined(US_SYSTEM_CHECK_ENABLED)
TEST_F(INSTANCE_MANAGER, DISABLED_LOCAL_Init) // TODO: Disabled in retail
#else
TEST_F(INSTANCE_MANAGER, LOCAL_Init)
#endif //US_RETAIL
{
initializeSdk();
TestInstancesManager_BF::SystemCheckerMock sysCheckMock;
configureSdk(GameConfig(
ApplicationId(NS_COMMON::Options::getApplicationId().c_str()),
NS_COMMON::Options::getApplicationBuildId().c_str()
#if defined(US_SDK_S2S)
, NS_COMMON::Options::environment()
#endif
, OnlineAccessContext::Standard
#if !defined(US_SDK_S2S)
, GameConfigEvent(US_SDK_VERSION_CONST_CHAR, US_TEST_NS::US_SDK_DUMMY_GAME_SKU, Vector<EventTypeInfo>())
#endif
#if defined(US_TARGET_PS4) || defined(US_TARGET_SWITCH) || defined(US_TARGET_XONE) || defined(US_TARGET_GGP) || defined(US_TARGET_KILI)
, GameConfigConsole(NS_COMMON::FIRSTPARTY_APP_ID)
#endif
));
{
Facade facade;
}
const uint32 memStart = EalMemGetAllocated();
// should delete hosted object (log, httpManager...)
US_TEST_NS::Helper::uninitializeSdk();
EXPECT_FALSE(sysCheckMock.hasAsserted());
const uint32 memEnd = EalMemGetAllocated();
EXPECT_GE(memStart, memEnd);
}
/// @test Validates normal destruction sequence happens after a login.
#if !defined(US_SYSTEM_CHECK_ENABLED)
TEST_F(INSTANCE_MANAGER, DISABLED_US_NormalUsageAndLogin) // TODO: Disabled in retail
#else
TEST_F(INSTANCE_MANAGER, US_NormalUsageAndLogin)
#endif // RETAIL_VERSION
{
initializeSdk();
TestInstancesManager_BF::SystemCheckerMock sysCheckMock;
configureSdk(GameConfig(
ApplicationId(NS_COMMON::Options::getApplicationId().c_str()),
NS_COMMON::Options::getApplicationBuildId().c_str()
#if defined(US_SDK_S2S)
, NS_COMMON::Options::environment()
#endif
#if defined(US_SDK_TEST_CHINA)
, OnlineAccessContext::China
#else
, OnlineAccessContext::Standard
#endif
#if !defined(US_SDK_S2S)
, GameConfigEvent(US_SDK_VERSION_CONST_CHAR, US_TEST_NS::US_SDK_DUMMY_GAME_SKU, Vector<EventTypeInfo>())
#endif
#if defined(US_TARGET_PS4) || defined(US_TARGET_SWITCH) || defined(US_TARGET_XONE) || defined(US_TARGET_GGP) || defined(US_TARGET_KILI)
, GameConfigConsole(NS_COMMON::FIRSTPARTY_APP_ID)
#endif
));
{
Facade facade;
const AsyncResult<Empty> loginAsync = facade.createSession(GET_CREDENTIALS(), {}, {});
EXPECT_TRUE(loginAsync.wait(NS_COMMON::DEFAULT_WAIT_TIME));
US_EXPECT_SUCCESS(loginAsync);
}
US_TEST_NS::Helper::uninitializeSdk();
EXPECT_FALSE(sysCheckMock.hasAsserted());
}
/// @test Validates that \c uninitializeSDK can be called when a facade
/// still exists. A system check is expected during facade destruction because
/// a message is attempted to be written to the EventLog.
/// @disabled Is this feature still supported? See US-4197
#if !defined(US_SYSTEM_CHECK_ENABLED)
TEST_F(INSTANCE_MANAGER, DISABLED_LOCAL_UninitThenDeleteFacade) // TODO: Disabled in retail
#else
TEST_F(INSTANCE_MANAGER, DISABLED_LOCAL_UninitThenDeleteFacade) // TODO: Is this feature still supported? See US-4197
#endif // US_RETAIL
{
initializeSdk();
TestInstancesManager_BF::SystemCheckerMock sysCheckMock;
{
configureSdk(GameConfig(
ApplicationId(NS_COMMON::Options::getApplicationId().c_str()),
NS_COMMON::Options::getApplicationBuildId().c_str()
#if defined(US_SDK_S2S)
, NS_COMMON::Options::environment()
#endif
, OnlineAccessContext::Standard
#if !defined(US_SDK_S2S)
, GameConfigEvent(US_SDK_VERSION_CONST_CHAR, US_TEST_NS::US_SDK_DUMMY_GAME_SKU, Vector<EventTypeInfo>())
#endif
#if defined(US_TARGET_PS4) || defined(US_TARGET_SWITCH) || defined(US_TARGET_XONE) || defined(US_TARGET_GGP) || defined(US_TARGET_KILI)
, GameConfigConsole(NS_COMMON::FIRSTPARTY_APP_ID)
#endif
));
Facade facade;
US_TEST_NS::Helper::uninitializeSdk();
EXPECT_FALSE(sysCheckMock.hasAsserted());
}
EXPECT_TRUE(sysCheckMock.hasAsserted());
}
/// @test Validates that \c uninitializeSdk may be called when a facade is connected.
/// A system check is expected during facade destruction because a message is
/// attempted to be written to the \c EventLog.
/// @disabled Is this feature still supported? See US-4197
#if !defined(US_SYSTEM_CHECK_ENABLED)
TEST_F(INSTANCE_MANAGER, DISABLED_US_UninitThenDeleteFacadeAfterLogin) // TODO: Disabled in retail
#else
// TODO review: adding the new event config request causes deadlock warnings.
// We must play with the locks level to make sure everything is fine
TEST_F(INSTANCE_MANAGER, DISABLED_US_UninitThenDeleteFacadeAfterLogin) // TODO: Is this feature still supported? See US-4197
#endif // US_RETAIL
{
initializeSdk();
TestInstancesManager_BF::SystemCheckerMock sysCheckMock;
{
configureSdk(GameConfig(
ApplicationId(NS_COMMON::Options::getApplicationId().c_str()),
NS_COMMON::Options::getApplicationBuildId().c_str()
#if defined(US_SDK_S2S)
, NS_COMMON::Options::environment()
#endif
, OnlineAccessContext::Standard
#if !defined(US_SDK_S2S)
, GameConfigEvent(US_SDK_VERSION_CONST_CHAR, US_TEST_NS::US_SDK_DUMMY_GAME_SKU, Vector<EventTypeInfo>())
#endif
#if defined(US_TARGET_PS4) || defined(US_TARGET_SWITCH) || defined(US_TARGET_XONE) || defined(US_TARGET_GGP) || defined(US_TARGET_KILI)
, GameConfigConsole(NS_COMMON::FIRSTPARTY_APP_ID)
#endif
));
Facade facade;
const AsyncResult<Empty> loginAsync = facade.createSession(GET_CREDENTIALS(), {}, {});
EXPECT_TRUE(loginAsync.wait(NS_COMMON::DEFAULT_WAIT_TIME));
US_EXPECT_SUCCESS(loginAsync);
US_TEST_NS::Helper::uninitializeSdk();
EXPECT_FALSE(sysCheckMock.hasAsserted());
}
EXPECT_TRUE(sysCheckMock.hasAsserted());
}
/// @test Validates that \c uninitializeSDK can be called when jobs are pending.
/// A system check is expected during facade destruction because a message is attempted
/// to be written to the EventLog.
#if !defined(US_SYSTEM_CHECK_ENABLED)
TEST_F(INSTANCE_MANAGER, DISABLED_US_UninitDuringLogin) // TODO: Disabled in retail
#else
/// @note Failed on Xbox One (flaky). Dead locking on tear down...
TEST_F(INSTANCE_MANAGER, DISABLED_US_UninitDuringLogin) // TODO: Disabled... why?
#endif // US_RETAIL
{
initializeSdk();
// Checking asserts does not work in retail
TestInstancesManager_BF::SystemCheckerMock sysCheckMock;
{
configureSdk(GameConfig(
ApplicationId(NS_COMMON::Options::getApplicationId().c_str()),
NS_COMMON::Options::getApplicationBuildId().c_str()
#if defined(US_SDK_S2S)
, NS_COMMON::Options::environment()
#endif
, OnlineAccessContext::Standard
#if !defined(US_SDK_S2S)
, GameConfigEvent(US_SDK_VERSION_CONST_CHAR, US_TEST_NS::US_SDK_DUMMY_GAME_SKU, Vector<EventTypeInfo>())
#endif
#if defined(US_TARGET_PS4) || defined(US_TARGET_SWITCH) || defined(US_TARGET_XONE) || defined(US_TARGET_GGP) || defined(US_TARGET_KILI)
, GameConfigConsole(NS_COMMON::FIRSTPARTY_APP_ID)
#endif
));
Facade facade;
const AsyncResult<Empty> loginAsync = facade.createSession(GET_CREDENTIALS(), {}, {});
ASSERT_TRUE(loginAsync.isProcessing());
Helper::sleep(500); // to make sure job is started
US_TEST_NS::Helper::uninitializeSdk();
EXPECT_FALSE(sysCheckMock.hasAsserted());
}
EXPECT_TRUE(sysCheckMock.hasAsserted());
}
namespace HelperUninit
{
struct Stats
{
ClockSteady::TDuration first = 0;
ClockSteady::TDuration min = static_cast<uint64>(-1);
ClockSteady::TDuration max = 0;
ClockSteady::TDuration sum = 0;
uint32 count = 0;
};
Stats UninitializeSdk()
{
Stats stats;
EXPECT_EQ(0, stats.count);
EXPECT_EQ(0, stats.sum);
UninitializeResult result;
do
{
const ClockSteady::TTimePoint start = ClockSteady::getTime();
result = uninitializeSdk();
const ClockSteady::TTimePoint end = ClockSteady::getTime();
const ClockSteady::TDuration duration = (end - start).getEpoch();
if (stats.first == 0)
{
stats.first = duration;
}
if (duration < stats.min)
{
stats.min = duration;
}
if (duration > stats.max)
{
stats.max = duration;
}
stats.sum += duration;
stats.count++;
} while (result != UninitializeResult::Complete);
PRINT_LINE("Time consumed executing uninitializeSdk (first call): %d", static_cast<uint32>(stats.first.getCount()));
if (stats.count > 1)
{
PRINT_LINE("Time consumed executing uninitializeSdk (min/max): %d/%d",
static_cast<uint32>(stats.min.getCount()), static_cast<uint32>(stats.max.getCount()));
}
else
{
PRINT_LINE("Time consumed executing uninitializeSdk (min/max): -/-");
}
PRINT_LINE("Total time consumed executing uninitializeSdk: %d", static_cast<uint32>(stats.sum.getCount()));
PRINT_LINE("Total calls to uninitializeSdk: %d", static_cast<uint32>(stats.count));
PRINT_LINE("Avegage time processing uninitializeSdk: %d", static_cast<uint32>((stats.sum.getCount()) / stats.count));
return stats;
}
}
TEST_F(INSTANCE_MANAGER, LOCAL_NonBlockingUninitWitness)
{
initializeSdk();
configureSdk(GameConfig(
ApplicationId(NS_COMMON::Options::getApplicationId().c_str()),
NS_COMMON::Options::getApplicationBuildId().c_str()
#if defined(US_SDK_S2S)
, NS_COMMON::Options::environment()
#endif
, OnlineAccessContext::Standard
#if !defined(US_SDK_S2S)
, GameConfigEvent(US_SDK_VERSION_CONST_CHAR, US_TEST_NS::US_SDK_DUMMY_GAME_SKU, Vector<EventTypeInfo>())
#endif
#if defined(US_TARGET_PS4) || defined(US_TARGET_SWITCH) || defined(US_TARGET_XONE) || defined(US_TARGET_GGP) || defined(US_TARGET_KILI)
, GameConfigConsole(NS_COMMON::FIRSTPARTY_APP_ID)
#endif
));
//US_TEST_NS::Helper::uninitializeSdk(); // Not applicable for this test.
const auto stats = HelperUninit::UninitializeSdk();
EXPECT_LE(stats.max.getCount(), TestInstancesManager_BF::MAX_UNINIT_TIME_IN_MICRO * 1000);
}
TEST_F(INSTANCE_MANAGER, US_NonBlockingUninitDuringLogin) // TODO: Rework required
{
initializeSdk();
configureSdk(GameConfig(
ApplicationId(NS_COMMON::Options::getApplicationId().c_str()),
NS_COMMON::Options::getApplicationBuildId().c_str()
#if defined(US_SDK_S2S)
, NS_COMMON::Options::environment()
#endif
, OnlineAccessContext::Standard
#if !defined(US_SDK_S2S)
, GameConfigEvent(US_SDK_VERSION_CONST_CHAR, US_TEST_NS::US_SDK_DUMMY_GAME_SKU, Vector<EventTypeInfo>())
#endif
#if defined(US_TARGET_PS4) || defined(US_TARGET_SWITCH) || defined(US_TARGET_XONE) || defined(US_TARGET_GGP) || defined(US_TARGET_KILI)
, GameConfigConsole(NS_COMMON::FIRSTPARTY_APP_ID)
#endif
));
Helper::sleep(500); // to make sure job is started
// Perform login
{
Facade facade;
const AsyncResult<Empty> loginAsync = facade.createSession(GET_CREDENTIALS(), {}, {});
ASSERT_TRUE(loginAsync.isProcessing());
Helper::sleep(500); // to make sure job is started
}
//US_TEST_NS::Helper::uninitializeSdk(); // Not applicable for this test.
const auto stats = HelperUninit::UninitializeSdk();
EXPECT_LE(stats.max.getCount(), TestInstancesManager_BF::MAX_UNINIT_TIME_IN_MICRO * 1000);
}
#if !defined(US_SDK_S2S)
TEST_F(INSTANCE_MANAGER, LOCAL_LocalizationLocaleCode)
{
initializeSdk();
{
configureSdk(GameConfig(
ApplicationId(NS_COMMON::Options::getApplicationId().c_str()),
NS_COMMON::Options::getApplicationBuildId().c_str()
#if defined(US_SDK_S2S)
, NS_COMMON::Options::environment()
#endif
, OnlineAccessContext::Standard
#if !defined(US_SDK_S2S)
, GameConfigEvent(US_SDK_VERSION_CONST_CHAR, US_TEST_NS::US_SDK_DUMMY_GAME_SKU, Vector<EventTypeInfo>())
#endif
#if defined(US_TARGET_PS4) || defined(US_TARGET_SWITCH) || defined(US_TARGET_XONE) || defined(US_TARGET_GGP) || defined(US_TARGET_KILI)
, GameConfigConsole(NS_COMMON::FIRSTPARTY_APP_ID)
#endif
));
// See LocalizationHelper documentation for information on why PS4 is disabled here.
#if !defined(US_TARGET_PS4) && !defined(US_TARGET_KILI)
EXPECT_NE(String(), LocalizationHelper::getLocaleCode());
EXPECT_EQ(LocalizationHelperPrivate::getPlatformLocaleCode(), LocalizationHelper::getLocaleCode());
#endif
const String localCode = "us-EN";
LocalizationHelper::setLocaleCode(localCode);
EXPECT_EQ(localCode, LocalizationHelper::getLocaleCode());
}
US_TEST_NS::Helper::uninitializeSdk();
}
#endif
};
#endif // !defined US_DLL && (!defined(US_UNITY3D) && !defined(RETAIL))