Skip to content

Commit f329f8d

Browse files
authored
Fix language server smoke tests (microsoft#3690)
For microsoft#3684
1 parent 940d613 commit f329f8d

File tree

6 files changed

+144
-108
lines changed

6 files changed

+144
-108
lines changed

news/3 Code Health/3684.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Fixed language server smoke tests.

src/test/smoke/_run_first_msLanguageServer.smoke.test.ts

Lines changed: 0 additions & 106 deletions
This file was deleted.

src/test/smoke/common.ts

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
// Copyright (c) Microsoft Corporation. All rights reserved.
2+
// Licensed under the MIT License.
3+
4+
'use strict';
5+
6+
// tslint:disable:no-any no-invalid-this no-default-export no-console
7+
8+
import * as assert from 'assert';
9+
import * as fs from 'fs-extra';
10+
import * as glob from 'glob';
11+
import * as path from 'path';
12+
import * as vscode from 'vscode';
13+
import { waitForCondition } from '../common';
14+
import { EXTENSION_ROOT_DIR_FOR_TESTS, IS_SMOKE_TEST, SMOKE_TEST_EXTENSIONS_DIR } from '../constants';
15+
import { noop, sleep } from '../core';
16+
import { initialize } from '../initialize';
17+
18+
let initialized = false;
19+
const fileDefinitions = path.join(EXTENSION_ROOT_DIR_FOR_TESTS, 'src', 'testMultiRootWkspc', 'smokeTests', 'definitions.py');
20+
21+
export async function initializeSmokeTests() {
22+
if (!IS_SMOKE_TEST || initialized) {
23+
return;
24+
}
25+
await removeLanguageServerFiles();
26+
await enableJedi(false);
27+
await initialize();
28+
await openFileAndWaitForLS(fileDefinitions);
29+
initialized = true;
30+
}
31+
32+
export async function updateSetting(setting: string, value: any) {
33+
const resource = vscode.workspace.workspaceFolders![0].uri;
34+
await vscode.workspace.getConfiguration('python', resource).update(setting, value, vscode.ConfigurationTarget.WorkspaceFolder);
35+
}
36+
export async function removeLanguageServerFiles() {
37+
const folders = await getLanaguageServerFolders();
38+
await Promise.all(folders.map(item => fs.remove(item).catch(noop)));
39+
}
40+
async function getLanaguageServerFolders(): Promise<string[]> {
41+
return new Promise<string[]>((resolve, reject) => {
42+
glob('languageServer.*', { cwd: SMOKE_TEST_EXTENSIONS_DIR }, (ex, matches) => {
43+
ex ? reject(ex) : resolve(matches.map(item => path.join(SMOKE_TEST_EXTENSIONS_DIR, item)));
44+
});
45+
});
46+
}
47+
export function isJediEnabled() {
48+
const resource = vscode.workspace.workspaceFolders![0].uri;
49+
const settings = vscode.workspace.getConfiguration('python', resource);
50+
return settings.get<boolean>('jediEnabled') === true;
51+
}
52+
export async function enableJedi(enable: boolean | undefined) {
53+
if (isJediEnabled() === enable) {
54+
return;
55+
}
56+
await updateSetting('jediEnabled', enable);
57+
}
58+
export async function openFileAndWaitForLS(file: string): Promise<vscode.TextDocument> {
59+
const textDocument = await vscode.workspace.openTextDocument(file);
60+
await vscode.window.showTextDocument(textDocument);
61+
assert(vscode.window.activeTextEditor, 'No active editor');
62+
// Make sure LS completes file loading and analysis.
63+
// In test mode it awaits for the completion before trying
64+
// to fetch data for completion, hover.etc.
65+
await vscode.commands.executeCommand('vscode.executeCompletionItemProvider', textDocument.uri, new vscode.Position(0, 0));
66+
await waitForCondition(isLanguageServerDownloaded, 30_000, 'Language Server not downloaded');
67+
// For for LS to get extracted.
68+
await sleep(10_000);
69+
return textDocument;
70+
}
71+
72+
async function isLanguageServerDownloaded() {
73+
// tslint:disable-next-line:no-unnecessary-local-variable
74+
const downloaded = await getLanaguageServerFolders().then(items => items.length > 0);
75+
return downloaded;
76+
}

src/test/smoke/debugger.smoke.test.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,15 +12,17 @@ import * as vscode from 'vscode';
1212
import { openFile, waitForCondition } from '../common';
1313
import { EXTENSION_ROOT_DIR_FOR_TESTS, IS_SMOKE_TEST } from '../constants';
1414
import { closeActiveWindows, initializeTest } from '../initialize';
15+
import { initializeSmokeTests } from './common';
1516

1617
suite('Smoke Test: Debug file', function () {
1718
// Large value to allow for LS to get downloaded.
1819
this.timeout(4 * 60_000);
1920

20-
suiteSetup(function () {
21+
suiteSetup(async function () {
2122
if (!IS_SMOKE_TEST) {
2223
return this.skip();
2324
}
25+
await initializeSmokeTests();
2426
});
2527
setup(initializeTest);
2628
suiteTeardown(closeActiveWindows);
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
// Copyright (c) Microsoft Corporation. All rights reserved.
2+
// Licensed under the MIT License.
3+
4+
'use strict';
5+
6+
// tslint:disable:max-func-body-length no-invalid-this no-any
7+
8+
import * as assert from 'assert';
9+
import { expect } from 'chai';
10+
import * as path from 'path';
11+
import * as vscode from 'vscode';
12+
import { updateSetting } from '../common';
13+
import { EXTENSION_ROOT_DIR_FOR_TESTS, IS_SMOKE_TEST } from '../constants';
14+
import { sleep } from '../core';
15+
import { closeActiveWindows, initializeTest } from '../initialize';
16+
import { enableJedi, initializeSmokeTests, openFileAndWaitForLS } from './common';
17+
18+
const fileDefinitions = path.join(EXTENSION_ROOT_DIR_FOR_TESTS, 'src', 'testMultiRootWkspc', 'smokeTests', 'definitions.py');
19+
20+
suite('Smoke Test: Language Server', function () {
21+
// Large value to allow for LS to get downloaded.
22+
this.timeout(4 * 60000);
23+
24+
suiteSetup(async function () {
25+
if (!IS_SMOKE_TEST) {
26+
return this.skip();
27+
}
28+
await updateSetting('linting.ignorePatterns', ['**/dir1/**'], vscode.workspace.workspaceFolders![0].uri, vscode.ConfigurationTarget.WorkspaceFolder);
29+
await initializeSmokeTests();
30+
});
31+
setup(async () => {
32+
await initializeTest();
33+
await closeActiveWindows();
34+
});
35+
suiteTeardown(async () => {
36+
await enableJedi(undefined);
37+
await closeActiveWindows();
38+
await updateSetting('linting.ignorePatterns', undefined, vscode.workspace.workspaceFolders![0].uri, vscode.ConfigurationTarget.WorkspaceFolder);
39+
});
40+
teardown(closeActiveWindows);
41+
42+
test('Definitions', async () => {
43+
const startPosition = new vscode.Position(13, 6);
44+
const textDocument = await openFileAndWaitForLS(fileDefinitions);
45+
let tested = false;
46+
for (let i = 0; i < 5; i += 1) {
47+
const locations = await vscode.commands.executeCommand<vscode.Location[]>('vscode.executeDefinitionProvider', textDocument.uri, startPosition);
48+
if (locations && locations.length > 0) {
49+
expect(locations![0].uri.fsPath).to.contain(path.basename(fileDefinitions));
50+
tested = true;
51+
break;
52+
} else {
53+
// Wait for LS to start.
54+
await sleep(5_000);
55+
}
56+
}
57+
if (!tested) {
58+
assert.fail('Failled to test definitions');
59+
}
60+
});
61+
});

src/test/smoke/runInTerminal.smoke.test.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,15 +11,17 @@ import * as vscode from 'vscode';
1111
import { openFile, waitForCondition } from '../common';
1212
import { EXTENSION_ROOT_DIR_FOR_TESTS, IS_SMOKE_TEST } from '../constants';
1313
import { closeActiveWindows, initializeTest } from '../initialize';
14+
import { initializeSmokeTests } from './common';
1415

1516
suite('Smoke Test: Run Python File In Terminal', function () {
1617
// Large value to allow for LS to get downloaded.
1718
this.timeout(4 * 60_000);
1819

19-
suiteSetup(function () {
20+
suiteSetup(async function () {
2021
if (!IS_SMOKE_TEST) {
2122
return this.skip();
2223
}
24+
await initializeSmokeTests();
2325
});
2426
setup(initializeTest);
2527
suiteTeardown(closeActiveWindows);

0 commit comments

Comments
 (0)