432 lines
15 KiB
C++
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
|
|
}
|