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