List <ProcessListEntry> GetProcessList(IProcessListRequest request) { // TODO: Use single cancelable task for both actions try { var enableSshAction = _actionRecorder.CreateToolAction(ActionType.GameletEnableSsh); if (!_cancelableTaskFactory .Create(TaskMessages.EnablingSSH, async _ => await _sshManager.EnableSshAsync(Gamelet, enableSshAction)) .RunAndRecord(enableSshAction)) { return(new List <ProcessListEntry>()); } } catch (Exception e) when(e is SshKeyException || e is CloudException) { Trace.WriteLine(e.ToString()); _dialogUtil.ShowError(ErrorStrings.FailedToEnableSsh(e.Message), e.ToString()); return(new List <ProcessListEntry>()); } // TODO: Handle ProcessException var processListAction = _actionRecorder.CreateToolAction(ActionType.ProcessList); var queryProcessesTask = _cancelableTaskFactory.Create( "Querying instance processes...", async() => await request.GetBySshAsync(new SshTarget(Gamelet))); queryProcessesTask.RunAndRecord(processListAction); return(queryProcessesTask.Result); }
void RefreshCoreList() { if (_instance == null) { return; } Cursor = System.Windows.Input.Cursors.Wait; try { var queryTaskTitle = "Querying instance crash dumps..."; var queryTask = _cancelableTaskFactory.Create( queryTaskTitle, async() => await _coreListRequest.GetCoreListAsync(new SshTarget(_instance))); // Ignore cancelation, and accept the empty result. queryTask.RunAndRecord(_actionRecorder, ActionType.CrashDumpList); CoreList.ItemsSource = queryTask.Result; } catch (ProcessException e) { Trace.WriteLine($"Unable to query instance crash dumps: {e}"); GameletMessageTextBox.Text = ErrorStrings.ErrorQueryingCoreFiles(e.Message); CoreList.ItemsSource = new List <CoreListEntry>(); } finally { Cursor = null; } }
public IVsiGameLaunch CreateLaunch(LaunchParams launchParams) { IAction action = _actionRecorder.CreateToolAction(ActionType.GameLaunchCreate); CreateLaunchResult launchRes = null; ICancelableTask launchTask = _cancelableTaskFactory.Create( TaskMessages.LaunchingGame, async task => { launchRes = await CreateLaunchAsync(launchParams, task, action); }); try { if (!launchTask.RunAndRecord(action)) { Trace.WriteLine("Launching a game has been canceled by user."); return(null); } } catch (ConfigurationException e) { _dialogUtil.ShowError(e.Message); return(null); } catch (CloudException e) { string message = $"{ErrorStrings.CouldNotStartTheGame}{Environment.NewLine}" + $"{e.Message}{Environment.NewLine}{Environment.NewLine}{ErrorStrings.SeeLogs}"; _dialogUtil.ShowError(message); return(null); } if (!string.IsNullOrWhiteSpace(launchRes.WarningMessage)) { _dialogUtil.ShowWarning(launchRes.WarningMessage); } if (!string.IsNullOrWhiteSpace(launchRes.SdkCompatibilityMessage)) { bool showAgain = _dialogUtil.ShowOkNoMoreDisplayWarning( launchRes.SdkCompatibilityMessage, new[] { "Tools", "Options", "Stadia SDK", "Game launch", "SDK incompatibility warning" }); if (!showAgain) { _vsiService.Options.AddSdkVersionsToHide(launchParams.GameletSdkVersion, launchParams.SdkVersion, launchParams.GameletName); } } return(launchRes.GameLaunch); }
public int AddPort(IDebugPortRequest2 request, out IDebugPort2 port) { var debugSessionMetrics = new DebugSessionMetrics(_metrics); debugSessionMetrics.UseNewDebugSessionId(); var actionRecorder = new ActionRecorder(debugSessionMetrics); port = null; if (request.GetPortName(out string gameletIdOrName) != VSConstants.S_OK) { return(VSConstants.E_FAIL); } var action = actionRecorder.CreateToolAction(ActionType.GameletGet); var gameletClient = _gameletClientFactory.Create(_cloudRunner.Intercept(action)); var gameletTask = _cancelableTaskFactory.Create( "Querying instance...", async() => await gameletClient.LoadByNameOrIdAsync(gameletIdOrName)); try { gameletTask.RunAndRecord(action); } catch (CloudException e) { Trace.WriteLine(e.ToString()); _dialogUtil.ShowError(e.Message); return(VSConstants.S_OK); } var debugPort = _debugPortFactory.Create(gameletTask.Result, this, debugSessionMetrics.DebugSessionId); _ports.Add(debugPort); port = debugPort; return(VSConstants.S_OK); }
/// <summary> /// Stop a gamelet and wait for it to return to the reserved state. /// </summary> Gamelet StopGamelet(Gamelet gamelet) { IAction action = _actionRecorder.CreateToolAction(ActionType.GameletStop); ICancelableTask stopTask = _cancelableTaskFactory.Create(TaskMessages.WaitingForGameStop, async(task) => { IGameletClient gameletClient = _gameletClientFactory.Create(_runner.Intercept(action)); try { await gameletClient.StopGameAsync(gamelet.Id); } catch (CloudException e) when((e.InnerException as RpcException) ?.StatusCode == StatusCode.FailedPrecondition) { // FailedPreconditions likely means there is no game session to stop. // For details see (internal). Trace.WriteLine("Potential race condition while stopping game; " + $"ignoring RPC error: {e.InnerException.Message}"); } while (!task.IsCanceled) { gamelet = await gameletClient.GetGameletByNameAsync(gamelet.Name); if (gamelet.State == GameletState.Reserved) { break; } await Task.Delay(1000); } }); if (stopTask.RunAndRecord(action)) { return(gamelet); } return(null); }
public void WaitUntilGameLaunchedTest(GameLaunchState[] launchStates, int[] stateRepeat, bool launchResult, EndReason?endReason = null, bool isDevResumeOfferEnabled = false) { _target = GetGameLaunch(isDevResumeOfferEnabled); Func <ICancelable, Task> currentTask = null; var action = Substitute.For <IAction>(); DeveloperLogEvent devEvent = SetupUpdateEvent(action); _actionRecorder.CreateToolAction(ActionType.GameLaunchWaitForStart).Returns(action); var cancelable = Substitute.For <ICancelableTask>(); action.Record(Arg.Any <Func <bool> >()).Returns(callInfo => { new JoinableTaskFactory(new JoinableTaskContext()).Run( () => currentTask(new NothingToCancel())); return(true); }); _cancelableTaskFactory.Create( TaskMessages.LaunchingGame, Arg.Any <Func <ICancelable, Task> >()).Returns(callInfo => { currentTask = callInfo.Arg <Func <ICancelable, Task> >(); return(cancelable); }); List <GameLaunchState> statusSequence = launchStates .Select((state, i) => Enumerable.Repeat(state, stateRepeat[i])) .SelectMany(states => states).ToList(); Task <GgpGrpc.Models.GameLaunch>[] launches = statusSequence.Select( (state, i) => Task.FromResult(GetGameLaunch(state, i == statusSequence.Count - 1 ? endReason : null))).ToArray(); _gameletClient.GetGameLaunchStateAsync(_launchName, action) .Returns(launches[0], launches.Skip(1).ToArray()); bool launched = _target.WaitUntilGameLaunched(); Assert.That(launched, Is.EqualTo(launchResult)); if (!launchResult) { _dialogUtil.Received(1).ShowError(Arg.Any <string>()); } Assert.That(devEvent.GameLaunchData.LaunchId, Is.EqualTo(_launchId)); Assert.That(devEvent.GameLaunchData.EndReason, Is.EqualTo((int?)endReason)); action.Received(1).Record(Arg.Any <Func <bool> >()); }
public void LoadSymbolsSendsEvent() { var action = Substitute.For <IAction>(); action.Record(Arg.Any <Func <bool> >()).Returns(true); _mockActionRecorder.CreateToolAction(ActionType.DebugModuleLoadSymbols).Returns(action); var task = Substitute.For <ICancelableTask <int> >(); task.Result.Returns(VSConstants.S_OK); _mockCancelableTaskFactory.Create(Arg.Any <string>(), Arg.Any <Func <ICancelable, int> >()) .Returns(task); _debugModule.LoadSymbols(); _mockEngineHandler.Received(1).SendEvent( Arg.Is <DebugEvent>(e => e is IDebugSymbolSearchEvent2), _mockDebugProgram, (IDebugThread2)null); }
public bool WaitUntilGameLaunched() { IAction action = _actionRecorder.CreateToolAction(ActionType.GameLaunchWaitForStart); ICancelableTask pollForLaunchStatusTask = _cancelableTaskFactory.Create( TaskMessages.LaunchingGame, async task => await PollForLaunchStatusAsync(task, action)); try { if (!pollForLaunchStatusTask.RunAndRecord(action)) { Trace.WriteLine("Polling for the launch status has been canceled by user."); return(false); } } catch (Exception e) when(e is TimeoutException || e is GameLaunchFailError) { Trace.WriteLine(e.Message); _dialogUtil.ShowError(e.Message); return(false); } return(true); }
public int LoadSymbols() { IAction action = _actionRecorder.CreateToolAction(ActionType.DebugModuleLoadSymbols); ICancelableTask <int> loadSymbolsTask = _cancelableTaskFactory.Create( "Loading symbols...", task => _moduleFileLoader.LoadModuleFilesAsync(new[] { _lldbModule }, task, _moduleFileLoadRecorderFactory.Create( action))); if (!loadSymbolsTask.RunAndRecord(action)) { return(VSConstants.E_ABORT); } _engineHandler.OnSymbolsLoaded(Self, ModuleName, null, loadSymbolsTask.Result == VSConstants.S_OK, _program); // Returning E_FAIL causes Visual Studio to show a file dialog when attached // to a running program or crash dump. This dialog can only be used to select PDB // files. return(loadSymbolsTask.Result == VSConstants.E_FAIL ? VSConstants.S_OK : loadSymbolsTask.Result); }
public void RunComplete() { bool ranToCompletion = false; var task = taskFactory.Create(Text, t => { t.ThrowIfCancellationRequested(); ranToCompletion = true; }); Assert.IsTrue(task.Run()); Assert.IsFalse(task.IsCanceled); Assert.IsTrue(ranToCompletion); }