Skip to content

Commit 2fd7b69

Browse files
authored
Unit tests for debugging module (#1297)
Fixes #1188
1 parent 3e40ce2 commit 2fd7b69

File tree

13 files changed

+98
-21
lines changed

13 files changed

+98
-21
lines changed

.vscode/settings.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,9 @@
1414
"coverage": true
1515
},
1616
"typescript.tsdk": "./node_modules/typescript/lib", // we want to use the TS server from our node_modules folder to control its version
17-
"tslint.enable": true, // We will run our own linting in gulp (& git commit hooks), else tslint extension just complains about unmodified files
17+
"tslint.enable": true,
1818
"python.linting.enabled": false,
1919
"python.unitTest.promptToConfigure": false,
2020
"python.workspaceSymbols.enabled": false,
2121
"python.formatting.provider": "none"
22-
}
22+
}

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1036,7 +1036,7 @@
10361036
{
10371037
"name": "Python Experimental: Attach",
10381038
"type": "pythonExperimental",
1039-
"request": "pythonExperimental",
1039+
"request": "attach",
10401040
"localRoot": "${workspaceFolder}",
10411041
"remoteRoot": "${workspaceFolder}",
10421042
"port": 3000,

src/client/common/helpers.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,9 @@ export interface Deferred<T> {
2929
}
3030

3131
class DeferredImpl<T> implements Deferred<T> {
32-
private _resolve: (value?: T | PromiseLike<T>) => void;
32+
private _resolve!: (value?: T | PromiseLike<T>) => void;
3333
// tslint:disable-next-line:no-any
34-
private _reject: (reason?: any) => void;
34+
private _reject!: (reason?: any) => void;
3535
private _resolved: boolean = false;
3636
private _rejected: boolean = false;
3737
private _promise: Promise<T>;
@@ -70,14 +70,14 @@ export function createDeferred<T>(scope: any = null): Deferred<T> {
7070
return new DeferredImpl<T>(scope);
7171
}
7272

73-
export function createTemporaryFile(extension: string, temporaryDirectory?: string): Promise<{ filePath: string, cleanupCallback: Function }> {
73+
export function createTemporaryFile(extension: string, temporaryDirectory?: string): Promise<{ filePath: string; cleanupCallback: Function }> {
7474
// tslint:disable-next-line:no-any
7575
const options: any = { postfix: extension };
7676
if (temporaryDirectory) {
7777
options.dir = temporaryDirectory;
7878
}
7979

80-
return new Promise<{ filePath: string, cleanupCallback: Function }>((resolve, reject) => {
80+
return new Promise<{ filePath: string; cleanupCallback: Function }>((resolve, reject) => {
8181
tmp.file(options, (err, tmpFile, fd, cleanupCallback) => {
8282
if (err) {
8383
return reject(err);
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
// Copyright (c) Microsoft Corporation. All rights reserved.
2+
// Licensed under the MIT License.
3+
4+
'use strict';
5+
6+
import * as path from 'path';
7+
import { EXTENSION_ROOT_DIR } from '../../common/constants';
8+
9+
export const PTVSD_PATH = path.join(EXTENSION_ROOT_DIR, 'pythonFiles', 'experimental', 'ptvsd');

src/client/debugger/DebugClients/LocalDebugClient.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,12 @@ import { ChildProcess, spawn } from 'child_process';
22
import * as path from 'path';
33
import { DebugSession, OutputEvent } from 'vscode-debugadapter';
44
import { DebugProtocol } from 'vscode-debugprotocol';
5-
import { EXTENSION_ROOT_DIR } from '../../common/constants';
65
import { open } from '../../common/open';
76
import { PathUtils } from '../../common/platform/pathUtils';
87
import { CurrentProcess } from '../../common/process/currentProcess';
98
import { EnvironmentVariablesService } from '../../common/variables/environment';
109
import { IServiceContainer } from '../../ioc/types';
10+
import { PTVSD_PATH } from '../Common/constants';
1111
import { DebugOptions, IDebugServer, IPythonProcess, LaunchRequestArguments } from '../Common/Contracts';
1212
import { IS_WINDOWS } from '../Common/Utils';
1313
import { BaseDebugServer } from '../DebugServers/BaseDebugServer';
@@ -88,8 +88,7 @@ export class LocalDebugClient extends DebugClient<LaunchRequestArguments> {
8888
const environmentVariables = await helper.getEnvironmentVariables(this.args);
8989
if (this.args.type === 'pythonExperimental') {
9090
// Import the PTVSD debugger, allowing users to use their own latest copies.
91-
const experimentalPTVSDPath = path.join(EXTENSION_ROOT_DIR, 'pythonFiles', 'experimental', 'ptvsd');
92-
environmentVariablesService.appendPythonPath(environmentVariables, experimentalPTVSDPath);
91+
environmentVariablesService.appendPythonPath(environmentVariables, PTVSD_PATH);
9392
}
9493
// tslint:disable-next-line:max-func-body-length cyclomatic-complexity no-any
9594
return new Promise<any>((resolve, reject) => {

src/test/debugger/attach.ptvsd.test.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,13 @@ import * as path from 'path';
1111
import { DebugClient } from 'vscode-debugadapter-testsupport';
1212
import { EXTENSION_ROOT_DIR } from '../../client/common/constants';
1313
import '../../client/common/extensions';
14+
import { PTVSD_PATH } from '../../client/debugger/Common/constants';
1415
import { DebugOptions } from '../../client/debugger/Common/Contracts';
1516
import { sleep } from '../common';
1617
import { initialize, IS_APPVEYOR, IS_MULTI_ROOT_TEST, TEST_DEBUGGER } from '../initialize';
1718
import { continueDebugging, createDebugAdapter } from './utils';
1819

1920
const fileToDebug = path.join(EXTENSION_ROOT_DIR, 'src', 'testMultiRootWkspc', 'workspace5', 'remoteDebugger-start-with-ptvsd.py');
20-
const ptvsdPath = path.join(EXTENSION_ROOT_DIR, 'pythonFiles', 'experimental', 'ptvsd');
2121

2222
suite('Attach Debugger - Experimental', () => {
2323
let debugClient: DebugClient;
@@ -55,7 +55,7 @@ suite('Attach Debugger - Experimental', () => {
5555

5656
// Set the path for PTVSD to be picked up.
5757
// tslint:disable-next-line:no-string-literal
58-
customEnv['PYTHONPATH'] = ptvsdPath;
58+
customEnv['PYTHONPATH'] = PTVSD_PATH;
5959
const pythonArgs = ['-m', 'ptvsd', '--server', '--port', `${port}`, '--file', fileToDebug.fileToCommandArgument()];
6060
procToKill = spawn('python', pythonArgs, { env: customEnv, cwd: path.dirname(fileToDebug) });
6161

src/test/debugger/capabilities.test.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,11 @@ import { expect } from 'chai';
99
import { ChildProcess, spawn } from 'child_process';
1010
import * as getFreePort from 'get-port';
1111
import { connect, Socket } from 'net';
12-
import * as path from 'path';
1312
import { PassThrough } from 'stream';
1413
import { Message } from 'vscode-debugadapter/lib/messages';
1514
import { DebugProtocol } from 'vscode-debugprotocol';
16-
import { EXTENSION_ROOT_DIR } from '../../client/common/constants';
1715
import { createDeferred } from '../../client/common/helpers';
16+
import { PTVSD_PATH } from '../../client/debugger/Common/constants';
1817
import { ProtocolParser } from '../../client/debugger/Common/protocolParser';
1918
import { ProtocolMessageWriter } from '../../client/debugger/Common/protocolWriter';
2019
import { PythonDebugger } from '../../client/debugger/mainV2';
@@ -75,7 +74,7 @@ suite('Debugging - Capabilities', () => {
7574
const host = 'localhost';
7675
const port = await getFreePort({ host });
7776
const env = { ...process.env };
78-
env.PYTHONPATH = path.join(EXTENSION_ROOT_DIR, 'pythonFiles', 'experimental', 'ptvsd');
77+
env.PYTHONPATH = PTVSD_PATH;
7978
proc = spawn('python', ['-m', 'ptvsd', '--server', '--port', `${port}`, '--file', 'someFile.py'], { cwd: __dirname, env });
8079
// Wait for the socket server to start.
8180
// Keep trying till we timeout.

src/test/debugger/misc.test.ts

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import { noop } from '../../client/common/core.utils';
1313
import { IS_WINDOWS } from '../../client/common/platform/constants';
1414
import { FileSystem } from '../../client/common/platform/fileSystem';
1515
import { PlatformService } from '../../client/common/platform/platformService';
16+
import { PTVSD_PATH } from '../../client/debugger/Common/constants';
1617
import { DebugOptions, LaunchRequestArguments } from '../../client/debugger/Common/Contracts';
1718
import { sleep } from '../common';
1819
import { IS_MULTI_ROOT_TEST, TEST_DEBUGGER } from '../initialize';
@@ -69,8 +70,9 @@ let testCounter = 0;
6970
const env = {};
7071
if (debuggerType === 'pythonExperimental') {
7172
// tslint:disable-next-line:no-string-literal
72-
env['PYTHONPATH'] = path.join(EXTENSION_ROOT_DIR, 'pythonFiles', 'experimental', 'ptvsd');
73+
env['PYTHONPATH'] = PTVSD_PATH;
7374
}
75+
// tslint:disable-next-line:no-unnecessary-local-variable
7476
const options: LaunchRequestArguments = {
7577
program: path.join(debugFilesPath, pythonFile),
7678
cwd: debugFilesPath,
@@ -84,11 +86,6 @@ let testCounter = 0;
8486
type: debuggerType
8587
};
8688

87-
// Custom experimental debugger options (filled in by DebugConfigurationProvider).
88-
if (debuggerType === 'pythonExperimental') {
89-
(options as any).redirectOutput = true;
90-
}
91-
9289
return options;
9390
}
9491

src/test/debugger/module.test.ts

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
// Copyright (c) Microsoft Corporation. All rights reserved.
2+
// Licensed under the MIT License.
3+
4+
'use strict';
5+
6+
// tslint:disable:no-suspicious-comment max-func-body-length no-invalid-this no-var-requires no-require-imports no-any
7+
8+
import * as path from 'path';
9+
import { DebugClient } from 'vscode-debugadapter-testsupport';
10+
import { EXTENSION_ROOT_DIR } from '../../client/common/constants';
11+
import { noop } from '../../client/common/core.utils';
12+
import { PTVSD_PATH } from '../../client/debugger/Common/constants';
13+
import { DebugOptions, LaunchRequestArguments } from '../../client/debugger/Common/Contracts';
14+
import { sleep } from '../common';
15+
import { IS_MULTI_ROOT_TEST, TEST_DEBUGGER } from '../initialize';
16+
import { createDebugAdapter } from './utils';
17+
18+
const workspaceDirectory = path.join(EXTENSION_ROOT_DIR, 'src', 'testMultiRootWkspc', 'workspace5');
19+
const debuggerType = 'pythonExperimental';
20+
suite(`Module Debugging - Misc tests: ${debuggerType}`, () => {
21+
let debugClient: DebugClient;
22+
setup(async function () {
23+
if (!IS_MULTI_ROOT_TEST || !TEST_DEBUGGER) {
24+
this.skip();
25+
}
26+
const coverageDirectory = path.join(EXTENSION_ROOT_DIR, 'debug_coverage_module');
27+
debugClient = await createDebugAdapter(coverageDirectory);
28+
});
29+
teardown(async () => {
30+
// Wait for a second before starting another test (sometimes, sockets take a while to get closed).
31+
await sleep(1000);
32+
try {
33+
await debugClient.stop().catch(noop);
34+
// tslint:disable-next-line:no-empty
35+
} catch (ex) { }
36+
await sleep(1000);
37+
});
38+
function buildLauncArgs(): LaunchRequestArguments {
39+
const env = {};
40+
// tslint:disable-next-line:no-string-literal
41+
env['PYTHONPATH'] = `.${path.delimiter}${PTVSD_PATH}`;
42+
43+
// tslint:disable-next-line:no-unnecessary-local-variable
44+
const options: LaunchRequestArguments = {
45+
module: 'mymod',
46+
program: '',
47+
cwd: workspaceDirectory,
48+
debugOptions: [DebugOptions.RedirectOutput],
49+
pythonPath: 'python',
50+
args: [],
51+
env,
52+
envFile: '',
53+
logToFile: false,
54+
type: debuggerType
55+
};
56+
57+
return options;
58+
}
59+
60+
test('Test stdout output', async () => {
61+
await Promise.all([
62+
debugClient.configurationSequence(),
63+
debugClient.launch(buildLauncArgs()),
64+
debugClient.waitForEvent('initialized'),
65+
debugClient.assertOutput('stdout', 'Hello world!'),
66+
debugClient.waitForEvent('exited'),
67+
debugClient.waitForEvent('terminated')
68+
]);
69+
});
70+
});
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
import sys
2+
import time
23
sys.stderr.write('error output')
34
sys.stderr.flush()
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
import sys
2+
import time
23
sys.stdout.write('normal output')
34
sys.stdout.flush()

src/testMultiRootWkspc/workspace5/mymod/__init__.py

Whitespace-only changes.
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
print("Hello world!")

0 commit comments

Comments
 (0)