Add support for headers in REST tests
This adds support for arbitrary headers sent with each REST request, it will allow us to test things like different xcontent-encoding (see 50_with_headers.yaml for what this looks like). Headers are specified at the same level as `catch`, so a request would look like: ```yaml - do: headers: Content-Type: application/yaml get: index: test_1 type: _all id: 1 ```
This commit is contained in:
parent
18a8c20cba
commit
a25b407aeb
|
@ -0,0 +1,30 @@
|
|||
---
|
||||
"REST test with headers":
|
||||
- skip:
|
||||
features: headers
|
||||
|
||||
- do:
|
||||
index:
|
||||
index: test_1
|
||||
type: test
|
||||
id: 1
|
||||
body: { "body": "foo" }
|
||||
|
||||
- do:
|
||||
headers:
|
||||
Content-Type: application/yaml
|
||||
get:
|
||||
index: test_1
|
||||
type: _all
|
||||
id: 1
|
||||
|
||||
- match:
|
||||
$body: |
|
||||
/^---\n
|
||||
_index:\s+\"test_1"\n
|
||||
_type:\s+"test"\n
|
||||
_id:\s+"1"\n
|
||||
_version:\s+1\n
|
||||
found:\s+true\n
|
||||
_source:\n
|
||||
\s+body:\s+"foo"\n$/
|
|
@ -62,7 +62,8 @@ public class RestTestExecutionContext implements Closeable {
|
|||
* Saves the obtained response in the execution context.
|
||||
* @throws RestException if the returned status code is non ok
|
||||
*/
|
||||
public RestResponse callApi(String apiName, Map<String, String> params, List<Map<String, Object>> bodies) throws IOException, RestException {
|
||||
public RestResponse callApi(String apiName, Map<String, String> params, List<Map<String, Object>> bodies,
|
||||
Map<String, String> headers) throws IOException, RestException {
|
||||
//makes a copy of the parameters before modifying them for this specific request
|
||||
HashMap<String, String> requestParams = new HashMap<>(params);
|
||||
for (Map.Entry<String, String> entry : requestParams.entrySet()) {
|
||||
|
@ -74,7 +75,7 @@ public class RestTestExecutionContext implements Closeable {
|
|||
String body = actualBody(bodies);
|
||||
|
||||
try {
|
||||
response = callApiInternal(apiName, requestParams, body);
|
||||
response = callApiInternal(apiName, requestParams, body, headers);
|
||||
//we always stash the last response body
|
||||
stash.stashValue("body", response.getBody());
|
||||
return response;
|
||||
|
@ -104,8 +105,8 @@ public class RestTestExecutionContext implements Closeable {
|
|||
return XContentFactory.jsonBuilder().map(body).string();
|
||||
}
|
||||
|
||||
private RestResponse callApiInternal(String apiName, Map<String, String> params, String body) throws IOException, RestException {
|
||||
return restClient.callApi(apiName, params, body);
|
||||
private RestResponse callApiInternal(String apiName, Map<String, String> params, String body, Map<String, String> headers) throws IOException, RestException {
|
||||
return restClient.callApi(apiName, params, body, headers);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -132,7 +132,7 @@ public class RestClient implements Closeable {
|
|||
* @throws RestException if the obtained status code is non ok, unless the specific error code needs to be ignored
|
||||
* according to the ignore parameter received as input (which won't get sent to elasticsearch)
|
||||
*/
|
||||
public RestResponse callApi(String apiName, Map<String, String> params, String body) throws IOException, RestException {
|
||||
public RestResponse callApi(String apiName, Map<String, String> params, String body, Map<String, String> headers) throws IOException, RestException {
|
||||
|
||||
List<Integer> ignores = new ArrayList<>();
|
||||
Map<String, String> requestParams = null;
|
||||
|
@ -151,6 +151,9 @@ public class RestClient implements Closeable {
|
|||
}
|
||||
|
||||
HttpRequestBuilder httpRequestBuilder = callApiBuilder(apiName, requestParams, body);
|
||||
for (Map.Entry<String, String> header : headers.entrySet()) {
|
||||
httpRequestBuilder.addHeader(header.getKey(), header.getValue());
|
||||
}
|
||||
logger.debug("calling api [{}]", apiName);
|
||||
HttpResponse httpResponse = httpRequestBuilder.execute();
|
||||
|
||||
|
|
|
@ -25,6 +25,8 @@ import org.elasticsearch.test.rest.section.ApiCallSection;
|
|||
import org.elasticsearch.test.rest.section.DoSection;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Parser for do sections
|
||||
|
@ -40,6 +42,8 @@ public class DoSectionParser implements RestTestFragmentParser<DoSection> {
|
|||
XContentParser.Token token;
|
||||
|
||||
DoSection doSection = new DoSection();
|
||||
ApiCallSection apiCallSection = null;
|
||||
Map<String, String> headers = new HashMap<>();
|
||||
|
||||
while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) {
|
||||
if (token == XContentParser.Token.FIELD_NAME) {
|
||||
|
@ -49,8 +53,17 @@ public class DoSectionParser implements RestTestFragmentParser<DoSection> {
|
|||
doSection.setCatch(parser.text());
|
||||
}
|
||||
} else if (token == XContentParser.Token.START_OBJECT) {
|
||||
if (currentFieldName != null) {
|
||||
ApiCallSection apiCallSection = new ApiCallSection(currentFieldName);
|
||||
if ("headers".equals(currentFieldName)) {
|
||||
String headerName = null;
|
||||
while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) {
|
||||
if (token == XContentParser.Token.FIELD_NAME) {
|
||||
headerName = parser.currentName();
|
||||
} else if (token.isValue()) {
|
||||
headers.put(headerName, parser.text());
|
||||
}
|
||||
}
|
||||
} else if (currentFieldName != null) { // must be part of API call then
|
||||
apiCallSection = new ApiCallSection(currentFieldName);
|
||||
String paramName = null;
|
||||
while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) {
|
||||
if (token == XContentParser.Token.FIELD_NAME) {
|
||||
|
@ -73,17 +86,20 @@ public class DoSectionParser implements RestTestFragmentParser<DoSection> {
|
|||
}
|
||||
}
|
||||
}
|
||||
doSection.setApiCallSection(apiCallSection);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
parser.nextToken();
|
||||
|
||||
if (doSection.getApiCallSection() == null) {
|
||||
throw new RestTestParseException("client call section is mandatory within a do section");
|
||||
try {
|
||||
if (apiCallSection == null) {
|
||||
throw new RestTestParseException("client call section is mandatory within a do section");
|
||||
}
|
||||
if (headers.isEmpty() == false) {
|
||||
apiCallSection.addHeaders(headers);
|
||||
}
|
||||
doSection.setApiCallSection(apiCallSection);
|
||||
} finally {
|
||||
parser.nextToken();
|
||||
}
|
||||
|
||||
return doSection;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -33,6 +33,7 @@ public class ApiCallSection {
|
|||
|
||||
private final String api;
|
||||
private final Map<String, String> params = new HashMap<>();
|
||||
private final Map<String, String> headers = new HashMap<>();
|
||||
private final List<Map<String, Object>> bodies = new ArrayList<>();
|
||||
|
||||
public ApiCallSection(String api) {
|
||||
|
@ -56,6 +57,18 @@ public class ApiCallSection {
|
|||
this.params.put(key, value);
|
||||
}
|
||||
|
||||
public void addHeaders(Map<String, String> otherHeaders) {
|
||||
this.headers.putAll(otherHeaders);
|
||||
}
|
||||
|
||||
public void addHeader(String key, String value) {
|
||||
this.headers.put(key, value);
|
||||
}
|
||||
|
||||
public Map<String, String> getHeaders() {
|
||||
return unmodifiableMap(headers);
|
||||
}
|
||||
|
||||
public List<Map<String, Object>> getBodies() {
|
||||
return Collections.unmodifiableList(bodies);
|
||||
}
|
||||
|
|
|
@ -45,6 +45,9 @@ import static org.junit.Assert.fail;
|
|||
*
|
||||
* - do:
|
||||
* catch: missing
|
||||
* headers:
|
||||
* Authorization: Basic user:pass
|
||||
* Content-Type: application/json
|
||||
* update:
|
||||
* index: test_1
|
||||
* type: test
|
||||
|
@ -86,7 +89,8 @@ public class DoSection implements ExecutableSection {
|
|||
}
|
||||
|
||||
try {
|
||||
RestResponse restResponse = executionContext.callApi(apiCallSection.getApi(), apiCallSection.getParams(), apiCallSection.getBodies());
|
||||
RestResponse restResponse = executionContext.callApi(apiCallSection.getApi(), apiCallSection.getParams(),
|
||||
apiCallSection.getBodies(), apiCallSection.getHeaders());
|
||||
if (Strings.hasLength(catchParam)) {
|
||||
String catchStatusCode;
|
||||
if (catches.containsKey(catchParam)) {
|
||||
|
|
|
@ -34,7 +34,7 @@ import java.util.List;
|
|||
*/
|
||||
public final class Features {
|
||||
|
||||
private static final List<String> SUPPORTED = Arrays.asList("stash_in_path", "groovy_scripting");
|
||||
private static final List<String> SUPPORTED = Arrays.asList("stash_in_path", "groovy_scripting", "headers");
|
||||
|
||||
private Features() {
|
||||
|
||||
|
|
|
@ -341,6 +341,29 @@ public class DoSectionParserTests extends AbstractParserTestCase {
|
|||
assertThat(doSection.getApiCallSection().hasBody(), equalTo(false));
|
||||
}
|
||||
|
||||
public void testParseDoSectionWithHeaders() throws Exception {
|
||||
parser = YamlXContent.yamlXContent.createParser(
|
||||
"headers:\n" +
|
||||
" Authorization: \"thing one\"\n" +
|
||||
" Content-Type: \"application/json\"\n" +
|
||||
"indices.get_warmer:\n" +
|
||||
" index: test_index\n" +
|
||||
" name: test_warmer"
|
||||
);
|
||||
|
||||
DoSectionParser doSectionParser = new DoSectionParser();
|
||||
DoSection doSection = doSectionParser.parse(new RestTestSuiteParseContext("api", "suite", parser));
|
||||
|
||||
assertThat(doSection.getApiCallSection(), notNullValue());
|
||||
assertThat(doSection.getApiCallSection().getApi(), equalTo("indices.get_warmer"));
|
||||
assertThat(doSection.getApiCallSection().getParams().size(), equalTo(2));
|
||||
assertThat(doSection.getApiCallSection().hasBody(), equalTo(false));
|
||||
assertThat(doSection.getApiCallSection().getHeaders(), notNullValue());
|
||||
assertThat(doSection.getApiCallSection().getHeaders().size(), equalTo(2));
|
||||
assertThat(doSection.getApiCallSection().getHeaders().get("Authorization"), equalTo("thing one"));
|
||||
assertThat(doSection.getApiCallSection().getHeaders().get("Content-Type"), equalTo("application/json"));
|
||||
}
|
||||
|
||||
public void testParseDoSectionWithoutClientCallSection() throws Exception {
|
||||
parser = YamlXContent.yamlXContent.createParser(
|
||||
"catch: missing\n"
|
||||
|
|
Loading…
Reference in New Issue