Skip to content

Commit 4af3726

Browse files
authored
[grid] ensure all states of StartOrDie are handled (#11297)
ensure all states of StartOrDie are handled DriverService.start did not fail, if the execution of the driver process was never started or the process did not bind the port.
1 parent 21d115e commit 4af3726

File tree

3 files changed

+37
-17
lines changed

3 files changed

+37
-17
lines changed

java/src/org/openqa/selenium/os/CommandLine.java

+5
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
import java.io.File;
2828
import java.io.OutputStream;
2929
import java.util.Map;
30+
import java.util.concurrent.TimeUnit;
3031

3132
public class CommandLine {
3233

@@ -100,6 +101,10 @@ public void execute() {
100101
waitFor();
101102
}
102103

104+
public boolean waitForProcessStarted(long duration, TimeUnit unit) {
105+
return process.waitForProcessStarted(duration, unit);
106+
}
107+
103108
public void waitFor() {
104109
try {
105110
process.waitFor();

java/src/org/openqa/selenium/os/OsProcess.java

+22-12
Original file line numberDiff line numberDiff line change
@@ -105,25 +105,32 @@ public void executeAsync() {
105105
}
106106
}
107107

108+
public boolean waitForProcessStarted(long duration, TimeUnit unit) {
109+
return executeWatchdog.waitForProcessStarted(duration, unit);
110+
}
111+
108112
private OutputStream getOutputStream() {
109113
return drainTo == null ? inputOut
110114
: new MultiOutputStream(inputOut, drainTo);
111115
}
112116

113117
public int destroy() {
114118
SeleniumWatchDog watchdog = executeWatchdog;
115-
watchdog.waitForProcessStarted();
116119

117-
// I literally have no idea why we don't try and kill the process nicely on Windows. If you do,
118-
// answers on the back of a postcard to SeleniumHQ, please.
119-
if (!Platform.getCurrent().is(WINDOWS)) {
120-
watchdog.destroyProcess();
121-
watchdog.waitForTerminationAfterDestroy(2, SECONDS);
122-
}
120+
if (watchdog.waitForProcessStarted(2, TimeUnit.MINUTES)) {
121+
// I literally have no idea why we don't try and kill the process nicely on Windows. If you do,
122+
// answers on the back of a postcard to SeleniumHQ, please.
123+
if (!Platform.getCurrent().is(WINDOWS)) {
124+
watchdog.destroyProcess();
125+
watchdog.waitForTerminationAfterDestroy(2, SECONDS);
126+
}
123127

124-
if (isRunning()) {
125-
watchdog.destroyHarder();
126-
watchdog.waitForTerminationAfterDestroy(1, SECONDS);
128+
if (isRunning()) {
129+
watchdog.destroyHarder();
130+
watchdog.waitForTerminationAfterDestroy(1, SECONDS);
131+
}
132+
} else {
133+
log.warning("Tried to destory a process which never started.");
127134
}
128135

129136
// Make a best effort to drain the streams.
@@ -236,15 +243,18 @@ public void reset() {
236243
starting = true;
237244
}
238245

239-
private void waitForProcessStarted() {
240-
while (starting) {
246+
private boolean waitForProcessStarted(long duration, TimeUnit unit) {
247+
long end = System.currentTimeMillis() + unit.toMillis(duration);
248+
while (starting && System.currentTimeMillis() < end) {
241249
try {
242250
Thread.sleep(50);
243251
} catch (InterruptedException e) {
244252
Thread.currentThread().interrupt();
245253
throw new WebDriverException(e);
246254
}
247255
}
256+
257+
return !starting;
248258
}
249259

250260
private void waitForTerminationAfterDestroy(int duration, TimeUnit unit) {

java/src/org/openqa/selenium/remote/service/DriverService.java

+10-5
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,9 @@ public void start() throws IOException {
213213
process.setEnvironmentVariables(environment);
214214
process.copyOutputTo(getOutputStream());
215215
process.executeAsync();
216+
if (!process.waitForProcessStarted(timeout.toMillis(), TimeUnit.MILLISECONDS)) {
217+
throw new WebDriverException("Timed out waiting for driver process to start.");
218+
}
216219

217220
CompletableFuture<StartOrDie> serverStarted = CompletableFuture.supplyAsync(() -> {
218221
waitUntilAvailable();
@@ -231,13 +234,15 @@ public void start() throws IOException {
231234
try {
232235
StartOrDie status = (StartOrDie) CompletableFuture.anyOf(serverStarted, processFinished)
233236
.get(getTimeout().toMillis() * 2, TimeUnit.MILLISECONDS);
234-
if (status == StartOrDie.SERVER_STARTED) {
235-
processFinished.cancel(true);
236-
} else {
237-
if (status == StartOrDie.PROCESS_DIED) {
237+
switch (status) {
238+
case SERVER_STARTED:
239+
processFinished.cancel(true);
240+
break;
241+
case PROCESS_DIED:
238242
process = null;
239243
throw new WebDriverException("Driver server process died prematurely.");
240-
}
244+
case PROCESS_IS_ACTIVE:
245+
throw new WebDriverException("Timed out waiting for driver server to bind the port.");
241246
}
242247
} catch (ExecutionException | TimeoutException e) {
243248
throw new WebDriverException("Timed out waiting for driver server to start.", e);

0 commit comments

Comments
 (0)