Files
UnrealEngineUWP/Engine/Source/Programs/TestPAL/Private/Main.cpp
Dmitry Rekman b4dc64d84f Linux: add missing GetOperatingSystemId() (UE-8013).
[CL 2531359 by Dmitry Rekman in Main branch]
2015-04-30 00:10:55 -04:00

344 lines
9.6 KiB
C++

// Copyright 1998-2015 Epic Games, Inc. All Rights Reserved.
#include "PrivatePCH.h"
#include "RequiredProgramMainCPPInclude.h"
#include "TestDirectoryWatcher.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.
srand(FPlatformProcess::GetCurrentProcessId());
double RandomWorkTime = FMath::FRandRange(0.0f, 6.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;
}
/**
* Message box test/
*/
int32 MessageBoxTest(const TCHAR* CommandLine)
{
FPlatformMisc::SetCrashHandler(NULL);
FPlatformMisc::SetGracefulTerminationHandler();
GEngineLoop.PreInit(CommandLine);
UE_LOG(LogTestPAL, Display, TEXT("Running message box test."));
FString Display(TEXT("I am a big big string in a big big game, it's not a big big thing if you print me. But I do do feel that I do do will be displayed wrong, displayed wrong... or not."));
FString Caption(TEXT("I am a big big caption in a big big game, it's not a big big thing if you print me. But I do do feel that I do do will be displayed wrong, displayed wrong... or not."));
EAppReturnType::Type Result = FPlatformMisc::MessageBoxExt(EAppMsgType::YesNo, *Display, *Caption);
UE_LOG(LogTestPAL, Display, TEXT("MessageBoxExt result: %d."), static_cast<int32>(Result));
FEngineLoop::AppPreExit();
FEngineLoop::AppExit();
return 0;
}
/**
* ************ Thread singleton test *****************
*/
/**
* Per-thread singleton
*/
struct FPerThreadTestSingleton : public TThreadSingleton<FPerThreadTestSingleton>
{
FPerThreadTestSingleton()
{
UE_LOG(LogTestPAL, Log, TEXT("FPerThreadTestSingleton (this=%p) created for thread %d"),
this,
FPlatformTLS::GetCurrentThreadId());
}
void DoSomething()
{
UE_LOG(LogTestPAL, Log, TEXT("Thread %d is about to quit"), FPlatformTLS::GetCurrentThreadId());
}
virtual ~FPerThreadTestSingleton()
{
UE_LOG(LogTestPAL, Log, TEXT("FPerThreadTestSingleton (%p) destroyed for thread %d"),
this,
FPlatformTLS::GetCurrentThreadId());
}
};
//DECLARE_THREAD_SINGLETON( FPerThreadTestSingleton );
/**
* Thread runnable
*/
struct FSingletonTestingThread : public FRunnable
{
virtual uint32 Run()
{
FPerThreadTestSingleton& Dummy = FPerThreadTestSingleton::Get();
FPlatformProcess::Sleep(3.0f);
Dummy.DoSomething();
return 0;
}
};
/**
* Thread singleton test
*/
int32 ThreadSingletonTest(const TCHAR* CommandLine)
{
FPlatformMisc::SetCrashHandler(NULL);
FPlatformMisc::SetGracefulTerminationHandler();
GEngineLoop.PreInit(CommandLine);
UE_LOG(LogTestPAL, Display, TEXT("Running thread singleton test."));
const int kNumTestThreads = 10;
FSingletonTestingThread * RunnableArray[kNumTestThreads] = { nullptr };
FRunnableThread * ThreadArray[kNumTestThreads] = { nullptr };
// start all threads
for (int Idx = 0; Idx < kNumTestThreads; ++Idx)
{
RunnableArray[Idx] = new FSingletonTestingThread();
ThreadArray[Idx] = FRunnableThread::Create(RunnableArray[Idx],
*FString::Printf(TEXT("TestThread%d"), Idx));
}
GLog->FlushThreadedLogs();
GLog->Flush();
// join all threads
for (int Idx = 0; Idx < kNumTestThreads; ++Idx)
{
ThreadArray[Idx]->WaitForCompletion();
delete ThreadArray[Idx];
ThreadArray[Idx] = nullptr;
delete RunnableArray[Idx];
RunnableArray[Idx] = nullptr;
}
FEngineLoop::AppPreExit();
FEngineLoop::AppExit();
return 0;
}
/**
* Sysinfo test
*/
int32 SysInfoTest(const TCHAR* CommandLine)
{
FPlatformMisc::SetCrashHandler(NULL);
FPlatformMisc::SetGracefulTerminationHandler();
GEngineLoop.PreInit(CommandLine);
UE_LOG(LogTestPAL, Display, TEXT("Running system info test."));
bool bIsRunningOnBattery = FPlatformMisc::IsRunningOnBattery();
UE_LOG(LogTestPAL, Display, TEXT(" FPlatformMisc::IsRunningOnBattery() = %s"), bIsRunningOnBattery ? TEXT("true") : TEXT("false"));
FString OSInstanceGuid = FPlatformMisc::GetOperatingSystemId();
UE_LOG(LogTestPAL, Display, TEXT(" FPlatformMisc::GetOperatingSystemId() = %s"), *OSInstanceGuid);
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);
}
else if (!FCStringAnsi::Strcmp(ArgV[IdxArg], ARG_MESSAGEBOX_TEST))
{
return MessageBoxTest(*TestPAL::CommandLine);
}
else if (!FCStringAnsi::Strcmp(ArgV[IdxArg], ARG_DIRECTORY_WATCHER_TEST))
{
return DirectoryWatcherTest(*TestPAL::CommandLine);
}
else if (!FCStringAnsi::Strcmp(ArgV[IdxArg], ARG_THREAD_SINGLETON_TEST))
{
return ThreadSingletonTest(*TestPAL::CommandLine);
}
else if (!FCStringAnsi::Strcmp(ArgV[IdxArg], ARG_SYSINFO_TEST))
{
return SysInfoTest(*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."));
UE_LOG(LogTestPAL, Warning, TEXT(""));
UE_LOG(LogTestPAL, Warning, TEXT("Available test cases:"));
UE_LOG(LogTestPAL, Warning, TEXT(" %s: test process handling API"), ANSI_TO_TCHAR( ARG_PROC_TEST ));
UE_LOG(LogTestPAL, Warning, TEXT(" %s: test case-insensitive file operations"), ANSI_TO_TCHAR( ARG_CASE_SENSITIVITY_TEST ));
UE_LOG(LogTestPAL, Warning, TEXT(" %s: test message box bug (too long strings)"), ANSI_TO_TCHAR( ARG_MESSAGEBOX_TEST ));
UE_LOG(LogTestPAL, Warning, TEXT(" %s: test directory watcher"), ANSI_TO_TCHAR( ARG_DIRECTORY_WATCHER_TEST ));
UE_LOG(LogTestPAL, Warning, TEXT(" %s: test per-thread singletons"), ANSI_TO_TCHAR( ARG_THREAD_SINGLETON_TEST ));
UE_LOG(LogTestPAL, Warning, TEXT(" %s: test (some) system information"), ANSI_TO_TCHAR( ARG_SYSINFO_TEST ))
UE_LOG(LogTestPAL, Warning, TEXT(""));
UE_LOG(LogTestPAL, Warning, TEXT("Pass one of those to run an appropriate test."));
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);
}