Skip to content

Commit be08f95

Browse files
committed
All query tests passing!
1 parent 5ee139f commit be08f95

File tree

5 files changed

+83
-77
lines changed

5 files changed

+83
-77
lines changed

test/protocol-tests-core/src/main/java/software/amazon/awssdk/protocol/asserts/marshalling/CompositeMarshallingAssertion.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@
1818
import com.github.tomakehurst.wiremock.verification.LoggedRequest;
1919
import java.util.ArrayList;
2020
import java.util.List;
21-
import software.amazon.awssdk.http.SdkHttpRequest;
2221

2322
/**
2423
* Composite for MarshallingAssertion objects.

test/protocol-tests-core/src/main/java/software/amazon/awssdk/protocol/asserts/marshalling/MarshallingAssertion.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@
1616
package software.amazon.awssdk.protocol.asserts.marshalling;
1717

1818
import com.github.tomakehurst.wiremock.verification.LoggedRequest;
19-
import software.amazon.awssdk.http.SdkHttpRequest;
2019

2120
/**
2221
* Assertion on the marshalled request.

test/protocol-tests-core/src/main/java/software/amazon/awssdk/protocol/runners/MarshallingTestRunner.java

Lines changed: 72 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -15,24 +15,27 @@
1515

1616
package software.amazon.awssdk.protocol.runners;
1717

18+
19+
import static com.github.tomakehurst.wiremock.client.WireMock.aResponse;
20+
import static com.github.tomakehurst.wiremock.client.WireMock.any;
21+
import static com.github.tomakehurst.wiremock.client.WireMock.stubFor;
22+
import static com.github.tomakehurst.wiremock.client.WireMock.urlMatching;
1823
import static org.junit.Assert.assertEquals;
1924

2025
import com.fasterxml.jackson.databind.JsonNode;
26+
import com.github.tomakehurst.wiremock.client.ResponseDefinitionBuilder;
27+
import com.github.tomakehurst.wiremock.client.WireMock;
2128
import com.github.tomakehurst.wiremock.verification.LoggedRequest;
2229
import java.lang.reflect.InvocationTargetException;
2330
import java.net.URI;
2431
import java.util.List;
2532
import org.junit.Assert;
2633
import software.amazon.awssdk.awscore.AwsRequest;
27-
import software.amazon.awssdk.awscore.AwsRequestOverrideConfiguration;
2834
import software.amazon.awssdk.codegen.model.intermediate.IntermediateModel;
29-
import software.amazon.awssdk.core.SdkPlugin;
30-
import software.amazon.awssdk.core.SdkServiceClientConfiguration;
3135
import software.amazon.awssdk.core.interceptor.Context;
3236
import software.amazon.awssdk.core.interceptor.ExecutionAttributes;
3337
import software.amazon.awssdk.core.interceptor.ExecutionInterceptor;
3438
import software.amazon.awssdk.core.sync.RequestBody;
35-
import software.amazon.awssdk.http.SdkHttpFullRequest;
3639
import software.amazon.awssdk.http.SdkHttpRequest;
3740
import software.amazon.awssdk.protocol.model.TestCase;
3841
import software.amazon.awssdk.protocol.reflect.ClientReflector;
@@ -47,52 +50,50 @@ class MarshallingTestRunner {
4750

4851
private final IntermediateModel model;
4952
private final ClientReflector clientReflector;
50-
private final RequestRecordingInterceptor recordingInterceptor;
53+
private final LocalhostOnlyForWiremockInterceptor localhostOnlyForWiremockInterceptor;
5154

5255
MarshallingTestRunner(IntermediateModel model, ClientReflector clientReflector) {
5356
this.model = model;
5457
this.clientReflector = clientReflector;
55-
this.recordingInterceptor = new RequestRecordingInterceptor();
56-
}
57-
58-
/**
59-
* @return LoggedRequest that wire mock captured.
60-
*/
61-
private static LoggedRequest getLoggedRequest() {
62-
List<LoggedRequest> requests = WireMockUtils.findAllLoggedRequests();
63-
assertEquals(1, requests.size());
64-
return requests.get(0);
58+
this.localhostOnlyForWiremockInterceptor = new LocalhostOnlyForWiremockInterceptor();
6559
}
6660

6761
void runTest(TestCase testCase) throws Exception {
62+
resetWireMock();
6863
ShapeModelReflector shapeModelReflector = createShapeModelReflector(testCase);
6964
AwsRequest request = createRequest(testCase, shapeModelReflector);
7065

71-
try {
72-
if (!model.getShapes().get(testCase.getWhen().getOperationName() + "Request").isHasStreamingMember()) {
73-
clientReflector.invokeMethod(testCase, request);
74-
} else {
75-
clientReflector.invokeMethod(testCase,
76-
request,
77-
RequestBody.fromString(shapeModelReflector.getStreamingMemberValue()));
78-
}
79-
Assert.fail("Expected SDK client to intercept and record request before transmission.");
80-
} catch (InvocationTargetException e) {
81-
if (e.getTargetException() instanceof StopExecutionException) {
82-
SdkHttpRequest recordedRequest = recordingInterceptor.getRequest();
83-
testCase.getThen().getMarshallingAssertion().assertMatches(getLoggedRequest());
84-
} else {
85-
throw e;
86-
}
66+
if (!model.getShapes().get(testCase.getWhen().getOperationName() + "Request").isHasStreamingMember()) {
67+
clientReflector.invokeMethod(testCase, request);
68+
} else {
69+
clientReflector.invokeMethod(testCase,
70+
request,
71+
RequestBody.fromString(shapeModelReflector.getStreamingMemberValue()));
8772
}
73+
testCase.getThen().getMarshallingAssertion()
74+
.assertMatches(localhostOnlyForWiremockInterceptor.getLoggedRequestWithOriginalHost());
75+
}
76+
77+
/**
78+
* Reset wire mock and re-configure stubbing.
79+
*/
80+
private void resetWireMock() {
81+
WireMock.reset();
82+
// Stub to return 200 for all requests
83+
ResponseDefinitionBuilder responseDefBuilder = aResponse().withStatus(200);
84+
// XML Unmarshallers expect at least one level in the XML document.
85+
if (model.getMetadata().isXmlProtocol()) {
86+
responseDefBuilder.withBody("<foo></foo>");
87+
}
88+
stubFor(any(urlMatching(".*")).willReturn(responseDefBuilder));
8889
}
8990

9091
private AwsRequest createRequest(TestCase testCase, ShapeModelReflector shapeModelReflector) {
9192
return ((AwsRequest) shapeModelReflector.createShapeObject())
9293
.toBuilder()
9394
.overrideConfiguration(requestConfiguration -> requestConfiguration
9495
.addPlugin(config -> {
95-
config.overrideConfiguration(c -> c.addExecutionInterceptor(recordingInterceptor));
96+
config.overrideConfiguration(c -> c.addExecutionInterceptor(localhostOnlyForWiremockInterceptor));
9697

9798
if (StringUtils.isNotBlank(testCase.getGiven().getHost())) {
9899
config.endpointOverride(URI.create("https://" + testCase.getGiven().getHost()));
@@ -115,26 +116,49 @@ private String getOperationRequestClassName(String operationName) {
115116
return operationName + "Request";
116117
}
117118

118-
private static final class RequestRecordingInterceptor implements ExecutionInterceptor {
119-
private SdkHttpRequest request;
119+
/**
120+
* Wiremock requires that requests use "localhost" as the host - any prefixes such as "foo.localhost" will
121+
* result in a DNS lookup that will fail. This interceptor modifies the request to ensure this and captures
122+
* the original host.
123+
*/
124+
private static final class LocalhostOnlyForWiremockInterceptor implements ExecutionInterceptor {
125+
private String originalHost;
126+
private String originalProtocol;
127+
private int originalPort;
120128

121129
@Override
122-
public void beforeTransmission(Context.BeforeTransmission context, ExecutionAttributes executionAttributes) {
123-
request = context.httpRequest();
124-
125-
// Log or record the request here
126-
System.out.println("Recording Request:");
127-
System.out.println("HTTP Method: " + request.method());
128-
System.out.println("Endpoint: " + request.getUri());
129-
System.out.println("Headers: " + request.headers());
130-
131-
throw new StopExecutionException();
130+
public SdkHttpRequest modifyHttpRequest(Context.ModifyHttpRequest context, ExecutionAttributes executionAttributes) {
131+
originalHost = context.httpRequest().host();
132+
originalProtocol = context.httpRequest().protocol();
133+
originalPort = context.httpRequest().port();
134+
135+
return context.httpRequest().toBuilder()
136+
.host("localhost")
137+
.port(WireMockUtils.port())
138+
.protocol("http")
139+
.build();
132140
}
133141

134-
public SdkHttpRequest getRequest() {
135-
return request;
142+
/**
143+
* @return LoggedRequest that wire mock captured modified with the original host captured by this
144+
* interceptor.
145+
*/
146+
public LoggedRequest getLoggedRequestWithOriginalHost() {
147+
List<LoggedRequest> requests = WireMockUtils.findAllLoggedRequests();
148+
assertEquals(1, requests.size());
149+
LoggedRequest loggedRequest = requests.get(0);
150+
return new LoggedRequest(
151+
loggedRequest.getUrl(),
152+
originalProtocol + "://" + originalHost + ":" + originalPort,
153+
loggedRequest.getMethod(),
154+
loggedRequest.getClientIp(),
155+
loggedRequest.getHeaders(),
156+
loggedRequest.getCookies(),
157+
loggedRequest.isBrowserProxyRequest(),
158+
loggedRequest.getLoggedDate(),
159+
loggedRequest.getBody(),
160+
loggedRequest.getParts()
161+
);
136162
}
137163
}
138-
139-
private static class StopExecutionException extends RuntimeException {}
140164
}

test/protocol-tests-core/src/main/resources/software/amazon/awssdk/protocol/suites/cases/query-input.json

Lines changed: 9 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,8 @@
2828
"id": "AwsQueryEndpointTrait",
2929
"description": "Operations can prepend to the given host if they define the\nendpoint trait.",
3030
"given": {
31-
"input": {}
31+
"input": {},
32+
"host": "example.com"
3233
},
3334
"when": {
3435
"action": "marshall",
@@ -45,7 +46,8 @@
4546
"body": {
4647
"queryEquals": "Action=EndpointOperation&Version=2020-01-08"
4748
},
48-
"uri": "/"
49+
"uri": "/",
50+
"resolvedHost": "foo.example.com"
4951
}
5052
}
5153
},
@@ -55,7 +57,8 @@
5557
"given": {
5658
"input": {
5759
"label": "bar"
58-
}
60+
},
61+
"host": "example.com"
5962
},
6063
"when": {
6164
"action": "marshall",
@@ -72,27 +75,8 @@
7275
"body": {
7376
"queryEquals": "Action=EndpointWithHostLabelOperation&Version=2020-01-08&label=bar"
7477
},
75-
"uri": "/"
76-
}
77-
}
78-
},
79-
{
80-
"id": "QueryHostWithPath",
81-
"description": "Custom endpoints supplied by users can have paths",
82-
"given": {
83-
"input": {}
84-
},
85-
"when": {
86-
"action": "marshall",
87-
"operation": "HostWithPathOperation"
88-
},
89-
"then": {
90-
"serializedAs": {
91-
"method": "POST",
92-
"body": {
93-
"queryEquals": "Action=HostWithPathOperation&Version=2020-01-08"
94-
},
95-
"uri": "/custom/"
78+
"uri": "/",
79+
"resolvedHost": "foo.bar.example.com"
9680
}
9781
}
9882
},
@@ -108,8 +92,7 @@
10892
"StringArg": "baz"
10993
}
11094
}
111-
},
112-
"host": "example.com"
95+
}
11396
},
11497
"when": {
11598
"action": "marshall",
Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
{
2-
"skipEndpointTestGeneration": true
2+
"skipEndpointTestGeneration": true,
3+
"enableGenerateCompiledEndpointRules": true
34
}

0 commit comments

Comments
 (0)