|
19 | 19 | package org.elasticsearch.test.rest.yaml; |
20 | 20 |
|
21 | 21 | import com.carrotsearch.randomizedtesting.RandomizedTest; |
| 22 | + |
22 | 23 | import org.apache.http.HttpEntity; |
23 | 24 | import org.apache.http.HttpHost; |
| 25 | +import org.apache.http.NameValuePair; |
| 26 | +import org.apache.http.ParseException; |
24 | 27 | import org.apache.http.client.methods.HttpGet; |
| 28 | +import org.apache.http.client.utils.URLEncodedUtils; |
25 | 29 | import org.apache.http.entity.ContentType; |
| 30 | +import org.apache.http.message.BasicNameValuePair; |
26 | 31 | import org.apache.http.util.EntityUtils; |
27 | 32 | import org.apache.logging.log4j.LogManager; |
28 | 33 | import org.apache.logging.log4j.Logger; |
|
44 | 49 | import java.io.UncheckedIOException; |
45 | 50 | import java.net.URI; |
46 | 51 | import java.net.URISyntaxException; |
| 52 | +import java.nio.charset.StandardCharsets; |
47 | 53 | import java.util.Arrays; |
48 | 54 | import java.util.HashMap; |
49 | 55 | import java.util.List; |
|
52 | 58 | import java.util.Set; |
53 | 59 | import java.util.stream.Collectors; |
54 | 60 |
|
| 61 | +import static com.carrotsearch.randomizedtesting.RandomizedTest.frequently; |
| 62 | + |
55 | 63 | /** |
56 | 64 | * Used by {@link ESClientYamlSuiteTestCase} to execute REST requests according to the tests written in yaml suite files. Wraps a |
57 | 65 | * {@link RestClient} instance used to send the REST requests. Holds the {@link ClientYamlSuiteRestSpec} used to translate api calls into |
@@ -158,7 +166,7 @@ public ClientYamlTestResponse callApi(String apiName, Map<String, String> params |
158 | 166 | } |
159 | 167 | String contentType = entity.getContentType().getValue(); |
160 | 168 | //randomly test the GET with source param instead of GET/POST with body |
161 | | - if (sendBodyAsSourceParam(supportedMethods, contentType, entity.getContentLength())) { |
| 169 | + if (sendBodyAsSourceParam(supportedMethods, contentType, entity)) { |
162 | 170 | logger.debug("sending the request body as source param with GET method"); |
163 | 171 | queryStringParams.put("source", EntityUtils.toString(entity)); |
164 | 172 | queryStringParams.put("source_content_type", contentType); |
@@ -215,25 +223,41 @@ protected static void setOptions(Request request, Map<String, String> headers) { |
215 | 223 | request.setOptions(options); |
216 | 224 | } |
217 | 225 |
|
218 | | - private static boolean sendBodyAsSourceParam(List<String> supportedMethods, String contentType, long contentLength) { |
| 226 | + private static boolean sendBodyAsSourceParam(List<String> supportedMethods, String contentType, HttpEntity entity) |
| 227 | + throws ParseException, IOException { |
219 | 228 | if (false == supportedMethods.contains(HttpGet.METHOD_NAME)) { |
220 | 229 | // The API doesn't claim to support GET anyway |
221 | 230 | return false; |
222 | 231 | } |
223 | | - if (contentLength < 0) { |
| 232 | + if (entity.getContentLength() < 0) { |
224 | 233 | // Negative length means "unknown" or "huge" in this case. Either way we can't send it as a parameter |
225 | 234 | return false; |
226 | 235 | } |
227 | | - if (contentLength > 2000) { |
228 | | - // Long bodies won't fit in the parameter and will cause a too_long_frame_exception |
| 236 | + if (entity.getContentLength() > 2000) { |
| 237 | + /* |
| 238 | + * HTTP lines longer than 4096 bytes will cause a too_long_frame_exception |
| 239 | + * so we chop at 2000 just to give us some room for extra parameters and |
| 240 | + * url encoding. |
| 241 | + */ |
229 | 242 | return false; |
230 | 243 | } |
231 | 244 | if (false == contentType.startsWith(ContentType.APPLICATION_JSON.getMimeType()) |
232 | 245 | && false == contentType.startsWith(YAML_CONTENT_TYPE.getMimeType())) { |
233 | 246 | // We can only encode JSON or YAML this way. |
234 | 247 | return false; |
235 | 248 | } |
236 | | - return RandomizedTest.rarely(); |
| 249 | + if (frequently()) { |
| 250 | + return false; |
| 251 | + } |
| 252 | + /* |
| 253 | + * Now, the last (expensive) test: make sure the *url encoded* size |
| 254 | + * isn't too big. We limit ourselves to 3000 bytes for the source of |
| 255 | + * the request out of 4096 so we can use the rest for other parameters |
| 256 | + * and the url and stuff. |
| 257 | + */ |
| 258 | + NameValuePair param = new BasicNameValuePair("source", EntityUtils.toString(entity)); |
| 259 | + String encoded = URLEncodedUtils.format(org.elasticsearch.common.collect.List.of(param), StandardCharsets.UTF_8); |
| 260 | + return encoded.length() < 3000; |
237 | 261 | } |
238 | 262 |
|
239 | 263 | private ClientYamlSuiteRestApi restApi(String apiName) { |
|
0 commit comments