Skip to content

Commit 42da916

Browse files
committed
Reproduction test failure in AggregationsCircuitBreakingIT.testCBTrippingOnBigComposite
1 parent abc660f commit 42da916

1 file changed

Lines changed: 132 additions & 0 deletions

File tree

Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
/*
2+
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
3+
* or more contributor license agreements. Licensed under the "Elastic License
4+
* 2.0", the "GNU Affero General Public License v3.0 only", and the "Server Side
5+
* Public License v 1"; you may not use this file except in compliance with, at
6+
* your election, the "Elastic License 2.0", the "GNU Affero General Public
7+
* License v3.0 only", or the "Server Side Public License, v 1".
8+
*/
9+
10+
package org.elasticsearch.aggregations.bucket;
11+
12+
import com.carrotsearch.randomizedtesting.annotations.Repeat;
13+
14+
import com.carrotsearch.randomizedtesting.annotations.Seed;
15+
import org.elasticsearch.action.DocWriteRequest;
16+
import org.elasticsearch.action.index.IndexRequestBuilder;
17+
import org.elasticsearch.action.search.SearchPhaseExecutionException;
18+
import org.elasticsearch.aggregations.AggregationIntegTestCase;
19+
import org.elasticsearch.common.breaker.CircuitBreakingException;
20+
import org.elasticsearch.common.settings.Settings;
21+
import org.elasticsearch.search.aggregations.bucket.composite.TermsValuesSourceBuilder;
22+
import org.elasticsearch.test.ESIntegTestCase;
23+
import org.elasticsearch.xcontent.XContentBuilder;
24+
import org.elasticsearch.xcontent.XContentFactory;
25+
import org.hamcrest.core.Every;
26+
27+
import java.io.IOException;
28+
import java.util.ArrayList;
29+
import java.util.List;
30+
import java.util.stream.IntStream;
31+
import java.util.stream.LongStream;
32+
33+
import static org.elasticsearch.indices.breaker.HierarchyCircuitBreakerService.REQUEST_CIRCUIT_BREAKER_LIMIT_SETTING;
34+
import static org.elasticsearch.indices.breaker.HierarchyCircuitBreakerService.REQUEST_CIRCUIT_BREAKER_TYPE_SETTING;
35+
import static org.elasticsearch.indices.breaker.HierarchyCircuitBreakerService.TOTAL_CIRCUIT_BREAKER_LIMIT_SETTING;
36+
import static org.elasticsearch.indices.breaker.HierarchyCircuitBreakerService.USE_REAL_MEMORY_USAGE_SETTING;
37+
import static org.elasticsearch.search.aggregations.AggregationBuilders.composite;
38+
import static org.elasticsearch.search.aggregations.AggregationBuilders.topHits;
39+
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertAcked;
40+
import static org.hamcrest.Matchers.instanceOf;
41+
42+
@ESIntegTestCase.ClusterScope(numDataNodes = 3)
43+
@Seed("E5524FB23B3BF049:709C06F1EF843BB9")
44+
public class AggregationsCircuitBreakingIT extends AggregationIntegTestCase {
45+
@Override
46+
protected Settings nodeSettings(int nodeOrdinal, Settings otherSettings) {
47+
return Settings.builder()
48+
.put(super.nodeSettings(nodeOrdinal, otherSettings))
49+
.put(REQUEST_CIRCUIT_BREAKER_TYPE_SETTING.getKey(), "memory")
50+
.build();
51+
}
52+
53+
private void createIndex() throws IOException {
54+
XContentBuilder mappingBuilder = XContentFactory.jsonBuilder();
55+
mappingBuilder.startObject();
56+
mappingBuilder.startObject("properties");
57+
{
58+
mappingBuilder.startObject("integer");
59+
mappingBuilder.field("type", "integer");
60+
mappingBuilder.endObject();
61+
}
62+
{
63+
mappingBuilder.startObject("long");
64+
mappingBuilder.field("type", "long");
65+
mappingBuilder.endObject();
66+
}
67+
68+
mappingBuilder.endObject(); // properties
69+
mappingBuilder.endObject();
70+
71+
assertAcked(
72+
prepareCreate("index").setSettings(Settings.builder().put("index.number_of_shards", randomIntBetween(1, 10)).build())
73+
.setMapping(mappingBuilder)
74+
);
75+
76+
int minimumCombinations = 10_000_000; // To fill the 65k buckets in the composite agg, times the 100 top_hits count
77+
int docCount = randomIntBetween(100, 10000); // 100 at least to fill the top_hits agg
78+
int integerFieldMvCount = randomIntBetween(100, (int) Math.ceil((double) minimumCombinations / docCount));
79+
int longFieldMvCount = (int) Math.ceil((double) minimumCombinations / docCount / integerFieldMvCount);
80+
81+
List<IndexRequestBuilder> docs = new ArrayList<>();
82+
for (int i = 0; i < docCount; i++) {
83+
XContentBuilder docSource = XContentFactory.jsonBuilder();
84+
docSource.startObject();
85+
final int docNumber = i;
86+
List<Integer> integerValues = IntStream.range(0, integerFieldMvCount).map(x -> docNumber + x * 100).boxed().toList();
87+
List<Long> longValues = LongStream.range(0, longFieldMvCount).map(x -> docNumber + x * 100).boxed().toList();
88+
docSource.field("integer", integerValues);
89+
docSource.field("long", longValues);
90+
docSource.endObject();
91+
92+
docs.add(prepareIndex("index").setOpType(DocWriteRequest.OpType.CREATE).setSource(docSource));
93+
}
94+
indexRandom(true, false, docs);
95+
}
96+
97+
public void testCBTrippingOnBigComposite() throws IOException {
98+
createIndex();
99+
100+
updateClusterSettings(
101+
Settings.builder()
102+
.put(TOTAL_CIRCUIT_BREAKER_LIMIT_SETTING.getKey(), "100MB")
103+
.put(REQUEST_CIRCUIT_BREAKER_LIMIT_SETTING.getKey(), "10MB")
104+
.put(USE_REAL_MEMORY_USAGE_SETTING.getKey(), true)
105+
);
106+
107+
var searchRequestBuilder = prepareSearch("index").setSize(0)
108+
.addAggregation(
109+
composite(
110+
"composite",
111+
List.of(new TermsValuesSourceBuilder("integer").field("integer"), new TermsValuesSourceBuilder("long").field("long"))
112+
).size(65536).subAggregation(
113+
topHits("top_hits").size(100)
114+
)
115+
);
116+
117+
try {
118+
searchRequestBuilder.get();
119+
120+
fail("Expected the breaker to trip");
121+
} catch (SearchPhaseExecutionException e) {
122+
assertThat(List.of(e.guessRootCauses()), Every.everyItem(instanceOf(CircuitBreakingException.class)));
123+
} finally {
124+
updateClusterSettings(
125+
Settings.builder()
126+
.putNull(TOTAL_CIRCUIT_BREAKER_LIMIT_SETTING.getKey())
127+
.putNull(REQUEST_CIRCUIT_BREAKER_LIMIT_SETTING.getKey())
128+
.putNull(USE_REAL_MEMORY_USAGE_SETTING.getKey())
129+
);
130+
}
131+
}
132+
}

0 commit comments

Comments
 (0)