Merge branch '1.0.x'

This commit is contained in:
Dave Syer
2017-04-24 09:21:35 +01:00
6 changed files with 269 additions and 33 deletions

View File

@@ -1,14 +1,17 @@
package com.example;
import static com.github.tomakehurst.wiremock.client.WireMock.aResponse;
import static com.github.tomakehurst.wiremock.client.WireMock.get;
import static com.github.tomakehurst.wiremock.client.WireMock.stubFor;
import static com.github.tomakehurst.wiremock.client.WireMock.urlEqualTo;
import static org.assertj.core.api.Assertions.assertThat;
import com.github.tomakehurst.wiremock.http.Fault;
import com.github.tomakehurst.wiremock.junit.WireMockClassRule;
import org.apache.http.MalformedChunkCodingException;
import org.apache.http.NoHttpResponseException;
import org.apache.http.client.ClientProtocolException;
import org.junit.ClassRule;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
@@ -16,7 +19,12 @@ import org.springframework.cloud.contract.wiremock.WireMockSpring;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.junit4.SpringRunner;
import com.github.tomakehurst.wiremock.junit.WireMockClassRule;
import static com.github.tomakehurst.wiremock.client.WireMock.aResponse;
import static com.github.tomakehurst.wiremock.client.WireMock.get;
import static com.github.tomakehurst.wiremock.client.WireMock.stubFor;
import static com.github.tomakehurst.wiremock.client.WireMock.urlEqualTo;
import static org.assertj.core.api.Assertions.assertThat;
import static org.hamcrest.CoreMatchers.instanceOf;
@RunWith(SpringRunner.class)
@SpringBootTest(properties="app.baseUrl=http://localhost:6061", webEnvironment=WebEnvironment.NONE)
@@ -26,14 +34,41 @@ public class WiremockServerApplicationTests {
@ClassRule
public static WireMockClassRule wiremock = new WireMockClassRule(WireMockSpring.options().port(6061));
@Rule
public ExpectedException expected = ExpectedException.none();
@Autowired
private Service service;
@Test
public void contextLoads() throws Exception {
public void hello() throws Exception {
stubFor(get(urlEqualTo("/resource"))
.willReturn(aResponse().withHeader("Content-Type", "text/plain").withBody("Hello World!")));
assertThat(this.service.go()).isEqualTo("Hello World!");
}
@Test
public void randomData() throws Exception {
stubFor(get(urlEqualTo("/resource"))
.willReturn(aResponse().withFault(Fault.RANDOM_DATA_THEN_CLOSE)));
expected.expectCause(instanceOf(ClientProtocolException.class));
assertThat(this.service.go()).isEqualTo("Oops!");
}
@Test
public void emptyResponse() throws Exception {
stubFor(get(urlEqualTo("/resource"))
.willReturn(aResponse().withFault(Fault.EMPTY_RESPONSE)));
expected.expectCause(instanceOf(NoHttpResponseException.class));
assertThat(this.service.go()).isEqualTo("Oops!");
}
@Test
public void malformed() throws Exception {
stubFor(get(urlEqualTo("/resource"))
.willReturn(aResponse().withFault(Fault.MALFORMED_RESPONSE_CHUNK)));
expected.expectCause(instanceOf(MalformedChunkCodingException.class));
assertThat(this.service.go()).isEqualTo("Oops!");
}
}

View File

@@ -1,14 +1,18 @@
package com.example;
import static com.github.tomakehurst.wiremock.client.WireMock.aResponse;
import static com.github.tomakehurst.wiremock.client.WireMock.get;
import static com.github.tomakehurst.wiremock.client.WireMock.stubFor;
import static com.github.tomakehurst.wiremock.client.WireMock.urlEqualTo;
import static org.assertj.core.api.Assertions.assertThat;
import java.io.IOException;
import com.github.tomakehurst.wiremock.http.Fault;
import com.github.tomakehurst.wiremock.junit.WireMockClassRule;
import org.apache.http.NoHttpResponseException;
import org.apache.http.client.ClientProtocolException;
import org.junit.ClassRule;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
@@ -16,7 +20,12 @@ import org.springframework.cloud.contract.wiremock.WireMockSpring;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.junit4.SpringRunner;
import com.github.tomakehurst.wiremock.junit.WireMockClassRule;
import static com.github.tomakehurst.wiremock.client.WireMock.aResponse;
import static com.github.tomakehurst.wiremock.client.WireMock.get;
import static com.github.tomakehurst.wiremock.client.WireMock.stubFor;
import static com.github.tomakehurst.wiremock.client.WireMock.urlEqualTo;
import static org.assertj.core.api.Assertions.assertThat;
import static org.hamcrest.CoreMatchers.instanceOf;
@RunWith(SpringRunner.class)
@SpringBootTest(properties="app.baseUrl=http://localhost:6067", webEnvironment=WebEnvironment.NONE)
@@ -26,6 +35,9 @@ public class WiremockServerApplicationTests {
@ClassRule
public static WireMockClassRule wiremock = new WireMockClassRule(WireMockSpring.options().port(6067));
@Rule
public ExpectedException expected = ExpectedException.none();
@Autowired
private Service service;
@@ -36,4 +48,30 @@ public class WiremockServerApplicationTests {
assertThat(this.service.go()).isEqualTo("Hello World!");
}
@Test
public void randomData() throws Exception {
stubFor(get(urlEqualTo("/resource"))
.willReturn(aResponse().withFault(Fault.RANDOM_DATA_THEN_CLOSE)));
expected.expectCause(instanceOf(ClientProtocolException.class));
assertThat(this.service.go()).isEqualTo("Oops!");
}
@Test
public void emptyResponse() throws Exception {
stubFor(get(urlEqualTo("/resource"))
.willReturn(aResponse().withFault(Fault.EMPTY_RESPONSE)));
expected.expectCause(instanceOf(NoHttpResponseException.class));
assertThat(this.service.go()).isEqualTo("Oops!");
}
@Test
public void malformed() throws Exception {
stubFor(get(urlEqualTo("/resource"))
.willReturn(aResponse().withFault(Fault.MALFORMED_RESPONSE_CHUNK)));
// It's a different exception type than Jetty, but it's in the right ballpark
expected.expectCause(instanceOf(IOException.class));
expected.expectMessage("chunk");
assertThat(this.service.go()).isEqualTo("Oops!");
}
}

View File

@@ -18,11 +18,28 @@ package org.springframework.cloud.contract.wiremock;
import javax.servlet.ServletContext;
import io.undertow.Undertow.Builder;
import com.github.tomakehurst.wiremock.common.HttpsSettings;
import com.github.tomakehurst.wiremock.common.Notifier;
import com.github.tomakehurst.wiremock.core.Options;
import com.github.tomakehurst.wiremock.core.WireMockApp;
import com.github.tomakehurst.wiremock.http.AdminRequestHandler;
import com.github.tomakehurst.wiremock.http.HttpServer;
import com.github.tomakehurst.wiremock.http.HttpServerFactory;
import com.github.tomakehurst.wiremock.http.RequestHandler;
import com.github.tomakehurst.wiremock.http.StubRequestHandler;
import com.github.tomakehurst.wiremock.jetty9.JettyFaultInjectorFactory;
import com.github.tomakehurst.wiremock.servlet.FaultInjectorFactory;
import com.github.tomakehurst.wiremock.servlet.NoFaultInjectorFactory;
import com.github.tomakehurst.wiremock.servlet.WireMockHandlerDispatchingServlet;
import org.apache.catalina.connector.Connector;
import org.eclipse.jetty.server.ConnectionFactory;
import org.eclipse.jetty.server.HttpConfiguration;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.ServerConnector;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.BeanPostProcessor;
@@ -62,21 +79,9 @@ import org.springframework.context.annotation.Import;
import org.springframework.context.event.EventListener;
import org.springframework.context.support.GenericApplicationContext;
import org.springframework.stereotype.Component;
import org.springframework.util.ClassUtils;
import org.springframework.web.context.ServletContextAware;
import com.github.tomakehurst.wiremock.common.HttpsSettings;
import com.github.tomakehurst.wiremock.common.Notifier;
import com.github.tomakehurst.wiremock.core.Options;
import com.github.tomakehurst.wiremock.core.WireMockApp;
import com.github.tomakehurst.wiremock.http.AdminRequestHandler;
import com.github.tomakehurst.wiremock.http.HttpServer;
import com.github.tomakehurst.wiremock.http.HttpServerFactory;
import com.github.tomakehurst.wiremock.http.RequestHandler;
import com.github.tomakehurst.wiremock.http.StubRequestHandler;
import com.github.tomakehurst.wiremock.servlet.WireMockHandlerDispatchingServlet;
import io.undertow.Undertow.Builder;
/**
* @author Dave Syer
*
@@ -258,6 +263,8 @@ class WiremockServerConfiguration {
@Autowired
private StubRequestHandler stubRequestHandler;
@Autowired
private FaultInjectorFactory faultInjectorFactory;
@Autowired
private Options options;
@Bean(name = DispatcherServletAutoConfiguration.DEFAULT_DISPATCHER_SERVLET_REGISTRATION_BEAN_NAME)
@@ -265,6 +272,10 @@ class WiremockServerConfiguration {
ServletRegistrationBean reg = new ServletRegistrationBean();
reg.addInitParameter(RequestHandler.HANDLER_CLASS_KEY,
StubRequestHandler.class.getName());
if (WiremockServerConfiguration.this.faultInjectorFactory != null) {
reg.addInitParameter(FaultInjectorFactory.INJECTOR_CLASS_KEY,
FaultInjectorFactory.class.getName());
}
reg.setServlet(new WireMockHandlerDispatchingServlet());
reg.setName("stub");
reg.addUrlMappings("/");
@@ -293,6 +304,10 @@ class WiremockServerConfiguration {
WiremockServerConfiguration.this.stubRequestHandler);
servletContext.setAttribute(Notifier.KEY,
WiremockServerConfiguration.this.options.notifier());
if (WiremockServerConfiguration.this.faultInjectorFactory != null) {
servletContext.setAttribute(FaultInjectorFactory.class.getName(),
WiremockServerConfiguration.this.faultInjectorFactory);
}
}
};
}
@@ -367,6 +382,11 @@ class ContainerConfiguration {
return tomcat;
}
@Bean
public FaultInjectorFactory faultInjectorFactory() {
return new TomcatFaultInjectorFactory();
}
@EventListener
public void serverUp(EmbeddedServletContainerInitializedEvent event) {
if (this.connector != null) {
@@ -417,6 +437,11 @@ class ContainerConfiguration {
return undertow;
}
@Bean
public FaultInjectorFactory faultInjectorFactory() {
return new NoFaultInjectorFactory();
}
@EventListener
public void serverUp(EmbeddedServletContainerInitializedEvent event) {
if (this.port != null) {
@@ -457,6 +482,11 @@ class ContainerConfiguration {
return jetty;
}
@Bean
public JettyFaultInjectorFactory faultInjectorFactory() {
return new JettyFaultInjectorFactory();
}
private org.eclipse.jetty.server.Connector createStandardConnector(
Server server) {
ServerConnector connector = new ServerConnector(server, -1, -1);

View File

@@ -0,0 +1,95 @@
/*
* Copyright 2016-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.cloud.contract.wiremock;
import java.io.IOException;
import java.lang.reflect.Field;
import java.nio.ByteBuffer;
import javax.servlet.http.HttpServletResponse;
import com.github.tomakehurst.wiremock.common.Exceptions;
import com.github.tomakehurst.wiremock.core.FaultInjector;
import com.google.common.base.Charsets;
import org.apache.coyote.Response;
import org.apache.tomcat.util.net.SocketWrapperBase;
import org.springframework.util.ReflectionUtils;
import static com.github.tomakehurst.wiremock.common.Exceptions.throwUnchecked;
/**
* @author Dave Syer
*
*/
public class TomcatFaultInjector implements FaultInjector {
private static final byte[] GARBAGE = "lskdu018973t09sylgasjkfg1][]'./.sdlv"
.getBytes(Charsets.UTF_8);
private final Response response;
private SocketWrapperBase<?> socket;
public TomcatFaultInjector(HttpServletResponse response) {
this.response = ((org.apache.catalina.connector.Response) getField(response,
"response")).getCoyoteResponse();
this.socket = (SocketWrapperBase<?>) getField(
getField(this.response, "outputBuffer"), "socketWrapper");
}
private Object getField(Object target, String string) {
Field field = ReflectionUtils.findField(target.getClass(), string);
ReflectionUtils.makeAccessible(field);
return ReflectionUtils.getField(field, target);
}
@Override
public void emptyResponseAndCloseConnection() {
try {
socket.close();
}
catch (IOException e) {
Exceptions.throwUnchecked(e);
}
}
@Override
public void malformedResponseChunk() {
try {
response.sendHeaders();
response.doWrite(ByteBuffer.wrap(GARBAGE));
socket.flush(true);
socket.close();
}
catch (IOException e) {
throwUnchecked(e);
}
}
@Override
public void randomDataAndCloseConnection() {
try {
socket.write(true, GARBAGE, 0, GARBAGE.length);
socket.flush(true);
socket.close();
}
catch (IOException e) {
throwUnchecked(e);
}
}
}

View File

@@ -0,0 +1,37 @@
/*
* Copyright 2016-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.cloud.contract.wiremock;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.github.tomakehurst.wiremock.core.FaultInjector;
import com.github.tomakehurst.wiremock.servlet.FaultInjectorFactory;
/**
* @author Dave Syer
*
*/
public class TomcatFaultInjectorFactory implements FaultInjectorFactory {
@Override
public FaultInjector buildFaultInjector(HttpServletRequest httpServletRequest,
HttpServletResponse httpServletResponse) {
return new TomcatFaultInjector(httpServletResponse);
}
}

View File

@@ -1,21 +1,22 @@
package org.springframework.cloud.contract.wiremock;
import static com.github.tomakehurst.wiremock.client.WireMock.aResponse;
import static com.github.tomakehurst.wiremock.client.WireMock.get;
import static com.github.tomakehurst.wiremock.client.WireMock.stubFor;
import static com.github.tomakehurst.wiremock.client.WireMock.urlEqualTo;
import static org.assertj.core.api.Assertions.assertThat;
import com.github.tomakehurst.wiremock.junit.WireMockClassRule;
import org.junit.ClassRule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.junit4.SpringRunner;
import com.github.tomakehurst.wiremock.junit.WireMockClassRule;
import static com.github.tomakehurst.wiremock.client.WireMock.aResponse;
import static com.github.tomakehurst.wiremock.client.WireMock.get;
import static com.github.tomakehurst.wiremock.client.WireMock.stubFor;
import static com.github.tomakehurst.wiremock.client.WireMock.urlEqualTo;
import static org.assertj.core.api.Assertions.assertThat;
@RunWith(SpringRunner.class)
@SpringBootTest(classes=WiremockTestsApplication.class, properties="app.baseUrl=http://localhost:8080", webEnvironment=WebEnvironment.NONE)
@@ -29,7 +30,7 @@ public class WiremockServerApplicationTests {
private Service service;
@Test
public void contextLoads() throws Exception {
public void hello() throws Exception {
stubFor(get(urlEqualTo("/test"))
.willReturn(aResponse().withHeader("Content-Type", "text/plain").withBody("Hello World!")));
assertThat(this.service.go()).isEqualTo("Hello World!");