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 .setDatabase(new TelemetryData.Database("H2", "11"))
63 .setUsingBranches(true);
65 private final Random random = new Random();
67 private final TelemetryDataJsonWriter underTest = new TelemetryDataJsonWriter();
70 public void write_server_id_and_version() {
71 TelemetryData data = SOME_TELEMETRY_DATA.build();
73 String json = writeTelemetryData(data);
75 assertJson(json).isSimilarTo("{" +
76 " \"id\": \"" + data.getServerId() + "\"," +
77 " \"version\": \"" + data.getVersion() + "\"" +
82 public void does_not_write_edition_if_null() {
83 TelemetryData data = SOME_TELEMETRY_DATA.build();
85 String json = writeTelemetryData(data);
87 assertThat(json).doesNotContain("edition");
91 public void write_external_auth_providers() {
92 TelemetryData data = SOME_TELEMETRY_DATA.build();
94 String json = writeTelemetryData(data);
96 assertJson(json).isSimilarTo("{ \"externalAuthProviders\": [ \"github\", \"gitlab\" ] }");
100 @UseDataProvider("allEditions")
101 public void writes_edition_if_non_null(EditionProvider.Edition edition) {
102 TelemetryData data = SOME_TELEMETRY_DATA
106 String json = writeTelemetryData(data);
108 assertJson(json).isSimilarTo("{" +
109 " \"edition\": \"" + edition.name().toLowerCase(Locale.ENGLISH) + "\"" +
114 public void does_not_write_license_type_if_null() {
115 TelemetryData data = SOME_TELEMETRY_DATA.build();
117 String json = writeTelemetryData(data);
119 assertThat(json).doesNotContain("licenseType");
123 public void writes_licenseType_if_non_null() {
124 String expected = randomAlphabetic(12);
125 TelemetryData data = SOME_TELEMETRY_DATA
126 .setLicenseType(expected)
129 String json = writeTelemetryData(data);
131 assertJson(json).isSimilarTo("{" +
132 " \"licenseType\": \"" + expected + "\"" +
137 public void writes_database() {
138 String name = randomAlphabetic(12);
139 String version = randomAlphabetic(10);
140 TelemetryData data = SOME_TELEMETRY_DATA
141 .setDatabase(new TelemetryData.Database(name, version))
144 String json = writeTelemetryData(data);
146 assertJson(json).isSimilarTo("{" +
148 " \"name\": \"" + name + "\"," +
149 " \"version\": \"" + version + "\"" +
155 public void writes_no_plugins() {
156 TelemetryData data = SOME_TELEMETRY_DATA
157 .setPlugins(Collections.emptyMap())
160 String json = writeTelemetryData(data);
162 assertJson(json).isSimilarTo("{" +
168 public void writes_all_plugins() {
169 Map<String, String> plugins = IntStream.range(0, 1 + random.nextInt(10))
171 .collect(MoreCollectors.uniqueIndex(i -> "P" + i, i -> "V" + i));
172 TelemetryData data = SOME_TELEMETRY_DATA
176 String json = writeTelemetryData(data);
178 assertJson(json).isSimilarTo("{" +
181 plugins.entrySet().stream().map(e -> "{\"name\":\"" + e.getKey() + "\",\"version\":\"" + e.getValue() + "\"}").collect(joining(",")) +
187 public void write_user_count() {
188 int userCount = random.nextInt(590);
189 TelemetryData data = SOME_TELEMETRY_DATA
190 .setUserCount(userCount)
193 String json = writeTelemetryData(data);
195 assertJson(json).isSimilarTo("{" +
196 " \"userCount\": " + userCount +
201 public void write_project_count_and_ncloc_and_no_stat_by_language() {
202 int projectCount = random.nextInt(8909);
203 TelemetryData data = SOME_TELEMETRY_DATA
204 .setProjectMeasuresStatistics(ProjectMeasuresStatistics.builder()
205 .setProjectCount(projectCount)
206 .setProjectCountByLanguage(Collections.emptyMap())
207 .setNclocByLanguage(Collections.emptyMap())
211 String json = writeTelemetryData(data);
213 assertJson(json).isSimilarTo("{" +
214 " \"projectCount\": " + projectCount + "," +
215 " \"projectCountByLanguage\": []," +
216 " \"nclocByLanguage\": []" +
221 public void write_project_count_by_scm() {
222 TelemetryData data = SOME_TELEMETRY_DATA
223 .setProjectCountByScm(ImmutableMap.of("git", 5L, "svn", 4L, "cvs", 3L, "undetected", 2L))
226 String json = writeTelemetryData(data);
228 assertJson(json).isSimilarTo("{" +
229 " \"projectCountByScm\": ["
230 + "{ \"scm\":\"git\", \"count\":5},"
231 + "{ \"scm\":\"svn\", \"count\":4},"
232 + "{ \"scm\":\"cvs\", \"count\":3},"
233 + "{ \"scm\":\"undetected\", \"count\":2},"
238 public void write_project_stats_by_language() {
239 int projectCount = random.nextInt(8909);
240 Map<String, Long> countByLanguage = IntStream.range(0, 1 + random.nextInt(10))
242 .collect(MoreCollectors.uniqueIndex(i -> "P" + i, i -> 100L + i));
243 Map<String, Long> nclocByLanguage = IntStream.range(0, 1 + random.nextInt(10))
245 .collect(MoreCollectors.uniqueIndex(i -> "P" + i, i -> 1_000L + i));
246 TelemetryData data = SOME_TELEMETRY_DATA
247 .setProjectMeasuresStatistics(ProjectMeasuresStatistics.builder()
248 .setProjectCount(projectCount)
249 .setProjectCountByLanguage(countByLanguage)
250 .setNclocByLanguage(nclocByLanguage)
254 String json = writeTelemetryData(data);
256 assertJson(json).isSimilarTo("{" +
257 " \"projectCount\": " + projectCount + "," +
258 " \"projectCountByLanguage\": " +
260 countByLanguage.entrySet().stream().map(e -> "{\"language\":\"" + e.getKey() + "\",\"count\":" + e.getValue() + "}").collect(joining()) +
262 " \"nclocByLanguage\": " +
264 nclocByLanguage.entrySet().stream().map(e -> "{\"language\":\"" + e.getKey() + "\",\"ncloc\":" + e.getValue() + "}").collect(joining()) +
270 public void write_alm_count_by_alm() {
271 TelemetryData data = SOME_TELEMETRY_DATA
272 .setAlmIntegrationCountByAlm(ImmutableMap.of(
280 String json = writeTelemetryData(data);
282 assertJson(json).isSimilarTo("{" +
283 " \"almIntegrationCount\": " +
285 + "{ \"alm\":\"github\", \"count\":4},"
286 + "{ \"alm\":\"github_cloud\", \"count\":1},"
287 + "{ \"alm\":\"gitlab\", \"count\":2},"
288 + "{ \"alm\":\"gitlab_cloud\", \"count\":5},"
289 + "{ \"alm\":\"azure_devops\", \"count\":1},"
296 public void does_not_write_installation_date_if_null() {
297 TelemetryData data = SOME_TELEMETRY_DATA
298 .setInstallationDate(null)
301 String json = writeTelemetryData(data);
303 assertThat(json).doesNotContain("installationDate");
307 public void write_installation_date() {
308 long installationDate = random.nextInt(590);
309 TelemetryData data = SOME_TELEMETRY_DATA
310 .setInstallationDate(installationDate)
313 String json = writeTelemetryData(data);
315 assertJson(json).isSimilarTo("{" +
316 " \"installationDate\": " + installationDate +
321 public void does_not_write_installation_version_if_null() {
322 TelemetryData data = SOME_TELEMETRY_DATA
323 .setInstallationVersion(null)
326 String json = writeTelemetryData(data);
328 assertThat(json).doesNotContain("installationVersion");
332 public void write_installation_version() {
333 String installationVersion = randomAlphabetic(5);
334 TelemetryData data = SOME_TELEMETRY_DATA
335 .setInstallationVersion(installationVersion)
338 String json = writeTelemetryData(data);
340 assertJson(json).isSimilarTo("{" +
341 " \"installationVersion\":\"" + installationVersion + "\"" +
346 public void write_docker_flag() {
347 boolean inDocker = random.nextBoolean();
348 TelemetryData data = SOME_TELEMETRY_DATA
349 .setInDocker(inDocker)
352 String json = writeTelemetryData(data);
354 assertJson(json).isSimilarTo("{" +
355 " \"docker\":" + inDocker +
360 public void writes_has_unanalyzed_languages() {
361 TelemetryData data = SOME_TELEMETRY_DATA
362 .setHasUnanalyzedC(true)
363 .setHasUnanalyzedCpp(false)
366 String json = writeTelemetryData(data);
368 assertJson(json).isSimilarTo("{" +
369 " \"hasUnanalyzedC\":true," +
370 " \"hasUnanalyzedCpp\":false," +
375 public void writes_security_custom_config() {
376 TelemetryData data = SOME_TELEMETRY_DATA
377 .setCustomSecurityConfigs(Arrays.asList("php", "java"))
380 String json = writeTelemetryData(data);
382 assertJson(json).isSimilarTo("{" +
383 " \"customSecurityConfig\": [\"php\", \"java\"]" +
388 public static Object[][] allEditions() {
389 return Arrays.stream(EditionProvider.Edition.values())
390 .map(t -> new Object[]{t})
391 .toArray(Object[][]::new);
394 private String writeTelemetryData(TelemetryData data) {
395 StringWriter jsonString = new StringWriter();
396 try (JsonWriter json = JsonWriter.of(jsonString)) {
397 underTest.writeTelemetryData(json, data);
399 return jsonString.toString();