2022-01-19 15:00:37 -05:00
// Copyright Epic Games, Inc. All Rights Reserved.
2023-05-30 18:38:07 -04:00
using System ;
2022-04-27 12:36:35 -04:00
using System.Collections.Generic ;
2022-01-19 15:00:37 -05:00
using System.IO ;
2022-04-27 12:36:35 -04:00
using System.Linq ;
using System.Xml.Linq ;
using EpicGames.Core ;
2023-05-30 18:38:07 -04:00
using UnrealBuildBase ;
2022-01-19 15:00:37 -05:00
namespace UnrealBuildTool
{
/// <summary>
/// ModuleRules extension for low level tests.
/// </summary>
public class TestModuleRules : ModuleRules
{
2022-04-27 12:36:35 -04:00
private readonly XNamespace BuildGraphNamespace = XNamespace . Get ( "http://www.epicgames.com/BuildGraph" ) ;
private readonly XNamespace SchemaInstance = XNamespace . Get ( "http://www.w3.org/2001/XMLSchema-instance" ) ;
private readonly XNamespace SchemaLocation = XNamespace . Get ( "http://www.epicgames.com/BuildGraph ../../Build/Graph/Schema.xsd" ) ;
private bool bUsesCatch2 = true ;
2022-01-19 15:00:37 -05:00
/// <summary>
/// Associated tested module of this test module.
/// </summary>
2022-04-27 12:36:35 -04:00
public ModuleRules ? TestedModule { get ; private set ; }
/// <summary>
/// Constructs a TestModuleRules object as its own test module.
/// </summary>
/// <param name="Target"></param>
public TestModuleRules ( ReadOnlyTargetRules Target ) : base ( Target )
{
SetupCommonProperties ( Target ) ;
}
/// <summary>
/// Constructs a TestModuleRules object as its own test module.
/// Sets value of bUsesCatch2.
/// </summary>
public TestModuleRules ( ReadOnlyTargetRules Target , bool InUsesCatch2 ) : base ( Target )
{
bUsesCatch2 = InUsesCatch2 ;
if ( bUsesCatch2 )
{
SetupCommonProperties ( Target ) ;
}
}
2022-01-19 15:00:37 -05:00
/// <summary>
/// Constructs a TestModuleRules object with an associated tested module.
/// </summary>
2022-04-20 14:24:59 -04:00
public TestModuleRules ( ModuleRules TestedModule ) : base ( TestedModule . Target )
2022-01-19 15:00:37 -05:00
{
this . TestedModule = TestedModule ;
Name = TestedModule . Name + "Tests" ;
2023-05-30 18:59:32 -04:00
if ( ! String . IsNullOrEmpty ( TestedModule . ShortName ) )
2022-01-19 15:00:37 -05:00
{
ShortName = TestedModule . ShortName + "Tests" ;
}
2022-04-20 14:24:59 -04:00
File = TestedModule . File ;
2022-01-19 15:00:37 -05:00
Directory = DirectoryReference . Combine ( TestedModule . Directory , "Tests" ) ;
Context = TestedModule . Context ;
2022-04-27 12:36:35 -04:00
PrivateDependencyModuleNames . AddRange ( TestedModule . PrivateDependencyModuleNames ) ;
2023-02-06 14:27:24 -05:00
PublicDependencyModuleNames . AddRange ( TestedModule . PublicDependencyModuleNames ) ;
2022-04-27 12:36:35 -04:00
2023-11-29 16:58:22 -05:00
DirectoriesForModuleSubClasses = new Dictionary < Type , DirectoryReference > ( ) ;
2022-04-27 12:36:35 -04:00
// Tests can refer to tested module's Public and Private paths
string ModulePublicDir = Path . Combine ( TestedModule . ModuleDirectory , "Public" ) ;
if ( System . IO . Directory . Exists ( ModulePublicDir ) )
{
PublicIncludePaths . Add ( ModulePublicDir ) ;
}
string ModulePrivateDir = Path . Combine ( TestedModule . ModuleDirectory , "Private" ) ;
if ( System . IO . Directory . Exists ( ModulePrivateDir ) )
{
PrivateIncludePaths . Add ( ModulePrivateDir ) ;
}
SetupCommonProperties ( Target ) ;
}
private void SetupCommonProperties ( ReadOnlyTargetRules Target )
{
bIsTestModuleOverride = true ;
2022-01-19 15:00:37 -05:00
PCHUsage = PCHUsageMode . NoPCHs ;
PrecompileForTargets = PrecompileTargetsType . None ;
if ( Target . Configuration = = UnrealTargetConfiguration . Debug & & Target . Platform = = UnrealTargetPlatform . Linux )
{
OptimizeCode = CodeOptimization . Never ;
}
bAllowConfidentialPlatformDefines = true ;
bLegalToDistributeObjectCode = true ;
// Required false for catch.hpp
bUseUnity = false ;
// Disable exception handling so that tests can assert for exceptions
bEnableObjCExceptions = false ;
bEnableExceptions = false ;
2022-10-18 11:48:58 -04:00
SetResourcesFolder ( "Resources" ) ;
2022-02-22 13:52:35 -05:00
2022-05-17 15:06:28 -04:00
if ( ! PublicDependencyModuleNames . Contains ( "Catch2" ) )
{
PublicDependencyModuleNames . Add ( "Catch2" ) ;
}
2022-02-22 13:52:35 -05:00
if ( ! PrivateDependencyModuleNames . Contains ( "LowLevelTestsRunner" ) )
{
PrivateDependencyModuleNames . Add ( "LowLevelTestsRunner" ) ;
}
2022-01-19 15:00:37 -05:00
// Platforms specific setup
if ( Target . Platform = = UnrealTargetPlatform . Android )
{
PublicDefinitions . Add ( "CATCH_CONFIG_NOSTDOUT" ) ;
}
2023-06-15 04:50:22 -04:00
if ( Target . Platform = = UnrealTargetPlatform . IOS | | Target . Platform = = UnrealTargetPlatform . TVOS )
{
// Fix missing frameworks from ApplicationCore
// Needed for CADisplayLink
PublicFrameworks . Add ( "QuartzCore" ) ;
// Needed for MTLCreateSystemDefaultDevice
PublicWeakFrameworks . Add ( "Metal" ) ;
}
2022-01-19 15:00:37 -05:00
}
2022-04-27 12:36:35 -04:00
/// <summary>
/// Set test-specific resources folder relative to module directory.
/// This will be copied to the binaries path during deployment.
/// </summary>
protected void SetResourcesFolder ( string ResourcesRelativeFolder )
{
2023-12-20 17:54:40 -05:00
AdditionalPropertiesForReceipt . RemoveAll ( Prop = > Prop . Name = = "ResourcesFolder" ) ;
2022-10-18 11:48:58 -04:00
foreach ( DirectoryReference Directory in GetAllModuleDirectories ( ) )
2022-04-27 12:36:35 -04:00
{
2022-10-18 11:48:58 -04:00
string TestResourcesDir = Path . Combine ( Directory . FullName , ResourcesRelativeFolder ) ;
if ( System . IO . Directory . Exists ( TestResourcesDir ) )
2022-04-27 12:36:35 -04:00
{
AdditionalPropertiesForReceipt . Add ( "ResourcesFolder" , TestResourcesDir ) ;
}
}
}
2023-05-04 11:05:46 -04:00
#pragma warning disable 8602
#pragma warning disable 8604
2022-04-27 12:36:35 -04:00
/// <summary>
2023-05-04 11:05:46 -04:00
/// Generates or updates metadata file for LowLevelTests.xml containing test flags: name, short name, target name, relative binaries path, supported platforms etc.
2022-04-27 12:36:35 -04:00
/// <paramref name="TestMetadata">The test metadata specifying name, short name etc used to populate the BuildGraph properties file.</paramref>
/// </summary>
2023-05-04 11:05:46 -04:00
protected void UpdateBuildGraphPropertiesFile ( Metadata TestMetadata )
2022-04-27 12:36:35 -04:00
{
2023-06-29 15:18:42 -04:00
bool bUpdateBuildGraphPropertiesFile = false ;
TestTargetRules ? TestTargetRules = Target . InnerTestTargetRules ;
if ( TestTargetRules ! = null )
{
bUpdateBuildGraphPropertiesFile = TestTargetRules . bUpdateBuildGraphPropertiesFile ;
}
2023-08-10 20:59:28 -04:00
bool bIsBuildMachine = Unreal . IsBuildMachine ( ) ;
2023-06-29 15:18:42 -04:00
if ( bIsBuildMachine | | ! bUpdateBuildGraphPropertiesFile | | TestMetadata = = null )
2022-06-28 15:11:17 -04:00
{
return ;
}
2023-08-17 16:15:06 -04:00
string BaseFolder = GetBaseFolder ( ) ;
2022-04-27 12:36:35 -04:00
string GeneratedPropertiesScriptFile ;
2023-08-17 16:15:06 -04:00
string NonPublicPath = Path . Combine ( BaseFolder , "Restricted" , "NotForLicensees" , "Build" , "LowLevelTests" , $"{TestMetadata.TestName}.xml" ) ;
2022-04-27 12:36:35 -04:00
2023-05-04 11:05:46 -04:00
bool ModuleInRestrictedPath = IsRestrictedPath ( ModuleDirectory ) ;
if ( ModuleInRestrictedPath )
2022-04-27 12:36:35 -04:00
{
GeneratedPropertiesScriptFile = NonPublicPath ;
}
else
{
2023-08-17 16:15:06 -04:00
GeneratedPropertiesScriptFile = Path . Combine ( BaseFolder , "Build" , "LowLevelTests" , $"{TestMetadata.TestName}.xml" ) ;
2022-04-27 12:36:35 -04:00
}
if ( ! System . IO . File . Exists ( GeneratedPropertiesScriptFile ) )
{
string? DirGenProps = Path . GetDirectoryName ( GeneratedPropertiesScriptFile ) ;
2023-05-04 11:05:46 -04:00
if ( DirGenProps ! = null & & ! System . IO . Directory . Exists ( DirGenProps ) )
2022-04-27 12:36:35 -04:00
{
System . IO . Directory . CreateDirectory ( DirGenProps ) ;
}
2023-05-04 11:05:46 -04:00
using ( FileStream FileStream = System . IO . File . Create ( GeneratedPropertiesScriptFile ) )
{
XDocument XInitFile = new XDocument ( new XElement ( BuildGraphNamespace + "BuildGraph" , new XAttribute ( XNamespace . Xmlns + "xsi" , SchemaInstance ) , new XAttribute ( SchemaInstance + "schemaLocation" , SchemaLocation ) ) ) ;
XInitFile . Root ? . Add (
new XElement (
BuildGraphNamespace + "Property" ,
new XAttribute ( "Name" , "TestNames" ) ,
new XAttribute ( "Value" , "$(TestNames);" + TestMetadata . TestName ) ) ) ;
2022-04-27 12:36:35 -04:00
2023-05-04 11:05:46 -04:00
XInitFile . Save ( FileStream ) ;
}
2022-04-27 12:36:35 -04:00
}
// All relevant properties
2023-05-04 11:05:46 -04:00
string TestTargetName = Target . LaunchModuleName ? ? "Launch" ;
2022-04-27 12:36:35 -04:00
string TestBinariesPath = TryGetBinariesPath ( ) ;
// Do not save full paths
if ( Path . IsPathRooted ( TestBinariesPath ) )
{
TestBinariesPath = Path . GetRelativePath ( Unreal . RootDirectory . FullName , TestBinariesPath ) ;
}
2023-08-17 16:15:06 -04:00
MakeFileWriteable ( GeneratedPropertiesScriptFile ) ;
2022-04-27 12:36:35 -04:00
XDocument GenPropsDoc = XDocument . Load ( GeneratedPropertiesScriptFile ) ;
XElement ? Root = GenPropsDoc . Root ;
// First descendant must be TestNames
if ( Root ! = null & & Root . FirstNode ! = null )
{
XElement TestNames = ( XElement ) Root . FirstNode ;
if ( TestNames ! = null )
{
XElement lastUpdatedNode = TestNames ;
2023-05-30 18:38:07 -04:00
2023-05-04 11:05:46 -04:00
InsertOrUpdateTestFlagProperty ( ref lastUpdatedNode , TestMetadata . TestName , "Disabled" , Convert . ToString ( TestMetadata . Disabled ) ) ;
InsertOrUpdateTestFlagProperty ( ref lastUpdatedNode , TestMetadata . TestName , "Short" , Convert . ToString ( TestMetadata . TestShortName ) ) ;
2023-06-22 17:41:56 -04:00
InsertOrUpdateTestFlagProperty ( ref lastUpdatedNode , TestMetadata . TestName , "StagesWithProjectFile" , Convert . ToString ( TestMetadata . StagesWithProjectFile ) ) ;
2023-05-04 11:05:46 -04:00
InsertOrUpdateTestFlagProperty ( ref lastUpdatedNode , TestMetadata . TestName , "Target" , Convert . ToString ( TestTargetName ) ) ;
InsertOrUpdateTestFlagProperty ( ref lastUpdatedNode , TestMetadata . TestName , "BinariesRelative" , Convert . ToString ( TestBinariesPath ) ) ;
InsertOrUpdateTestFlagProperty ( ref lastUpdatedNode , TestMetadata . TestName , "ReportType" , Convert . ToString ( TestMetadata . ReportType ) ) ;
2023-08-10 11:53:46 -04:00
InsertOrUpdateTestFlagProperty ( ref lastUpdatedNode , TestMetadata . TestName , "GauntletArgs" , Convert . ToString ( TestMetadata . InitialExtraArgs ) + Convert . ToString ( TestMetadata . GauntletArgs ) ) ;
InsertOrUpdateTestFlagProperty ( ref lastUpdatedNode , TestMetadata . TestName , "ExtraArgs" , Convert . ToString ( TestMetadata . ExtraArgs ) ) ;
2023-05-04 11:05:46 -04:00
InsertOrUpdateTestFlagProperty ( ref lastUpdatedNode , TestMetadata . TestName , "HasAfterSteps" , Convert . ToString ( TestMetadata . HasAfterSteps ) ) ;
InsertOrUpdateTestFlagProperty ( ref lastUpdatedNode , TestMetadata . TestName , "UsesCatch2" , Convert . ToString ( TestMetadata . UsesCatch2 ) ) ;
2022-04-27 12:36:35 -04:00
2023-06-22 17:41:56 -04:00
InsertOrUpdateTestOption ( ref lastUpdatedNode , TestMetadata . TestName , $"Run {TestMetadata.TestShortName} Tests" , "Run" , "Tests" , false . ToString ( ) ) ;
2022-04-27 12:36:35 -04:00
2023-08-17 16:15:06 -04:00
InsertOrUpdateTestFlagProperty ( ref lastUpdatedNode , TestMetadata . TestName , "SupportedPlatforms" , TestMetadata . SupportedPlatforms . Aggregate ( "" , ( current , next ) = > ( String . IsNullOrEmpty ( current ) ? next . ToString ( ) : current + ";" + next . ToString ( ) ) ) ) ;
2022-04-27 12:36:35 -04:00
}
}
2023-05-04 11:05:46 -04:00
GenPropsDoc . Save ( GeneratedPropertiesScriptFile ) ;
// Platform-specific configurations
string GeneratedPropertiesPlatformFile ;
string NonPublicPathPlatform ;
// Generate peroperty file for each platform
2023-05-31 13:37:21 -04:00
foreach ( UnrealTargetPlatform ValidPlatform in UnrealTargetPlatform . GetValidPlatforms ( ) )
2023-05-04 11:05:46 -04:00
{
bool IsRestrictedPlatformName = IsPlatformRestricted ( ValidPlatform ) ;
if ( IsRestrictedPlatformName )
{
2023-08-17 16:15:06 -04:00
NonPublicPathPlatform = Path . Combine ( BaseFolder , "Restricted" , "NotForLicensees" , "Platforms" , ValidPlatform . ToString ( ) , "Build" , "LowLevelTests" , $"{TestMetadata.TestName}.xml" ) ;
2023-05-04 11:05:46 -04:00
}
else
{
2023-08-17 16:15:06 -04:00
NonPublicPathPlatform = Path . Combine ( BaseFolder , "Restricted" , "NotForLicensees" , "Build" , "LowLevelTests" , $"{TestMetadata.TestName}.xml" ) ;
2023-05-04 11:05:46 -04:00
}
if ( ModuleInRestrictedPath )
{
GeneratedPropertiesPlatformFile = NonPublicPathPlatform ;
}
else
{
if ( IsRestrictedPlatformName )
{
2023-08-17 16:15:06 -04:00
GeneratedPropertiesPlatformFile = Path . Combine ( BaseFolder , "Platforms" , ValidPlatform . ToString ( ) , "Build" , "LowLevelTests" , $"{TestMetadata.TestName}.xml" ) ;
2023-05-04 11:05:46 -04:00
}
else
{
2023-08-17 16:15:06 -04:00
GeneratedPropertiesPlatformFile = Path . Combine ( BaseFolder , "Build" , "LowLevelTests" , $"{TestMetadata.TestName}.xml" ) ;
2023-05-04 11:05:46 -04:00
}
}
if ( ! System . IO . File . Exists ( GeneratedPropertiesPlatformFile ) )
{
string? DirGenPropsPlatforms = Path . GetDirectoryName ( GeneratedPropertiesPlatformFile ) ;
if ( DirGenPropsPlatforms ! = null & & ! System . IO . Directory . Exists ( DirGenPropsPlatforms ) )
{
System . IO . Directory . CreateDirectory ( DirGenPropsPlatforms ) ;
}
using ( FileStream FileStream = System . IO . File . Create ( GeneratedPropertiesPlatformFile ) )
{
2023-05-30 18:38:07 -04:00
new XDocument ( new XElement ( BuildGraphNamespace + "BuildGraph" , new XAttribute ( XNamespace . Xmlns + "xsi" , SchemaInstance ) , new XAttribute ( SchemaInstance + "schemaLocation" , SchemaLocation ) ) ) . Save ( FileStream ) ;
2023-05-04 11:05:46 -04:00
}
}
2023-08-17 16:15:06 -04:00
MakeFileWriteable ( GeneratedPropertiesPlatformFile ) ;
2023-05-04 11:05:46 -04:00
XDocument XInitPlatformFile = XDocument . Load ( GeneratedPropertiesPlatformFile ) ;
// Adding per-test and per-platform tags
2023-05-30 18:59:32 -04:00
string TagsValue = TestMetadata . PlatformTags . ContainsKey ( ValidPlatform ) ? TestMetadata . PlatformTags [ ValidPlatform ] : String . Empty ;
2023-05-04 11:05:46 -04:00
AppendOrUpdateTestFlagProperty ( ref XInitPlatformFile , TestMetadata . TestName , ValidPlatform . ToString ( ) , "Tags" , TagsValue ) ;
2023-05-30 18:59:32 -04:00
string ExtraCompilationArgsValue = TestMetadata . PlatformCompilationExtraArgs . ContainsKey ( ValidPlatform ) ? TestMetadata . PlatformCompilationExtraArgs [ ValidPlatform ] : String . Empty ;
2023-05-04 11:05:46 -04:00
AppendOrUpdateTestFlagProperty ( ref XInitPlatformFile , TestMetadata . TestName , ValidPlatform . ToString ( ) , "ExtraCompilationArgs" , ExtraCompilationArgsValue ) ;
string RunSupportedValue = TestMetadata . PlatformsRunUnsupported . Contains ( ValidPlatform ) ? "False" : "True" ;
AppendOrUpdateTestFlagProperty ( ref XInitPlatformFile , TestMetadata . TestName , ValidPlatform . ToString ( ) , "RunSupported" , RunSupportedValue ) ;
2023-09-11 12:55:31 -04:00
string RunContainerizedValue = TestMetadata . PlatformRunContainerized . ContainsKey ( ValidPlatform ) ? "True" : "False" ;
AppendOrUpdateTestFlagProperty ( ref XInitPlatformFile , TestMetadata . TestName , ValidPlatform . ToString ( ) , "RunContainerized" , RunContainerizedValue ) ;
2023-05-04 11:05:46 -04:00
XInitPlatformFile . Save ( GeneratedPropertiesPlatformFile ) ;
}
}
2023-08-17 16:15:06 -04:00
private string GetBaseFolder ( )
{
string RelativeModulePath = Path . GetRelativePath ( Unreal . RootDirectory . FullName , ModuleDirectory ) ;
string [ ] BreadCrumbs = RelativeModulePath . Split ( new char [ ] { '\\' , '/' } , StringSplitOptions . RemoveEmptyEntries ) ;
if ( BreadCrumbs . Length > 0 )
{
return Path . Combine ( Unreal . RootDirectory . FullName , BreadCrumbs [ 0 ] ) ;
}
return Unreal . EngineDirectory . FullName ;
}
2023-05-04 11:05:46 -04:00
private bool IsPlatformRestricted ( UnrealTargetPlatform Platform )
{
return RestrictedFolder . GetNames ( ) . Contains ( Platform . ToString ( ) ) ;
2022-04-27 12:36:35 -04:00
}
private bool IsRestrictedPath ( string ModuleDirectory )
{
foreach ( string RestrictedFolderName in RestrictedFolder . GetNames ( ) )
{
if ( ModuleDirectory . Contains ( RestrictedFolderName ) )
{
return true ;
}
}
return false ;
}
private string TryGetBinariesPath ( )
{
int SourceFolderIndex = ModuleDirectory . IndexOf ( "Source" ) ;
if ( SourceFolderIndex < 0 )
{
2023-08-17 16:15:06 -04:00
int PluginFolderIndex = ModuleDirectory . IndexOf ( "Plugins" ) ;
if ( PluginFolderIndex > = 0 )
{
return ModuleDirectory . Substring ( 0 , PluginFolderIndex ) + "Binaries" ;
}
2022-04-27 12:36:35 -04:00
throw new Exception ( "Could not detect source folder path for module " + GetType ( ) ) ;
}
return ModuleDirectory . Substring ( 0 , SourceFolderIndex ) + "Binaries" ;
}
2023-05-04 11:05:46 -04:00
private void AppendOrUpdateTestFlagProperty ( ref XDocument Document , string FlagRadix , string FlagPrefix , string FlagSuffix , string FlagValue )
{
XElement ? Existing = Document . Root ! . Elements ( ) . Where ( element = > element . Attribute ( "Name" ) . Value = = FlagPrefix + FlagRadix + FlagSuffix ) . FirstOrDefault ( ) ;
if ( Existing ! = null )
{
Existing ! . SetAttributeValue ( "Value" , FlagValue ) ;
}
else
{
XElement ElementAppend = new XElement ( BuildGraphNamespace + "Property" ) ;
ElementAppend . SetAttributeValue ( "Name" , FlagPrefix + FlagRadix + FlagSuffix ) ;
ElementAppend . SetAttributeValue ( "Value" , FlagValue ) ;
Document . Root ! . Add ( ElementAppend ) ;
}
}
private void InsertOrUpdateTestFlagProperty ( ref XElement ElementUpsertAfter , string TestName , string FlagSuffix , string FlagValue )
2022-04-27 12:36:35 -04:00
{
IEnumerable < XElement > NextChunk = ElementUpsertAfter . ElementsAfterSelf ( BuildGraphNamespace + "Property" )
. Where ( prop = > prop . Attribute ( "Name" ) . Value . EndsWith ( FlagSuffix ) ) ;
2023-05-31 13:37:21 -04:00
if ( ! NextChunk
. Where ( prop = > prop . Attribute ( "Name" ) . Value = = TestName + FlagSuffix ) . Any ( ) )
2022-04-27 12:36:35 -04:00
{
XElement ElementInsert = new XElement ( BuildGraphNamespace + "Property" ) ;
ElementInsert . SetAttributeValue ( "Name" , TestName + FlagSuffix ) ;
ElementInsert . SetAttributeValue ( "Value" , FlagValue ) ;
ElementUpsertAfter . AddAfterSelf ( ElementInsert ) ;
}
else
{
NextChunk
. Where ( prop = > prop . Attribute ( "Name" ) . Value = = TestName + FlagSuffix ) . First ( ) . SetAttributeValue ( "Value" , FlagValue ) ;
}
ElementUpsertAfter = NextChunk . Last ( ) ;
}
2023-05-04 11:05:46 -04:00
private void InsertOrUpdateTestOption ( ref XElement ElementUpsertAfter , string OptionRadix , string Description , string OptionPrefix , string OptionSuffix , string DefaultValue )
2022-04-27 12:36:35 -04:00
{
IEnumerable < XElement > NextChunk = ElementUpsertAfter . ElementsAfterSelf ( BuildGraphNamespace + "Option" )
. Where ( prop = > prop . Attribute ( "Name" ) . Value . StartsWith ( OptionPrefix ) & & prop . Attribute ( "Name" ) . Value . EndsWith ( OptionSuffix ) ) ;
2023-05-31 13:37:21 -04:00
if ( ! NextChunk
. Where ( prop = > prop . Attribute ( "Name" ) . Value = = OptionPrefix + OptionRadix + OptionSuffix ) . Any ( ) )
2022-04-27 12:36:35 -04:00
{
XElement ElementInsert = new XElement ( BuildGraphNamespace + "Option" ) ;
2023-05-04 11:05:46 -04:00
ElementInsert . SetAttributeValue ( "Name" , OptionPrefix + OptionRadix + OptionSuffix ) ;
2022-04-27 12:36:35 -04:00
ElementInsert . SetAttributeValue ( "DefaultValue" , DefaultValue ) ;
2023-05-04 11:05:46 -04:00
ElementInsert . SetAttributeValue ( "Description" , Description ) ;
2022-04-27 12:36:35 -04:00
ElementUpsertAfter . AddAfterSelf ( ElementInsert ) ;
}
else
{
XElement ElementUpdate = NextChunk
2023-05-04 11:05:46 -04:00
. Where ( prop = > prop . Attribute ( "Name" ) . Value = = OptionPrefix + OptionRadix + OptionSuffix ) . First ( ) ;
ElementUpdate . SetAttributeValue ( "Description" , Description ) ;
2022-04-27 12:36:35 -04:00
ElementUpdate . SetAttributeValue ( "DefaultValue" , DefaultValue ) ;
}
ElementUpsertAfter = NextChunk . Last ( ) ;
}
2023-05-04 11:05:46 -04:00
#pragma warning restore 8604
2022-04-27 12:36:35 -04:00
#pragma warning restore 8602
2023-08-17 16:15:06 -04:00
private void MakeFileWriteable ( string InFilePath )
{
System . IO . File . SetAttributes ( InFilePath , System . IO . File . GetAttributes ( InFilePath ) & ~ FileAttributes . ReadOnly ) ;
}
2023-05-04 11:05:46 -04:00
#pragma warning disable 8618
2022-04-27 12:36:35 -04:00
/// <summary>
/// Test metadata class.
/// </summary>
public class Metadata
{
/// <summary>
/// Test long name.
/// </summary>
2023-05-04 11:05:46 -04:00
public string TestName { get ; set ; }
2022-04-27 12:36:35 -04:00
/// <summary>
/// Test short name used for display in build system.
/// </summary>
2023-05-04 11:05:46 -04:00
public string TestShortName { get ; set ; }
2022-04-27 12:36:35 -04:00
2023-06-01 16:57:35 -04:00
private string ReportTypePrivate = "console" ;
2022-04-27 12:36:35 -04:00
/// <summary>
/// Type of Catch2 report, defaults to console.
/// </summary>
2023-06-01 16:57:35 -04:00
public string ReportType {
get = > ReportTypePrivate ;
set = > ReportTypePrivate = value ;
}
2022-04-27 12:36:35 -04:00
2023-06-22 17:41:56 -04:00
/// <summary>
2023-08-10 11:53:46 -04:00
/// Does this test use project files for staging additional files
2023-06-22 17:41:56 -04:00
/// and cause the build to use BuildCookRun instead of a Compile step
/// </summary>
public bool StagesWithProjectFile { get ; set ; }
2022-04-27 12:36:35 -04:00
/// <summary>
/// Is this test disabled?
/// </summary>
2023-05-04 11:05:46 -04:00
public bool Disabled { get ; set ; }
2022-04-27 12:36:35 -04:00
2023-08-10 11:53:46 -04:00
/// <summary>
/// Depercated, use GauntletArgs or ExtraArgs instead to help indicate arguments to launch the test under.
/// </summary>
public string InitialExtraArgs
{
get ;
[Obsolete]
set ;
}
2022-04-27 12:36:35 -04:00
/// <summary>
2023-08-17 16:15:06 -04:00
/// Any initial Gauntlet args to be passed to the test executable
2022-04-27 12:36:35 -04:00
/// </summary>
2023-08-10 11:53:46 -04:00
public string GauntletArgs { get ; set ; }
/// <summary>
/// Any extra args to be passed to the test executable as --extra-args
/// </summary>
public string ExtraArgs { get ; set ; }
2023-05-04 11:05:46 -04:00
/// <summary>
/// Whether there's a step that gets executed after the tests have finished.
/// Typically used for cleanup of resources.
/// </summary>
public bool HasAfterSteps { get ; set ; }
private bool UsesCatch2Private = true ;
/// <summary>
/// Test built with a frakework other than Catch2
/// </summary>
public bool UsesCatch2
2022-04-27 12:36:35 -04:00
{
2023-05-30 18:01:50 -04:00
get = > UsesCatch2Private ;
set = > UsesCatch2Private = value ;
2022-04-27 12:36:35 -04:00
}
2023-08-17 16:15:06 -04:00
/// <summary>
/// Set of supported platforms.
/// </summary>
public HashSet < UnrealTargetPlatform > SupportedPlatforms { get ; set ; } = new HashSet < UnrealTargetPlatform > ( ) { UnrealTargetPlatform . Win64 } ;
2023-05-04 11:05:46 -04:00
private Dictionary < UnrealTargetPlatform , string > PlatformTagsPrivate = new Dictionary < UnrealTargetPlatform , string > ( ) ;
2022-04-27 12:36:35 -04:00
/// <summary>
2023-05-04 11:05:46 -04:00
/// Per-platform tags.
2022-04-27 12:36:35 -04:00
/// </summary>
2023-05-04 11:05:46 -04:00
public Dictionary < UnrealTargetPlatform , string > PlatformTags
2022-04-27 12:36:35 -04:00
{
2023-05-30 18:01:50 -04:00
get = > PlatformTagsPrivate ;
set = > PlatformTagsPrivate = value ;
2022-04-27 12:36:35 -04:00
}
2023-05-04 11:05:46 -04:00
private Dictionary < UnrealTargetPlatform , string > PlatformCompilationExtraArgsPrivate = new Dictionary < UnrealTargetPlatform , string > ( ) ;
2022-04-27 12:36:35 -04:00
/// <summary>
2023-05-04 11:05:46 -04:00
/// Per-platform extra compilation arguments.
2022-04-27 12:36:35 -04:00
/// </summary>
2023-05-04 11:05:46 -04:00
public Dictionary < UnrealTargetPlatform , string > PlatformCompilationExtraArgs
2022-04-27 12:36:35 -04:00
{
2023-05-30 18:01:50 -04:00
get = > PlatformCompilationExtraArgsPrivate ;
set = > PlatformCompilationExtraArgsPrivate = value ;
2023-05-04 11:05:46 -04:00
}
2023-08-17 16:15:06 -04:00
private List < UnrealTargetPlatform > PlatformsRunUnsupportedPrivate = new List < UnrealTargetPlatform > ( ) {
UnrealTargetPlatform . Android ,
UnrealTargetPlatform . IOS ,
UnrealTargetPlatform . TVOS ,
UnrealTargetPlatform . VisionOS } ;
2023-05-04 11:05:46 -04:00
/// <summary>
/// List of platforms that cannot run tests.
/// </summary>
public List < UnrealTargetPlatform > PlatformsRunUnsupported
{
2023-05-30 18:01:50 -04:00
get = > PlatformsRunUnsupportedPrivate ;
set = > PlatformsRunUnsupportedPrivate = value ;
2022-04-27 12:36:35 -04:00
}
2023-09-11 12:55:31 -04:00
private Dictionary < UnrealTargetPlatform , bool > PlatformRunContainerizedPrivate = new Dictionary < UnrealTargetPlatform , bool > ( ) ;
/// <summary>
/// Whether or not the test is run inside a Docker container for a given platform.
/// </summary>
public Dictionary < UnrealTargetPlatform , bool > PlatformRunContainerized
{
2023-12-21 18:50:32 -05:00
get = > PlatformRunContainerizedPrivate ;
set = > PlatformRunContainerizedPrivate = value ;
2023-09-11 12:55:31 -04:00
}
2022-04-27 12:36:35 -04:00
}
2023-05-04 11:05:46 -04:00
#pragma warning restore 8618
2022-01-19 15:00:37 -05:00
}
2022-04-27 12:36:35 -04:00
}