]> source.dussan.org Git - sonarqube.git/blob
b777f7f5cc89a77f417c1f7b531a093f6e8eb098
[sonarqube.git] /
1 /*
2  * SonarQube
3  * Copyright (C) 2009-2022 SonarSource SA
4  * mailto:info AT sonarsource DOT com
5  *
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.
10  *
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.
15  *
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.
19  */
20 package org.sonar.server.telemetry;
21
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;
30 import java.util.Map;
31 import java.util.Random;
32 import java.util.stream.Collectors;
33 import java.util.stream.IntStream;
34 import org.apache.commons.codec.digest.DigestUtils;
35 import org.jetbrains.annotations.NotNull;
36 import org.junit.Test;
37 import org.junit.runner.RunWith;
38 import org.sonar.api.utils.text.JsonWriter;
39 import org.sonar.core.platform.EditionProvider;
40 import org.sonar.core.util.stream.MoreCollectors;
41 import org.sonar.db.user.UserTelemetryDto;
42
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;
47
48 @RunWith(DataProviderRunner.class)
49 public class TelemetryDataJsonWriterTest {
50
51   private final Random random = new Random();
52
53   private final TelemetryDataJsonWriter underTest = new TelemetryDataJsonWriter();
54
55   @Test
56   public void write_server_id_and_version() {
57     TelemetryData data = telemetryBuilder().build();
58
59     String json = writeTelemetryData(data);
60
61     assertJson(json).isSimilarTo("{" +
62       "  \"id\": \"" + data.getServerId() + "\"," +
63       "  \"version\": \"" + data.getVersion() + "\"" +
64       "}");
65   }
66
67   @Test
68   public void does_not_write_edition_if_null() {
69     TelemetryData data = telemetryBuilder().build();
70
71     String json = writeTelemetryData(data);
72
73     assertThat(json).doesNotContain("edition");
74   }
75
76   @Test
77   @UseDataProvider("allEditions")
78   public void writes_edition_if_non_null(EditionProvider.Edition edition) {
79     TelemetryData data = telemetryBuilder()
80       .setEdition(edition)
81       .build();
82
83     String json = writeTelemetryData(data);
84
85     assertJson(json).isSimilarTo("{" +
86       "  \"edition\": \"" + edition.name().toLowerCase(Locale.ENGLISH) + "\"" +
87       "}");
88   }
89
90   @Test
91   public void does_not_write_license_type_if_null() {
92     TelemetryData data = telemetryBuilder().build();
93
94     String json = writeTelemetryData(data);
95
96     assertThat(json).doesNotContain("licenseType");
97   }
98
99   @Test
100   public void writes_licenseType_if_non_null() {
101     String expected = randomAlphabetic(12);
102     TelemetryData data = telemetryBuilder()
103       .setLicenseType(expected)
104       .build();
105
106     String json = writeTelemetryData(data);
107
108     assertJson(json).isSimilarTo("{" +
109       "  \"licenseType\": \"" + expected + "\"" +
110       "}");
111   }
112
113   @Test
114   public void writes_database() {
115     String name = randomAlphabetic(12);
116     String version = randomAlphabetic(10);
117     TelemetryData data = telemetryBuilder()
118       .setDatabase(new TelemetryData.Database(name, version))
119       .build();
120
121     String json = writeTelemetryData(data);
122
123     assertJson(json).isSimilarTo("{" +
124       "  \"database\": {" +
125       "    \"name\": \"" + name + "\"," +
126       "    \"version\": \"" + version + "\"" +
127       "  }" +
128       "}");
129   }
130
131   @Test
132   public void writes_no_plugins() {
133     TelemetryData data = telemetryBuilder()
134       .setPlugins(Collections.emptyMap())
135       .build();
136
137     String json = writeTelemetryData(data);
138
139     assertJson(json).isSimilarTo("{" +
140       "  \"plugins\": []" +
141       "}");
142   }
143
144   @Test
145   public void writes_all_plugins() {
146     Map<String, String> plugins = IntStream.range(0, 1 + random.nextInt(10))
147       .boxed()
148       .collect(MoreCollectors.uniqueIndex(i -> "P" + i, i -> "V" + i));
149     TelemetryData data = telemetryBuilder()
150       .setPlugins(plugins)
151       .build();
152
153     String json = writeTelemetryData(data);
154
155     assertJson(json).isSimilarTo("{" +
156       "  \"plugins\": " +
157       "[" +
158       plugins.entrySet().stream().map(e -> "{\"name\":\"" + e.getKey() + "\",\"version\":\"" + e.getValue() + "\"}").collect(joining(",")) +
159       "]" +
160       "}");
161   }
162
163   @Test
164   public void does_not_write_installation_date_if_null() {
165     TelemetryData data = telemetryBuilder()
166       .setInstallationDate(null)
167       .build();
168
169     String json = writeTelemetryData(data);
170
171     assertThat(json).doesNotContain("installationDate");
172   }
173
174   @Test
175   public void write_installation_date_in_utc_format() {
176     TelemetryData data = telemetryBuilder()
177       .setInstallationDate(1_000L)
178       .build();
179
180     String json = writeTelemetryData(data);
181
182     assertJson(json).isSimilarTo("{" +
183       "  \"installationDate\":\"1970-01-01T00:00:01+0000\"," +
184       "}");
185   }
186
187   @Test
188   public void does_not_write_installation_version_if_null() {
189     TelemetryData data = telemetryBuilder()
190       .setInstallationVersion(null)
191       .build();
192
193     String json = writeTelemetryData(data);
194
195     assertThat(json).doesNotContain("installationVersion");
196   }
197
198   @Test
199   public void write_installation_version() {
200     String installationVersion = randomAlphabetic(5);
201     TelemetryData data = telemetryBuilder()
202       .setInstallationVersion(installationVersion)
203       .build();
204
205     String json = writeTelemetryData(data);
206
207     assertJson(json).isSimilarTo("{" +
208       "  \"installationVersion\":\"" + installationVersion + "\"" +
209       "}");
210   }
211
212   @Test
213   public void write_docker_flag() {
214     boolean inDocker = random.nextBoolean();
215     TelemetryData data = telemetryBuilder()
216       .setInDocker(inDocker)
217       .build();
218
219     String json = writeTelemetryData(data);
220
221     assertJson(json).isSimilarTo("{" +
222       "  \"docker\":" + inDocker +
223       "}");
224   }
225
226   @Test
227   public void writes_security_custom_config() {
228     TelemetryData data = telemetryBuilder()
229       .setCustomSecurityConfigs(Arrays.asList("php", "java"))
230       .build();
231
232     String json = writeTelemetryData(data);
233
234     assertJson(json).isSimilarTo("{" +
235       "  \"customSecurityConfig\": [\"php\", \"java\"]" +
236       "}");
237   }
238
239   @Test
240   public void writes_all_users_with_anonymous_md5_uuids() {
241     TelemetryData data = telemetryBuilder()
242       .setUsers(attachUsers())
243       .build();
244
245     String json = writeTelemetryData(data);
246
247     assertJson(json).isSimilarTo("{" +
248       "  \"users\": [" +
249       "    {" +
250       "      \"userUuid\":\"" + DigestUtils.sha3_224Hex("uuid-0") + "\"," +
251       "      \"lastActivity\":\"1970-01-01T00:00:00+0000\"," +
252       "      \"identityProvider\":\"gitlab\"," +
253       "      \"lastSonarlintActivity\":\"1970-01-01T00:00:00+0000\"," +
254       "      \"status\":\"active\"" +
255       "    }," +
256       "    {" +
257       "      \"userUuid\":\"" + DigestUtils.sha3_224Hex("uuid-1") + "\"," +
258       "      \"lastActivity\":\"1970-01-01T00:00:00+0000\"," +
259       "      \"identityProvider\":\"gitlab\"," +
260       "      \"lastSonarlintActivity\":\"1970-01-01T00:00:00+0000\"," +
261       "      \"status\":\"inactive\"" +
262       "    }," +
263       "    {" +
264       "      \"userUuid\":\"" + DigestUtils.sha3_224Hex("uuid-2") + "\"," +
265       "      \"lastActivity\":\"1970-01-01T00:00:00+0000\"," +
266       "      \"identityProvider\":\"gitlab\"," +
267       "      \"lastSonarlintActivity\":\"1970-01-01T00:00:00+0000\"," +
268       "      \"status\":\"active\"" +
269       "    }" +
270       "  ]" +
271       "}");
272   }
273
274   @Test
275   public void writes_all_projects() {
276     TelemetryData data = telemetryBuilder()
277       .setProjects(attachProjects())
278       .build();
279
280     String json = writeTelemetryData(data);
281
282     assertJson(json).isSimilarTo("{" +
283       "  \"projects\": [" +
284       "    {" +
285       "      \"projectUuid\": \"uuid-0\"," +
286       "      \"lastAnalysis\":\"1970-01-01T00:00:00+0000\"," +
287       "      \"language\": \"lang-0\"," +
288       "      \"loc\": 2" +
289       "    }," +
290       "    {" +
291       "      \"projectUuid\": \"uuid-1\"," +
292       "      \"lastAnalysis\":\"1970-01-01T00:00:00+0000\"," +
293       "      \"language\": \"lang-1\"," +
294       "      \"loc\": 4" +
295       "    }," +
296       "    {" +
297       "      \"projectUuid\": \"uuid-2\"," +
298       "      \"lastAnalysis\":\"1970-01-01T00:00:00+0000\"," +
299       "      \"language\": \"lang-2\"," +
300       "      \"loc\": 6" +
301       "    }" +
302       "  ]" +
303       "}");
304   }
305
306   @Test
307   public void writes_all_projects_stats_with_analyzed_languages() {
308     TelemetryData data = telemetryBuilder()
309       .setProjectStatistics(attachProjectStats(true))
310       .build();
311
312     String json = writeTelemetryData(data);
313
314     assertJson(json).isSimilarTo("{" +
315       "  \"projects-general-stats\": [" +
316       "    {" +
317       "      \"projectUuid\": \"uuid-0\"," +
318       "      \"branchCount\": 2," +
319       "      \"pullRequestCount\": 2," +
320       "      \"scm\": \"scm-0\"," +
321       "      \"ci\": \"ci-0\"," +
322       "      \"devopsPlatform\": \"devops-0\"," +
323       "      \"hasUnanalyzedC\": true," +
324       "      \"hasUnanalyzedCpp\": false" +
325       "    }," +
326       "    {" +
327       "      \"projectUuid\": \"uuid-1\"," +
328       "      \"branchCount\": 4," +
329       "      \"pullRequestCount\": 4," +
330       "      \"scm\": \"scm-1\"," +
331       "      \"ci\": \"ci-1\"," +
332       "      \"devopsPlatform\": \"devops-1\"," +
333       "      \"hasUnanalyzedC\": false," +
334       "      \"hasUnanalyzedCpp\": true" +
335       "    }," +
336       "    {" +
337       "      \"projectUuid\": \"uuid-2\"," +
338       "      \"branchCount\": 6," +
339       "      \"pullRequestCount\": 6," +
340       "      \"scm\": \"scm-2\"," +
341       "      \"ci\": \"ci-2\"," +
342       "      \"devopsPlatform\": \"devops-2\"," +
343       "      \"hasUnanalyzedC\": true," +
344       "      \"hasUnanalyzedCpp\": false" +
345       "    }" +
346       "  ]" +
347       "}");
348   }
349
350   @Test
351   public void writes_all_projects_stats_with_unanalyzed_languages() {
352     TelemetryData data = telemetryBuilder()
353       .setProjectStatistics(attachProjectStats(false))
354       .build();
355
356     String json = writeTelemetryData(data);
357     assertThat(json).doesNotContain("hasUnanalyzedC", "hasUnanalyzedCpp");
358   }
359
360   private static TelemetryData.Builder telemetryBuilder() {
361     return TelemetryData.builder()
362       .setServerId("foo")
363       .setVersion("bar")
364       .setPlugins(Collections.emptyMap())
365       .setDatabase(new TelemetryData.Database("H2", "11"));
366   }
367
368   @NotNull
369   private static List<UserTelemetryDto> attachUsers() {
370     return IntStream.range(0, 3)
371       .mapToObj(
372         i -> new UserTelemetryDto().setUuid("uuid-" + i).setActive(i % 2 == 0).setLastConnectionDate(1L).setLastSonarlintConnectionDate(2L).setExternalIdentityProvider("gitlab"))
373       .collect(Collectors.toList());
374   }
375
376   private static List<TelemetryData.Project> attachProjects() {
377     return IntStream.range(0, 3).mapToObj(i -> new TelemetryData.Project("uuid-" + i, 1L, "lang-" + i, (i + 1L) * 2L)).collect(Collectors.toList());
378   }
379
380   private List<TelemetryData.ProjectStatistics> attachProjectStats(boolean hasUnanalyzedLanguages) {
381     return IntStream.range(0, 3).mapToObj(i -> new TelemetryData.ProjectStatistics("uuid-" + i, (i + 1L) * 2L, (i + 1L) * 2L, hasUnanalyzedLanguages ? i % 2 == 0 : null, hasUnanalyzedLanguages ? i % 2 != 0 : null, "scm-" + i, "ci-" + i, "devops-" + i))
382       .collect(Collectors.toList());
383   }
384
385   @DataProvider
386   public static Object[][] allEditions() {
387     return Arrays.stream(EditionProvider.Edition.values())
388       .map(t -> new Object[] {t})
389       .toArray(Object[][]::new);
390   }
391
392   private String writeTelemetryData(TelemetryData data) {
393     StringWriter jsonString = new StringWriter();
394     try (JsonWriter json = JsonWriter.of(jsonString)) {
395       underTest.writeTelemetryData(json, data);
396     }
397     return jsonString.toString();
398   }
399 }