You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

TelemetryDataJsonWriterTest.java 23KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792
  1. /*
  2. * SonarQube
  3. * Copyright (C) 2009-2024 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. import com.tngtech.java.junit.dataprovider.DataProvider;
  22. import com.tngtech.java.junit.dataprovider.DataProviderRunner;
  23. import com.tngtech.java.junit.dataprovider.UseDataProvider;
  24. import java.io.StringWriter;
  25. import java.util.Arrays;
  26. import java.util.Collections;
  27. import java.util.List;
  28. import java.util.Locale;
  29. import java.util.Map;
  30. import java.util.Random;
  31. import java.util.Set;
  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.System2;
  39. import org.sonar.api.utils.text.JsonWriter;
  40. import org.sonar.core.platform.EditionProvider;
  41. import org.sonar.core.telemetry.TelemetryExtension;
  42. import org.sonar.db.project.CreationMethod;
  43. import org.sonar.db.user.UserTelemetryDto;
  44. import org.sonar.server.qualitygate.Condition;
  45. import static java.util.stream.Collectors.joining;
  46. import static org.apache.commons.lang3.RandomStringUtils.randomAlphabetic;
  47. import static org.assertj.core.api.Assertions.assertThat;
  48. import static org.mockito.Mockito.mock;
  49. import static org.mockito.Mockito.when;
  50. import static org.sonar.db.newcodeperiod.NewCodePeriodType.NUMBER_OF_DAYS;
  51. import static org.sonar.db.newcodeperiod.NewCodePeriodType.PREVIOUS_VERSION;
  52. import static org.sonar.server.qualitygate.Condition.Operator.fromDbValue;
  53. import static org.sonar.test.JsonAssert.assertJson;
  54. @RunWith(DataProviderRunner.class)
  55. public class TelemetryDataJsonWriterTest {
  56. private final Random random = new Random();
  57. private final TelemetryExtension extension = mock(TelemetryExtension.class);
  58. private final System2 system2 = mock(System2.class);
  59. private final TelemetryDataJsonWriter underTest = new TelemetryDataJsonWriter(List.of(extension), system2);
  60. private static final int NCD_ID = 12345;
  61. private static final TelemetryData.NewCodeDefinition NCD_INSTANCE = new TelemetryData.NewCodeDefinition(PREVIOUS_VERSION.name(), "", "instance");
  62. private static final TelemetryData.NewCodeDefinition NCD_PROJECT = new TelemetryData.NewCodeDefinition(NUMBER_OF_DAYS.name(), "30", "project");
  63. @Test
  64. public void write_server_id_version_and_sequence() {
  65. TelemetryData data = telemetryBuilder().build();
  66. String json = writeTelemetryData(data);
  67. assertJson(json).isSimilarTo("""
  68. {
  69. "id": "%s",
  70. "version": "%s",
  71. "messageSequenceNumber": %s
  72. }
  73. """.formatted(data.getServerId(), data.getVersion(), data.getMessageSequenceNumber()));
  74. }
  75. @Test
  76. public void does_not_write_edition_if_null() {
  77. TelemetryData data = telemetryBuilder().build();
  78. String json = writeTelemetryData(data);
  79. assertThat(json).doesNotContain("edition");
  80. }
  81. @Test
  82. @UseDataProvider("allEditions")
  83. public void writes_edition_if_non_null(EditionProvider.Edition edition) {
  84. TelemetryData data = telemetryBuilder()
  85. .setEdition(edition)
  86. .build();
  87. String json = writeTelemetryData(data);
  88. assertJson(json).isSimilarTo("""
  89. {
  90. "edition": "%s"
  91. }
  92. """.formatted(edition.name().toLowerCase(Locale.ENGLISH)));
  93. }
  94. @Test
  95. public void writes_default_qg() {
  96. TelemetryData data = telemetryBuilder()
  97. .setDefaultQualityGate("default-qg")
  98. .build();
  99. String json = writeTelemetryData(data);
  100. assertJson(json).isSimilarTo("""
  101. {
  102. "defaultQualityGate": "%s"
  103. }
  104. """.formatted(data.getDefaultQualityGate()));
  105. }
  106. @Test
  107. public void writes_sonarWay_qg() {
  108. TelemetryData data = telemetryBuilder()
  109. .setSonarWayQualityGate("sonarWayUUID")
  110. .build();
  111. String json = writeTelemetryData(data);
  112. assertJson(json).isSimilarTo("""
  113. {
  114. "sonarway_quality_gate_uuid": "%s"
  115. }
  116. """.formatted(data.getSonarWayQualityGate()));
  117. }
  118. @Test
  119. public void writes_database() {
  120. String name = randomAlphabetic(12);
  121. String version = randomAlphabetic(10);
  122. TelemetryData data = telemetryBuilder()
  123. .setDatabase(new TelemetryData.Database(name, version))
  124. .build();
  125. String json = writeTelemetryData(data);
  126. assertJson(json).isSimilarTo("""
  127. {
  128. "database": {
  129. "name": "%s",
  130. "version": "%s"
  131. }
  132. }
  133. """.formatted(name, version));
  134. }
  135. @Test
  136. public void writes_no_plugins() {
  137. TelemetryData data = telemetryBuilder()
  138. .setPlugins(Collections.emptyMap())
  139. .build();
  140. String json = writeTelemetryData(data);
  141. assertJson(json).isSimilarTo("""
  142. {
  143. "plugins": []
  144. }
  145. """);
  146. }
  147. @Test
  148. public void writes_all_plugins() {
  149. Map<String, String> plugins = IntStream.range(0, 1 + random.nextInt(10))
  150. .boxed()
  151. .collect(Collectors.toMap(i -> "P" + i, i1 -> "V" + i1));
  152. TelemetryData data = telemetryBuilder()
  153. .setPlugins(plugins)
  154. .build();
  155. String json = writeTelemetryData(data);
  156. assertJson(json).isSimilarTo("""
  157. {
  158. "plugins": [%s]
  159. }
  160. """.formatted(plugins.entrySet().stream().map(e -> "{\"name\":\"" + e.getKey() + "\",\"version\":\"" + e.getValue() + "\"}").collect(joining(","))));
  161. }
  162. @Test
  163. public void does_not_write_installation_date_if_null() {
  164. TelemetryData data = telemetryBuilder()
  165. .setInstallationDate(null)
  166. .build();
  167. String json = writeTelemetryData(data);
  168. assertThat(json).doesNotContain("installationDate");
  169. }
  170. @Test
  171. public void write_installation_date_in_utc_format() {
  172. TelemetryData data = telemetryBuilder()
  173. .setInstallationDate(1_000L)
  174. .build();
  175. String json = writeTelemetryData(data);
  176. assertJson(json).isSimilarTo("""
  177. {
  178. "installationDate":"1970-01-01T00:00:01+0000"
  179. }
  180. """);
  181. }
  182. @Test
  183. public void does_not_write_installation_version_if_null() {
  184. TelemetryData data = telemetryBuilder()
  185. .setInstallationVersion(null)
  186. .build();
  187. String json = writeTelemetryData(data);
  188. assertThat(json).doesNotContain("installationVersion");
  189. }
  190. @Test
  191. public void write_installation_version() {
  192. String installationVersion = randomAlphabetic(5);
  193. TelemetryData data = telemetryBuilder()
  194. .setInstallationVersion(installationVersion)
  195. .build();
  196. String json = writeTelemetryData(data);
  197. assertJson(json).isSimilarTo("""
  198. {
  199. "installationVersion": "%s"
  200. }
  201. """.formatted(installationVersion));
  202. }
  203. @Test
  204. @UseDataProvider("getFeatureFlagEnabledStates")
  205. public void write_container_flag(boolean isIncontainer) {
  206. TelemetryData data = telemetryBuilder()
  207. .setInContainer(isIncontainer)
  208. .build();
  209. String json = writeTelemetryData(data);
  210. assertJson(json).isSimilarTo("""
  211. {
  212. "container": %s
  213. }
  214. """.formatted(isIncontainer));
  215. }
  216. @DataProvider
  217. public static Object[][] getManagedInstanceData() {
  218. return new Object[][] {
  219. {true, "scim"},
  220. {true, "github"},
  221. {true, "gitlab"},
  222. {false, null},
  223. };
  224. }
  225. @Test
  226. @UseDataProvider("getManagedInstanceData")
  227. public void writeTelemetryData_encodesCorrectlyManagedInstanceInformation(boolean isManaged, String provider) {
  228. TelemetryData data = telemetryBuilder()
  229. .setManagedInstanceInformation(new TelemetryData.ManagedInstanceInformation(isManaged, provider))
  230. .build();
  231. String json = writeTelemetryData(data);
  232. if (isManaged) {
  233. assertJson(json).isSimilarTo("""
  234. {
  235. "managedInstanceInformation": {
  236. "isManaged": true,
  237. "provider": "%s"
  238. }
  239. }
  240. """.formatted(provider));
  241. } else {
  242. assertJson(json).isSimilarTo("""
  243. {
  244. "managedInstanceInformation": {
  245. "isManaged": false
  246. }
  247. }
  248. """);
  249. }
  250. }
  251. @Test
  252. public void writeTelemetryData_shouldWriteCloudUsage() {
  253. TelemetryData data = telemetryBuilder().build();
  254. String json = writeTelemetryData(data);
  255. assertJson(json).isSimilarTo("""
  256. {
  257. "cloudUsage": {
  258. "kubernetes": true,
  259. "kubernetesVersion": "1.27",
  260. "kubernetesPlatform": "linux/amd64",
  261. "kubernetesProvider": "5.4.181-99.354.amzn2.x86_64",
  262. "officialHelmChart": "10.1.0",
  263. "officialImage": false,
  264. "containerRuntime": "docker"
  265. }
  266. }
  267. """);
  268. }
  269. @Test
  270. public void writes_has_unanalyzed_languages() {
  271. TelemetryData data = telemetryBuilder()
  272. .setHasUnanalyzedC(true)
  273. .setHasUnanalyzedCpp(false)
  274. .build();
  275. String json = writeTelemetryData(data);
  276. assertJson(json).isSimilarTo("""
  277. {
  278. "hasUnanalyzedC": true,
  279. "hasUnanalyzedCpp": false,
  280. }
  281. """);
  282. }
  283. @Test
  284. public void writes_security_custom_config() {
  285. TelemetryData data = telemetryBuilder()
  286. .setCustomSecurityConfigs(Set.of("php", "java"))
  287. .build();
  288. String json = writeTelemetryData(data);
  289. assertJson(json).isSimilarTo("""
  290. {
  291. "customSecurityConfig": ["php", "java"]
  292. }
  293. """);
  294. }
  295. @Test
  296. public void writes_local_timestamp() {
  297. when(system2.now()).thenReturn(1000L);
  298. TelemetryData data = telemetryBuilder().build();
  299. String json = writeTelemetryData(data);
  300. assertJson(json).isSimilarTo("""
  301. {
  302. "localTimestamp": "1970-01-01T00:00:01+0000"
  303. }
  304. """);
  305. }
  306. @Test
  307. public void writes_all_users_with_anonymous_md5_uuids() {
  308. TelemetryData data = telemetryBuilder()
  309. .setUsers(attachUsers())
  310. .build();
  311. String json = writeTelemetryData(data);
  312. assertJson(json).isSimilarTo("""
  313. {
  314. "users": [
  315. {
  316. "userUuid": "%s",
  317. "status": "active",
  318. "identityProvider": "gitlab",
  319. "lastActivity": "1970-01-01T00:00:00+0000",
  320. "lastSonarlintActivity": "1970-01-01T00:00:00+0000",
  321. "managed": true
  322. },
  323. {
  324. "userUuid": "%s",
  325. "status": "inactive",
  326. "identityProvider": "gitlab",
  327. "lastActivity": "1970-01-01T00:00:00+0000",
  328. "lastSonarlintActivity": "1970-01-01T00:00:00+0000",
  329. "managed": false
  330. },
  331. {
  332. "userUuid": "%s",
  333. "status": "active",
  334. "identityProvider": "gitlab",
  335. "lastActivity": "1970-01-01T00:00:00+0000",
  336. "lastSonarlintActivity": "1970-01-01T00:00:00+0000",
  337. "managed": true
  338. }
  339. ]
  340. }
  341. """
  342. .formatted(DigestUtils.sha3_224Hex("uuid-0"), DigestUtils.sha3_224Hex("uuid-1"), DigestUtils.sha3_224Hex("uuid-2")));
  343. }
  344. @Test
  345. public void writes_all_projects() {
  346. TelemetryData data = telemetryBuilder()
  347. .setProjects(attachProjects())
  348. .build();
  349. String json = writeTelemetryData(data);
  350. assertJson(json).isSimilarTo("""
  351. {
  352. "projects": [
  353. {
  354. "projectUuid": "uuid-0",
  355. "lastAnalysis": "1970-01-01T00:00:00+0000",
  356. "language": "lang-0",
  357. "qualityProfile" : "qprofile-0",
  358. "loc": 2
  359. },
  360. {
  361. "projectUuid": "uuid-1",
  362. "lastAnalysis": "1970-01-01T00:00:00+0000",
  363. "language": "lang-1",
  364. "qualityProfile" : "qprofile-1",
  365. "loc": 4
  366. },
  367. {
  368. "projectUuid": "uuid-2",
  369. "lastAnalysis": "1970-01-01T00:00:00+0000",
  370. "language": "lang-2",
  371. "qualityProfile" : "qprofile-2",
  372. "loc": 6
  373. }
  374. ]
  375. }
  376. """);
  377. }
  378. @Test
  379. public void writeTelemetryData_whenAnalyzedLanguages_shouldwriteAllProjectsStats() {
  380. TelemetryData data = telemetryBuilder()
  381. .setProjectStatistics(attachProjectStatsWithMetrics())
  382. .build();
  383. String json = writeTelemetryData(data);
  384. assertJson(json).isSimilarTo("""
  385. {
  386. "projects-general-stats": [
  387. {
  388. "projectUuid": "uuid-0",
  389. "branchCount": 2,
  390. "pullRequestCount": 2,
  391. "qualityGate": "qg-0",
  392. "scm": "scm-0",
  393. "ci": "ci-0",
  394. "devopsPlatform": "devops-0",
  395. "bugs": 2,
  396. "vulnerabilities": 3,
  397. "securityHotspots": 4,
  398. "technicalDebt": 60,
  399. "developmentCost": 30,
  400. "ncdId": 12345,
  401. "externalSecurityReportExportedAt": 1500000,
  402. "project_creation_method": "LOCAL_API",
  403. "monorepo": true
  404. },
  405. {
  406. "projectUuid": "uuid-1",
  407. "branchCount": 4,
  408. "pullRequestCount": 4,
  409. "qualityGate": "qg-1",
  410. "scm": "scm-1",
  411. "ci": "ci-1",
  412. "devopsPlatform": "devops-1",
  413. "bugs": 4,
  414. "vulnerabilities": 6,
  415. "securityHotspots": 8,
  416. "technicalDebt": 120,
  417. "developmentCost": 60,
  418. "ncdId": 12345,
  419. "externalSecurityReportExportedAt": 1500001,
  420. "project_creation_method": "LOCAL_API",
  421. "monorepo": false
  422. },
  423. {
  424. "projectUuid": "uuid-2",
  425. "branchCount": 6,
  426. "pullRequestCount": 6,
  427. "qualityGate": "qg-2",
  428. "scm": "scm-2",
  429. "ci": "ci-2",
  430. "devopsPlatform": "devops-2",
  431. "bugs": 6,
  432. "vulnerabilities": 9,
  433. "securityHotspots": 12,
  434. "technicalDebt": 180,
  435. "developmentCost": 90,
  436. "ncdId": 12345,
  437. "externalSecurityReportExportedAt": 1500002,
  438. "project_creation_method": "LOCAL_API",
  439. "monorepo": true
  440. }
  441. ]
  442. }
  443. """);
  444. }
  445. @Test
  446. public void writes_all_projects_stats_with_unanalyzed_languages() {
  447. TelemetryData data = telemetryBuilder()
  448. .setProjectStatistics(attachProjectStats())
  449. .build();
  450. String json = writeTelemetryData(data);
  451. assertThat(json).doesNotContain("hasUnanalyzedC", "hasUnanalyzedCpp");
  452. }
  453. @Test
  454. public void writes_all_projects_stats_without_missing_metrics() {
  455. TelemetryData data = telemetryBuilder()
  456. .setProjectStatistics(attachProjectStats())
  457. .build();
  458. String json = writeTelemetryData(data);
  459. assertThat(json).doesNotContain("bugs", "vulnerabilities", "securityHotspots", "technicalDebt", "developmentCost");
  460. }
  461. @Test
  462. public void writes_all_quality_gates() {
  463. TelemetryData data = telemetryBuilder()
  464. .setQualityGates(attachQualityGates())
  465. .build();
  466. String json = writeTelemetryData(data);
  467. assertJson(json).isSimilarTo("""
  468. {
  469. "quality-gates": [
  470. {
  471. "uuid": "uuid-0",
  472. "caycStatus": "non-compliant",
  473. "conditions": [
  474. {
  475. "metric": "new_coverage",
  476. "comparison_operator": "LT",
  477. "error_value": "80"
  478. },
  479. {
  480. "metric": "new_duplicated_lines_density",
  481. "comparison_operator": "GT",
  482. "error_value": "3"
  483. }
  484. ]
  485. },
  486. {
  487. "uuid": "uuid-1",
  488. "caycStatus": "compliant",
  489. "conditions": [
  490. {
  491. "metric": "new_coverage",
  492. "comparison_operator": "LT",
  493. "error_value": "80"
  494. },
  495. {
  496. "metric": "new_duplicated_lines_density",
  497. "comparison_operator": "GT",
  498. "error_value": "3"
  499. }
  500. ]
  501. },
  502. {
  503. "uuid": "uuid-2",
  504. "caycStatus": "over-compliant",
  505. "conditions": [
  506. {
  507. "metric": "new_coverage",
  508. "comparison_operator": "LT",
  509. "error_value": "80"
  510. },
  511. {
  512. "metric": "new_duplicated_lines_density",
  513. "comparison_operator": "GT",
  514. "error_value": "3"
  515. }
  516. ]
  517. }
  518. ]
  519. }
  520. """);
  521. }
  522. @Test
  523. public void writeTelemetryData_shouldWriteQualityProfiles() {
  524. TelemetryData data = telemetryBuilder()
  525. .setQualityProfiles(List.of(
  526. new TelemetryData.QualityProfile("uuid-1", "parent-uuid-1", "js", true, false, true, 2, 3, 4),
  527. new TelemetryData.QualityProfile("uuid-1", null, "js", false, true, null, null, null, null)))
  528. .build();
  529. String json = writeTelemetryData(data);
  530. assertJson(json).isSimilarTo("""
  531. {
  532. "quality-profiles": [
  533. {
  534. "uuid": "uuid-1",
  535. "parentUuid": "parent-uuid-1",
  536. "language": "js",
  537. "default": true,
  538. "builtIn": false,
  539. "builtInParent": true,
  540. "rulesOverriddenCount": 2,
  541. "rulesActivatedCount": 3,
  542. "rulesDeactivatedCount": 4
  543. },
  544. {
  545. "uuid": "uuid-1",
  546. "language": "js",
  547. "default": false,
  548. "builtIn": true
  549. }
  550. ]}
  551. """);
  552. }
  553. @Test
  554. public void writes_all_branches() {
  555. TelemetryData data = telemetryBuilder()
  556. .setBranches(attachBranches())
  557. .build();
  558. String json = writeTelemetryData(data);
  559. assertJson(json).isSimilarTo("""
  560. {
  561. "branches": [
  562. {
  563. "projectUuid": "projectUuid1",
  564. "branchUuid": "branchUuid1",
  565. "ncdId": 12345,
  566. "greenQualityGateCount": 1,
  567. "analysisCount": 2,
  568. "excludeFromPurge": true
  569. },
  570. {
  571. "projectUuid": "projectUuid2",
  572. "branchUuid": "branchUuid2",
  573. "ncdId": 12345,
  574. "greenQualityGateCount": 0,
  575. "analysisCount": 2,
  576. "excludeFromPurge": true
  577. }
  578. ]
  579. }
  580. """);
  581. }
  582. @Test
  583. public void writes_new_code_definitions() {
  584. TelemetryData data = telemetryBuilder()
  585. .setNewCodeDefinitions(attachNewCodeDefinitions())
  586. .build();
  587. String json = writeTelemetryData(data);
  588. assertJson(json).isSimilarTo("""
  589. {
  590. "new-code-definitions": [
  591. {
  592. "ncdId": %s,
  593. "type": "%s",
  594. "value": "%s",
  595. "scope": "%s"
  596. },
  597. {
  598. "ncdId": %s,
  599. "type": "%s",
  600. "value": "%s",
  601. "scope": "%s"
  602. },
  603. ]
  604. }
  605. """.formatted(NCD_INSTANCE.hashCode(), NCD_INSTANCE.type(), NCD_INSTANCE.value(), NCD_INSTANCE.scope(), NCD_PROJECT.hashCode(),
  606. NCD_PROJECT.type(), NCD_PROJECT.value(), NCD_PROJECT.scope()));
  607. }
  608. @Test
  609. public void writes_instance_new_code_definition() {
  610. TelemetryData data = telemetryBuilder().build();
  611. String json = writeTelemetryData(data);
  612. assertThat(json).contains("ncdId");
  613. }
  614. private static TelemetryData.Builder telemetryBuilder() {
  615. return TelemetryData.builder()
  616. .setServerId("foo")
  617. .setVersion("bar")
  618. .setMessageSequenceNumber(1L)
  619. .setPlugins(Collections.emptyMap())
  620. .setManagedInstanceInformation(new TelemetryData.ManagedInstanceInformation(false, null))
  621. .setCloudUsage(new TelemetryData.CloudUsage(true, "1.27", "linux/amd64", "5.4.181-99.354.amzn2.x86_64", "10.1.0", "docker", false))
  622. .setDatabase(new TelemetryData.Database("H2", "11"))
  623. .setNcdId(NCD_ID);
  624. }
  625. @NotNull
  626. private static List<UserTelemetryDto> attachUsers() {
  627. return IntStream.range(0, 3)
  628. .mapToObj(
  629. i -> new UserTelemetryDto().setUuid("uuid-" + i).setActive(i % 2 == 0).setLastConnectionDate(1L)
  630. .setLastSonarlintConnectionDate(2L).setExternalIdentityProvider("gitlab").setScimUuid(i % 2 == 0 ? "scim-uuid-" + i : null))
  631. .toList();
  632. }
  633. private static List<TelemetryData.Project> attachProjects() {
  634. return IntStream.range(0, 3).mapToObj(i -> new TelemetryData.Project("uuid-" + i, 1L, "lang-" + i, "qprofile-" + i, (i + 1L) * 2)).toList();
  635. }
  636. private static List<TelemetryData.ProjectStatistics> attachProjectStatsWithMetrics() {
  637. return IntStream.range(0, 3).mapToObj(i -> getProjectStatisticsWithMetricBuilder(i).build()).toList();
  638. }
  639. private static List<TelemetryData.ProjectStatistics> attachProjectStats() {
  640. return IntStream.range(0, 3).mapToObj(i -> getProjectStatisticsBuilder(i).build()).toList();
  641. }
  642. private static TelemetryData.ProjectStatistics.Builder getProjectStatisticsBuilder(int i) {
  643. return new TelemetryData.ProjectStatistics.Builder()
  644. .setProjectUuid("uuid-" + i)
  645. .setBranchCount((i + 1L) * 2L)
  646. .setPRCount((i + 1L) * 2L)
  647. .setQG("qg-" + i).setCi("ci-" + i)
  648. .setScm("scm-" + i)
  649. .setDevops("devops-" + i)
  650. .setNcdId(NCD_ID)
  651. .setCreationMethod(CreationMethod.LOCAL_API)
  652. .setMonorepo(false);
  653. }
  654. private static TelemetryData.ProjectStatistics.Builder getProjectStatisticsWithMetricBuilder(int i) {
  655. return getProjectStatisticsBuilder(i)
  656. .setBugs((i + 1L) * 2)
  657. .setVulnerabilities((i + 1L) * 3)
  658. .setSecurityHotspots((i + 1L) * 4)
  659. .setDevelopmentCost((i + 1L) * 30d)
  660. .setTechnicalDebt((i + 1L) * 60d)
  661. .setExternalSecurityReportExportedAt(1_500_000L + i)
  662. .setCreationMethod(CreationMethod.LOCAL_API)
  663. .setMonorepo(i % 2 == 0);
  664. }
  665. private List<TelemetryData.QualityGate> attachQualityGates() {
  666. List<Condition> qualityGateConditions = attachQualityGateConditions();
  667. return List.of(new TelemetryData.QualityGate("uuid-0", "non-compliant", qualityGateConditions),
  668. new TelemetryData.QualityGate("uuid-1", "compliant", qualityGateConditions),
  669. new TelemetryData.QualityGate("uuid-2", "over-compliant", qualityGateConditions));
  670. }
  671. private List<Condition> attachQualityGateConditions() {
  672. return List.of(new Condition("new_coverage", fromDbValue("LT"), "80"),
  673. new Condition("new_duplicated_lines_density", fromDbValue("GT"), "3"));
  674. }
  675. private List<TelemetryData.Branch> attachBranches() {
  676. return List.of(new TelemetryData.Branch("projectUuid1", "branchUuid1", NCD_ID, 1, 2, true),
  677. new TelemetryData.Branch("projectUuid2", "branchUuid2", NCD_ID, 0, 2, true));
  678. }
  679. private List<TelemetryData.NewCodeDefinition> attachNewCodeDefinitions() {
  680. return List.of(NCD_INSTANCE, NCD_PROJECT);
  681. }
  682. @DataProvider
  683. public static Object[][] allEditions() {
  684. return Arrays.stream(EditionProvider.Edition.values())
  685. .map(t -> new Object[] {t})
  686. .toArray(Object[][]::new);
  687. }
  688. private String writeTelemetryData(TelemetryData data) {
  689. StringWriter jsonString = new StringWriter();
  690. try (JsonWriter json = JsonWriter.of(jsonString)) {
  691. underTest.writeTelemetryData(json, data);
  692. }
  693. return jsonString.toString();
  694. }
  695. @DataProvider
  696. public static Set<Boolean> getFeatureFlagEnabledStates() {
  697. return Set.of(true, false);
  698. }
  699. }