Files
UnrealEngineUWP/Engine/Source/Developer/AutomationController/Private/AutomationControllerManager.h
Ben Marsh 4ba423868f Copying //UE4/Dev-Build to //UE4/Dev-Main (Source: //UE4/Dev-Build @ 3209340)
#lockdown Nick.Penwarden
#rb none

==========================
MAJOR FEATURES + CHANGES
==========================

Change 3209340 on 2016/11/23 by Ben.Marsh

	Convert UE4 codebase to an "include what you use" model - where every header just includes the dependencies it needs, rather than every source file including large monolithic headers like Engine.h and UnrealEd.h.

	Measured full rebuild times around 2x faster using XGE on Windows, and improvements of 25% or more for incremental builds and full rebuilds on most other platforms.

	  * Every header now includes everything it needs to compile.
	        * There's a CoreMinimal.h header that gets you a set of ubiquitous types from Core (eg. FString, FName, TArray, FVector, etc...). Most headers now include this first.
	        * There's a CoreTypes.h header that sets up primitive UE4 types and build macros (int32, PLATFORM_WIN64, etc...). All headers in Core include this first, as does CoreMinimal.h.
	  * Every .cpp file includes its matching .h file first.
	        * This helps validate that each header is including everything it needs to compile.
	  * No engine code includes a monolithic header such as Engine.h or UnrealEd.h any more.
	        * You will get a warning if you try to include one of these from the engine. They still exist for compatibility with game projects and do not produce warnings when included there.
	        * There have only been minor changes to our internal games down to accommodate these changes. The intent is for this to be as seamless as possible.
	  * No engine code explicitly includes a precompiled header any more.
	        * We still use PCHs, but they're force-included on the compiler command line by UnrealBuildTool instead. This lets us tune what they contain without breaking any existing include dependencies.
	        * PCHs are generated by a tool to get a statistical amount of coverage for the source files using it, and I've seeded the new shared PCHs to contain any header included by > 15% of source files.

	Tool used to generate this transform is at Engine\Source\Programs\IncludeTool.

[CL 3209342 by Ben Marsh in Main branch]
2016-11-23 15:48:37 -05:00

506 lines
14 KiB
C++

// Copyright 1998-2016 Epic Games, Inc. All Rights Reserved.
#pragma once
#include "CoreMinimal.h"
#include "UObject/ObjectMacros.h"
#include "Misc/Guid.h"
#include "Containers/Queue.h"
#include "Misc/AutomationTest.h"
#include "Interfaces/IAutomationControllerManager.h"
#include "IMessageContext.h"
#include "Helpers/MessageEndpoint.h"
#include "Developer/AutomationController/Private/AutomationDeviceClusterManager.h"
#include "Developer/AutomationController/Private/AutomationReportManager.h"
#include "Async/Future.h"
#include "ImageComparer.h"
#include "Interfaces/IScreenShotManager.h"
#include "AutomationControllerManager.generated.h"
USTRUCT()
struct FAutomatedTestResult
{
GENERATED_BODY()
public:
UPROPERTY()
FString TestName;
UPROPERTY()
FString TestResult;
UPROPERTY()
TArray<FString> TestInfo;
UPROPERTY()
TArray<FString> TestErrors;
UPROPERTY()
TArray<FString> TestWarnings;
FAutomatedTestResult()
{
TestResult = TEXT("Not Run");
}
};
USTRUCT()
struct FAutomatedTestPassResults
{
GENERATED_BODY()
public:
FAutomatedTestPassResults()
: NumSucceeded(0)
, NumFailed(0)
, NumNotRun(0)
{
}
UPROPERTY()
int32 NumSucceeded;
UPROPERTY()
int32 NumFailed;
UPROPERTY()
int32 NumNotRun;
UPROPERTY()
TArray<FAutomatedTestResult> TestInformation;
void ClearAllEntries()
{
NumSucceeded = 0;
NumFailed = 0;
NumNotRun = 0;
TestInformation.Empty();
}
};
/**
* Implements the AutomationController module.
*/
class FAutomationControllerManager : public IAutomationControllerManager
{
public:
// IAutomationController Interface
virtual void RequestAvailableWorkers( const FGuid& InSessionId ) override;
virtual void RequestTests() override;
virtual void RunTests( const bool bIsLocalSession) override;
virtual void StopTests() override;
virtual void Init() override;
virtual void RequestLoadAsset( const FString& InAssetName ) override;
virtual void Tick() override;
virtual void SetNumPasses(const int32 InNumPasses) override
{
NumTestPasses = InNumPasses;
}
virtual int32 GetNumPasses() override
{
return NumTestPasses;
}
virtual bool IsSendAnalytics() const override
{
return bSendAnalytics;
}
virtual void SetSendAnalytics(const bool bNewValue) override
{
bSendAnalytics = bNewValue;
}
virtual bool IsScreenshotAllowed() const override
{
return bScreenshotsEnabled;
}
virtual void SetScreenshotsEnabled( const bool bNewValue ) override
{
bScreenshotsEnabled = bNewValue;
}
virtual void SetFilter( TSharedPtr< AutomationFilterCollection > InFilter ) override
{
ReportManager.SetFilter( InFilter );
}
virtual TArray <TSharedPtr <IAutomationReport> >& GetReports() override
{
return ReportManager.GetFilteredReports();
}
virtual int32 GetNumDeviceClusters() const override
{
return DeviceClusterManager.GetNumClusters();
}
virtual int32 GetNumDevicesInCluster(const int32 ClusterIndex) const override
{
return DeviceClusterManager.GetNumDevicesInCluster(ClusterIndex);
}
virtual FString GetClusterGroupName(const int32 ClusterIndex) const override
{
return DeviceClusterManager.GetClusterGroupName(ClusterIndex);
}
virtual FString GetDeviceTypeName(const int32 ClusterIndex) const override
{
return DeviceClusterManager.GetClusterDeviceType(ClusterIndex);
}
virtual FString GetGameInstanceName(const int32 ClusterIndex, const int32 DeviceIndex) const override
{
return DeviceClusterManager.GetClusterDeviceName(ClusterIndex, DeviceIndex);
}
virtual void SetVisibleTestsEnabled(const bool bEnabled) override
{
ReportManager.SetVisibleTestsEnabled (bEnabled);
}
virtual int32 GetEnabledTestsNum() const override
{
return ReportManager.GetEnabledTestsNum();
}
virtual void GetEnabledTestNames(TArray<FString>& OutEnabledTestNames) const override
{
ReportManager.GetEnabledTestNames(OutEnabledTestNames);
}
virtual void SetEnabledTests(const TArray<FString>& EnabledTests) override
{
ReportManager.SetEnabledTests(EnabledTests);
}
virtual EAutomationControllerModuleState::Type GetTestState( ) const override
{
return AutomationTestState;
}
virtual void SetDeveloperDirectoryIncluded(const bool bInDeveloperDirectoryIncluded) override
{
bDeveloperDirectoryIncluded = bInDeveloperDirectoryIncluded;
}
virtual bool IsDeveloperDirectoryIncluded(void) const override
{
return bDeveloperDirectoryIncluded;
}
virtual void SetRequestedTestFlags(const uint32 InRequestedTestFlags) override
{
RequestedTestFlags = InRequestedTestFlags;
RequestTests();
}
virtual const bool CheckTestResultsAvailable() const override
{
return bTestResultsAvailable;
}
virtual const bool ReportsHaveErrors() const override
{
return bHasErrors;
}
virtual const bool ReportsHaveWarnings() const override
{
return bHasWarning;
}
virtual const bool ReportsHaveLogs() const override
{
return bHasLogs;
}
virtual void ClearAutomationReports() override
{
ReportManager.Empty();
}
virtual const bool ExportReport(uint32 FileExportTypeMask) override;
virtual bool IsTestRunnable( IAutomationReportPtr InReport ) const override;
virtual void RemoveCallbacks() override;
virtual void Shutdown() override;
virtual void Startup() override;
virtual FOnAutomationControllerManagerShutdown& OnShutdown( ) override
{
return ShutdownDelegate;
}
virtual FOnAutomationControllerManagerTestsAvailable& OnTestsAvailable( ) override
{
return TestsAvailableDelegate;
}
virtual FOnAutomationControllerTestsRefreshed& OnTestsRefreshed( ) override
{
return TestsRefreshedDelegate;
}
virtual FOnAutomationControllerTestsComplete& OnTestsComplete() override
{
return TestsCompleteDelegate;
}
virtual FOnAutomationControllerReset& OnControllerReset() override
{
return ControllerResetDelegate;
}
virtual bool IsDeviceGroupFlagSet( EAutomationDeviceGroupTypes::Type InDeviceGroup ) const override;
virtual void ToggleDeviceGroupFlag( EAutomationDeviceGroupTypes::Type InDeviceGroup ) override;
virtual void UpdateDeviceGroups() override;
virtual void TrackReportHistory(const bool bShouldTrack, const int32 NumReportsToTrack) override;
virtual const bool IsTrackingHistory() const override;
virtual const int32 GetNumberHistoryItemsTracking() const override;
protected:
/**
* Adds a ping result from a running test.
*
* @param ResponderAddress The address of the message endpoint that responded to a ping.
*/
void AddPingResult( const FMessageAddress& ResponderAddress );
/**
* Spew all of our results of the test out to the log.
*/
void ReportTestResults();
/**
* Create a json file that contains all of our test report data at /saved/automation/logs/AutomationReport-{CL}-{DateTime}.json
*/
void GenerateJsonTestPassSummary();
/**
* Updates the result value of a finished test.
*
* @param TestName The test that was just run.
* @param TestResult The result that the test returned.
*/
void UpdateTestResultValue(FString TestName, EAutomationState::Type TestResult);
/**
* Gather all info, warning, and error lines generated over the course of a test.
*
* @param TestName The test that was just run.
* @param TestResult All of the messages of note generated during the test case.
*/
void CollectTestNotes(FString TestName, const FAutomationWorkerRunTestsReply& Message);
/**
* Checks the child result.
*
* @param InReport The child result to check.
*/
void CheckChildResult( TSharedPtr< IAutomationReport > InReport );
/**
* Execute the next task thats available.
*
* @param ClusterIndex The Cluster index of the device type we intend to use.
* @param bAllTestsCompleted Whether all tests have been completed.
*/
void ExecuteNextTask( int32 ClusterIndex, OUT bool& bAllTestsCompleted );
/** Process the comparison queue to see if there are comparisons we need to respond to the test with. */
void ProcessComparisonQueue();
/** Distributes any tests that are pending and deal with tests finishing. */
void ProcessAvailableTasks();
/** Processes the results after tests are complete. */
void ProcessResults();
/**
* Removes the test info.
*
* @param TestToRemove The test to remove.
*/
void RemoveTestRunning( const FMessageAddress& TestToRemove );
/** Resets the data holders which have been used to generate the tests available from a worker. */
void ResetIntermediateTestData()
{
TestInfo.Empty();
}
/** Changes the controller state. */
void SetControllerStatus( EAutomationControllerModuleState::Type AutomationTestState );
/** stores the tests that are valid for a particular device classification. */
void SetTestNames(const FMessageAddress& AutomationWorkerAddress);
/** Updates the tests to ensure they are all still running. */
void UpdateTests();
private:
/** Handles FAutomationWorkerFindWorkersResponse messages. */
void HandleFindWorkersResponseMessage( const FAutomationWorkerFindWorkersResponse& Message, const IMessageContextRef& Context );
/** Handles FAutomationWorkerPong messages. */
void HandlePongMessage( const FAutomationWorkerPong& Message, const IMessageContextRef& Context );
/** Handles FAutomationWorkerScreenImage messages. */
void HandleReceivedScreenShot( const FAutomationWorkerScreenImage& Message, const IMessageContextRef& Context );
/** Handles FAutomationWorkerRequestNextNetworkCommand messages. */
void HandleRequestNextNetworkCommandMessage( const FAutomationWorkerRequestNextNetworkCommand& Message, const IMessageContextRef& Context );
/** Handles FAutomationWorkerRequestTestsReply messages. */
void HandleRequestTestsReplyMessage( const FAutomationWorkerRequestTestsReply& Message, const IMessageContextRef& Context );
/** Handles FAutomationWorkerRequestTestsReplyComplete messages. */
void HandleRequestTestsReplyCompleteMessage(const FAutomationWorkerRequestTestsReplyComplete& Message, const IMessageContextRef& Context);
/** Handles FAutomationWorkerRunTestsReply messages. */
void HandleRunTestsReplyMessage( const FAutomationWorkerRunTestsReply& Message, const IMessageContextRef& Context );
/** Handles FAutomationWorkerWorkerOffline messages. */
void HandleWorkerOfflineMessage( const FAutomationWorkerWorkerOffline& Message, const IMessageContextRef& Context );
private:
/** Session this controller is currently communicating with */
FGuid ActiveSessionId;
/** The automation test state */
EAutomationControllerModuleState::Type AutomationTestState;
/** Which grouping flags are enabled */
uint32 DeviceGroupFlags;
/** Whether to include developer content in the automation tests */
bool bDeveloperDirectoryIncluded;
/** Some tests have errors */
bool bHasErrors;
/** Some tests have warnings */
bool bHasWarning;
/** Some tests have logs */
bool bHasLogs;
/** Is this a local session */
bool bIsLocalSession;
/** Are tests results available */
bool bTestResultsAvailable;
/** Which sets of tests to consider */
uint32 RequestedTestFlags;
/** Timer to keep track of the last time tests were updated */
double CheckTestTimer;
/** Whether tick is still executing tests for different clusters */
uint32 ClusterDistributionMask;
/** Available worker GUIDs */
FAutomationDeviceClusterManager DeviceClusterManager;
/** The iteration number of executing the tests. Ensures restarting the tests won't allow stale results to try and commit */
uint32 ExecutionCount;
/** Last time the update tests function was ticked */
double LastTimeUpdateTicked;
/** Holds the messaging endpoint. */
FMessageEndpointPtr MessageEndpoint;
/** Counter for number of workers we have received responses from for Refreshing the Test List */
uint32 RefreshTestResponses;
/** Available stats/status for all tests. */
FAutomationReportManager ReportManager;
/** The number we are expecting to receive from a worker */
int32 NumOfTestsToReceive;
/** The collection of test data we are to send to a controller. */
TArray< FAutomationTestInfo > TestInfo;
/** A data holder to keep track of how long tests have been running. */
struct FTestRunningInfo
{
FTestRunningInfo( FMessageAddress InMessageAddress ):
OwnerMessageAddress( InMessageAddress),
LastPingTime( 0.f )
{
}
/** The test runners message address */
FMessageAddress OwnerMessageAddress;
/** The time since we had a ping from the instance*/
float LastPingTime;
};
/** A array of running tests. */
TArray< FTestRunningInfo > TestRunningArray;
/** The number of test passes to perform. */
int32 NumTestPasses;
/** The current test pass we are on. */
int32 CurrentTestPass;
/** If screenshots are enabled. */
bool bScreenshotsEnabled;
/** If we should send result to analytics */
bool bSendAnalytics;
/** If we should track any test history for the next run. */
bool bTrackHistory;
/** The number of history items we wish to track. */
int32 NumberOfHistoryItemsTracked;
/** The list of results generated by our test pass. */
FAutomatedTestPassResults OurPassResults;
/** The screenshot manager. */
IScreenShotManagerPtr ScreenshotManager;
struct FComparisonEntry
{
FMessageAddress Sender;
TFuture<FImageComparisonResult> PendingComparison;
};
/** Pending image comparisons */
TQueue<TSharedPtr<FComparisonEntry>> ComparisonQueue;
private:
/** Holds a delegate that is invoked when the controller shuts down. */
FOnAutomationControllerManagerShutdown ShutdownDelegate;
/** Holds a delegate that is invoked when the controller has tests available. */
FOnAutomationControllerManagerTestsAvailable TestsAvailableDelegate;
/** Holds a delegate that is invoked when the controller's tests are being refreshed. */
FOnAutomationControllerTestsRefreshed TestsRefreshedDelegate;
/** Holds a delegate that is invoked when the controller's reset. */
FOnAutomationControllerReset ControllerResetDelegate;
/** Holds a delegate that is invoked when the tests have completed. */
FOnAutomationControllerTestsComplete TestsCompleteDelegate;
};