From 8f759484da46adcf7d6e685d23eb0670417f3dbb Mon Sep 17 00:00:00 2001 From: "Kirschner, Andreas {DXRE~Penzberg}" Date: Mon, 28 Dec 2020 15:14:47 +0100 Subject: [PATCH 1/5] make pattern configurable for testhost detection --- package.json | 14 ++++++++++++-- src/debug.ts | 10 ++++++---- src/executor.ts | 13 ++++++++----- src/testCommands.ts | 4 ---- src/utility.ts | 10 ++++++++++ 5 files changed, 36 insertions(+), 15 deletions(-) diff --git a/package.json b/package.json index 4dfc13b..3f40b89 100644 --- a/package.json +++ b/package.json @@ -2,12 +2,12 @@ "name": "dotnet-test-explorer", "displayName": ".NET Core Test Explorer", "description": "Test Explorer for .NET Core (MSTest, xUnit, NUnit)", - "version": "0.7.4", + "version": "0.7.4-ak1", "publisher": "formulahendry", "license": "MIT", "icon": "testexplorer_dark.png", "engines": { - "vscode": "^1.25.1" + "vscode": "^1.45.1" }, "categories": [ "Programming Languages" @@ -253,6 +253,16 @@ "default": "", "description": "Additional arguments that are added to the dotnet test command." }, + "dotnet-test-explorer.testhost.started.pattern": { + "type": "string", + "default": "Host debugging is enabled", + "description": "Pattern in stdout of testhost that triggers attachment of debugger" + }, + "dotnet-test-explorer.testhost.processId.pattern": { + "type": "string", + "default": "Process Id: (\\d+),", + "description": "Pattern in stdout of testhost that matches its process id" + }, "dotnet-test-explorer.leftClickAction": { "type": "string", "default": "gotoTest", diff --git a/src/debug.ts b/src/debug.ts index 9033d2a..cc31a5d 100644 --- a/src/debug.ts +++ b/src/debug.ts @@ -1,4 +1,5 @@ import * as vscode from "vscode"; +import { Logger } from "./logger"; import { TestCommands } from "./testCommands"; import { ITestResult, TestResult } from "./testResult"; import { Utility } from "./utility"; @@ -12,7 +13,8 @@ export interface IDebugRunnerInfo { } export class Debug { - private processIdRegexp = /Process Id: (.*),/gm; + private processIdRegexp = new RegExp(Utility.testhostProcessIdPattern, 'mi'); + private debuggingEnabledRegexp = new RegExp(Utility.testhostStartedPattern, 'mi'); public onData(data: string, debugRunnerInfo?: IDebugRunnerInfo): IDebugRunnerInfo { @@ -20,13 +22,13 @@ export class Debug { debugRunnerInfo = {isRunning: false, isSettingUp: true, waitingForAttach: false, processId: ""}; } - if (!debugRunnerInfo.waitingForAttach) { - debugRunnerInfo.waitingForAttach = data.indexOf("Waiting for debugger attach...") > -1; + if (!debugRunnerInfo.waitingForAttach && this.debuggingEnabledRegexp.test(data)) { + debugRunnerInfo.waitingForAttach = true; } if (debugRunnerInfo.processId.length <= 0) { const match = this.processIdRegexp.exec(data); - + if (match && match[1]) { debugRunnerInfo.processId = match[1]; } diff --git a/src/executor.ts b/src/executor.ts index 7b67d4e..ef71fac 100644 --- a/src/executor.ts +++ b/src/executor.ts @@ -31,6 +31,9 @@ export class Executor { Logger.Log(`Process ${childProcess.pid} started`); this.processes.push(childProcess); + childProcess.stdout.on("data", (buf) => { + Logger.Log(buf); + }); childProcess.on("close", (code: number) => { @@ -63,24 +66,24 @@ export class Executor { if (addToProcessList) { Logger.Log(`Process ${childProcess.pid} started`); + Logger.Log(`Waiting for debugger to attach`); this.processes.push(childProcess); childProcess.stdout.on("data", (buf) => { - + if (this.debugRunnerInfo && this.debugRunnerInfo.isRunning) { return; } - - Logger.Log(`Waiting for debugger to attach`); - + const stdout = String(buf); + Logger.Log(stdout); this.debugRunnerInfo = debug.onData(stdout, this.debugRunnerInfo); if (this.debugRunnerInfo.config) { - Logger.Log(`Debugger process found, attaching`); + Logger.Log(`Debugger process found (pid: ${this.debugRunnerInfo.processId}), attaching`); this.debugRunnerInfo.isRunning = true; diff --git a/src/testCommands.ts b/src/testCommands.ts index 042dc43..0856ca8 100644 --- a/src/testCommands.ts +++ b/src/testCommands.ts @@ -272,8 +272,6 @@ export class TestCommands implements Disposable { reject(new Error("UserAborted")); } - Logger.Log(stdout, "Test Explorer (Test runner output)"); - resolve(); }, testDirectoryPath, true); } else { @@ -284,8 +282,6 @@ export class TestCommands implements Disposable { reject(new Error("UserAborted")); } - Logger.Log(stdout, "Test Explorer (Test runner output)"); - resolve(); }, testDirectoryPath, true); } diff --git a/src/utility.ts b/src/utility.ts index 36e9163..e5e80de 100644 --- a/src/utility.ts +++ b/src/utility.ts @@ -38,6 +38,16 @@ export class Utility { return (testArguments && testArguments.length > 0) ? ` ${testArguments}` : ""; } + public static get testhostStartedPattern(): string { + const pattern = Utility.getConfiguration().get("testhost.started.pattern"); + return (pattern && pattern.length > 0) ? pattern : "Host debugging is enabled"; + } + + public static get testhostProcessIdPattern(): string { + const pattern = Utility.getConfiguration().get("testhost.processId.pattern"); + return (pattern && pattern.length > 0) ? pattern : "Process Id: (\d+),"; + } + public static getConfiguration(): vscode.WorkspaceConfiguration { return vscode.workspace.getConfiguration("dotnet-test-explorer"); } From 382b15e9bc0f5038ec6a9f451a3c21f62f64fabd Mon Sep 17 00:00:00 2001 From: "Kirschner, Andreas {DXRE~Penzberg}" Date: Mon, 28 Dec 2020 15:26:29 +0100 Subject: [PATCH 2/5] remove import statements --- src/debug.ts | 5 +---- src/executor.ts | 6 +++--- 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/src/debug.ts b/src/debug.ts index cc31a5d..35f3da1 100644 --- a/src/debug.ts +++ b/src/debug.ts @@ -1,7 +1,4 @@ import * as vscode from "vscode"; -import { Logger } from "./logger"; -import { TestCommands } from "./testCommands"; -import { ITestResult, TestResult } from "./testResult"; import { Utility } from "./utility"; export interface IDebugRunnerInfo { @@ -28,7 +25,7 @@ export class Debug { if (debugRunnerInfo.processId.length <= 0) { const match = this.processIdRegexp.exec(data); - + if (match && match[1]) { debugRunnerInfo.processId = match[1]; } diff --git a/src/executor.ts b/src/executor.ts index ef71fac..cad306f 100644 --- a/src/executor.ts +++ b/src/executor.ts @@ -71,11 +71,11 @@ export class Executor { this.processes.push(childProcess); childProcess.stdout.on("data", (buf) => { - + if (this.debugRunnerInfo && this.debugRunnerInfo.isRunning) { return; } - + const stdout = String(buf); Logger.Log(stdout); @@ -87,7 +87,7 @@ export class Executor { this.debugRunnerInfo.isRunning = true; - vscode.debug.startDebugging(vscode.workspace.workspaceFolders[0], this.debugRunnerInfo.config).then( (c) => { + vscode.debug.startDebugging(vscode.workspace.workspaceFolders[0], this.debugRunnerInfo.config).then((c) => { // When we attach to the debugger it seems to be stuck before loading the actual assembly that's running in code // This is to try to continue past this invisible break point and into the actual code the user wants to debug setTimeout(() => { From a400a556e86fe6f2020198a0c491ee7fc7b2493f Mon Sep 17 00:00:00 2001 From: "Kirschner, Andreas {DXRE~Penzberg}" Date: Mon, 28 Dec 2020 15:42:46 +0100 Subject: [PATCH 3/5] fix ut --- test/debug.test.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/debug.test.ts b/test/debug.test.ts index 7296075..437e9d9 100644 --- a/test/debug.test.ts +++ b/test/debug.test.ts @@ -10,13 +10,13 @@ suite("Debug tests", () => { assert.equal(results.isSettingUp, true); }); - test("Detects that debug is ready for attach har started", () => { + test("Detects that debug is ready for attach has started", () => { const debug = new Debug(); let results = debug.onData("data"); results = debug.onData(` This is output from vstest - Waiting for debugger attach... + Host debugging is enabled Tra la lalala la `, results); @@ -44,7 +44,7 @@ suite("Debug tests", () => { results = debug.onData(` This is output from vstest - Waiting for debugger attach... + Host debugging is enabled Tra la lalala la `, results); From 3c811e4ccf4829072753caabf40eae30da8ee05b Mon Sep 17 00:00:00 2001 From: "Kirschner, Andreas {DXRE~Penzberg}" Date: Mon, 28 Dec 2020 16:12:15 +0100 Subject: [PATCH 4/5] add option to clear panel before test run --- package.json | 5 +++++ src/executor.ts | 8 ++++++++ src/logger.ts | 4 ++++ src/utility.ts | 2 ++ 4 files changed, 19 insertions(+) diff --git a/package.json b/package.json index 3f40b89..1b04245 100644 --- a/package.json +++ b/package.json @@ -277,6 +277,11 @@ "type": "boolean", "default": false, "description": "If true, will discover/build and run test in parallel if you have multiple test projects" + }, + "dotnet-test-explorer.clearTerminalBeforeTestRun": { + "type": "boolean", + "default": false, + "description": "If true, clears the output panel before running/debugging test" } } }, diff --git a/src/executor.ts b/src/executor.ts index cad306f..b6788c7 100644 --- a/src/executor.ts +++ b/src/executor.ts @@ -4,6 +4,7 @@ import { platform } from "os"; import * as vscode from "vscode"; import { Debug, IDebugRunnerInfo } from "./debug"; import { Logger } from "./logger"; +import { Utility } from "./utility"; export class Executor { @@ -19,6 +20,10 @@ export class Executor { } public static exec(command: string, callback, cwd?: string, addToProcessList?: boolean) { + if (Utility.clearTerminalBeforeTestRun){ + Logger.Clear(); + } + // DOTNET_CLI_UI_LANGUAGE does not seem to be respected when passing it as a parameter to the exec // function so we set the variable here instead process.env.DOTNET_CLI_UI_LANGUAGE = "en"; @@ -49,6 +54,9 @@ export class Executor { } public static debug(command: string, callback, cwd?: string, addToProcessList?: boolean) { + if (Utility.clearTerminalBeforeTestRun){ + Logger.Clear(); + } // DOTNET_CLI_UI_LANGUAGE does not seem to be respected when passing it as a parameter to the exec // function so we set the variable here instead process.env.DOTNET_CLI_UI_LANGUAGE = "en"; diff --git a/src/logger.ts b/src/logger.ts index d0ba00b..6c4b5bc 100644 --- a/src/logger.ts +++ b/src/logger.ts @@ -18,6 +18,10 @@ export class Logger { Logger.Log(`[WARNING] ${message}`); } + public static Clear(output: string = this.defaultOutput): void { + this.outputTerminals[output].clear(); + } + public static Show(): void { if (this.outputTerminals && this.outputTerminals[this.defaultOutput]) { this.outputTerminals[this.defaultOutput].show(); diff --git a/src/utility.ts b/src/utility.ts index e5e80de..0b06abc 100644 --- a/src/utility.ts +++ b/src/utility.ts @@ -7,6 +7,7 @@ export class Utility { public static skipBuild: boolean; public static runInParallel: boolean; + public static clearTerminalBeforeTestRun: boolean; public static get codeLensEnabled(): boolean { return Utility.showCodeLens; @@ -84,6 +85,7 @@ export class Utility { Utility.autoExpandTree = configuration.get("autoExpandTree", false); Utility.skipBuild = Utility.additionalArgumentsOption.indexOf("--no-build") > -1; Utility.runInParallel = configuration.get("runInParallel", false); + Utility.clearTerminalBeforeTestRun = configuration.get("clearTerminalBeforeTestRun", false); } /** From 7197e64004a94a861e15614234382b7e75b46d4c Mon Sep 17 00:00:00 2001 From: "Kirschner, Andreas {DXRE~Penzberg}" Date: Tue, 12 Jan 2021 09:11:41 +0100 Subject: [PATCH 5/5] improve logging --- .gitignore | 4 +++- src/executor.ts | 11 ++--------- src/logger.ts | 12 ++++++++---- src/testCommands.ts | 4 ++++ 4 files changed, 17 insertions(+), 14 deletions(-) diff --git a/.gitignore b/.gitignore index b631c59..f8f973b 100644 --- a/.gitignore +++ b/.gitignore @@ -6,4 +6,6 @@ npm-debug.log yarn.* [Bb]in/ [Oo]bj/ -lcov.info \ No newline at end of file +lcov.info +.vscode-test +*.vsix \ No newline at end of file diff --git a/src/executor.ts b/src/executor.ts index b6788c7..5860438 100644 --- a/src/executor.ts +++ b/src/executor.ts @@ -20,10 +20,6 @@ export class Executor { } public static exec(command: string, callback, cwd?: string, addToProcessList?: boolean) { - if (Utility.clearTerminalBeforeTestRun){ - Logger.Clear(); - } - // DOTNET_CLI_UI_LANGUAGE does not seem to be respected when passing it as a parameter to the exec // function so we set the variable here instead process.env.DOTNET_CLI_UI_LANGUAGE = "en"; @@ -37,7 +33,7 @@ export class Executor { this.processes.push(childProcess); childProcess.stdout.on("data", (buf) => { - Logger.Log(buf); + Logger.LogRaw(buf); }); childProcess.on("close", (code: number) => { @@ -54,9 +50,6 @@ export class Executor { } public static debug(command: string, callback, cwd?: string, addToProcessList?: boolean) { - if (Utility.clearTerminalBeforeTestRun){ - Logger.Clear(); - } // DOTNET_CLI_UI_LANGUAGE does not seem to be respected when passing it as a parameter to the exec // function so we set the variable here instead process.env.DOTNET_CLI_UI_LANGUAGE = "en"; @@ -85,7 +78,7 @@ export class Executor { } const stdout = String(buf); - Logger.Log(stdout); + Logger.LogRaw(stdout); this.debugRunnerInfo = debug.onData(stdout, this.debugRunnerInfo); diff --git a/src/logger.ts b/src/logger.ts index 6c4b5bc..409ea65 100644 --- a/src/logger.ts +++ b/src/logger.ts @@ -2,20 +2,24 @@ import * as vscode from "vscode"; export class Logger { - public static Log(message: string, output: string = this.defaultOutput): void { + public static LogRaw(message: string, output: string = this.defaultOutput): void { if (this.outputTerminals[output] === undefined ) { this.outputTerminals[output] = vscode.window.createOutputChannel(output); } - this.outputTerminals[output].appendLine(message); + this.outputTerminals[output].appendLine(message.trim()); + } + + public static Log(message: string): void { + Logger.LogRaw(`[INFO] ${message}`); } public static LogError(message: string, error: any): void { - Logger.Log(`[ERROR] ${message} - ${Logger.formatError(error)}`); + Logger.LogRaw(`[ERROR] ${message} - ${Logger.formatError(error)}`); } public static LogWarning(message: string): void { - Logger.Log(`[WARNING] ${message}`); + Logger.LogRaw(`[WARNING] ${message}`); } public static Clear(output: string = this.defaultOutput): void { diff --git a/src/testCommands.ts b/src/testCommands.ts index 0856ca8..1e5ece2 100644 --- a/src/testCommands.ts +++ b/src/testCommands.ts @@ -262,6 +262,10 @@ export class TestCommands implements Disposable { this.runBuildCommandForSpecificDirectory(testDirectoryPath) .then(() => { + if (Utility.clearTerminalBeforeTestRun){ + Logger.Clear(); + Logger.Show(); + } Logger.Log(`Executing ${command} in ${testDirectoryPath}`); if (!debug) {