]> source.dussan.org Git - sonarqube.git/blob
152956666afdc4bb1e192cba00ef46f2292f52ba
[sonarqube.git] /
1 /*
2  * SonarQube
3  * Copyright (C) 2009-2024 SonarSource SA
4  * mailto:info AT sonarsource DOT com
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 3 of the License, or (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public License
17  * along with this program; if not, write to the Free Software Foundation,
18  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
19  */
20 package org.sonar.server.es.searchrequest;
21
22 import java.util.Arrays;
23 import java.util.Optional;
24 import java.util.Random;
25 import java.util.stream.IntStream;
26 import java.util.stream.Stream;
27 import org.elasticsearch.index.query.BoolQueryBuilder;
28 import org.elasticsearch.search.aggregations.AggregationBuilder;
29 import org.elasticsearch.search.aggregations.AggregationBuilders;
30 import org.elasticsearch.search.aggregations.bucket.filter.FilterAggregationBuilder;
31 import org.elasticsearch.search.aggregations.bucket.terms.TermsAggregationBuilder;
32 import org.elasticsearch.search.aggregations.metrics.MinAggregationBuilder;
33 import org.junit.Test;
34
35 import static org.apache.commons.lang3.RandomStringUtils.randomAlphabetic;
36 import static org.assertj.core.api.Assertions.assertThat;
37 import static org.assertj.core.api.Assertions.assertThatThrownBy;
38 import static org.elasticsearch.index.query.QueryBuilders.boolQuery;
39 import static org.mockito.Mockito.mock;
40 import static org.mockito.Mockito.verifyNoInteractions;
41 import static org.mockito.Mockito.when;
42 import static org.sonar.server.es.searchrequest.TopAggregationHelper.NO_EXTRA_FILTER;
43 import static org.sonar.server.es.searchrequest.TopAggregationHelper.NO_OTHER_SUBAGGREGATION;
44
45 public class TopAggregationHelperTest {
46
47   public static final int DEFAULT_BUCKET_SIZE = 10;
48   private RequestFiltersComputer filtersComputer = mock(RequestFiltersComputer.class);
49   private SubAggregationHelper subAggregationHelper = mock(SubAggregationHelper.class);
50   private TopAggregationHelper underTest = new TopAggregationHelper(filtersComputer, subAggregationHelper);
51
52   @Test
53   public void buildTopAggregation_fails_with_ISE_if_no_subaggregation_added_by_lambda() {
54     String aggregationName = "name";
55     SimpleFieldTopAggregationDefinition topAggregation = new SimpleFieldTopAggregationDefinition("bar", false);
56
57     assertThatThrownBy(() -> underTest.buildTopAggregation(aggregationName, topAggregation, NO_EXTRA_FILTER, NO_OTHER_SUBAGGREGATION))
58       .isInstanceOf(IllegalStateException.class)
59       .hasMessage("no sub-aggregation has been added to top-aggregation " + aggregationName);
60   }
61
62   @Test
63   public void buildTopAggregation_adds_subAggregation_from_lambda_parameter() {
64     SimpleFieldTopAggregationDefinition topAggregation = new SimpleFieldTopAggregationDefinition("bar", false);
65     AggregationBuilder[] subAggs = IntStream.range(0, 1 + new Random().nextInt(12))
66       .mapToObj(i -> AggregationBuilders.min("subAgg_" + i))
67       .toArray(AggregationBuilder[]::new);
68     String topAggregationName = randomAlphabetic(10);
69
70     AggregationBuilder aggregationBuilder = underTest.buildTopAggregation(topAggregationName, topAggregation,
71       NO_EXTRA_FILTER, t -> Arrays.stream(subAggs).forEach(t::subAggregation));
72
73     assertThat(aggregationBuilder.getName()).isEqualTo(topAggregationName);
74     assertThat(aggregationBuilder.getSubAggregations()).hasSize(subAggs.length);
75     assertThat(aggregationBuilder.getSubAggregations()).containsExactlyInAnyOrder(subAggs);
76   }
77
78   @Test
79   public void buildTopAggregation_adds_filter_from_FiltersComputer_for_TopAggregation() {
80     SimpleFieldTopAggregationDefinition topAggregation = new SimpleFieldTopAggregationDefinition("bar", false);
81     SimpleFieldTopAggregationDefinition otherTopAggregation = new SimpleFieldTopAggregationDefinition("acme", false);
82     BoolQueryBuilder computerFilter = boolQuery();
83     BoolQueryBuilder otherFilter = boolQuery();
84     when(filtersComputer.getTopAggregationFilter(topAggregation)).thenReturn(Optional.of(computerFilter));
85     when(filtersComputer.getTopAggregationFilter(otherTopAggregation)).thenReturn(Optional.of(otherFilter));
86     MinAggregationBuilder subAggregation = AggregationBuilders.min("donut");
87     String topAggregationName = randomAlphabetic(10);
88
89     FilterAggregationBuilder aggregationBuilder = underTest.buildTopAggregation(topAggregationName, topAggregation,
90       NO_EXTRA_FILTER, t -> t.subAggregation(subAggregation));
91
92     assertThat(aggregationBuilder.getName()).isEqualTo(topAggregationName);
93     assertThat(aggregationBuilder.getFilter()).isSameAs(computerFilter);
94   }
95
96   @Test
97   public void buildTopAggregation_has_empty_filter_when_FiltersComputer_returns_empty_for_TopAggregation() {
98     SimpleFieldTopAggregationDefinition topAggregation = new SimpleFieldTopAggregationDefinition("bar", false);
99     SimpleFieldTopAggregationDefinition otherTopAggregation = new SimpleFieldTopAggregationDefinition("acme", false);
100     BoolQueryBuilder otherFilter = boolQuery();
101     when(filtersComputer.getTopAggregationFilter(topAggregation)).thenReturn(Optional.empty());
102     when(filtersComputer.getTopAggregationFilter(otherTopAggregation)).thenReturn(Optional.of(otherFilter));
103     MinAggregationBuilder subAggregation = AggregationBuilders.min("donut");
104     String topAggregationName = randomAlphabetic(10);
105
106     FilterAggregationBuilder aggregationBuilder = underTest.buildTopAggregation(topAggregationName, topAggregation,
107       NO_EXTRA_FILTER, t -> t.subAggregation(subAggregation));
108
109     assertThat(aggregationBuilder.getName()).isEqualTo(topAggregationName);
110     assertThat(aggregationBuilder.getFilter()).isEqualTo(boolQuery()).isNotSameAs(otherFilter);
111   }
112
113   @Test
114   public void buildTopAggregation_adds_filter_from_FiltersComputer_for_TopAggregation_and_extra_one() {
115     String topAggregationName = randomAlphabetic(10);
116     SimpleFieldTopAggregationDefinition topAggregation = new SimpleFieldTopAggregationDefinition("bar", false);
117     SimpleFieldTopAggregationDefinition otherTopAggregation = new SimpleFieldTopAggregationDefinition("acme", false);
118     BoolQueryBuilder computerFilter = boolQuery();
119     BoolQueryBuilder otherFilter = boolQuery();
120     BoolQueryBuilder extraFilter = boolQuery();
121     when(filtersComputer.getTopAggregationFilter(topAggregation)).thenReturn(Optional.of(computerFilter));
122     when(filtersComputer.getTopAggregationFilter(otherTopAggregation)).thenReturn(Optional.of(otherFilter));
123     MinAggregationBuilder subAggregation = AggregationBuilders.min("donut");
124
125     FilterAggregationBuilder aggregationBuilder = underTest.buildTopAggregation(topAggregationName, topAggregation,
126       t -> t.must(extraFilter), t -> t.subAggregation(subAggregation));
127
128     assertThat(aggregationBuilder.getName()).isEqualTo(topAggregationName);
129     assertThat(aggregationBuilder.getFilter()).isEqualTo(computerFilter);
130     assertThat(((BoolQueryBuilder) aggregationBuilder.getFilter()).must()).containsExactly(extraFilter);
131   }
132
133   @Test
134   public void buildTopAggregation_does_not_add_subaggregation_from_subAggregationHelper() {
135     SimpleFieldTopAggregationDefinition topAggregation = new SimpleFieldTopAggregationDefinition("bar", false);
136     when(filtersComputer.getTopAggregationFilter(topAggregation)).thenReturn(Optional.empty());
137     MinAggregationBuilder subAggregation = AggregationBuilders.min("donut");
138     String topAggregationName = randomAlphabetic(10);
139
140     underTest.buildTopAggregation(topAggregationName, topAggregation, NO_EXTRA_FILTER, t -> t.subAggregation(subAggregation));
141
142     verifyNoInteractions(subAggregationHelper);
143   }
144
145   @Test
146   public void buildTermTopAggregation_adds_term_subaggregation_from_subAggregationHelper() {
147     String topAggregationName = randomAlphabetic(10);
148     SimpleFieldTopAggregationDefinition topAggregation = new SimpleFieldTopAggregationDefinition("bar", false);
149     TermsAggregationBuilder termSubAgg = AggregationBuilders.terms("foo");
150     when(subAggregationHelper.buildTermsAggregation(topAggregationName, topAggregation, null)).thenReturn(termSubAgg);
151
152     FilterAggregationBuilder aggregationBuilder = underTest.buildTermTopAggregation(
153       topAggregationName, topAggregation, null,
154       NO_EXTRA_FILTER, NO_OTHER_SUBAGGREGATION);
155
156     assertThat(aggregationBuilder.getName()).isEqualTo(topAggregationName);
157     assertThat(aggregationBuilder.getSubAggregations()).hasSize(1);
158     assertThat(aggregationBuilder.getSubAggregations().iterator().next()).isSameAs(termSubAgg);
159   }
160
161   @Test
162   public void buildTermTopAggregation_adds_subAggregation_from_lambda_parameter() {
163     SimpleFieldTopAggregationDefinition topAggregation = new SimpleFieldTopAggregationDefinition("bar", false);
164     AggregationBuilder[] subAggs = IntStream.range(0, 1 + new Random().nextInt(12))
165       .mapToObj(i -> AggregationBuilders.min("subAgg_" + i))
166       .toArray(AggregationBuilder[]::new);
167     String topAggregationName = randomAlphabetic(10);
168     TermsAggregationBuilder termSubAgg = AggregationBuilders.terms("foo");
169     when(subAggregationHelper.buildTermsAggregation(topAggregationName, topAggregation, null)).thenReturn(termSubAgg);
170     AggregationBuilder[] allSubAggs = Stream.concat(Arrays.stream(subAggs), Stream.of(termSubAgg)).toArray(AggregationBuilder[]::new);
171
172     AggregationBuilder aggregationBuilder = underTest.buildTermTopAggregation(
173       topAggregationName, topAggregation, null,
174       NO_EXTRA_FILTER, t -> Arrays.stream(subAggs).forEach(t::subAggregation));
175
176     assertThat(aggregationBuilder.getName()).isEqualTo(topAggregationName);
177     assertThat(aggregationBuilder.getSubAggregations()).hasSize(allSubAggs.length);
178     assertThat(aggregationBuilder.getSubAggregations()).containsExactlyInAnyOrder(allSubAggs);
179   }
180
181   @Test
182   public void buildTermTopAggregation_adds_filter_from_FiltersComputer_for_TopAggregation() {
183     SimpleFieldTopAggregationDefinition topAggregation = new SimpleFieldTopAggregationDefinition("bar", false);
184     SimpleFieldTopAggregationDefinition otherTopAggregation = new SimpleFieldTopAggregationDefinition("acme", false);
185     BoolQueryBuilder computerFilter = boolQuery();
186     BoolQueryBuilder otherFilter = boolQuery();
187     when(filtersComputer.getTopAggregationFilter(topAggregation)).thenReturn(Optional.of(computerFilter));
188     when(filtersComputer.getTopAggregationFilter(otherTopAggregation)).thenReturn(Optional.of(otherFilter));
189     String topAggregationName = randomAlphabetic(10);
190     TermsAggregationBuilder termSubAgg = AggregationBuilders.terms("foo");
191     when(subAggregationHelper.buildTermsAggregation(topAggregationName, topAggregation, null)).thenReturn(termSubAgg);
192
193     FilterAggregationBuilder aggregationBuilder = underTest.buildTermTopAggregation(
194       topAggregationName, topAggregation, null,
195       NO_EXTRA_FILTER, NO_OTHER_SUBAGGREGATION);
196
197     assertThat(aggregationBuilder.getName()).isEqualTo(topAggregationName);
198     assertThat(aggregationBuilder.getFilter()).isSameAs(computerFilter);
199   }
200
201   @Test
202   public void buildTermTopAggregation_has_empty_filter_when_FiltersComputer_returns_empty_for_TopAggregation() {
203     SimpleFieldTopAggregationDefinition topAggregation = new SimpleFieldTopAggregationDefinition("bar", false);
204     SimpleFieldTopAggregationDefinition otherTopAggregation = new SimpleFieldTopAggregationDefinition("acme", false);
205     BoolQueryBuilder otherFilter = boolQuery();
206     when(filtersComputer.getTopAggregationFilter(topAggregation)).thenReturn(Optional.empty());
207     when(filtersComputer.getTopAggregationFilter(otherTopAggregation)).thenReturn(Optional.of(otherFilter));
208     String topAggregationName = randomAlphabetic(10);
209     TermsAggregationBuilder termSubAgg = AggregationBuilders.terms("foo");
210     when(subAggregationHelper.buildTermsAggregation(topAggregationName, topAggregation, null)).thenReturn(termSubAgg);
211
212     FilterAggregationBuilder aggregationBuilder = underTest.buildTermTopAggregation(
213       topAggregationName, topAggregation, null,
214       NO_EXTRA_FILTER, NO_OTHER_SUBAGGREGATION);
215
216     assertThat(aggregationBuilder.getName()).isEqualTo(topAggregationName);
217     assertThat(aggregationBuilder.getFilter()).isEqualTo(boolQuery()).isNotSameAs(otherFilter);
218   }
219
220   @Test
221   public void buildTermTopAggregation_adds_filter_from_FiltersComputer_for_TopAggregation_and_extra_one() {
222     String topAggregationName = randomAlphabetic(10);
223     SimpleFieldTopAggregationDefinition topAggregation = new SimpleFieldTopAggregationDefinition("bar", false);
224     SimpleFieldTopAggregationDefinition otherTopAggregation = new SimpleFieldTopAggregationDefinition("acme", false);
225     BoolQueryBuilder computerFilter = boolQuery();
226     BoolQueryBuilder otherFilter = boolQuery();
227     BoolQueryBuilder extraFilter = boolQuery();
228     when(filtersComputer.getTopAggregationFilter(topAggregation)).thenReturn(Optional.of(computerFilter));
229     when(filtersComputer.getTopAggregationFilter(otherTopAggregation)).thenReturn(Optional.of(otherFilter));
230     TermsAggregationBuilder termSubAgg = AggregationBuilders.terms("foo");
231     when(subAggregationHelper.buildTermsAggregation(topAggregationName, topAggregation, null)).thenReturn(termSubAgg);
232
233     FilterAggregationBuilder aggregationBuilder = underTest.buildTermTopAggregation(
234       topAggregationName, topAggregation, null,
235       t -> t.must(extraFilter), NO_OTHER_SUBAGGREGATION);
236
237     assertThat(aggregationBuilder.getName()).isEqualTo(topAggregationName);
238     assertThat(aggregationBuilder.getFilter()).isEqualTo(computerFilter);
239     assertThat(((BoolQueryBuilder) aggregationBuilder.getFilter()).must()).containsExactly(extraFilter);
240   }
241 }