JD2022-TU1/main/extern/UbiServices/custom/tests/fixture/authenticationFixture.inl

434 lines
No EOL
14 KiB
C++

////////////////////////////////////////////////////////////////////////////////
// (c) Copyright, Ubisoft Entertainment Inc. || Created by Harbour //
////////////////////////////////////////////////////////////////////////////////
/// @cond PREVENTS_DOXYGEN_WARNING
#pragma once
#include "tests/common/helpers.h"
#include <../private/ubiservices/core/chrono/chronometer.h>
#include <../private/ubiservices/core/debug/systemChecker.h>
#include <ubiservices/core/errors/errorDetails.h>
#include <../private/ubiservices/core/helpers/instancesManager.h>
#include <../private/ubiservices/core/helpers/streamOperators.h>
#include <ubiservices/core/JSON/jsonWriter.h>
#include <ubiservices/core/log/devices/logDeviceConsole.h>
#include <ubiservices/core/log/outputFormat.h>
#include <ubiservices/facade.h>
#include <ubiservices/loggingHelper.h>
#include <ubiservices/services/authentication/authenticationClient.h>
#include <ubiservices/services/authentication/sessionInfo.h>
#include <ubiservices/services/event/eventClient.h>
#include <ubiservices/services/event/eventNotification.h>
#include <ubiservices/services/notification/notificationClient.h>
#include <../private/ubiservices/services/parameters/featureSwitch.h>
#include <usCommon/authenticationHelper.h>
#include <usCommon/options.h>
#include <usCommon/settings.h>
namespace US_NS {;
bool EventsNotificationHelper::waitForEventConfig(ListenerHandler<EventNotification>& handler)
{
bool isRequestEventConfigDone = false;
bool isConfigSuccess = false;
HighResolutionChrono chrono;
while(!isRequestEventConfigDone && chrono.getElapsed()/1000u < NS_COMMON::DEFAULT_WAIT_TIME*1000u)
{
do
{
Helper::sleep(25);
if (handler.isNotificationAvailable())
{
const EventNotification notif = handler.popNotification();
if(notif.m_type == EventNotificationType::EventConfigFailure)
{
isRequestEventConfigDone = true;
isConfigSuccess = false;
}
if(notif.m_type == EventNotificationType::EventConfigSuccess)
{
isRequestEventConfigDone = true;
isConfigSuccess = true;
}
}
}
while (handler.isNotificationAvailable());
}
return isConfigSuccess;
}
template<uint32 facadesCount, bool executeLogin>
AuthenticationFixture<facadesCount, executeLogin>::AuthenticationFixture()
#if !defined(US_SDK_S2S)
: m_notificationContentTypes(NULL)
#endif
{
for(uint32 i = 0; i < facadesCount; i++)
{
m_loginIsSuccessfulArray[i] = false;
m_facades[i] = NULL;
#if !defined(US_SDK_S2S)
m_credentials[i] = NULL;
#endif
}
}
#if !defined(US_SDK_S2S)
template<uint32 facadesCount, bool executeLogin>
AuthenticationFixture<facadesCount, executeLogin>::~AuthenticationFixture()
{
US_DELETE(m_notificationContentTypes);
}
#endif
template<uint32 facadesCount, bool executeLogin>
void AuthenticationFixture<facadesCount, executeLogin>::SetUp()
{
LeakChecker::SetUp(); // Done first to maximize memory leak coverage
for(uint32 i = 0; i < facadesCount; i++)
{
SetUp(i);
}
}
template<uint32 facadesCount, bool executeLogin>
void AuthenticationFixture<facadesCount, executeLogin>::TearDown()
{
// Code here is called right after each test (before the destructor).
for(uint32 i = 0; i < facadesCount; i++)
{
TearDown(i);
}
LeakChecker::TearDown(); // Done last to maximize memory leak coverage
}
template<uint32 facadesCount, bool executeLogin>
uint32 AuthenticationFixture<facadesCount, executeLogin>::getInstancesCount() const
{
return m_facadesCount;
}
template<uint32 facadesCount, bool executeLogin>
bool AuthenticationFixture<facadesCount, executeLogin>::isLoginRequired() const
{
return m_executeLogin;
}
template<uint32 facadesCount, bool executeLogin>
Facade& AuthenticationFixture<facadesCount, executeLogin>::getFacade(uint32 index)
{
US_TEST_ASSERT(index < facadesCount, "Index out of range");
return *m_facades[index];
}
template<uint32 facadesCount, bool executeLogin>
const Facade& AuthenticationFixture<facadesCount, executeLogin>::getFacade(uint32 index) const
{
US_TEST_ASSERT(index < facadesCount, "Index out of range");
return *m_facades[index];
}
template<uint32 facadesCount, bool executeLogin>
const Facade& AuthenticationFixture<facadesCount, executeLogin>::getFacadeConst(uint32 index) const
{
US_TEST_ASSERT(index < facadesCount, "Index out of range");
return *m_facades[index];
}
template<uint32 facadesCount, bool executeLogin>
FacadeInternal& AuthenticationFixture<facadesCount, executeLogin>::getFacadeInternal(uint32 index)
{
US_TEST_ASSERT(index < facadesCount, "Index out of range");
return *reinterpret_cast<FacadeInternal*>(m_facades[index]->m_facadeInternal.getPtr());
}
template<uint32 facadesCount, bool executeLogin>
const FacadeInternal& AuthenticationFixture<facadesCount, executeLogin>::getFacadeInternal(uint32 index) const
{
US_TEST_ASSERT(index < facadesCount, "Index out of range");
return *reinterpret_cast<FacadeInternal*>(m_facades[index]->m_facadeInternal.getPtr());
}
template<uint32 facadesCount, bool executeLogin>
ListenerHandler<EventNotification>& AuthenticationFixture<facadesCount, executeLogin>::getHandler(uint32 index)
{
US_TEST_ASSERT(index < facadesCount, "Index out of range");
return *m_handlers[index];
}
#if !defined(US_SDK_S2S)
template<uint32 facadesCount, bool executeLogin>
const PlayerCredentials& AuthenticationFixture<facadesCount, executeLogin>::getCredentials(uint32 index) const
{
US_TEST_ASSERT(index < facadesCount, "Index out of range");
return *m_credentials[index];
}
template<uint32 facadesCount, bool executeLogin>
Vector<String> AuthenticationFixture<facadesCount, executeLogin>::getWebSocketContentTypes() const
{
// Create a somewhat unique tag for types to be able to filter connections
if (m_notificationContentTypes == NULL)
{
m_notificationContentTypes = US_NEW(Vector<String>);
#if defined(US_CHINA_PROD_NOTIFICATION_TYPE)
*m_notificationContentTypes = {
"OnlineNotificationType*",
};
#else
const String typeTag = String::formatText("_%llu", ClockSteady::getTimeNano());
*m_notificationContentTypes = {
"OnlineNotificationType Test content type 1" + typeTag,
"OnlineNotificationType Test content type 2" + typeTag,
};
#endif
}
return *m_notificationContentTypes;
}
template<uint32 facadesCount, bool executeLogin>
String AuthenticationFixture<facadesCount, executeLogin>::getWebSocketJsonData() const
{
if (m_notificationContentTypes == NULL)
{
US_IGNORE_RESULT(getWebSocketContentTypes());
}
JsonWriter jsonWriter;
jsonWriter["Testproperty"] = m_notificationContentTypes->front(); //"TestValue";
const String jsonData = jsonWriter.renderContent();
return jsonData;
}
#endif
#if !defined(US_SDK_S2S)
template<uint32 facadesCount, bool executeLogin>
bool AuthenticationFixture<facadesCount, executeLogin>::isEnvironmentNot(Environment target)
{
return (
getFacade().getAuthenticationClient().getSessionInfo().hasValidSession() &&
(getFacade().getAuthenticationClient().getSessionInfo().getEnvironmentCode()) != target);
}
#endif
#if !defined(US_DLL)
template<uint32 facadesCount, bool executeLogin>
void AuthenticationFixture<facadesCount, executeLogin>::waitForPostLoginCompletion(uint32 waitTimeInMSec)
{
if (!TestHelpers_BF::waitForPostLoginCompletion(getFacade(), waitTimeInMSec))
{
GTEST_FAIL();
}
}
#endif
template<uint32 facadesCount, bool executeLogin>
void AuthenticationFixture<facadesCount, executeLogin>::SetUp(uint32 index)
{
m_facades[index] = US_NEW(US_NS::Facade);
m_handlers[index] = US_NEW(ListenerHandler<EventNotification>, m_facades[index]->getEventClient().createNotificationListener());
resetLogLevel();
setMultiLinesLog(true);
#if defined(US_LOG_ENABLED) && defined(DEBUGGING)
LoggingHelper::enableVerbose(true);
LoggingHelper::disableCategory(LogCategory::HttpEngine);
#endif
uint32 count = facadesCount; // avoids warning "conditional expression is constant"
#if defined(US_SDK_S2S)
ASSERT_TRUE(count == 1) << "There is no such thing as multiple players in s2s context.";
#else
if(count > 1)
{
m_credentials[index] = NS_COMMON::AuthenticationHelper::createPlayerCredentials(index);
}
else
{
ASSERT_TRUE(index == 0);
m_credentials[index] = NS_COMMON::AuthenticationHelper::createPlayerCredentials();
}
ASSERT_TRUE(m_credentials[index] != NULL);
#endif
if (!isLoginRequired())
{
return;
}
uint32 triesCount = 3;
while (triesCount > 0)
{
PRINT_DEBUG("CALLING UbiServices Login...");
const AsyncResult<Empty> resultLogin = m_facades[index]->createSession(
#if defined(US_SDK_S2S)
GET_CREDENTIALS(), {}, {}
#else
*m_credentials[index], {}, {}, EventsParams(), getWebSocketJsonData()
#endif
);
if (!resultLogin.isProcessing())
{
US_DELETE(m_handlers[index]);
US_DELETE(m_facades[index]);
#if !defined(US_SDK_S2S)
US_DELETE(m_notificationContentTypes);
US_DELETE(m_credentials[index]);
#endif
GTEST_FATAL_FAILURE_("Login initialization failed");
}
InstancesManager* mgr = InstancesManager::getInstance();
ASSERT_TRUE(mgr != NULL);
if (!resultLogin.wait(NS_COMMON::DEFAULT_WAIT_TIME))
{
US_DELETE(m_handlers[index]);
US_DELETE(m_facades[index]);
#if !defined(US_SDK_S2S)
US_DELETE(m_notificationContentTypes);
US_DELETE(m_credentials[index]);
#endif
#if defined(ENABLE_STRONG_VALIDATION)
GTEST_FATAL_FAILURE_("Login failed with a timeout"); // Commenting this line to allow retries
#else
m_facades[index] = US_NEW(US_NS::Facade);
m_handlers[index] = US_NEW(ListenerHandler<EventNotification>, m_facades[index]->getEventClient().createNotificationListener());
#if defined(US_SDK_S2S)
ASSERT_TRUE(count == 1) << "There is no such thing as multiple players in s2s context.";
#else
if(count > 1)
{
m_credentials[index] = NS_COMMON::AuthenticationHelper::createPlayerCredentials(index);
}
else
{
ASSERT_TRUE(index == 0);
m_credentials[index] = NS_COMMON::AuthenticationHelper::createPlayerCredentials();
}
#endif
#endif
}
if (resultLogin.hasFailed() && (triesCount == 1))
{
US_DELETE(m_handlers[index]);
US_DELETE(m_facades[index]);
#if !defined(US_SDK_S2S)
US_DELETE(m_notificationContentTypes);
US_DELETE(m_credentials[index]);
#endif
StringStream ss;
#if defined(US_LOG_ENABLED)
ss << "Login failed with an error (" << resultLogin.getError() << ")";
#else
ss << "Login failed with an error (" << resultLogin.getError().m_code << ")";
#endif
GTEST_FATAL_FAILURE_(ss.getContent().getUtf8());
}
if (resultLogin.hasSucceeded())
{
//PRINT_LINE("UbiServices Login OK!");
triesCount = 0;
}
else
{
triesCount--;
if (triesCount > 0)
{
PRINT_LINE("RETRYING UbiServices login... %d", triesCount);
}
}
}
// Checks if the facade is connected.
if (!getFacade(index).getAuthenticationClient().getSessionInfo().hasValidSession())
{
US_DELETE(m_handlers[index]);
US_DELETE(m_facades[index]);
#if !defined(US_SDK_S2S)
US_DELETE(m_notificationContentTypes);
US_DELETE(m_credentials[index]);
#endif
GTEST_FATAL_FAILURE_("UbiServices facade is not connected to Uplay");
}
m_loginIsSuccessfulArray[index] = true;
}
template<uint32 facadesCount, bool executeLogin>
void AuthenticationFixture<facadesCount, executeLogin>::TearDown(uint32 index)
{
if (m_loginIsSuccessfulArray[index])
{
AsyncResult<Empty> deleteSessionAsync = m_facades[index]->deleteSession();
if (!deleteSessionAsync.isProcessing())
{
// Add this test in case the job finishes before we get to this point (can occur when log level is Debug)
if(!deleteSessionAsync.hasFailed() && !deleteSessionAsync.hasSucceeded())
{
US_DELETE(m_handlers[index]);
US_DELETE(m_facades[index]);
#if !defined(US_SDK_S2S)
US_DELETE(m_notificationContentTypes);
US_DELETE(m_credentials[index]);
#endif
GTEST_FATAL_FAILURE_("Delete session initialization failed");
}
}
if (!deleteSessionAsync.wait(NS_COMMON::DEFAULT_WAIT_TIME))
{
US_DELETE(m_handlers[index]);
US_DELETE(m_facades[index]);
#if !defined(US_SDK_S2S)
US_DELETE(m_notificationContentTypes);
US_DELETE(m_credentials[index]);
#endif
#if defined(ENABLE_STRONG_VALIDATION)
GTEST_FATAL_FAILURE_("Delete session failed with a timeout");
#else
PRINT_LINE("ERROR: WARNING: Delete session TIMED OUT");
#endif
}
else if (deleteSessionAsync.hasFailed())
{
US_DELETE(m_handlers[index]);
US_DELETE(m_facades[index]);
#if !defined(US_SDK_S2S)
US_DELETE(m_notificationContentTypes);
US_DELETE(m_credentials[index]);
#endif
StringStream ss;
#if defined(US_LOG_ENABLED)
ss << "Delete session failed with an error (" << deleteSessionAsync.getError() << ")";
#else
ss << "Delete session failed with an error (" << deleteSessionAsync.getError().m_code << ")";
#endif
GTEST_FATAL_FAILURE_(ss.getContent().getUtf8());
}
}
US_DELETE(m_handlers[index]);
US_DELETE(m_facades[index]);
#if !defined(US_SDK_S2S)
US_DELETE(m_notificationContentTypes);
US_DELETE(m_credentials[index]);
#endif
}
};
/// @endcond