/// <summary> /// Entry point for the commandlet /// </summary> public override void ExecuteBuild() { string OutputDir = ParseParamValue("OutputDir"); string ContentOnlyPlatformsString = ParseParamValue("ContentOnlyPlatforms"); IEnumerable <UnrealTargetPlatform> ContentOnlyPlatforms = Enumerable.Empty <UnrealTargetPlatform>(); if (!String.IsNullOrWhiteSpace(ContentOnlyPlatformsString)) { ContentOnlyPlatforms = ContentOnlyPlatformsString.Split(';').Where(x => !String.IsNullOrWhiteSpace(x)).Select(x => UnrealTargetPlatform.Parse(x)); } string AnalyticsTypeOverride = ParseParamValue("AnalyticsTypeOverride"); // Write InstalledBuild.txt to indicate Engine is installed string InstalledBuildFile = CommandUtils.CombinePaths(OutputDir, "Engine/Build/InstalledBuild.txt"); CommandUtils.CreateDirectory(CommandUtils.GetDirectoryName(InstalledBuildFile)); CommandUtils.WriteAllText(InstalledBuildFile, ""); // Write InstalledBuild.txt to indicate Engine is installed string Project = ParseParamValue("Project"); if (Project != null) { string InstalledProjectBuildFile = CommandUtils.CombinePaths(OutputDir, "Engine/Build/InstalledProjectBuild.txt"); CommandUtils.CreateDirectory(CommandUtils.GetDirectoryName(InstalledProjectBuildFile)); CommandUtils.WriteAllText(InstalledProjectBuildFile, new FileReference(Project).MakeRelativeTo(new DirectoryReference(OutputDir))); } string OutputEnginePath = Path.Combine(OutputDir, "Engine"); string OutputBaseEnginePath = Path.Combine(OutputEnginePath, "Config", "BaseEngine.ini"); FileAttributes OutputAttributes = FileAttributes.ReadOnly; List <String> IniLines = new List <String>(); // Should always exist but if not, we don't need extra line if (File.Exists(OutputBaseEnginePath)) { OutputAttributes = File.GetAttributes(OutputBaseEnginePath); IniLines.Add(""); } else { CommandUtils.CreateDirectory(CommandUtils.GetDirectoryName(OutputBaseEnginePath)); CommandUtils.WriteAllText(OutputBaseEnginePath, ""); OutputAttributes = File.GetAttributes(OutputBaseEnginePath) | OutputAttributes; } // Create list of platform configurations installed in a Rocket build List <InstalledPlatformInfo.InstalledPlatformConfiguration> InstalledConfigs = new List <InstalledPlatformInfo.InstalledPlatformConfiguration>(); // Add the editor platform, otherwise we'll never be able to run UAT string EditorArchitecture = PlatformExports.GetDefaultArchitecture(HostPlatform.Current.HostEditorPlatform, null); InstalledConfigs.Add(new InstalledPlatformInfo.InstalledPlatformConfiguration(UnrealTargetConfiguration.Development, HostPlatform.Current.HostEditorPlatform, TargetRules.TargetType.Editor, EditorArchitecture, "", EProjectType.Unknown, false)); InstalledConfigs.Add(new InstalledPlatformInfo.InstalledPlatformConfiguration(UnrealTargetConfiguration.DebugGame, HostPlatform.Current.HostEditorPlatform, TargetRules.TargetType.Editor, EditorArchitecture, "", EProjectType.Unknown, false)); foreach (UnrealTargetPlatform CodeTargetPlatform in UnrealTargetPlatform.GetValidPlatforms()) { if (PlatformExports.IsPlatformAvailable(CodeTargetPlatform)) { string Architecture = PlatformExports.GetDefaultArchitecture(CodeTargetPlatform, null); // Try to parse additional Architectures from the command line string Architectures = ParseParamValue(CodeTargetPlatform.ToString() + "Architectures"); string GPUArchitectures = ParseParamValue(CodeTargetPlatform.ToString() + "GPUArchitectures"); // Build a list of pre-compiled architecture combinations for this platform if any List <string> AllArchNames; if (!String.IsNullOrWhiteSpace(Architectures) && !String.IsNullOrWhiteSpace(GPUArchitectures)) { AllArchNames = (from Arch in Architectures.Split('+') from GPUArch in GPUArchitectures.Split('+') select "-" + Arch + "-" + GPUArch).ToList(); } else if (!String.IsNullOrWhiteSpace(Architectures)) { AllArchNames = Architectures.Split('+').ToList(); } // if there aren't any, use the default else { AllArchNames = new List <string>() { Architecture }; } // Check whether this platform should only be used for content based projects EProjectType ProjectType = ContentOnlyPlatforms.Contains(CodeTargetPlatform) ? EProjectType.Content : EProjectType.Any; // Allow Content only platforms to be shown as options in all projects bool bCanBeDisplayed = ProjectType == EProjectType.Content; foreach (UnrealTargetConfiguration CodeTargetConfiguration in Enum.GetValues(typeof(UnrealTargetConfiguration))) { Dictionary <String, TargetType> Targets = new Dictionary <string, TargetType>() { { "UE4Game", TargetType.Game }, { "UE4Client", TargetType.Client }, { "UE4Server", TargetType.Server } }; foreach (KeyValuePair <string, TargetType> Target in Targets) { string CurrentTargetName = Target.Key; TargetType CurrentTargetType = Target.Value; // Need to check for development receipt as we use that for the Engine code in DebugGame UnrealTargetConfiguration EngineConfiguration = (CodeTargetConfiguration == UnrealTargetConfiguration.DebugGame) ? UnrealTargetConfiguration.Development : CodeTargetConfiguration; // Android has multiple architecture flavors built without receipts, so use the default arch target instead if (CodeTargetPlatform == UnrealTargetPlatform.Android) { FileReference ReceiptFileName = TargetReceipt.GetDefaultPath(new DirectoryReference(OutputEnginePath), CurrentTargetName, CodeTargetPlatform, EngineConfiguration, Architecture); if (FileReference.Exists(ReceiptFileName)) { // Strip the output folder so that this can be used on any machine string RelativeReceiptFileName = ReceiptFileName.MakeRelativeTo(new DirectoryReference(OutputDir)); // Blindly append all of the architecture names if (AllArchNames.Count > 0) { foreach (string Arch in AllArchNames) { InstalledConfigs.Add(new InstalledPlatformInfo.InstalledPlatformConfiguration(CodeTargetConfiguration, CodeTargetPlatform, CurrentTargetType, Arch, RelativeReceiptFileName, ProjectType, bCanBeDisplayed)); } } // if for some reason we didn't specify any flavors, just add the default one. else { InstalledConfigs.Add(new InstalledPlatformInfo.InstalledPlatformConfiguration(CodeTargetConfiguration, CodeTargetPlatform, CurrentTargetType, Architecture, RelativeReceiptFileName, ProjectType, bCanBeDisplayed)); } } } // If we're not Android, check the existence of the target receipts for each architecture specified. else { foreach (string Arch in AllArchNames) { FileReference ReceiptFileName = TargetReceipt.GetDefaultPath(new DirectoryReference(OutputEnginePath), CurrentTargetName, CodeTargetPlatform, EngineConfiguration, Arch); if (FileReference.Exists(ReceiptFileName)) { string RelativeReceiptFileName = ReceiptFileName.MakeRelativeTo(new DirectoryReference(OutputDir)); InstalledConfigs.Add(new InstalledPlatformInfo.InstalledPlatformConfiguration(CodeTargetConfiguration, CodeTargetPlatform, CurrentTargetType, Arch, RelativeReceiptFileName, ProjectType, bCanBeDisplayed)); } } } } } } } UnrealBuildTool.InstalledPlatformInfo.WriteConfigFileEntries(InstalledConfigs, ref IniLines); if (!String.IsNullOrEmpty(AnalyticsTypeOverride)) { // Write Custom Analytics type setting IniLines.Add(""); IniLines.Add("[Analytics]"); IniLines.Add(String.Format("UE4TypeOverride=\"{0}\"", AnalyticsTypeOverride)); } // Make sure we can write to the the config file File.SetAttributes(OutputBaseEnginePath, OutputAttributes & ~FileAttributes.ReadOnly); File.AppendAllLines(OutputBaseEnginePath, IniLines); File.SetAttributes(OutputBaseEnginePath, OutputAttributes); }
/// <summary> /// Execute all tests according to the provided context /// </summary> /// <param name="Context"></param> /// <returns></returns> public ExitCode RunTests(UnrealTestOptions ContextOptions) { if (ContextOptions.Verbose) { Gauntlet.Log.Level = Gauntlet.LogLevel.Verbose; } if (ContextOptions.VeryVerbose) { Gauntlet.Log.Level = Gauntlet.LogLevel.VeryVerbose; } if (ParseParam("log")) { if (!Directory.Exists(ContextOptions.LogDir)) { Directory.CreateDirectory(ContextOptions.LogDir); } // include test names and timestamp in log filename as multiple (parallel or sequential) Gauntlet tests may be outputting to same directory string LogPath = Path.Combine(ContextOptions.LogDir, string.Format("GauntletLog{0}-{1}.txt", ContextOptions.TestList.Aggregate(new StringBuilder(), (SB, T) => SB.AppendFormat("-{0}", T.ToString())).ToString(), DateTime.Now.ToString(@"yyyy.MM.dd.HH.mm.ss"))); Gauntlet.Log.Verbose("Writing Gauntlet log to {0}", LogPath); Gauntlet.Log.SaveToFile(LogPath); } // prune our temp folder Utils.SystemHelpers.CleanupMarkedDirectories(ContextOptions.TempDir, 7); if (string.IsNullOrEmpty(ContextOptions.Build)) { throw new AutomationException("No builds specified. Use -builds=p:\\path\\to\\build"); } if (typeof(UnrealBuildSource).IsAssignableFrom(ContextOptions.BuildSourceType) == false) { throw new AutomationException("Provided BuildSource type does not inherit from UnrealBuildSource"); } // make -test=none implicit if no test is supplied if (ContextOptions.TestList.Count == 0) { Gauntlet.Log.Info("No test specified, using default '{0}'", DefaultTestName); ContextOptions.TestList.Add(TestRequest.CreateRequest(DefaultTestName)); } bool EditorForAllRoles = Globals.Params.ParseParam("editor") || string.Equals(Globals.Params.ParseValue("build", ""), "editor", StringComparison.OrdinalIgnoreCase); if (EditorForAllRoles) { Gauntlet.Log.Verbose("Will use Editor for all roles"); } Dictionary <UnrealTargetRole, UnrealTestRoleContext> RoleContexts = new Dictionary <UnrealTargetRole, UnrealTestRoleContext>(); // Default platform to the current os UnrealTargetPlatform DefaultPlatform = BuildHostPlatform.Current.Platform; UnrealTargetConfiguration DefaultConfiguration = UnrealTargetConfiguration.Development; DirectoryReference UnrealPath = new DirectoryReference(Environment.CurrentDirectory); // todo, pass this in as a BuildSource and remove the COntextOption params specific to finding builds UnrealBuildSource BuildInfo = (UnrealBuildSource)Activator.CreateInstance(ContextOptions.BuildSourceType, new object[] { ContextOptions.Project, ContextOptions.ProjectPath, UnrealPath, ContextOptions.UsesSharedBuildType, ContextOptions.Build, ContextOptions.SearchPaths }); // Setup accounts SetupAccounts(); List <ITestNode> AllTestNodes = new List <ITestNode>(); bool InitializedDevices = false; HashSet <UnrealTargetPlatform> UsedPlatforms = new HashSet <UnrealTargetPlatform>(); // for all platforms we want to test... foreach (ArgumentWithParams PlatformWithParams in ContextOptions.PlatformList) { string PlatformString = PlatformWithParams.Argument; // combine global and platform-specific params Params CombinedParams = new Params(ContextOptions.Params.AllArguments.Concat(PlatformWithParams.AllArguments).ToArray()); UnrealTargetPlatform PlatformType = UnrealTargetPlatform.Parse(PlatformString); if (!InitializedDevices) { // Setup the devices and assign them to the executor SetupDevices(PlatformType, ContextOptions); InitializedDevices = true; } // Create a context for each process type to operate as foreach (UnrealTargetRole Type in Enum.GetValues(typeof(UnrealTargetRole))) { UnrealTestRoleContext Role = new UnrealTestRoleContext(); // Default to these Role.Type = Type; Role.Platform = DefaultPlatform; Role.Configuration = DefaultConfiguration; // globally, what was requested (e.g -platform=PS4 -configuration=Shipping) UnrealTargetPlatform RequestedPlatform = PlatformType; UnrealTargetConfiguration RequestedConfiguration = ContextOptions.Configuration; // look for FooConfiguration, FooPlatform overrides. // e.g. ServerConfiguration, ServerPlatform string PlatformRoleString = Globals.Params.ParseValue(Type.ToString() + "Platform", null); string ConfigString = Globals.Params.ParseValue(Type.ToString() + "Configuration", null); if (string.IsNullOrEmpty(PlatformRoleString) == false) { RequestedPlatform = UnrealTargetPlatform.Parse(PlatformRoleString); } if (string.IsNullOrEmpty(ConfigString) == false) { RequestedConfiguration = (UnrealTargetConfiguration)Enum.Parse(typeof(UnrealTargetConfiguration), ConfigString, true); } // look for -clientargs= and -editorclient etc Role.ExtraArgs = Globals.Params.ParseValue(Type.ToString() + "Args", ""); // look for -clientexeccmds=, -editorexeccmds= etc, these are separate from clientargs for sanity string ExecCmds = Globals.Params.ParseValue(Type.ToString() + "ExecCmds", ""); if (!string.IsNullOrEmpty(ExecCmds)) { Role.ExtraArgs += string.Format(" -ExecCmds=\"{0}\"", ExecCmds); } bool UsesEditor = EditorForAllRoles || Globals.Params.ParseParam("Editor" + Type.ToString()); if (UsesEditor) { Gauntlet.Log.Verbose("Will use Editor for role {0}", Type); } Role.Skip = Globals.Params.ParseParam("Skip" + Type.ToString()); if (Role.Skip) { Gauntlet.Log.Verbose("Will use NullPlatform to skip role {0}", Type); } // TODO - the below is a bit rigid, but maybe that's good enough since the "actually use the editor.." option // is specific to clients and servers // client can override platform and config if (Type.IsClient()) { Role.Platform = RequestedPlatform; Role.Configuration = RequestedConfiguration; if (UsesEditor) { Role.Type = UnrealTargetRole.EditorGame; Role.Platform = DefaultPlatform; Role.Configuration = UnrealTargetConfiguration.Development; } } else if (Type.IsServer()) { // server can only override config Role.Configuration = RequestedConfiguration; if (UsesEditor) { Role.Type = UnrealTargetRole.EditorServer; Role.Platform = DefaultPlatform; Role.Configuration = UnrealTargetConfiguration.Development; } } Gauntlet.Log.Verbose("Mapped Role {0} to RoleContext {1}", Type, Role); RoleContexts[Type] = Role; UsedPlatforms.Add(Role.Platform); } UnrealTestContext Context = new UnrealTestContext(BuildInfo, RoleContexts, ContextOptions); IEnumerable <ITestNode> TestNodes = CreateTestList(Context, CombinedParams, PlatformWithParams); AllTestNodes.AddRange(TestNodes); } bool AllTestsPassed = ExecuteTests(ContextOptions, AllTestNodes); // dispose now, not during shutdown gc, because this runs commands... DevicePool.Instance.Dispose(); DoCleanup(UsedPlatforms); return(AllTestsPassed ? ExitCode.Success : ExitCode.Error_TestFailure); }
public override void ExecuteBuild() { CommandUtils.LogInformation("************************* List Third Party Software"); string ProjectPath = ParseParamValue("Project", String.Empty); //Add quotes to avoid issues with spaces in project path if (ProjectPath != String.Empty) { ProjectPath = "\"" + ProjectPath + "\""; } // Parse the list of targets to list TPS for. Each target is specified by -Target="Name|Configuration|Platform" on the command line. HashSet <FileReference> TpsFiles = new HashSet <FileReference>(); foreach (string Target in ParseParamValues(Params, "Target")) { // Get the path to store the exported JSON target data FileReference OutputFile = FileReference.Combine(CommandUtils.EngineDirectory, "Intermediate", "Build", "ThirdParty.json"); IProcessResult Result; Result = Run(UE4Build.GetUBTExecutable(), String.Format("{0} {1} -Mode=JsonExport -OutputFile=\"{2}\"", Target.Replace('|', ' '), ProjectPath, OutputFile.FullName), Options: ERunOptions.Default); if (Result.ExitCode != 0) { throw new AutomationException("Failed to run UBT"); } // Read the exported target info back in JsonObject Object = JsonObject.Read(OutputFile); // Get the project file if there is one FileReference ProjectFile = null; string ProjectFileName; if (Object.TryGetStringField("ProjectFile", out ProjectFileName)) { ProjectFile = new FileReference(ProjectFileName); } // Get the default paths to search HashSet <DirectoryReference> DirectoriesToScan = new HashSet <DirectoryReference>(); DirectoriesToScan.Add(DirectoryReference.Combine(CommandUtils.EngineDirectory, "Shaders")); DirectoriesToScan.Add(DirectoryReference.Combine(CommandUtils.EngineDirectory, "Content")); if (ProjectFile != null) { DirectoriesToScan.Add(DirectoryReference.Combine(ProjectFile.Directory, "Content")); } // Add all the paths for each module, and its runtime dependencies JsonObject Modules = Object.GetObjectField("Modules"); foreach (string ModuleName in Modules.KeyNames) { JsonObject Module = Modules.GetObjectField(ModuleName); DirectoriesToScan.Add(new DirectoryReference(Module.GetStringField("Directory"))); foreach (JsonObject RuntimeDependency in Module.GetObjectArrayField("RuntimeDependencies")) { string RuntimeDependencyPath; if (RuntimeDependency.TryGetStringField("SourcePath", out RuntimeDependencyPath) || RuntimeDependency.TryGetStringField("Path", out RuntimeDependencyPath)) { List <FileReference> Files = FileFilter.ResolveWildcard(DirectoryReference.Combine(CommandUtils.EngineDirectory, "Source"), RuntimeDependencyPath); DirectoriesToScan.UnionWith(Files.Select(x => x.Directory)); } } } // Remove any directories that are under other directories, and sort the output list List <DirectoryReference> SortedDirectoriesToScan = new List <DirectoryReference>(); foreach (DirectoryReference DirectoryToScan in DirectoriesToScan.OrderBy(x => x.FullName)) { if (SortedDirectoriesToScan.Count == 0 || !DirectoryToScan.IsUnderDirectory(SortedDirectoriesToScan[SortedDirectoriesToScan.Count - 1])) { SortedDirectoriesToScan.Add(DirectoryToScan); } } // Get the platforms to exclude List <UnrealTargetPlatform> SupportedPlatforms = new List <UnrealTargetPlatform> { UnrealTargetPlatform.Parse(Object.GetStringField("Platform")) }; string[] ExcludePlatformNames = Utils.MakeListOfUnsupportedPlatforms(SupportedPlatforms).ToArray(); // Find all the TPS files under the engine directory which match foreach (DirectoryReference DirectoryToScan in SortedDirectoriesToScan) { foreach (FileReference TpsFile in DirectoryReference.EnumerateFiles(DirectoryToScan, "*.tps", SearchOption.AllDirectories)) { if (!TpsFile.ContainsAnyNames(ExcludePlatformNames, DirectoryToScan)) { TpsFiles.Add(TpsFile); } } } } // Also add any redirects List <string> OutputMessages = new List <string>(); foreach (FileReference TpsFile in TpsFiles) { string Message = TpsFile.FullName; try { string[] Lines = FileReference.ReadAllLines(TpsFile); foreach (string Line in Lines) { const string RedirectPrefix = "Redirect:"; int Idx = Line.IndexOf(RedirectPrefix, StringComparison.InvariantCultureIgnoreCase); if (Idx >= 0) { FileReference RedirectTpsFile = FileReference.Combine(TpsFile.Directory, Line.Substring(Idx + RedirectPrefix.Length).Trim()); Message = String.Format("{0} (redirect from {1})", RedirectTpsFile.FullName, TpsFile.FullName); break; } } } catch (Exception Ex) { ExceptionUtils.AddContext(Ex, "while processing {0}", TpsFile); throw; } OutputMessages.Add(Message); } OutputMessages.Sort(); // Print them all out foreach (string OutputMessage in OutputMessages) { CommandUtils.LogInformation(OutputMessage); } }
/// <summary> /// Create the list of tests specified by the context. /// </summary> /// <param name="Context"></param> /// <returns></returns> IEnumerable <ITestNode> CreateTestList(UnrealTestContext Context, Params DefaultParams, ArgumentWithParams PlatformParams = null) { List <ITestNode> NodeList = new List <ITestNode>(); IEnumerable <string> Namespaces = Context.Options.Namespaces.Split(',').Select(S => S.Trim()); List <string> BuildIssues = new List <string>(); UnrealTargetPlatform UnrealPlatform = UnrealTargetPlatform.Parse(PlatformParams.Argument); //List<string> Platforms = Globals.Params.ParseValue("platform") // Create an instance of each test and add it to the executor foreach (var Test in Context.Options.TestList) { // create a copy of the context for this test UnrealTestContext TestContext = (UnrealTestContext)Context.Clone(); // if test specifies platforms, filter for this context if (Test.Platforms.Count() > 0 && Test.Platforms.Where(Plat => Plat.Argument == PlatformParams.Argument).Count() == 0) { continue; } if (Blacklist.Instance.IsTestBlacklisted(Test.TestName, UnrealPlatform, TestContext.BuildInfo.Branch)) { Gauntlet.Log.Info("Test {0} is currently blacklisted on {1} in branch {2}", Test.TestName, UnrealPlatform, TestContext.BuildInfo.Branch); continue; } // combine global and test-specific params Params CombinedParams = new Params(DefaultParams.AllArguments.Concat(Test.TestParams.AllArguments).ToArray()); // parse any target constraints List <string> PerfSpecArgs = CombinedParams.ParseValues("PerfSpec", false); string PerfSpecArg = PerfSpecArgs.Count > 0 ? PerfSpecArgs.Last() : "Unspecified"; EPerfSpec PerfSpec; if (!Enum.TryParse <EPerfSpec>(PerfSpecArg, true, out PerfSpec)) { throw new AutomationException("Unable to convert perfspec '{0}' into an EPerfSpec", PerfSpec); } // parse hardware model List <string> ModelArgs = CombinedParams.ParseValues("PerfModel", false); string Model = ModelArgs.Count > 0 ? ModelArgs.Last() : string.Empty; TestContext.Constraint = new UnrealTargetConstraint(UnrealPlatform, PerfSpec, Model); // parse worker job id List <string> WorkerJobIDArgs = CombinedParams.ParseValues("WorkerJobID", false); TestContext.WorkerJobID = WorkerJobIDArgs.Count > 0 ? WorkerJobIDArgs.Last() : null; TestContext.TestParams = CombinedParams; // This will throw if the test cannot be created ITestNode NewTest = Utils.TestConstructor.ConstructTest <ITestNode, UnrealTestContext>(Test.TestName, TestContext, Namespaces); NodeList.Add(NewTest); } return(NodeList); }
public override void ExecuteBuild() { LogInformation("************************* CopySharedCookedBuild"); // Parse the project filename (as a local path) string CmdLinePlatform = ParseParamValue("Platform", null); bool bOnlyCopyAssetRegistry = ParseParam("onlycopyassetregistry"); string SharedBuildCL = ParseParamValue("buildcl", "any"); SharedCookedBuild.SharedCookType BuildType = (SharedCookedBuild.SharedCookType)Enum.Parse(typeof(SharedCookedBuild.SharedCookType), SharedBuildCL, true); List <UnrealTargetPlatform> TargetPlatforms = new List <UnrealTargetPlatform>(); var PlatformNames = new List <string>(CmdLinePlatform.Split('+')); foreach (var PlatformName in PlatformNames) { // Look for dependent platforms, Source_1.Dependent_1+Source_2.Dependent_2+Standalone_3 var SubPlatformNames = new List <string>(PlatformName.Split('.')); foreach (var SubPlatformName in SubPlatformNames) { TargetPlatforms.Add(UnrealTargetPlatform.Parse(SubPlatformName)); } } new SharedCookedBuild(ProjectFile, TargetPlatforms.Select(x => x.ToString()), BuildType).CopySharedCookedBuilds(); /* * // Build the list of paths that need syncing * List<string> SyncPaths = new List<string>(); * if(bIsProjectFile) * { * SyncPaths.Add(CommandUtils.CombinePaths(PathSeparator.Slash, BranchRoot, "*")); * SyncPaths.Add(CommandUtils.CombinePaths(PathSeparator.Slash, BranchRoot, "Engine", "...")); * SyncPaths.Add(CommandUtils.CombinePaths(PathSeparator.Slash, CommandUtils.GetDirectoryName(ProjectFileRecord.DepotFile), "...")); * } * else * { * SyncPaths.Add(CommandUtils.CombinePaths(PathSeparator.Slash, CommandUtils.GetDirectoryName(ProjectFileRecord.DepotFile), "...")); * } * * // Sync them down * foreach(string SyncPath in SyncPaths) * { * Log("Syncing {0}@{1}", SyncPath, CL); * P4.Sync(String.Format("{0}@{1}", SyncPath, CL)); * } * * // Get the name of the editor target * string EditorTargetName = "UE4Editor"; * if(bIsProjectFile) * { * string SourceDirectoryName = Path.Combine(Path.GetDirectoryName(ProjectFileName), "Source"); * if(Directory.Exists(SourceDirectoryName)) * { * foreach(string EditorTargetFileName in Directory.EnumerateFiles(SourceDirectoryName, "*Editor.Target.cs")) * { * EditorTargetName = Path.GetFileNameWithoutExtension(Path.GetFileNameWithoutExtension(EditorTargetFileName)); * break; * } * } * } * * // Build everything * UnrealTargetPlatform CurrentPlatform = HostPlatform.Current.HostEditorPlatform; * * UE4Build.BuildAgenda Agenda = new UE4Build.BuildAgenda(); * Agenda.AddTarget("UnrealHeaderTool", CurrentPlatform, UnrealTargetConfiguration.Development); * Agenda.AddTarget(EditorTargetName, CurrentPlatform, UnrealTargetConfiguration.Development, ProjectFileName.EndsWith(".uproject", StringComparison.InvariantCultureIgnoreCase)? new FileReference(ProjectFileName) : null); * Agenda.AddTarget("ShaderCompileWorker", CurrentPlatform, UnrealTargetConfiguration.Development); * Agenda.AddTarget("UnrealLightmass", CurrentPlatform, UnrealTargetConfiguration.Development); * Agenda.AddTarget("CrashReportClient", CurrentPlatform, UnrealTargetConfiguration.Shipping); * * UE4Build Build = new UE4Build(this); * Build.UpdateVersionFiles(ActuallyUpdateVersionFiles: true, ChangelistNumberOverride: CL); * Build.Build(Agenda, InUpdateVersionFiles: false);*/ }
/// <summary> /// Reserve devices from service /// </summary> public bool ReserveDevicesFromService(string DeviceURL, Dictionary <UnrealTargetConstraint, int> DeviceTypes) { if (String.IsNullOrEmpty(DeviceURL)) { return(false); } Dictionary <UnrealTargetPlatform, string> DeviceMap = new Dictionary <UnrealTargetPlatform, string>(); foreach (string Platform in UnrealTargetPlatform.GetValidPlatformNames()) { if (Platform == "PS4" || Platform == "XboxOne") { DeviceMap.Add(UnrealTargetPlatform.Parse(Platform), string.Format("{0}-DevKit", Platform)); } else { DeviceMap.Add(UnrealTargetPlatform.Parse(Platform), Platform); } } List <string> Devices = new List <string>(); // convert devices to request list foreach (KeyValuePair <UnrealTargetConstraint, int> Entry in DeviceTypes) { if (Entry.Key.Platform == null) { continue; } if (!DeviceMap.ContainsKey(Entry.Key.Platform.Value)) { // if an unsupported device, we can't reserve it Log.Info("Unable to reserve service device of type: {0}", Entry.Key); return(false); } if (!string.IsNullOrEmpty(Entry.Key.Model)) { // if specific device model, we can't currently reserve it from (legacy) service if (DeviceURL.ToLower().Contains("deviceservice.epicgames.net")) { Log.Info("Unable to reserve service device of model: {0} on legacy service", Entry.Key.Model); return(false); } } for (int i = 0; i < Entry.Value; i++) { // @todo: if any additional reservation requirements, encode constraint into json string Constraint = Entry.Key.PerfSpec.ToString(); if (!string.IsNullOrEmpty(Entry.Key.Model)) { Constraint = Entry.Key.Model; } Devices.Add(DeviceMap[Entry.Key.Platform.Value] + ":" + Constraint); } } // reserve devices Uri ReservationServerUri; if (Uri.TryCreate(DeviceURL, UriKind.Absolute, out ReservationServerUri)) { DeviceReservationAutoRenew DeviceReservation = null; string PoolID = Globals.WorkerPoolID != -1 ? Globals.WorkerPoolID.ToString() : ""; try { DeviceReservation = new DeviceReservationAutoRenew(DeviceURL, 0, PoolID, Devices.ToArray()); } catch (Exception Ex) { Log.Info("Unable to make device registration: {0}", Ex.Message); return(false); } if (DeviceReservation == null || DeviceReservation.Devices.Count != Devices.Count()) { return(false); } // Add target devices from reservation List <ITargetDevice> ReservedDevices = new List <ITargetDevice>(); foreach (var Device in DeviceReservation.Devices) { DeviceDefinition Def = new DeviceDefinition(); Def.Address = Device.IPOrHostName; Def.Name = Device.Name; Def.Platform = DeviceMap.FirstOrDefault(Entry => Entry.Value == Device.Type).Key; Def.DeviceData = Device.DeviceData; Def.Model = string.Empty; if (!String.IsNullOrEmpty(Device.PerfSpec) && !Enum.TryParse <EPerfSpec>(Device.PerfSpec, true, out Def.PerfSpec)) { throw new AutomationException("Unable to convert perfspec '{0}' into an EPerfSpec", Device.PerfSpec); } ITargetDevice TargetDevice = CreateAndRegisterDeviceFromDefinition(Def); // If a device from service can't be added, fail reservation and cleanup devices // @todo: device problem reporting, requesting additional devices if (TargetDevice == null) { ReportDeviceError(Device.Name, "CreateDeviceError"); // If some devices from reservation have been created, release them which will also dispose of reservation if (ReservedDevices.Count > 0) { ReleaseDevices(ReservedDevices); } else { // otherwise, no devices have been creation so just cancel this reservation DeviceReservation.Dispose(); } Log.Info("Unable to make device registration: device registration failed for {0}:{1}", Def.Platform, Def.Name); return(false); } else { ReservedDevices.Add(TargetDevice); } ServiceDeviceInfo[TargetDevice] = Def; ServiceReservations[TargetDevice] = DeviceReservation; } Log.Info("Successfully reserved service devices"); Devices.ForEach(Device => Log.Verbose(" Device: {0}", Device)); return(true); } Log.Info("Unable to reserve service devices:"); Devices.ForEach(Device => Log.Info(" Device: {0}", Device)); return(false); }
public override ExitCode Execute() { Log.Level = Gauntlet.LogLevel.VeryVerbose; AutoParam.ApplyParamsAndDefaults(this, Environment.GetCommandLineArgs()); // Fix up any pathing issues (some implementations don't like backslashes i.e. xbox) Project = Project.Replace(@"\", "/"); Path = Path.Replace(@"\", "/"); UnrealTargetPlatform ParsedPlatform = UnrealTargetPlatform.Parse(Platform); UnrealTargetConfiguration ParseConfiguration = (UnrealTargetConfiguration)Enum.Parse(typeof(UnrealTargetConfiguration), Configuration, true); DevicePool.Instance.AddDevices(ParsedPlatform, Devices, false); // Find sources for this platform (note some platforms have multiple sources for staged builds, packaged builds etc) IEnumerable <IFolderBuildSource> BuildSources = Gauntlet.Utils.InterfaceHelpers.FindImplementations <IFolderBuildSource>().Where(S => S.CanSupportPlatform(ParsedPlatform)); // Find all builds at the specified path IBuild Build = BuildSources.SelectMany(S => S.GetBuildsAtPath(Project, Path)).FirstOrDefault(); if (Build == null) { throw new AutomationException("No builds for platform {0} found at {1}", Platform, Path); } UnrealAppConfig Config = new UnrealAppConfig(); Config.Build = Build; Config.ProjectName = Project; Config.Configuration = ParseConfiguration; Config.CommandLine = Commandline; List <ITargetDevice> AcquiredDevices = new List <ITargetDevice>(); /* This seems redundant but it's the only way to grab the devices at this stage * Todo: This will only pass in devices that are powered on, find a way to grab off devices and power them on */ DevicePool.Instance.EnumerateDevices(new UnrealTargetConstraint(ParsedPlatform), Device => { if (!AcquiredDevices.Contains(Device)) { AcquiredDevices.Add(Device); } return(false); }); if (AcquiredDevices.Count == 0) { Log.Error("Failed to find any valid devices!"); return(ExitCode.Error_AppInstallFailed); } Log.Info("Beginning Installation!"); // Reserve our devices so nothing else can use them DevicePool.Instance.ReserveDevices(AcquiredDevices); foreach (ITargetDevice Device in AcquiredDevices) { if (!Device.IsAvailable) { Log.Info("{0} is not available, skipping", Device.Name); continue; } if (!Device.IsOn) { Log.Info("Powering on {0}", Device); Device.PowerOn(); } else if (Globals.Params.ParseParam("reboot")) { Log.Info("Rebooting {0}", Device); Device.Reboot(); } if (!Device.Connect()) { Log.Warning("Failed to connect to {0}", Device.Name); continue; } Log.Info("Installing {0} to {1}", Config.Build.ToString(), Device.Name); try { Device.InstallApplication(Config); } catch (AutomationException error) { Log.Error("Failed to install to {0} due to: {1}", Device.Name, error.ToString()); } Log.Info("Disconnecting from {0}", Device.Name); Device.Disconnect(); } // Release our saved devices DevicePool.Instance.ReleaseDevices(AcquiredDevices); return(ExitCode.Success); }
/// <summary> /// Parse an argument containing a list of platforms /// </summary> /// <param name="Name">Name of the argument</param> /// <returns>List of platforms</returns> List <UnrealTargetPlatform> ParsePlatformsParamValue(string Name) { string PlatformsString = ParseParamValue(Name); if (String.IsNullOrWhiteSpace(PlatformsString)) { return(new List <UnrealTargetPlatform>()); } else { return(PlatformsString.Split(new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries).Select(x => UnrealTargetPlatform.Parse(x)).ToList()); } }