debug: correlate debug sessions to testing, delegate restarts (#214537)

Implements #214486
This commit is contained in:
Connor Peet
2024-06-06 21:15:59 -07:00
committed by GitHub
parent f89375854f
commit e2bf3453f5
16 changed files with 154 additions and 27 deletions
@@ -119,7 +119,7 @@ export async function activate(context: vscode.ExtensionContext) {
map,
task,
kind === vscode.TestRunProfileKind.Debug
? await runner.debug(currentArgs, req.include)
? await runner.debug(task, currentArgs, req.include)
: await runner.run(currentArgs, req.include),
coverageDir,
cancellationToken
@@ -37,7 +37,7 @@ export abstract class VSCodeTestRunner {
return new TestOutputScanner(cp, args);
}
public async debug(baseArgs: ReadonlyArray<string>, filter?: ReadonlyArray<vscode.TestItem>) {
public async debug(testRun: vscode.TestRun, baseArgs: ReadonlyArray<string>, filter?: ReadonlyArray<vscode.TestItem>) {
const port = await this.findOpenPort();
const baseConfiguration = vscode.workspace
.getConfiguration('launch', this.repoLocation)
@@ -95,7 +95,7 @@ export abstract class VSCodeTestRunner {
},
});
vscode.debug.startDebugging(this.repoLocation, { ...baseConfiguration, port });
vscode.debug.startDebugging(this.repoLocation, { ...baseConfiguration, port }, { testRun });
let exited = false;
let rootSession: vscode.DebugSession | undefined;
@@ -12,5 +12,6 @@
"../../../src/vscode-dts/vscode.d.ts",
"../../../src/vscode-dts/vscode.proposed.testObserver.d.ts",
"../../../src/vscode-dts/vscode.proposed.attributableCoverage.d.ts",
"../../../src/vscode-dts/vscode.proposed.testRunInDebug.d.ts",
]
}
@@ -329,6 +329,7 @@ export class MainThreadDebugService implements MainThreadDebugServiceShape, IDeb
compact: options.compact,
compoundRoot: parentSession?.compoundRoot,
saveBeforeRestart: saveBeforeStart,
testRun: options.testRun,
suppressDebugStatusbar: options.suppressDebugStatusbar,
suppressDebugToolbar: options.suppressDebugToolbar,
@@ -84,7 +84,7 @@ import { IExtHostTask } from 'vs/workbench/api/common/extHostTask';
import { ExtHostTelemetryLogger, IExtHostTelemetry, isNewAppInstall } from 'vs/workbench/api/common/extHostTelemetry';
import { IExtHostTerminalService } from 'vs/workbench/api/common/extHostTerminalService';
import { IExtHostTerminalShellIntegration } from 'vs/workbench/api/common/extHostTerminalShellIntegration';
import { ExtHostTesting } from 'vs/workbench/api/common/extHostTesting';
import { IExtHostTesting } from 'vs/workbench/api/common/extHostTesting';
import { ExtHostEditors } from 'vs/workbench/api/common/extHostTextEditors';
import { ExtHostTheming } from 'vs/workbench/api/common/extHostTheming';
import { ExtHostTimeline } from 'vs/workbench/api/common/extHostTimeline';
@@ -205,7 +205,7 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I
const extHostWebviewPanels = rpcProtocol.set(ExtHostContext.ExtHostWebviewPanels, new ExtHostWebviewPanels(rpcProtocol, extHostWebviews, extHostWorkspace));
const extHostCustomEditors = rpcProtocol.set(ExtHostContext.ExtHostCustomEditors, new ExtHostCustomEditors(rpcProtocol, extHostDocuments, extensionStoragePaths, extHostWebviews, extHostWebviewPanels));
const extHostWebviewViews = rpcProtocol.set(ExtHostContext.ExtHostWebviewViews, new ExtHostWebviewViews(rpcProtocol, extHostWebviews));
const extHostTesting = rpcProtocol.set(ExtHostContext.ExtHostTesting, new ExtHostTesting(rpcProtocol, extHostLogService, extHostCommands, extHostDocumentsAndEditors));
const extHostTesting = rpcProtocol.set(ExtHostContext.ExtHostTesting, accessor.get(IExtHostTesting));
const extHostUriOpeners = rpcProtocol.set(ExtHostContext.ExtHostUriOpeners, new ExtHostUriOpeners(rpcProtocol));
const extHostProfileContentHandlers = rpcProtocol.set(ExtHostContext.ExtHostProfileContentHandlers, new ExtHostProfileContentHandlers(rpcProtocol));
rpcProtocol.set(ExtHostContext.ExtHostInteractive, new ExtHostInteractive(rpcProtocol, extHostNotebook, extHostDocumentsAndEditors, extHostCommands, extHostLogService));
@@ -31,6 +31,7 @@ import { ExtHostManagedSockets, IExtHostManagedSockets } from 'vs/workbench/api/
import { ExtHostAuthentication, IExtHostAuthentication } from 'vs/workbench/api/common/extHostAuthentication';
import { ExtHostLanguageModels, IExtHostLanguageModels } from 'vs/workbench/api/common/extHostLanguageModels';
import { IExtHostTerminalShellIntegration, ExtHostTerminalShellIntegration } from 'vs/workbench/api/common/extHostTerminalShellIntegration';
import { ExtHostTesting, IExtHostTesting } from 'vs/workbench/api/common/extHostTesting';
registerSingleton(IExtHostLocalizationService, ExtHostLocalizationService, InstantiationType.Delayed);
registerSingleton(ILoggerService, ExtHostLoggerService, InstantiationType.Delayed);
@@ -40,6 +41,7 @@ registerSingleton(IExtHostAuthentication, ExtHostAuthentication, InstantiationTy
registerSingleton(IExtHostLanguageModels, ExtHostLanguageModels, InstantiationType.Eager);
registerSingleton(IExtHostConfiguration, ExtHostConfiguration, InstantiationType.Eager);
registerSingleton(IExtHostConsumerFileSystem, ExtHostConsumerFileSystem, InstantiationType.Eager);
registerSingleton(IExtHostTesting, ExtHostTesting, InstantiationType.Eager);
registerSingleton(IExtHostDebugService, WorkerExtHostDebugService, InstantiationType.Eager);
registerSingleton(IExtHostDecorations, ExtHostDecorations, InstantiationType.Eager);
registerSingleton(IExtHostDocumentsAndEditors, ExtHostDocumentsAndEditors, InstantiationType.Eager);
@@ -55,7 +55,7 @@ import { IChatProgressResponseContent } from 'vs/workbench/contrib/chat/common/c
import { IChatFollowup, IChatProgress, IChatResponseErrorDetails, IChatTask, IChatTaskDto, IChatUserActionEvent, ChatAgentVoteDirection } from 'vs/workbench/contrib/chat/common/chatService';
import { IChatRequestVariableValue, IChatVariableData, IChatVariableResolverProgress } from 'vs/workbench/contrib/chat/common/chatVariables';
import { IChatMessage, IChatResponseFragment, ILanguageModelChatMetadata, ILanguageModelChatSelector, ILanguageModelsChangeEvent } from 'vs/workbench/contrib/chat/common/languageModels';
import { DebugConfigurationProviderTriggerKind, IAdapterDescriptor, IConfig, IDebugSessionReplMode, IDebugVisualization, IDebugVisualizationContext, IDebugVisualizationTreeItem, MainThreadDebugVisualization } from 'vs/workbench/contrib/debug/common/debug';
import { DebugConfigurationProviderTriggerKind, IAdapterDescriptor, IConfig, IDebugSessionReplMode, IDebugTestRunReference, IDebugVisualization, IDebugVisualizationContext, IDebugVisualizationTreeItem, MainThreadDebugVisualization } from 'vs/workbench/contrib/debug/common/debug';
import * as notebookCommon from 'vs/workbench/contrib/notebook/common/notebookCommon';
import { CellExecutionUpdateType } from 'vs/workbench/contrib/notebook/common/notebookExecutionService';
import { ICellExecutionComplete, ICellExecutionStateUpdate } from 'vs/workbench/contrib/notebook/common/notebookExecutionStateService';
@@ -1566,6 +1566,7 @@ export interface IStartDebuggingOptions {
suppressDebugStatusbar?: boolean;
suppressDebugView?: boolean;
suppressSaveBeforeStart?: boolean;
testRun?: IDebugTestRunReference;
}
export interface MainThreadDebugServiceShape extends IDisposable {
@@ -30,6 +30,7 @@ import { ThemeIcon as ThemeIconUtils } from 'vs/base/common/themables';
import { IExtHostCommands } from 'vs/workbench/api/common/extHostCommands';
import * as Convert from 'vs/workbench/api/common/extHostTypeConverters';
import { coalesce } from 'vs/base/common/arrays';
import { IExtHostTesting } from 'vs/workbench/api/common/extHostTesting';
export const IExtHostDebugService = createDecorator<IExtHostDebugService>('IExtHostDebugService');
@@ -123,6 +124,7 @@ export abstract class ExtHostDebugServiceBase extends DisposableCls implements I
@IExtHostEditorTabs protected _editorTabs: IExtHostEditorTabs,
@IExtHostVariableResolverProvider private _variableResolver: IExtHostVariableResolverProvider,
@IExtHostCommands private _commands: IExtHostCommands,
@IExtHostTesting private _testing: IExtHostTesting,
) {
super();
@@ -466,6 +468,8 @@ export abstract class ExtHostDebugServiceBase extends DisposableCls implements I
}
public startDebugging(folder: vscode.WorkspaceFolder | undefined, nameOrConfig: string | vscode.DebugConfiguration, options: vscode.DebugSessionOptions): Promise<boolean> {
const testRunMeta = options.testRun && this._testing.getMetadataForRun(options.testRun);
return this._debugServiceProxy.$startDebugging(folder ? folder.uri : undefined, nameOrConfig, {
parentSessionID: options.parentSession ? options.parentSession.id : undefined,
lifecycleManagedByParent: options.lifecycleManagedByParent,
@@ -473,6 +477,10 @@ export abstract class ExtHostDebugServiceBase extends DisposableCls implements I
noDebug: options.noDebug,
compact: options.compact,
suppressSaveBeforeStart: options.suppressSaveBeforeStart,
testRun: testRunMeta && {
runId: testRunMeta.runId,
taskId: testRunMeta.taskId,
},
// Check debugUI for back-compat, #147264
suppressDebugStatusbar: options.suppressDebugStatusbar ?? (options as any).debugUI?.simple,
@@ -1247,8 +1255,9 @@ export class WorkerExtHostDebugService extends ExtHostDebugServiceBase {
@IExtHostConfiguration configurationService: IExtHostConfiguration,
@IExtHostEditorTabs editorTabs: IExtHostEditorTabs,
@IExtHostVariableResolverProvider variableResolver: IExtHostVariableResolverProvider,
@IExtHostCommands commands: IExtHostCommands
@IExtHostCommands commands: IExtHostCommands,
@IExtHostTesting testing: IExtHostTesting,
) {
super(extHostRpcService, workspaceService, extensionService, configurationService, editorTabs, variableResolver, commands);
super(extHostRpcService, workspaceService, extensionService, configurationService, editorTabs, variableResolver, commands, testing);
}
}
+54 -15
View File
@@ -16,10 +16,11 @@ import { MarshalledId } from 'vs/base/common/marshallingIds';
import { isDefined } from 'vs/base/common/types';
import { generateUuid } from 'vs/base/common/uuid';
import { IExtensionDescription, IRelaxedExtensionDescription } from 'vs/platform/extensions/common/extensions';
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
import { ILogService } from 'vs/platform/log/common/log';
import { ExtHostTestingShape, ILocationDto, MainContext, MainThreadTestingShape } from 'vs/workbench/api/common/extHost.protocol';
import { ExtHostCommands } from 'vs/workbench/api/common/extHostCommands';
import { ExtHostDocumentsAndEditors } from 'vs/workbench/api/common/extHostDocumentsAndEditors';
import { IExtHostCommands } from 'vs/workbench/api/common/extHostCommands';
import { IExtHostDocumentsAndEditors } from 'vs/workbench/api/common/extHostDocumentsAndEditors';
import { IExtHostRpcService } from 'vs/workbench/api/common/extHostRpcService';
import { ExtHostTestItemCollection, TestItemImpl, TestItemRootImpl, toItemFromContext } from 'vs/workbench/api/common/extHostTestItem';
import * as Convert from 'vs/workbench/api/common/extHostTypeConverters';
@@ -45,7 +46,14 @@ let followupCounter = 0;
const testResultInternalIDs = new WeakMap<vscode.TestRunResult, string>();
export const IExtHostTesting = createDecorator<IExtHostTesting>('IExtHostTesting');
export interface IExtHostTesting extends ExtHostTesting {
readonly _serviceBrand: undefined;
}
export class ExtHostTesting extends Disposable implements ExtHostTestingShape {
declare readonly _serviceBrand: undefined;
private readonly resultsChangedEmitter = this._register(new Emitter<void>());
protected readonly controllers = new Map</* controller ID */ string, ControllerInfo>();
private readonly proxy: MainThreadTestingShape;
@@ -61,8 +69,8 @@ export class ExtHostTesting extends Disposable implements ExtHostTestingShape {
constructor(
@IExtHostRpcService rpc: IExtHostRpcService,
@ILogService private readonly logService: ILogService,
private readonly commands: ExtHostCommands,
private readonly editors: ExtHostDocumentsAndEditors,
@IExtHostCommands private readonly commands: IExtHostCommands,
@IExtHostDocumentsAndEditors private readonly editors: IExtHostDocumentsAndEditors,
) {
super();
this.proxy = rpc.getProxy(MainContext.MainThreadTesting);
@@ -111,6 +119,8 @@ export class ExtHostTesting extends Disposable implements ExtHostTestingShape {
});
}
//#region public API
/**
* Implements vscode.test.registerTestProvider
*/
@@ -236,6 +246,9 @@ export class ExtHostTesting extends Disposable implements ExtHostTestingShape {
return { dispose: () => { this.followupProviders.delete(provider); } };
}
//#endregion
//#region RPC methods
/**
* @inheritdoc
*/
@@ -412,6 +425,32 @@ export class ExtHostTesting extends Disposable implements ExtHostTestingShape {
return this.commands.executeCommand(command.command, ...(command.arguments || []));
}
/**
* Cancels an ongoing test run.
*/
public $cancelExtensionTestRun(runId: string | undefined) {
if (runId === undefined) {
this.runTracker.cancelAllRuns();
} else {
this.runTracker.cancelRunById(runId);
}
}
//#endregion
public getMetadataForRun(run: vscode.TestRun) {
for (const tracker of this.runTracker.trackers) {
const taskId = tracker.getTaskIdForRun(run);
if (!taskId) {
return undefined;
}
return { taskId, runId: tracker.id };
}
return undefined;
}
private async runControllerTestRequest(req: ICallProfileRunHandler | ICallProfileRunHandler, isContinuous: boolean, token: CancellationToken): Promise<IStartControllerTestsResult> {
const lookup = this.controllers.get(req.controllerId);
if (!lookup) {
@@ -467,17 +506,6 @@ export class ExtHostTesting extends Disposable implements ExtHostTestingShape {
}
}
}
/**
* Cancels an ongoing test run.
*/
public $cancelExtensionTestRun(runId: string | undefined) {
if (runId === undefined) {
this.runTracker.cancelAllRuns();
} else {
this.runTracker.cancelRunById(runId);
}
}
}
// Deadline after being requested by a user that a test run is forcibly cancelled.
@@ -543,6 +571,17 @@ class TestRunTracker extends Disposable {
}));
}
/** Gets the task ID from a test run object. */
public getTaskIdForRun(run: vscode.TestRun) {
for (const [taskId, { run: r }] of this.tasks) {
if (r === run) {
return taskId;
}
}
return undefined;
}
/** Requests cancellation of the run. On the second call, forces cancellation. */
public cancel() {
if (this.state === TestRunTrackerState.Running) {
@@ -27,6 +27,7 @@ import { ExtensionDescriptionRegistry } from 'vs/workbench/services/extensions/c
import type * as vscode from 'vscode';
import { ExtHostConfigProvider, IExtHostConfiguration } from '../common/extHostConfiguration';
import { IExtHostCommands } from 'vs/workbench/api/common/extHostCommands';
import { IExtHostTesting } from 'vs/workbench/api/common/extHostTesting';
export class ExtHostDebugService extends ExtHostDebugServiceBase {
@@ -44,8 +45,9 @@ export class ExtHostDebugService extends ExtHostDebugServiceBase {
@IExtHostEditorTabs editorTabs: IExtHostEditorTabs,
@IExtHostVariableResolverProvider variableResolver: IExtHostVariableResolverProvider,
@IExtHostCommands commands: IExtHostCommands,
@IExtHostTesting testing: IExtHostTesting,
) {
super(extHostRpcService, workspaceService, extensionService, configurationService, editorTabs, variableResolver, commands);
super(extHostRpcService, workspaceService, extensionService, configurationService, editorTabs, variableResolver, commands, testing);
}
protected override createDebugAdapter(adapter: IAdapterDescriptor, session: ExtHostDebugSession): AbstractDebugAdapter | undefined {
@@ -51,6 +51,7 @@ import { ViewModel } from 'vs/workbench/contrib/debug/common/debugViewModel';
import { Debugger } from 'vs/workbench/contrib/debug/common/debugger';
import { DisassemblyViewInput } from 'vs/workbench/contrib/debug/common/disassemblyViewInput';
import { VIEWLET_ID as EXPLORER_VIEWLET_ID } from 'vs/workbench/contrib/files/common/files';
import { ITestService } from 'vs/workbench/contrib/testing/common/testService';
import { IActivityService, NumberBadge } from 'vs/workbench/services/activity/common/activity';
import { IEditorService } from 'vs/workbench/services/editor/common/editorService';
import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions';
@@ -112,6 +113,7 @@ export class DebugService implements IDebugService {
@IQuickInputService private readonly quickInputService: IQuickInputService,
@IWorkspaceTrustRequestService private readonly workspaceTrustRequestService: IWorkspaceTrustRequestService,
@IUriIdentityService private readonly uriIdentityService: IUriIdentityService,
@ITestService private readonly testService: ITestService,
) {
this.breakpointsToSendOnResourceSaved = new Set<URI>();
@@ -839,6 +841,21 @@ export class DebugService implements IDebugService {
}
};
// For debug sessions spawned by test runs, cancel the test run and stop
// the session, then start the test run again; tests have no notion of restarts.
if (session.correlatedTestRun) {
if (!session.correlatedTestRun.completedAt) {
this.testService.cancelTestRun(session.correlatedTestRun.id);
await Event.toPromise(session.correlatedTestRun.onComplete);
// todo@connor4312 is there any reason to wait for the debug session to
// terminate? I don't think so, test extension should already handle any
// state conflicts...
}
this.testService.runResolvedTests(session.correlatedTestRun.request);
return;
}
if (session.capabilities.supportsRestartRequest) {
const taskResult = await runTasks();
if (taskResult === TaskRunResult.Success) {
@@ -42,6 +42,9 @@ import { IPaneCompositePartService } from 'vs/workbench/services/panecomposite/b
import { getActiveWindow } from 'vs/base/browser/dom';
import { mainWindow } from 'vs/base/browser/window';
import { isDefined } from 'vs/base/common/types';
import { ITestService } from 'vs/workbench/contrib/testing/common/testService';
import { ITestResultService } from 'vs/workbench/contrib/testing/common/testResultService';
import { LiveTestResult } from 'vs/workbench/contrib/testing/common/testResult';
const TRIGGERED_BREAKPOINT_MAX_DELAY = 1500;
@@ -66,6 +69,11 @@ export class DebugSession implements IDebugSession, IDisposable {
private stoppedDetails: IRawStoppedDetails[] = [];
private readonly statusQueue = this.rawListeners.add(new ThreadStatusScheduler());
/** Test run this debug session was spawned by */
public readonly correlatedTestRun?: LiveTestResult;
/** Whether we terminated the correlated run yet. Used so a 2nd terminate request goes through to the underlying session. */
private didTerminateTestRun?: boolean;
private readonly _onDidChangeState = new Emitter<void>();
private readonly _onDidEndAdapter = new Emitter<AdapterEndEvent | undefined>();
@@ -106,7 +114,9 @@ export class DebugSession implements IDebugSession, IDisposable {
@IInstantiationService private readonly instantiationService: IInstantiationService,
@ICustomEndpointTelemetryService private readonly customEndpointTelemetryService: ICustomEndpointTelemetryService,
@IWorkbenchEnvironmentService private readonly workbenchEnvironmentService: IWorkbenchEnvironmentService,
@ILogService private readonly logService: ILogService
@ILogService private readonly logService: ILogService,
@ITestService private readonly testService: ITestService,
@ITestResultService testResultService: ITestResultService,
) {
this._options = options || {};
this.parentSession = this._options.parentSession;
@@ -126,6 +136,16 @@ export class DebugSession implements IDebugSession, IDisposable {
}));
}
// Cast here, it's not possible to reference a hydrated result in this code path.
this.correlatedTestRun = options?.testRun
? (testResultService.getResult(options.testRun.runId) as LiveTestResult)
: this.parentSession?.correlatedTestRun;
if (this.correlatedTestRun) {
// Listen to the test completing because the user might have taken the cancel action rather than stopping the session.
toDispose.add(this.correlatedTestRun.onComplete(() => this.terminate()));
}
const compoundRoot = this._options.compoundRoot;
if (compoundRoot) {
toDispose.add(compoundRoot.onDidSessionStop(() => this.terminate()));
@@ -387,6 +407,9 @@ export class DebugSession implements IDebugSession, IDisposable {
this.cancelAllRequests();
if (this._options.lifecycleManagedByParent && this.parentSession) {
await this.parentSession.terminate(restart);
} else if (this.correlatedTestRun && !this.correlatedTestRun.completedAt && !this.didTerminateTestRun) {
this.didTerminateTestRun = true;
this.testService.cancelTestRun(this.correlatedTestRun.id);
} else if (this.raw) {
if (this.raw.capabilities.supportsTerminateRequest && this._configuration.resolved.request === 'launch') {
await this.raw.terminate(restart);
@@ -27,6 +27,7 @@ import { DebugCompoundRoot } from 'vs/workbench/contrib/debug/common/debugCompou
import { IDataBreakpointOptions, IFunctionBreakpointOptions, IInstructionBreakpointOptions } from 'vs/workbench/contrib/debug/common/debugModel';
import { Source } from 'vs/workbench/contrib/debug/common/debugSource';
import { ITaskIdentifier } from 'vs/workbench/contrib/tasks/common/tasks';
import { LiveTestResult } from 'vs/workbench/contrib/testing/common/testResult';
import { IEditorService } from 'vs/workbench/services/editor/common/editorService';
export const VIEWLET_ID = 'workbench.view.debug';
@@ -219,6 +220,11 @@ export interface LoadedSourceEvent {
export type IDebugSessionReplMode = 'separate' | 'mergeWithParent';
export interface IDebugTestRunReference {
runId: string;
taskId: string;
}
export interface IDebugSessionOptions {
noDebug?: boolean;
parentSession?: IDebugSession;
@@ -231,6 +237,11 @@ export interface IDebugSessionOptions {
suppressDebugToolbar?: boolean;
suppressDebugStatusbar?: boolean;
suppressDebugView?: boolean;
/**
* Set if the debug session is correlated with a test run. Stopping/restarting
* the session will instead stop/restart the test run.
*/
testRun?: IDebugTestRunReference;
}
export interface IDataBreakpointInfoResponse {
@@ -353,6 +364,8 @@ export interface IDebugSession extends ITreeElement {
readonly suppressDebugStatusbar: boolean;
readonly suppressDebugView: boolean;
readonly lifecycleManagedByParent: boolean;
/** Test run this debug session was spawned by */
readonly correlatedTestRun?: LiveTestResult;
setSubId(subId: string | undefined): void;
@@ -41,7 +41,7 @@ export function createTestSession(model: DebugModel, name = 'mockSession', optio
}
};
}
} as IDebugService, undefined!, undefined!, new TestConfigurationService({ debug: { console: { collapseIdenticalLines: true } } }), undefined!, mockWorkspaceContextService, undefined!, undefined!, undefined!, mockUriIdentityService, new TestInstantiationService(), undefined!, undefined!, new NullLogService());
} as IDebugService, undefined!, undefined!, new TestConfigurationService({ debug: { console: { collapseIdenticalLines: true } } }), undefined!, mockWorkspaceContextService, undefined!, undefined!, undefined!, mockUriIdentityService, new TestInstantiationService(), undefined!, undefined!, new NullLogService(), undefined!, undefined!);
}
function createTwoStackFrames(session: DebugSession): { firstStackFrame: StackFrame; secondStackFrame: StackFrame } {
@@ -445,7 +445,7 @@ suite('Debug - CallStack', () => {
override get state(): State {
return State.Stopped;
}
}(generateUuid(), { resolved: { name: 'stoppedSession', type: 'node', request: 'launch' }, unresolved: undefined }, undefined, model, undefined, undefined!, undefined!, undefined!, undefined!, undefined!, mockWorkspaceContextService, undefined!, undefined!, undefined!, mockUriIdentityService, new TestInstantiationService(), undefined!, undefined!, new NullLogService());
}(generateUuid(), { resolved: { name: 'stoppedSession', type: 'node', request: 'launch' }, unresolved: undefined }, undefined, model, undefined, undefined!, undefined!, undefined!, undefined!, undefined!, mockWorkspaceContextService, undefined!, undefined!, undefined!, mockUriIdentityService, new TestInstantiationService(), undefined!, undefined!, new NullLogService(), undefined!, undefined!);
disposables.add(session);
const runningSession = createTestSession(model);
@@ -118,6 +118,7 @@ export const allApiProposals = Object.freeze({
terminalSelection: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.terminalSelection.d.ts',
terminalShellIntegration: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.terminalShellIntegration.d.ts',
testObserver: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.testObserver.d.ts',
testRunInDebug: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.testRunInDebug.d.ts',
textSearchProvider: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.textSearchProvider.d.ts',
timeline: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.timeline.d.ts',
tokenInformation: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.tokenInformation.d.ts',
+18
View File
@@ -0,0 +1,18 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
declare module 'vscode' {
// https://github.com/microsoft/vscode/issues/214486
export interface DebugSessionOptions {
/**
* Signals to the editor that the debug session was started from a test run
* request. This is used to link the lifecycle of the debug session and
* test run in UI actions.
*/
testRun?: TestRun;
}
}