public void testCustomCircuitBreakerRegistration() throws Exception {
    Iterable<CircuitBreakerService> serviceIter =
        internalCluster().getInstances(CircuitBreakerService.class);

    final String breakerName = "customBreaker";
    BreakerSettings breakerSettings = new BreakerSettings(breakerName, 8, 1.03);
    CircuitBreaker breaker = null;

    for (CircuitBreakerService s : serviceIter) {
      s.registerBreaker(breakerSettings);
      breaker = s.getBreaker(breakerSettings.getName());
    }

    if (breaker != null) {
      try {
        breaker.addEstimateBytesAndMaybeBreak(16, "test");
      } catch (CircuitBreakingException e) {
        // ignore, we forced a circuit break
      }
    }

    NodesStatsResponse stats =
        client().admin().cluster().prepareNodesStats().clear().setBreaker(true).get();
    int breaks = 0;
    for (NodeStats stat : stats.getNodes()) {
      CircuitBreakerStats breakerStats = stat.getBreaker().getStats(breakerName);
      breaks += breakerStats.getTrippedCount();
    }
    assertThat(breaks, greaterThanOrEqualTo(1));
  }
  public void testRamAccountingTermsEnum() throws Exception {
    if (noopBreakerUsed()) {
      logger.info("--> noop breakers used, skipping test");
      return;
    }
    final Client client = client();

    // Create an index where the mappings have a field data filter
    assertAcked(
        prepareCreate("ramtest")
            .setSource(
                "{\"mappings\": {\"type\": {\"properties\": {\"test\": "
                    + "{\"type\": \"text\",\"fielddata\": true,\"fielddata_frequency_filter\": {\"max\": 10000}}}}}}"));

    ensureGreen("ramtest");

    // 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("ramtest", "type", Long.toString(id))
              .setSource("test", "value" + id));
    }
    indexRandom(true, false, true, reqs);

    // execute a search that loads field data (sorting on the "test" field)
    client.prepareSearch("ramtest").setQuery(matchAllQuery()).addSort("test", SortOrder.DESC).get();

    // clear field data cache (thus setting the loaded field data back to 0)
    clearFieldData();

    // Update circuit breaker settings
    Settings settings =
        Settings.builder()
            .put(
                HierarchyCircuitBreakerService.FIELDDATA_CIRCUIT_BREAKER_LIMIT_SETTING.getKey(),
                "100b")
            .put(
                HierarchyCircuitBreakerService.FIELDDATA_CIRCUIT_BREAKER_OVERHEAD_SETTING.getKey(),
                1.05)
            .build();
    assertAcked(client.admin().cluster().prepareUpdateSettings().setTransientSettings(settings));

    // execute a search that loads field data (sorting on the "test" field)
    // again, this time it should trip the breaker
    assertFailures(
        client.prepareSearch("ramtest").setQuery(matchAllQuery()).addSort("test", SortOrder.DESC),
        RestStatus.INTERNAL_SERVER_ERROR,
        containsString("Data too large, data for [test] would be larger than limit of [100/100b]"));

    NodesStatsResponse stats = client.admin().cluster().prepareNodesStats().setBreaker(true).get();
    int breaks = 0;
    for (NodeStats stat : stats.getNodes()) {
      CircuitBreakerStats breakerStats = stat.getBreaker().getStats(CircuitBreaker.FIELDDATA);
      breaks += breakerStats.getTrippedCount();
    }
    assertThat(breaks, greaterThanOrEqualTo(1));
  }