//////////////////////////////////////////////////////////////////////////////// // (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 #include #include "../private/ubiservices/core/helpers/instancesManager.h" #if defined(US_ENABLE_ALLOC_STATS) #include #endif #include #include #include #include #include #if defined(US_TARGET_UWP) || defined(US_TARGET_MANJARO) #include #elif defined(US_TARGET_SWITCH) #include #include #include #include #include #include #include #include #include #include // nn::time::Initialize() #include #include #include #include //#define ENABLE_SWITCH_CPU_PROFILING // Requires libnn_profiler.a for linking #if defined(ENABLE_SWITCH_CPU_PROFILING) #include #endif #include #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 #include #include 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(jenv->GetObjectArrayElement(jargv, i)); argv[i] = const_cast(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 #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^ 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 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(argsVector[i].c_str()); } #endif US_NS::uint32 result = 0; #if defined(US_TARGET_UWP) const NS_COMMON::CmdLineArgs cmdLineArgs(ARGC_HACK, const_cast(argv_hack)); #elif defined(US_TARGET_SWITCH) const NS_COMMON::CmdLineArgs cmdLineArgs(ARGC_HACK, const_cast(argv_hack)); #else const NS_COMMON::CmdLineArgs cmdLineArgs(argc, const_cast(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(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 socket 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 }