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.

CleanOrphanRowsInCeTablesTest.java 7.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  1. /*
  2. * SonarQube
  3. * Copyright (C) 2009-2019 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.platform.db.migration.version.v74;
  21. import java.sql.SQLException;
  22. import java.util.Random;
  23. import java.util.stream.IntStream;
  24. import java.util.stream.Stream;
  25. import javax.annotation.Nullable;
  26. import org.junit.Rule;
  27. import org.junit.Test;
  28. import org.junit.rules.ExpectedException;
  29. import org.sonar.api.impl.config.MapSettings;
  30. import org.sonar.core.util.UuidFactoryFast;
  31. import org.sonar.db.CoreDbTester;
  32. import static org.apache.commons.lang.RandomStringUtils.randomAlphabetic;
  33. import static org.apache.commons.lang.RandomStringUtils.randomAlphanumeric;
  34. import static org.assertj.core.api.Assertions.assertThat;
  35. public class CleanOrphanRowsInCeTablesTest {
  36. @Rule
  37. public final CoreDbTester db = CoreDbTester.createForSchema(CleanOrphanRowsInCeTablesTest.class, "ce_tables.sql");
  38. @Rule
  39. public ExpectedException expectedException = ExpectedException.none();
  40. private Random random = new Random();
  41. private MapSettings settings = new MapSettings();
  42. private CleanOrphanRowsInCeTables underTest = new CleanOrphanRowsInCeTables(db.database(), settings.asConfig());
  43. @Test
  44. public void execute_has_no_effect_on_empty_tables() throws SQLException {
  45. underTest.execute();
  46. }
  47. @Test
  48. public void execute_deletes_rows_of_ce_activity_and_child_tables_which_have_main_component_equals_component_and_at_least_one_characteristic() throws SQLException {
  49. String projectUuid = randomAlphabetic(10);
  50. String branchUuid = randomAlphanumeric(11);
  51. String mainBranchTask = insertCeActivity(projectUuid, projectUuid, 0);
  52. String existingBranchTask = insertCeActivity(projectUuid, branchUuid, 1 + new Random().nextInt(10));
  53. String nonExistingBranchTask = insertCeActivity(projectUuid, projectUuid, 1 + new Random().nextInt(10));
  54. String missingTask = "missing_task";
  55. Stream.of(mainBranchTask, existingBranchTask, nonExistingBranchTask, missingTask)
  56. .forEach(taskUuid -> {
  57. insertCeTaskInput(taskUuid);
  58. insertCeScannerContext(taskUuid);
  59. });
  60. insertCeTaskCharacteristics(missingTask);
  61. underTest.execute();
  62. assertThat(uuidsOf("ce_activity")).containsOnly(mainBranchTask, existingBranchTask);
  63. assertThat(taskUuidsOf("ce_task_input")).containsOnly(mainBranchTask, existingBranchTask, missingTask);
  64. assertThat(taskUuidsOf("ce_scanner_context")).containsOnly(mainBranchTask, existingBranchTask, missingTask);
  65. assertThat(taskUuidsOf("ce_task_characteristics")).containsOnly(existingBranchTask, missingTask);
  66. }
  67. @Test
  68. public void execute_has_no_effect_on_SonarCloud() throws SQLException {
  69. String projectUuid = randomAlphabetic(10);
  70. String branchUuid = randomAlphanumeric(11);
  71. String mainBranchTask = insertCeActivity(projectUuid, projectUuid, 0);
  72. String existingBranchTask = insertCeActivity(projectUuid, branchUuid, 1 + new Random().nextInt(10));
  73. String nonExistingBranchTask = insertCeActivity(projectUuid, projectUuid, 1 + new Random().nextInt(10));
  74. String missingTask = "missing_task";
  75. Stream.of(mainBranchTask, existingBranchTask, nonExistingBranchTask, missingTask)
  76. .forEach(taskUuid -> {
  77. insertCeTaskInput(taskUuid);
  78. insertCeScannerContext(taskUuid);
  79. });
  80. insertCeTaskCharacteristics(missingTask);
  81. settings.setProperty("sonar.sonarcloud.enabled", true);
  82. underTest.execute();
  83. assertThat(uuidsOf("ce_activity")).containsOnly(mainBranchTask, existingBranchTask, nonExistingBranchTask);
  84. assertThat(taskUuidsOf("ce_task_input")).containsOnly(mainBranchTask, existingBranchTask, nonExistingBranchTask, missingTask);
  85. assertThat(taskUuidsOf("ce_scanner_context")).containsOnly(mainBranchTask, existingBranchTask, nonExistingBranchTask, missingTask);
  86. assertThat(taskUuidsOf("ce_task_characteristics")).containsOnly(existingBranchTask, nonExistingBranchTask, missingTask);
  87. }
  88. @Test
  89. public void execute_is_reentrant() throws SQLException {
  90. String projectUuid = randomAlphabetic(10);
  91. String branchUuid = randomAlphanumeric(11);
  92. String mainBranchTask = insertCeActivity(projectUuid, projectUuid, 0);
  93. String existingBranchTask = insertCeActivity(projectUuid, branchUuid, 1 + new Random().nextInt(10));
  94. String nonExistingBranchTask = insertCeActivity(projectUuid, projectUuid, 1 + new Random().nextInt(10));
  95. Stream.of(mainBranchTask, existingBranchTask, nonExistingBranchTask)
  96. .forEach(taskUuid -> {
  97. insertCeTaskInput(taskUuid);
  98. insertCeScannerContext(taskUuid);
  99. });
  100. underTest.execute();
  101. underTest.execute();
  102. }
  103. private Stream<String> taskUuidsOf(String tableName) {
  104. return db.select("select distinct task_uuid as \"TASK_UUID\" from " + tableName)
  105. .stream()
  106. .map(r -> (String) r.get("TASK_UUID"));
  107. }
  108. private Stream<String> uuidsOf(String tableName) {
  109. return db.select("select uuid as \"UUID\" from " + tableName)
  110. .stream()
  111. .map(r -> (String) r.get("UUID"));
  112. }
  113. private String insertCeActivity(@Nullable String componentUuid, @Nullable String mainComponentUuid, int numberOfCharacteristics) {
  114. String uuid = UuidFactoryFast.getInstance().create();
  115. db.executeInsert(
  116. "ce_activity",
  117. "UUID", uuid,
  118. "COMPONENT_UUID", componentUuid,
  119. "MAIN_COMPONENT_UUID", mainComponentUuid,
  120. "TASK_TYPE", randomAlphanumeric(10),
  121. "STATUS", randomAlphanumeric(10),
  122. "IS_LAST", random.nextBoolean(),
  123. "IS_LAST_KEY", randomAlphanumeric(15),
  124. "EXECUTION_COUNT", random.nextInt(99),
  125. "SUBMITTED_AT", random.nextInt(95654354),
  126. "CREATED_AT", random.nextInt(95654354),
  127. "UPDATED_AT", random.nextInt(95654354));
  128. IntStream.range(0, numberOfCharacteristics)
  129. .forEach(i -> insertCeTaskCharacteristic(uuid, i));
  130. return uuid;
  131. }
  132. private void insertCeTaskInput(String taskUuid) {
  133. db.executeInsert(
  134. "ce_task_input",
  135. "TASK_UUID", taskUuid,
  136. "INPUT_DATA", randomAlphanumeric(123).getBytes(),
  137. "CREATED_AT", random.nextInt(95654354),
  138. "UPDATED_AT", random.nextInt(95654354));
  139. }
  140. private void insertCeScannerContext(String taskUuid) {
  141. db.executeInsert(
  142. "ce_scanner_context",
  143. "TASK_UUID", taskUuid,
  144. "CONTEXT_DATA", randomAlphanumeric(123).getBytes(),
  145. "CREATED_AT", random.nextInt(95654354),
  146. "UPDATED_AT", random.nextInt(95654354));
  147. }
  148. private void insertCeTaskCharacteristics(String taskUuid) {
  149. for (int i = 0; i < 1 + random.nextInt(3); i++) {
  150. insertCeTaskCharacteristic(taskUuid, i);
  151. }
  152. }
  153. private void insertCeTaskCharacteristic(String taskUuid, int i) {
  154. String uuid = UuidFactoryFast.getInstance().create();
  155. db.executeInsert(
  156. "ce_task_characteristics",
  157. "UUID", uuid,
  158. "TASK_UUID", taskUuid,
  159. "KEE", "kee_" + uuid + i,
  160. "TEXT_VALUE", randomAlphanumeric(18));
  161. }
  162. @Test
  163. public void migration_is_not_reentrant() throws SQLException {
  164. // FIXME
  165. underTest.execute();
  166. underTest.execute();
  167. }
  168. }