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.Arrays.asList;
41 import static java.util.stream.Collectors.joining;
42 import static org.apache.commons.lang.RandomStringUtils.randomAlphabetic;
43 import static org.assertj.core.api.Assertions.assertThat;
44 import static org.sonar.test.JsonAssert.assertJson;
46 @RunWith(DataProviderRunner.class)
47 public class TelemetryDataJsonWriterTest {
49 private static final TelemetryData.Builder SOME_TELEMETRY_DATA = TelemetryData.builder()
52 .setPlugins(Collections.emptyMap())
53 .setAlmIntegrationCountByAlm(Collections.emptyMap())
54 .setProjectMeasuresStatistics(ProjectMeasuresStatistics.builder()
56 .setProjectCountByLanguage(Collections.emptyMap())
57 .setNclocByLanguage(Collections.emptyMap())
60 .setExternalAuthenticationProviders(asList("github", "gitlab"))
61 .setProjectCountByScm(Collections.emptyMap())
62 .setSonarlintWeeklyUsers(10)
63 .setDatabase(new TelemetryData.Database("H2", "11"))
64 .setUsingBranches(true);
66 private final Random random = new Random();
68 private final TelemetryDataJsonWriter underTest = new TelemetryDataJsonWriter();
71 public void write_server_id_and_version() {
72 TelemetryData data = SOME_TELEMETRY_DATA.build();
74 String json = writeTelemetryData(data);
76 assertJson(json).isSimilarTo("{" +
77 " \"id\": \"" + data.getServerId() + "\"," +
78 " \"version\": \"" + data.getVersion() + "\"" +
83 public void does_not_write_edition_if_null() {
84 TelemetryData data = SOME_TELEMETRY_DATA.build();
86 String json = writeTelemetryData(data);
88 assertThat(json).doesNotContain("edition");
92 public void write_external_auth_providers() {
93 TelemetryData data = SOME_TELEMETRY_DATA.build();
95 String json = writeTelemetryData(data);
97 assertJson(json).isSimilarTo("{ \"externalAuthProviders\": [ \"github\", \"gitlab\" ] }");
101 public void write_sonarlint_weekly_users() {
102 TelemetryData data = SOME_TELEMETRY_DATA.build();
104 String json = writeTelemetryData(data);
106 assertJson(json).isSimilarTo("{ \"sonarlintWeeklyUsers\": 10 }");
110 @UseDataProvider("allEditions")
111 public void writes_edition_if_non_null(EditionProvider.Edition edition) {
112 TelemetryData data = SOME_TELEMETRY_DATA
116 String json = writeTelemetryData(data);
118 assertJson(json).isSimilarTo("{" +
119 " \"edition\": \"" + edition.name().toLowerCase(Locale.ENGLISH) + "\"" +
124 public void does_not_write_license_type_if_null() {
125 TelemetryData data = SOME_TELEMETRY_DATA.build();
127 String json = writeTelemetryData(data);
129 assertThat(json).doesNotContain("licenseType");
133 public void writes_licenseType_if_non_null() {
134 String expected = randomAlphabetic(12);
135 TelemetryData data = SOME_TELEMETRY_DATA
136 .setLicenseType(expected)
139 String json = writeTelemetryData(data);
141 assertJson(json).isSimilarTo("{" +
142 " \"licenseType\": \"" + expected + "\"" +
147 public void writes_database() {
148 String name = randomAlphabetic(12);
149 String version = randomAlphabetic(10);
150 TelemetryData data = SOME_TELEMETRY_DATA
151 .setDatabase(new TelemetryData.Database(name, version))
154 String json = writeTelemetryData(data);
156 assertJson(json).isSimilarTo("{" +
158 " \"name\": \"" + name + "\"," +
159 " \"version\": \"" + version + "\"" +
165 public void writes_no_plugins() {
166 TelemetryData data = SOME_TELEMETRY_DATA
167 .setPlugins(Collections.emptyMap())
170 String json = writeTelemetryData(data);
172 assertJson(json).isSimilarTo("{" +
178 public void writes_all_plugins() {
179 Map<String, String> plugins = IntStream.range(0, 1 + random.nextInt(10))
181 .collect(MoreCollectors.uniqueIndex(i -> "P" + i, i -> "V" + i));
182 TelemetryData data = SOME_TELEMETRY_DATA
186 String json = writeTelemetryData(data);
188 assertJson(json).isSimilarTo("{" +
191 plugins.entrySet().stream().map(e -> "{\"name\":\"" + e.getKey() + "\",\"version\":\"" + e.getValue() + "\"}").collect(joining(",")) +
197 public void write_user_count() {
198 int userCount = random.nextInt(590);
199 TelemetryData data = SOME_TELEMETRY_DATA
200 .setUserCount(userCount)
203 String json = writeTelemetryData(data);
205 assertJson(json).isSimilarTo("{" +
206 " \"userCount\": " + userCount +
211 public void write_project_count_and_ncloc_and_no_stat_by_language() {
212 int projectCount = random.nextInt(8909);
213 TelemetryData data = SOME_TELEMETRY_DATA
214 .setProjectMeasuresStatistics(ProjectMeasuresStatistics.builder()
215 .setProjectCount(projectCount)
216 .setProjectCountByLanguage(Collections.emptyMap())
217 .setNclocByLanguage(Collections.emptyMap())
221 String json = writeTelemetryData(data);
223 assertJson(json).isSimilarTo("{" +
224 " \"projectCount\": " + projectCount + "," +
225 " \"projectCountByLanguage\": []," +
226 " \"nclocByLanguage\": []" +
231 public void write_project_count_by_scm() {
232 TelemetryData data = SOME_TELEMETRY_DATA
233 .setProjectCountByScm(ImmutableMap.of("git", 5L, "svn", 4L, "cvs", 3L, "undetected", 2L))
236 String json = writeTelemetryData(data);
238 assertJson(json).isSimilarTo("{" +
239 " \"projectCountByScm\": ["
240 + "{ \"scm\":\"git\", \"count\":5},"
241 + "{ \"scm\":\"svn\", \"count\":4},"
242 + "{ \"scm\":\"cvs\", \"count\":3},"
243 + "{ \"scm\":\"undetected\", \"count\":2},"
248 public void write_project_stats_by_language() {
249 int projectCount = random.nextInt(8909);
250 Map<String, Long> countByLanguage = IntStream.range(0, 1 + random.nextInt(10))
252 .collect(MoreCollectors.uniqueIndex(i -> "P" + i, i -> 100L + i));
253 Map<String, Long> nclocByLanguage = IntStream.range(0, 1 + random.nextInt(10))
255 .collect(MoreCollectors.uniqueIndex(i -> "P" + i, i -> 1_000L + i));
256 TelemetryData data = SOME_TELEMETRY_DATA
257 .setProjectMeasuresStatistics(ProjectMeasuresStatistics.builder()
258 .setProjectCount(projectCount)
259 .setProjectCountByLanguage(countByLanguage)
260 .setNclocByLanguage(nclocByLanguage)
264 String json = writeTelemetryData(data);
266 assertJson(json).isSimilarTo("{" +
267 " \"projectCount\": " + projectCount + "," +
268 " \"projectCountByLanguage\": " +
270 countByLanguage.entrySet().stream().map(e -> "{\"language\":\"" + e.getKey() + "\",\"count\":" + e.getValue() + "}").collect(joining()) +
272 " \"nclocByLanguage\": " +
274 nclocByLanguage.entrySet().stream().map(e -> "{\"language\":\"" + e.getKey() + "\",\"ncloc\":" + e.getValue() + "}").collect(joining()) +
280 public void write_alm_count_by_alm() {
281 TelemetryData data = SOME_TELEMETRY_DATA
282 .setAlmIntegrationCountByAlm(ImmutableMap.of(
290 String json = writeTelemetryData(data);
292 assertJson(json).isSimilarTo("{" +
293 " \"almIntegrationCount\": " +
295 + "{ \"alm\":\"github\", \"count\":4},"
296 + "{ \"alm\":\"github_cloud\", \"count\":1},"
297 + "{ \"alm\":\"gitlab\", \"count\":2},"
298 + "{ \"alm\":\"gitlab_cloud\", \"count\":5},"
299 + "{ \"alm\":\"azure_devops\", \"count\":1},"
306 public void does_not_write_installation_date_if_null() {
307 TelemetryData data = SOME_TELEMETRY_DATA
308 .setInstallationDate(null)
311 String json = writeTelemetryData(data);
313 assertThat(json).doesNotContain("installationDate");
317 public void write_installation_date() {
318 long installationDate = random.nextInt(590);
319 TelemetryData data = SOME_TELEMETRY_DATA
320 .setInstallationDate(installationDate)
323 String json = writeTelemetryData(data);
325 assertJson(json).isSimilarTo("{" +
326 " \"installationDate\": " + installationDate +
331 public void does_not_write_installation_version_if_null() {
332 TelemetryData data = SOME_TELEMETRY_DATA
333 .setInstallationVersion(null)
336 String json = writeTelemetryData(data);
338 assertThat(json).doesNotContain("installationVersion");
342 public void write_installation_version() {
343 String installationVersion = randomAlphabetic(5);
344 TelemetryData data = SOME_TELEMETRY_DATA
345 .setInstallationVersion(installationVersion)
348 String json = writeTelemetryData(data);
350 assertJson(json).isSimilarTo("{" +
351 " \"installationVersion\":\"" + installationVersion + "\"" +
356 public void write_docker_flag() {
357 boolean inDocker = random.nextBoolean();
358 TelemetryData data = SOME_TELEMETRY_DATA
359 .setInDocker(inDocker)
362 String json = writeTelemetryData(data);
364 assertJson(json).isSimilarTo("{" +
365 " \"docker\":" + inDocker +
370 public void writes_has_unanalyzed_languages() {
371 TelemetryData data = SOME_TELEMETRY_DATA
372 .setHasUnanalyzedC(true)
373 .setHasUnanalyzedCpp(false)
376 String json = writeTelemetryData(data);
378 assertJson(json).isSimilarTo("{" +
379 " \"hasUnanalyzedC\":true," +
380 " \"hasUnanalyzedCpp\":false," +
385 public void writes_security_custom_config() {
386 TelemetryData data = SOME_TELEMETRY_DATA
387 .setCustomSecurityConfigs(Arrays.asList("php", "java"))
390 String json = writeTelemetryData(data);
392 assertJson(json).isSimilarTo("{" +
393 " \"customSecurityConfig\": [\"php\", \"java\"]" +
398 public static Object[][] allEditions() {
399 return Arrays.stream(EditionProvider.Edition.values())
400 .map(t -> new Object[]{t})
401 .toArray(Object[][]::new);
404 private String writeTelemetryData(TelemetryData data) {
405 StringWriter jsonString = new StringWriter();
406 try (JsonWriter json = JsonWriter.of(jsonString)) {
407 underTest.writeTelemetryData(json, data);
409 return jsonString.toString();