3 * Copyright (C) 2009-2022 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.tngtech.java.junit.dataprovider.DataProvider;
23 import com.tngtech.java.junit.dataprovider.DataProviderRunner;
24 import com.tngtech.java.junit.dataprovider.UseDataProvider;
25 import java.io.StringWriter;
26 import java.util.Arrays;
27 import java.util.Collections;
28 import java.util.List;
29 import java.util.Locale;
31 import java.util.Random;
32 import java.util.stream.Collectors;
33 import java.util.stream.IntStream;
34 import org.jetbrains.annotations.NotNull;
35 import org.junit.Test;
36 import org.junit.runner.RunWith;
37 import org.sonar.api.utils.text.JsonWriter;
38 import org.sonar.core.platform.EditionProvider;
39 import org.sonar.core.util.stream.MoreCollectors;
40 import org.sonar.db.user.UserTelemetryDto;
42 import static java.util.Arrays.asList;
43 import static java.util.stream.Collectors.joining;
44 import static org.apache.commons.lang.RandomStringUtils.randomAlphabetic;
45 import static org.assertj.core.api.Assertions.assertThat;
46 import static org.sonar.test.JsonAssert.assertJson;
48 @RunWith(DataProviderRunner.class)
49 public class TelemetryDataJsonWriterTest {
51 private static final TelemetryData.Builder SOME_TELEMETRY_DATA = TelemetryData.builder()
54 .setPlugins(Collections.emptyMap())
55 .setExternalAuthenticationProviders(asList("github", "gitlab"))
56 .setDatabase(new TelemetryData.Database("H2", "11"));
58 private final Random random = new Random();
60 private final TelemetryDataJsonWriter underTest = new TelemetryDataJsonWriter();
63 public void write_server_id_and_version() {
64 TelemetryData data = SOME_TELEMETRY_DATA.build();
66 String json = writeTelemetryData(data);
68 assertJson(json).isSimilarTo("{" +
69 " \"id\": \"" + data.getServerId() + "\"," +
70 " \"version\": \"" + data.getVersion() + "\"" +
75 public void does_not_write_edition_if_null() {
76 TelemetryData data = SOME_TELEMETRY_DATA.build();
78 String json = writeTelemetryData(data);
80 assertThat(json).doesNotContain("edition");
84 public void write_external_auth_providers() {
85 TelemetryData data = SOME_TELEMETRY_DATA.build();
87 String json = writeTelemetryData(data);
89 assertJson(json).isSimilarTo("{ \"externalAuthProviders\": [ \"github\", \"gitlab\" ] }");
93 @UseDataProvider("allEditions")
94 public void writes_edition_if_non_null(EditionProvider.Edition edition) {
95 TelemetryData data = SOME_TELEMETRY_DATA
99 String json = writeTelemetryData(data);
101 assertJson(json).isSimilarTo("{" +
102 " \"edition\": \"" + edition.name().toLowerCase(Locale.ENGLISH) + "\"" +
107 public void does_not_write_license_type_if_null() {
108 TelemetryData data = SOME_TELEMETRY_DATA.build();
110 String json = writeTelemetryData(data);
112 assertThat(json).doesNotContain("licenseType");
116 public void writes_licenseType_if_non_null() {
117 String expected = randomAlphabetic(12);
118 TelemetryData data = SOME_TELEMETRY_DATA
119 .setLicenseType(expected)
122 String json = writeTelemetryData(data);
124 assertJson(json).isSimilarTo("{" +
125 " \"licenseType\": \"" + expected + "\"" +
130 public void writes_database() {
131 String name = randomAlphabetic(12);
132 String version = randomAlphabetic(10);
133 TelemetryData data = SOME_TELEMETRY_DATA
134 .setDatabase(new TelemetryData.Database(name, version))
137 String json = writeTelemetryData(data);
139 assertJson(json).isSimilarTo("{" +
141 " \"name\": \"" + name + "\"," +
142 " \"version\": \"" + version + "\"" +
148 public void writes_no_plugins() {
149 TelemetryData data = SOME_TELEMETRY_DATA
150 .setPlugins(Collections.emptyMap())
153 String json = writeTelemetryData(data);
155 assertJson(json).isSimilarTo("{" +
161 public void writes_all_plugins() {
162 Map<String, String> plugins = IntStream.range(0, 1 + random.nextInt(10))
164 .collect(MoreCollectors.uniqueIndex(i -> "P" + i, i -> "V" + i));
165 TelemetryData data = SOME_TELEMETRY_DATA
169 String json = writeTelemetryData(data);
171 assertJson(json).isSimilarTo("{" +
174 plugins.entrySet().stream().map(e -> "{\"name\":\"" + e.getKey() + "\",\"version\":\"" + e.getValue() + "\"}").collect(joining(",")) +
180 public void does_not_write_installation_date_if_null() {
181 TelemetryData data = SOME_TELEMETRY_DATA
182 .setInstallationDate(null)
185 String json = writeTelemetryData(data);
187 assertThat(json).doesNotContain("installationDate");
191 public void write_installation_date() {
192 long installationDate = random.nextInt(590);
193 TelemetryData data = SOME_TELEMETRY_DATA
194 .setInstallationDate(installationDate)
197 String json = writeTelemetryData(data);
199 assertJson(json).isSimilarTo("{" +
200 " \"installationDate\": " + installationDate +
205 public void does_not_write_installation_version_if_null() {
206 TelemetryData data = SOME_TELEMETRY_DATA
207 .setInstallationVersion(null)
210 String json = writeTelemetryData(data);
212 assertThat(json).doesNotContain("installationVersion");
216 public void write_installation_version() {
217 String installationVersion = randomAlphabetic(5);
218 TelemetryData data = SOME_TELEMETRY_DATA
219 .setInstallationVersion(installationVersion)
222 String json = writeTelemetryData(data);
224 assertJson(json).isSimilarTo("{" +
225 " \"installationVersion\":\"" + installationVersion + "\"" +
230 public void write_docker_flag() {
231 boolean inDocker = random.nextBoolean();
232 TelemetryData data = SOME_TELEMETRY_DATA
233 .setInDocker(inDocker)
236 String json = writeTelemetryData(data);
238 assertJson(json).isSimilarTo("{" +
239 " \"docker\":" + inDocker +
244 public void writes_has_unanalyzed_languages() {
245 TelemetryData data = SOME_TELEMETRY_DATA
246 .setHasUnanalyzedC(true)
247 .setHasUnanalyzedCpp(false)
250 String json = writeTelemetryData(data);
252 assertJson(json).isSimilarTo("{" +
253 " \"hasUnanalyzedC\":true," +
254 " \"hasUnanalyzedCpp\":false," +
259 public void writes_security_custom_config() {
260 TelemetryData data = SOME_TELEMETRY_DATA
261 .setCustomSecurityConfigs(Arrays.asList("php", "java"))
264 String json = writeTelemetryData(data);
266 assertJson(json).isSimilarTo("{" +
267 " \"customSecurityConfig\": [\"php\", \"java\"]" +
272 public void writes_all_users() {
273 TelemetryData data = SOME_TELEMETRY_DATA
274 .setUsers(getUsers())
277 String json = writeTelemetryData(data);
279 assertJson(json).isSimilarTo("{" +
282 " \"userUuid\":\"uuid-0\"," +
283 " \"lastActivity\":\"1970-01-01T00:00:00+0000\"," +
284 " \"lastSonarlintActivity\":\"1970-01-01T00:00:00+0000\"," +
285 " \"status\":\"active\"" +
288 " \"userUuid\":\"uuid-1\"," +
289 " \"lastActivity\":\"1970-01-01T00:00:00+0000\"," +
290 " \"lastSonarlintActivity\":\"1970-01-01T00:00:00+0000\"," +
291 " \"status\":\"inactive\"" +
294 " \"userUuid\":\"uuid-2\"," +
295 " \"lastActivity\":\"1970-01-01T01:00:00+0100\"," +
296 " \"lastSonarlintActivity\":\"1970-01-01T00:00:00+0000\"," +
297 " \"status\":\"active\"" +
304 public void writes_all_projects() {
305 TelemetryData data = SOME_TELEMETRY_DATA
306 .setProjects(getProjects())
309 String json = writeTelemetryData(data);
311 assertJson(json).isSimilarTo("{" +
314 " \"projectUuid\": \"uuid-0\"," +
315 " \"language\": \"lang-0\"," +
316 " \"lastAnalysis\":\"1970-01-01T00:00:00+0000\"," +
320 " \"projectUuid\": \"uuid-1\"," +
321 " \"language\": \"lang-1\"," +
322 " \"lastAnalysis\":\"1970-01-01T00:00:00+0000\"," +
326 " \"projectUuid\": \"uuid-2\"," +
327 " \"language\": \"lang-2\"," +
328 " \"lastAnalysis\":\"1970-01-01T00:00:00+0000\"," +
336 public void writes_all_projects_stats() {
337 TelemetryData data = SOME_TELEMETRY_DATA
338 .setProjectStatistics(getProjectStats())
341 String json = writeTelemetryData(data);
343 assertJson(json).isSimilarTo("{" +
344 " \"projects-general-stats\": [" +
346 " \"projectUuid\": \"uuid-0\"," +
347 " \"branchCount\": 2," +
348 " \"pullRequestCount\": 2," +
349 " \"scm\": \"scm-0\"," +
350 " \"ci\": \"ci-0\"," +
351 " \"alm\": \"alm-0\"" +
354 " \"projectUuid\": \"uuid-1\"," +
355 " \"branchCount\": 4," +
356 " \"pullRequestCount\": 4," +
357 " \"scm\": \"scm-1\"," +
358 " \"ci\": \"ci-1\"," +
359 " \"alm\": \"alm-1\"" +
362 " \"projectUuid\": \"uuid-2\"," +
363 " \"branchCount\": 6," +
364 " \"pullRequestCount\": 6," +
365 " \"scm\": \"scm-2\"," +
366 " \"ci\": \"ci-2\"," +
367 " \"alm\": \"alm-2\"" +
374 private static List<UserTelemetryDto> getUsers() {
375 return IntStream.range(0, 3).mapToObj(i -> new UserTelemetryDto().setUuid("uuid-" + i).setActive(i % 2 == 0).setLastConnectionDate(1L).setLastSonarlintConnectionDate(2L))
376 .collect(Collectors.toList());
379 private static List<TelemetryData.Project> getProjects() {
380 return IntStream.range(0, 3).mapToObj(i -> new TelemetryData.Project("uuid-" + i, 1L, "lang-" + i, (i + 1L) * 2L)).collect(Collectors.toList());
383 private List<TelemetryData.ProjectStatistics> getProjectStats() {
384 return IntStream.range(0, 3).mapToObj(i -> new TelemetryData.ProjectStatistics("uuid-" + i, (i + 1L) * 2L, (i + 1L) * 2L, "scm-" + i, "ci-" + i, "alm-" + i))
385 .collect(Collectors.toList());
389 public static Object[][] allEditions() {
390 return Arrays.stream(EditionProvider.Edition.values())
391 .map(t -> new Object[] {t})
392 .toArray(Object[][]::new);
395 private String writeTelemetryData(TelemetryData data) {
396 StringWriter jsonString = new StringWriter();
397 try (JsonWriter json = JsonWriter.of(jsonString)) {
398 underTest.writeTelemetryData(json, data);
400 return jsonString.toString();