// Copyright 1998-2015 Epic Games, Inc. All Rights Reserved. #include "PrivatePCH.h" #include "RequiredProgramMainCPPInclude.h" DEFINE_LOG_CATEGORY(LogTestPAL); IMPLEMENT_APPLICATION(TestPAL, "TestPAL"); namespace TestPAL { FString CommandLine; }; /** * FProcHandle test (child instance) */ int32 ProcRunAsChild(const TCHAR* CommandLine) { FPlatformMisc::SetCrashHandler(NULL); FPlatformMisc::SetGracefulTerminationHandler(); GEngineLoop.PreInit(CommandLine); // set a random delay pretending to do some useful work up to a minute. double RandomWorkTime = FMath::FRandRange(0.0f, 60.0f); UE_LOG(LogTestPAL, Display, TEXT("Running proc test as child (pid %d), will be doing work for %f seconds."), FPlatformProcess::GetCurrentProcessId(), RandomWorkTime); double StartTime = FPlatformTime::Seconds(); // Use all the CPU! for (;;) { double CurrentTime = FPlatformTime::Seconds(); if (CurrentTime - StartTime >= RandomWorkTime) { break; } } UE_LOG(LogTestPAL, Display, TEXT("Child (pid %d) finished work."), FPlatformProcess::GetCurrentProcessId()); FEngineLoop::AppPreExit(); FEngineLoop::AppExit(); return 0; } /** * FProcHandle test (parent instance) */ int32 ProcRunAsParent(const TCHAR* CommandLine) { FPlatformMisc::SetCrashHandler(NULL); FPlatformMisc::SetGracefulTerminationHandler(); GEngineLoop.PreInit(CommandLine); UE_LOG(LogTestPAL, Display, TEXT("Running proc test as parent.")); // Run slave instance continuously int NumChildrenToSpawn = 255, MaxAtOnce = 5; FParent Parent(NumChildrenToSpawn, MaxAtOnce); Parent.Run(); UE_LOG(LogTestPAL, Display, TEXT("Parent quit.")); FEngineLoop::AppPreExit(); FEngineLoop::AppExit(); return 0; } /** * Tests a single file. */ void TestCaseInsensitiveFile(const FString & Filename, const FString & WrongFilename) { IPlatformFile& PlatformFile = FPlatformFileManager::Get().GetPlatformFile(); IFileHandle * CreationHandle = PlatformFile.OpenWrite(*Filename); checkf(CreationHandle, TEXT("Could not create a test file for '%s'"), *Filename); delete CreationHandle; IFileHandle* CheckGoodHandle = PlatformFile.OpenRead(*Filename); checkf(CheckGoodHandle, TEXT("Could not open a test file for '%s' (zero probe)"), *Filename); delete CheckGoodHandle; IFileHandle* CheckWrongCaseRelHandle = PlatformFile.OpenRead(*WrongFilename); checkf(CheckWrongCaseRelHandle, TEXT("Could not open a test file for '%s'"), *WrongFilename); delete CheckWrongCaseRelHandle; PlatformFile.DeleteFile(*Filename); } /** * Case-(in)sensitivity test/ */ int32 CaseTest(const TCHAR* CommandLine) { FPlatformMisc::SetCrashHandler(NULL); FPlatformMisc::SetGracefulTerminationHandler(); GEngineLoop.PreInit(CommandLine); UE_LOG(LogTestPAL, Display, TEXT("Running case sensitivity test.")); TestCaseInsensitiveFile(TEXT("Test.Test"), TEXT("teSt.teSt")); FString File(TEXT("Test^%!CaseInsens")); FString AbsFile = FPaths::ConvertRelativePathToFull(File); FString AbsFileUpper = AbsFile.ToUpper(); TestCaseInsensitiveFile(AbsFile, AbsFileUpper); FEngineLoop::AppPreExit(); FEngineLoop::AppExit(); return 0; } /** * Selects and runs one of test cases. * * @param ArgC Number of commandline arguments. * @param ArgV Commandline arguments. * @return Test case's return code. */ int32 MultiplexedMain(int32 ArgC, char* ArgV[]) { for (int32 IdxArg = 0; IdxArg < ArgC; ++IdxArg) { if (!FCStringAnsi::Strcmp(ArgV[IdxArg], ARG_PROC_TEST_CHILD)) { return ProcRunAsChild(*TestPAL::CommandLine); } else if (!FCStringAnsi::Strcmp(ArgV[IdxArg], ARG_PROC_TEST)) { return ProcRunAsParent(*TestPAL::CommandLine); } else if (!FCStringAnsi::Strcmp(ArgV[IdxArg], ARG_CASE_SENSITIVITY_TEST)) { return CaseTest(*TestPAL::CommandLine); } } FPlatformMisc::SetCrashHandler(NULL); FPlatformMisc::SetGracefulTerminationHandler(); GEngineLoop.PreInit(*TestPAL::CommandLine); UE_LOG(LogTestPAL, Warning, TEXT("Unable to find any known test name, no test started.")); FEngineLoop::AppPreExit(); FEngineLoop::AppExit(); return 1; } int32 main(int32 ArgC, char* ArgV[]) { TestPAL::CommandLine = TEXT(""); for (int32 Option = 1; Option < ArgC; Option++) { TestPAL::CommandLine += TEXT(" "); FString Argument(ANSI_TO_TCHAR(ArgV[Option])); if (Argument.Contains(TEXT(" "))) { if (Argument.Contains(TEXT("="))) { FString ArgName; FString ArgValue; Argument.Split( TEXT("="), &ArgName, &ArgValue ); Argument = FString::Printf( TEXT("%s=\"%s\""), *ArgName, *ArgValue ); } else { Argument = FString::Printf(TEXT("\"%s\""), *Argument); } } TestPAL::CommandLine += Argument; } return MultiplexedMain(ArgC, ArgV); }