Add mock report when deleting mock
This commit is contained in:
parent
d476478192
commit
0b4f4e0cf8
11 changed files with 224 additions and 26 deletions
|
@ -49,13 +49,13 @@ class ContextExecutor {
|
||||||
Util.createResponse(httpExchange, response.text, response.statusCode)
|
Util.createResponse(httpExchange, response.text, response.statusCode)
|
||||||
}
|
}
|
||||||
|
|
||||||
int removeMock(String name) {
|
List<MockEvent> removeMock(String name) {
|
||||||
Mock mock = mocks.find { it.name == name }
|
Mock mock = mocks.find { it.name == name }
|
||||||
if (mock) {
|
if (mock) {
|
||||||
mocks.remove(mock)
|
mocks.remove(mock)
|
||||||
return mock.counter
|
return mock.history
|
||||||
}
|
}
|
||||||
return 0
|
return []
|
||||||
}
|
}
|
||||||
|
|
||||||
void addMock(Mock mock) {
|
void addMock(Mock mock) {
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
package pl.touk.mockserver.server
|
package pl.touk.mockserver.server
|
||||||
|
|
||||||
import com.sun.net.httpserver.HttpExchange
|
import com.sun.net.httpserver.HttpExchange
|
||||||
import groovy.transform.PackageScope
|
|
||||||
import groovy.util.slurpersupport.GPathResult
|
import groovy.util.slurpersupport.GPathResult
|
||||||
import groovy.xml.MarkupBuilder
|
import groovy.xml.MarkupBuilder
|
||||||
|
|
||||||
|
@ -10,7 +9,6 @@ import java.util.concurrent.CopyOnWriteArraySet
|
||||||
|
|
||||||
import static pl.touk.mockserver.server.Util.createResponse
|
import static pl.touk.mockserver.server.Util.createResponse
|
||||||
|
|
||||||
@PackageScope
|
|
||||||
class HttpMockServer {
|
class HttpMockServer {
|
||||||
|
|
||||||
private final HttpServerWraper httpServerWraper
|
private final HttpServerWraper httpServerWraper
|
||||||
|
@ -104,11 +102,43 @@ class HttpMockServer {
|
||||||
throw new RuntimeException('mock not registered')
|
throw new RuntimeException('mock not registered')
|
||||||
}
|
}
|
||||||
println "Removing $name"
|
println "Removing $name"
|
||||||
int used = childServers.inject(0) { int res, HttpServerWraper server -> server.removeMock(name) + res }
|
List<MockEvent> mockEvents = childServers.collect { it.removeMock(name) }.flatten()
|
||||||
mockNames.remove(name)
|
mockNames.remove(name)
|
||||||
StringWriter sw = new StringWriter()
|
StringWriter sw = new StringWriter()
|
||||||
MarkupBuilder builder = new MarkupBuilder(sw)
|
MarkupBuilder builder = new MarkupBuilder(sw)
|
||||||
builder.mockRemoved used
|
builder.mockRemoved {
|
||||||
|
mockEvents.each { MockEvent m ->
|
||||||
|
builder.mockEvent {
|
||||||
|
builder.request {
|
||||||
|
text m.request.text
|
||||||
|
headers {
|
||||||
|
m.request.headers.each {
|
||||||
|
builder.param(name: it.key, it.value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
query {
|
||||||
|
m.request.query.each {
|
||||||
|
builder.param(name: it.key, it.value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
path {
|
||||||
|
m.request.path.each {
|
||||||
|
builder.elem it
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
builder.response {
|
||||||
|
text m.response.text
|
||||||
|
headers {
|
||||||
|
m.response.headers.each {
|
||||||
|
builder.param(name: it.key, it.value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
statusCode m.response.statusCode
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
createResponse(ex, sw.toString(), 200)
|
createResponse(ex, sw.toString(), 200)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -42,8 +42,8 @@ class HttpServerWraper {
|
||||||
httpServer.stop(0)
|
httpServer.stop(0)
|
||||||
}
|
}
|
||||||
|
|
||||||
int removeMock(String name) {
|
List<MockEvent> removeMock(String name) {
|
||||||
return executors.inject(0) { int res, ContextExecutor e -> e.removeMock(name) + res }
|
return executors.collect { it.removeMock(name) }.flatten()
|
||||||
}
|
}
|
||||||
|
|
||||||
List<Mock> getMocks() {
|
List<Mock> getMocks() {
|
||||||
|
|
|
@ -3,6 +3,8 @@ package pl.touk.mockserver.server
|
||||||
import groovy.transform.EqualsAndHashCode
|
import groovy.transform.EqualsAndHashCode
|
||||||
import groovy.transform.PackageScope
|
import groovy.transform.PackageScope
|
||||||
|
|
||||||
|
import java.util.concurrent.CopyOnWriteArrayList
|
||||||
|
|
||||||
@PackageScope
|
@PackageScope
|
||||||
@EqualsAndHashCode(excludes = ["counter"])
|
@EqualsAndHashCode(excludes = ["counter"])
|
||||||
class Mock implements Comparable<Mock> {
|
class Mock implements Comparable<Mock> {
|
||||||
|
@ -16,6 +18,7 @@ class Mock implements Comparable<Mock> {
|
||||||
int statusCode = 200
|
int statusCode = 200
|
||||||
String method = 'POST'
|
String method = 'POST'
|
||||||
int counter = 0
|
int counter = 0
|
||||||
|
final List<MockEvent> history = new CopyOnWriteArrayList<>()
|
||||||
|
|
||||||
Mock(String name, String path, int port) {
|
Mock(String name, String path, int port) {
|
||||||
if (!(name)) {
|
if (!(name)) {
|
||||||
|
@ -36,7 +39,9 @@ class Mock implements Comparable<Mock> {
|
||||||
String responseText = response(request)
|
String responseText = response(request)
|
||||||
String response = soap ? wrapSoap(responseText) : responseText
|
String response = soap ? wrapSoap(responseText) : responseText
|
||||||
Map<String, String> headers = responseHeaders(request)
|
Map<String, String> headers = responseHeaders(request)
|
||||||
return new MockResponse(statusCode, response, headers)
|
MockResponse mockResponse = new MockResponse(statusCode, response, headers)
|
||||||
|
history << new MockEvent(request, mockResponse)
|
||||||
|
return mockResponse
|
||||||
}
|
}
|
||||||
|
|
||||||
private static String wrapSoap(String request) {
|
private static String wrapSoap(String request) {
|
||||||
|
|
14
src/main/groovy/pl/touk/mockserver/server/MockEvent.groovy
Normal file
14
src/main/groovy/pl/touk/mockserver/server/MockEvent.groovy
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
package pl.touk.mockserver.server
|
||||||
|
|
||||||
|
import groovy.transform.PackageScope
|
||||||
|
|
||||||
|
@PackageScope
|
||||||
|
class MockEvent {
|
||||||
|
final MockRequest request
|
||||||
|
final MockResponse response
|
||||||
|
|
||||||
|
MockEvent(MockRequest request, MockResponse response) {
|
||||||
|
this.request = request
|
||||||
|
this.response = response
|
||||||
|
}
|
||||||
|
}
|
|
@ -31,17 +31,32 @@ class ControlServerClient {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int removeMock(String name) {
|
List<MockEvent> removeMock(String name) {
|
||||||
HttpPost removeMockPost = new HttpPost(address)
|
HttpPost removeMockPost = new HttpPost(address)
|
||||||
removeMockPost.entity = buildRemoveMockRequest(new RemoveMockRequestData(name: name))
|
removeMockPost.entity = buildRemoveMockRequest(new RemoveMockRequestData(name: name))
|
||||||
CloseableHttpResponse response = client.execute(removeMockPost)
|
CloseableHttpResponse response = client.execute(removeMockPost)
|
||||||
GPathResult responseXml = Util.extractXmlResponse(response)
|
GPathResult responseXml = Util.extractXmlResponse(response)
|
||||||
if (responseXml.name() == 'mockRemoved') {
|
if (responseXml.name() == 'mockRemoved') {
|
||||||
return responseXml.text() as int
|
return responseXml.'mockEvent'.collect {
|
||||||
|
new MockEvent(mockRequestFromXml(it.request), mockResponseFromXml(it.response))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
throw new MockDoesNotExist()
|
throw new MockDoesNotExist()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static MockResponse mockResponseFromXml(GPathResult xml) {
|
||||||
|
return new MockResponse(xml.statusCode.text() as int, xml.text.text(), xml.headers.param.collectEntries { [(it.@name.text()):it.text()] })
|
||||||
|
}
|
||||||
|
|
||||||
|
private static MockRequest mockRequestFromXml(GPathResult xml) {
|
||||||
|
return new MockRequest(
|
||||||
|
xml.text.text(),
|
||||||
|
xml.headers.param.collectEntries { [(it.@name.text()):it.text()] },
|
||||||
|
xml.query.param.collectEntries { [(it.@name.text()):it.text()] },
|
||||||
|
xml.path.elem*.text()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
private static StringEntity buildRemoveMockRequest(RemoveMockRequestData data) {
|
private static StringEntity buildRemoveMockRequest(RemoveMockRequestData data) {
|
||||||
return new StringEntity("""\
|
return new StringEntity("""\
|
||||||
<removeMock>
|
<removeMock>
|
||||||
|
|
18
src/test/groovy/pl/touk/mockserver/client/MockEvent.groovy
Normal file
18
src/test/groovy/pl/touk/mockserver/client/MockEvent.groovy
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
package pl.touk.mockserver.client
|
||||||
|
|
||||||
|
import groovy.transform.CompileStatic
|
||||||
|
import groovy.transform.EqualsAndHashCode
|
||||||
|
import groovy.transform.TypeChecked
|
||||||
|
|
||||||
|
@EqualsAndHashCode
|
||||||
|
@CompileStatic
|
||||||
|
@TypeChecked
|
||||||
|
class MockEvent {
|
||||||
|
final MockRequest request
|
||||||
|
final MockResponse response
|
||||||
|
|
||||||
|
MockEvent(MockRequest request, MockResponse response) {
|
||||||
|
this.request = request
|
||||||
|
this.response = response
|
||||||
|
}
|
||||||
|
}
|
22
src/test/groovy/pl/touk/mockserver/client/MockRequest.groovy
Normal file
22
src/test/groovy/pl/touk/mockserver/client/MockRequest.groovy
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
package pl.touk.mockserver.client
|
||||||
|
|
||||||
|
import groovy.transform.CompileStatic
|
||||||
|
import groovy.transform.EqualsAndHashCode
|
||||||
|
import groovy.transform.TypeChecked
|
||||||
|
|
||||||
|
@CompileStatic
|
||||||
|
@TypeChecked
|
||||||
|
@EqualsAndHashCode
|
||||||
|
class MockRequest {
|
||||||
|
final String text
|
||||||
|
final Map<String, String> headers
|
||||||
|
final Map<String, String> query
|
||||||
|
final List<String> path
|
||||||
|
|
||||||
|
MockRequest(String text, Map<String, String> headers, Map<String, String> query, List<String> path) {
|
||||||
|
this.text = text
|
||||||
|
this.headers = headers
|
||||||
|
this.query = query
|
||||||
|
this.path = path
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,20 @@
|
||||||
|
package pl.touk.mockserver.client
|
||||||
|
|
||||||
|
import groovy.transform.CompileStatic
|
||||||
|
import groovy.transform.EqualsAndHashCode
|
||||||
|
import groovy.transform.TypeChecked
|
||||||
|
|
||||||
|
@CompileStatic
|
||||||
|
@TypeChecked
|
||||||
|
@EqualsAndHashCode
|
||||||
|
class MockResponse {
|
||||||
|
final int statusCode
|
||||||
|
final String text
|
||||||
|
final Map<String, String> headers
|
||||||
|
|
||||||
|
MockResponse(int statusCode, String text, Map<String, String> headers) {
|
||||||
|
this.statusCode = statusCode
|
||||||
|
this.text = text
|
||||||
|
this.headers = headers
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
package pl.touk.mockserver.server
|
package pl.touk.mockserver.tests
|
||||||
|
|
||||||
import groovy.util.slurpersupport.GPathResult
|
import groovy.util.slurpersupport.GPathResult
|
||||||
import org.apache.http.client.methods.*
|
import org.apache.http.client.methods.*
|
||||||
|
@ -8,10 +8,10 @@ import org.apache.http.impl.client.CloseableHttpClient
|
||||||
import org.apache.http.impl.client.HttpClients
|
import org.apache.http.impl.client.HttpClients
|
||||||
import org.apache.http.util.EntityUtils
|
import org.apache.http.util.EntityUtils
|
||||||
import pl.touk.mockserver.client.*
|
import pl.touk.mockserver.client.*
|
||||||
|
import pl.touk.mockserver.server.HttpMockServer
|
||||||
import spock.lang.Shared
|
import spock.lang.Shared
|
||||||
import spock.lang.Specification
|
import spock.lang.Specification
|
||||||
import spock.lang.Unroll
|
import spock.lang.Unroll
|
||||||
import pl.touk.mockserver.client.Util
|
|
||||||
|
|
||||||
class MockServerIntegrationTest extends Specification {
|
class MockServerIntegrationTest extends Specification {
|
||||||
|
|
||||||
|
@ -49,7 +49,7 @@ class MockServerIntegrationTest extends Specification {
|
||||||
GPathResult restPostResponse = Util.extractXmlResponse(response)
|
GPathResult restPostResponse = Util.extractXmlResponse(response)
|
||||||
restPostResponse.name() == 'goodResponseRest-request'
|
restPostResponse.name() == 'goodResponseRest-request'
|
||||||
expect:
|
expect:
|
||||||
controlServerClient.removeMock('testRest') == 1
|
controlServerClient.removeMock('testRest')?.size() == 1
|
||||||
}
|
}
|
||||||
|
|
||||||
def "should add soap mock on endpoint"() {
|
def "should add soap mock on endpoint"() {
|
||||||
|
@ -71,10 +71,10 @@ class MockServerIntegrationTest extends Specification {
|
||||||
soapPostResponse.name() == 'Envelope'
|
soapPostResponse.name() == 'Envelope'
|
||||||
soapPostResponse.Body.'goodResponseSoap-request'.size() == 1
|
soapPostResponse.Body.'goodResponseSoap-request'.size() == 1
|
||||||
expect:
|
expect:
|
||||||
controlServerClient.removeMock('testSoap') == 1
|
controlServerClient.removeMock('testSoap')?.size() == 1
|
||||||
}
|
}
|
||||||
|
|
||||||
def "should not remove mock when it does not exist"() {
|
def "should throw exception when try to remove mock when it does not exist"() {
|
||||||
when:
|
when:
|
||||||
controlServerClient.removeMock('testSoap')
|
controlServerClient.removeMock('testSoap')
|
||||||
then:
|
then:
|
||||||
|
@ -89,7 +89,7 @@ class MockServerIntegrationTest extends Specification {
|
||||||
soap: true
|
soap: true
|
||||||
))
|
))
|
||||||
and:
|
and:
|
||||||
controlServerClient.removeMock('testSoap') == 0
|
controlServerClient.removeMock('testSoap') == []
|
||||||
when:
|
when:
|
||||||
controlServerClient.removeMock('testSoap')
|
controlServerClient.removeMock('testSoap')
|
||||||
then:
|
then:
|
||||||
|
@ -144,7 +144,7 @@ class MockServerIntegrationTest extends Specification {
|
||||||
soap: true
|
soap: true
|
||||||
))
|
))
|
||||||
and:
|
and:
|
||||||
controlServerClient.removeMock('testSoap') == 0
|
controlServerClient.removeMock('testSoap') == []
|
||||||
and:
|
and:
|
||||||
controlServerClient.addMock(new AddMockRequestData(
|
controlServerClient.addMock(new AddMockRequestData(
|
||||||
name: 'testSoap',
|
name: 'testSoap',
|
||||||
|
@ -637,5 +637,78 @@ class MockServerIntegrationTest extends Specification {
|
||||||
restPostResponse.name == 'goodResponse-15'
|
restPostResponse.name == 'goodResponse-15'
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO def "should get mock report"(){}
|
def "should get mock report when deleting mock"() {
|
||||||
|
expect:
|
||||||
|
controlServerClient.addMock(new AddMockRequestData(
|
||||||
|
name: 'testRest',
|
||||||
|
path: 'testEndpoint',
|
||||||
|
port: 9999,
|
||||||
|
predicate: '''{req -> req.xml.name()[0..6] == 'request' }''',
|
||||||
|
response: '''{req -> "<goodResponseRest-${req.xml.name()}/>"}''',
|
||||||
|
statusCode: 201,
|
||||||
|
responseHeaders: '''{req -> ['aaa':'14']}''',
|
||||||
|
soap: false
|
||||||
|
))
|
||||||
|
controlServerClient.addMock(new AddMockRequestData(
|
||||||
|
name: 'testRest2',
|
||||||
|
path: 'testEndpoint',
|
||||||
|
port: 9999,
|
||||||
|
predicate: '''{req -> req.xml.name() == 'reqXYZ' }''',
|
||||||
|
response: '''{req -> "<goodResponseRest/>"}''',
|
||||||
|
statusCode: 202,
|
||||||
|
responseHeaders: '''{req -> ['aaa':'15']}''',
|
||||||
|
soap: false
|
||||||
|
))
|
||||||
|
when:
|
||||||
|
HttpPost post1 = new HttpPost('http://localhost:9999/testEndpoint')
|
||||||
|
post1.entity = new StringEntity('<request/>', ContentType.create("text/xml", "UTF-8"))
|
||||||
|
CloseableHttpResponse response1 = client.execute(post1)
|
||||||
|
then:
|
||||||
|
GPathResult restPostResponse1 = Util.extractXmlResponse(response1)
|
||||||
|
restPostResponse1.name() == 'goodResponseRest-request'
|
||||||
|
when:
|
||||||
|
HttpPost post2 = new HttpPost('http://localhost:9999/testEndpoint/hello')
|
||||||
|
post2.entity = new StringEntity('<request15/>', ContentType.create("text/xml", "UTF-8"))
|
||||||
|
CloseableHttpResponse response2 = client.execute(post2)
|
||||||
|
then:
|
||||||
|
GPathResult restPostResponse2 = Util.extractXmlResponse(response2)
|
||||||
|
restPostResponse2.name() == 'goodResponseRest-request15'
|
||||||
|
when:
|
||||||
|
HttpPost post3 = new HttpPost('http://localhost:9999/testEndpoint?id=123')
|
||||||
|
post3.entity = new StringEntity('<reqXYZ/>', ContentType.create("text/xml", "UTF-8"))
|
||||||
|
CloseableHttpResponse response3 = client.execute(post3)
|
||||||
|
then:
|
||||||
|
GPathResult restPostResponse3 = Util.extractXmlResponse(response3)
|
||||||
|
restPostResponse3.name() == 'goodResponseRest'
|
||||||
|
when:
|
||||||
|
List<MockEvent> mockHistories1 = controlServerClient.removeMock('testRest')
|
||||||
|
then:
|
||||||
|
mockHistories1.size() == 2
|
||||||
|
mockHistories1[0].request.text == '<request/>'
|
||||||
|
!mockHistories1[0].request.headers?.keySet()?.empty
|
||||||
|
mockHistories1[0].request.query == [:]
|
||||||
|
mockHistories1[0].request.path == ['testEndpoint']
|
||||||
|
!mockHistories1[0].response.headers?.keySet()?.empty
|
||||||
|
mockHistories1[0].response.text == '<goodResponseRest-request/>'
|
||||||
|
mockHistories1[0].response.statusCode == 201
|
||||||
|
|
||||||
|
mockHistories1[1].request.text == '<request15/>'
|
||||||
|
!mockHistories1[1].request.headers?.keySet()?.empty
|
||||||
|
mockHistories1[1].request.query == [:]
|
||||||
|
mockHistories1[1].request.path == ['testEndpoint', 'hello']
|
||||||
|
!mockHistories1[1].response.headers?.keySet()?.empty
|
||||||
|
mockHistories1[1].response.text == '<goodResponseRest-request15/>'
|
||||||
|
mockHistories1[1].response.statusCode == 201
|
||||||
|
when:
|
||||||
|
List<MockEvent> mockHistories2 = controlServerClient.removeMock('testRest2')
|
||||||
|
then:
|
||||||
|
mockHistories2.size() == 1
|
||||||
|
mockHistories2[0].request.text == '<reqXYZ/>'
|
||||||
|
!mockHistories2[0].request.headers?.keySet()?.empty
|
||||||
|
mockHistories2[0].request.query == [id: '123']
|
||||||
|
mockHistories2[0].request.path == ['testEndpoint']
|
||||||
|
mockHistories2[0].response.headers.aaa == '15'
|
||||||
|
mockHistories2[0].response.text == '<goodResponseRest/>'
|
||||||
|
mockHistories2[0].response.statusCode == 202
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
package pl.touk.mockserver.server
|
package pl.touk.mockserver.tests
|
||||||
|
|
||||||
import groovy.util.slurpersupport.GPathResult
|
import groovy.util.slurpersupport.GPathResult
|
||||||
import org.apache.http.client.HttpClient
|
import org.apache.http.client.HttpClient
|
||||||
|
@ -10,6 +10,7 @@ import org.apache.http.impl.client.HttpClients
|
||||||
import pl.touk.mockserver.client.AddMockRequestData
|
import pl.touk.mockserver.client.AddMockRequestData
|
||||||
import pl.touk.mockserver.client.ControlServerClient
|
import pl.touk.mockserver.client.ControlServerClient
|
||||||
import pl.touk.mockserver.client.Util
|
import pl.touk.mockserver.client.Util
|
||||||
|
import pl.touk.mockserver.server.HttpMockServer
|
||||||
import spock.lang.Specification
|
import spock.lang.Specification
|
||||||
|
|
||||||
class ServerMockPT extends Specification {
|
class ServerMockPT extends Specification {
|
||||||
|
@ -38,7 +39,7 @@ class ServerMockPT extends Specification {
|
||||||
restPost.entity = new StringEntity("<request$current/>", ContentType.create("text/xml", "UTF-8"))
|
restPost.entity = new StringEntity("<request$current/>", ContentType.create("text/xml", "UTF-8"))
|
||||||
CloseableHttpResponse response = client.execute(restPost)
|
CloseableHttpResponse response = client.execute(restPost)
|
||||||
responses[current] = Util.extractXmlResponse(response)
|
responses[current] = Util.extractXmlResponse(response)
|
||||||
assert controlServerClient.removeMock("testRest$current") == 1
|
assert controlServerClient.removeMock("testRest$current").size() == 1
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
when:
|
when:
|
Loading…
Add table
Add a link
Reference in a new issue