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 .setExternalAuthenticationProviders(Arrays.asList("github", "gitlab"))
60 .setDatabase(new TelemetryData.Database("H2", "11"))
61 .setUsingBranches(true);
63 private final Random random = new Random();
65 private final TelemetryDataJsonWriter underTest = new TelemetryDataJsonWriter();
68 public void write_server_id_and_version() {
69 TelemetryData data = SOME_TELEMETRY_DATA.build();
71 String json = writeTelemetryData(data);
73 assertJson(json).isSimilarTo("{" +
74 " \"id\": \"" + data.getServerId() + "\"," +
75 " \"version\": \"" + data.getVersion() + "\"" +
80 public void does_not_write_edition_if_null() {
81 TelemetryData data = SOME_TELEMETRY_DATA.build();
83 String json = writeTelemetryData(data);
85 assertThat(json).doesNotContain("edition");
89 public void write_external_auth_providers() {
90 TelemetryData data = SOME_TELEMETRY_DATA.build();
92 String json = writeTelemetryData(data);
94 assertJson(json).isSimilarTo("{ \"externalAuthProviders\": [ \"github\", \"gitlab\" ] }");
98 @UseDataProvider("allEditions")
99 public void writes_edition_if_non_null(EditionProvider.Edition edition) {
100 TelemetryData data = SOME_TELEMETRY_DATA
104 String json = writeTelemetryData(data);
106 assertJson(json).isSimilarTo("{" +
107 " \"edition\": \"" + edition.name().toLowerCase(Locale.ENGLISH) + "\"" +
112 public void does_not_write_license_type_if_null() {
113 TelemetryData data = SOME_TELEMETRY_DATA.build();
115 String json = writeTelemetryData(data);
117 assertThat(json).doesNotContain("licenseType");
121 public void writes_licenseType_if_non_null() {
122 String expected = randomAlphabetic(12);
123 TelemetryData data = SOME_TELEMETRY_DATA
124 .setLicenseType(expected)
127 String json = writeTelemetryData(data);
129 assertJson(json).isSimilarTo("{" +
130 " \"licenseType\": \"" + expected + "\"" +
135 public void writes_database() {
136 String name = randomAlphabetic(12);
137 String version = randomAlphabetic(10);
138 TelemetryData data = SOME_TELEMETRY_DATA
139 .setDatabase(new TelemetryData.Database(name, version))
142 String json = writeTelemetryData(data);
144 assertJson(json).isSimilarTo("{" +
146 " \"name\": \"" + name + "\"," +
147 " \"version\": \"" + version + "\"" +
153 public void writes_no_plugins() {
154 TelemetryData data = SOME_TELEMETRY_DATA
155 .setPlugins(Collections.emptyMap())
158 String json = writeTelemetryData(data);
160 assertJson(json).isSimilarTo("{" +
166 public void writes_all_plugins() {
167 Map<String, String> plugins = IntStream.range(0, 1 + random.nextInt(10))
169 .collect(MoreCollectors.uniqueIndex(i -> "P" + i, i -> "V" + i));
170 TelemetryData data = SOME_TELEMETRY_DATA
174 String json = writeTelemetryData(data);
176 assertJson(json).isSimilarTo("{" +
179 plugins.entrySet().stream().map(e -> "{\"name\":\"" + e.getKey() + "\",\"version\":\"" + e.getValue() + "\"}").collect(joining(",")) +
185 public void write_user_count() {
186 int userCount = random.nextInt(590);
187 TelemetryData data = SOME_TELEMETRY_DATA
188 .setUserCount(userCount)
191 String json = writeTelemetryData(data);
193 assertJson(json).isSimilarTo("{" +
194 " \"userCount\": " + userCount +
199 public void write_project_count_and_ncloc_and_no_stat_by_language() {
200 int projectCount = random.nextInt(8909);
201 TelemetryData data = SOME_TELEMETRY_DATA
202 .setProjectMeasuresStatistics(ProjectMeasuresStatistics.builder()
203 .setProjectCount(projectCount)
204 .setProjectCountByLanguage(Collections.emptyMap())
205 .setNclocByLanguage(Collections.emptyMap())
209 String json = writeTelemetryData(data);
211 assertJson(json).isSimilarTo("{" +
212 " \"projectCount\": " + projectCount + "," +
213 " \"projectCountByLanguage\": []," +
214 " \"nclocByLanguage\": []" +
219 public void write_project_stats_by_language() {
220 int projectCount = random.nextInt(8909);
221 Map<String, Long> countByLanguage = IntStream.range(0, 1 + random.nextInt(10))
223 .collect(MoreCollectors.uniqueIndex(i -> "P" + i, i -> 100L + i));
224 Map<String, Long> nclocByLanguage = IntStream.range(0, 1 + random.nextInt(10))
226 .collect(MoreCollectors.uniqueIndex(i -> "P" + i, i -> 1_000L + i));
227 TelemetryData data = SOME_TELEMETRY_DATA
228 .setProjectMeasuresStatistics(ProjectMeasuresStatistics.builder()
229 .setProjectCount(projectCount)
230 .setProjectCountByLanguage(countByLanguage)
231 .setNclocByLanguage(nclocByLanguage)
235 String json = writeTelemetryData(data);
237 assertJson(json).isSimilarTo("{" +
238 " \"projectCount\": " + projectCount + "," +
239 " \"projectCountByLanguage\": " +
241 countByLanguage.entrySet().stream().map(e -> "{\"language\":\"" + e.getKey() + "\",\"count\":" + e.getValue() + "}").collect(joining()) +
243 " \"nclocByLanguage\": " +
245 nclocByLanguage.entrySet().stream().map(e -> "{\"language\":\"" + e.getKey() + "\",\"ncloc\":" + e.getValue() + "}").collect(joining()) +
251 public void write_alm_count_by_alm() {
252 TelemetryData data = SOME_TELEMETRY_DATA
253 .setAlmIntegrationCountByAlm(ImmutableMap.of(
261 String json = writeTelemetryData(data);
263 assertJson(json).isSimilarTo("{" +
264 " \"almIntegrationCount\": " +
266 + "{ \"alm\":\"github\", \"count\":4},"
267 + "{ \"alm\":\"github_cloud\", \"count\":1},"
268 + "{ \"alm\":\"gitlab\", \"count\":2},"
269 + "{ \"alm\":\"gitlab_cloud\", \"count\":5},"
270 + "{ \"alm\":\"azure_devops\", \"count\":1},"
277 public void does_not_write_installation_date_if_null() {
278 TelemetryData data = SOME_TELEMETRY_DATA
279 .setInstallationDate(null)
282 String json = writeTelemetryData(data);
284 assertThat(json).doesNotContain("installationDate");
288 public void write_installation_date() {
289 long installationDate = random.nextInt(590);
290 TelemetryData data = SOME_TELEMETRY_DATA
291 .setInstallationDate(installationDate)
294 String json = writeTelemetryData(data);
296 assertJson(json).isSimilarTo("{" +
297 " \"installationDate\": " + installationDate +
302 public void does_not_write_installation_version_if_null() {
303 TelemetryData data = SOME_TELEMETRY_DATA
304 .setInstallationVersion(null)
307 String json = writeTelemetryData(data);
309 assertThat(json).doesNotContain("installationVersion");
313 public void write_installation_version() {
314 String installationVersion = randomAlphabetic(5);
315 TelemetryData data = SOME_TELEMETRY_DATA
316 .setInstallationVersion(installationVersion)
319 String json = writeTelemetryData(data);
321 assertJson(json).isSimilarTo("{" +
322 " \"installationVersion\":\"" + installationVersion + "\"" +
327 public void write_docker_flag() {
328 boolean inDocker = random.nextBoolean();
329 TelemetryData data = SOME_TELEMETRY_DATA
330 .setInDocker(inDocker)
333 String json = writeTelemetryData(data);
335 assertJson(json).isSimilarTo("{" +
336 " \"docker\":" + inDocker +
341 public void writes_has_unanalyzed_languages() {
342 TelemetryData data = SOME_TELEMETRY_DATA
343 .setHasUnanalyzedC(true)
344 .setHasUnanalyzedCpp(false)
347 String json = writeTelemetryData(data);
349 assertJson(json).isSimilarTo("{" +
350 " \"hasUnanalyzedC\":true," +
351 " \"hasUnanalyzedCpp\":false," +
356 public void writes_security_custom_config() {
357 TelemetryData data = SOME_TELEMETRY_DATA
358 .setCustomSecurityConfigs(Arrays.asList("php", "java"))
361 String json = writeTelemetryData(data);
363 assertJson(json).isSimilarTo("{" +
364 " \"customSecurityConfig\": [\"php\", \"java\"]" +
369 public static Object[][] allEditions() {
370 return Arrays.stream(EditionProvider.Edition.values())
371 .map(t -> new Object[] {t})
372 .toArray(Object[][]::new);
375 private String writeTelemetryData(TelemetryData data) {
376 StringWriter jsonString = new StringWriter();
377 try (JsonWriter json = JsonWriter.of(jsonString)) {
378 underTest.writeTelemetryData(json, data);
380 return jsonString.toString();