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)); }
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)); }
/** Returns true if any of the nodes used a noop breaker */ private boolean noopBreakerUsed() { NodesStatsResponse stats = client().admin().cluster().prepareNodesStats().setBreaker(true).get(); for (NodeStats nodeStats : stats.getNodes()) { if (nodeStats.getBreaker().getStats(CircuitBreaker.REQUEST).getLimit() == NoopCircuitBreaker.LIMIT) { return true; } if (nodeStats.getBreaker().getStats(CircuitBreaker.IN_FLIGHT_REQUESTS).getLimit() == NoopCircuitBreaker.LIMIT) { return true; } if (nodeStats.getBreaker().getStats(CircuitBreaker.FIELDDATA).getLimit() == NoopCircuitBreaker.LIMIT) { return true; } } return false; }