Skip to content

Commit d9617cf

Browse files
eleanorjboydanthonykim1
authored andcommitted
Revert "Debug cancelation (microsoft#23262)" (microsoft#23301)
This reverts commit 51cf852. CI has been failing and we need CI to pass to get out a build of insiders and prep for the release.
1 parent e6fb6c2 commit d9617cf

File tree

5 files changed

+6
-235
lines changed

5 files changed

+6
-235
lines changed

src/client/testing/common/debugLauncher.ts

+3-25
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 { debug, DebugConfiguration, Disposable, l10n, Uri, WorkspaceFolder } from 'vscode';
3+
import { DebugConfiguration, l10n, Uri, WorkspaceFolder } 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, traceLog } from '../../logging';
12+
import { traceError } from '../../logging';
1313
import { TestProvider } from '../types';
1414
import { ITestDebugLauncher, LaunchOptions } from './types';
1515
import { getConfigurationsForWorkspace } from '../../debugger/extension/configuration/launch.json/launchJsonReader';
@@ -48,29 +48,7 @@ export class DebugLauncher implements ITestDebugLauncher {
4848
);
4949
const debugManager = this.serviceContainer.get<IDebugService>(IDebugService);
5050

51-
let disposeOfDebugger: Disposable | undefined;
52-
const disposeOfStartDebugging = debugManager.onDidStartDebugSession((session) => {
53-
if (options.token) {
54-
disposeOfDebugger = options?.token.onCancellationRequested(() => {
55-
console.log('Canceling debugger, due to cancelation token called.');
56-
debug.stopDebugging(session);
57-
});
58-
}
59-
});
60-
61-
let disposeTerminateWatcher: Disposable | undefined;
62-
// eslint-disable-next-line prefer-const
63-
disposeTerminateWatcher = debugManager.onDidTerminateDebugSession(() => {
64-
traceLog('Terminating the debugging session and disposing of debugger listeners.');
65-
if (disposeOfDebugger !== undefined) {
66-
disposeOfDebugger.dispose();
67-
}
68-
if (disposeOfStartDebugging !== undefined) {
69-
disposeOfStartDebugging.dispose();
70-
}
71-
if (disposeTerminateWatcher !== undefined) {
72-
disposeTerminateWatcher.dispose();
73-
}
51+
debugManager.onDidTerminateDebugSession(() => {
7452
deferred.resolve();
7553
callback?.();
7654
});

src/client/testing/testController/common/utils.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -220,7 +220,7 @@ export async function startRunResultNamedPipe(
220220
perConnectionDisposables.push(
221221
// per connection, add a listener for the cancellation token and the data
222222
cancellationToken?.onCancellationRequested(() => {
223-
traceVerbose(`Test Result named pipe ${pipeName} cancelled`);
223+
console.log(`Test Result named pipe ${pipeName} cancelled`);
224224
// if cancel is called on one connection, dispose of all connections
225225
disposeOfServer();
226226
}),

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

-1
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,6 @@ export class PytestTestExecutionAdapter implements ITestExecutionAdapter {
167167
};
168168
traceInfo(`Running DEBUG pytest with arguments: ${testArgs} for workspace ${uri.fsPath} \r\n`);
169169
await debugLauncher!.launchDebugger(launchOptions, () => {
170-
traceInfo("Debugger callback called, resolving 'till EOT' deferred for the workspace.");
171170
serverDispose(); // this will resolve deferredTillServerClose
172171
deferredTillEOT?.resolve();
173172
});

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

-6
Original file line numberDiff line numberDiff line change
@@ -139,12 +139,6 @@ suite('Unit Tests - Debug Launcher', () => {
139139
return undefined as any;
140140
})
141141
.verifiable(TypeMoq.Times.once());
142-
debugService
143-
.setup((d) => d.onDidStartDebugSession(TypeMoq.It.isAny()))
144-
.returns(() => {
145-
return undefined as any;
146-
})
147-
.verifiable(TypeMoq.Times.once());
148142
}
149143
function createWorkspaceFolder(folderPath: string): WorkspaceFolder {
150144
return {

src/test/testing/common/testingAdapter.test.ts

+2-202
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,15 @@
11
/* eslint-disable @typescript-eslint/no-explicit-any */
22
// Copyright (c) Microsoft Corporation. All rights reserved.
33
// Licensed under the MIT License.
4-
import { CancellationTokenSource, DebugSession, TestController, TestRun, Uri, debug } from 'vscode';
4+
import { TestController, TestRun, Uri } from 'vscode';
55
import * as typeMoq from 'typemoq';
66
import * as path from 'path';
77
import * as assert from 'assert';
88
import * as fs from 'fs';
9-
import * as sinon from 'sinon';
10-
import { Observable } from 'rxjs';
119
import * as os from 'os';
1210
import { PytestTestDiscoveryAdapter } from '../../../client/testing/testController/pytest/pytestDiscoveryAdapter';
1311
import { ITestController, ITestResultResolver } from '../../../client/testing/testController/common/types';
14-
import { IPythonExecutionFactory, IPythonExecutionService, Output } from '../../../client/common/process/types';
12+
import { IPythonExecutionFactory } from '../../../client/common/process/types';
1513
import { IConfigurationService, ITestOutputChannel } from '../../../client/common/types';
1614
import { IServiceContainer } from '../../../client/ioc/types';
1715
import { EXTENSION_ROOT_DIR_FOR_TESTS, initialize } from '../../initialize';
@@ -23,9 +21,6 @@ import { PythonResultResolver } from '../../../client/testing/testController/com
2321
import { TestProvider } from '../../../client/testing/types';
2422
import { PYTEST_PROVIDER, UNITTEST_PROVIDER } from '../../../client/testing/common/constants';
2523
import { IEnvironmentVariablesProvider } from '../../../client/common/variables/types';
26-
import { ITestDebugLauncher } from '../../../client/testing/common/types';
27-
import { MockChildProcess } from '../../mocks/mockChildProcess';
28-
import { createDeferred } from '../../../client/common/utils/async';
2924

3025
suite('End to End Tests: test adapters', () => {
3126
let resultResolver: ITestResultResolver;
@@ -155,9 +150,6 @@ suite('End to End Tests: test adapters', () => {
155150
traceLog('Symlink was not found to remove after tests, exiting successfully, nestedSymlink.');
156151
}
157152
});
158-
teardown(async () => {
159-
sinon.restore();
160-
});
161153
test('unittest discovery adapter small workspace', async () => {
162154
// result resolver and saved data for assertions
163155
let actualData: {
@@ -1081,196 +1073,4 @@ suite('End to End Tests: test adapters', () => {
10811073
assert.strictEqual(failureOccurred, false, failureMsg);
10821074
});
10831075
});
1084-
test('Pytest debug cancelation', async () => {
1085-
const debugLauncher = serviceContainer.get<ITestDebugLauncher>(ITestDebugLauncher);
1086-
const stopDebuggingStub = sinon.stub(debug, 'stopDebugging');
1087-
let calledStopDebugging = false;
1088-
stopDebuggingStub.callsFake(() => {
1089-
calledStopDebugging = true;
1090-
return Promise.resolve();
1091-
});
1092-
1093-
// // mock exec service and exec factory, not very necessary for this test
1094-
const execServiceStub = typeMoq.Mock.ofType<IPythonExecutionService>();
1095-
const execFactoryStub = typeMoq.Mock.ofType<IPythonExecutionFactory>();
1096-
const cancellationTokenSource = new CancellationTokenSource();
1097-
let mockProc: MockChildProcess;
1098-
execServiceStub
1099-
.setup((x) => x.execObservable(typeMoq.It.isAny(), typeMoq.It.isAny()))
1100-
.returns(() => ({
1101-
proc: mockProc,
1102-
out: typeMoq.Mock.ofType<Observable<Output<string>>>().object,
1103-
dispose: () => {
1104-
/* no-body */
1105-
},
1106-
}));
1107-
execFactoryStub
1108-
.setup((x) => x.createActivatedEnvironment(typeMoq.It.isAny()))
1109-
.returns(() => Promise.resolve(execServiceStub.object));
1110-
execFactoryStub.setup((p) => ((p as unknown) as any).then).returns(() => undefined);
1111-
execServiceStub.setup((p) => ((p as unknown) as any).then).returns(() => undefined);
1112-
1113-
resultResolver = new PythonResultResolver(testController, pytestProvider, workspaceUri);
1114-
1115-
const testId = `${rootPathErrorWorkspace}/test_seg_fault.py::TestSegmentationFault::test_segfault`;
1116-
const testIds: string[] = [testId];
1117-
1118-
// set workspace to test workspace folder
1119-
workspaceUri = Uri.parse(rootPathErrorWorkspace);
1120-
configService.getSettings(workspaceUri).testing.pytestArgs = [];
1121-
1122-
const debugSessionStub = typeMoq.Mock.ofType<DebugSession>();
1123-
sinon.stub(debug, 'onDidStartDebugSession').callsFake((cb) => {
1124-
// run the callback right away to add the cancelation token listener
1125-
cb(debugSessionStub.object);
1126-
return {
1127-
dispose: () => {
1128-
/* no-body */
1129-
},
1130-
};
1131-
});
1132-
const awaitStopDebugging = createDeferred();
1133-
1134-
sinon.stub(debug, 'onDidTerminateDebugSession').callsFake((cb) => {
1135-
// wait for the stop debugging to be called before resolving the promise
1136-
// the terminate debug session does cleanup
1137-
awaitStopDebugging.promise.then(() => {
1138-
cb(debugSessionStub.object);
1139-
});
1140-
return {
1141-
dispose: () => {
1142-
// void
1143-
},
1144-
};
1145-
});
1146-
// handle cancelation token from debugger
1147-
sinon.stub(debug, 'startDebugging').callsFake((folder, nameOrConfiguration, _parentSession) => {
1148-
// check to make sure start debugging is called correctly
1149-
if (typeof nameOrConfiguration !== 'string') {
1150-
assert.strictEqual(nameOrConfiguration.type, 'debugpy', 'Expected debugpy');
1151-
} else {
1152-
assert.fail('Expected nameOrConfiguration to be an object');
1153-
}
1154-
assert.ok(folder, 'Expected folder to be defined');
1155-
assert.strictEqual(folder.name, 'test', 'Expected folder name to be test');
1156-
// cancel the token and trigger the stop debugging callback
1157-
awaitStopDebugging.resolve();
1158-
cancellationTokenSource.cancel();
1159-
return Promise.resolve(true);
1160-
});
1161-
1162-
// run pytest execution
1163-
const executionAdapter = new PytestTestExecutionAdapter(
1164-
configService,
1165-
testOutputChannel.object,
1166-
resultResolver,
1167-
envVarsService,
1168-
);
1169-
1170-
const testRun = typeMoq.Mock.ofType<TestRun>();
1171-
testRun.setup((t) => t.token).returns(() => cancellationTokenSource.token);
1172-
1173-
await executionAdapter
1174-
.runTests(workspaceUri, testIds, true, testRun.object, pythonExecFactory, debugLauncher)
1175-
.finally(() => {
1176-
// verify that the stop debugging was called
1177-
assert.ok(calledStopDebugging, 'Expected stopDebugging to be called');
1178-
});
1179-
});
1180-
test('UNITTEST debug cancelation', async () => {
1181-
const debugLauncher = serviceContainer.get<ITestDebugLauncher>(ITestDebugLauncher);
1182-
const stopDebuggingStub = sinon.stub(debug, 'stopDebugging');
1183-
let calledStopDebugging = false;
1184-
stopDebuggingStub.callsFake(() => {
1185-
calledStopDebugging = true;
1186-
return Promise.resolve();
1187-
});
1188-
1189-
// // mock exec service and exec factory, not very necessary for this test
1190-
const execServiceStub = typeMoq.Mock.ofType<IPythonExecutionService>();
1191-
const execFactoryStub = typeMoq.Mock.ofType<IPythonExecutionFactory>();
1192-
const cancellationTokenSource = new CancellationTokenSource();
1193-
let mockProc: MockChildProcess;
1194-
execServiceStub
1195-
.setup((x) => x.execObservable(typeMoq.It.isAny(), typeMoq.It.isAny()))
1196-
.returns(() => ({
1197-
proc: mockProc,
1198-
out: typeMoq.Mock.ofType<Observable<Output<string>>>().object,
1199-
dispose: () => {
1200-
/* no-body */
1201-
},
1202-
}));
1203-
execFactoryStub
1204-
.setup((x) => x.createActivatedEnvironment(typeMoq.It.isAny()))
1205-
.returns(() => Promise.resolve(execServiceStub.object));
1206-
execFactoryStub.setup((p) => ((p as unknown) as any).then).returns(() => undefined);
1207-
execServiceStub.setup((p) => ((p as unknown) as any).then).returns(() => undefined);
1208-
1209-
resultResolver = new PythonResultResolver(testController, pytestProvider, workspaceUri);
1210-
1211-
const testId = `${rootPathErrorWorkspace}/test_seg_fault.py::TestSegmentationFault::test_segfault`;
1212-
const testIds: string[] = [testId];
1213-
1214-
// set workspace to test workspace folder
1215-
workspaceUri = Uri.parse(rootPathErrorWorkspace);
1216-
configService.getSettings(workspaceUri).testing.pytestArgs = [];
1217-
1218-
const debugSessionStub = typeMoq.Mock.ofType<DebugSession>();
1219-
sinon.stub(debug, 'onDidStartDebugSession').callsFake((cb) => {
1220-
// run the callback right away to add the cancelation token listener
1221-
cb(debugSessionStub.object);
1222-
return {
1223-
dispose: () => {
1224-
/* no-body */
1225-
},
1226-
};
1227-
});
1228-
const awaitStopDebugging = createDeferred();
1229-
1230-
sinon.stub(debug, 'onDidTerminateDebugSession').callsFake((cb) => {
1231-
// wait for the stop debugging to be called before resolving the promise
1232-
// the terminate debug session does cleanup
1233-
awaitStopDebugging.promise.then(() => {
1234-
cb(debugSessionStub.object);
1235-
});
1236-
return {
1237-
dispose: () => {
1238-
// void
1239-
},
1240-
};
1241-
});
1242-
// handle cancelation token from debugger
1243-
sinon.stub(debug, 'startDebugging').callsFake((folder, nameOrConfiguration, _parentSession) => {
1244-
// check to make sure start debugging is called correctly
1245-
if (typeof nameOrConfiguration !== 'string') {
1246-
assert.strictEqual(nameOrConfiguration.type, 'debugpy', 'Expected debugpy');
1247-
} else {
1248-
assert.fail('Expected nameOrConfiguration to be an object');
1249-
}
1250-
assert.ok(folder, 'Expected folder to be defined');
1251-
assert.strictEqual(folder.name, 'test', 'Expected folder name to be test');
1252-
// cancel the token and trigger the stop debugging callback
1253-
awaitStopDebugging.resolve();
1254-
cancellationTokenSource.cancel();
1255-
return Promise.resolve(true);
1256-
});
1257-
1258-
// run pytest execution
1259-
const executionAdapter = new UnittestTestExecutionAdapter(
1260-
configService,
1261-
testOutputChannel.object,
1262-
resultResolver,
1263-
envVarsService,
1264-
);
1265-
1266-
const testRun = typeMoq.Mock.ofType<TestRun>();
1267-
testRun.setup((t) => t.token).returns(() => cancellationTokenSource.token);
1268-
1269-
await executionAdapter
1270-
.runTests(workspaceUri, testIds, true, testRun.object, pythonExecFactory, debugLauncher)
1271-
.finally(() => {
1272-
// verify that the stop debugging was called
1273-
assert.ok(calledStopDebugging, 'Expected stopDebugging to be called');
1274-
});
1275-
});
12761076
});

0 commit comments

Comments
 (0)