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

Reduce flakiness on Windows for BwoB tests #17479

Closed
wants to merge 1 commit into from
Closed
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 @@ -25,8 +25,15 @@
import java.io.File;
import java.io.IOException;
import java.net.DatagramSocket;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.SocketAddress;
import java.net.SocketException;
import java.nio.channels.SocketChannel;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Comparator;
import java.util.Random;

/** Integration test utilities. */
Expand Down Expand Up @@ -73,6 +80,23 @@ public static int pickUnusedRandomPort() throws IOException, InterruptedExceptio
throw new IOException("Failed to find available port");
}

public static void waitForPortOpen(int port) throws IOException, InterruptedException {
boolean scanning = true;
while (scanning) {
try {
SocketAddress addr = new InetSocketAddress("localhost", port);
try (var socketChannel = SocketChannel.open()) {
socketChannel.configureBlocking(/* block= */ true);
socketChannel.connect(addr);
}
scanning = false;
} catch (IOException ignored) {
System.out.println("Connect failed, waiting and trying again");
Thread.sleep(1);
}
}
}

public static WorkerInstance startWorker() throws IOException, InterruptedException {
return startWorker(/* useHttp= */ false);
}
Expand All @@ -82,7 +106,6 @@ public static WorkerInstance startWorker(boolean useHttp)
PathFragment testTmpDir = PathFragment.create(tmpDirFile().getAbsolutePath());
PathFragment workPath = testTmpDir.getRelative("remote.work_path");
PathFragment casPath = testTmpDir.getRelative("remote.cas_path");
PathFragment pidPath = testTmpDir.getRelative("remote.pid_file");
int workerPort = pickUnusedRandomPort();
ensureMkdir(workPath);
ensureMkdir(casPath);
Expand All @@ -94,20 +117,10 @@ public static WorkerInstance startWorker(boolean useHttp)
workerPath,
"--work_path=" + workPath.getSafePathString(),
"--cas_path=" + casPath.getSafePathString(),
(useHttp ? "--http_listen_port=" : "--listen_port=") + workerPort,
"--pid_file=" + pidPath))
(useHttp ? "--http_listen_port=" : "--listen_port=") + workerPort))
.start();

File pidFile = new File(pidPath.getSafePathString());
while (!pidFile.exists()) {
if (!workerProcess.isAlive()) {
String message = new String(workerProcess.getErrorStream().readAllBytes(), UTF_8);
throw new IOException("Failed to start worker: " + message);
}
Thread.sleep(1);
}

return new WorkerInstance(workerProcess, workerPort, workPath, casPath, pidPath);
waitForPortOpen(workerPort);
return new WorkerInstance(workerProcess, workerPort, workPath, casPath);
}

private static void ensureMkdir(PathFragment path) throws IOException {
Expand All @@ -125,23 +138,28 @@ public static class WorkerInstance {
private final int port;
private final PathFragment workPath;
private final PathFragment casPath;
private final PathFragment pidPath;

private WorkerInstance(
Subprocess process,
int port,
PathFragment workPath,
PathFragment casPath,
PathFragment pidPath) {
PathFragment casPath) {
this.process = process;
this.port = port;
this.workPath = workPath;
this.casPath = casPath;
this.pidPath = pidPath;
}

public void stop() {
public void stop() throws IOException {
process.destroyAndWait();
deleteDir(workPath);
deleteDir(casPath);
}

private static void deleteDir(PathFragment path) throws IOException {
try (var stream = Files.walk(Paths.get(path.getSafePathString()))) {
stream.sorted(Comparator.reverseOrder()).map(Path::toFile).forEach(File::delete);
}
}

public int getPort() {
Expand All @@ -155,9 +173,5 @@ public PathFragment getWorkPath() {
public PathFragment getCasPath() {
return casPath;
}

public PathFragment getPidPath() {
return pidPath;
}
}
}