You've already forked UnrealEngineUWP
mirror of
https://github.com/izzy2lost/UnrealEngineUWP.git
synced 2026-03-26 18:15:20 -07:00
Allow cooked editor to run in cooked for in gauntlet and uncooked form. Switch to using the -cookedEditor commandline argument for game specific cooked editor. Adjusted parameters to allow the game to override exes to look for and name their module type #preflight: 620df1e0f44e27e076620baf [REVIEW] [at]Andrew.Grant [at]Jerome.Delattre [at]Chris.Constantinescu #ROBOMERGE-AUTHOR: eric.knapik #ROBOMERGE-SOURCE: CL 19035750 via CL 19037678 via CL 19038828 via CL 19039124 via CL 19039805 #ROBOMERGE-BOT: UE5 (Release-Engine-Staging -> Main) (v918-19018356) [CL 19040295 by eric knapik in ue5-main branch]
267 lines
7.5 KiB
C#
267 lines
7.5 KiB
C#
// Copyright Epic Games, Inc. All Rights Reserved.
|
|
|
|
using AutomationTool;
|
|
using EpicGame;
|
|
using Gauntlet;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.IO;
|
|
using System.Linq;
|
|
using System.Text.RegularExpressions;
|
|
|
|
namespace UE
|
|
{
|
|
/// <summary>
|
|
/// Test that waits for the client and server to get to the front-end then quits
|
|
/// </summary>
|
|
public class BootTest : UnrealTestNode<UnrealTestConfiguration>
|
|
{
|
|
/// <summary>
|
|
/// Used to track progress via logging
|
|
/// </summary>
|
|
int LogLinesLastTick = 0;
|
|
|
|
/// <summary>
|
|
/// Time we last saw a change in logging
|
|
/// </summary>
|
|
DateTime LastLogTime = DateTime.Now;
|
|
|
|
/// <summary>
|
|
/// Set to true once we detect the game has launched correctly
|
|
/// </summary>
|
|
bool DidDetectLaunch = false;
|
|
|
|
/// <summary>
|
|
/// Default constructor
|
|
/// </summary>
|
|
/// <param name="InContext"></param>
|
|
public BootTest(Gauntlet.UnrealTestContext InContext)
|
|
: base(InContext)
|
|
{
|
|
}
|
|
|
|
/// <summary>
|
|
/// Returns the configuration description for this test
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public override UnrealTestConfiguration GetConfiguration()
|
|
{
|
|
UnrealTestConfiguration Config = base.GetConfiguration();
|
|
|
|
UnrealTestRole Client = Config.RequireRole(UnrealTargetRole.Client);
|
|
|
|
return Config;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Called to begin the test.
|
|
/// </summary>
|
|
/// <param name="Pass"></param>
|
|
/// <param name="InNumPasses"></param>
|
|
/// <returns></returns>
|
|
public override bool StartTest(int Pass, int InNumPasses)
|
|
{
|
|
// Call the base class to actually start the test running
|
|
if (!base.StartTest(Pass, InNumPasses))
|
|
{
|
|
return false;
|
|
}
|
|
|
|
// track our starting condition
|
|
LastLogTime = DateTime.Now;
|
|
LogLinesLastTick = 0;
|
|
DidDetectLaunch = true;
|
|
|
|
return true;
|
|
}
|
|
|
|
/// <summary>
|
|
/// String that we search for to be considered "Booted"
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
protected virtual string GetCompletionString()
|
|
{
|
|
return "Engine is initialized. Leaving FEngineLoop::Init()";
|
|
}
|
|
|
|
/// <summary>
|
|
/// Called periodically while the test is running to allow code to monitor health.
|
|
/// </summary>
|
|
public override void TickTest()
|
|
{
|
|
const int kTimeOutDuration = 10;
|
|
|
|
// run the base class tick;
|
|
base.TickTest();
|
|
|
|
// Get the log of the first client app
|
|
IAppInstance RunningInstance = this.TestInstance.RunningRoles.First().AppInstance;
|
|
|
|
UnrealLogParser LogParser = new UnrealLogParser(RunningInstance.StdOut);
|
|
|
|
IEnumerable<string> BusyLogLines = LogParser.GetEditorBusyChannels();
|
|
int BusyLineCount = BusyLogLines.Count();
|
|
|
|
if (BusyLineCount > LogLinesLastTick)
|
|
{
|
|
LastLogTime = DateTime.Now;
|
|
// log new entries so people have something to look at
|
|
BusyLogLines.Skip(LogLinesLastTick).ToList().ForEach(S => Log.Info("{0}", S));
|
|
LogLinesLastTick = BusyLineCount;
|
|
}
|
|
|
|
// Gauntlet will timeout tests based on the -timeout argument, but we have greater insight here so can bail earlier to save
|
|
// tests from idling on the farm needlessly.
|
|
if ((DateTime.Now - LastLogTime).TotalMinutes > kTimeOutDuration)
|
|
{
|
|
Log.Error("No logfile activity observed in last {0} minutes. Ending test", kTimeOutDuration);
|
|
MarkTestComplete();
|
|
SetUnrealTestResult(TestResult.TimedOut);
|
|
}
|
|
|
|
// now see if the game has brought the first world up for play
|
|
IEnumerable<string> LogWorldLines = LogParser.GetLogChannel("World");
|
|
|
|
string CompletionString = GetCompletionString();
|
|
|
|
if (!string.IsNullOrEmpty(CompletionString))
|
|
{
|
|
if (LogParser.Content.IndexOf(CompletionString, StringComparison.OrdinalIgnoreCase) > 0)
|
|
{
|
|
Log.Info("Found '{0}'. Ending Test", GetCompletionString());
|
|
MarkTestComplete();
|
|
DidDetectLaunch = true;
|
|
SetUnrealTestResult(TestResult.Passed);
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Called after a test finishes to create an overall summary based on looking at the artifacts
|
|
/// </summary>
|
|
/// <param name="Result"></param>
|
|
/// <returns>ITestReport</returns>
|
|
/// <param name="Build"></param>
|
|
/// <param name="Artifacts"></param>
|
|
/// <param name="InArtifactPath"></param>
|
|
public override ITestReport CreateReport(TestResult Result, UnrealTestContext Context, UnrealBuildSource Build, IEnumerable<UnrealRoleResult> InResults, string InArtifactPath)
|
|
{
|
|
if (Result == TestResult.Passed)
|
|
{
|
|
if (!DidDetectLaunch)
|
|
{
|
|
ReportError("Failed to detect completion of launch");
|
|
}
|
|
else
|
|
{
|
|
// find a logfile or something that indicates the process ran successsfully
|
|
bool MissingFiles = false;
|
|
|
|
foreach (var RoleResult in InResults)
|
|
{
|
|
DirectoryInfo RoleDir = new DirectoryInfo(RoleResult.Artifacts.ArtifactPath);
|
|
|
|
IEnumerable<FileInfo> ArtifactFiles = RoleDir.EnumerateFiles("*.*", SearchOption.AllDirectories);
|
|
|
|
// user may not have cleared paths between runs, so throw away anything that's older than 2m
|
|
ArtifactFiles = ArtifactFiles.Where(F => (DateTime.Now - F.LastWriteTime).TotalMinutes < 2);
|
|
|
|
if (ArtifactFiles.Any() == false)
|
|
{
|
|
MissingFiles = true;
|
|
ReportError("No artifact files found for {0}. Were they not retrieved from the device?", RoleResult.Artifacts.SessionRole);
|
|
}
|
|
|
|
IEnumerable<FileInfo> LogFiles = ArtifactFiles.Where(F => F.Extension.Equals(".log", StringComparison.OrdinalIgnoreCase));
|
|
|
|
if (LogFiles.Any() == false)
|
|
{
|
|
MissingFiles = true;
|
|
ReportError("No log files found for {0}. Were they not retrieved from the device?", RoleResult.Artifacts.SessionRole);
|
|
}
|
|
}
|
|
|
|
if (MissingFiles)
|
|
{
|
|
SetUnrealTestResult(TestResult.Failed);
|
|
ReportError("One or more roles did not generated any artifacts");
|
|
}
|
|
|
|
Log.Info("Found valid artifacts for test");
|
|
}
|
|
}
|
|
|
|
return base.CreateReport(GetTestResult());
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Test that verifies the editor boots
|
|
/// </summary>
|
|
public class EditorBootTest : BootTest
|
|
{
|
|
public EditorBootTest(Gauntlet.UnrealTestContext InContext)
|
|
: base(InContext)
|
|
{
|
|
}
|
|
|
|
/// <summary>
|
|
/// Returns the configuration description for this test
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public override UnrealTestConfiguration GetConfiguration()
|
|
{
|
|
UnrealTestConfiguration Config = base.GetConfiguration();
|
|
// currently needed as BootTest isn't an abstract class. Can be changed for 4.27
|
|
Config.ClearRoles();
|
|
UnrealTestRole EditorRole = Config.RequireRole(UnrealTargetRole.Editor);
|
|
EditorRole.CommandLineParams.Add("execcmds", "QUIT_EDITOR");
|
|
return Config;
|
|
}
|
|
|
|
protected override string GetCompletionString()
|
|
{
|
|
return null;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Test that verifies a target boots
|
|
/// </summary>
|
|
public class TargetBootTest : BootTest
|
|
{
|
|
public TargetBootTest(Gauntlet.UnrealTestContext InContext)
|
|
: base(InContext)
|
|
{
|
|
}
|
|
|
|
/// <summary>
|
|
/// Returns the configuration description for this test
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public override UnrealTestConfiguration GetConfiguration()
|
|
{
|
|
UnrealTestConfiguration Config = base.GetConfiguration();
|
|
Config.RequireRole(UnrealTargetRole.Client);
|
|
return Config;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Provided for backwards compatibility with scripts
|
|
namespace Gauntlet.UnrealTest
|
|
{
|
|
class BootTest : UE.BootTest
|
|
{
|
|
/// <summary>
|
|
/// Default constructor
|
|
/// </summary>
|
|
/// <param name="InContext"></param>
|
|
public BootTest(Gauntlet.UnrealTestContext InContext)
|
|
: base(InContext)
|
|
{
|
|
Log.Warning("Gauntlet.UnrealTest.BootTest is deprecated and will be removed in 4.27. Use UE.BootTest. All arguments are the same");
|
|
}
|
|
}
|
|
}
|