3 * Copyright (C) 2009-2021 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.telemetry;
22 import com.google.common.collect.ImmutableMap;
23 import com.tngtech.java.junit.dataprovider.DataProvider;
24 import com.tngtech.java.junit.dataprovider.DataProviderRunner;
25 import com.tngtech.java.junit.dataprovider.UseDataProvider;
26 import java.io.StringWriter;
27 import java.util.Arrays;
28 import java.util.Collections;
29 import java.util.Locale;
31 import java.util.Random;
32 import java.util.stream.IntStream;
33 import org.junit.Test;
34 import org.junit.runner.RunWith;
35 import org.sonar.api.utils.text.JsonWriter;
36 import org.sonar.core.platform.EditionProvider;
37 import org.sonar.core.util.stream.MoreCollectors;
38 import org.sonar.server.measure.index.ProjectMeasuresStatistics;
40 import static java.util.stream.Collectors.joining;
41 import static org.apache.commons.lang.RandomStringUtils.randomAlphabetic;
42 import static org.assertj.core.api.Assertions.assertThat;
43 import static org.sonar.test.JsonAssert.assertJson;
45 @RunWith(DataProviderRunner.class)
46 public class TelemetryDataJsonWriterTest {
48 private static final TelemetryData.Builder SOME_TELEMETRY_DATA = TelemetryData.builder()
51 .setPlugins(Collections.emptyMap())
52 .setAlmIntegrationCountByAlm(Collections.emptyMap())
53 .setProjectMeasuresStatistics(ProjectMeasuresStatistics.builder()
55 .setProjectCountByLanguage(Collections.emptyMap())
56 .setNclocByLanguage(Collections.emptyMap())
59 .setDatabase(new TelemetryData.Database("H2", "11"))
60 .setUsingBranches(true);
62 private final Random random = new Random();
64 private final TelemetryDataJsonWriter underTest = new TelemetryDataJsonWriter();
67 public void write_server_id_and_version() {
68 TelemetryData data = SOME_TELEMETRY_DATA.build();
70 String json = writeTelemetryData(data);
72 assertJson(json).isSimilarTo("{" +
73 " \"id\": \"" + data.getServerId() + "\"," +
74 " \"version\": \"" + data.getVersion() + "\"" +
79 public void does_not_write_edition_if_null() {
80 TelemetryData data = SOME_TELEMETRY_DATA.build();
82 String json = writeTelemetryData(data);
84 assertThat(json).doesNotContain("edition");
88 @UseDataProvider("allEditions")
89 public void writes_edition_if_non_null(EditionProvider.Edition edition) {
90 TelemetryData data = SOME_TELEMETRY_DATA
94 String json = writeTelemetryData(data);
96 assertJson(json).isSimilarTo("{" +
97 " \"edition\": \"" + edition.name().toLowerCase(Locale.ENGLISH) + "\"" +
102 public void does_not_write_license_type_if_null() {
103 TelemetryData data = SOME_TELEMETRY_DATA.build();
105 String json = writeTelemetryData(data);
107 assertThat(json).doesNotContain("licenseType");
111 public void writes_licenseType_if_non_null() {
112 String expected = randomAlphabetic(12);
113 TelemetryData data = SOME_TELEMETRY_DATA
114 .setLicenseType(expected)
117 String json = writeTelemetryData(data);
119 assertJson(json).isSimilarTo("{" +
120 " \"licenseType\": \"" + expected + "\"" +
125 public void writes_database() {
126 String name = randomAlphabetic(12);
127 String version = randomAlphabetic(10);
128 TelemetryData data = SOME_TELEMETRY_DATA
129 .setDatabase(new TelemetryData.Database(name, version))
132 String json = writeTelemetryData(data);
134 assertJson(json).isSimilarTo("{" +
136 " \"name\": \"" + name + "\"," +
137 " \"version\": \"" + version + "\"" +
143 public void writes_no_plugins() {
144 TelemetryData data = SOME_TELEMETRY_DATA
145 .setPlugins(Collections.emptyMap())
148 String json = writeTelemetryData(data);
150 assertJson(json).isSimilarTo("{" +
156 public void writes_all_plugins() {
157 Map<String, String> plugins = IntStream.range(0, 1 + random.nextInt(10))
159 .collect(MoreCollectors.uniqueIndex(i -> "P" + i, i -> "V" + i));
160 TelemetryData data = SOME_TELEMETRY_DATA
164 String json = writeTelemetryData(data);
166 assertJson(json).isSimilarTo("{" +
169 plugins.entrySet().stream().map(e -> "{\"name\":\"" + e.getKey() + "\",\"version\":\"" + e.getValue() + "\"}").collect(joining(",")) +
175 public void write_user_count() {
176 int userCount = random.nextInt(590);
177 TelemetryData data = SOME_TELEMETRY_DATA
178 .setUserCount(userCount)
181 String json = writeTelemetryData(data);
183 assertJson(json).isSimilarTo("{" +
184 " \"userCount\": " + userCount +
189 public void write_project_count_and_ncloc_and_no_stat_by_language() {
190 int projectCount = random.nextInt(8909);
191 TelemetryData data = SOME_TELEMETRY_DATA
192 .setProjectMeasuresStatistics(ProjectMeasuresStatistics.builder()
193 .setProjectCount(projectCount)
194 .setProjectCountByLanguage(Collections.emptyMap())
195 .setNclocByLanguage(Collections.emptyMap())
199 String json = writeTelemetryData(data);
201 assertJson(json).isSimilarTo("{" +
202 " \"projectCount\": " + projectCount + "," +
203 " \"projectCountByLanguage\": []," +
204 " \"nclocByLanguage\": []" +
209 public void write_project_stats_by_language() {
210 int projectCount = random.nextInt(8909);
211 Map<String, Long> countByLanguage = IntStream.range(0, 1 + random.nextInt(10))
213 .collect(MoreCollectors.uniqueIndex(i -> "P" + i, i -> 100L + i));
214 Map<String, Long> nclocByLanguage = IntStream.range(0, 1 + random.nextInt(10))
216 .collect(MoreCollectors.uniqueIndex(i -> "P" + i, i -> 1_000L + i));
217 TelemetryData data = SOME_TELEMETRY_DATA
218 .setProjectMeasuresStatistics(ProjectMeasuresStatistics.builder()
219 .setProjectCount(projectCount)
220 .setProjectCountByLanguage(countByLanguage)
221 .setNclocByLanguage(nclocByLanguage)
225 String json = writeTelemetryData(data);
227 assertJson(json).isSimilarTo("{" +
228 " \"projectCount\": " + projectCount + "," +
229 " \"projectCountByLanguage\": " +
231 countByLanguage.entrySet().stream().map(e -> "{\"language\":\"" + e.getKey() + "\",\"count\":" + e.getValue() + "}").collect(joining()) +
233 " \"nclocByLanguage\": " +
235 nclocByLanguage.entrySet().stream().map(e -> "{\"language\":\"" + e.getKey() + "\",\"ncloc\":" + e.getValue() + "}").collect(joining()) +
241 public void write_alm_count_by_alm() {
242 TelemetryData data = SOME_TELEMETRY_DATA
243 .setAlmIntegrationCountByAlm(ImmutableMap.of(
251 String json = writeTelemetryData(data);
253 assertJson(json).isSimilarTo("{" +
254 " \"almIntegrationCount\": " +
256 + "{ \"alm\":\"github\", \"count\":4},"
257 + "{ \"alm\":\"github_cloud\", \"count\":1},"
258 + "{ \"alm\":\"gitlab\", \"count\":2},"
259 + "{ \"alm\":\"gitlab_cloud\", \"count\":5},"
260 + "{ \"alm\":\"azure_devops\", \"count\":1},"
267 public void does_not_write_installation_date_if_null() {
268 TelemetryData data = SOME_TELEMETRY_DATA
269 .setInstallationDate(null)
272 String json = writeTelemetryData(data);
274 assertThat(json).doesNotContain("installationDate");
278 public void write_installation_date() {
279 long installationDate = random.nextInt(590);
280 TelemetryData data = SOME_TELEMETRY_DATA
281 .setInstallationDate(installationDate)
284 String json = writeTelemetryData(data);
286 assertJson(json).isSimilarTo("{" +
287 " \"installationDate\": " + installationDate +
292 public void does_not_write_installation_version_if_null() {
293 TelemetryData data = SOME_TELEMETRY_DATA
294 .setInstallationVersion(null)
297 String json = writeTelemetryData(data);
299 assertThat(json).doesNotContain("installationVersion");
303 public void write_installation_version() {
304 String installationVersion = randomAlphabetic(5);
305 TelemetryData data = SOME_TELEMETRY_DATA
306 .setInstallationVersion(installationVersion)
309 String json = writeTelemetryData(data);
311 assertJson(json).isSimilarTo("{" +
312 " \"installationVersion\":\"" + installationVersion + "\"" +
317 public void write_docker_flag() {
318 boolean inDocker = random.nextBoolean();
319 TelemetryData data = SOME_TELEMETRY_DATA
320 .setInDocker(inDocker)
323 String json = writeTelemetryData(data);
325 assertJson(json).isSimilarTo("{" +
326 " \"docker\":" + inDocker +
331 public void writes_has_unanalyzed_languages() {
332 TelemetryData data = SOME_TELEMETRY_DATA
333 .setHasUnanalyzedC(true)
334 .setHasUnanalyzedCpp(false)
337 String json = writeTelemetryData(data);
339 assertJson(json).isSimilarTo("{" +
340 " \"hasUnanalyzedC\":true," +
341 " \"hasUnanalyzedCpp\":false," +
346 public static Object[][] allEditions() {
347 return Arrays.stream(EditionProvider.Edition.values())
348 .map(t -> new Object[] {t})
349 .toArray(Object[][]::new);
352 private String writeTelemetryData(TelemetryData data) {
353 StringWriter jsonString = new StringWriter();
354 try (JsonWriter json = JsonWriter.of(jsonString)) {
355 underTest.writeTelemetryData(json, data);
357 return jsonString.toString();