[TEST] prevent yaml tests from using raw requests (#26044)

Raw requests are supported only by the java yaml test runner and were introduced to test docs snippets. Some yaml tests ended up using them (see #23497) which causes failures for other language clients. This commit migrates those yaml tests to Java tests that send requests through the Java low-level REST client, and also moves the ability to send raw requests to a special client that's only available when testing docs snippets.

Closes #25694
This commit is contained in:
Luca Cavanna 2017-08-07 11:02:16 +02:00 committed by GitHub
parent 11ce6b91a4
commit 14ba36977e
22 changed files with 262 additions and 194 deletions

View File

@ -0,0 +1,88 @@
/*
* Licensed to Elasticsearch under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch licenses this file to you 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.elasticsearch.test.rest;
import org.elasticsearch.client.ResponseException;
import java.io.IOException;
import static org.hamcrest.CoreMatchers.containsString;
public class RequestsWithoutContentIT extends ESRestTestCase {
public void testIndexMissingBody() throws IOException {
ResponseException responseException = expectThrows(ResponseException.class, () -> client().performRequest(
randomBoolean() ? "POST" : "PUT", "/idx/type/123"));
assertResponseException(responseException, "request body is required");
}
public void testBulkMissingBody() throws IOException {
ResponseException responseException = expectThrows(ResponseException.class, () -> client().performRequest(
randomBoolean() ? "POST" : "PUT", "/_bulk"));
assertResponseException(responseException, "request body is required");
}
public void testPutSettingsMissingBody() throws IOException {
ResponseException responseException = expectThrows(ResponseException.class, () -> client().performRequest(
"PUT", "/_settings"));
assertResponseException(responseException, "request body is required");
}
public void testPutMappingsMissingBody() throws IOException {
ResponseException responseException = expectThrows(ResponseException.class, () -> client().performRequest(
randomBoolean() ? "POST" : "PUT", "/test_index/test_type/_mapping"));
assertResponseException(responseException, "request body is required");
}
public void testPutIndexTemplateMissingBody() throws IOException {
ResponseException responseException = expectThrows(ResponseException.class, () -> client().performRequest(
randomBoolean() ? "PUT" : "POST", "/_template/my_template"));
assertResponseException(responseException, "request body is required");
}
public void testMultiSearchMissingBody() throws IOException {
ResponseException responseException = expectThrows(ResponseException.class, () -> client().performRequest(
randomBoolean() ? "POST" : "GET", "/_msearch"));
assertResponseException(responseException, "request body or source parameter is required");
}
public void testPutPipelineMissingBody() throws IOException {
ResponseException responseException = expectThrows(ResponseException.class, () -> client().performRequest(
"PUT", "/_ingest/pipeline/my_pipeline"));
assertResponseException(responseException, "request body or source parameter is required");
}
public void testSimulatePipelineMissingBody() throws IOException {
ResponseException responseException = expectThrows(ResponseException.class, () -> client().performRequest(
randomBoolean() ? "POST" : "GET", "/_ingest/pipeline/my_pipeline/_simulate"));
assertResponseException(responseException, "request body or source parameter is required");
}
public void testPutScriptMissingBody() throws IOException {
ResponseException responseException = expectThrows(ResponseException.class, () -> client().performRequest(
randomBoolean() ? "POST" : "PUT", "/_scripts/lang"));
assertResponseException(responseException, "request body is required");
}
private static void assertResponseException(ResponseException responseException, String message) {
assertEquals(400, responseException.getResponse().getStatusLine().getStatusCode());
assertThat(responseException.getMessage(), containsString(message));
}
}

View File

@ -21,10 +21,16 @@ package org.elasticsearch.smoketest;
import com.carrotsearch.randomizedtesting.annotations.Name;
import com.carrotsearch.randomizedtesting.annotations.ParametersFactory;
import org.elasticsearch.Version;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.http.HttpHost;
import org.elasticsearch.test.rest.yaml.ClientYamlDocsTestClient;
import org.elasticsearch.test.rest.yaml.ClientYamlTestCandidate;
import org.elasticsearch.test.rest.yaml.ClientYamlTestClient;
import org.elasticsearch.test.rest.yaml.ESClientYamlSuiteTestCase;
import org.elasticsearch.test.rest.yaml.restspec.ClientYamlSuiteRestSpec;
import java.io.IOException;
import java.util.List;
public class DocsClientYamlTestSuiteIT extends ESClientYamlSuiteTestCase {
@ -52,5 +58,11 @@ public class DocsClientYamlTestSuiteIT extends ESClientYamlSuiteTestCase {
protected boolean randomizeContentType() {
return false;
}
@Override
protected ClientYamlTestClient initClientYamlTestClient(ClientYamlSuiteRestSpec restSpec, RestClient restClient,
List<HttpHost> hosts, Version esVersion) throws IOException {
return new ClientYamlDocsTestClient(restSpec, restClient, hosts, esVersion);
}
}

View File

@ -203,16 +203,3 @@ teardown:
catch: missing
ingest.get_pipeline:
id: "my_pipeline"
---
"missing body":
- skip:
version: " - 5.99.99"
reason: NPE caused by missing body fixed in 6.0.0
- do:
catch: /request body or source parameter is required/
raw:
method: PUT
path: _ingest/pipeline/my_pipeline

View File

@ -605,16 +605,3 @@ teardown:
- length: { docs.0.processor_results.1: 2 }
- match: { docs.0.processor_results.1.tag: "rename-1" }
- match: { docs.0.processor_results.1.doc._source.new_status: 200 }
---
"missing body":
- skip:
version: " - 5.99.99"
reason: NPE caused by missing body fixed in 6.0.0
- do:
catch: /request body or source parameter is required/
raw:
method: POST
path: _ingest/pipeline/my_pipeline/_simulate

View File

@ -0,0 +1,44 @@
/*
* Licensed to Elasticsearch under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch licenses this file to you 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.elasticsearch.script.mustache;
import org.elasticsearch.client.ResponseException;
import org.elasticsearch.test.rest.ESRestTestCase;
import java.io.IOException;
import static org.hamcrest.CoreMatchers.containsString;
public class SearchTemplateWithoutContentIT extends ESRestTestCase {
public void testSearchTemplateMissingBody() throws IOException {
ResponseException responseException = expectThrows(ResponseException.class, () -> client().performRequest(
randomBoolean() ? "POST" : "GET", "/_search/template"));
assertEquals(400, responseException.getResponse().getStatusLine().getStatusCode());
assertThat(responseException.getMessage(), containsString("request body or source parameter is required"));
}
public void testMultiSearchTemplateMissingBody() throws IOException {
ResponseException responseException = expectThrows(ResponseException.class, () -> client().performRequest(
randomBoolean() ? "POST" : "GET", "/_msearch/template"));
assertEquals(400, responseException.getResponse().getStatusLine().getStatusCode());
assertThat(responseException.getMessage(), containsString("request body or source parameter is required"));
}
}

View File

@ -11,16 +11,3 @@
nodes.info: {}
- match: { nodes.$master.modules.0.name: lang-mustache }
---
"missing body":
- skip:
version: " - 5.99.99"
reason: NPE caused by missing body fixed in 6.0.0
- do:
catch: /request body is required/
raw:
method: POST
path: _search/template/1

View File

@ -122,16 +122,3 @@
- match: { hits.total: 1 }
- length: { hits.hits: 1 }
- length: { profile: 1 }
---
"missing body":
- skip:
version: " - 5.99.99"
reason: NPE caused by missing body fixed in 6.0.0
- do:
catch: /request body or source parameter is required/
raw:
method: POST
path: _search/template

View File

@ -156,16 +156,3 @@ setup:
- match: { responses.0.hits.total: 2 }
- match: { responses.1.hits.total: 1 }
- match: { responses.2.hits.total: 1 }
---
"missing body":
- skip:
version: " - 5.99.99"
reason: NPE caused by missing body fixed in 6.0.0
- do:
catch: /request body or source parameter is required/
raw:
method: POST
path: _msearch/template

View File

@ -0,0 +1,37 @@
/*
* Licensed to Elasticsearch under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch licenses this file to you 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.elasticsearch.index.reindex;
import org.elasticsearch.client.ResponseException;
import org.elasticsearch.test.rest.ESRestTestCase;
import java.io.IOException;
import static org.hamcrest.CoreMatchers.containsString;
public class ReindexWithoutContentIT extends ESRestTestCase {
public void testReindexMissingBody() throws IOException {
ResponseException responseException = expectThrows(ResponseException.class, () -> client().performRequest(
"POST", "/_reindex"));
assertEquals(400, responseException.getResponse().getStatusLine().getStatusCode());
assertThat(responseException.getMessage(), containsString("request body is required"));
}
}

View File

@ -299,16 +299,3 @@
index: source
metric: search
- match: {indices.source.total.search.open_contexts: 0}
---
"missing body":
- skip:
version: " - 5.99.99"
reason: NPE caused by missing body fixed in 6.0.0
- do:
catch: /request body is required/
raw:
method: POST
path: _reindex

View File

@ -59,19 +59,6 @@
- match: { count: 2 }
---
"missing body":
- skip:
version: " - 5.4.99"
reason: NPE caused by missing body fixed in 5.5.0
- do:
catch: /request body is required/
raw:
method: POST
path: _bulk
---
"empty action":

View File

@ -1,12 +0,0 @@
---
"missing body":
- skip:
version: " - 5.4.99"
reason: NPE caused by missing body fixed in 5.5.0
- do:
catch: /request body is required/
raw:
method: POST
path: _scripts/lang

View File

@ -74,16 +74,3 @@
include_defaults: true
- match: {defaults.node.attr.testattr: "test"}
---
"missing body":
- skip:
version: " - 5.4.99"
reason: NPE caused by missing body fixed in 5.5.0
- do:
catch: /request body is required/
raw:
method: PUT
path: _settings

View File

@ -32,16 +32,3 @@
type: type
id: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
body: { foo: bar }
---
"missing body":
- skip:
version: " - 5.4.99"
reason: NPE caused by missing body fixed in 5.5.0
- do:
catch: /request body is required/
raw:
method: POST
path: idx/type/123

View File

@ -67,16 +67,3 @@
properties:
"":
type: keyword
---
"missing body":
- skip:
version: " - 5.4.99"
reason: NPE caused by missing body fixed in 5.5.0
- do:
catch: /request body is required/
raw:
method: POST
path: test_index/test_type/_mapping

View File

@ -210,16 +210,3 @@
catch: missing
indices.get_template:
name: "my_template"
---
"missing body":
- skip:
version: " - 5.4.99"
reason: NPE caused by missing body fixed in 5.5.0
- do:
catch: /request body is required/
raw:
method: PUT
path: _template/my_template

View File

@ -61,16 +61,3 @@ setup:
- match: { responses.3.error.root_cause.0.reason: "/no.such.index/" }
- match: { responses.3.error.root_cause.0.index: index_3 }
- match: { responses.4.hits.total: 4 }
---
"missing body":
- skip:
version: " - 5.4.99"
reason: NPE caused by missing body fixed in 5.5.0
- do:
catch: /request body or source parameter is required/
raw:
method: POST
path: _msearch

View File

@ -0,0 +1,66 @@
/*
* Licensed to Elasticsearch under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch licenses this file to you 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.elasticsearch.test.rest.yaml;
import org.elasticsearch.Version;
import org.elasticsearch.client.Response;
import org.elasticsearch.client.ResponseException;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.http.HttpEntity;
import org.elasticsearch.client.http.HttpHost;
import org.elasticsearch.test.rest.yaml.restspec.ClientYamlSuiteRestSpec;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
/**
* Used to execute REST requests according to the docs snippets that need to be tests. Wraps a
* {@link RestClient} instance used to send the REST requests. Holds the {@link ClientYamlSuiteRestSpec} used to translate api calls into
* REST calls. Supports raw requests besides the usual api calls based on the rest spec.
*/
public final class ClientYamlDocsTestClient extends ClientYamlTestClient {
public ClientYamlDocsTestClient(ClientYamlSuiteRestSpec restSpec, RestClient restClient, List<HttpHost> hosts, Version esVersion)
throws IOException {
super(restSpec, restClient, hosts, esVersion);
}
public ClientYamlTestResponse callApi(String apiName, Map<String, String> params, HttpEntity entity, Map<String, String> headers)
throws IOException {
if ("raw".equals(apiName)) {
// Raw requests are bit simpler....
Map<String, String> queryStringParams = new HashMap<>(params);
String method = Objects.requireNonNull(queryStringParams.remove("method"), "Method must be set to use raw request");
String path = "/" + Objects.requireNonNull(queryStringParams.remove("path"), "Path must be set to use raw request");
// And everything else is a url parameter!
try {
Response response = restClient.performRequest(method, path, queryStringParams, entity);
return new ClientYamlTestResponse(response);
} catch (ResponseException e) {
throw new ClientYamlTestResponseException(e);
}
}
return super.callApi(apiName, params, entity, headers);
}
}

View File

@ -19,6 +19,11 @@
package org.elasticsearch.test.rest.yaml;
import com.carrotsearch.randomizedtesting.RandomizedTest;
import org.apache.logging.log4j.Logger;
import org.elasticsearch.Version;
import org.elasticsearch.client.Response;
import org.elasticsearch.client.ResponseException;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.http.Header;
import org.elasticsearch.client.http.HttpEntity;
import org.elasticsearch.client.http.HttpHost;
@ -26,11 +31,6 @@ import org.elasticsearch.client.http.client.methods.HttpGet;
import org.elasticsearch.client.http.entity.ContentType;
import org.elasticsearch.client.http.message.BasicHeader;
import org.elasticsearch.client.http.util.EntityUtils;
import org.apache.logging.log4j.Logger;
import org.elasticsearch.Version;
import org.elasticsearch.client.Response;
import org.elasticsearch.client.ResponseException;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.common.logging.Loggers;
import org.elasticsearch.test.rest.yaml.restspec.ClientYamlSuiteRestApi;
import org.elasticsearch.test.rest.yaml.restspec.ClientYamlSuiteRestPath;
@ -42,7 +42,6 @@ import java.net.URISyntaxException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
/**
* Used by {@link ESClientYamlSuiteTestCase} to execute REST requests according to the tests written in yaml suite files. Wraps a
@ -55,7 +54,7 @@ public class ClientYamlTestClient {
private static final ContentType YAML_CONTENT_TYPE = ContentType.create("application/yaml");
private final ClientYamlSuiteRestSpec restSpec;
private final RestClient restClient;
protected final RestClient restClient;
private final Version esVersion;
public ClientYamlTestClient(ClientYamlSuiteRestSpec restSpec, RestClient restClient, List<HttpHost> hosts,
@ -76,20 +75,6 @@ public class ClientYamlTestClient {
public ClientYamlTestResponse callApi(String apiName, Map<String, String> params, HttpEntity entity, Map<String, String> headers)
throws IOException {
if ("raw".equals(apiName)) {
// Raw requests are bit simpler....
Map<String, String> queryStringParams = new HashMap<>(params);
String method = Objects.requireNonNull(queryStringParams.remove("method"), "Method must be set to use raw request");
String path = "/"+ Objects.requireNonNull(queryStringParams.remove("path"), "Path must be set to use raw request");
// And everything else is a url parameter!
try {
Response response = restClient.performRequest(method, path, queryStringParams, entity);
return new ClientYamlTestResponse(response);
} catch(ResponseException e) {
throw new ClientYamlTestResponseException(e);
}
}
ClientYamlSuiteRestApi restApi = restApi(apiName);
//divide params between ones that go within query string and ones that go within path

View File

@ -47,7 +47,7 @@ public class ClientYamlTestResponse {
private ObjectPath parsedResponse;
private String bodyAsString;
ClientYamlTestResponse(Response response) throws IOException {
public ClientYamlTestResponse(Response response) throws IOException {
this.response = response;
if (response.getEntity() != null) {
String contentType = response.getHeader("Content-Type");

View File

@ -32,7 +32,7 @@ public class ClientYamlTestResponseException extends IOException {
private final ClientYamlTestResponse restTestResponse;
private final ResponseException responseException;
ClientYamlTestResponseException(ResponseException responseException) throws IOException {
public ClientYamlTestResponseException(ResponseException responseException) throws IOException {
super(responseException);
this.responseException = responseException;
this.restTestResponse = new ClientYamlTestResponse(responseException.getResponse());

View File

@ -119,8 +119,7 @@ public abstract class ESClientYamlSuiteTestCase extends ESRestTestCase {
throw ex;
}
}
ClientYamlTestClient clientYamlTestClient =
new ClientYamlTestClient(restSpec, restClient, hosts, esVersion);
ClientYamlTestClient clientYamlTestClient = initClientYamlTestClient(restSpec, restClient, hosts, esVersion);
restTestExecutionContext = new ClientYamlTestExecutionContext(clientYamlTestClient, randomizeContentType());
adminExecutionContext = new ClientYamlTestExecutionContext(clientYamlTestClient, false);
String[] blacklist = resolvePathsProperty(REST_TESTS_BLACKLIST, null);
@ -139,6 +138,11 @@ public abstract class ESClientYamlSuiteTestCase extends ESRestTestCase {
restTestExecutionContext.clear();
}
protected ClientYamlTestClient initClientYamlTestClient(ClientYamlSuiteRestSpec restSpec, RestClient restClient,
List<HttpHost> hosts, Version esVersion) throws IOException {
return new ClientYamlTestClient(restSpec, restClient, hosts, esVersion);
}
@Override
protected void afterIfFailed(List<Throwable> errors) {
// Dump the stash on failure. Instead of dumping it in true json we escape `\n`s so stack traces are easier to read