2021-09-29 15:50:57 -04:00
// Copyright Epic Games, Inc. All Rights Reserved.
using System ;
using System.Collections.Generic ;
using System.Linq ;
using System.IO ;
using AutomationTool ;
using UnrealBuildTool ;
using UnrealBuildBase ;
using Gauntlet ;
using System.Text.RegularExpressions ;
using AutomationTool.DeviceReservation ;
namespace LowLevelTests
{
public class RunLowLevelTests : BuildCommand
{
public override ExitCode Execute ( )
{
Log . Level = LogLevel . VeryVerbose ;
Globals . Params = new Params ( Params ) ;
LowLevelTestExecutorOptions ContextOptions = new LowLevelTestExecutorOptions ( ) ;
AutoParam . ApplyParamsAndDefaults ( ContextOptions , Globals . Params . AllArguments ) ;
if ( ContextOptions . TestApp = = string . Empty )
{
Log . Error ( "Error: -testapp flag is missing on the command line. Expected test project that extends LowLevelTests module." ) ;
return ExitCode . Error_Arguments ;
}
if ( string . IsNullOrEmpty ( ContextOptions . Build ) )
{
Log . Error ( "No build path specified. Set -build= to test executable and resources directory." ) ;
return ExitCode . Error_Arguments ;
}
2021-10-15 12:17:53 -04:00
if ( ! Path . IsPathRooted ( ContextOptions . Build ) )
{
2021-11-18 14:37:34 -05:00
ContextOptions . Build = Path . Combine ( Globals . UnrealRootDir , ContextOptions . Build ) ;
2021-10-15 12:17:53 -04:00
}
2021-09-29 15:50:57 -04:00
return RunTests ( ContextOptions ) ;
}
public ExitCode RunTests ( LowLevelTestExecutorOptions ContextOptions )
{
UnrealTargetPlatform TestPlatform = ContextOptions . Platform ;
LowLevelTestRoleContext RoleContext = new LowLevelTestRoleContext ( ) ;
RoleContext . Platform = TestPlatform ;
LowLevelTestsBuildSource BuildSource = new LowLevelTestsBuildSource (
ContextOptions . TestApp ,
ContextOptions . Build ,
2022-08-11 07:31:45 -04:00
ContextOptions . Platform ,
ContextOptions . Configuration ) ;
2021-09-29 15:50:57 -04:00
SetupDevices ( TestPlatform , ContextOptions ) ;
LowLevelTestContext TestContext = new LowLevelTestContext ( BuildSource , RoleContext , ContextOptions ) ;
ITestNode NewTest = Gauntlet . Utils . TestConstructor . ConstructTest < ITestNode , LowLevelTestContext > ( ContextOptions . TestApp , TestContext , new string [ ] { "LowLevelTests" } ) ;
2021-11-09 12:47:22 -05:00
if ( ! ( NewTest is LowLevelTests ) )
{
throw new AutomationException ( "Expected ITestNode type of LowLevelTests" ) ;
}
2021-09-29 15:50:57 -04:00
bool TestPassed = ExecuteTest ( ContextOptions , NewTest ) ;
DevicePool . Instance . Dispose ( ) ;
DoCleanup ( TestPlatform ) ;
return TestPassed ? ExitCode . Success : ExitCode . Error_TestFailure ;
}
void DoCleanup ( UnrealTargetPlatform Platform )
{
2021-10-01 09:58:15 -04:00
// TODO: Platform specific cleanup
2021-09-29 15:50:57 -04:00
}
private bool ExecuteTest ( LowLevelTestExecutorOptions Options , ITestNode LowLevelTestNode )
{
2022-10-11 02:54:50 -04:00
var Executor = new TestExecutor ( ToString ( ) ) ;
2021-09-29 15:50:57 -04:00
try
{
bool Result = Executor . ExecuteTests ( Options , new List < ITestNode > ( ) { LowLevelTestNode } ) ;
return Result ;
}
catch ( Exception ex )
{
Log . Info ( "" ) ;
Log . Error ( "{0}.\r\n\r\n{1}" , ex . Message , ex . StackTrace ) ;
return false ;
}
finally
{
Executor . Dispose ( ) ;
2021-10-15 12:17:53 -04:00
if ( ! string . IsNullOrEmpty ( Options . Device ) )
{
2021-11-09 12:47:22 -05:00
( LowLevelTestNode as LowLevelTests )
2022-02-24 09:01:29 -05:00
. LowLevelTestsApp ?
. UnrealDeviceReservation ?
2021-11-09 12:47:22 -05:00
. ReleaseDevices ( ) ;
2021-10-15 12:17:53 -04:00
}
2021-09-29 15:50:57 -04:00
DevicePool . Instance . Dispose ( ) ;
if ( ParseParam ( "clean" ) )
{
LogInformation ( "Deleting temp dir {0}" , Options . TempDir ) ;
DirectoryInfo TempDirInfo = new DirectoryInfo ( Options . TempDir ) ;
if ( TempDirInfo . Exists )
{
TempDirInfo . Delete ( true ) ;
}
}
GC . Collect ( ) ;
}
}
protected void SetupDevices ( UnrealTargetPlatform TestPlatform , LowLevelTestExecutorOptions Options )
{
Reservation . ReservationDetails = Options . JobDetails ;
DevicePool . Instance . SetLocalOptions ( Options . TempDir , Options . Parallel > 1 , Options . DeviceURL ) ;
2021-10-15 12:17:53 -04:00
DevicePool . Instance . AddLocalDevices ( 1 ) ;
2022-06-09 04:05:18 -04:00
DevicePool . Instance . AddVirtualDevices ( 2 ) ;
2021-09-29 15:50:57 -04:00
if ( ! string . IsNullOrEmpty ( Options . Device ) )
{
DevicePool . Instance . AddDevices ( TestPlatform , Options . Device ) ;
}
}
}
public class LowLevelTestExecutorOptions : TestExecutorOptions , IAutoParamNotifiable
{
public Params Params { get ; protected set ; }
public string TempDir ;
[AutoParam("")]
public string DeviceURL ;
[AutoParam("")]
public string JobDetails ;
public string TestApp ;
2022-03-24 13:28:25 -04:00
public string Tags ;
2022-08-24 15:53:16 -04:00
[AutoParam(0)]
public int Sleep ;
2022-09-13 15:06:34 -04:00
public bool AttachToDebugger ;
2021-09-29 15:50:57 -04:00
public string Build ;
[AutoParam("")]
public string LogDir ;
2022-10-03 14:53:22 -04:00
[AutoParam("console")]
public string ReportType ;
2021-09-29 15:50:57 -04:00
public Type BuildSourceType { get ; protected set ; }
[AutoParam(UnrealTargetConfiguration.Development)]
public UnrealTargetConfiguration Configuration ;
public UnrealTargetPlatform Platform ;
public string Device ;
public LowLevelTestExecutorOptions ( )
{
BuildSourceType = typeof ( LowLevelTestsBuildSource ) ;
}
public virtual void ParametersWereApplied ( string [ ] InParams )
{
Params = new Params ( InParams ) ;
if ( string . IsNullOrEmpty ( TempDir ) )
{
TempDir = Globals . TempDir ;
}
else
{
Globals . TempDir = TempDir ;
}
if ( string . IsNullOrEmpty ( LogDir ) )
{
LogDir = Globals . LogDir ;
}
else
{
Globals . LogDir = LogDir ;
}
LogDir = Path . GetFullPath ( LogDir ) ;
TempDir = Path . GetFullPath ( TempDir ) ;
Build = Params . ParseValue ( "build=" , null ) ;
TestApp = Globals . Params . ParseValue ( "testapp=" , "" ) ;
2022-03-24 13:28:25 -04:00
Tags = Params . ParseValue ( "tags=" , null ) ;
2022-09-13 15:06:34 -04:00
AttachToDebugger = Params . ParseParam ( "attachtodebugger" ) ;
2022-03-24 13:28:25 -04:00
2022-10-03 14:53:22 -04:00
ReportType = Params . ParseValue ( "reporttype=" , "console" ) ;
2021-09-29 15:50:57 -04:00
string PlatformArgString = Params . ParseValue ( "platform=" , null ) ;
Platform = string . IsNullOrEmpty ( PlatformArgString ) ? BuildHostPlatform . Current . Platform : UnrealTargetPlatform . Parse ( PlatformArgString ) ;
string DeviceArgString = Params . ParseValue ( "device=" , null ) ;
Device = string . IsNullOrEmpty ( PlatformArgString ) ? "default" : DeviceArgString ;
string [ ] CleanArgs = Params . AllArguments
. Where ( Arg = > ! Arg . StartsWith ( "test=" , StringComparison . OrdinalIgnoreCase )
& & ! Arg . StartsWith ( "platform=" , StringComparison . OrdinalIgnoreCase )
& & ! Arg . StartsWith ( "device=" , StringComparison . OrdinalIgnoreCase ) )
. ToArray ( ) ;
Params = new Params ( CleanArgs ) ;
}
}
public class LowLevelTestsSession : IDisposable
{
2021-10-15 12:17:53 -04:00
private static int QUERY_STATE_INTERVAL = 1 ;
2022-03-24 13:28:25 -04:00
public IAppInstall Install { get ; protected set ; }
2021-09-29 15:50:57 -04:00
public IAppInstance Instance { get ; protected set ; }
private LowLevelTestsBuildSource BuildSource { get ; set ; }
2022-03-24 13:28:25 -04:00
private string Tags { get ; set ; }
2022-08-24 15:53:16 -04:00
private int Sleep { get ; set ; }
2022-09-13 15:06:34 -04:00
private bool AttachToDebugger { get ; set ; }
2022-10-03 14:53:22 -04:00
private string ReportType { get ; set ; }
2021-09-29 15:50:57 -04:00
2021-11-09 12:47:22 -05:00
public UnrealDeviceReservation UnrealDeviceReservation { get ; private set ; }
2022-10-03 14:53:22 -04:00
public LowLevelTestsSession ( LowLevelTestsBuildSource InBuildSource , string InTags , int InSleep , bool InAttachToDebugger , string InReportType )
2021-09-29 15:50:57 -04:00
{
BuildSource = InBuildSource ;
2022-03-24 13:28:25 -04:00
Tags = InTags ;
2022-08-24 15:53:16 -04:00
Sleep = InSleep ;
2022-09-13 15:06:34 -04:00
AttachToDebugger = InAttachToDebugger ;
2022-10-03 14:53:22 -04:00
ReportType = InReportType ;
2021-11-09 12:47:22 -05:00
UnrealDeviceReservation = new UnrealDeviceReservation ( ) ;
2021-09-29 15:50:57 -04:00
}
public bool TryReserveDevices ( )
{
Dictionary < UnrealDeviceTargetConstraint , int > RequiredDeviceTypes = new Dictionary < UnrealDeviceTargetConstraint , int > ( ) ;
// Only one device required.
RequiredDeviceTypes . Add ( new UnrealDeviceTargetConstraint ( BuildSource . Platform ) , 1 ) ;
return UnrealDeviceReservation . TryReserveDevices ( RequiredDeviceTypes , 1 ) ;
}
/// <summary>
/// Copies build folder on device and launches app natively.
/// Does not retry.
/// No packaging required.
/// </summary>
public IAppInstance InstallAndRunNativeTestApp ( )
{
bool InstallSuccess = false ;
bool RunSuccess = false ;
// TargetDevice<Platform> classes have a hard dependency on UnrealAppConfig instead of IAppConfig.
// More refactoring needed to support non-packaged applications that can be run natively from a path on the device.
2022-10-03 14:53:22 -04:00
UnrealAppConfig AppConfig = BuildSource . GetUnrealAppConfig ( Tags , Sleep , AttachToDebugger , ReportType ) ;
2021-09-29 15:50:57 -04:00
IEnumerable < ITargetDevice > DevicesToInstallOn = UnrealDeviceReservation . ReservedDevices . ToArray ( ) ;
ITargetDevice Device = DevicesToInstallOn . Where ( D = > D . IsConnected & & D . Platform = = BuildSource . Platform ) . First ( ) ;
IDeviceUsageReporter . RecordStart ( Device . Name , ( UnrealTargetPlatform ) Device . Platform , IDeviceUsageReporter . EventType . Device , IDeviceUsageReporter . EventState . Success ) ;
IDeviceUsageReporter . RecordStart ( Device . Name , ( UnrealTargetPlatform ) Device . Platform , IDeviceUsageReporter . EventType . Install , IDeviceUsageReporter . EventState . Success , BuildSource . BuildName ) ;
try
{
Install = Device . InstallApplication ( AppConfig ) ;
InstallSuccess = true ;
IDeviceUsageReporter . RecordEnd ( Device . Name , ( UnrealTargetPlatform ) Device . Platform , IDeviceUsageReporter . EventType . Install , IDeviceUsageReporter . EventState . Success ) ;
}
catch ( Exception Ex )
{
InstallSuccess = false ;
2022-08-24 15:53:16 -04:00
Log . Info ( "Failed to install low level tests app onto device {0}: {1}" , Device , Ex . ToString ( ) ) ;
2021-09-29 15:50:57 -04:00
UnrealDeviceReservation . MarkProblemDevice ( Device ) ;
IDeviceUsageReporter . RecordEnd ( Device . Name , ( UnrealTargetPlatform ) Device . Platform , IDeviceUsageReporter . EventType . Install , IDeviceUsageReporter . EventState . Failure ) ;
}
if ( ! InstallSuccess )
{
// release all devices
UnrealDeviceReservation . ReleaseDevices ( ) ;
Log . Info ( "\nUnable to install low level tests app.\n" ) ;
}
else
{
try
{
2021-10-15 12:17:53 -04:00
if ( Device is IRunningStateOptions )
{
// Don't wait to detect running state and query for running state every second
IRunningStateOptions DeviceWithStateOptions = ( IRunningStateOptions ) Device ;
DeviceWithStateOptions . WaitForRunningState = false ;
DeviceWithStateOptions . CachedStateRefresh = QUERY_STATE_INTERVAL ;
}
Instance = Device . Run ( Install ) ;
2021-09-29 15:50:57 -04:00
IDeviceUsageReporter . RecordStart ( Instance . Device . Name , ( UnrealTargetPlatform ) Instance . Device . Platform , IDeviceUsageReporter . EventType . Test ) ;
RunSuccess = true ;
}
catch ( DeviceException DeviceEx )
{
Log . Warning ( "Device {0} threw an exception during launch. \nException={1}" , Install . Device , DeviceEx . Message ) ;
RunSuccess = false ;
}
if ( RunSuccess = = false )
{
Log . Warning ( "Failed to start low level test on {0}. Marking as problem device. Will not retry." , Device ) ;
if ( Instance ! = null )
{
Instance . Kill ( ) ;
}
UnrealDeviceReservation . MarkProblemDevice ( Device ) ;
UnrealDeviceReservation . ReleaseDevices ( ) ;
throw new AutomationException ( "Unable to start low level tests app, see warnings for details." ) ;
}
}
return Instance ;
}
public void Dispose ( )
{
if ( Instance ! = null )
{
Instance . Kill ( ) ;
IDeviceUsageReporter . RecordEnd ( Instance . Device . Name , ( UnrealTargetPlatform ) Instance . Device . Platform , IDeviceUsageReporter . EventType . Test , IDeviceUsageReporter . EventState . Success ) ;
if ( Instance . HasExited )
{
IDeviceUsageReporter . RecordEnd ( Instance . Device . Name , ( UnrealTargetPlatform ) Instance . Device . Platform , IDeviceUsageReporter . EventType . Test , IDeviceUsageReporter . EventState . Failure ) ;
}
2022-06-09 04:05:18 -04:00
UnrealDeviceReservation ? . ReleaseDevices ( ) ;
2021-09-29 15:50:57 -04:00
}
}
}
public class LowLevelTestRoleContext : ICloneable
{
public UnrealTargetRole Type { get { return UnrealTargetRole . Client ; } }
public UnrealTargetPlatform Platform ;
public UnrealTargetConfiguration Configuration { get { return UnrealTargetConfiguration . Development ; } }
public object Clone ( )
{
return this . MemberwiseClone ( ) ;
}
public override string ToString ( )
{
string Description = string . Format ( "{0} {1} {2}" , Platform , Configuration , Type ) ;
return Description ;
}
} ;
public class LowLevelTestContext : ITestContext , ICloneable
{
public LowLevelTestsBuildSource BuildInfo { get ; private set ; }
public string WorkerJobID ;
public LowLevelTestExecutorOptions Options { get ; set ; }
public Params TestParams { get ; set ; }
public LowLevelTestRoleContext RoleContext { get ; set ; }
public UnrealDeviceTargetConstraint Constraint ;
public LowLevelTestContext ( LowLevelTestsBuildSource InBuildInfo , LowLevelTestRoleContext InRoleContext , LowLevelTestExecutorOptions InOptions )
{
BuildInfo = InBuildInfo ;
Options = InOptions ;
TestParams = new Params ( new string [ 0 ] ) ;
RoleContext = InRoleContext ;
}
public object Clone ( )
{
LowLevelTestContext Copy = ( LowLevelTestContext ) MemberwiseClone ( ) ;
Copy . RoleContext = ( LowLevelTestRoleContext ) RoleContext . Clone ( ) ;
return Copy ;
}
public override string ToString ( )
{
string Description = string . Format ( "{0}" , RoleContext ) ;
if ( WorkerJobID ! = null )
{
Description + = " " + WorkerJobID ;
}
return Description ;
}
}
2022-03-24 13:28:25 -04:00
/// <summary>
/// Platform-specific reporting utility for defining Catch2 report path and means to copy it to a saved storage either from its local directory or from a target device.
/// </summary>
public interface ILowLevelTestsReporting
{
/// <summary>
/// Use this to implement platform-specific specializations of ILowLevelTestsReporting.
/// </summary>
bool CanSupportPlatform ( UnrealTargetPlatform InPlatform ) ;
/// <summary>
/// Specify Catch2 target report path for this platform.
/// </summary>
string GetTargetReportPath ( UnrealTargetPlatform InPlatform , string InTestApp , string InBuildPath ) ;
/// <summary>
/// Copy generated report and return copied path
/// </summary>
string CopyDeviceReportTo ( IAppInstall InAppInstall , UnrealTargetPlatform InPlatform , string InTestApp , string InBuildPath , string InTargetDirectory ) ;
}
2021-10-15 12:17:53 -04:00
public interface ILowLevelTestsBuildFactory
{
bool CanSupportPlatform ( UnrealTargetPlatform InPlatform ) ;
2022-08-11 07:31:45 -04:00
LowLevelTestsBuild CreateBuild ( UnrealTargetPlatform InPlatform , UnrealTargetConfiguration InConfiguration , string InTestApp , string InBuildPath ) ;
2021-10-15 12:17:53 -04:00
2022-08-11 07:31:45 -04:00
protected static string GetExecutable ( UnrealTargetPlatform InPlatform , UnrealTargetConfiguration InConfiguration , string InTestApp , string InBuildPath , string FileRegEx )
2021-10-15 12:17:53 -04:00
{
IEnumerable < string > Executables = DirectoryUtils . FindFiles ( InBuildPath , new Regex ( FileRegEx ) ) ;
2022-09-13 15:06:34 -04:00
string ParentDirPath ;
string BuildExecutableName ;
2021-10-15 12:17:53 -04:00
foreach ( string Executable in Executables )
{
2022-09-13 15:06:34 -04:00
ParentDirPath = Directory . GetParent ( Executable ) . FullName ;
BuildExecutableName = Path . GetFileNameWithoutExtension ( Executable ) ;
if ( ParentDirPath . ToLower ( ) . Contains ( InPlatform . ToString ( ) . ToLower ( ) ) )
2021-10-15 12:17:53 -04:00
{
2022-09-13 15:06:34 -04:00
if ( ParentDirPath . ToLower ( ) . Contains ( InTestApp . ToString ( ) . ToLower ( ) ) )
2021-10-15 12:17:53 -04:00
{
2022-09-13 15:06:34 -04:00
// Executable name must not contain any configuration or platform name
if ( InConfiguration = = UnrealTargetConfiguration . Development )
{
if ( BuildExecutableName . CompareTo ( InTestApp ) = = 0 & & ! BuildExecutableName . Contains ( InPlatform . ToString ( ) ) )
{
return Path . GetRelativePath ( InBuildPath , Executable ) ;
}
}
else if ( BuildExecutableName . Contains ( InTestApp ) & & BuildExecutableName . Contains ( InPlatform . ToString ( ) ) )
2022-08-11 07:31:45 -04:00
{
return Path . GetRelativePath ( InBuildPath , Executable ) ;
}
2021-10-15 12:17:53 -04:00
}
}
}
throw new AutomationException ( "Cannot find low level test executable for {0} in build path {1} for {2} using regex \"{3}\"" , InPlatform , InBuildPath , InTestApp , FileRegEx ) ;
}
2022-08-11 07:31:45 -04:00
protected static void CleanupUnusedFiles ( UnrealTargetPlatform InPlatform , UnrealTargetConfiguration InConfiguration , string InBuildPath )
2021-10-15 12:17:53 -04:00
{
try
{
string [ ] BuildFiles = Directory . GetFiles ( InBuildPath ) ;
foreach ( string BuildFile in BuildFiles )
{
2022-08-11 07:31:45 -04:00
if ( new FileInfo ( BuildFile ) . Extension = = ".pdb" & & InConfiguration ! = UnrealTargetConfiguration . Debug )
2021-10-15 12:17:53 -04:00
{
File . Delete ( BuildFile ) ;
}
}
}
catch ( Exception cleanupEx )
{
Log . Error ( "Could not cleanup files for {0} build: {1}." , InPlatform . ToString ( ) , cleanupEx ) ;
}
}
}
public class DesktopLowLevelTestsBuildFactory : ILowLevelTestsBuildFactory
{
public bool CanSupportPlatform ( UnrealTargetPlatform InPlatform )
{
return InPlatform . IsInGroup ( UnrealPlatformGroup . Desktop ) ;
}
2022-08-11 07:31:45 -04:00
public LowLevelTestsBuild CreateBuild ( UnrealTargetPlatform InPlatform , UnrealTargetConfiguration InConfiguration , string InTestApp , string InBuildPath )
2021-10-15 12:17:53 -04:00
{
string DesktopExecutableRegEx ;
2022-05-05 10:56:38 -04:00
if ( InPlatform . IsInGroup ( UnrealPlatformGroup . Windows ) )
2021-10-15 12:17:53 -04:00
{
2022-08-11 07:31:45 -04:00
DesktopExecutableRegEx = @"\w+Tests(?:-\w+)?(?:-\w+)?.exe$" ;
2021-10-15 12:17:53 -04:00
}
else if ( InPlatform = = UnrealTargetPlatform . Linux | | InPlatform = = UnrealTargetPlatform . Mac )
{
DesktopExecutableRegEx = @"\w+Tests$" ;
}
else
{
throw new AutomationException ( "Cannot create build for non-desktop platform " + InPlatform ) ;
}
2022-08-11 07:31:45 -04:00
string ExecutablePath = ILowLevelTestsBuildFactory . GetExecutable ( InPlatform , InConfiguration , InTestApp , InBuildPath , DesktopExecutableRegEx ) ;
return new LowLevelTestsBuild ( InPlatform , InConfiguration , InBuildPath , ExecutablePath ) ;
2021-10-15 12:17:53 -04:00
}
}
2022-03-24 13:28:25 -04:00
public class DesktopLowLevelTestsReporting : ILowLevelTestsReporting
{
public bool CanSupportPlatform ( UnrealTargetPlatform InPlatform )
{
return InPlatform . IsInGroup ( UnrealPlatformGroup . Desktop ) ;
}
public string GetTargetReportPath ( UnrealTargetPlatform InPlatform , string InTestApp , string InBuildPath )
{
return string . Format ( "{0}LLTResults.out" , InPlatform . ToString ( ) ) ;
}
public string CopyDeviceReportTo ( IAppInstall InAppInstall , UnrealTargetPlatform InPlatform , string InTestApp , string InBuildPath , string InTargetDirectory )
{
string ReportRelativePath = GetTargetReportPath ( InPlatform , InTestApp , InBuildPath ) ;
string ReportPath = Path . Combine ( InBuildPath , ReportRelativePath ) ;
string ExpectedLocalPath = Path . Combine ( InTargetDirectory , ReportRelativePath ) ;
2022-05-05 10:56:38 -04:00
File . Copy ( ReportPath , ExpectedLocalPath ) ;
2022-03-24 13:28:25 -04:00
return ExpectedLocalPath ;
}
}
2021-09-29 15:50:57 -04:00
public class LowLevelTestsBuildSource : IBuildSource
{
private string TestApp ;
2022-03-24 13:28:25 -04:00
private string BuildPath ;
2021-10-15 12:17:53 -04:00
private UnrealAppConfig CachedConfig = null ;
2021-09-29 15:50:57 -04:00
2022-03-24 13:28:25 -04:00
private ILowLevelTestsBuildFactory LowLevelTestsBuildFactory ;
private ILowLevelTestsReporting LowLevelTestsReporting ;
2021-09-29 15:50:57 -04:00
public UnrealTargetPlatform Platform { get ; protected set ; }
2022-08-11 07:31:45 -04:00
public UnrealTargetConfiguration Configuration { get ; protected set ; }
2021-09-29 15:50:57 -04:00
public LowLevelTestsBuild DiscoveredBuild { get ; protected set ; }
2022-08-11 07:31:45 -04:00
public LowLevelTestsBuildSource ( string InTestApp , string InBuildPath , UnrealTargetPlatform InTargetPlatform , UnrealTargetConfiguration InConfiguration )
2021-09-29 15:50:57 -04:00
{
TestApp = InTestApp ;
Platform = InTargetPlatform ;
2022-03-24 13:28:25 -04:00
BuildPath = InBuildPath ;
2022-08-11 07:31:45 -04:00
Configuration = InConfiguration ;
InitBuildSource ( InTestApp , InBuildPath , InTargetPlatform , InConfiguration ) ;
2021-09-29 15:50:57 -04:00
}
2022-08-11 07:31:45 -04:00
protected void InitBuildSource ( string InTestApp , string InBuildPath , UnrealTargetPlatform InTargetPlatform , UnrealTargetConfiguration InConfiguration )
2021-09-29 15:50:57 -04:00
{
2022-03-24 13:28:25 -04:00
LowLevelTestsBuildFactory = Gauntlet . Utils . InterfaceHelpers . FindImplementations < ILowLevelTestsBuildFactory > ( true )
2021-10-15 12:17:53 -04:00
. Where ( B = > B . CanSupportPlatform ( InTargetPlatform ) )
. First ( ) ;
2022-08-11 07:31:45 -04:00
DiscoveredBuild = LowLevelTestsBuildFactory . CreateBuild ( InTargetPlatform , InConfiguration , InTestApp , InBuildPath ) ;
2021-09-29 15:50:57 -04:00
if ( DiscoveredBuild = = null )
{
throw new AutomationException ( "No builds were discovered at path {0} matching test app name {1} and target platform {2}" , InBuildPath , InTestApp , InTargetPlatform ) ;
}
2022-03-24 13:28:25 -04:00
LowLevelTestsReporting = Gauntlet . Utils . InterfaceHelpers . FindImplementations < ILowLevelTestsReporting > ( true )
. Where ( B = > B . CanSupportPlatform ( InTargetPlatform ) )
. First ( ) ;
2021-09-29 15:50:57 -04:00
}
2022-10-03 14:53:22 -04:00
public UnrealAppConfig GetUnrealAppConfig ( string InTags , int InSleep , bool InAttachToDebugger , string InReportType )
2021-09-29 15:50:57 -04:00
{
2021-10-15 12:17:53 -04:00
if ( CachedConfig = = null )
{
CachedConfig = new UnrealAppConfig ( ) ;
CachedConfig . Name = BuildName ;
CachedConfig . ProjectName = TestApp ;
CachedConfig . ProcessType = UnrealTargetRole . Client ;
CachedConfig . Platform = Platform ;
CachedConfig . Configuration = UnrealTargetConfiguration . Development ;
CachedConfig . Build = DiscoveredBuild ;
CachedConfig . Sandbox = "LowLevelTests" ;
CachedConfig . FilesToCopy = new List < UnrealFileToCopy > ( ) ;
2022-03-24 13:28:25 -04:00
// Set reporting options, filters etc
2022-09-13 15:06:34 -04:00
CachedConfig . CommandLineParams . AddRawCommandline ( "--durations=no" ) ;
2022-10-03 14:53:22 -04:00
CachedConfig . CommandLineParams . AddRawCommandline ( string . Format ( "--reporter={0}" , InReportType ) ) ;
2022-08-24 15:53:16 -04:00
CachedConfig . CommandLineParams . AddRawCommandline ( string . Format ( "--out={0}" , LowLevelTestsReporting . GetTargetReportPath ( Platform , TestApp , BuildPath ) ) ) ;
CachedConfig . CommandLineParams . AddRawCommandline ( "--filenames-as-tags" ) ;
2022-03-24 13:28:25 -04:00
if ( ! string . IsNullOrEmpty ( InTags ) )
{
CachedConfig . CommandLineParams . Add ( InTags , null , true ) ;
}
2022-08-24 15:53:16 -04:00
if ( InSleep > 0 )
{
CachedConfig . CommandLineParams . AddRawCommandline ( String . Format ( "--sleep={0}" , InSleep ) ) ;
}
CachedConfig . CommandLineParams . AddRawCommandline ( "--debug" ) ;
2022-09-13 15:06:34 -04:00
CachedConfig . CommandLineParams . AddRawCommandline ( "--log" ) ;
if ( InAttachToDebugger )
{
CachedConfig . CommandLineParams . AddRawCommandline ( "--attach-to-debugger" ) ;
}
2021-10-15 12:17:53 -04:00
}
return CachedConfig ;
2021-09-29 15:50:57 -04:00
}
public bool CanSupportPlatform ( UnrealTargetPlatform Platform )
{
return true ;
}
public string BuildName { get { return TestApp ; } }
2021-10-15 12:17:53 -04:00
}
2021-09-29 15:50:57 -04:00
2021-10-15 12:17:53 -04:00
public class LowLevelTestsBuild : StagedBuild
{
2022-08-11 07:31:45 -04:00
public LowLevelTestsBuild ( UnrealTargetPlatform InPlatform , UnrealTargetConfiguration InConfiguration , string InBuildPath , string InExecutablePath )
: base ( InPlatform , InConfiguration , UnrealTargetRole . Client , InBuildPath , InExecutablePath )
2021-09-29 15:50:57 -04:00
{
2022-07-08 03:38:58 -04:00
Flags = BuildFlags . CanReplaceExecutable | BuildFlags . Loose ;
2021-09-29 15:50:57 -04:00
}
}
2022-08-24 15:53:16 -04:00
}