Skip to content

Commit

Permalink
#213 Add incremental capture option
Browse files Browse the repository at this point in the history
  • Loading branch information
tommysitu committed Jul 23, 2019
1 parent 610eb5d commit e7be008
Show file tree
Hide file tree
Showing 9 changed files with 123 additions and 5 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ target/

# Test resources which shouldn't be part of SCM
src/test/resources/hoverfly/recorded-simulation.json
src/test/resources/hoverfly/incremental-capture.json
src/test/resources/hoverfly/third-multi-capture/
io_specto_hoverfly_junit5_HoverflyDefaultCaptureTest_NestedTest.json
*scenario.json
Expand Down
10 changes: 10 additions & 0 deletions src/main/java/io/specto/hoverfly/junit/core/HoverflyConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ public abstract class HoverflyConfig {
protected List<String> captureHeaders;
protected boolean webServer;
protected boolean statefulCapture;
protected boolean incrementalCapture;
protected SimulationPreprocessor simulationPreprocessor;

/**
Expand Down Expand Up @@ -147,6 +148,15 @@ public HoverflyConfig enableStatefulCapture() {
return this;
}

/**
* By default Hoverfly exports the captured requests and responses to a new file by replacing any existing one. Enable this
* option to import any existing simulation file and append new requests to it in capture mode.
* @return the {@link HoverflyConfig} for further customizations
*/
public HoverflyConfig enableIncrementalCapture() {
this.incrementalCapture = true;
return this;
}

/**
* Set proxy CA certificate to validate the authenticity of a Hoverfly instance.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ public class HoverflyConfiguration {
private Logger hoverflyLogger;
private LogLevel logLevel;
private boolean statefulCapture;
private boolean incrementalCapture;
private SimulationPreprocessor simulationPreprocessor;
private String binaryNameFormat;
private List<String> commands;
Expand All @@ -55,8 +56,9 @@ public class HoverflyConfiguration {
final List<String> captureHeaders,
final boolean webServer,
final boolean statefulCapture,
final boolean incrementalCapture,
final SimulationPreprocessor preprocessor) {
this(proxyPort, adminPort, proxyLocalHost, destination, proxyCaCertificate, captureHeaders, webServer, null, null, statefulCapture, preprocessor);
this(proxyPort, adminPort, proxyLocalHost, destination, proxyCaCertificate, captureHeaders, webServer, null, null, statefulCapture, incrementalCapture, preprocessor);
setScheme(scheme);
setHost(host);
this.authToken = authToken;
Expand All @@ -77,6 +79,7 @@ public HoverflyConfiguration(final int proxyPort,
final Logger hoverflyLogger,
final LogLevel logLevel,
final boolean statefulCapture,
final boolean incrementalCapture,
final SimulationPreprocessor preprocessor
) {
this.proxyPort = proxyPort;
Expand All @@ -89,6 +92,7 @@ public HoverflyConfiguration(final int proxyPort,
this.hoverflyLogger = hoverflyLogger;
this.logLevel = logLevel;
this.statefulCapture = statefulCapture;
this.incrementalCapture = incrementalCapture;
this.simulationPreprocessor = preprocessor;
}

Expand Down Expand Up @@ -250,6 +254,10 @@ public boolean isStatefulCapture() {
return statefulCapture;
}

public boolean isIncrementalCapture() {
return incrementalCapture;
}

private boolean isNotBlank(String str) {
return str != null && !str.trim().isEmpty();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ public LocalHoverflyConfig addCommands(String... commands) {
@Override
public HoverflyConfiguration build() {
HoverflyConfiguration configs = new HoverflyConfiguration(proxyPort, adminPort, proxyLocalHost, destination,
proxyCaCert, captureHeaders, webServer, hoverflyLogger, logLevel, statefulCapture, simulationPreprocessor);
proxyCaCert, captureHeaders, webServer, hoverflyLogger, logLevel, statefulCapture, incrementalCapture, simulationPreprocessor);
configs.setSslCertificatePath(sslCertificatePath);
configs.setSslKeyPath(sslKeyPath);
configs.setTlsVerificationDisabled(tlsVerificationDisabled);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ public HoverflyConfiguration build() {
proxyPort = DEFAULT_PROXY_PORT;
}
HoverflyConfiguration configs = new HoverflyConfiguration(scheme, host, proxyPort, adminPort, proxyLocalHost,
destination, proxyCaCert, authToken, adminCertificate, captureHeaders, webServer, statefulCapture,
destination, proxyCaCert, authToken, adminCertificate, captureHeaders, webServer, statefulCapture, incrementalCapture,
simulationPreprocessor);
HoverflyConfigValidator validator = new HoverflyConfigValidator();
return validator.validate(configs);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ public static HoverflyRule inCaptureOrSimulationMode(String recordFile) {
*/
public static HoverflyRule inCaptureOrSimulationMode(String recordFile, HoverflyConfig hoverflyConfig) {
Path path = fileRelativeToTestResourcesHoverfly(recordFile);
if (Files.exists(path) && Files.isRegularFile(path)) {
if (Files.isReadable(path)) {
return inSimulationMode(file(path), hoverflyConfig);
} else {
return inCaptureMode(recordFile, hoverflyConfig);
Expand Down Expand Up @@ -300,6 +300,10 @@ protected void before() {
if (hoverflyMode.allowSimulationImport()) {
importSimulation();
}

if (hoverfly.getHoverflyConfig().isIncrementalCapture() && this.capturePath != null && Files.isReadable(this.capturePath)) {
hoverfly.simulate(SimulationSource.file(this.capturePath));
}
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ public void shouldHaveDefaultSettings() {
assertThat(configs.isWebServer()).isFalse();
assertThat(configs.isTlsVerificationDisabled()).isFalse();
assertThat(configs.isStatefulCapture()).isFalse();
assertThat(configs.isIncrementalCapture()).isFalse();
assertThat(configs.getLogLevel()).isNotPresent();
assertThat(configs.getHoverflyLogger()).isEqualTo(Optional.of(LoggerFactory.getLogger("hoverfly")));
}
Expand Down Expand Up @@ -171,6 +172,14 @@ public void shouldEnableStatefulCapture() {
assertThat(configs.isStatefulCapture()).isTrue();
}

@Test
public void shouldEnableIncrementalCapture() {
HoverflyConfiguration configs = localConfigs().enableIncrementalCapture().build();

assertThat(configs.isIncrementalCapture()).isTrue();
}


@Test
public void shouldAddCommands() {
HoverflyConfiguration configs = localConfigs()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,12 @@

import io.specto.hoverfly.junit.core.Hoverfly;
import io.specto.hoverfly.junit.core.SimulationSource;
import org.junit.Before;
import org.junit.Test;
import org.powermock.reflect.Whitebox;

import java.nio.file.Path;

import static io.specto.hoverfly.junit.core.HoverflyConfig.localConfigs;
import static io.specto.hoverfly.junit.core.SimulationSource.empty;
import static io.specto.hoverfly.junit.dsl.HoverflyDsl.service;
import static io.specto.hoverfly.junit.dsl.ResponseCreators.success;
Expand Down Expand Up @@ -116,6 +116,7 @@ public void shouldThrowExceptionIfOutputFilenameIsEmpty() {
private Hoverfly getHoverflyMock(HoverflyRule hoverflyRule) {
Hoverfly mockHoverfly = mock(Hoverfly.class);
Whitebox.setInternalState(hoverflyRule, "hoverfly", mockHoverfly);
when(mockHoverfly.getHoverflyConfig()).thenReturn(localConfigs().build());
return mockHoverfly;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
package io.specto.hoverfly.ruletest;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.common.io.Resources;
import io.specto.hoverfly.junit.core.model.RequestResponsePair;
import io.specto.hoverfly.junit.core.model.Simulation;
import io.specto.hoverfly.junit.rule.HoverflyRule;
import io.specto.hoverfly.webserver.CaptureModeTestWebServer;
import org.apache.commons.io.FileUtils;
import org.json.JSONException;
import org.junit.*;
import org.skyscreamer.jsonassert.JSONAssert;
import org.skyscreamer.jsonassert.JSONCompareMode;
import org.springframework.web.client.RestTemplate;

import java.io.IOException;
import java.io.PrintWriter;
import java.net.URI;
import java.net.URISyntaxException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Set;

import static io.specto.hoverfly.junit.core.HoverflyConfig.localConfigs;
import static java.nio.charset.Charset.defaultCharset;
import static org.assertj.core.api.Assertions.assertThat;

public class IncrementalCaptureTest {


private static final Path SIMULATION_FILE = Paths.get("src/test/resources/hoverfly/incremental-capture.json");
private static final String SIMULATION_FILE_NAME = "incremental-capture.json";

private static URI webServerBaseUrl;

@BeforeClass
public static void beforeAll() throws Exception {

Files.deleteIfExists(SIMULATION_FILE);
webServerBaseUrl = CaptureModeTestWebServer.run();
}

@Rule
public HoverflyRule hoverflyRule = HoverflyRule.inCaptureMode(SIMULATION_FILE_NAME,
localConfigs()
.captureAllHeaders()
.proxyLocalHost()
.enableIncrementalCapture());


private RestTemplate restTemplate = new RestTemplate();


@Test
public void shouldRecordFirstRequest() {
// When
restTemplate.getForObject(webServerBaseUrl, String.class);
}

@Test
public void shouldRecordSecondRequest() {
// When
restTemplate.getForObject(webServerBaseUrl + "/other", String.class);
}


// We have to assert after the rule has executed because that's when the classpath is written to the filesystem
@AfterClass
public static void afterAll() throws IOException {

// Verify captured data is expected
final String actualSimulation = new String(Files.readAllBytes(SIMULATION_FILE), defaultCharset());

// Verify headers are captured
ObjectMapper objectMapper = new ObjectMapper();
Simulation simulation = objectMapper.readValue(actualSimulation, Simulation.class);
Set<RequestResponsePair> pairs = simulation.getHoverflyData().getPairs();
assertThat(pairs).hasSize(2);
assertThat(pairs.iterator().next().getRequest().getHeaders()).isNotEmpty();

CaptureModeTestWebServer.terminate();
}

}

0 comments on commit e7be008

Please sign in to comment.