Skip to content

Commit eaade81

Browse files
author
Piotr Puszkiewicz
authored
Merge pull request #1839 from TheRealPiotrP/dev/piotrp/launchConfigIntegrationTests
Add Debug Launch integration test
2 parents 2e1ee60 + 63c74d2 commit eaade81

File tree

8 files changed

+153
-56
lines changed

8 files changed

+153
-56
lines changed

src/assets.ts

Lines changed: 20 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,14 @@
55

66
import * as fs from 'fs-extra';
77
import * as path from 'path';
8-
import * as vscode from 'vscode';
8+
import * as protocol from './omnisharp/protocol';
9+
import * as serverUtils from './omnisharp/utils';
910
import * as tasks from 'vscode-tasks';
11+
import * as util from './common';
12+
import * as vscode from 'vscode';
13+
1014
import { OmniSharpServer } from './omnisharp/server';
11-
import * as serverUtils from './omnisharp/utils';
12-
import * as protocol from './omnisharp/protocol';
1315
import { tolerantParse } from './json';
14-
import * as util from './common';
1516

1617
export class AssetGenerator {
1718
public rootPath: string;
@@ -546,24 +547,20 @@ function shouldGenerateAssets(generator: AssetGenerator) {
546547
});
547548
}
548549

549-
export function generateAssets(server: OmniSharpServer) {
550-
serverUtils.requestWorkspaceInformation(server).then(info => {
551-
if (protocol.containsDotNetCoreProjects(info)) {
552-
const generator = new AssetGenerator(info);
553-
getOperations(generator).then(operations => {
554-
if (hasAddOperations(operations)) {
555-
shouldGenerateAssets(generator).then(res => {
556-
if (res) {
557-
fs.ensureDir(generator.vscodeFolder, err => {
558-
addAssets(generator, operations);
559-
});
560-
}
561-
});
562-
}
563-
});
564-
}
565-
else {
566-
vscode.window.showErrorMessage("Could not locate .NET Core project. Assets were not generated.");
550+
export async function generateAssets(server: OmniSharpServer) {
551+
let workspaceInformation = await serverUtils.requestWorkspaceInformation(server);
552+
if (protocol.containsDotNetCoreProjects(workspaceInformation)) {
553+
const generator = new AssetGenerator(workspaceInformation);
554+
let operations = await getOperations(generator);
555+
if (hasAddOperations(operations)) {
556+
let doGenerateAssets = await shouldGenerateAssets(generator);
557+
if (doGenerateAssets) {
558+
await fs.ensureDir(generator.vscodeFolder);
559+
await addAssets(generator, operations);
560+
}
567561
}
568-
});
562+
}
563+
else {
564+
await vscode.window.showErrorMessage("Could not locate .NET Core project. Assets were not generated.");
565+
}
569566
}

src/coreclr-debug/activate.ts

Lines changed: 22 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -4,40 +4,49 @@
44
*--------------------------------------------------------------------------------------------*/
55
'use strict';
66

7-
import * as vscode from 'vscode';
7+
import * as debugInstall from './install';
88
import * as os from 'os';
9-
import TelemetryReporter from 'vscode-extension-telemetry';
9+
import * as vscode from 'vscode';
10+
1011
import { CoreClrDebugUtil, DotnetInfo, } from './util';
11-
import * as debugInstall from './install';
12+
1213
import { Logger } from './../logger';
1314
import { PlatformInformation } from './../platform';
15+
import TelemetryReporter from 'vscode-extension-telemetry';
1416

1517
let _debugUtil: CoreClrDebugUtil = null;
1618
let _reporter: TelemetryReporter = null;
1719
let _logger: Logger = null;
1820

19-
export function activate(thisExtension : vscode.Extension<any>, context: vscode.ExtensionContext, reporter: TelemetryReporter, logger: Logger, channel: vscode.OutputChannel) {
21+
export async function activate(thisExtension : vscode.Extension<any>, context: vscode.ExtensionContext, reporter: TelemetryReporter, logger: Logger, channel: vscode.OutputChannel) {
2022
_debugUtil = new CoreClrDebugUtil(context.extensionPath, logger);
2123
_reporter = reporter;
2224
_logger = logger;
2325

2426
if (!CoreClrDebugUtil.existsSync(_debugUtil.debugAdapterDir())) {
25-
PlatformInformation.GetCurrent().then((info) => {
26-
if (info.architecture !== "x86_64") {
27-
if (info.isWindows() && info.architecture === "x86") {
27+
let platformInformation: PlatformInformation;
28+
29+
try {
30+
platformInformation = await PlatformInformation.GetCurrent();
31+
}
32+
catch (err) {
33+
// Somehow we couldn't figure out the platform we are on
34+
logger.appendLine("[ERROR]: C# Extension failed to install the debugger package");
35+
showInstallErrorMessage(channel);
36+
}
37+
38+
if (platformInformation) {
39+
if (platformInformation.architecture !== "x86_64") {
40+
if (platformInformation.isWindows() && platformInformation.architecture === "x86") {
2841
logger.appendLine(`[WARNING]: x86 Windows is not currently supported by the .NET Core debugger. Debugging will not be available.`);
2942
} else {
30-
logger.appendLine(`[WARNING]: Processor architecture '${info.architecture}' is not currently supported by the .NET Core debugger. Debugging will not be available.`);
43+
logger.appendLine(`[WARNING]: Processor architecture '${platformInformation.architecture}' is not currently supported by the .NET Core debugger. Debugging will not be available.`);
3144
}
3245
} else {
3346
logger.appendLine("[ERROR]: C# Extension failed to install the debugger package");
3447
showInstallErrorMessage(channel);
3548
}
36-
}, (err) => {
37-
// Somehow we couldn't figure out the platform we are on
38-
logger.appendLine("[ERROR]: C# Extension failed to install the debugger package");
39-
showInstallErrorMessage(channel);
40-
});
49+
}
4150
} else if (!CoreClrDebugUtil.existsSync(_debugUtil.installCompleteFilePath())) {
4251
completeDebuggerInstall(logger, channel);
4352
}

src/main.ts

Lines changed: 24 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -3,19 +3,19 @@
33
* Licensed under the MIT License. See License.txt in the project root for license information.
44
*--------------------------------------------------------------------------------------------*/
55

6-
import * as vscode from 'vscode';
7-
import TelemetryReporter from 'vscode-extension-telemetry';
8-
9-
import * as coreclrdebug from './coreclr-debug/activate';
106
import * as OmniSharp from './omnisharp/extension';
7+
import * as coreclrdebug from './coreclr-debug/activate';
118
import * as util from './common';
12-
import { Logger } from './logger';
9+
import * as vscode from 'vscode';
10+
1311
import { CSharpExtDownloader } from './CSharpExtDownloader';
12+
import { Logger } from './logger';
13+
import TelemetryReporter from 'vscode-extension-telemetry';
1414
import { addJSONProviders } from './features/json/jsonContributions';
1515

1616
let _channel: vscode.OutputChannel = null;
1717

18-
export function activate(context: vscode.ExtensionContext): any {
18+
export async function activate(context: vscode.ExtensionContext): Promise<{ initializationFinished: Promise<void> }> {
1919

2020
const extensionId = 'ms-vscode.csharp';
2121
const extension = vscode.extensions.getExtension(extensionId);
@@ -29,19 +29,24 @@ export function activate(context: vscode.ExtensionContext): any {
2929

3030
let logger = new Logger(text => _channel.append(text));
3131

32-
ensureRuntimeDependencies(extension, logger, reporter)
33-
.then((success : boolean) => {
34-
// activate language services
35-
OmniSharp.activate(context, reporter, _channel);
36-
37-
// register JSON completion & hover providers for project.json
38-
context.subscriptions.push(addJSONProviders());
39-
40-
if (success) {
41-
// activate coreclr-debug
42-
coreclrdebug.activate(extension, context, reporter, logger, _channel);
43-
}
44-
});
32+
let runtimeDependenciesExist = await ensureRuntimeDependencies(extension, logger, reporter);
33+
34+
// activate language services
35+
let omniSharpPromise = OmniSharp.activate(context, reporter, _channel);
36+
37+
// register JSON completion & hover providers for project.json
38+
context.subscriptions.push(addJSONProviders());
39+
40+
let coreClrDebugPromise = Promise.resolve();
41+
if (runtimeDependenciesExist) {
42+
// activate coreclr-debug
43+
coreClrDebugPromise = coreclrdebug.activate(extension, context, reporter, logger, _channel);
44+
}
45+
46+
return {
47+
initializationFinished: Promise.all([omniSharpPromise, coreClrDebugPromise])
48+
.then(a => {})
49+
};
4550
}
4651

4752
function ensureRuntimeDependencies(extension: vscode.Extension<any>, logger: Logger, reporter: TelemetryReporter): Promise<boolean> {

src/omnisharp/extension.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,4 +157,6 @@ export function activate(context: vscode.ExtensionContext, reporter: TelemetryRe
157157
disposables.push(vscode.debug.registerDebugConfigurationProvider('coreclr', new CSharpConfigurationProvider(server)));
158158

159159
context.subscriptions.push(...disposables);
160+
161+
return new Promise<string>(resolve => server.onServerStart(e => resolve(e)));
160162
}

test/integrationTests/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ var testRunner = require('vscode/lib/testrunner');
2121
// See https://github.com/mochajs/mocha/wiki/Using-mocha-programmatically#set-options for more info
2222

2323
testRunner.configure({
24-
timeout: 10000,
24+
timeout: 60000,
2525
ui: 'tdd', // the TDD UI is being used in extension.test.ts (suite, test, etc.)
2626
useColors: true // colored output from test results
2727
});
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
/*---------------------------------------------------------------------------------------------
2+
* Copyright (c) Microsoft Corporation. All rights reserved.
3+
* Licensed under the MIT License. See License.txt in the project root for license information.
4+
*--------------------------------------------------------------------------------------------*/
5+
6+
import * as fs from 'async-file';
7+
import * as vscode from 'vscode';
8+
9+
import poll from './poll';
10+
import { should } from 'chai';
11+
import testAssetWorkspace from './testAssets/testAssetWorkspace';
12+
13+
const chai = require('chai');
14+
chai.use(require('chai-arrays'));
15+
chai.use(require('chai-fs'));
16+
17+
suite(`Tasks generation: ${testAssetWorkspace.description}`, function() {
18+
suiteSetup(async function() {
19+
should();
20+
21+
let csharpExtension = vscode.extensions.getExtension("ms-vscode.csharp");
22+
if (!csharpExtension.isActive) {
23+
await csharpExtension.activate();
24+
}
25+
26+
testAssetWorkspace.deleteBuildArtifacts();
27+
28+
await fs.rimraf(testAssetWorkspace.vsCodeDirectoryPath);
29+
30+
await csharpExtension.exports.initializationFinished;
31+
32+
await vscode.commands.executeCommand("dotnet.generateAssets");
33+
34+
await poll(async () => await fs.exists(testAssetWorkspace.launchJsonPath), 10000, 100);
35+
});
36+
37+
test("Starting .NET Core Launch (console) from the workspace root should create an Active Debug Session", async () => {
38+
await vscode.debug.startDebugging(vscode.workspace.workspaceFolders[0], ".NET Core Launch (console)");
39+
40+
let debugSessionTerminated = new Promise(resolve => {
41+
vscode.debug.onDidTerminateDebugSession((e) => resolve());
42+
});
43+
44+
vscode.debug.activeDebugSession.type.should.equal("coreclr");
45+
46+
await debugSessionTerminated;
47+
});
48+
});

test/integrationTests/poll.ts

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
/*---------------------------------------------------------------------------------------------
2+
* Copyright (c) Microsoft Corporation. All rights reserved.
3+
* Licensed under the MIT License. See License.txt in the project root for license information.
4+
*--------------------------------------------------------------------------------------------*/
5+
6+
export default async function poll<T>(getValue: () => T, duration: number, step: number): Promise<T> {
7+
while (duration > 0) {
8+
let value = await getValue();
9+
10+
if (value) {
11+
return value;
12+
}
13+
14+
await sleep(step);
15+
16+
duration -= step;
17+
}
18+
19+
throw new Error("Polling did not succeed within the alotted duration.");
20+
}
21+
22+
function sleep(ms = 0) {
23+
return new Promise(r => setTimeout(r, ms));
24+
}

test/integrationTests/testAssets/testAssets.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,18 @@ export class TestAssetWorkspace {
4545
async deleteBuildArtifacts(): Promise<void> {
4646
this.projects.forEach(async p => await p.deleteBuildArtifacts());
4747
}
48+
49+
get vsCodeDirectoryPath(): string {
50+
return path.join(vscode.workspace.rootPath, ".vscode");;
51+
}
52+
53+
get launchJsonPath(): string {
54+
return path.join(this.vsCodeDirectoryPath, "launch.json");
55+
}
56+
57+
get tasksJsonPath(): string {
58+
return path.join(this.vsCodeDirectoryPath, "tasks.json");
59+
}
4860

4961
description: string;
5062

0 commit comments

Comments
 (0)