Skip to content

Commit 0076072

Browse files
authored
Fix flakey pipe removal (#837)
On posix platforms if a named pipe hasn't been written to then occasionally calls to fs.lstat (which I believe fs.rm uses internally) will hang indefinitely. If a test run failed due to a compiler error in the build then the pipe never be written to. By repeatedly trying to perform a test run with code that fails to compile eventually this hang would appear. Work around the issue by writing to the pipe if compilation fails, ensuring the connection opens/closes and the pipe can be removed.
1 parent 9c1069d commit 0076072

File tree

2 files changed

+18
-0
lines changed

2 files changed

+18
-0
lines changed

src/TestExplorer/TestParsers/SwiftTestingOutputParser.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import {
2323
import { ITestRunState } from "./TestRunState";
2424
import { TestClass } from "../TestDiscovery";
2525
import { sourceLocationToVSCodeLocation } from "../../utilities/utilities";
26+
import { exec } from "child_process";
2627

2728
// All events produced by a swift-testing run will be one of these three types.
2829
// Detailed information about swift-testing's JSON schema is available here:
@@ -149,6 +150,7 @@ export interface SourceLocation {
149150
export class SwiftTestingOutputParser {
150151
private completionMap = new Map<number, boolean>();
151152
private testCaseMap = new Map<string, Map<string, TestCase>>();
153+
private path?: string;
152154

153155
constructor(
154156
public testRunStarted: () => void,
@@ -164,6 +166,8 @@ export class SwiftTestingOutputParser {
164166
runState: ITestRunState,
165167
pipeReader?: INamedPipeReader
166168
): Promise<void> {
169+
this.path = path;
170+
167171
// Creates a reader based on the platform unless being provided in a test context.
168172
const reader = pipeReader ?? this.createReader(path);
169173
const readlinePipe = new Readable({
@@ -182,6 +186,18 @@ export class SwiftTestingOutputParser {
182186
reader.start(readlinePipe);
183187
}
184188

189+
public async close() {
190+
if (!this.path) {
191+
return;
192+
}
193+
194+
return new Promise<void>(resolve => {
195+
exec(`echo '{}' > ${this.path}`, () => {
196+
resolve();
197+
});
198+
});
199+
}
200+
185201
private createReader(path: string): INamedPipeReader {
186202
return process.platform === "win32"
187203
? new WindowsNamedPipeReader(path)

src/TestExplorer/TestRunner.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -508,6 +508,8 @@ export class TestRunner {
508508
// Test failures result in error code 1
509509
if (error !== 1) {
510510
this.testRun.appendOutput(`\r\nError: ${getErrorDescription(error)}`);
511+
} else {
512+
this.swiftTestOutputParser.close();
511513
}
512514
} finally {
513515
outputStream.end();

0 commit comments

Comments
 (0)