Skip to content
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
12 changes: 10 additions & 2 deletions src/TestExplorer/TestRunner.ts
Original file line number Diff line number Diff line change
Expand Up @@ -449,6 +449,8 @@ export class TestRunner {
private testArgs: TestRunArguments;
private xcTestOutputParser: IXCTestOutputParser;
private swiftTestOutputParser: SwiftTestingOutputParser;
private debugSessionTerminatedEmitter = new vscode.EventEmitter<void>();
public onDebugSessionTerminated: vscode.Event<void>;
private static CANCELLATION_ERROR = "Test run cancelled.";

/**
Expand Down Expand Up @@ -487,6 +489,7 @@ export class TestRunner {
this.testRun.addParameterizedTestCase,
this.testRun.addAttachment
);
this.onDebugSessionTerminated = this.debugSessionTerminatedEmitter.event;
}

/**
Expand Down Expand Up @@ -1158,8 +1161,13 @@ export class TestRunner {
LoggingDebugAdapterTracker.setDebugSessionCallback(
session,
this.workspaceContext.logger,
output => {
outputHandler(output);
output => outputHandler(output),
exitCode => {
// Debug session is stopped with exitCode 9 (SIGKILL)
// when the user terminates it manually.
if (exitCode === 9) {
this.debugSessionTerminatedEmitter.fire();
}
}
);

Expand Down
5 changes: 5 additions & 0 deletions src/commands/testMultipleTimes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,10 @@ export async function runTestMultipleTimes(
token.token
);

// If the user terminates a debugging session we want
// to cancel the remaining iterations.
const terminationListener = runner.onDebugSessionTerminated(() => token.cancel());

testExplorer.onDidCreateTestRunEmitter.fire(runner.testRun);

const testRunState = new TestRunnerTestRunState(runner.testRun);
Expand Down Expand Up @@ -91,6 +95,7 @@ export async function runTestMultipleTimes(
}
}
await runner.testRun.end();
terminationListener.dispose();

return runStates;
}
Expand Down
48 changes: 32 additions & 16 deletions src/debugger/logTracker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ export class LoggingDebugAdapterTrackerFactory implements vscode.DebugAdapterTra
interface OutputEventBody {
category: string;
output: string;
exitCode: number | undefined;
}

interface DebugMessage {
Expand Down Expand Up @@ -68,7 +69,9 @@ export class LoggingDebugAdapterTracker implements vscode.DebugAdapterTracker {
private static debugSessionIdMap: { [id: string]: LoggingDebugAdapterTracker } = {};

private cb?: (output: string) => void;
private exitHandler?: (exitCode: number) => void;
private output: string[] = [];
private exitCode: number | undefined;

constructor(public id: string) {
LoggingDebugAdapterTracker.debugSessionIdMap[id] = this;
Expand All @@ -77,49 +80,62 @@ export class LoggingDebugAdapterTracker implements vscode.DebugAdapterTracker {
static setDebugSessionCallback(
session: vscode.DebugSession,
logger: SwiftLogger,
cb: (log: string) => void
cb: (log: string) => void,
exitHandler: (exitCode: number) => void
) {
const loggingDebugAdapter = this.debugSessionIdMap[session.id];
if (loggingDebugAdapter) {
loggingDebugAdapter.cb = cb;
loggingDebugAdapter.setCallbacks(cb, exitHandler);
for (const o of loggingDebugAdapter.output) {
cb(o);
}
if (loggingDebugAdapter.exitCode) {
exitHandler(loggingDebugAdapter.exitCode);
}
loggingDebugAdapter.output = [];
loggingDebugAdapter.exitCode = undefined;
} else {
logger.error("Could not find debug adapter for session: " + session.id);
}
}

setCallbacks(handleOutput: (output: string) => void, handleExit: (exitCode: number) => void) {
this.cb = handleOutput;
this.exitHandler = handleExit;
}

/**
* The debug adapter has sent a Debug Adapter Protocol message to the editor. Check
* it is a output message and is not being sent to the console
*/
onDidSendMessage(message: unknown): void {
const debugMessage = message as DebugMessage;
if (
!(
debugMessage &&
debugMessage.type === "event" &&
debugMessage.event === "output" &&
debugMessage.body.category !== "console"
)
) {
if (!debugMessage) {
return;
}
const output = debugMessage.body.output;
if (this.cb) {
this.cb(output);
} else {
this.output.push(output);

if (debugMessage.event === "exited" && debugMessage.body.exitCode) {
this.exitCode = debugMessage.body.exitCode;
this.exitHandler?.(debugMessage.body.exitCode);
} else if (
debugMessage.type === "event" &&
debugMessage.event === "output" &&
debugMessage.body.category !== "console"
) {
const output = debugMessage.body.output;
if (this.cb) {
this.cb(output);
} else {
this.output.push(output);
}
}
}

/**
* The debug adapter session is about to be stopped. Delete the session from
* the tracker
*/
onWillStopSession?(): void {
onWillStopSession(): void {
delete LoggingDebugAdapterTracker.debugSessionIdMap[this.id];
}
}