feat - Support debug test delegation (#1536)

This commit is contained in:
Sheng Chen 2024-07-31 16:42:42 +08:00 коммит произвёл GitHub
Родитель 131f4cd300
Коммит 59195dc209
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: B5690EEEBB952194
3 изменённых файлов: 62 добавлений и 2 удалений

Просмотреть файл

@ -76,7 +76,7 @@ public class GradleDelegateCommandHandler implements IDelegateCommandHandler {
getEnvVarPairs(arguments)
);
testParams.setData(scalaTestSuites);
buildServerConnection.buildTargetTest(testParams).join();
buildServerConnection.buildTargetTest(testParams);
return null;
default:
break;

Просмотреть файл

@ -251,6 +251,11 @@ export class Extension {
if (api) {
const testRunner: GradleTestRunner = this.buildServerController.getGradleTestRunner(api);
api.registerTestProfile("Delegate Test to Gradle", vscode.TestRunProfileKind.Run, testRunner);
api.registerTestProfile(
"Delegate Test to Gradle (Debug)",
vscode.TestRunProfileKind.Debug,
testRunner
);
}
});
}

Просмотреть файл

@ -6,18 +6,24 @@ import {
IRunTestContext,
TestIdParts,
} from "../java-test-runner.api";
import * as getPort from "get-port";
import { waitOnTcp } from "../util";
import * as os from "os";
import * as path from "path";
export class GradleTestRunner implements TestRunner {
private readonly _onDidChangeTestItemStatus = new vscode.EventEmitter<TestItemStatusChangeEvent>();
private readonly _onDidFinishTestRun = new vscode.EventEmitter<TestFinishEvent>();
private context: IRunTestContext;
private testRunnerApi: any;
private testInitScriptPath: string;
public onDidChangeTestItemStatus: vscode.Event<TestItemStatusChangeEvent> = this._onDidChangeTestItemStatus.event;
public onDidFinishTestRun: vscode.Event<TestFinishEvent> = this._onDidFinishTestRun.event;
constructor(testRunnerApi: any) {
this.testRunnerApi = testRunnerApi;
this.testInitScriptPath = path.join(os.tmpdir(), "testInitScript.gradle");
}
public async launch(context: IRunTestContext): Promise<void> {
@ -40,8 +46,34 @@ export class GradleTestRunner implements TestRunner {
tests.set(parts.class, testMethods);
});
const agrs = context.testConfig?.args;
const agrs = context.testConfig?.args ?? [];
const vmArgs = context.testConfig?.vmArgs;
const isDebug = context.isDebug && !!vscode.extensions.getExtension("vscjava.vscode-java-debug");
let debugPort = -1;
if (isDebug) {
debugPort = await getPort();
// See: https://docs.gradle.org/current/javadoc/org/gradle/tooling/TestLauncher.html#debugTestsOn(int)
// since the gradle tooling api does not support debug tests in server=y mode, so we use the init script
// as a workaround
const initScriptContent = `allprojects {
afterEvaluate {
tasks.withType(Test) {
debugOptions {
enabled = true
host = 'localhost'
port = ${debugPort}
server = true
suspend = true
}
}
}
}`;
await vscode.workspace.fs.writeFile(
vscode.Uri.file(this.testInitScriptPath),
Buffer.from(initScriptContent)
);
agrs.unshift("--init-script", this.testInitScriptPath);
}
const env = context.testConfig?.env;
try {
await vscode.commands.executeCommand(
@ -53,6 +85,9 @@ export class GradleTestRunner implements TestRunner {
vmArgs,
env
);
if (isDebug) {
this.startJavaDebug(debugPort);
}
} catch (error) {
this.finishTestRun(-1, error.message);
}
@ -125,4 +160,24 @@ export class GradleTestRunner implements TestRunner {
"worker.org.gradle.process.internal.",
];
}
private async startJavaDebug(javaDebugPort: number): Promise<void> {
if (javaDebugPort < 0) {
return;
}
await waitOnTcp("localhost", javaDebugPort);
const debugConfig = {
type: "java",
name: "Debug (Attach) via Gradle",
request: "attach",
hostName: "localhost",
port: javaDebugPort,
projectName: this.context.projectName,
};
const startedDebugging = await vscode.debug.startDebugging(this.context.workspaceFolder, debugConfig);
if (!startedDebugging) {
throw new Error("The debugger was not started");
}
}
}