JD2022-TU1/main/extern/UbiServices/custom/tests/testMain.cpp

432 lines
15 KiB
C++

////////////////////////////////////////////////////////////////////////////////
// (c) Copyright, Ubisoft Entertainment Inc. || Created by Harbour //
////////////////////////////////////////////////////////////////////////////////
#include "tests/config.h"
#include "tests/common/gtestFilter.h"
#include "tests/common/gtestRepeatHelper.h"
#include "tests/common/helpers.h"
#if defined(US_TARGET_GGP)
#include "tests/ggp/platformTestHelper.h"
#endif
#include "testsIntegration/integrationTest.h"
#include "testsUnit/unitTest.h"
#include "environmentSetupTest.h"
#include <ubiservices/core/configs/config.h>
#include <ubiservices/core/log/log.h>
#include "../private/ubiservices/core/helpers/instancesManager.h"
#if defined(US_ENABLE_ALLOC_STATS)
#include <ubiservices/core/memory/memoryManagement.h>
#endif
#include <ubiservices/loggingHelper.h>
#include <ubiservices/platformHelper.h>
#include <usCommon/cmdlineArgs.h>
#include <usCommon/environmentSetup.h>
#include <usCommon/options.h>
#if defined(US_TARGET_UWP) || defined(US_TARGET_MANJARO)
#include <windows.h>
#elif defined(US_TARGET_SWITCH)
#include <nn/os.h>
#include <nn/init.h>
#include <nn/nn_Log.h>
#include <nn/nn_Assert.h>
#include <nn/lmem/lmem_ExpHeap.h>
#include <nn/nifm.h>
#include <nn/socket.h>
#include <nn/ssl/ssl_Types.h>
#include <nn/ssl/ssl_Context.h>
#include <nn/time/time_Api.h> // nn::time::Initialize()
#include <nn/account/account_Api.h>
#include <nn/account/account_ApiForApplications.h>
#include <nn/oe.h>
#include <usCommon/authenticationHelper.h>
//#define ENABLE_SWITCH_CPU_PROFILING // Requires libnn_profiler.a for linking
#if defined(ENABLE_SWITCH_CPU_PROFILING)
#include <nn/profiler.h>
#endif
#include <curl/curl.h>
#endif
#if defined(US_TARGET_ANDROID) && !defined(US_TARGET_ANDROID_VS)
#if (__GNUC__ >= 4) || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)
# ifndef GCC_HASCLASSVISIBILITY
# define GCC_HASCLASSVISIBILITY
# endif
#endif
#ifndef SWIGEXPORT
# if defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__)
# if defined(STATIC_LINKED)
# define SWIGEXPORT
# else
# define SWIGEXPORT __declspec(dllexport)
# endif
# else
# if defined(__GNUC__) && defined(GCC_HASCLASSVISIBILITY)
# define SWIGEXPORT __attribute__ ((visibility("default")))
# else
# define SWIGEXPORT
# endif
# endif
#endif
#include <jni.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char** argv);
#ifdef __cplusplus
extern "C" {;
#endif
extern JavaVM* g_NativeApplicationVM;
extern jobject g_activity;
SWIGEXPORT jint JNICALL Java_com_ubisoft_ubiservices_testMainJNI_main(JNIEnv* jenv, jclass jcls, jobject activity, jint jargc, jobjectArray jargv)
{
if (jenv->GetJavaVM(&g_NativeApplicationVM) != JNI_OK)
return -1;
g_activity = jenv->NewGlobalRef(activity);
char** argv = new char*[jargc];
for (int i = 0; i < jargc; i++)
{
jstring argumentText = static_cast<jstring>(jenv->GetObjectArrayElement(jargv, i));
argv[i] = const_cast<char*>(jenv->GetStringUTFChars(argumentText, NULL));
}
const int result = main(jargc, argv);
delete[] argv;
jenv->DeleteGlobalRef(g_activity);
return result;
}
#ifdef __cplusplus
}
#endif
#endif
#if defined(US_TARGET_ANDROID_VS)
#include <android_native_app_glue.h>
#endif
#if defined(US_TARGET_ANDROID_VS) || defined(US_ENABLE_UBIMOBILE)
struct android_app* g_androidApp = NULL;
#endif
#if defined(US_ENABLE_ALLOC_STATS)
extern struct AllocStatistics g_stats;
#endif
namespace US_NS {;
// #if !defined(US_RETAIL)
// extern bool US_DLL_API s_forceNonSecure;
// #endif
};
void activateFloatingPointExceptions()
{
#if defined (US_TARGET_WINDOWS) || defined(US_TARGET_MANJARO)
// _controlfp_s() is cross-platform, but flags used in parameters are not
_controlfp_s(
NULL,
(unsigned int)~(_EM_OVERFLOW | _EM_ZERODIVIDE | _EM_INVALID),
(unsigned int)MCW_EM);
#endif
}
#if defined(US_TARGET_XONE)
int mainXboxOne(int argc, US_NS::tchar** argv)
#elif (defined(US_TARGET_WINDOWS) && defined(UNICODE)) || defined(US_TARGET_XONE) || defined(US_TARGET_MANJARO)
int _tmain(int argc, TCHAR** argv)
#elif defined(US_TARGET_UWP)
int main(Platform::Array<Platform::String^>^ args)
#elif defined(US_TARGET_ANDROID_VS)
void android_main(struct android_app* androidApp)
#elif defined(US_TARGET_IOS)
// This method is called from "..\tests\ios\AppDelegate.mm"
int mainIOS(int argc, char** argv)
#elif defined(US_TARGET_SWITCH)
extern "C" void nnMain(int argc, char** argv)
#else
int main(int argc, char** argv)
#endif
{
activateFloatingPointExceptions();
#if defined(US_TARGET_WINDOWS) || defined(US_TARGET_MANJARO)
if (_putenv_s("all_proxy", "proxy-mtl.ubisoft.org:3128") != 0)
{
US_NS::Log::print("ERROR: Setting ALL_PROXY environment setting failed.\n");
}
#endif
#if defined(US_TARGET_ANDROID_VS)
g_androidApp = androidApp;
#elif defined(US_TARGET_ANDROID)
if (g_activity == NULL)
{
US_NS::Log::print("***************************************************************************\n");
US_NS::Log::print("DEAD.\n");
US_NS::Log::print("***************************************************************************\n");
return -1;
}
#endif
#if defined(US_TARGET_UWP)
int argc = args->Length;
TCHAR** argv = new TCHAR*[argc];
for (int i = 0; i < argc; i++)
{
argv[i] = (TCHAR*)args[i]->Data();
}
#endif
#if defined(US_TARGET_SWITCH)
NN_ABORT_UNLESS_RESULT_SUCCESS(nn::time::Initialize());
NN_LOG("nn::time::Initialize\n");
// To use the system network interface, the program must initialize the network interface manager (NIFM).
NN_ABORT_UNLESS_RESULT_SUCCESS(nn::nifm::Initialize());
//--------------------------------------------------------------------------
// Socket memory.
static NN_ALIGNAS(4096) uint8_t s_SocketMemoryPoolBuffer[(10 * 1024 * 1024)/*nn::socket::DefaultSocketMemoryPoolSize*/];
// Initialize the library, providing the specific amount of memory needed...
const nn::Result ret = nn::socket::Initialize(
s_SocketMemoryPoolBuffer,
sizeof(s_SocketMemoryPoolBuffer),
nn::socket::MinSocketAllocatorSize,
nn::socket::DefaultConcurrencyLimit);
if (ret.IsFailure())
{
NN_LOG("\nError: nn::socket::Initialize() failed. Err Desc: %d\n\n", ret.GetDescription());
// This application no longer requires the use of the network interface.
nn::nifm::CancelNetworkRequest();
}
//--------------------------------------------------------------------------
// Makes a request to the system to use the network connection
// and determines whether it is available before conducting communication.
#if USING_BLOCKING_API
nn::nifm::SubmitNetworkRequestAndWait(); // Blocking call
#else // non-blocking API (checking for completion by polling)
nn::nifm::CancelNetworkRequest();
nn::nifm::SubmitNetworkRequest();
while (nn::nifm::IsNetworkRequestOnHold())
{
NN_LOG("Network request is on hold...\n");
nn::os::SleepThread(nn::TimeSpan::FromSeconds(1));
}
#endif
if (!nn::nifm::IsNetworkAvailable())
{
NN_LOG("Error: The network is not available.\n");
// This application no longer requires the use of the network interface.
nn::nifm::CancelNetworkRequest();
return;
}
nn::oe::Initialize();
nn::account::Initialize();
#if defined(ENABLE_SWITCH_CPU_PROFILING)
char* buffer = new char[nn::profiler::MinimumBufferSize];
nn::Result resultX = nn::profiler::Initialize(buffer, nn::profiler::MinimumBufferSize);
NN_ABORT_UNLESS_RESULT_SUCCESS(resultX);
nn::profiler::RecordHeartbeat(nn::profiler::Heartbeats_Main);
#endif // ENABLE_SWITCH_CPU_PROFILING
#endif
#if defined(US_TARGET_UWP)
US_UNUSED(argc);
const int ARGC_HACK = 3;
US_NS::tchar* argv_hack[ARGC_HACK];
const std::wstring exePath(_T("Dummy/Path"));
US_NS::tchar* tempExePath = new US_NS::tchar[exePath.length() + 1];
wcscpy(tempExePath, exePath.c_str());
argv_hack[0] = tempExePath;
const std::wstring filter(_T("--gtest_filter=*"));
US_NS::tchar* tempFilter = new US_NS::tchar[filter.length() + 1];
wcscpy(tempFilter, filter.c_str());
argv_hack[1] = tempFilter;
const std::wstring color(_T("--gtest_color=no")); // _T("--gtest_repeat=25")
US_NS::tchar* tempColor = new US_NS::tchar[color.length() + 1];
wcscpy(tempColor, color.c_str());
argv_hack[2] = tempColor;
#elif defined(US_TARGET_SWITCH)
US_UNUSED(argc);
const int ARGC_HACK = 4;
char* argv_hack[ARGC_HACK];
const std::string exePath("Dummy/Path");
char* tempExePath = new char[exePath.length() + 1];
strcpy(tempExePath, exePath.c_str());
argv_hack[0] = tempExePath;
const std::string filter(nn::os::GetHostArgc() > 1 ? nn::os::GetHostArgv()[1] : "--gtest_filter=*");
char* tempFilter = new char[filter.length() + 1];
strcpy(tempFilter, filter.c_str());
argv_hack[1] = tempFilter;
const std::string color(nn::os::GetHostArgc() > 2 ? nn::os::GetHostArgv()[2] : "--gtest_color=no"); // _T("--gtest_repeat=25")
char* tempColor = new char[color.length() + 1];
strcpy(tempColor, color.c_str());
argv_hack[2] = tempColor;
const std::string tempX(nn::os::GetHostArgc() > 3 ? nn::os::GetHostArgv()[3] : "-env Uat"); // _T("--gtest_repeat=25")
char* tempXYZ = new char[tempX.length() + 1];
strcpy(tempXYZ, tempX.c_str());
argv_hack[3] = tempXYZ;
#endif
#if defined(US_TARGET_XONE)
// Leave time for the DebugStringMonitoring to attach itself before launching the application when on command line (build farm).
for (int i = 0; i < argc; i++)
{
if (_tcscmp(argv[i], _T("-applicationid")) == 0)
{
US_NS::Helper::sleep(3*1000); // Empirical delay value.
}
}
if (Windows::Xbox::System::User::Users->Size == 0)
{
US_NS::Log::print("***************************************************************************\n");
US_NS::Log::print("THERE MUST BE ONE PLAYER LOGGED IN ON THE CONSOLE FOR THE TESTS TO EXECUTE.\n");
US_NS::Log::print("***************************************************************************\n");
return -1;
}
#endif
#if defined(US_TARGET_ANDROID_VS)
std::vector<std::string> argsVector;
argsVector.push_back("MandatoryFirstValueSkipped");
//argsVector.push_back("--gtest_filter=*USNOT_LoginWithAccessTokenFromUbiServicesSDK_V2");
//argsVector.push_back("--gtest_filter=*USTK*");
argsVector.push_back("--gtest_filter=*");
//argsVector.push_back("--gtest_repeat=-1");
const int argc = argsVector.size();
char** argv = new char*[argsVector.size()];
for (int i = 0; i < argc; i++)
{
argv[i] = const_cast<char*>(argsVector[i].c_str());
}
#endif
US_NS::uint32 result = 0;
#if defined(US_TARGET_UWP)
const NS_COMMON::CmdLineArgs cmdLineArgs(ARGC_HACK, const_cast<const US_NS::tchar**>(argv_hack));
#elif defined(US_TARGET_SWITCH)
const NS_COMMON::CmdLineArgs cmdLineArgs(ARGC_HACK, const_cast<const US_NS::tchar**>(argv_hack));
#else
const NS_COMMON::CmdLineArgs cmdLineArgs(argc, const_cast<const US_NS::tchar**>(argv));
#endif
// This variable is not needed but building it fills the US_COMMON::Options;
// TODO : Implement a cleaner and more explicit way
NS_COMMON::EnvironmentSetup::setOptions(cmdLineArgs);
#if !defined(US_SDK_S2S)
// We can't configure InstancesManager environment when creating the GameConfig so we use SetTestEnvironment
// to set a variable that will be used to initiate the environment.
US_NS::InstancesManager::SetTestEnvironment(NS_COMMON::Options::environment());
#endif
#if defined(US_TARGET_GGP)
PlatformTestHelper::getInstance().init();
#endif
{
testing::AddGlobalTestEnvironment(new US_TEST_NS::EnvironmentSetupTest());
::testing::GTEST_FLAG(catch_exceptions) = false;
US_NS::UnitTests::registerTests();
US_NS::IntegrationTests::registerTests();
US_TEST_NS::GTestRepeatHelper* testHelper = new US_TEST_NS::GTestRepeatHelper(2); // Auto-delete by gtest FW!
result = testHelper->run(cmdLineArgs.getArgc(), const_cast<US_NS::tchar**>(cmdLineArgs.getArgv()));
}
#if defined(US_ENABLE_ALLOC_STATS)
US_NS::Log::print("\n");
US_NS::Log::print("--- Memory allocation statistics ---\n");
US_NS::Log::print("m_allocCountCurrent = %d\n", g_stats.m_allocCountCurrent);
US_NS::Log::print("m_allocCountTotal = %d\n", g_stats.m_allocCountTotal);
US_NS::Log::print("m_allocSizeTotal = %d\n", g_stats.m_allocSizeTotal);
US_NS::Log::print("\n");
US_NS::Log::print("m_allocArrayCountCurrent = %d\n", g_stats.m_allocArrayCountCurrent);
US_NS::Log::print("m_allocArrayCountTotal = %d\n", g_stats.m_allocArrayCountTotal);
US_NS::Log::print("m_allocArraySizeTotal = %d\n", g_stats.m_allocArraySizeTotal);
US_NS::Log::print("\n");
US_NS::Log::print("m_newArrayWithZero = %d\n", g_stats.m_newArrayWithZero);
US_NS::Log::print("m_deleteWithNull = %d\n", g_stats.m_deleteWithNull);
US_NS::Log::print("m_deleteArrayWithNull = %d\n", g_stats.m_deleteArrayWithNull);
US_NS::Log::print("-----------------------------------\n");
#endif
// ******* WARNING *********
// Be very careful in modifying these text strips.
// The build farm uses it to determine if all the test have completed without interruption or crash.
US_NS::Log::print(result == 0
? "Ubiservices Tests have come to a completion with success.\n"
: "Ubiservices Tests have come to a completion with failure.\n");
#if defined(US_TARGET_SWITCH)
NS_COMMON::AuthenticationHelper::closeUserHandle();
#endif
NS_COMMON::Options::getInstance()->deleteInstance();
#if defined(US_TARGET_SWITCH)
// Clean up the <tt>socket</tt> library.
NN_ABORT_UNLESS_RESULT_SUCCESS(nn::socket::Finalize());
nn::nifm::CancelNetworkRequest();
// Finalizes the time library.
NN_ABORT_UNLESS_RESULT_SUCCESS(nn::time::Finalize());
NN_LOG("nn::time::Finalize\n");
#if defined(ENABLE_SWITCH_CPU_PROFILING)
{
nn::profiler::ProfilerStatus status = nn::profiler::GetProfilerStatus();
while (status == nn::profiler::ProfilerStatus_Profiling || status == nn::profiler::ProfilerStatus_Transferring)
{
nn::os::SleepThread(nn::TimeSpan::FromMilliSeconds(1));
status = nn::profiler::GetProfilerStatus();
}
}
// Finalize the profiler
resultX = nn::profiler::Finalize();
NN_ABORT_UNLESS_RESULT_SUCCESS(resultX);
delete[] buffer;
#endif
#elif defined(US_TARGET_ANDROID_VS)
ANativeActivity_finish(androidApp->activity);
exit(result == 0 ? EXIT_SUCCESS : EXIT_FAILURE);
#elif defined(US_TARGET_GGP)
PlatformTestHelper::getInstance().uninit();
#else
return result;
#endif
}