示例#1
0
        public bool CanSupportRole(UnrealSessionRole Role, ref List <string> Reasons)
        {
            if (Role.RoleType.UsesEditor() && UnrealPath == null)
            {
                Reasons.Add(string.Format("Role {0} wants editor but no path to Unreal exists", Role));
                return(false);
            }

            // null platform. Need a better way of specifying this
            if (Role.IsNullRole())
            {
                return(true);
            }

            // Query our build list
            if (Role.Platform != null)
            {
                var MatchingBuilds = GetMatchingBuilds(Role.RoleType, Role.Platform.Value, Role.Configuration, Role.RequiredBuildFlags);

                if (MatchingBuilds.Count() > 0)
                {
                    return(true);
                }
            }

            Reasons.Add(string.Format("No build at {0} that matches {1}", string.Join(",", BuildPaths), Role.ToString()));

            return(false);
        }
示例#2
0
 /// <summary>
 /// Constructor, all values must be provided
 /// </summary>
 /// <param name="InSessionRole"></param>
 /// <param name="InAppInstance"></param>
 /// <param name="InArtifactPath"></param>
 /// <param name="InLogSummary"></param>
 public UnrealRoleArtifacts(UnrealSessionRole InSessionRole, IAppInstance InAppInstance, string InArtifactPath, string InLogPath, UnrealLogParser InLog)
 {
     SessionRole  = InSessionRole;
     AppInstance  = InAppInstance;
     ArtifactPath = InArtifactPath;
     LogPath      = InLogPath;
     LogParser    = InLog;
 }
        /// <summary>
        /// Apply our options to the provided app config
        /// </summary>
        /// <param name="AppConfig"></param>
        /// <returns></returns>
        public virtual void ApplyToConfig(UnrealAppConfig AppConfig, UnrealSessionRole ConfigRole, IEnumerable <UnrealSessionRole> OtherRoles)
        {
            if (AppConfig.ProcessType.IsClient())
            {
                if (Nullrhi)
                {
                    AppConfig.CommandLine += " -nullrhi";
                }
                else
                {
                    if (AppConfig.Platform == UnrealTargetPlatform.Win64 || AppConfig.Platform == UnrealTargetPlatform.Mac)
                    {
                        if (!IgnoreDefaultResolutionAndWindowMode)
                        {
                            if (Globals.Params.ToString().Contains("-resx") == false)
                            {
                                AppConfig.CommandLine += String.Format(" -ResX={0} -ResY={1}", ResX, ResY);
                            }
                            if (WindowMode == EWindowMode.Windowed || Windowed)
                            {
                                AppConfig.CommandLine += " -windowed";
                            }
                            else if (WindowMode == EWindowMode.Fullscreen)
                            {
                                AppConfig.CommandLine += " -fullscreen";
                            }
                            else if (WindowMode == EWindowMode.WindowedFullscreen)                             // Proper -windowedfullscreen flag does not exist and some platforms treat both modes as the same.
                            {
                                AppConfig.CommandLine += " -fullscreen";
                            }
                            else
                            {
                                Log.Warning("Test config uses an unsupported WindowMode: {0}! WindowMode not set.", Enum.GetName(typeof(EWindowMode), WindowMode));
                            }
                        }
                    }

                    if (ScreenshotPeriod > 0 && Nullrhi == false)
                    {
                        AppConfig.CommandLine += string.Format(" -gauntlet.screenshotperiod={0}", ScreenshotPeriod);
                    }
                }
            }

            // use -log on servers so we get a window..
            if (AppConfig.ProcessType.IsServer())
            {
                AppConfig.CommandLine += " -log";
            }

            if (Attended == false)
            {
                AppConfig.CommandLine += " -unattended";
            }

            AppConfig.CommandLine += " -stdout -AllowStdOutLogVerbosity";
        }
示例#4
0
        /// <summary>
        /// Installs and launches all of our roles and returns an UnrealSessonInstance that represents the aggregate
        /// of all of these processes. Will perform retries if errors with devices are encountered so this is a "best
        /// attempt" at running with the devices provided
        /// </summary>
        /// <returns></returns>
        public UnrealSessionInstance LaunchSession()
        {
            SessionInstance = null;

            // tries to find devices and launch our session. Will loop until we succeed, we run out of devices/retries, or
            // something fatal occurs..
            while (SessionInstance == null && Globals.CancelSignalled == false)
            {
                int Retries   = 5;
                int RetryWait = 120;

                IEnumerable <UnrealSessionRole> RolesNeedingDevices = SessionRoles.Where(R => R.IsNullRole() == false);

                while (ReservedDevices.Count() < RolesNeedingDevices.Count())
                {
                    // get devices
                    TryReserveDevices();

                    if (Globals.CancelSignalled)
                    {
                        break;
                    }

                    // if we failed to get enough devices, show a message and wait
                    if (ReservedDevices.Count() != SessionRoles.Count())
                    {
                        if (Retries == 0)
                        {
                            throw new AutomationException("Unable to acquire all devices for test.");
                        }
                        Log.Info("\nUnable to find enough device(s). Waiting {0} secs (retries left={1})\n", RetryWait, --Retries);
                        Thread.Sleep(RetryWait * 1000);
                    }
                }

                if (Globals.CancelSignalled)
                {
                    return(null);
                }

                Dictionary <IAppInstall, UnrealSessionRole> InstallsToRoles = new Dictionary <IAppInstall, UnrealSessionRole>();

                // create a copy of our list
                IEnumerable <ITargetDevice> DevicesToInstallOn = ReservedDevices.ToArray();

                bool InstallSuccess = true;


#if !__MonoCS__
                // count how many desktop clients
                IEnumerable <UnrealSessionRole> DesktopClients = SessionRoles.Where(R => R.Platform == BuildHostPlatform.Current.Platform).Where(R => R.RoleType.IsClient());

                if (DesktopClients.Count() > 1)
                {
                    int NumClientRows = (int)Math.Ceiling(DesktopClients.Count() / 2.0);

                    var ScreenRect = System.Windows.Forms.Screen.PrimaryScreen.Bounds;

                    double Ratio = 16.0 / 9.0;

                    // pick width
                    int DesiredWidth = ScreenRect.Width / 2;

                    // height at 16:9 aspect
                    int DesiredHeight = (int)(DesiredWidth / Ratio);

                    // constrain width if the screen can't have that many rows
                    if (DesiredHeight * NumClientRows > ScreenRect.Height)
                    {
                        DesiredHeight = ScreenRect.Height / NumClientRows;
                        DesiredWidth  = (int)(DesiredHeight * Ratio);
                    }

                    // now set all these params and disable the regular params that pick windowed stuff
                    for (int i = 0; i < DesktopClients.Count(); i++)
                    {
                        UnrealSessionRole Role = DesktopClients.ElementAt(i);
                        int Row    = i / 2;
                        int Column = i - (Row * 2);

                        // this is hacky, but not sure if a better way to do it right now without changing interfaces in a TBD way
                        UnrealTestConfiguration ConfigOptions = Role.Options as UnrealTestConfiguration;

                        if (ConfigOptions != null)
                        {
                            ConfigOptions.IgnoreDefaultResolutionAndWindowMode = true;
                        }

                        Role.CommandLine += string.Format(" -WinX={0} -WinY={1} -ResX={2} -ResY={3} -windowed",
                                                          Column * DesiredWidth, Row * DesiredHeight, DesiredWidth, DesiredHeight);
                    }
                }
#endif

                // sort by constraints, so that we pick constrained devices first
                List <UnrealSessionRole> SortedRoles = SessionRoles.OrderBy(R => R.Constraint.IsIdentity() ? 1 : 0).ToList();

                // first install all roles on these devices
                foreach (var Role in SortedRoles)
                {
                    ITargetDevice Device = null;

                    if (Role.IsNullRole() == false)
                    {
                        Device = DevicesToInstallOn.Where(D => D.IsConnected && D.Platform == Role.Platform &&
                                                          (Role.Constraint.IsIdentity() || DevicePool.Instance.GetConstraint(D) == Role.Constraint)).First();

                        DevicesToInstallOn = DevicesToInstallOn.Where(D => D != Device);
                    }
                    else
                    {
                        Device = new TargetDeviceNull(string.Format("Null{0}", Role.RoleType));
                    }

                    var OtherRoles = SortedRoles.Where(R => R != Role);

                    // create a config from the build source (this also applies the role options)
                    UnrealAppConfig AppConfig = BuildSource.CreateConfiguration(Role, OtherRoles);

                    // todo - should this be elsewhere?
                    AppConfig.Sandbox = Sandbox;

                    IAppInstall Install = null;

                    try
                    {
                        Install = Device.InstallApplication(AppConfig);
                    }
                    catch (System.Exception Ex)
                    {
                        // Warn, ignore the device, and do not continue
                        Log.Info("Failed to install app onto device {0} for role {1}. {2}. Will retry with new device", Device, Role, Ex);
                        MarkProblemDevice(Device);
                        InstallSuccess = false;
                        break;
                    }

                    if (Globals.CancelSignalled)
                    {
                        break;
                    }

                    // Device has app installed, give role a chance to configure device
                    Role.ConfigureDevice?.Invoke(Device);

                    InstallsToRoles[Install] = Role;
                }

                if (InstallSuccess == false)
                {
                    // release all devices
                    ReleaseDevices();
                }


                if (InstallSuccess && Globals.CancelSignalled == false)
                {
                    List <UnrealSessionInstance.RoleInstance> RunningRoles = new List <UnrealSessionInstance.RoleInstance>();

                    // Now try to run all installs on their devices
                    foreach (var InstallRoleKV in InstallsToRoles)
                    {
                        IAppInstall CurrentInstall = InstallRoleKV.Key;

                        bool Success = false;

                        try
                        {
                            IAppInstance Instance = CurrentInstall.Run();

                            if (Instance != null || Globals.CancelSignalled)
                            {
                                RunningRoles.Add(new UnrealSessionInstance.RoleInstance(InstallRoleKV.Value, Instance));
                            }

                            Success = true;
                        }
                        catch (DeviceException Ex)
                        {
                            // shutdown all
                            Log.Warning("Device {0} threw an exception during launch. \nException={1}", CurrentInstall.Device, Ex.Message);
                            Success = false;
                        }

                        if (Success == false)
                        {
                            Log.Warning("Failed to start build on {0}. Marking as problem device and retrying with new set", CurrentInstall.Device);

                            // terminate anything that's running
                            foreach (UnrealSessionInstance.RoleInstance RunningRole in RunningRoles)
                            {
                                Log.Info("Shutting down {0}", RunningRole.AppInstance.Device);
                                RunningRole.AppInstance.Kill();
                                RunningRole.AppInstance.Device.Disconnect();
                            }

                            // mark that device as a problem
                            MarkProblemDevice(CurrentInstall.Device);

                            // release all devices
                            ReleaseDevices();

                            break;                             // do not continue loop
                        }
                    }

                    if (RunningRoles.Count() == SessionRoles.Count())
                    {
                        SessionInstance = new UnrealSessionInstance(RunningRoles.ToArray());
                    }
                }
            }

            return(SessionInstance);
        }
示例#5
0
 public RoleInstance(UnrealSessionRole InRole, IAppInstance InInstance)
 {
     Role        = InRole;
     AppInstance = InInstance;
 }
示例#6
0
        virtual public UnrealAppConfig CreateConfiguration(UnrealSessionRole Role, IEnumerable <UnrealSessionRole> OtherRoles)
        {
            List <string> Issues = new List <string>();

            Log.Verbose("Creating configuration Role {0}", Role);
            if (!CanSupportRole(Role, ref Issues))
            {
                Issues.ForEach(S => Log.Error(S));
                return(null);
            }

            UnrealAppConfig Config = new UnrealAppConfig();

            Config.Name          = this.BuildName;
            Config.ProjectName   = ProjectName;
            Config.ProcessType   = Role.RoleType;
            Config.Platform      = Role.Platform;
            Config.Configuration = Role.Configuration;
            Config.CommandLine   = "";
            Config.FilesToCopy   = new List <UnrealFileToCopy>();

            // new system of retrieving and encapsulating the info needed to install/launch. Android & Mac
            Config.Build = GetMatchingBuilds(Role.RoleType, Role.Platform, Role.Configuration, Role.RequiredBuildFlags).FirstOrDefault();

            if (Config.Build == null && Role.IsNullRole() == false)
            {
                var SupportedBuilds = String.Join("\n", DiscoveredBuilds.Select(B => B.ToString()));

                Log.Info("Available builds:\n{0}", SupportedBuilds);
                throw new AutomationException("No build found that can support a role of {0}.", Role);
            }

            if (Role.Options != null)
            {
                UnrealTestConfiguration ConfigOptions = Role.Options as UnrealTestConfiguration;
                ConfigOptions.ApplyToConfig(Config, Role, OtherRoles);
            }

            if (string.IsNullOrEmpty(Role.CommandLine) == false)
            {
                Config.CommandLine += " " + Role.CommandLine;
            }

            // Cleanup the commandline
            Config.CommandLine = GenerateProcessedCommandLine(Config.CommandLine);

            // Now add the project (the above code doesn't handle arguments without a leading - so do this last
            bool IsContentOnlyProject = (Config.Build.Flags & BuildFlags.ContentOnlyProject) == BuildFlags.ContentOnlyProject;

            // Add in editor - TODO, should this be in the editor build?
            if (Role.RoleType.UsesEditor() || IsContentOnlyProject)
            {
                // add in -game or -server
                if (Role.RoleType.IsClient())
                {
                    Config.CommandLine = "-game " + Config.CommandLine;
                }
                else if (Role.RoleType.IsServer())
                {
                    Config.CommandLine = "-server " + Config.CommandLine;
                }

                string ProjectParam = ProjectPath.FullName;

                // if content only we need to provide a relative path to the uproject.
                if (IsContentOnlyProject && !Role.RoleType.UsesEditor())
                {
                    ProjectParam = string.Format("../../../{0}/{0}.uproject", ProjectName);
                }

                // project must be first
                Config.CommandLine = String.Format("\"{0}\"", ProjectParam) + " " + Config.CommandLine;
            }

            if (Role.FilesToCopy != null)
            {
                Config.FilesToCopy = Role.FilesToCopy;
            }

            return(Config);
        }
示例#7
0
 virtual public UnrealAppConfig CreateConfiguration(UnrealSessionRole Role)
 {
     return(CreateConfiguration(Role, new UnrealSessionRole[] { }));
 }
示例#8
0
        protected bool PrepareUnrealApp()
        {
            // Get our configuration
            TConfigClass Config = GetConfiguration();

            if (Config == null)
            {
                throw new AutomationException("Test {0} returned null config!", this);
            }

            if (UnrealApp != null)
            {
                throw new AutomationException("Node already has an UnrealApp, was PrepareUnrealSession called twice?");
            }

            // pass through any arguments such as -TestNameArg or -TestNameArg=Value
            var TestName  = this.GetType().Name;
            var ShortName = TestName.Replace("Test", "");

            var PassThroughArgs = Context.TestParams.AllArguments
                                  .Where(A => A.StartsWith(TestName, System.StringComparison.OrdinalIgnoreCase) || A.StartsWith(ShortName, System.StringComparison.OrdinalIgnoreCase))
                                  .Select(A =>
            {
                A = "-" + A;

                var EqIndex = A.IndexOf("=");

                // no =? Just a -switch then
                if (EqIndex == -1)
                {
                    return(A);
                }

                var Cmd  = A.Substring(0, EqIndex + 1);
                var Args = A.Substring(EqIndex + 1);

                // if no space in the args, just leave it
                if (Args.IndexOf(" ") == -1)
                {
                    return(A);
                }

                return(string.Format("{0}\"{1}\"", Cmd, Args));
            });

            List <UnrealSessionRole> SessionRoles = new List <UnrealSessionRole>();

            // Go through each type of role that was required and create a session role
            foreach (var TypesToRoles in Config.RequiredRoles)
            {
                // get the actual context of what this role means.
                UnrealTestRoleContext RoleContext = Context.GetRoleContext(TypesToRoles.Key);

                foreach (UnrealTestRole TestRole in TypesToRoles.Value)
                {
                    // important, use the type from the ContextRolke because Server may have been mapped to EditorServer etc
                    UnrealTargetPlatform SessionPlatform = TestRole.PlatformOverride != UnrealTargetPlatform.Unknown ? TestRole.PlatformOverride : RoleContext.Platform;

                    UnrealSessionRole SessionRole = new UnrealSessionRole(RoleContext.Type, SessionPlatform, RoleContext.Configuration, TestRole.CommandLine);

                    SessionRole.RoleModifier = TestRole.RoleType;
                    SessionRole.Constraint   = TestRole.Type == UnrealTargetRole.Client ? Context.Constraint : new UnrealTargetConstraint(SessionPlatform);

                    Log.Verbose("Created SessionRole {0} from RoleContext {1} (RoleType={2})", SessionRole, RoleContext, TypesToRoles.Key);

                    // TODO - this can all / mostly go into UnrealTestConfiguration.ApplyToConfig

                    // Deal with command lines
                    if (string.IsNullOrEmpty(TestRole.ExplicitClientCommandLine) == false)
                    {
                        SessionRole.CommandLine = TestRole.ExplicitClientCommandLine;
                    }
                    else
                    {
                        // start with anything from our context
                        SessionRole.CommandLine = RoleContext.ExtraArgs;

                        // did the test ask for anything?
                        if (string.IsNullOrEmpty(TestRole.CommandLine) == false)
                        {
                            SessionRole.CommandLine += " " + TestRole.CommandLine;
                        }

                        // add controllers
                        if (TestRole.Controllers.Count > 0)
                        {
                            SessionRole.CommandLine += string.Format(" -gauntlet=\"{0}\"", string.Join(",", TestRole.Controllers));
                        }

                        if (PassThroughArgs.Count() > 0)
                        {
                            SessionRole.CommandLine += " " + string.Join(" ", PassThroughArgs);
                        }

                        // add options
                        SessionRole.Options = Config;
                    }

                    if (RoleContext.Skip)
                    {
                        SessionRole.RoleModifier = ERoleModifier.Null;
                    }

                    SessionRole.FilesToCopy = TestRole.FilesToCopy;

                    SessionRoles.Add(SessionRole);
                }
            }

            UnrealApp = new UnrealSession(Context.BuildInfo, SessionRoles)
            {
                Sandbox = Context.Options.Sandbox
            };

            return(true);
        }