Esempio n. 1
0
        public async Task LaunchNoDebugLegacyFlowAsync([Values(false, true)] bool renderdoc,
                                                       [Values(false, true)] bool rgp,
                                                       [Values(null, "optprintasserts")]
                                                       string vulkanDriverVariant)
        {
            _project.GetLaunchRenderDocAsync().Returns(renderdoc);
            _project.GetLaunchRgpAsync().Returns(rgp);
            _project.GetVulkanDriverVariantAsync().Returns(vulkanDriverVariant);

            var gamelets = new List <Gamelet>
            {
                new Gamelet
                {
                    Id     = _testGameletId,
                    Name   = _testGameletName,
                    IpAddr = _testGameletIp,
                    State  = GameletState.Reserved,
                }
            };

            _gameletClient.ListGameletsAsync().Returns(Task.FromResult(gamelets));

            _gameletSelector.TrySelectAndPrepareGamelet(Arg.Any <string>(),
                                                        Arg.Any <DeployOnLaunchSetting>(), gamelets,
                                                        Arg.Any <TestAccount>(), Arg.Any <string>(),
                                                        out Gamelet _).Returns(x =>
            {
                x[_outVariableIndex] = gamelets[0];
                return(true);
            });

            var launchSettings = await QueryDebugTargetsAsync(DebugLaunchOptions.NoDebug);

            Assert.AreEqual(1, launchSettings.Count);
            Assert.AreEqual(DebugLaunchOptions.NoDebug | DebugLaunchOptions.MergeEnvironment,
                            launchSettings[0].LaunchOptions);
            Assert.AreEqual(_testProjectDir, launchSettings[0].CurrentDirectory);
            Assert.AreEqual(Environment.SystemDirectory + "\\cmd.exe",
                            launchSettings[0].Executable);

            _launchCommandFormatter.Parse(launchSettings[0].Arguments,
                                          out LaunchParams launchParams, out _);
            Assert.AreEqual(await _project.GetTargetFileNameAsync(), launchParams.Cmd);
            Assert.AreEqual(renderdoc, launchParams.RenderDoc);
            Assert.AreEqual(rgp, launchParams.Rgp);
            Assert.AreEqual(_testApplicationName, launchParams.ApplicationName);
            Assert.AreEqual(_testGameletName, launchParams.GameletName);
            Assert.AreEqual(_testAccount, launchParams.Account);
            Assert.IsFalse(launchParams.Debug);
            Assert.AreEqual(_sdkVersionString, launchParams.SdkVersion);
            Assert.AreEqual(launchParams.VulkanDriverVariant, vulkanDriverVariant);
            Assert.AreEqual(launchParams.QueryParams, _customQueryParams);

            await _remoteDeploy.Received().DeployGameExecutableAsync(
                _project, new SshTarget(gamelets[0]), Arg.Any <ICancelable>(), Arg.Any <IAction>());

            AssertMetricRecorded(DeveloperEventType.Types.Type.VsiDebugSetupQueries,
                                 DeveloperEventStatus.Types.Code.Success);
            AssertMetricRecorded(DeveloperEventType.Types.Type.VsiDeployBinary,
                                 DeveloperEventStatus.Types.Code.Success);
        }
        public async Task <IReadOnlyList <IDebugLaunchSettings> > QueryDebugTargetsAsync(
            IAsyncProject project, DebugLaunchOptions launchOptions)
        {
            try
            {
                // Make sure we can find the target executable.
                var targetPath = await project.GetTargetPathAsync();

                if (!_fileSystem.File.Exists(targetPath))
                {
                    Trace.WriteLine($"Unable to find target executable: {targetPath}");
                    _dialogUtil.ShowError(ErrorStrings.UnableToFindTargetExecutable(targetPath));
                    return(new IDebugLaunchSettings[] { });
                }

                _metrics.UseNewDebugSessionId();
                var actionRecorder = new ActionRecorder(_metrics);

                var targetFileName = await project.GetTargetFileNameAsync();

                var gameletCommand = (targetFileName + " " +
                                      await project.GetGameletLaunchArgumentsAsync()).Trim();

                var launchParams = new LaunchParams()
                {
                    Cmd       = gameletCommand,
                    RenderDoc = await project.GetLaunchRenderDocAsync(),
                    Rgp       = await project.GetLaunchRgpAsync(),
                    SurfaceEnforcementMode = await project.GetSurfaceEnforcementAsync(),
                    VulkanDriverVariant    = await project.GetVulkanDriverVariantAsync(),
                    QueryParams            = await project.GetQueryParamsAsync(),
                    Endpoint = await project.GetEndpointAsync()
                };

                if (_sdkVersion != null && !string.IsNullOrEmpty(_sdkVersion.ToString()))
                {
                    launchParams.SdkVersion = _sdkVersion.ToString();
                }

                if (!TrySetupQueries(project, actionRecorder,
                                     out SetupQueriesResult setupQueriesResult))
                {
                    return(new IDebugLaunchSettings[] { });
                }

                launchParams.ApplicationName = setupQueriesResult.Application.Name;
                launchParams.ApplicationId   = setupQueriesResult.Application.Id;
                if (setupQueriesResult.TestAccount != null)
                {
                    launchParams.TestAccount          = setupQueriesResult.TestAccount.Name;
                    launchParams.TestAccountGamerName =
                        setupQueriesResult.TestAccount.GamerStadiaName;
                }

                DeployOnLaunchSetting deployOnLaunchAsync = await project.GetDeployOnLaunchAsync();

                launchParams.Account = _credentialManager.LoadAccount();

                // TODO: Enable PlayerEndpoint Launches for non-internal usage in VS.
                if (launchParams.Endpoint == StadiaEndpoint.PlayerEndpoint &&
                    launchParams.Account != null &&
                    !launchParams.Account.EndsWith("@sparklingsunset.com") &&
                    !launchParams.Account.EndsWith("@subtlesunset.com"))
                {
                    throw new NotImplementedException(
                              "Player Endpoints are not yet supported, please select " +
                              "Test Client in the Project Properties instead.");
                }

                // TODO: Enable launch on any endpoint for external accounts.
                if (launchParams.Endpoint == StadiaEndpoint.AnyEndpoint &&
                    launchParams.Account != null &&
                    !launchParams.Account.EndsWith("@sparklingsunset.com") &&
                    !launchParams.Account.EndsWith("@subtlesunset.com"))
                {
                    throw new NotImplementedException(
                              "Launch on any player endpoint is not supported yet, please select " +
                              "another endpoint in the Project Properties instead.");
                }

                bool launchGameApiEnabled =
                    _yetiVsiService.Options.LaunchGameApiFlow == LaunchGameApiFlow.ENABLED;
                IGameletSelector gameletSelector =
                    _gameletSelectorFactory.Create(launchGameApiEnabled, actionRecorder);
                if (!gameletSelector.TrySelectAndPrepareGamelet(
                        targetPath, deployOnLaunchAsync, setupQueriesResult.Gamelets,
                        setupQueriesResult.TestAccount, launchParams.Account, out Gamelet gamelet))
                {
                    return(new IDebugLaunchSettings[] { });
                }

                launchParams.GameletName            = gamelet.Name;
                launchParams.PoolId                 = gamelet.PoolId;
                launchParams.GameletSdkVersion      = gamelet.GameletVersions.DevToolingVersion;
                launchParams.GameletEnvironmentVars =
                    await project.GetGameletEnvironmentVariablesAsync();

                // Prepare for debug launch using these settings.
                var debugLaunchSettings = new DebugLaunchSettings(launchOptions);
                debugLaunchSettings.Environment["PATH"] = await project.GetExecutablePathAsync();

                debugLaunchSettings.LaunchOperation  = DebugLaunchOperation.CreateProcess;
                debugLaunchSettings.CurrentDirectory = await project.GetAbsoluteRootPathAsync();

                if (!launchOptions.HasFlag(DebugLaunchOptions.NoDebug))
                {
                    var parameters = _paramsFactory.Create();
                    parameters.TargetIp         = new SshTarget(gamelet).GetString();
                    parameters.DebugSessionId   = _metrics.DebugSessionId;
                    debugLaunchSettings.Options = _paramsFactory.Serialize(parameters);
                }

                IAction action     = actionRecorder.CreateToolAction(ActionType.RemoteDeploy);
                bool    isDeployed = _cancelableTaskFactory.Create(
                    TaskMessages.DeployingExecutable, async task =>
                {
                    await _remoteDeploy.DeployGameExecutableAsync(
                        project, new SshTarget(gamelet), task, action);
                    task.Progress.Report(TaskMessages.CustomDeployCommand);
                    await _remoteDeploy.ExecuteCustomCommandAsync(project, gamelet, action);
                }).RunAndRecord(action);

                if (!isDeployed)
                {
                    return(new IDebugLaunchSettings[] { });
                }

                if (launchOptions.HasFlag(DebugLaunchOptions.NoDebug))
                {
                    if (_gameLauncher.LaunchGameApiEnabled ||
                        launchParams.Endpoint == StadiaEndpoint.PlayerEndpoint ||
                        launchParams.Endpoint == StadiaEndpoint.AnyEndpoint)
                    {
                        IVsiGameLaunch launch = _gameLauncher.CreateLaunch(launchParams);
                        if (launch != null)
                        {
                            debugLaunchSettings.Arguments =
                                _launchCommandFormatter.CreateWithLaunchName(
                                    launchParams, launch.LaunchName);
                        }
                        else
                        {
                            Trace.WriteLine("Unable to retrieve launch name from the launch api.");
                            return(new IDebugLaunchSettings[] { });
                        }
                    }
                    else
                    {
                        debugLaunchSettings.Arguments =
                            _launchCommandFormatter.CreateFromParams(launchParams);
                    }

                    debugLaunchSettings.Executable =
                        Path.Combine(Environment.SystemDirectory, YetiConstants.Command);

                    debugLaunchSettings.LaunchOptions = DebugLaunchOptions.NoDebug |
                                                        DebugLaunchOptions.MergeEnvironment;
                }
                else
                {
                    if (_yetiVsiService.DebuggerOptions[DebuggerOption.SKIP_WAIT_LAUNCH] ==
                        DebuggerOptionState.DISABLED)
                    {
                        launchParams.Debug = true;
                    }

                    // TODO: This should really be the game_client executable, since
                    // the args we pass are for game_client as well.  We just need to find another
                    // way to pass the game executable.
                    debugLaunchSettings.Executable            = targetPath;
                    debugLaunchSettings.LaunchDebugEngineGuid = YetiConstants.DebugEngineGuid;
                    debugLaunchSettings.Arguments             =
                        _launchCommandFormatter.EncodeLaunchParams(launchParams);
                    debugLaunchSettings.LaunchOptions = DebugLaunchOptions.MergeEnvironment;
                }

                return(new IDebugLaunchSettings[] { debugLaunchSettings });
            }
            catch (Exception e)
            {
                Trace.WriteLine(e.ToString());
                _dialogUtil.ShowError(e.Message, e.ToString());
                return(new IDebugLaunchSettings[] { });
            }
        }