Skip to content

Commit 1c8d20e

Browse files
authored
Debug test session proposed (microsoft#23891)
fixes microsoft#23752 skip tests due to: microsoft#22170
1 parent f6a6a32 commit 1c8d20e

File tree

3 files changed

+44
-10
lines changed

3 files changed

+44
-10
lines changed

src/client/testing/common/debugLauncher.ts

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { inject, injectable, named } from 'inversify';
22
import * as path from 'path';
3-
import { DebugConfiguration, l10n, Uri, WorkspaceFolder } from 'vscode';
3+
import { DebugConfiguration, l10n, Uri, WorkspaceFolder, DebugSession } from 'vscode';
44
import { IApplicationShell, IDebugService } from '../../common/application/types';
55
import { EXTENSION_ROOT_DIR } from '../../common/constants';
66
import * as internalScripts from '../../common/process/internal/scripts';
@@ -9,7 +9,7 @@ import { DebuggerTypeName, PythonDebuggerTypeName } from '../../debugger/constan
99
import { IDebugConfigurationResolver } from '../../debugger/extension/configuration/types';
1010
import { DebugPurpose, LaunchRequestArguments } from '../../debugger/types';
1111
import { IServiceContainer } from '../../ioc/types';
12-
import { traceError } from '../../logging';
12+
import { traceError, traceVerbose } from '../../logging';
1313
import { TestProvider } from '../types';
1414
import { ITestDebugLauncher, LaunchOptions } from './types';
1515
import { getConfigurationsForWorkspace } from '../../debugger/extension/configuration/launch.json/launchJsonReader';
@@ -34,12 +34,20 @@ export class DebugLauncher implements ITestDebugLauncher {
3434

3535
public async launchDebugger(options: LaunchOptions, callback?: () => void): Promise<void> {
3636
const deferred = createDeferred<void>();
37+
let hasCallbackBeenCalled = false;
3738
if (options.token && options.token.isCancellationRequested) {
39+
hasCallbackBeenCalled = true;
3840
return undefined;
3941
deferred.resolve();
4042
callback?.();
4143
}
4244

45+
options.token?.onCancellationRequested(() => {
46+
deferred.resolve();
47+
callback?.();
48+
hasCallbackBeenCalled = true;
49+
});
50+
4351
const workspaceFolder = DebugLauncher.resolveWorkspaceFolder(options.cwd);
4452
const launchArgs = await this.getLaunchArgs(
4553
options,
@@ -48,11 +56,23 @@ export class DebugLauncher implements ITestDebugLauncher {
4856
);
4957
const debugManager = this.serviceContainer.get<IDebugService>(IDebugService);
5058

51-
debugManager.onDidTerminateDebugSession(() => {
52-
deferred.resolve();
53-
callback?.();
59+
let activatedDebugSession: DebugSession | undefined;
60+
debugManager.startDebugging(workspaceFolder, launchArgs).then(() => {
61+
// Save the debug session after it is started so we can check if it is the one that was terminated.
62+
activatedDebugSession = debugManager.activeDebugSession;
63+
});
64+
debugManager.onDidTerminateDebugSession((session) => {
65+
traceVerbose(`Debug session terminated. sessionId: ${session.id}`);
66+
// Only resolve no callback has been made and the session is the one that was started.
67+
if (
68+
!hasCallbackBeenCalled &&
69+
activatedDebugSession !== undefined &&
70+
session.id === activatedDebugSession?.id
71+
) {
72+
deferred.resolve();
73+
callback?.();
74+
}
5475
});
55-
debugManager.startDebugging(workspaceFolder, launchArgs);
5676
return deferred.promise;
5777
}
5878

src/client/testing/testController/controller.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -378,7 +378,6 @@ export class PythonTestController implements ITestController, IExtensionSingleAc
378378
`Running Tests for Workspace(s): ${workspaces.map((w) => w.uri.fsPath).join(';')}`,
379379
true,
380380
);
381-
382381
const dispose = token.onCancellationRequested(() => {
383382
runInstance.appendOutput(`\nRun instance cancelled.\r\n`);
384383
runInstance.end();

src/test/testing/common/debugLauncher.unit.test.ts

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import * as sinon from 'sinon';
1010
import * as TypeMoq from 'typemoq';
1111
import * as fs from 'fs-extra';
1212
import * as workspaceApis from '../../../client/common/vscodeApis/workspaceApis';
13-
import { CancellationTokenSource, DebugConfiguration, Uri, WorkspaceFolder } from 'vscode';
13+
import { CancellationTokenSource, DebugConfiguration, DebugSession, Uri, WorkspaceFolder } from 'vscode';
1414
import { IInvalidPythonPathInDebuggerService } from '../../../client/application/diagnostics/types';
1515
import { IApplicationShell, IDebugService } from '../../../client/common/application/types';
1616
import { EXTENSION_ROOT_DIR } from '../../../client/common/constants';
@@ -30,6 +30,7 @@ import { TestProvider } from '../../../client/testing/types';
3030
import { isOs, OSType } from '../../common';
3131
import { IEnvironmentActivationService } from '../../../client/interpreter/activation/types';
3232
import * as util from '../../../client/testing/testController/common/utils';
33+
import { createDeferred } from '../../../client/common/utils/async';
3334

3435
use(chaiAsPromised);
3536

@@ -125,17 +126,31 @@ suite('Unit Tests - Debug Launcher', () => {
125126
.setup((x) => x.getEnvironmentVariables(TypeMoq.It.isAny(), TypeMoq.It.isAny()))
126127
.returns(() => Promise.resolve(expected.env));
127128

129+
const deferred = createDeferred<void>();
130+
128131
debugService
129132
.setup((d) => d.startDebugging(TypeMoq.It.isValue(workspaceFolder), TypeMoq.It.isValue(expected)))
130133
.returns((_wspc: WorkspaceFolder, _expectedParam: DebugConfiguration) => {
134+
deferred.resolve();
131135
return Promise.resolve(undefined as any);
132-
})
136+
});
137+
138+
// create a fake debug session that the debug service will return on terminate
139+
const fakeDebugSession = TypeMoq.Mock.ofType<DebugSession>();
140+
fakeDebugSession.setup((ds) => ds.id).returns(() => 'id-val');
141+
const debugSessionInstance = fakeDebugSession.object;
142+
143+
debugService
144+
.setup((d) => d.activeDebugSession)
145+
.returns(() => debugSessionInstance)
133146
.verifiable(TypeMoq.Times.once());
134147

135148
debugService
136149
.setup((d) => d.onDidTerminateDebugSession(TypeMoq.It.isAny()))
137150
.returns((callback) => {
138-
callback();
151+
deferred.promise.then(() => {
152+
callback(debugSessionInstance);
153+
});
139154
return undefined as any;
140155
})
141156
.verifiable(TypeMoq.Times.once());

0 commit comments

Comments
 (0)