Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support debug test delegation #1536

Merged
merged 2 commits into from
Jul 31, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ public Object executeCommand(String commandId, List<Object> arguments, IProgress
getEnvVarPairs(arguments)
);
testParams.setData(scalaTestSuites);
buildServerConnection.buildTargetTest(testParams).join();
buildServerConnection.buildTargetTest(testParams);
return null;
default:
break;
Expand Down
5 changes: 5 additions & 0 deletions extension/src/Extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -247,10 +247,15 @@
private async activate(): Promise<void> {
const testExtension = vscode.extensions.getExtension("vscjava.vscode-java-test");
if (testExtension) {
testExtension.activate().then((api: any) => {

Check warning on line 250 in extension/src/Extension.ts

View workflow job for this annotation

GitHub Actions / Build & Analyse

Unexpected any. Specify a different type
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
);
}
});
}
Expand Down
57 changes: 56 additions & 1 deletion extension/src/bs/GradleTestRunner.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,24 @@
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;

Check warning on line 18 in extension/src/bs/GradleTestRunner.ts

View workflow job for this annotation

GitHub Actions / Build & Analyse

Unexpected any. Specify a different type
private testInitScriptPath: string;

public onDidChangeTestItemStatus: vscode.Event<TestItemStatusChangeEvent> = this._onDidChangeTestItemStatus.event;
public onDidFinishTestRun: vscode.Event<TestFinishEvent> = this._onDidFinishTestRun.event;

constructor(testRunnerApi: any) {

Check warning on line 24 in extension/src/bs/GradleTestRunner.ts

View workflow job for this annotation

GitHub Actions / Build & Analyse

Unexpected any. Specify a different type
this.testRunnerApi = testRunnerApi;
this.testInitScriptPath = path.join(os.tmpdir(), "testInitScript.gradle");
}

public async launch(context: IRunTestContext): Promise<void> {
Expand All @@ -40,8 +46,34 @@
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(
Expand All @@ -53,6 +85,9 @@
vmArgs,
env
);
if (isDebug) {
this.startJavaDebug(debugPort);
}
} catch (error) {
this.finishTestRun(-1, error.message);
}
Expand Down Expand Up @@ -125,4 +160,24 @@
"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");
}
}
}
Loading