Last active
May 20, 2024 21:10
-
-
Save hach-que/8a736c37bc6a17e10a2a039f4b228467 to your computer and use it in GitHub Desktop.
Scripts to use Gauntlet in Unreal Engine 4 (UE4) - this is for testing a plugin in a host demo project
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
call "GetMSBuildPath.bat" | |
cd ../../ | |
%MSBUILD_EXE% /nologo /verbosity:quiet Source\Programs\AutomationTool\Gauntlet\Gauntlet.Automation.csproj /property:Configuration=Development /property:Platform=AnyCPU |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
param() | |
$ErrorActionPreference = "Stop" | |
if ($env:CI_COMMIT_BRANCH -eq $null) { | |
Write-Output "Not running on GitLab - skipping build." | |
return | |
} | |
$ProjectRoot = (Resolve-Path -Path $PSScriptRoot\..).Path | |
$UE4_VERSION = $env:CI_COMMIT_BRANCH.Substring($env:CI_COMMIT_BRANCH.Length-2, 2) | |
$SDK_ROOT = "C:\Program Files (x86)\Android\android-sdk" | |
$env:PATH = "$env:PATH;$SDK_ROOT\tools\bin;$SDK_ROOT\emulator;$SDK_ROOT\platform-tools" | |
if ($env:CI_JOB_ID -ne $null) { | |
# Really running on GitLab, always do a fresh clone of the Demo project. | |
if (Test-Path $ProjectRoot\Demo) { | |
Remove-Item -Force -Recurse $ProjectRoot\Demo | |
} | |
} | |
if (!(Test-Path $ProjectRoot\Demo)) { | |
git clone --branch $env:CI_COMMIT_BRANCH https://github.com/RedpointGames/RSIDemo "$ProjectRoot\Demo" | |
if ($LASTEXITCODE -ne 0) { | |
exit $LASTEXITCODE | |
} | |
} | |
else { | |
Push-Location "$ProjectRoot\Demo" | |
try { | |
git fetch --all | |
if ($LASTEXITCODE -ne 0) { | |
exit $LASTEXITCODE | |
} | |
git checkout -f origin/$env:CI_COMMIT_BRANCH | |
if ($LASTEXITCODE -ne 0) { | |
exit $LASTEXITCODE | |
} | |
} finally { | |
Pop-Location | |
} | |
} | |
# Add our test to Gauntlet so we can run it. | |
Set-Content -Force -Path "C:\Program Files\Epic Games\UE_4.$UE4_VERSION\Engine\Source\Programs\AutomationTool\Gauntlet\Unreal\Game\ReplicatedSublevelInstancesTest.cs" -Value @" | |
using System; | |
using System.Collections.Generic; | |
using System.Linq; | |
using System.Text; | |
using System.Threading.Tasks; | |
using AutomationTool; | |
using UnrealBuildTool; | |
using Gauntlet; | |
using System.IO; | |
using System.IO.Compression; | |
namespace UE4Game | |
{ | |
public class ReplicatedSublevelInstancesTest : UnrealTestNode<UE4TestConfig> | |
{ | |
public ReplicatedSublevelInstancesTest(UnrealTestContext InContext) : base(InContext) | |
{ | |
} | |
public override UE4TestConfig GetConfiguration() | |
{ | |
UE4TestConfig Config = base.GetConfiguration(); | |
// Create four Win64 roles, with one as the listen server. | |
List<UnrealTestRole> Roles = Config.RequireRoles(UnrealTargetRole.Client, UnrealTargetPlatform.Win64, 4).ToList(); | |
var ServerRole = Roles[0]; | |
var ClientRole1 = Roles[1]; | |
var ClientRole2 = Roles[2]; | |
var ClientRole3 = Roles[3]; | |
// The -testrsiserver and -testrsiclient flags below are custom flags that are detected in blueprints | |
// with the "Has Launch Option" node. This allows the game to activate special testing logic when it's | |
// launched through Gauntlet. | |
// | |
// For Gauntlet tests, you need to make sure all of the created roles exit normally before MaxDuration | |
// is elapsed. | |
// Set up the listen server. | |
ServerRole.MapOverride = "/Game/DemoWorld?listen"; | |
ServerRole.CommandLine += " -testrsiserver"; | |
// Set up the clients. | |
ClientRole1.MapOverride = "127.0.0.1:7777"; | |
ClientRole1.CommandLine += " -testrsiclient"; | |
ClientRole2.MapOverride = "127.0.0.1:7777"; | |
ClientRole2.CommandLine += " -testrsiclient"; | |
ClientRole3.MapOverride = "127.0.0.1:7777"; | |
ClientRole3.CommandLine += " -testrsiclient"; | |
// Launch an Android device as a client as well. | |
// todo: We currently need to find a suitable Android N device. | |
//UnrealTestRole AndroidRole = Config.RequireRole(UnrealTargetRole.Client, UnrealTargetPlatform.Android); | |
//AndroidRole.MapOverride = "<todo find IP>"; | |
//AndroidRole.CommandLine += " -testrsiclient"; | |
// 1 minute (60 seconds) | |
Config.MaxDuration = 60; | |
return Config; | |
} | |
} | |
} | |
"@ | |
$GauntletProjectPath = "C:\Program Files\Epic Games\UE_4.$UE4_VERSION\Engine\Source\Programs\AutomationTool\Gauntlet\Gauntlet.Automation.csproj" | |
if (Test-Path $GauntletProjectPath) { | |
$GauntletProject = Get-Content -Raw -Path $GauntletProjectPath | |
if (!$GauntletProject.Contains("ReplicatedSublevelInstancesTest.cs")) { | |
$GauntletProject = $GauntletProject.Replace( | |
"<Compile Include=`"Unreal\Game\Samples\ElementalDemoTest.cs`" />", | |
"<Compile Include=`"Unreal\Game\Samples\ElementalDemoTest.cs`" /><Compile Include=`"Unreal\Game\ReplicatedSublevelInstancesTest.cs`" />" | |
) | |
Set-Content -Force -Path $GauntletProjectPath -Value $GauntletProject | |
} | |
} | |
# We need to patch a file in Gauntlet, because it's not designed to handle listen servers, which require the presence of a ? character | |
# in the command line. By default, Gauntlet will replace ? characters with spaces. | |
$GauntletUnrealBuildSourcePath = "C:\Program Files\Epic Games\UE_4.$UE4_VERSION\Engine\Source\Programs\AutomationTool\Gauntlet\Unreal\BuildSource\Gauntlet.UnrealBuildSource.cs" | |
if (Test-Path $GauntletUnrealBuildSourcePath) { | |
$GauntletUnrealBuildSource = Get-Content -Raw -Path $GauntletUnrealBuildSourcePath | |
$Old = 'MatchCollection Matches = Regex.Matches(InCommandLine, "(?<option>\\-?[\\w\\d.:\\[\\]\\/\\\\]+)(=(?<value>(\"([^\"]*)\")|(\\S+)))?");' | |
$New = 'MatchCollection Matches = Regex.Matches(InCommandLine, "(?<option>\\-?[\\w\\d.:\\[\\]\\/\\\\\\?]+)(=(?<value>(\"([^\"]*)\")|(\\S+)))?");' | |
if (!$GauntletUnrealBuildSource.Contains($New)) { | |
$GauntletUnrealBuildSource = $GauntletUnrealBuildSource.Replace($Old, $New) | |
Set-Content -Force -Path $GauntletUnrealBuildSourcePath -Value $GauntletUnrealBuildSource | |
} | |
} | |
if (!(Test-Path $ProjectRoot\Demo\Plugins)) { | |
New-Item -ItemType Directory -Path $ProjectRoot\Demo\Plugins | |
} | |
if (Test-Path $ProjectRoot\Demo\Plugins\ReplicatedSublevelInstances) { | |
Remove-Item -Force -Recurse $ProjectRoot\Demo\Plugins\ReplicatedSublevelInstances | |
} | |
Copy-Item -Force -Recurse $ProjectRoot\Packaged $ProjectRoot\Demo\Plugins\ReplicatedSublevelInstances | |
# Open the firewall to allow mobile devices to connect to the listen server. | |
netsh advfirewall firewall add rule name="Unreal Engine Game" dir=in action=allow protocol=UDP localport=7777 | |
Push-Location "C:\Program Files\Epic Games\UE_4.$UE4_VERSION\Engine\Build\BatchFiles" | |
try { | |
# | |
# For Windows targets, the staging directory *MUST* be prefixed with "Windows", otherwise Gauntlet won't find them. By default | |
# both Win32 and Win64 builds share the same directory (WindowsNoEditor), so we override each here. | |
# | |
Write-Output "Building for Win32 ... " | |
.\runuat.bat BuildCookRun -project="$ProjectRoot\Demo\RSIDemo.uproject" -targetplatform=Win32 -target=Game -clientconfig=Development -build -cook -allmaps -stage -pak -rocket -stagingdirectory="$ProjectRoot\Demo\Saved\StagedBuilds\Windows_Win32" | |
if ($LASTEXITCODE -ne 0) { | |
exit $LASTEXITCODE | |
} | |
Write-Output "Building for Win64 ... " | |
.\runuat.bat BuildCookRun -project="$ProjectRoot\Demo\RSIDemo.uproject" -targetplatform=Win64 -target=Game -clientconfig=Development -build -cook -allmaps -stage -pak -rocket -stagingdirectory="$ProjectRoot\Demo\Saved\StagedBuilds\Windows_Win64" | |
if ($LASTEXITCODE -ne 0) { | |
exit $LASTEXITCODE | |
} | |
# | |
# For Android targets, Gauntlet requires the batch files to *NOT* contain "armv7", so we do a little post-build work to rename them into | |
# something that Gauntlet will accept (see below). | |
# | |
Write-Output "Building for Android ... " | |
.\runuat.bat BuildCookRun -project="$ProjectRoot\Demo\RSIDemo.uproject" -targetplatform=Android -target=Game -clientconfig=Development -build -cook -cookflavor=Multi -allmaps -stage -pak -package -rocket | |
if ($LASTEXITCODE -ne 0) { | |
exit $LASTEXITCODE | |
} | |
Move-Item -Force "$ProjectRoot\Demo\Binaries\Android\Install_RSIDemo-armv7-es2.bat" "$ProjectRoot\Demo\Binaries\Android\Install_RSIDemoClient-arm.bat" | |
Move-Item -Force "$ProjectRoot\Demo\Binaries\Android\Uninstall_RSIDemo-armv7-es2.bat" "$ProjectRoot\Demo\Binaries\Android\Uninstall_RSIDemoClient-arm.bat" | |
Move-Item -Force "$ProjectRoot\Demo\Binaries\Android\RSIDemo-armv7-es2.apk" "$ProjectRoot\Demo\Binaries\Android\RSIDemoClient-arm.apk" | |
# If you need to put the Android device into TCP/IP mode so that it can be connected to over the network: | |
# | |
# adb -s 43000d8eb244a04b tcpip 5555 | |
# adb connect android-test.agent.build.redpoint.games:5555 | |
# | |
# You can only use device IDs or IPv4 addresses in the Address field for Android devices, so here we resolve | |
# the DNS name in Powershell first. | |
Write-Host "Writing device list..." | |
$AndroidDevice = (Resolve-DnsName -Name "android-test.agent.build.redpoint.games" -Type "A")[0].IPAddress | |
Set-Content -Force -Path $ProjectRoot\BuildScripts\DeviceList.json -Value @" | |
[ | |
{ | |
"Name": "Win64", | |
"Address": "default", | |
"Platform": { "Name": "Win64" } | |
}, | |
{ | |
"Name": "Win32", | |
"Address": "default", | |
"Platform": { "Name": "Win32" } | |
}, | |
{ | |
"Name": "Android", | |
"Address": "${AndroidDevice}:5555", | |
"Platform": { "Name": "Android" } | |
} | |
] | |
"@ | |
Write-Output "Running Gauntlet automation test ..." | |
& $ProjectRoot\BuildScripts\ForceRebuildUAT.bat | |
.\runuat.bat RunUnreal -project="$ProjectRoot\Demo\RSIDemo.uproject" -platform=Win64 -configuration=Development -build=local -test=ReplicatedSublevelInstancesTest -devices="$ProjectRoot\BuildScripts\DeviceList.json" | |
if ($LASTEXITCODE -ne 0) { | |
exit $LASTEXITCODE | |
} | |
exit 0 | |
} finally { | |
Pop-Location | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment