3 * Copyright (C) 2009-2023 SonarSource SA
4 * mailto:info AT sonarsource DOT com
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.
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.
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.
20 package org.sonar.server.issue.notification;
22 import com.google.common.collect.ImmutableSet;
23 import com.google.common.collect.Lists;
24 import java.util.Arrays;
25 import java.util.Collections;
26 import java.util.List;
27 import java.util.Optional;
28 import java.util.Random;
29 import java.util.stream.Collectors;
30 import java.util.stream.IntStream;
31 import java.util.stream.Stream;
32 import javax.annotation.CheckForNull;
33 import org.junit.Test;
34 import org.sonar.api.issue.Issue;
35 import org.sonar.api.rule.RuleKey;
36 import org.sonar.api.rules.RuleType;
37 import org.sonar.api.utils.Duration;
38 import org.sonar.core.issue.DefaultIssue;
39 import org.sonar.server.issue.notification.NewIssuesStatistics.Metric;
41 import static org.apache.commons.lang.RandomStringUtils.randomAlphabetic;
42 import static org.apache.commons.lang.RandomStringUtils.randomAlphanumeric;
43 import static org.assertj.core.api.Assertions.assertThat;
44 import static org.assertj.core.api.Assertions.assertThatThrownBy;
46 public class NewIssuesStatisticsTest {
48 private final Random random = new Random();
49 private RuleType randomRuleTypeExceptHotspot = RuleType.values()[random.nextInt(RuleType.values().length - 1)];
50 private NewIssuesStatistics underTest = new NewIssuesStatistics(Issue::isNew);
53 public void add_fails_with_NPE_if_RuleType_is_null() {
54 String assignee = randomAlphanumeric(10);
55 DefaultIssue issue = new DefaultIssue().setType(null).setAssigneeUuid(assignee).setNew(new Random().nextBoolean());
57 assertThatThrownBy(() -> underTest.add(issue))
58 .isInstanceOf(NullPointerException.class);
62 public void add_issues_with_correct_global_statistics() {
63 DefaultIssue issue = new DefaultIssue()
64 .setAssigneeUuid("maynard")
65 .setComponentUuid("file-uuid")
67 .setType(RuleType.BUG)
68 .setRuleKey(RuleKey.of("SonarQube", "rule-the-world"))
69 .setTags(Lists.newArrayList("bug", "owasp"))
70 .setEffort(Duration.create(5L));
73 underTest.add(issue.setAssigneeUuid("james"));
74 underTest.add(issue.setAssigneeUuid("keenan"));
76 assertThat(countDistributionTotal(Metric.ASSIGNEE, "maynard")).isOne();
77 assertThat(countDistributionTotal(Metric.ASSIGNEE, "james")).isOne();
78 assertThat(countDistributionTotal(Metric.ASSIGNEE, "keenan")).isOne();
79 assertThat(countDistributionTotal(Metric.ASSIGNEE, "wrong.login")).isNull();
80 assertThat(countDistributionTotal(Metric.COMPONENT, "file-uuid")).isEqualTo(3);
81 assertThat(countDistributionTotal(Metric.COMPONENT, "wrong-uuid")).isNull();
82 assertThat(countDistributionTotal(Metric.RULE_TYPE, RuleType.BUG.name())).isEqualTo(3);
83 assertThat(countDistributionTotal(Metric.RULE_TYPE, RuleType.CODE_SMELL.name())).isNull();
84 assertThat(countDistributionTotal(Metric.TAG, "owasp")).isEqualTo(3);
85 assertThat(countDistributionTotal(Metric.TAG, "wrong-tag")).isNull();
86 assertThat(countDistributionTotal(Metric.RULE, "SonarQube:rule-the-world")).isEqualTo(3);
87 assertThat(countDistributionTotal(Metric.RULE, "SonarQube:has-a-fake-rule")).isNull();
88 assertThat(underTest.globalStatistics().effort().getTotal()).isEqualTo(15L);
89 assertThat(underTest.globalStatistics().hasIssues()).isTrue();
90 assertThat(underTest.hasIssues()).isTrue();
91 assertThat(underTest.getAssigneesStatistics().get("maynard").hasIssues()).isTrue();
95 public void add_counts_issue_per_RuleType_on_current_analysis_globally_and_per_assignee() {
96 String assignee = randomAlphanumeric(10);
97 Arrays.stream(RuleType.values())
98 .map(ruleType -> new DefaultIssue().setType(ruleType).setAssigneeUuid(assignee).setNew(true))
99 .forEach(underTest::add);
101 DistributedMetricStatsInt globalDistribution = underTest.globalStatistics().getDistributedMetricStats(Metric.RULE_TYPE);
102 DistributedMetricStatsInt assigneeDistribution = underTest.getAssigneesStatistics().get(assignee).getDistributedMetricStats(Metric.RULE_TYPE);
103 Stream.of(globalDistribution, assigneeDistribution)
104 .forEach(distribution -> Arrays.stream(RuleType.values()).forEach(ruleType -> assertStats(distribution, ruleType.name(), 1, 1)));
108 public void add_counts_issue_per_RuleType_off_current_analysis_globally_and_per_assignee() {
109 String assignee = randomAlphanumeric(10);
110 Arrays.stream(RuleType.values())
111 .map(ruleType -> new DefaultIssue().setType(ruleType).setAssigneeUuid(assignee).setNew(false))
112 .forEach(underTest::add);
114 DistributedMetricStatsInt globalDistribution = underTest.globalStatistics().getDistributedMetricStats(Metric.RULE_TYPE);
115 DistributedMetricStatsInt assigneeDistribution = underTest.getAssigneesStatistics().get(assignee).getDistributedMetricStats(Metric.RULE_TYPE);
116 Stream.of(globalDistribution, assigneeDistribution)
117 .forEach(distribution -> Arrays.stream(RuleType.values()).forEach(ruleType -> assertStats(distribution, ruleType.name(), 0, 1)));
121 public void add_counts_issue_per_component_on_current_analysis_globally_and_per_assignee() {
122 List<String> componentUuids = IntStream.range(0, 1 + new Random().nextInt(10)).mapToObj(i -> randomAlphabetic(3)).collect(Collectors.toList());
123 String assignee = randomAlphanumeric(10);
124 componentUuids.stream()
125 .map(componentUuid -> new DefaultIssue().setType(randomRuleTypeExceptHotspot).setComponentUuid(componentUuid).setAssigneeUuid(assignee).setNew(true))
126 .forEach(underTest::add);
128 DistributedMetricStatsInt globalDistribution = underTest.globalStatistics().getDistributedMetricStats(Metric.COMPONENT);
129 DistributedMetricStatsInt assigneeDistribution = underTest.getAssigneesStatistics().get(assignee).getDistributedMetricStats(Metric.COMPONENT);
130 Stream.of(globalDistribution, assigneeDistribution)
131 .forEach(distribution -> componentUuids.forEach(componentUuid -> assertStats(distribution, componentUuid, 1, 1)));
135 public void add_counts_issue_per_component_off_current_analysis_globally_and_per_assignee() {
136 List<String> componentUuids = IntStream.range(0, 1 + new Random().nextInt(10)).mapToObj(i -> randomAlphabetic(3)).collect(Collectors.toList());
137 String assignee = randomAlphanumeric(10);
138 componentUuids.stream()
139 .map(componentUuid -> new DefaultIssue().setType(randomRuleTypeExceptHotspot).setComponentUuid(componentUuid).setAssigneeUuid(assignee).setNew(false))
140 .forEach(underTest::add);
142 DistributedMetricStatsInt globalDistribution = underTest.globalStatistics().getDistributedMetricStats(Metric.COMPONENT);
143 NewIssuesStatistics.Stats stats = underTest.getAssigneesStatistics().get(assignee);
144 DistributedMetricStatsInt assigneeDistribution = stats.getDistributedMetricStats(Metric.COMPONENT);
145 Stream.of(globalDistribution, assigneeDistribution)
146 .forEach(distribution -> componentUuids.forEach(componentUuid -> assertStats(distribution, componentUuid, 0, 1)));
150 public void add_does_not_count_component_if_null_neither_globally_nor_per_assignee() {
151 String assignee = randomAlphanumeric(10);
152 underTest.add(new DefaultIssue().setType(randomRuleTypeExceptHotspot).setComponentUuid(null).setAssigneeUuid(assignee).setNew(new Random().nextBoolean()));
154 DistributedMetricStatsInt globalDistribution = underTest.globalStatistics().getDistributedMetricStats(Metric.COMPONENT);
155 DistributedMetricStatsInt assigneeDistribution = underTest.getAssigneesStatistics().get(assignee).getDistributedMetricStats(Metric.COMPONENT);
156 Stream.of(globalDistribution, assigneeDistribution)
157 .forEach(distribution -> {
158 assertThat(distribution.getTotal()).isZero();
159 assertThat(distribution.getForLabel(null)).isEmpty();
164 public void add_counts_issue_per_ruleKey_on_current_analysis_globally_and_per_assignee() {
165 String repository = randomAlphanumeric(3);
166 List<String> ruleKeys = IntStream.range(0, 1 + new Random().nextInt(10)).mapToObj(i -> randomAlphabetic(3)).collect(Collectors.toList());
167 String assignee = randomAlphanumeric(10);
169 .map(ruleKey -> new DefaultIssue().setType(randomRuleTypeExceptHotspot).setRuleKey(RuleKey.of(repository, ruleKey)).setAssigneeUuid(assignee).setNew(true))
170 .forEach(underTest::add);
172 DistributedMetricStatsInt globalDistribution = underTest.globalStatistics().getDistributedMetricStats(Metric.RULE);
173 NewIssuesStatistics.Stats stats = underTest.getAssigneesStatistics().get(assignee);
174 DistributedMetricStatsInt assigneeDistribution = stats.getDistributedMetricStats(Metric.RULE);
175 Stream.of(globalDistribution, assigneeDistribution)
176 .forEach(distribution -> ruleKeys.forEach(ruleKey -> assertStats(distribution, RuleKey.of(repository, ruleKey).toString(), 1, 1)));
180 public void add_counts_issue_per_ruleKey_off_current_analysis_globally_and_per_assignee() {
181 String repository = randomAlphanumeric(3);
182 List<String> ruleKeys = IntStream.range(0, 1 + new Random().nextInt(10)).mapToObj(i -> randomAlphabetic(3)).collect(Collectors.toList());
183 String assignee = randomAlphanumeric(10);
185 .map(ruleKey -> new DefaultIssue().setType(randomRuleTypeExceptHotspot).setRuleKey(RuleKey.of(repository, ruleKey)).setAssigneeUuid(assignee).setNew(false))
186 .forEach(underTest::add);
188 DistributedMetricStatsInt globalDistribution = underTest.globalStatistics().getDistributedMetricStats(Metric.RULE);
189 DistributedMetricStatsInt assigneeDistribution = underTest.getAssigneesStatistics().get(assignee).getDistributedMetricStats(Metric.RULE);
190 Stream.of(globalDistribution, assigneeDistribution)
191 .forEach(distribution -> ruleKeys.forEach(ruleKey -> assertStats(distribution, RuleKey.of(repository, ruleKey).toString(), 0, 1)));
195 public void add_does_not_count_ruleKey_if_null_neither_globally_nor_per_assignee() {
196 String assignee = randomAlphanumeric(10);
197 underTest.add(new DefaultIssue().setType(randomRuleTypeExceptHotspot).setRuleKey(null).setAssigneeUuid(assignee).setNew(new Random().nextBoolean()));
199 DistributedMetricStatsInt globalDistribution = underTest.globalStatistics().getDistributedMetricStats(Metric.RULE);
200 DistributedMetricStatsInt assigneeDistribution = underTest.getAssigneesStatistics().get(assignee).getDistributedMetricStats(Metric.RULE);
201 Stream.of(globalDistribution, assigneeDistribution)
202 .forEach(distribution -> {
203 assertThat(distribution.getTotal()).isZero();
204 assertThat(distribution.getForLabel(null)).isEmpty();
209 public void add_counts_issue_per_assignee_on_current_analysis_globally_and_per_assignee() {
210 List<String> assignees = IntStream.range(0, 1 + new Random().nextInt(10)).mapToObj(i -> randomAlphabetic(3)).collect(Collectors.toList());
212 .map(assignee -> new DefaultIssue().setType(randomRuleTypeExceptHotspot).setAssigneeUuid(assignee).setNew(true))
213 .forEach(underTest::add);
215 DistributedMetricStatsInt globalDistribution = underTest.globalStatistics().getDistributedMetricStats(Metric.ASSIGNEE);
216 assignees.forEach(assignee -> assertStats(globalDistribution, assignee, 1, 1));
217 assignees.forEach(assignee -> {
218 NewIssuesStatistics.Stats stats = underTest.getAssigneesStatistics().get(assignee);
219 DistributedMetricStatsInt assigneeStats = stats.getDistributedMetricStats(Metric.ASSIGNEE);
220 assertThat(assigneeStats.getOnCurrentAnalysis()).isOne();
221 assertThat(assigneeStats.getTotal()).isOne();
222 assignees.forEach(s -> {
223 Optional<MetricStatsInt> forLabelOpts = assigneeStats.getForLabel(s);
224 if (s.equals(assignee)) {
225 assertThat(forLabelOpts).isPresent();
226 MetricStatsInt forLabel = forLabelOpts.get();
227 assertThat(forLabel.getOnCurrentAnalysis()).isOne();
228 assertThat(forLabel.getTotal()).isOne();
230 assertThat(forLabelOpts).isEmpty();
237 public void add_counts_issue_per_assignee_off_current_analysis_globally_and_per_assignee() {
238 List<String> assignees = IntStream.range(0, 1 + new Random().nextInt(10)).mapToObj(i -> randomAlphabetic(3)).collect(Collectors.toList());
240 .map(assignee -> new DefaultIssue().setType(randomRuleTypeExceptHotspot).setAssigneeUuid(assignee).setNew(false))
241 .forEach(underTest::add);
243 DistributedMetricStatsInt globalDistribution = underTest.globalStatistics().getDistributedMetricStats(Metric.ASSIGNEE);
244 assignees.forEach(assignee -> assertStats(globalDistribution, assignee, 0, 1));
245 assignees.forEach(assignee -> {
246 NewIssuesStatistics.Stats stats = underTest.getAssigneesStatistics().get(assignee);
247 DistributedMetricStatsInt assigneeStats = stats.getDistributedMetricStats(Metric.ASSIGNEE);
248 assertThat(assigneeStats.getOnCurrentAnalysis()).isZero();
249 assertThat(assigneeStats.getTotal()).isOne();
250 assignees.forEach(s -> {
251 Optional<MetricStatsInt> forLabelOpts = assigneeStats.getForLabel(s);
252 if (s.equals(assignee)) {
253 assertThat(forLabelOpts).isPresent();
254 MetricStatsInt forLabel = forLabelOpts.get();
255 assertThat(forLabel.getOnCurrentAnalysis()).isZero();
256 assertThat(forLabel.getTotal()).isOne();
258 assertThat(forLabelOpts).isEmpty();
265 public void add_does_not_assignee_if_empty_neither_globally_nor_per_assignee() {
266 underTest.add(new DefaultIssue().setType(randomRuleTypeExceptHotspot).setAssigneeUuid(null).setNew(new Random().nextBoolean()));
268 DistributedMetricStatsInt globalDistribution = underTest.globalStatistics().getDistributedMetricStats(Metric.ASSIGNEE);
269 assertThat(globalDistribution.getTotal()).isZero();
270 assertThat(globalDistribution.getForLabel(null)).isEmpty();
271 assertThat(underTest.getAssigneesStatistics()).isEmpty();
275 public void add_counts_issue_per_tags_on_current_analysis_globally_and_per_assignee() {
276 List<String> tags = IntStream.range(0, 1 + new Random().nextInt(10)).mapToObj(i -> randomAlphabetic(3)).collect(Collectors.toList());
277 String assignee = randomAlphanumeric(10);
278 underTest.add(new DefaultIssue().setType(randomRuleTypeExceptHotspot).setTags(tags).setAssigneeUuid(assignee).setNew(true));
280 DistributedMetricStatsInt globalDistribution = underTest.globalStatistics().getDistributedMetricStats(Metric.TAG);
281 DistributedMetricStatsInt assigneeDistribution = underTest.getAssigneesStatistics().get(assignee).getDistributedMetricStats(Metric.TAG);
282 Stream.of(globalDistribution, assigneeDistribution)
283 .forEach(distribution -> tags.forEach(tag -> assertStats(distribution, tag, 1, 1)));
287 public void add_counts_issue_per_tags_off_current_analysis_globally_and_per_assignee() {
288 List<String> tags = IntStream.range(0, 1 + new Random().nextInt(10)).mapToObj(i -> randomAlphabetic(3)).collect(Collectors.toList());
289 String assignee = randomAlphanumeric(10);
290 underTest.add(new DefaultIssue().setType(randomRuleTypeExceptHotspot).setTags(tags).setAssigneeUuid(assignee).setNew(false));
292 DistributedMetricStatsInt globalDistribution = underTest.globalStatistics().getDistributedMetricStats(Metric.TAG);
293 DistributedMetricStatsInt assigneeDistribution = underTest.getAssigneesStatistics().get(assignee).getDistributedMetricStats(Metric.TAG);
294 Stream.of(globalDistribution, assigneeDistribution)
295 .forEach(distribution -> tags.forEach(tag -> assertStats(distribution, tag, 0, 1)));
299 public void add_does_not_count_tags_if_empty_neither_globally_nor_per_assignee() {
300 String assignee = randomAlphanumeric(10);
301 underTest.add(new DefaultIssue().setType(randomRuleTypeExceptHotspot).setTags(Collections.emptyList()).setAssigneeUuid(assignee).setNew(new Random().nextBoolean()));
303 DistributedMetricStatsInt globalDistribution = underTest.globalStatistics().getDistributedMetricStats(Metric.TAG);
304 DistributedMetricStatsInt assigneeDistribution = underTest.getAssigneesStatistics().get(assignee).getDistributedMetricStats(Metric.TAG);
305 Stream.of(globalDistribution, assigneeDistribution)
306 .forEach(distribution -> {
307 assertThat(distribution.getTotal()).isZero();
308 assertThat(distribution.getForLabel(null)).isEmpty();
313 public void add_sums_effort_on_current_analysis_globally_and_per_assignee() {
314 Random random = new Random();
315 List<Integer> efforts = IntStream.range(0, 1 + random.nextInt(10)).mapToObj(i -> 10_000 * i).collect(Collectors.toList());
316 int expected = efforts.stream().mapToInt(s -> s).sum();
317 String assignee = randomAlphanumeric(10);
319 .map(effort -> new DefaultIssue().setType(randomRuleTypeExceptHotspot).setEffort(Duration.create(effort)).setAssigneeUuid(assignee).setNew(true))
320 .forEach(underTest::add);
322 MetricStatsLong globalDistribution = underTest.globalStatistics().effort();
323 MetricStatsLong assigneeDistribution = underTest.getAssigneesStatistics().get(assignee).effort();
324 Stream.of(globalDistribution, assigneeDistribution)
325 .forEach(distribution -> {
326 assertThat(distribution.getOnCurrentAnalysis()).isEqualTo(expected);
327 assertThat(distribution.getOffCurrentAnalysis()).isZero();
328 assertThat(distribution.getTotal()).isEqualTo(expected);
333 public void add_sums_effort_off_current_analysis_globally_and_per_assignee() {
334 Random random = new Random();
335 List<Integer> efforts = IntStream.range(0, 1 + random.nextInt(10)).mapToObj(i -> 10_000 * i).collect(Collectors.toList());
336 int expected = efforts.stream().mapToInt(s -> s).sum();
337 String assignee = randomAlphanumeric(10);
339 .map(effort -> new DefaultIssue().setType(randomRuleTypeExceptHotspot).setEffort(Duration.create(effort)).setAssigneeUuid(assignee).setNew(false))
340 .forEach(underTest::add);
342 MetricStatsLong globalDistribution = underTest.globalStatistics().effort();
343 MetricStatsLong assigneeDistribution = underTest.getAssigneesStatistics().get(assignee).effort();
344 Stream.of(globalDistribution, assigneeDistribution)
345 .forEach(distribution -> {
346 assertThat(distribution.getOnCurrentAnalysis()).isZero();
347 assertThat(distribution.getOffCurrentAnalysis()).isEqualTo(expected);
348 assertThat(distribution.getTotal()).isEqualTo(expected);
353 public void add_does_not_sum_effort_if_null_neither_globally_nor_per_assignee() {
354 String assignee = randomAlphanumeric(10);
355 underTest.add(new DefaultIssue().setType(randomRuleTypeExceptHotspot).setEffort(null).setAssigneeUuid(assignee).setNew(new Random().nextBoolean()));
357 MetricStatsLong globalDistribution = underTest.globalStatistics().effort();
358 MetricStatsLong assigneeDistribution = underTest.getAssigneesStatistics().get(assignee).effort();
359 Stream.of(globalDistribution, assigneeDistribution)
360 .forEach(distribution -> assertThat(distribution.getTotal()).isZero());
364 public void do_not_have_issues_when_no_issue_added() {
365 assertThat(underTest.globalStatistics().hasIssues()).isFalse();
369 public void verify_toString() {
370 String componentUuid = randomAlphanumeric(2);
371 String tag = randomAlphanumeric(3);
372 String assignee = randomAlphanumeric(4);
373 int effort = 10 + new Random().nextInt(5);
374 RuleKey ruleKey = RuleKey.of(randomAlphanumeric(5), randomAlphanumeric(6));
375 underTest.add(new DefaultIssue()
376 .setType(randomRuleTypeExceptHotspot)
377 .setComponentUuid(componentUuid)
378 .setTags(ImmutableSet.of(tag))
379 .setAssigneeUuid(assignee)
381 .setEffort(Duration.create(effort)));
383 assertThat(underTest.toString())
384 .isEqualTo("NewIssuesStatistics{" +
385 "assigneesStatistics={" + assignee + "=" +
386 "Stats{distributions={" +
387 "RULE_TYPE=DistributedMetricStatsInt{globalStats=MetricStatsInt{on=1, off=0}, " +
388 "statsPerLabel={" + randomRuleTypeExceptHotspot.name() + "=MetricStatsInt{on=1, off=0}}}, " +
389 "TAG=DistributedMetricStatsInt{globalStats=MetricStatsInt{on=1, off=0}, " +
390 "statsPerLabel={" + tag + "=MetricStatsInt{on=1, off=0}}}, " +
391 "COMPONENT=DistributedMetricStatsInt{globalStats=MetricStatsInt{on=1, off=0}, " +
392 "statsPerLabel={" + componentUuid + "=MetricStatsInt{on=1, off=0}}}, " +
393 "ASSIGNEE=DistributedMetricStatsInt{globalStats=MetricStatsInt{on=1, off=0}, " +
394 "statsPerLabel={" + assignee + "=MetricStatsInt{on=1, off=0}}}, " +
395 "RULE=DistributedMetricStatsInt{globalStats=MetricStatsInt{on=1, off=0}, " +
396 "statsPerLabel={" + ruleKey.toString() + "=MetricStatsInt{on=1, off=0}}}}, " +
397 "effortStats=MetricStatsLong{on=" + effort + ", off=0}}}, " +
398 "globalStatistics=Stats{distributions={" +
399 "RULE_TYPE=DistributedMetricStatsInt{globalStats=MetricStatsInt{on=1, off=0}, " +
400 "statsPerLabel={" + randomRuleTypeExceptHotspot.name() + "=MetricStatsInt{on=1, off=0}}}, " +
401 "TAG=DistributedMetricStatsInt{globalStats=MetricStatsInt{on=1, off=0}, " +
402 "statsPerLabel={" + tag + "=MetricStatsInt{on=1, off=0}}}, " +
403 "COMPONENT=DistributedMetricStatsInt{globalStats=MetricStatsInt{on=1, off=0}, " +
404 "statsPerLabel={" + componentUuid + "=MetricStatsInt{on=1, off=0}}}, " +
405 "ASSIGNEE=DistributedMetricStatsInt{globalStats=MetricStatsInt{on=1, off=0}, " +
406 "statsPerLabel={" + assignee + "=MetricStatsInt{on=1, off=0}}}, " +
407 "RULE=DistributedMetricStatsInt{globalStats=MetricStatsInt{on=1, off=0}, " +
408 "statsPerLabel={" + ruleKey.toString() + "=MetricStatsInt{on=1, off=0}}}}, " +
409 "effortStats=MetricStatsLong{on=" + effort + ", off=0}}}");
413 private Integer countDistributionTotal(Metric metric, String label) {
414 return underTest.globalStatistics()
415 .getDistributedMetricStats(metric)
417 .map(MetricStatsInt::getTotal)
421 private void assertStats(DistributedMetricStatsInt distribution, String label, int onCurrentAnalysis, int total) {
422 Optional<MetricStatsInt> statsOption = distribution.getForLabel(label);
423 assertThat(statsOption.isPresent()).describedAs("distribution for label %s not found", label).isTrue();
424 MetricStatsInt stats = statsOption.get();
425 assertThat(stats.getOnCurrentAnalysis()).isEqualTo(onCurrentAnalysis);
426 assertThat(stats.getTotal()).isEqualTo(total);