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