Skip to content

Commit 29d4f35

Browse files
authored
fix debug restart (#24438)
fixes #24437 also tested and fixes microsoft/vscode-python-debugger#338
1 parent dfa0520 commit 29d4f35

File tree

9 files changed

+50
-21
lines changed

9 files changed

+50
-21
lines changed

src/client/common/application/debugService.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import {
1313
DebugConsole,
1414
DebugSession,
1515
DebugSessionCustomEvent,
16+
DebugSessionOptions,
1617
Disposable,
1718
Event,
1819
WorkspaceFolder,
@@ -57,7 +58,7 @@ export class DebugService implements IDebugService {
5758
public startDebugging(
5859
folder: WorkspaceFolder | undefined,
5960
nameOrConfiguration: string | DebugConfiguration,
60-
parentSession?: DebugSession,
61+
parentSession?: DebugSession | DebugSessionOptions,
6162
): Thenable<boolean> {
6263
return debug.startDebugging(folder, nameOrConfiguration, parentSession);
6364
}

src/client/testing/common/debugLauncher.ts

Lines changed: 7 additions & 3 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, DebugSession } from 'vscode';
3+
import { DebugConfiguration, l10n, Uri, WorkspaceFolder, DebugSession, DebugSessionOptions } 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';
@@ -32,7 +32,11 @@ export class DebugLauncher implements ITestDebugLauncher {
3232
this.configService = this.serviceContainer.get<IConfigurationService>(IConfigurationService);
3333
}
3434

35-
public async launchDebugger(options: LaunchOptions, callback?: () => void): Promise<void> {
35+
public async launchDebugger(
36+
options: LaunchOptions,
37+
callback?: () => void,
38+
sessionOptions?: DebugSessionOptions,
39+
): Promise<void> {
3640
const deferred = createDeferred<void>();
3741
let hasCallbackBeenCalled = false;
3842
if (options.token && options.token.isCancellationRequested) {
@@ -57,7 +61,7 @@ export class DebugLauncher implements ITestDebugLauncher {
5761
const debugManager = this.serviceContainer.get<IDebugService>(IDebugService);
5862

5963
let activatedDebugSession: DebugSession | undefined;
60-
debugManager.startDebugging(workspaceFolder, launchArgs).then(() => {
64+
debugManager.startDebugging(workspaceFolder, launchArgs, sessionOptions).then(() => {
6165
// Save the debug session after it is started so we can check if it is the one that was terminated.
6266
activatedDebugSession = debugManager.activeDebugSession;
6367
});

src/client/testing/common/types.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { CancellationToken, Disposable, OutputChannel, Uri } from 'vscode';
1+
import { CancellationToken, DebugSessionOptions, Disposable, OutputChannel, Uri } from 'vscode';
22
import { Product } from '../../common/types';
33
import { TestSettingsPropertyNames } from '../configuration/types';
44
import { TestProvider } from '../types';
@@ -89,7 +89,7 @@ export interface ITestConfigurationManagerFactory {
8989
}
9090
export const ITestDebugLauncher = Symbol('ITestDebugLauncher');
9191
export interface ITestDebugLauncher {
92-
launchDebugger(options: LaunchOptions, callback?: () => void): Promise<void>;
92+
launchDebugger(options: LaunchOptions, callback?: () => void, sessionOptions?: DebugSessionOptions): Promise<void>;
9393
}
9494

9595
export const IUnitTestSocketServer = Symbol('IUnitTestSocketServer');

src/client/testing/testController/pytest/pytestExecutionAdapter.ts

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
// Copyright (c) Microsoft Corporation. All rights reserved.
22
// Licensed under the MIT License.
33

4-
import { CancellationTokenSource, TestRun, TestRunProfileKind, Uri } from 'vscode';
4+
import { CancellationTokenSource, DebugSessionOptions, TestRun, TestRunProfileKind, Uri } from 'vscode';
55
import * as path from 'path';
66
import { ChildProcess } from 'child_process';
77
import { IConfigurationService, ITestOutputChannel } from '../../../common/types';
@@ -167,10 +167,17 @@ export class PytestTestExecutionAdapter implements ITestExecutionAdapter {
167167
runTestIdsPort: testIdsFileName,
168168
pytestPort: resultNamedPipeName,
169169
};
170+
const sessionOptions: DebugSessionOptions = {
171+
testRun: runInstance,
172+
};
170173
traceInfo(`Running DEBUG pytest with arguments: ${testArgs} for workspace ${uri.fsPath} \r\n`);
171-
await debugLauncher!.launchDebugger(launchOptions, () => {
172-
serverCancel.cancel();
173-
});
174+
await debugLauncher!.launchDebugger(
175+
launchOptions,
176+
() => {
177+
serverCancel.cancel();
178+
},
179+
sessionOptions,
180+
);
174181
} else {
175182
// deferredTillExecClose is resolved when all stdout and stderr is read
176183
const deferredTillExecClose: Deferred<void> = utils.createTestingDeferred();

src/client/testing/testController/unittest/testExecutionAdapter.ts

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
// Licensed under the MIT License.
33

44
import * as path from 'path';
5-
import { CancellationTokenSource, TestRun, TestRunProfileKind, Uri } from 'vscode';
5+
import { CancellationTokenSource, DebugSessionOptions, TestRun, TestRunProfileKind, Uri } from 'vscode';
66
import { ChildProcess } from 'child_process';
77
import { IConfigurationService, ITestOutputChannel } from '../../../common/types';
88
import { Deferred, createDeferred } from '../../../common/utils/async';
@@ -166,15 +166,22 @@ export class UnittestTestExecutionAdapter implements ITestExecutionAdapter {
166166
runTestIdsPort: testIdsFileName,
167167
pytestPort: resultNamedPipeName, // change this from pytest
168168
};
169+
const sessionOptions: DebugSessionOptions = {
170+
testRun: runInstance,
171+
};
169172
traceInfo(`Running DEBUG unittest for workspace ${options.cwd} with arguments: ${args}\r\n`);
170173

171174
if (debugLauncher === undefined) {
172175
traceError('Debug launcher is not defined');
173176
throw new Error('Debug launcher is not defined');
174177
}
175-
await debugLauncher.launchDebugger(launchOptions, () => {
176-
serverCancel.cancel();
177-
});
178+
await debugLauncher.launchDebugger(
179+
launchOptions,
180+
() => {
181+
serverCancel.cancel();
182+
},
183+
sessionOptions,
184+
);
178185
} else {
179186
// This means it is running the test
180187
traceInfo(`Running unittests for workspace ${cwd} with arguments: ${args}\r\n`);

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

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,9 @@ suite('Unit Tests - Debug Launcher', () => {
129129
const deferred = createDeferred<void>();
130130

131131
debugService
132-
.setup((d) => d.startDebugging(TypeMoq.It.isValue(workspaceFolder), TypeMoq.It.isValue(expected)))
132+
.setup((d) =>
133+
d.startDebugging(TypeMoq.It.isValue(workspaceFolder), TypeMoq.It.isValue(expected), undefined),
134+
)
133135
.returns((_wspc: WorkspaceFolder, _expectedParam: DebugConfiguration) => {
134136
deferred.resolve();
135137
return Promise.resolve(undefined as any);
@@ -299,7 +301,7 @@ suite('Unit Tests - Debug Launcher', () => {
299301
});
300302
test(`Must not launch debugger if cancelled ${testTitleSuffix}`, async () => {
301303
debugService
302-
.setup((d) => d.startDebugging(TypeMoq.It.isAny(), TypeMoq.It.isAny()))
304+
.setup((d) => d.startDebugging(TypeMoq.It.isAny(), TypeMoq.It.isAny(), TypeMoq.It.isAny()))
303305
.returns(() => {
304306
return Promise.resolve(undefined as any);
305307
})

src/test/testing/testController/pytest/pytestExecutionAdapter.unit.test.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
// Copyright (c) Microsoft Corporation. All rights reserved.
33
// Licensed under the MIT License.
44
import * as assert from 'assert';
5-
import { TestRun, Uri, TestRunProfileKind } from 'vscode';
5+
import { TestRun, Uri, TestRunProfileKind, DebugSessionOptions } from 'vscode';
66
import * as typeMoq from 'typemoq';
77
import * as sinon from 'sinon';
88
import * as path from 'path';
@@ -238,7 +238,7 @@ suite('pytest test execution adapter', () => {
238238
const deferred3 = createDeferred();
239239
utilsWriteTestIdsFileStub.callsFake(() => Promise.resolve('testIdPipe-mockName'));
240240
debugLauncher
241-
.setup((dl) => dl.launchDebugger(typeMoq.It.isAny(), typeMoq.It.isAny()))
241+
.setup((dl) => dl.launchDebugger(typeMoq.It.isAny(), typeMoq.It.isAny(), typeMoq.It.isAny()))
242242
.returns(async (_opts, callback) => {
243243
traceInfo('stubs launch debugger');
244244
if (typeof callback === 'function') {
@@ -273,6 +273,10 @@ suite('pytest test execution adapter', () => {
273273
return true;
274274
}),
275275
typeMoq.It.isAny(),
276+
typeMoq.It.is<DebugSessionOptions>((sessionOptions) => {
277+
assert.equal(sessionOptions.testRun, testRun.object);
278+
return true;
279+
}),
276280
),
277281
typeMoq.Times.once(),
278282
);

src/test/testing/testController/testCancellationRunAdapters.unit.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -185,7 +185,7 @@ suite('Execution Flow Run Adapters', () => {
185185

186186
// debugLauncher mocked
187187
debugLauncher
188-
.setup((dl) => dl.launchDebugger(typeMoq.It.isAny(), typeMoq.It.isAny()))
188+
.setup((dl) => dl.launchDebugger(typeMoq.It.isAny(), typeMoq.It.isAny(), typeMoq.It.isAny()))
189189
.callback((_options, callback) => {
190190
if (callback) {
191191
callback();

src/test/testing/testController/unittest/testExecutionAdapter.unit.test.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
// Copyright (c) Microsoft Corporation. All rights reserved.
33
// Licensed under the MIT License.
44
import * as assert from 'assert';
5-
import { TestRun, TestRunProfileKind, Uri } from 'vscode';
5+
import { DebugSessionOptions, TestRun, TestRunProfileKind, Uri } from 'vscode';
66
import * as typeMoq from 'typemoq';
77
import * as sinon from 'sinon';
88
import * as path from 'path';
@@ -237,7 +237,7 @@ suite('Unittest test execution adapter', () => {
237237
const deferred3 = createDeferred();
238238
utilsWriteTestIdsFileStub.callsFake(() => Promise.resolve('testIdPipe-mockName'));
239239
debugLauncher
240-
.setup((dl) => dl.launchDebugger(typeMoq.It.isAny(), typeMoq.It.isAny()))
240+
.setup((dl) => dl.launchDebugger(typeMoq.It.isAny(), typeMoq.It.isAny(), typeMoq.It.isAny()))
241241
.returns(async (_opts, callback) => {
242242
traceInfo('stubs launch debugger');
243243
if (typeof callback === 'function') {
@@ -271,6 +271,10 @@ suite('Unittest test execution adapter', () => {
271271
return true;
272272
}),
273273
typeMoq.It.isAny(),
274+
typeMoq.It.is<DebugSessionOptions>((sessionOptions) => {
275+
assert.equal(sessionOptions.testRun, testRun.object);
276+
return true;
277+
}),
274278
),
275279
typeMoq.Times.once(),
276280
);

0 commit comments

Comments
 (0)