Skip to content

Commit a3f3023

Browse files
martin-tarjanyitommysitu
authored andcommitted
Allow health check timeout configuration
1 parent af50dd8 commit a3f3023

File tree

8 files changed

+199
-74
lines changed

8 files changed

+199
-74
lines changed

src/main/java/io/specto/hoverfly/junit/core/Hoverfly.java

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -12,16 +12,6 @@
1212
*/
1313
package io.specto.hoverfly.junit.core;
1414

15-
import static io.specto.hoverfly.junit.core.HoverflyConfig.localConfigs;
16-
import static io.specto.hoverfly.junit.core.HoverflyMode.CAPTURE;
17-
import static io.specto.hoverfly.junit.core.HoverflyMode.DIFF;
18-
import static io.specto.hoverfly.junit.core.HoverflyUtils.checkPortInUse;
19-
import static io.specto.hoverfly.junit.core.HoverflyUtils.readSimulationFromString;
20-
import static io.specto.hoverfly.junit.dsl.matchers.HoverflyMatchers.any;
21-
import static io.specto.hoverfly.junit.verification.HoverflyVerifications.atLeastOnce;
22-
import static io.specto.hoverfly.junit.verification.HoverflyVerifications.never;
23-
import static io.specto.hoverfly.junit.verification.HoverflyVerifications.times;
24-
2515
import io.specto.hoverfly.junit.api.HoverflyClient;
2616
import io.specto.hoverfly.junit.api.HoverflyClientException;
2717
import io.specto.hoverfly.junit.api.model.ModeArguments;
@@ -38,6 +28,12 @@
3828
import io.specto.hoverfly.junit.verification.HoverflyDiffAssertionError;
3929
import io.specto.hoverfly.junit.verification.VerificationCriteria;
4030
import io.specto.hoverfly.junit.verification.VerificationData;
31+
import org.apache.commons.lang3.StringUtils;
32+
import org.slf4j.Logger;
33+
import org.slf4j.LoggerFactory;
34+
import org.zeroturnaround.exec.ProcessExecutor;
35+
import org.zeroturnaround.exec.StartedProcess;
36+
4137
import java.io.File;
4238
import java.io.IOException;
4339
import java.io.OutputStream;
@@ -58,20 +54,23 @@
5854
import java.util.concurrent.TimeUnit;
5955
import java.util.concurrent.TimeoutException;
6056
import java.util.stream.Stream;
61-
import org.apache.commons.lang3.StringUtils;
62-
import org.slf4j.Logger;
63-
import org.slf4j.LoggerFactory;
64-
import org.zeroturnaround.exec.ProcessExecutor;
65-
import org.zeroturnaround.exec.StartedProcess;
57+
58+
import static io.specto.hoverfly.junit.core.HoverflyConfig.localConfigs;
59+
import static io.specto.hoverfly.junit.core.HoverflyMode.CAPTURE;
60+
import static io.specto.hoverfly.junit.core.HoverflyMode.DIFF;
61+
import static io.specto.hoverfly.junit.core.HoverflyUtils.checkPortInUse;
62+
import static io.specto.hoverfly.junit.core.HoverflyUtils.readSimulationFromString;
63+
import static io.specto.hoverfly.junit.dsl.matchers.HoverflyMatchers.any;
64+
import static io.specto.hoverfly.junit.verification.HoverflyVerifications.atLeastOnce;
65+
import static io.specto.hoverfly.junit.verification.HoverflyVerifications.never;
66+
import static io.specto.hoverfly.junit.verification.HoverflyVerifications.times;
6667

6768
/**
6869
* A wrapper class for the Hoverfly binary. Manage the lifecycle of the processes, and then manage Hoverfly itself by using it's API endpoints.
6970
*/
7071
public class Hoverfly implements AutoCloseable {
7172

7273
private static final Logger LOGGER = LoggerFactory.getLogger(Hoverfly.class);
73-
private static final int BOOT_TIMEOUT_SECONDS = 10;
74-
private static final int RETRY_BACKOFF_INTERVAL_MS = 100;
7574

7675

7776
private final HoverflyConfiguration hoverflyConfig;
@@ -533,16 +532,17 @@ private void persistSimulation(Path path, Simulation simulation) throws IOExcept
533532
private void waitForHoverflyToBecomeHealthy() {
534533
final Instant now = Instant.now();
535534

536-
while (Duration.between(now, Instant.now()).getSeconds() < BOOT_TIMEOUT_SECONDS) {
535+
while (Duration.between(now, Instant.now()).toMillis() < hoverflyConfig.getHealthCheckTimeout().toMillis()) {
537536
if (hoverflyClient.getHealth()) return;
538537
try {
539538
// TODO: prefer executors and tasks to threads
540-
Thread.sleep(RETRY_BACKOFF_INTERVAL_MS);
539+
Thread.sleep(hoverflyConfig.getHealthCheckRetryInterval().toMillis());
541540
} catch (InterruptedException e) {
542541
throw new RuntimeException(e);
543542
}
544543
}
545-
throw new IllegalStateException("Hoverfly has not become healthy in " + BOOT_TIMEOUT_SECONDS + " seconds");
544+
throw new IllegalStateException(
545+
"Hoverfly has not become healthy in " + hoverflyConfig.getHealthCheckTimeout().toMillis() + " milliseconds");
546546
}
547547

548548
private void setModeWithArguments(HoverflyMode mode, HoverflyConfiguration config) {

src/main/java/io/specto/hoverfly/junit/core/HoverflyConstants.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,17 @@
11
package io.specto.hoverfly.junit.core;
22

3+
import java.time.Duration;
4+
35
public class HoverflyConstants {
46

57
public static final int DEFAULT_PROXY_PORT = 8500;
68
public static final int DEFAULT_ADMIN_PORT = 8888;
79
public static final int DEFAULT_HTTPS_ADMIN_PORT = 443;
810

11+
// Timeout
12+
public static final Duration DEFAULT_HEALTH_CHECK_TIMEOUT = Duration.ofSeconds(10);
13+
public static final Duration DEFAULT_HEALTH_CHECK_RETRY_INTERVAL = Duration.ofMillis(100);
14+
915
// Hoverfly custom auth header name
1016
public static final String X_HOVERFLY_AUTHORIZATION = "X-HOVERFLY-AUTHORIZATION";
1117

src/main/java/io/specto/hoverfly/junit/core/config/HoverflyConfigValidator.java

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,13 @@
33
import io.specto.hoverfly.junit.core.Hoverfly;
44
import io.specto.hoverfly.junit.core.HoverflyConfig;
55
import io.specto.hoverfly.junit.core.HoverflyConstants;
6-
import java.net.URL;
7-
import java.nio.file.Paths;
86
import org.apache.commons.lang3.StringUtils;
97

108
import java.io.IOException;
119
import java.net.ServerSocket;
1210
import java.net.URI;
1311
import java.net.URISyntaxException;
12+
import java.net.URL;
1413
import java.util.Optional;
1514

1615

@@ -69,6 +68,14 @@ HoverflyConfiguration validate(HoverflyConfiguration hoverflyConfig) {
6968
}
7069
}
7170

71+
if (hoverflyConfig.getHealthCheckTimeout() == null) {
72+
hoverflyConfig.setHealthCheckTimeout(HoverflyConstants.DEFAULT_HEALTH_CHECK_TIMEOUT);
73+
}
74+
75+
if (hoverflyConfig.getHealthCheckRetryInterval() == null) {
76+
hoverflyConfig.setHealthCheckRetryInterval(HoverflyConstants.DEFAULT_HEALTH_CHECK_RETRY_INTERVAL);
77+
}
78+
7279
// Check proxy CA cert exists
7380
if (hoverflyConfig.getProxyCaCertificate().isPresent()) {
7481
checkResourceOnClasspath(hoverflyConfig.getProxyCaCertificate().get());

src/main/java/io/specto/hoverfly/junit/core/config/HoverflyConfiguration.java

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import io.specto.hoverfly.junit.core.SimulationPreprocessor;
55
import org.slf4j.Logger;
66

7+
import java.time.Duration;
78
import java.util.List;
89
import java.util.Optional;
910

@@ -47,6 +48,8 @@ public class HoverflyConfiguration {
4748
private String clientCaCertPath;
4849
private String responseBodyFilesPath;
4950
private boolean isRelativeResponseBodyFilesPath;
51+
private Duration healthCheckTimeout;
52+
private Duration healthCheckRetryInterval;
5053

5154
/**
5255
* Create configurations for external hoverfly
@@ -353,4 +356,20 @@ public boolean isRelativeResponseBodyFilesPath() {
353356
public void setRelativeResponseBodyFilesPath(boolean relativeResponseBodyFilesPath) {
354357
isRelativeResponseBodyFilesPath = relativeResponseBodyFilesPath;
355358
}
359+
360+
public Duration getHealthCheckTimeout() {
361+
return healthCheckTimeout;
362+
}
363+
364+
public void setHealthCheckTimeout(Duration healthCheckTimeout) {
365+
this.healthCheckTimeout = healthCheckTimeout;
366+
}
367+
368+
public Duration getHealthCheckRetryInterval() {
369+
return healthCheckRetryInterval;
370+
}
371+
372+
public void setHealthCheckRetryInterval(Duration healthCheckRetryInterval) {
373+
this.healthCheckRetryInterval = healthCheckRetryInterval;
374+
}
356375
}

src/main/java/io/specto/hoverfly/junit/core/config/LocalHoverflyConfig.java

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,14 @@
1414

1515
import io.specto.hoverfly.junit.core.Hoverfly;
1616
import io.specto.hoverfly.junit.core.HoverflyConfig;
17+
import org.slf4j.Logger;
18+
import org.slf4j.LoggerFactory;
19+
1720
import java.net.InetSocketAddress;
21+
import java.time.Duration;
1822
import java.util.Arrays;
1923
import java.util.LinkedList;
2024
import java.util.List;
21-
import org.slf4j.Logger;
22-
import org.slf4j.LoggerFactory;
2325

2426
/**
2527
* Config builder interface for settings specific to {@link Hoverfly} managed internally
@@ -40,6 +42,8 @@ public class LocalHoverflyConfig extends HoverflyConfig {
4042
private String clientKeyPath;
4143
private String clientAuthDestination;
4244
private String clientCaCertPath;
45+
private Duration healthCheckTimeout;
46+
private Duration healthCheckRetryInterval;
4347

4448
/**
4549
* Sets the certificate file to override the default Hoverfly's CA cert
@@ -202,6 +206,26 @@ public LocalHoverflyConfig clientAuthCaCertPath(String clientCaCertPath) {
202206
return this;
203207
}
204208

209+
/**
210+
* Set the maximum time to wait for Hoverfly to be healthy.
211+
* @param healthCheckTimeout the health check timeout
212+
* @return the {@link HoverflyConfig} for further customizations
213+
*/
214+
public HoverflyConfig healthCheckTimeout(Duration healthCheckTimeout) {
215+
this.healthCheckTimeout = healthCheckTimeout;
216+
return this;
217+
}
218+
219+
/**
220+
* Set the interval between health checks.
221+
* @param healthCheckRetryInterval the health check retry interval
222+
* @return the {@link HoverflyConfig} for further customizations
223+
*/
224+
public HoverflyConfig healthCheckRetryInterval(Duration healthCheckRetryInterval) {
225+
this.healthCheckRetryInterval = healthCheckRetryInterval;
226+
return this;
227+
}
228+
205229
@Override
206230
public HoverflyConfiguration build() {
207231
HoverflyConfiguration configs = new HoverflyConfiguration(proxyPort, adminPort, proxyLocalHost, destination,
@@ -220,6 +244,8 @@ public HoverflyConfiguration build() {
220244
configs.setClientCaCertPath(clientCaCertPath);
221245
configs.setResponseBodyFilesPath(responseBodyFilesPath);
222246
configs.setRelativeResponseBodyFilesPath(isRelativeResponseBodyFilesPath);
247+
configs.setHealthCheckTimeout(healthCheckTimeout);
248+
configs.setHealthCheckRetryInterval(healthCheckRetryInterval);
223249
HoverflyConfigValidator validator = new HoverflyConfigValidator();
224250
return validator.validate(configs);
225251
}

src/main/java/io/specto/hoverfly/junit/core/config/RemoteHoverflyConfig.java

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
import io.specto.hoverfly.junit.core.HoverflyConfig;
55
import io.specto.hoverfly.junit.core.HoverflyConstants;
66

7+
import java.time.Duration;
8+
79
import static io.specto.hoverfly.junit.core.HoverflyConstants.DEFAULT_ADMIN_PORT;
810
import static io.specto.hoverfly.junit.core.HoverflyConstants.DEFAULT_PROXY_PORT;
911

@@ -16,6 +18,8 @@ public class RemoteHoverflyConfig extends HoverflyConfig {
1618
private String scheme;
1719
private String authToken;
1820
private String adminCertificate; // file name relative to test resources folder
21+
private Duration healthCheckTimeout;
22+
private Duration healthCheckRetryInterval;
1923

2024

2125
/**
@@ -59,6 +63,26 @@ public RemoteHoverflyConfig withHttpsAdminEndpoint() {
5963
return this;
6064
}
6165

66+
/**
67+
* Set the maximum time to wait for Hoverfly to be healthy.
68+
* @param healthCheckTimeout the health check timeout
69+
* @return the {@link HoverflyConfig} for further customizations
70+
*/
71+
public HoverflyConfig healthCheckTimeout(Duration healthCheckTimeout) {
72+
this.healthCheckTimeout = healthCheckTimeout;
73+
return this;
74+
}
75+
76+
/**
77+
* Set the interval between health checks.
78+
* @param healthCheckRetryInterval the health check retry interval
79+
* @return the {@link HoverflyConfig} for further customizations
80+
*/
81+
public HoverflyConfig healthCheckRetryInterval(Duration healthCheckRetryInterval) {
82+
this.healthCheckRetryInterval = healthCheckRetryInterval;
83+
return this;
84+
}
85+
6286
// TODO add support for custom server certificate for admin endpoint
6387

6488
@Override
@@ -72,6 +96,8 @@ public HoverflyConfiguration build() {
7296
HoverflyConfiguration configs = new HoverflyConfiguration(scheme, host, proxyPort, adminPort, proxyLocalHost,
7397
destination, proxyCaCert, authToken, adminCertificate, captureHeaders, webServer, statefulCapture, incrementalCapture,
7498
simulationPreprocessor);
99+
configs.setHealthCheckTimeout(healthCheckTimeout);
100+
configs.setHealthCheckRetryInterval(healthCheckRetryInterval);
75101
HoverflyConfigValidator validator = new HoverflyConfigValidator();
76102
return validator.validate(configs);
77103
}

src/test/java/io/specto/hoverfly/junit/core/HoverflyConfigTest.java

Lines changed: 34 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,19 @@
11
package io.specto.hoverfly.junit.core;
22

33
import io.specto.hoverfly.junit.core.config.HoverflyConfiguration;
4-
import java.net.InetSocketAddress;
5-
import java.util.Optional;
6-
74
import io.specto.hoverfly.junit.core.config.LogLevel;
85
import org.junit.Rule;
96
import org.junit.Test;
107
import org.junit.contrib.java.lang.system.EnvironmentVariables;
118
import org.slf4j.LoggerFactory;
129

10+
import java.net.InetSocketAddress;
11+
import java.time.Duration;
12+
import java.util.Optional;
13+
1314
import static io.specto.hoverfly.junit.core.HoverflyConfig.localConfigs;
1415
import static io.specto.hoverfly.junit.core.HoverflyConfig.remoteConfigs;
1516
import static org.assertj.core.api.Assertions.assertThat;
16-
import static org.assertj.core.api.Assertions.assertThatThrownBy;
1717

1818

1919
public class HoverflyConfigTest {
@@ -47,6 +47,9 @@ public void shouldHaveDefaultSettings() {
4747
assertThat(configs.getClientKeyPath()).isNull();
4848
assertThat(configs.getClientAuthDestination()).isNull();
4949
assertThat(configs.getClientCaCertPath()).isNull();
50+
51+
assertThat(configs.getHealthCheckTimeout()).isEqualTo(Duration.ofSeconds(10));
52+
assertThat(configs.getHealthCheckRetryInterval()).isEqualTo(Duration.ofMillis(100));
5053
}
5154

5255
@Test
@@ -237,4 +240,31 @@ public void shouldSetClientAuthCaCert() {
237240
assertThat(configs.getClientCaCertPath()).isEqualTo("ssl/ca.pem");
238241
}
239242

243+
@Test
244+
public void shouldSetHealthCheckTimeoutInLocalConfig() {
245+
HoverflyConfiguration configs = localConfigs().healthCheckTimeout(Duration.ofSeconds(20)).build();
246+
247+
assertThat(configs.getHealthCheckTimeout()).isEqualTo(Duration.ofSeconds(20));
248+
}
249+
250+
@Test
251+
public void shouldSetHealthCheckRetryIntervalInLocalConfig() {
252+
HoverflyConfiguration configs = localConfigs().healthCheckRetryInterval(Duration.ofSeconds(5)).build();
253+
254+
assertThat(configs.getHealthCheckRetryInterval()).isEqualTo(Duration.ofSeconds(5));
255+
}
256+
257+
@Test
258+
public void shouldSetHealthCheckTimeoutInRemoteConfig() {
259+
HoverflyConfiguration configs = remoteConfigs().healthCheckTimeout(Duration.ofSeconds(20)).build();
260+
261+
assertThat(configs.getHealthCheckTimeout()).isEqualTo(Duration.ofSeconds(20));
262+
}
263+
264+
@Test
265+
public void shouldSetHealthCheckRetryIntervalInRemoteConfig() {
266+
HoverflyConfiguration configs = remoteConfigs().healthCheckRetryInterval(Duration.ofSeconds(5)).build();
267+
268+
assertThat(configs.getHealthCheckRetryInterval()).isEqualTo(Duration.ofSeconds(5));
269+
}
240270
}

0 commit comments

Comments
 (0)