Skip to content

Commit

Permalink
feat: add option to mock server to disable persistant HTTP/1.1 connec…
Browse files Browse the repository at this point in the history
…tions #1383 #342
  • Loading branch information
Ronald Holshausen committed Jun 27, 2021
1 parent 2caa5b9 commit c3e2fe9
Show file tree
Hide file tree
Showing 5 changed files with 42 additions and 4 deletions.
10 changes: 10 additions & 0 deletions consumer/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -643,3 +643,13 @@ newJsonArray {
}
}
```

## Dealing with persistent HTTP/1.1 connections (Keep Alive)

As each test will get a new mock server, connections can not be persisted between tests. HTTP clients can cache
connections with HTTP/1.1, and this can cause subsequent tests to fail. See [#342](https://github.com/pact-foundation/pact-jvm/issues/342)
and [#1383](https://github.com/pact-foundation/pact-jvm/issues/1383).

One option (if the HTTP client supports it, Apache HTTP Client does) is to set the system property `http.keepAlive` to `false` in
the test JVM. The other option is to set `pact.mockserver.addCloseHeader` to `true` to force the mock server to
send a `Connection: close` header with every response (supported with Pact-JVM 4.2.7+).
10 changes: 10 additions & 0 deletions consumer/junit/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -773,3 +773,13 @@ You can also just use the key instead of an expression:
```java
.valueFromProviderState('userId', 'userId', 100) // will look value using userId as the key
```

## Dealing with persistent HTTP/1.1 connections (Keep Alive)

As each test will get a new mock server, connections can not be persisted between tests. HTTP clients can cache
connections with HTTP/1.1, and this can cause subsequent tests to fail. See [#342](https://github.com/pact-foundation/pact-jvm/issues/342)
and [#1383](https://github.com/pact-foundation/pact-jvm/issues/1383).

One option (if the HTTP client supports it, Apache HTTP Client does) is to set the system property `http.keepAlive` to `false` in
the test JVM. The other option is to set `pact.mockserver.addCloseHeader` to `true` to force the mock server to
send a `Connection: close` header with every response (supported with Pact-JVM 4.2.7+).
10 changes: 10 additions & 0 deletions consumer/junit5/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,16 @@ To enable this:

For an example, see [MultiProviderTest](https://github.com/DiUS/pact-jvm/blob/master/consumer/junit5/src/test/groovy/au/com/dius/pact/consumer/junit5/MultiProviderTest.groovy).

## Dealing with persistent HTTP/1.1 connections (Keep Alive)

As each test will get a new mock server, connections can not be persisted between tests. HTTP clients can cache
connections with HTTP/1.1, and this can cause subsequent tests to fail. See [#342](https://github.com/pact-foundation/pact-jvm/issues/342)
and [#1383](https://github.com/pact-foundation/pact-jvm/issues/1383).

One option (if the HTTP client supports it, Apache HTTP Client does) is to set the system property `http.keepAlive` to `false` in
the test JVM. The other option is to set `pact.mockserver.addCloseHeader` to `true` to force the mock server to
send a `Connection: close` header with every response (supported with Pact-JVM 4.2.7+).

# Message Pacts
## Consumer test for a message consumer
For testing a consumer of messages from a message queue using JUnit 5 and Pact V4, see [AsyncMessageTest](https://github.com/pact-foundation/pact-jvm/blob/ac6a0eae0b18183f6f453eafddb89b90741ace42/consumer/junit5/src/test/java/au/com/dius/pact/consumer/junit5/AsyncMessageTest.java).
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,9 @@ abstract class BaseJdkMockServer(
private fun pactResponseToHttpExchange(response: IResponse, exchange: HttpExchange) {
val headers = response.headers
exchange.responseHeaders.putAll(headers)
if (config.addCloseHeader) {
exchange.responseHeaders.add("Connection", "close")
}
val body = response.body
if (body.isPresent()) {
val bytes = body.unwrap()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,8 @@ open class MockProviderConfig @JvmOverloads constructor (
open val port: Int = 0,
open val pactVersion: PactSpecVersion = PactSpecVersion.V3,
open val scheme: String = HTTP,
open val mockServerImplementation: MockServerImplementation = MockServerImplementation.JavaHttpServer
open val mockServerImplementation: MockServerImplementation = MockServerImplementation.JavaHttpServer,
open val addCloseHeader: Boolean = false
) {

fun url() = "$scheme://$hostname:$port"
Expand All @@ -52,12 +53,15 @@ open class MockProviderConfig @JvmOverloads constructor (
const val HTTP = "http"

@JvmStatic
@JvmOverloads
fun httpConfig(
hostname: String = LOCALHOST,
port: Int = 0,
pactVersion: PactSpecVersion = PactSpecVersion.V3,
implementation: MockServerImplementation = MockServerImplementation.JavaHttpServer
) = MockProviderConfig(hostname, port, pactVersion, HTTP, implementation.merge(MockServerImplementation.JavaHttpServer))
implementation: MockServerImplementation = MockServerImplementation.JavaHttpServer,
addCloseHeader: Boolean = System.getProperty("pact.mockserver.addCloseHeader") == "true"
) = MockProviderConfig(hostname, port, pactVersion, HTTP,
implementation.merge(MockServerImplementation.JavaHttpServer), addCloseHeader)

@JvmStatic
fun createDefault() = createDefault(LOCALHOST, PactSpecVersion.V3)
Expand All @@ -67,6 +71,7 @@ open class MockProviderConfig @JvmOverloads constructor (

@JvmStatic
fun createDefault(host: String, pactVersion: PactSpecVersion) =
MockProviderConfig(hostname = host, pactVersion = pactVersion)
MockProviderConfig(hostname = host, pactVersion = pactVersion,
addCloseHeader = System.getProperty("pact.mockserver.addCloseHeader") == "true")
}
}

0 comments on commit c3e2fe9

Please sign in to comment.