/** Reset all breaker settings back to their defaults */
 private void reset() {
   logger.info("--> resetting breaker settings");
   Settings resetSettings =
       Settings.builder()
           .put(
               HierarchyCircuitBreakerService.FIELDDATA_CIRCUIT_BREAKER_LIMIT_SETTING.getKey(),
               HierarchyCircuitBreakerService.FIELDDATA_CIRCUIT_BREAKER_LIMIT_SETTING
                   .getDefaultRaw(null))
           .put(
               HierarchyCircuitBreakerService.FIELDDATA_CIRCUIT_BREAKER_OVERHEAD_SETTING.getKey(),
               HierarchyCircuitBreakerService.FIELDDATA_CIRCUIT_BREAKER_OVERHEAD_SETTING
                   .getDefaultRaw(null))
           .put(
               HierarchyCircuitBreakerService.REQUEST_CIRCUIT_BREAKER_LIMIT_SETTING.getKey(),
               HierarchyCircuitBreakerService.REQUEST_CIRCUIT_BREAKER_LIMIT_SETTING.getDefaultRaw(
                   null))
           .put(
               HierarchyCircuitBreakerService.REQUEST_CIRCUIT_BREAKER_OVERHEAD_SETTING.getKey(),
               1.0)
           .put(
               HierarchyCircuitBreakerService.IN_FLIGHT_REQUESTS_CIRCUIT_BREAKER_LIMIT_SETTING
                   .getKey(),
               HierarchyCircuitBreakerService.IN_FLIGHT_REQUESTS_CIRCUIT_BREAKER_LIMIT_SETTING
                   .getDefaultRaw(null))
           .put(
               HierarchyCircuitBreakerService.IN_FLIGHT_REQUESTS_CIRCUIT_BREAKER_OVERHEAD_SETTING
                   .getKey(),
               1.0)
           .put(
               HierarchyCircuitBreakerService.TOTAL_CIRCUIT_BREAKER_LIMIT_SETTING.getKey(),
               HierarchyCircuitBreakerService.TOTAL_CIRCUIT_BREAKER_LIMIT_SETTING.getDefaultRaw(
                   null))
           .build();
   assertAcked(
       client().admin().cluster().prepareUpdateSettings().setTransientSettings(resetSettings));
 }
  /**
   * Test that a breaker correctly redistributes to a different breaker, in this case, the fielddata
   * breaker borrows space from the request breaker
   */
  @AwaitsFix(bugUrl = "https://github.com/elastic/elasticsearch/issues/18325")
  public void testParentChecking() throws Exception {
    if (noopBreakerUsed()) {
      logger.info("--> noop breakers used, skipping test");
      return;
    }
    assertAcked(
        prepareCreate(
                "cb-test", 1, Settings.builder().put(SETTING_NUMBER_OF_REPLICAS, between(0, 1)))
            .addMapping("type", "test", "type=text,fielddata=true"));
    Client client = client();

    // index some different terms so we have some field data for loading
    int docCount = scaledRandomIntBetween(300, 1000);
    List<IndexRequestBuilder> reqs = new ArrayList<>();
    for (long id = 0; id < docCount; id++) {
      reqs.add(
          client
              .prepareIndex("cb-test", "type", Long.toString(id))
              .setSource("test", "value" + id));
    }
    indexRandom(true, reqs);

    Settings resetSettings =
        Settings.builder()
            .put(
                HierarchyCircuitBreakerService.FIELDDATA_CIRCUIT_BREAKER_LIMIT_SETTING.getKey(),
                "10b")
            .put(
                HierarchyCircuitBreakerService.FIELDDATA_CIRCUIT_BREAKER_OVERHEAD_SETTING.getKey(),
                1.0)
            .build();
    assertAcked(
        client.admin().cluster().prepareUpdateSettings().setTransientSettings(resetSettings));

    // Perform a search to load field data for the "test" field
    try {
      client
          .prepareSearch("cb-test")
          .setQuery(matchAllQuery())
          .addSort("test", SortOrder.DESC)
          .get();
      fail("should have thrown an exception");
    } catch (Exception e) {
      String errMsg =
          "[fielddata] Data too large, data for [test] would be larger than limit of [10/10b]";
      assertThat(
          "Exception: [" + e.toString() + "] should contain a CircuitBreakingException",
          e.toString(),
          containsString(errMsg));
    }

    assertFailures(
        client.prepareSearch("cb-test").setQuery(matchAllQuery()).addSort("test", SortOrder.DESC),
        RestStatus.INTERNAL_SERVER_ERROR,
        containsString("Data too large, data for [test] would be larger than limit of [10/10b]"));

    reset();

    // Adjust settings so the parent breaker will fail, but neither the fielddata breaker nor the
    // node request breaker will fail
    resetSettings =
        Settings.builder()
            .put(
                HierarchyCircuitBreakerService.TOTAL_CIRCUIT_BREAKER_LIMIT_SETTING.getKey(), "500b")
            .put(
                HierarchyCircuitBreakerService.FIELDDATA_CIRCUIT_BREAKER_LIMIT_SETTING.getKey(),
                "90%")
            .put(
                HierarchyCircuitBreakerService.FIELDDATA_CIRCUIT_BREAKER_OVERHEAD_SETTING.getKey(),
                1.0)
            .build();
    client
        .admin()
        .cluster()
        .prepareUpdateSettings()
        .setTransientSettings(resetSettings)
        .execute()
        .actionGet();

    // Perform a search to load field data for the "test" field
    try {
      client
          .prepareSearch("cb-test")
          .setQuery(matchAllQuery())
          .addSort("test", SortOrder.DESC)
          .get();
      fail("should have thrown an exception");
    } catch (Exception e) {
      final Throwable cause = ExceptionsHelper.unwrap(e, CircuitBreakingException.class);
      assertNotNull("CircuitBreakingException is not the cause of " + e, cause);
      String errMsg = "would be larger than limit of [500/500b]]";
      assertThat(
          "Exception: [" + cause.toString() + "] should contain a CircuitBreakingException",
          cause.toString(),
          startsWith("CircuitBreakingException[[parent] Data too large"));
      assertThat(
          "Exception: [" + cause.toString() + "] should contain a CircuitBreakingException",
          cause.toString(),
          endsWith(errMsg));
    } finally {
      // reset before teardown as it requires properly set up breakers
      reset();
    }
  }