|
14 | 14 | import org.elasticsearch.common.breaker.CircuitBreaker; |
15 | 15 | import org.elasticsearch.common.breaker.CircuitBreakingException; |
16 | 16 | import org.elasticsearch.common.settings.Settings; |
| 17 | +import org.elasticsearch.common.util.concurrent.EsRejectedExecutionException; |
17 | 18 | import org.elasticsearch.common.util.set.Sets; |
18 | 19 | import org.elasticsearch.compute.operator.exchange.ExchangeService; |
19 | 20 | import org.elasticsearch.test.FailingFieldPlugin; |
@@ -268,12 +269,62 @@ public void testFailToStartRequestOnRemoteCluster() throws Exception { |
268 | 269 | } |
269 | 270 | } |
270 | 271 |
|
| 272 | + public void testFailSearchShardsOnLocalCluster() throws Exception { |
| 273 | + populateIndices(); |
| 274 | + Exception simulatedFailure = randomFailure(); |
| 275 | + for (TransportService transportService : cluster(LOCAL_CLUSTER).getInstances(TransportService.class)) { |
| 276 | + MockTransportService ts = asInstanceOf(MockTransportService.class, transportService); |
| 277 | + ts.addRequestHandlingBehavior( |
| 278 | + EsqlSearchShardsAction.NAME, |
| 279 | + (handler, request, channel, task) -> { channel.sendResponse(simulatedFailure); } |
| 280 | + ); |
| 281 | + } |
| 282 | + try { |
| 283 | + EsqlQueryRequest request = new EsqlQueryRequest(); |
| 284 | + request.query("FROM ok*,*a:ok* | KEEP id"); |
| 285 | + request.includeCCSMetadata(randomBoolean()); |
| 286 | + { |
| 287 | + request.allowPartialResults(false); |
| 288 | + var error = expectThrows(Exception.class, () -> runQuery(request).close()); |
| 289 | + EsqlTestUtils.assertEsqlFailure(error); |
| 290 | + var unwrapped = ExceptionsHelper.unwrap(error, simulatedFailure.getClass()); |
| 291 | + assertNotNull(unwrapped); |
| 292 | + assertThat(unwrapped.getMessage(), equalTo(simulatedFailure.getMessage())); |
| 293 | + } |
| 294 | + request.allowPartialResults(true); |
| 295 | + try (var resp = runQuery(request)) { |
| 296 | + assertTrue(resp.isPartial()); |
| 297 | + List<List<Object>> rows = getValuesList(resp); |
| 298 | + Set<String> returnedIds = new HashSet<>(); |
| 299 | + for (List<Object> row : rows) { |
| 300 | + assertThat(row.size(), equalTo(1)); |
| 301 | + String id = (String) row.get(0); |
| 302 | + assertTrue(returnedIds.add(id)); |
| 303 | + } |
| 304 | + assertThat(returnedIds, equalTo(remote1.okIds)); |
| 305 | + if (request.includeCCSMetadata()) { |
| 306 | + EsqlExecutionInfo.Cluster localInfo = resp.getExecutionInfo().getCluster(LOCAL_CLUSTER); |
| 307 | + assertThat(localInfo.getStatus(), equalTo(EsqlExecutionInfo.Cluster.Status.PARTIAL)); |
| 308 | + |
| 309 | + EsqlExecutionInfo.Cluster remoteInfo = resp.getExecutionInfo().getCluster(REMOTE_CLUSTER_1); |
| 310 | + assertThat(remoteInfo.getStatus(), equalTo(EsqlExecutionInfo.Cluster.Status.SUCCESSFUL)); |
| 311 | + } |
| 312 | + } |
| 313 | + } finally { |
| 314 | + for (TransportService transportService : cluster(LOCAL_CLUSTER).getInstances(TransportService.class)) { |
| 315 | + MockTransportService ts = asInstanceOf(MockTransportService.class, transportService); |
| 316 | + ts.clearAllRules(); |
| 317 | + } |
| 318 | + } |
| 319 | + } |
| 320 | + |
271 | 321 | private static Exception randomFailure() { |
272 | 322 | return randomFrom( |
273 | 323 | new IllegalStateException("driver was closed already"), |
274 | 324 | new CircuitBreakingException("low memory", CircuitBreaker.Durability.PERMANENT), |
275 | 325 | new IOException("broken disk"), |
276 | | - new ResourceNotFoundException("exchange sink was not found") |
| 326 | + new ResourceNotFoundException("exchange sink was not found"), |
| 327 | + new EsRejectedExecutionException("node is shutting down") |
277 | 328 | ); |
278 | 329 | } |
279 | 330 |
|
|
0 commit comments