Skip to content

Commit 318aa39

Browse files
authored
Unit testing of experimental debugger on CI server
Fixes microsoft#742
1 parent 93c2bf8 commit 318aa39

8 files changed

Lines changed: 57 additions & 43 deletions

File tree

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,3 +13,4 @@ npm-debug.log
1313
coverage/
1414
.vscode-test/**
1515
.venv
16+
pythonFiles/experimental/ptvsd/**

.travis.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ before_install: |
2323
export TRAVIS_PYTHON_PATH=`which python`
2424
install:
2525
- pip install --upgrade -r requirements.txt
26+
- pip install -t ./pythonFiles/experimental/ptvsd git+https://github.com/Microsoft/ptvsd/
2627
- yarn
2728

2829
script:
@@ -33,6 +34,7 @@ script:
3334
- if [ $TRAVIS_UPLOAD_COVERAGE == "true" ]; then
3435
bash <(curl -s https://codecov.io/bash);
3536
fi
37+
- rm -rf ./pythonFiles/experimental/ptvsd
3638
- yarn run clean
3739
- yarn run vscode:prepublish
3840
- yarn run cover:enable

appveyor.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ install:
1515
- yarn
1616
- "SET PATH=%PYTHON%;%PYTHON%\\Scripts;%PATH%"
1717
- pip install -U pip
18+
- pip install -t ./pythonFiles/experimental/ptvsd git+https://github.com/Microsoft/ptvsd/
1819
- python --version
1920
- python -m easy_install -U setuptools
2021
- "%PYTHON%/Scripts/pip.exe install --upgrade -r requirements.txt"

news/3 Code Health/742.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Enable unit testing of the experimental debugger on CI servers

src/client/common/constants.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
1+
import * as path from 'path';
22
export const PythonLanguage = { language: 'python' };
33

44
export namespace Commands {
@@ -69,3 +69,5 @@ export function isTestExecution(): boolean {
6969
// tslint:disable-next-line:interface-name no-string-literal
7070
return process.env['VSC_PYTHON_CI_TEST'] === '1';
7171
}
72+
73+
export const EXTENSION_ROOT_DIR = path.join(__dirname, '..', '..', '..');

src/client/debugger/DebugClients/LocalDebugClient.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { ChildProcess } from 'child_process';
33
import * as path from 'path';
44
import { DebugSession, OutputEvent } from 'vscode-debugadapter';
55
import { DebugProtocol } from 'vscode-debugprotocol';
6+
import { EXTENSION_ROOT_DIR } from '../../common/constants';
67
import { open } from '../../common/open';
78
import { PathUtils } from '../../common/platform/pathUtils';
89
import { CurrentProcess } from '../../common/process/currentProcess';
@@ -82,8 +83,14 @@ export class LocalDebugClient extends DebugClient<LaunchRequestArguments> {
8283
public async LaunchApplicationToDebug(dbgServer: IDebugServer): Promise<any> {
8384
const pathUtils = new PathUtils(IS_WINDOWS);
8485
const currentProcess = new CurrentProcess();
85-
const helper = new DebugClientHelper(new EnvironmentVariablesService(pathUtils), pathUtils, currentProcess);
86+
const environmentVariablesService = new EnvironmentVariablesService(pathUtils);
87+
const helper = new DebugClientHelper(environmentVariablesService, pathUtils, currentProcess);
8688
const environmentVariables = await helper.getEnvironmentVariables(this.args);
89+
if (this.args.type === 'pythonExperimental') {
90+
// 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);
93+
}
8794
// tslint:disable-next-line:max-func-body-length cyclomatic-complexity no-any
8895
return new Promise<any>((resolve, reject) => {
8996
const fileDir = this.args && this.args.program ? path.dirname(this.args.program) : '';

src/test/debugger/misc.test.ts

Lines changed: 38 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,10 @@ import * as path from 'path';
99
import { ThreadEvent } from 'vscode-debugadapter';
1010
import { DebugClient } from 'vscode-debugadapter-testsupport';
1111
import { DebugProtocol } from 'vscode-debugprotocol';
12+
import { noop } from '../../client/common/core.utils';
1213
import { LaunchRequestArguments } from '../../client/debugger/Common/Contracts';
1314
import { sleep } from '../common';
14-
import { IS_CI_SERVER, IS_MULTI_ROOT_TEST, TEST_DEBUGGER } from '../initialize';
15+
import { IS_MULTI_ROOT_TEST, TEST_DEBUGGER } from '../initialize';
1516

1617
const isProcessRunning = require('is-running') as (number) => boolean;
1718

@@ -34,10 +35,6 @@ const THREAD_TIMEOUT = 10000;
3435
if (!IS_MULTI_ROOT_TEST || !TEST_DEBUGGER) {
3536
this.skip();
3637
}
37-
// Temporary, untill new version of PTVSD is bundled we cannot run tests
38-
if (debuggerType !== 'python' && IS_CI_SERVER) {
39-
return this.skip();
40-
}
4138
await new Promise(resolve => setTimeout(resolve, 1000));
4239
debugClient = new DebugClient('node', testAdapterFilePath, debuggerType);
4340
await debugClient.start();
@@ -46,26 +43,20 @@ const THREAD_TIMEOUT = 10000;
4643
// Wait for a second before starting another test (sometimes, sockets take a while to get closed).
4744
await sleep(1000);
4845
try {
49-
// tslint:disable-next-line:no-empty
50-
await debugClient.stop().catch(() => { });
46+
await debugClient.stop().catch(noop);
5147
// tslint:disable-next-line:no-empty
5248
} catch (ex) { }
5349
await sleep(1000);
5450
});
55-
5651
function buildLauncArgs(pythonFile: string, stopOnEntry: boolean = false): LaunchRequestArguments {
57-
// Temporary, untill new version of PTVSD is bundled we cannot run tests.
58-
// For now lets run test locally.
59-
const pythonPath = debuggerType === 'python' ? 'python' : '/Users/donjayamanne/Desktop/Development/PythonStuff/IssueRepos/debuggerTests/.envp36/bin/python';
60-
const env = debuggerType === 'python' ? {} : { PYTHONPATH: '/Users/donjayamanne/Desktop/Development/PythonStuff/IssueRepos/expPTVSD/ptvsd' };
6152
return {
6253
program: path.join(debugFilesPath, pythonFile),
6354
cwd: debugFilesPath,
6455
stopOnEntry,
6556
debugOptions: ['RedirectOutput'],
66-
pythonPath,
57+
pythonPath: 'python',
6758
args: [],
68-
env,
59+
env: {},
6960
envFile: '',
7061
logToFile: false,
7162
type: debuggerType
@@ -325,17 +316,23 @@ const THREAD_TIMEOUT = 10000;
325316
const threadId = ((await threadIdPromise) as ThreadEvent).body.threadId;
326317
await debugClient.assertStoppedLocation('breakpoint', breakpointLocation);
327318

328-
await debugClient.nextRequest({ threadId });
329319
const functionLocation = { path: path.join(debugFilesPath, 'sample2.py'), column: 1, line: 7 };
330-
await debugClient.assertStoppedLocation('step', functionLocation);
320+
await Promise.all([
321+
debugClient.nextRequest({ threadId }),
322+
debugClient.assertStoppedLocation('step', functionLocation)
323+
]);
331324

332-
await debugClient.nextRequest({ threadId });
333325
const functionInvocationLocation = { path: path.join(debugFilesPath, 'sample2.py'), column: 1, line: 11 };
334-
await debugClient.assertStoppedLocation('step', functionInvocationLocation);
326+
await Promise.all([
327+
debugClient.nextRequest({ threadId }),
328+
debugClient.assertStoppedLocation('step', functionInvocationLocation)
329+
]);
335330

336-
await debugClient.nextRequest({ threadId });
337331
const printLocation = { path: path.join(debugFilesPath, 'sample2.py'), column: 1, line: 13 };
338-
await debugClient.assertStoppedLocation('step', printLocation);
332+
await Promise.all([
333+
debugClient.nextRequest({ threadId }),
334+
debugClient.assertStoppedLocation('step', printLocation)
335+
]);
339336
});
340337
test('Test stepin and stepout', async () => {
341338
const threadIdPromise = debugClient.waitForEvent('thread', THREAD_TIMEOUT);
@@ -357,28 +354,37 @@ const THREAD_TIMEOUT = 10000;
357354
await debugClient.assertStoppedLocation('breakpoint', breakpointLocation);
358355
const threadId = ((await threadIdPromise) as ThreadEvent).body.threadId;
359356

360-
await debugClient.nextRequest({ threadId });
361357
const functionLocation = { path: path.join(debugFilesPath, 'sample2.py'), column: 1, line: 7 };
362-
await debugClient.assertStoppedLocation('step', functionLocation);
358+
await Promise.all([
359+
debugClient.nextRequest({ threadId }),
360+
debugClient.assertStoppedLocation('step', functionLocation)
361+
]);
363362

364-
await debugClient.nextRequest({ threadId });
365363
const functionInvocationLocation = { path: path.join(debugFilesPath, 'sample2.py'), column: 1, line: 11 };
366-
await debugClient.assertStoppedLocation('step', functionInvocationLocation);
364+
await Promise.all([
365+
debugClient.nextRequest({ threadId }),
366+
debugClient.assertStoppedLocation('step', functionInvocationLocation)
367+
]);
367368

368-
await debugClient.stepInRequest({ threadId });
369369
const loopPrintLocation = { path: path.join(debugFilesPath, 'sample2.py'), column: 1, line: 8 };
370-
await debugClient.assertStoppedLocation('step', loopPrintLocation);
370+
await Promise.all([
371+
debugClient.stepInRequest({ threadId }),
372+
debugClient.assertStoppedLocation('step', loopPrintLocation)
373+
]);
371374

372-
await debugClient.stepOutRequest({ threadId });
373-
await debugClient.assertStoppedLocation('step', functionInvocationLocation);
375+
await Promise.all([
376+
debugClient.stepOutRequest({ threadId }),
377+
debugClient.assertStoppedLocation('step', functionInvocationLocation)
378+
]);
374379

375-
await debugClient.nextRequest({ threadId });
376380
const printLocation = { path: path.join(debugFilesPath, 'sample2.py'), column: 1, line: 13 };
377-
await debugClient.assertStoppedLocation('step', printLocation);
381+
await Promise.all([
382+
debugClient.nextRequest({ threadId }),
383+
debugClient.assertStoppedLocation('step', printLocation)
384+
]);
378385
});
379386
test('Test pausing', async function () {
380-
// TODO: re-enable for new debugger once it's running on CI
381-
if (debuggerType !== 'pythonExperimental' || IS_CI_SERVER) {
387+
if (debuggerType !== 'pythonExperimental') {
382388
return this.skip();
383389
}
384390

src/test/debugger/portAndHost.test.ts

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import * as getFreePort from 'get-port';
77
import * as net from 'net';
88
import * as path from 'path';
99
import { DebugClient } from 'vscode-debugadapter-testsupport';
10+
import { noop } from '../../client/common/core.utils';
1011
import { LaunchRequestArguments } from '../../client/debugger/Common/Contracts';
1112
import { IS_MULTI_ROOT_TEST, TEST_DEBUGGER } from '../initialize';
1213

@@ -28,10 +29,6 @@ const EXPERIMENTAL_DEBUG_ADAPTER = path.join(__dirname, '..', '..', 'client', 'd
2829
// tslint:disable-next-line:no-invalid-this
2930
this.skip();
3031
}
31-
if (debuggerType !== 'python') {
32-
// tslint:disable-next-line:no-invalid-this
33-
return this.skip();
34-
}
3532
await new Promise(resolve => setTimeout(resolve, 1000));
3633
debugClient = new DebugClient('node', testAdapterFilePath, debuggerType);
3734
await debugClient.start();
@@ -40,14 +37,12 @@ const EXPERIMENTAL_DEBUG_ADAPTER = path.join(__dirname, '..', '..', 'client', 'd
4037
// Wait for a second before starting another test (sometimes, sockets take a while to get closed).
4138
await new Promise(resolve => setTimeout(resolve, 1000));
4239
try {
43-
// tslint:disable-next-line:no-empty
44-
debugClient.stop().catch(() => { });
40+
debugClient.stop().catch(noop);
4541
// tslint:disable-next-line:no-empty
4642
} catch (ex) { }
4743
});
4844

4945
function buildLauncArgs(pythonFile: string, stopOnEntry: boolean = false, port?: number, host?: string): LaunchRequestArguments {
50-
// pythonPath: '/Users/donjayamanne/anaconda3/envs/py36/bin/python',
5146
return {
5247
program: path.join(debugFilesPath, pythonFile),
5348
cwd: debugFilesPath,
@@ -103,8 +98,7 @@ const EXPERIMENTAL_DEBUG_ADAPTER = path.join(__dirname, '..', '..', 'client', 'd
10398
expect(exception!.message).contains('ENOTFOUND', 'Debugging failed for some other reason');
10499
});
105100
test('Confirm debuggig fails when provided port is in use', async () => {
106-
// tslint:disable-next-line:no-empty
107-
const server = net.createServer((s) => { });
101+
const server = net.createServer(noop);
108102
const port = await new Promise<number>((resolve, reject) => server.listen({ host: 'localhost', port: 0 }, () => resolve(server.address().port)));
109103
let exception: Error | undefined;
110104
try {

0 commit comments

Comments
 (0)