Exemple #1
0
        /// <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);
        }
Exemple #3
0
    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);*/
    }
Exemple #6
0
        /// <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());
            }
        }