JD2022-TU1/main/extern/UbiServices/custom/tests/common/helpers.h

288 lines
No EOL
14 KiB
C++

////////////////////////////////////////////////////////////////////////////////
// (c) Copyright, Ubisoft Entertainment Inc. || Created by Harbour //
////////////////////////////////////////////////////////////////////////////////
#pragma once
#include "tests/config.h"
#include "tests/common/confignamespace.h"
#include "tests/common/restStatusCode.h"
#include <ubiservices/core/configs/config.h>
#include <ubiservices/core/helpers/assertionHelper.h>
#include <../private/ubiservices/core/helpers/helpers.h>
#include <../private/ubiservices/core/debug/macros.h>
#include <../private/ubiservices/core/helpers/instancesHelper.h>
#include <../private/ubiservices/core/helpers/spinTest.h>
#include <../private/ubiservices/core/network/URLInfo.h>
#include <ubiservices/facade.h>
#if (defined(US_TARGET_ANDROID) || defined(US_TARGET_IOS) || defined(US_TARGET_WINDOWS) || defined(US_TARGET_MANJARO) || defined(US_TARGET_OSX)) && !defined(US_SDK_S2S)
#include <ubiservices/services/authentication/playerCredentials.h>
#if !defined(US_TARGET_WINDOWS)
#include <../private/ubiservices/services/authentication/deviceStorage.h>
#endif
#endif
#include <ubiservices/services/event/types/eventInfoService.h>
#include <ubiservices/services/http/httpHeader.h>
#include <gtest/gtest.h>
#include <ostream>
#if defined(US_TARGET_WINDOWS) || defined(US_TARGET_MANJARO)
#include <Windows.h>
#include <winhttp.h>
#endif
namespace TestHelpers_BF
{
const char* const SERVICE_EVENT_NAME = "Testing";
#if defined(US_SDK_S2S)
const char* const SERVICE_EVENT_APPLICATION_ID = "9fa03659-c0b2-461e-af3a-c802a4fd1829"; // UbiServices SDK Server RETAIL
const char* const SERVICE_EVENT_PROFILE_ID = "4d9061de-7c20-4cc9-9f55-b8d6228da6ae"; // ussdk001
const char* const SERVICE_EVENT_SPACE_ID = "9708a546-7060-483b-9db8-36fe9aef1c48"; // UbiServices SDK Server RETAIL
#endif
// This function is used to poll a class method continuously until it either match a specific value (success)
// or the maximum wait time is reached (failure). This can be useful to wait for a condition that will be set by another thread.
// To use this easily, use the macro defined below (US_EXPECT_PROP_WAIT or US_ASSERT_PROP_WAIT)
template<typename Class, typename PropType>
inline testing::AssertionResult waitForPropertyValue(const Class* obj, PropType (Class::*method)() const, PropType value,
const char* description, US_NS::ClockSteady::TTimeMilli maxTimeMs)
{
const US_NS::ClockSteady::TTimeMilli startTime = US_NS::ClockSteady::getTimeMilli();
US_NS::ClockSteady::TTimeMilli elapsed = 0;
while (elapsed <= maxTimeMs)
{
if ((obj->*method)() == value)
{
PRINT_LINE("Property value detected after %d ms", elapsed);
return testing::AssertionSuccess();
}
elapsed = US_NS::ClockSteady::getTimeMilli() - startTime;
US_NS::Helper::sleep(10);
}
return testing::AssertionFailure() << "Property " << description << " failed to be equal to " << value << " after " << maxTimeMs << " Ms";
}
template<typename Class, typename PropType>
inline testing::AssertionResult waitForPropertyValue(const Class& obj, PropType (Class::*method)() const, PropType value,
const char* description, US_NS::ClockSteady::TTimeMilli maxTimeMs)
{
return waitForPropertyValue(&obj, method, value, description, maxTimeMs);
}
US_NS::StringUrl getHttpTestUrl(const US_NS::String& path, const US_NS::String& query = US_NS::String(),
bool useCompression = false, bool useChunkedEncoding = false, bool useSecureTransfer = true);
US_NS::StringUrl getHttpStatusCodeTestUrl(US_TEST_NS::RestStatusCode::Enum statusCode, bool useChunkedEncoding = false);
US_NS::StringUrl getHttpRedirectTestUrl(US_NS::uint32 redirectCode, const US_NS::StringUrl& redirectUrl = US_NS::StringUrl());
US_NS::HttpHeader getHttpBoxHeader();
US_NS::HttpHeader getHttpContentHeader();
#if !defined(US_DLL)
bool waitForPostLoginCompletion(US_NS::Facade& facade, US_NS::uint32 waitTimeInMSec = 10000);
bool waitForEventSetupCompletion(US_NS::Facade& facade);
US_NS::Vector<US_NS::String> getEnvironmentURLPrefixes(bool isPreflight = false);
US_NS::Vector<US_NS::String> getOnlineAccessContextURLPrefixes();
US_NS::Vector<US_NS::String> getURLPrefixes(bool isPreflight = false);
template<typename T>
inline void checkValueInExpectedSet(US_NS::Vector<T> expectedDataSet, T value)
{
EXPECT_FALSE(std::find(expectedDataSet.begin(), expectedDataSet.end(), value) == expectedDataSet.end());
}
#endif
US_NS::EventInfoService getServiceEvent(const US_NS::String name = SERVICE_EVENT_NAME, const US_NS::StringJson& customData = "{}");
void SetBackdoorEnvironment(const US_NS::Environment& env);
struct AssertHandler
{
AssertHandler()
: m_assertCount(0)
{
US_NS::AssertionHelper::registerCallback(&AssertHandler::assertCallback);
s_instance = this;
}
~AssertHandler()
{
US_NS::AssertionHelper::unregisterCallback();
}
static void assertCallback(const char*, const char*, US_NS::uint32)
{
s_instance->m_assertCount++;
}
static AssertHandler* s_instance;
US_NS::uint32 m_assertCount;
};
}
#if (defined(US_TARGET_SUPPORT_CPP11) || defined(_MSC_VER) && (_MSC_VER >= 1700)) && !defined(UNICODE)
// static_assert directive only accessible in C++11 ready compilers
#define US_TEST_STATIC_ASSERT(expr, msg) static_assert(expr, msg)
#else //defined(US_TARGET_SUPPORT_CPP11) || defined(_MSC_VER) && (_MSC_VER >= 1700)
#define US_TEST_STATIC_ASSERT(expr, msg)
#endif //defined(US_TARGET_SUPPORT_CPP11) || defined(_MSC_VER) && (_MSC_VER >= 1700)
#if defined(US_SYSTEM_CHECK_ENABLED)
// Note: Using GetTrue() instead of "true" in the system check expression avoids
// compiler warning C4127 (conditional expression is constant) when calling the
// macro with a constant expression, i.e. "US_ASSERT(false)"
#if defined(US_UNITY3D)
#define US_TEST_ASSERT(cond, msg) \
if((static_cast<bool>(cond) != US_NS::SystemChecker::GetTrue())) \
{ \
US_NS::StringStream ss; \
ss << msg; \
ubiservices::Log::print("\n\nUbiservices ASSERT FAILURE: %s (%s:%d)\n", ss.getContent().getUtf8(), US_FILE, US_LINE); \
}
#else // defined(US_UNITY3D)
#define US_TEST_ASSERT(cond, msg) \
if((static_cast<bool>(cond) != US_NS::SystemChecker::GetTrue())) \
{ \
static eal_u32 pStatic = 0; \
US_NS::StringStream ss; \
ss << msg; \
if (EalLogAssert2(EAL_ID_TG_UBISERVICES, #cond, ss.getContent().getUtf8(), US_FILE, US_LINE, EAL_LOG_ASSERT_NORMAL, &pStatic)) \
{ \
US_SYSTEM_CHECK(cond); \
} \
}
#endif // defined(US_UNITY3D)
#else // defined(US_SYSTEM_CHECK_ENABLED)
#define US_TEST_ASSERT(cond, msg)
#endif
#define US_DEFINE_LONG_TEST_P(fixtureName, shortVersionParam, longVersionParam) \
INSTANTIATE_TEST_CASE_P(SHORT, fixtureName, ::testing::Values(shortVersionParam)); \
INSTANTIATE_TEST_CASE_P(LONG, fixtureName, ::testing::Values(longVersionParam))
//------------------------------------------------------------------------------
// Spin tests macros
//------------------------------------------------------------------------------
#define _GOOGLE_SPINTEST(C,DELAY,ACTION,FAILURE) \
{ \
US_NS::SpinTest oST(100, (DELAY)*1000, US_NS::SpinTest::Leave); \
US_SPIN_ON_ACTION(oST, !(C), ACTION); \
if (!oST.hasTimedOut()) \
{ \
PRINT_LINE("Spinned %d/%d on " #C, oST.getElapsed(), oST.getTimeout()); \
} \
else \
{ \
FAILURE("SpinTest Timeout occured"); \
} \
}
//#define _ASSERT_GOOGLE_SPINTEST(C, DELAY, ACTION) _GOOGLE_SPINTEST(C, DELAY, ACTION, GTEST_FATAL_FAILURE_)
#define _EXPECT_GOOGLE_SPINTEST(C, DELAY, ACTION) _GOOGLE_SPINTEST(C, DELAY, ACTION, GTEST_NONFATAL_FAILURE_)
//#define ASSERT_GOOGLE_SPINTEST(C, DELAY) _ASSERT_GOOGLE_SPINTEST(C, DELAY, int32 iDummy = 0; iDummy++)
#define EXPECT_GOOGLE_SPINTEST(C, DELAY) _EXPECT_GOOGLE_SPINTEST(C, DELAY, int32 iDummy = 0; iDummy++)
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
#define US_EXPECT_SUCCESS(_asyncResult) \
EXPECT_TRUE(_asyncResult.hasSucceeded()); \
EXPECT_EQ(Errors::SUCCESS, _asyncResult.getError().m_code);
#define US_ASSERT_SUCCESS(_asyncResult) \
EXPECT_TRUE(_asyncResult.hasSucceeded()); \
ASSERT_EQ(Errors::SUCCESS, _asyncResult.getError().m_code);
#define US_EXPECT_FAILURE(_asyncResult, _errorCode) \
EXPECT_TRUE(_asyncResult.hasFailed()); \
EXPECT_EQ(US_BUILD_ERROR_CODE(_errorCode), _asyncResult.getError().m_code);
#define US_ASSERT_FAILURE(_asyncResult, _errorCode) \
EXPECT_TRUE(_asyncResult.hasFailed()); \
ASSERT_EQ(US_BUILD_ERROR_CODE(_errorCode), _asyncResult.getError().m_code);
#define US_WAIT_PROPERTY(OBJECT, PROPERTY, VALUE, WAIT_MS) \
TestHelpers_BF::waitForPropertyValue(OBJECT, &PROPERTY, VALUE, #PROPERTY, WAIT_MS);
#define US_EXPECT_PROPERTY_WAIT(OBJECT, PROPERTY, VALUE, WAIT_MS) EXPECT_TRUE(TestHelpers_BF::waitForPropertyValue(OBJECT, &PROPERTY, VALUE, #PROPERTY, WAIT_MS))
#define US_ASSERT_PROPERTY_WAIT(OBJECT, PROPERTY, VALUE, WAIT_MS) ASSERT_TRUE(TestHelpers_BF::waitForPropertyValue(OBJECT, &PROPERTY, VALUE, #PROPERTY, WAIT_MS))
#define US_WAIT_MOCK_PROPERTY_DEFAULT_TIME 500
#define US_CODENAME() Debug::getWhereTxt(US_WHERE())
#define US_CODENAME_LINE() US_CODENAME() + "/#" + String::getText(static_cast<uint32>(__LINE__))
//===================================================================================================
#define US_DEFINE_TEST(FileName) namespace FileName##_BF { int registerTest() {return 0;} }
#define US_DECLARE_TEST(FileName) namespace FileName##_BF { int registerTest();}
#define US_REGISTER_TEST(FileName) + FileName##_BF::registerTest()
#define US_REGISTER_TEST_LIST(Namespace, TEST_LIST_TUPLE) \
namespace Namespace \
{ \
uint32 registerTests() \
{ \
return 0 TEST_LIST_TUPLE(US_REGISTER_TEST); \
} \
}
//===================================================================================================
US_TEST_NS_BEGIN;
namespace Helper
{
void sleep(US_NS::TimeMilli milliseconds);
void uninitializeSdk(US_NS::TimeMilli milliseconds = 10);
struct ConditionTemplate
{
virtual bool operator()() const = 0;
};
bool WaitFor(const ConditionTemplate& fonctor, US_NS::uint64 sleepIntervalMs, US_NS::DurationMilli timeOutMs, const char* const text);
::testing::AssertionResult waitForPostLogin(US_NS::Facade& facade, US_NS::uint32 waitTimeInMSec = 10000);
::testing::AssertionResult waitForWebsocketInit(US_NS::Facade& facade);
#if !defined(US_SDK_S2S)
enum class State
{
PostLogin,
WebsocketInit,
};
::testing::AssertionResult waitForStates(US_NS::Facade& facade, const std::vector<State>& states);
#endif
}
namespace EventHelper
{
US_NS::Vector<US_NS::String> getRequestEvents(const US_NS::Json& requestBody);
US_NS::Vector<US_NS::int32> getSequenceIds(const US_NS::Json& requestBody);
}
#if defined(US_TARGET_WINDOWS) || defined(US_TARGET_MANJARO)
namespace ProxyHelper
{
US_NS::String findAutomaticProxySettings(const US_NS::String& url);
};
#endif
#if (defined(US_TARGET_ANDROID) || defined(US_TARGET_IOS) || defined(US_TARGET_WINDOWS) || defined(US_TARGET_OSX)) && !defined(US_SDK_S2S)
namespace SilentLoginHelper
{
US_NS::PlayerCredentialsSilent buildPlayerCredentialsSilent();
US_NS::String getDeviceId();
#if !defined(US_TARGET_WINDOWS) && !defined(US_TARGET_OSX)
US_NS::DeviceStorage buildDeviceStorage();
#endif
};
#endif
US_TEST_NS_END;
//Leave this comment here, else, gcc/clang warns on compilations