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.

CeActivityDaoIT.java 44KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935
  1. /*
  2. * SonarQube
  3. * Copyright (C) 2009-2023 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.db.ce;
  21. import com.google.common.base.Function;
  22. import com.google.common.base.Strings;
  23. import com.google.common.collect.ImmutableSet;
  24. import com.tngtech.java.junit.dataprovider.DataProvider;
  25. import com.tngtech.java.junit.dataprovider.DataProviderRunner;
  26. import com.tngtech.java.junit.dataprovider.UseDataProvider;
  27. import java.util.Arrays;
  28. import java.util.Collections;
  29. import java.util.List;
  30. import java.util.Optional;
  31. import java.util.Random;
  32. import java.util.stream.IntStream;
  33. import javax.annotation.Nonnull;
  34. import javax.annotation.Nullable;
  35. import org.assertj.core.api.AbstractListAssert;
  36. import org.assertj.core.api.ObjectAssert;
  37. import org.assertj.core.groups.Tuple;
  38. import org.junit.Before;
  39. import org.junit.Rule;
  40. import org.junit.Test;
  41. import org.junit.runner.RunWith;
  42. import org.sonar.api.impl.utils.TestSystem2;
  43. import org.sonar.core.util.CloseableIterator;
  44. import org.sonar.core.util.UuidFactoryFast;
  45. import org.sonar.db.DbSession;
  46. import org.sonar.db.DbTester;
  47. import org.sonar.db.Pagination;
  48. import org.sonar.db.component.BranchDto;
  49. import org.sonar.db.project.ProjectDto;
  50. import static java.util.Collections.emptyList;
  51. import static java.util.Collections.singleton;
  52. import static java.util.Collections.singletonList;
  53. import static org.apache.commons.lang.RandomStringUtils.randomAlphabetic;
  54. import static org.assertj.core.api.Assertions.assertThat;
  55. import static org.assertj.core.api.Assertions.tuple;
  56. import static org.sonar.db.Pagination.forPage;
  57. import static org.sonar.db.ce.CeActivityDto.Status.CANCELED;
  58. import static org.sonar.db.ce.CeActivityDto.Status.FAILED;
  59. import static org.sonar.db.ce.CeActivityDto.Status.SUCCESS;
  60. import static org.sonar.db.ce.CeQueueDto.Status.PENDING;
  61. import static org.sonar.db.ce.CeQueueTesting.makeInProgress;
  62. import static org.sonar.db.ce.CeTaskTypes.REPORT;
  63. @RunWith(DataProviderRunner.class)
  64. public class CeActivityDaoIT {
  65. private static final String ENTITY_1 = randomAlphabetic(12);
  66. private static final String MAINCOMPONENT_2 = randomAlphabetic(13);
  67. private static final String COMPONENT_1 = randomAlphabetic(14);
  68. private static final long INITIAL_TIME = 1_450_000_000_000L;
  69. private static final String NODE_NAME = "node1";
  70. private final TestSystem2 system2 = new TestSystem2().setNow(INITIAL_TIME);
  71. @Rule
  72. public DbTester db = DbTester.create(system2);
  73. private final DbSession dbSession = db.getSession();
  74. private final CeActivityDao underTest = new CeActivityDao(system2);
  75. @Before
  76. public void setup() {
  77. system2.setNow(INITIAL_TIME);
  78. }
  79. @Test
  80. public void test_insert() {
  81. CeActivityDto inserted = insert("TASK_1", REPORT, COMPONENT_1, ENTITY_1, SUCCESS);
  82. Optional<CeActivityDto> saved = underTest.selectByUuid(db.getSession(), "TASK_1");
  83. assertThat(saved).isPresent();
  84. CeActivityDto dto = saved.get();
  85. assertThat(dto.getUuid()).isEqualTo("TASK_1");
  86. assertThat(dto.getNodeName()).isEqualTo(NODE_NAME);
  87. assertThat(dto.getEntityUuid()).isEqualTo(ENTITY_1);
  88. assertThat(dto.getComponentUuid()).isEqualTo(COMPONENT_1);
  89. assertThat(dto.getStatus()).isEqualTo(SUCCESS);
  90. assertThat(dto.getSubmitterUuid()).isEqualTo("submitter uuid");
  91. assertThat(dto.getSubmittedAt()).isEqualTo(1_450_000_000_000L);
  92. assertThat(dto.getWorkerUuid()).isEqualTo("worker uuid");
  93. assertThat(dto.getIsLast()).isTrue();
  94. assertThat(dto.getMainIsLast()).isTrue();
  95. assertThat(dto.getIsLastKey()).isEqualTo("REPORT" + COMPONENT_1);
  96. assertThat(dto.getMainIsLastKey()).isEqualTo("REPORT" + ENTITY_1);
  97. assertThat(dto.getCreatedAt()).isEqualTo(INITIAL_TIME + 1);
  98. assertThat(dto.getStartedAt()).isEqualTo(1_500_000_000_000L);
  99. assertThat(dto.getExecutedAt()).isEqualTo(1_500_000_000_500L);
  100. assertThat(dto.getExecutionTimeMs()).isEqualTo(500L);
  101. assertThat(dto.getAnalysisUuid()).isEqualTo(inserted.getAnalysisUuid());
  102. assertThat(dto.toString()).isNotEmpty();
  103. assertThat(dto.getErrorMessage()).isNull();
  104. assertThat(dto.getErrorStacktrace()).isNull();
  105. assertThat(dto.getErrorType()).isNull();
  106. assertThat(dto.isHasScannerContext()).isFalse();
  107. assertThat(dto.getCeTaskMessageDtos()).isEmpty();
  108. }
  109. @Test
  110. public void selectByUuid_populates_messages() {
  111. CeActivityDto[] tasks = {
  112. insert("TASK_1", REPORT, "PROJECT_1", SUCCESS),
  113. insert("TASK_2", REPORT, "PROJECT_1", SUCCESS),
  114. insert("TASK_3", REPORT, "PROJECT_1", SUCCESS)
  115. };
  116. List<CeTaskMessageDto> task1messages = insertCeTaskMessage(tasks[0], 4);
  117. List<CeTaskMessageDto> task2messages = insertCeTaskMessage(tasks[1], 0);
  118. List<CeTaskMessageDto> task3messages = insertCeTaskMessage(tasks[2], 1);
  119. getCeActivityAndAssertMessages(tasks[0].getUuid(), task1messages);
  120. getCeActivityAndAssertMessages(tasks[1].getUuid(), task2messages);
  121. getCeActivityAndAssertMessages(tasks[2].getUuid(), task3messages);
  122. }
  123. private void getCeActivityAndAssertMessages(String taskUuid, List<CeTaskMessageDto> taskMessages) {
  124. CeActivityDto ceActivityDto = underTest.selectByUuid(dbSession, taskUuid).orElseThrow();
  125. assertThat(ceActivityDto.getCeTaskMessageDtos()).usingRecursiveFieldByFieldElementComparator().hasSameElementsAs(taskMessages);
  126. }
  127. private List<CeTaskMessageDto> insertCeTaskMessage(CeActivityDto task, int messagesCount) {
  128. List<CeTaskMessageDto> ceTaskMessageDtos = IntStream.range(0, messagesCount)
  129. .mapToObj(i -> createMessage(task, i))
  130. .toList();
  131. ceTaskMessageDtos.forEach(ceTaskMessageDto -> db.getDbClient().ceTaskMessageDao().insert(dbSession, ceTaskMessageDto));
  132. db.commit();
  133. return ceTaskMessageDtos;
  134. }
  135. private static CeTaskMessageDto createMessage(CeActivityDto task, int i) {
  136. return new CeTaskMessageDto()
  137. .setUuid(UuidFactoryFast.getInstance().create())
  138. .setTaskUuid(task.getUuid())
  139. .setMessage("message_" + task.getUuid() + "_" + i)
  140. .setType(CeTaskMessageType.GENERIC)
  141. .setCreatedAt(task.getUuid().hashCode() + i);
  142. }
  143. @Test
  144. @UseDataProvider("notCanceledStatus")
  145. public void insert_resets_is_last_and_main_is_last_fields_based_on_component_and_main_component(CeActivityDto.Status status) {
  146. String project1 = randomAlphabetic(5);
  147. String branch11 = randomAlphabetic(6);
  148. String project2 = randomAlphabetic(8);
  149. String branch21 = randomAlphabetic(9);
  150. String type = randomAlphabetic(10);
  151. String task1Project1 = insertAndCommit(newUuid(), type, project1, project1, status).getUuid();
  152. assertIsLastAndMainIsLastFieldsOf(task1Project1).containsOnly(tuple(true, true));
  153. String task2Project1 = insertAndCommit(newUuid(), type, project1, project1, status).getUuid();
  154. assertIsLastAndMainIsLastFieldsOf(task1Project1).containsOnly(tuple(false, false));
  155. assertIsLastAndMainIsLastFieldsOf(task2Project1).containsOnly(tuple(true, true));
  156. String task1Branch11 = insertAndCommit(newUuid(), type, branch11, project1, status).getUuid();
  157. assertIsLastAndMainIsLastFieldsOf(task1Project1).containsOnly(tuple(false, false));
  158. assertIsLastAndMainIsLastFieldsOf(task2Project1).containsOnly(tuple(true, false));
  159. assertIsLastAndMainIsLastFieldsOf(task1Branch11).containsOnly(tuple(true, true));
  160. String task2Branch11 = insertAndCommit(newUuid(), type, branch11, project1, status).getUuid();
  161. assertIsLastAndMainIsLastFieldsOf(task1Project1).containsOnly(tuple(false, false));
  162. assertIsLastAndMainIsLastFieldsOf(task2Project1).containsOnly(tuple(true, false));
  163. assertIsLastAndMainIsLastFieldsOf(task1Branch11).containsOnly(tuple(false, false));
  164. assertIsLastAndMainIsLastFieldsOf(task2Branch11).containsOnly(tuple(true, true));
  165. String task1Project2 = insertAndCommit(newUuid(), type, project2, project2, status).getUuid();
  166. assertIsLastAndMainIsLastFieldsOf(task1Project1).containsOnly(tuple(false, false));
  167. assertIsLastAndMainIsLastFieldsOf(task2Project1).containsOnly(tuple(true, false));
  168. assertIsLastAndMainIsLastFieldsOf(task1Branch11).containsOnly(tuple(false, false));
  169. assertIsLastAndMainIsLastFieldsOf(task2Branch11).containsOnly(tuple(true, true));
  170. assertIsLastAndMainIsLastFieldsOf(task1Project2).containsOnly(tuple(true, true));
  171. String task2Project2 = insertAndCommit(newUuid(), type, project2, project2, status).getUuid();
  172. assertIsLastAndMainIsLastFieldsOf(task1Project1).containsOnly(tuple(false, false));
  173. assertIsLastAndMainIsLastFieldsOf(task2Project1).containsOnly(tuple(true, false));
  174. assertIsLastAndMainIsLastFieldsOf(task1Branch11).containsOnly(tuple(false, false));
  175. assertIsLastAndMainIsLastFieldsOf(task2Branch11).containsOnly(tuple(true, true));
  176. assertIsLastAndMainIsLastFieldsOf(task1Project2).containsOnly(tuple(false, false));
  177. assertIsLastAndMainIsLastFieldsOf(task2Project2).containsOnly(tuple(true, true));
  178. String task1Branch21 = insertAndCommit(newUuid(), type, branch21, project2, status).getUuid();
  179. assertIsLastAndMainIsLastFieldsOf(task1Project1).containsOnly(tuple(false, false));
  180. assertIsLastAndMainIsLastFieldsOf(task2Project1).containsOnly(tuple(true, false));
  181. assertIsLastAndMainIsLastFieldsOf(task1Branch11).containsOnly(tuple(false, false));
  182. assertIsLastAndMainIsLastFieldsOf(task2Branch11).containsOnly(tuple(true, true));
  183. assertIsLastAndMainIsLastFieldsOf(task1Project2).containsOnly(tuple(false, false));
  184. assertIsLastAndMainIsLastFieldsOf(task2Project2).containsOnly(tuple(true, false));
  185. assertIsLastAndMainIsLastFieldsOf(task1Branch21).containsOnly(tuple(true, true));
  186. String task3project1 = insertAndCommit(newUuid(), type, project1, project1, status).getUuid();
  187. assertIsLastAndMainIsLastFieldsOf(task1Project1).containsOnly(tuple(false, false));
  188. assertIsLastAndMainIsLastFieldsOf(task2Project1).containsOnly(tuple(false, false));
  189. assertIsLastAndMainIsLastFieldsOf(task1Branch11).containsOnly(tuple(false, false));
  190. assertIsLastAndMainIsLastFieldsOf(task2Branch11).containsOnly(tuple(true, false));
  191. assertIsLastAndMainIsLastFieldsOf(task1Project2).containsOnly(tuple(false, false));
  192. assertIsLastAndMainIsLastFieldsOf(task2Project2).containsOnly(tuple(true, false));
  193. assertIsLastAndMainIsLastFieldsOf(task1Branch21).containsOnly(tuple(true, true));
  194. assertIsLastAndMainIsLastFieldsOf(task3project1).containsOnly(tuple(true, true));
  195. }
  196. @Test
  197. @UseDataProvider("notCanceledStatus")
  198. public void insert_resets_is_last_and_main_is_last_fields_based_on_type(CeActivityDto.Status status) {
  199. String type1 = randomAlphabetic(10);
  200. String type2 = randomAlphabetic(11);
  201. String project = randomAlphabetic(5);
  202. String branch = randomAlphabetic(6);
  203. String type1Project1 = insertAndCommit(newUuid(), type1, project, project, status).getUuid();
  204. assertIsLastAndMainIsLastFieldsOf(type1Project1).containsOnly(tuple(true, true));
  205. String type2Project1 = insertAndCommit(newUuid(), type2, project, project, status).getUuid();
  206. assertIsLastAndMainIsLastFieldsOf(type1Project1).containsOnly(tuple(true, true));
  207. assertIsLastAndMainIsLastFieldsOf(type2Project1).containsOnly(tuple(true, true));
  208. String type2Project2 = insertAndCommit(newUuid(), type2, project, project, status).getUuid();
  209. assertIsLastAndMainIsLastFieldsOf(type1Project1).containsOnly(tuple(true, true));
  210. assertIsLastAndMainIsLastFieldsOf(type2Project1).containsOnly(tuple(false, false));
  211. assertIsLastAndMainIsLastFieldsOf(type2Project2).containsOnly(tuple(true, true));
  212. String type1Branch1 = insertAndCommit(newUuid(), type1, branch, project, status).getUuid();
  213. assertIsLastAndMainIsLastFieldsOf(type1Project1).containsOnly(tuple(true, false));
  214. assertIsLastAndMainIsLastFieldsOf(type2Project1).containsOnly(tuple(false, false));
  215. assertIsLastAndMainIsLastFieldsOf(type2Project2).containsOnly(tuple(true, true));
  216. assertIsLastAndMainIsLastFieldsOf(type1Branch1).containsOnly(tuple(true, true));
  217. String type2Branch1 = insertAndCommit(newUuid(), type2, branch, project, status).getUuid();
  218. assertIsLastAndMainIsLastFieldsOf(type1Project1).containsOnly(tuple(true, false));
  219. assertIsLastAndMainIsLastFieldsOf(type2Project1).containsOnly(tuple(false, false));
  220. assertIsLastAndMainIsLastFieldsOf(type2Project2).containsOnly(tuple(true, false));
  221. assertIsLastAndMainIsLastFieldsOf(type1Branch1).containsOnly(tuple(true, true));
  222. assertIsLastAndMainIsLastFieldsOf(type2Branch1).containsOnly(tuple(true, true));
  223. String type2Branch2 = insertAndCommit(newUuid(), type2, branch, project, status).getUuid();
  224. assertIsLastAndMainIsLastFieldsOf(type1Project1).containsOnly(tuple(true, false));
  225. assertIsLastAndMainIsLastFieldsOf(type2Project1).containsOnly(tuple(false, false));
  226. assertIsLastAndMainIsLastFieldsOf(type2Project2).containsOnly(tuple(true, false));
  227. assertIsLastAndMainIsLastFieldsOf(type1Branch1).containsOnly(tuple(true, true));
  228. assertIsLastAndMainIsLastFieldsOf(type2Branch1).containsOnly(tuple(false, false));
  229. assertIsLastAndMainIsLastFieldsOf(type2Branch2).containsOnly(tuple(true, true));
  230. }
  231. @Test
  232. @UseDataProvider("notCanceledStatus")
  233. public void insert_resets_is_last_and_main_is_last_fields_based_on_component_or_not(CeActivityDto.Status status) {
  234. String project = randomAlphabetic(5);
  235. String type1 = randomAlphabetic(11);
  236. String type2 = randomAlphabetic(11);
  237. String type1Project1 = insertAndCommit(newUuid(), type1, project, project, status).getUuid();
  238. assertIsLastAndMainIsLastFieldsOf(type1Project1).containsOnly(tuple(true, true));
  239. String type1NoProject1 = insertAndCommit(newUuid(), type1, null, null, status).getUuid();
  240. assertIsLastAndMainIsLastFieldsOf(type1Project1).containsOnly(tuple(true, true));
  241. assertIsLastAndMainIsLastFieldsOf(type1NoProject1).containsOnly(tuple(true, true));
  242. String type1NoProject2 = insertAndCommit(newUuid(), type1, null, null, status).getUuid();
  243. assertIsLastAndMainIsLastFieldsOf(type1Project1).containsOnly(tuple(true, true));
  244. assertIsLastAndMainIsLastFieldsOf(type1NoProject1).containsOnly(tuple(false, false));
  245. assertIsLastAndMainIsLastFieldsOf(type1NoProject2).containsOnly(tuple(true, true));
  246. String type2NoProject1 = insertAndCommit(newUuid(), type2, null, null, status).getUuid();
  247. assertIsLastAndMainIsLastFieldsOf(type1Project1).containsOnly(tuple(true, true));
  248. assertIsLastAndMainIsLastFieldsOf(type1NoProject1).containsOnly(tuple(false, false));
  249. assertIsLastAndMainIsLastFieldsOf(type1NoProject2).containsOnly(tuple(true, true));
  250. assertIsLastAndMainIsLastFieldsOf(type2NoProject1).containsOnly(tuple(true, true));
  251. String type2NoProject2 = insertAndCommit(newUuid(), type2, null, null, status).getUuid();
  252. assertIsLastAndMainIsLastFieldsOf(type1Project1).containsOnly(tuple(true, true));
  253. assertIsLastAndMainIsLastFieldsOf(type1NoProject1).containsOnly(tuple(false, false));
  254. assertIsLastAndMainIsLastFieldsOf(type1NoProject2).containsOnly(tuple(true, true));
  255. assertIsLastAndMainIsLastFieldsOf(type2NoProject1).containsOnly(tuple(false, false));
  256. assertIsLastAndMainIsLastFieldsOf(type2NoProject2).containsOnly(tuple(true, true));
  257. String type1Project2 = insertAndCommit(newUuid(), type1, project, project, status).getUuid();
  258. assertIsLastAndMainIsLastFieldsOf(type1Project1).containsOnly(tuple(false, false));
  259. assertIsLastAndMainIsLastFieldsOf(type1NoProject1).containsOnly(tuple(false, false));
  260. assertIsLastAndMainIsLastFieldsOf(type1NoProject2).containsOnly(tuple(true, true));
  261. assertIsLastAndMainIsLastFieldsOf(type2NoProject1).containsOnly(tuple(false, false));
  262. assertIsLastAndMainIsLastFieldsOf(type2NoProject2).containsOnly(tuple(true, true));
  263. assertIsLastAndMainIsLastFieldsOf(type1Project2).containsOnly(tuple(true, true));
  264. }
  265. @Test
  266. @UseDataProvider("notCanceledStatus")
  267. public void insert_does_not_resets_is_last_and_main_is_last_fields_if_status_is_CANCELED(CeActivityDto.Status status) {
  268. String project = randomAlphabetic(5);
  269. String branch = randomAlphabetic(6);
  270. String type = randomAlphabetic(10);
  271. String task1Project1 = insertAndCommit(newUuid(), type, project, project, status).getUuid();
  272. assertIsLastAndMainIsLastFieldsOf(task1Project1).containsOnly(tuple(true, true));
  273. String task1Project2 = insertAndCommit(newUuid(), type, project, project, status).getUuid();
  274. assertIsLastAndMainIsLastFieldsOf(task1Project1).containsOnly(tuple(false, false));
  275. assertIsLastAndMainIsLastFieldsOf(task1Project2).containsOnly(tuple(true, true));
  276. String task1Project3 = insertAndCommit(newUuid(), type, project, project, CANCELED).getUuid();
  277. assertIsLastAndMainIsLastFieldsOf(task1Project1).containsOnly(tuple(false, false));
  278. assertIsLastAndMainIsLastFieldsOf(task1Project2).containsOnly(tuple(true, true));
  279. assertIsLastAndMainIsLastFieldsOf(task1Project3).containsOnly(tuple(false, false));
  280. String task1Branch1 = insertAndCommit(newUuid(), type, branch, project, status).getUuid();
  281. assertIsLastAndMainIsLastFieldsOf(task1Project1).containsOnly(tuple(false, false));
  282. assertIsLastAndMainIsLastFieldsOf(task1Project2).containsOnly(tuple(true, false));
  283. assertIsLastAndMainIsLastFieldsOf(task1Project3).containsOnly(tuple(false, false));
  284. assertIsLastAndMainIsLastFieldsOf(task1Branch1).containsOnly(tuple(true, true));
  285. String task1Branch2 = insertAndCommit(newUuid(), type, branch, project, CANCELED).getUuid();
  286. assertIsLastAndMainIsLastFieldsOf(task1Project1).containsOnly(tuple(false, false));
  287. assertIsLastAndMainIsLastFieldsOf(task1Project2).containsOnly(tuple(true, false));
  288. assertIsLastAndMainIsLastFieldsOf(task1Project3).containsOnly(tuple(false, false));
  289. assertIsLastAndMainIsLastFieldsOf(task1Branch1).containsOnly(tuple(true, true));
  290. assertIsLastAndMainIsLastFieldsOf(task1Branch2).containsOnly(tuple(false, false));
  291. }
  292. @DataProvider
  293. public static Object[][] notCanceledStatus() {
  294. return Arrays.stream(CeActivityDto.Status.values())
  295. .filter(t -> t != CANCELED)
  296. .map(t -> new Object[] {t})
  297. .toArray(Object[][]::new);
  298. }
  299. private AbstractListAssert<?, List<? extends Tuple>, Tuple, ObjectAssert<Tuple>> assertIsLastAndMainIsLastFieldsOf(String taskUuid) {
  300. return assertThat(db.select("select is_last as \"IS_LAST\", main_is_last as \"MAIN_IS_LAST\" from ce_activity where uuid='" + taskUuid + "'"))
  301. .extracting(t -> toBoolean(t.get("IS_LAST")), t -> toBoolean(t.get("MAIN_IS_LAST")));
  302. }
  303. private static boolean toBoolean(Object o) {
  304. if (o instanceof Boolean) {
  305. return (Boolean) o;
  306. }
  307. if (o instanceof Long) {
  308. Long longBoolean = (Long) o;
  309. return longBoolean.equals(1L);
  310. }
  311. throw new IllegalArgumentException("Unsupported object type returned for boolean: " + o.getClass());
  312. }
  313. @Test
  314. public void test_insert_of_errorMessage_of_1_000_chars() {
  315. CeActivityDto dto = createActivityDto("TASK_1", REPORT, COMPONENT_1, ENTITY_1, FAILED)
  316. .setErrorMessage(Strings.repeat("x", 1_000));
  317. underTest.insert(db.getSession(), dto);
  318. Optional<CeActivityDto> saved = underTest.selectByUuid(db.getSession(), "TASK_1");
  319. assertThat(saved.get().getErrorMessage()).isEqualTo(dto.getErrorMessage());
  320. }
  321. @Test
  322. public void test_insert_of_errorMessage_of_1_001_chars_is_truncated_to_1000() {
  323. String expected = Strings.repeat("x", 1_000);
  324. CeActivityDto dto = createActivityDto("TASK_1", REPORT, COMPONENT_1, ENTITY_1, FAILED)
  325. .setErrorMessage(expected + "y");
  326. underTest.insert(db.getSession(), dto);
  327. Optional<CeActivityDto> saved = underTest.selectByUuid(db.getSession(), "TASK_1");
  328. assertThat(saved.get().getErrorMessage()).isEqualTo(expected);
  329. }
  330. @Test
  331. public void test_insert_error_message_and_stacktrace() {
  332. CeActivityDto dto = createActivityDto("TASK_1", REPORT, COMPONENT_1, ENTITY_1, FAILED)
  333. .setErrorStacktrace("error stack");
  334. underTest.insert(db.getSession(), dto);
  335. Optional<CeActivityDto> saved = underTest.selectByUuid(db.getSession(), "TASK_1");
  336. CeActivityDto read = saved.get();
  337. assertThat(read.getErrorMessage()).isEqualTo(dto.getErrorMessage());
  338. assertThat(read.getErrorStacktrace()).isEqualTo(dto.getErrorStacktrace());
  339. assertThat(read.getErrorType()).isNotNull().isEqualTo(dto.getErrorType());
  340. }
  341. @Test
  342. public void test_insert_error_message_only() {
  343. CeActivityDto dto = createActivityDto("TASK_1", REPORT, COMPONENT_1, ENTITY_1, FAILED);
  344. underTest.insert(db.getSession(), dto);
  345. Optional<CeActivityDto> saved = underTest.selectByUuid(db.getSession(), "TASK_1");
  346. CeActivityDto read = saved.get();
  347. assertThat(read.getErrorMessage()).isEqualTo(read.getErrorMessage());
  348. assertThat(read.getErrorStacktrace()).isNull();
  349. }
  350. @Test
  351. public void insert_must_set_relevant_is_last_field() {
  352. // only a single task on MAINCOMPONENT_1 -> is_last=true
  353. insert("TASK_1", REPORT, ENTITY_1, SUCCESS);
  354. assertThat(underTest.selectByUuid(db.getSession(), "TASK_1").get().getIsLast()).isTrue();
  355. // only a single task on MAINCOMPONENT_2 -> is_last=true
  356. insert("TASK_2", REPORT, MAINCOMPONENT_2, SUCCESS);
  357. assertThat(underTest.selectByUuid(db.getSession(), "TASK_2").get().getIsLast()).isTrue();
  358. // two tasks on MAINCOMPONENT_1, the most recent one is TASK_3
  359. insert("TASK_3", REPORT, ENTITY_1, FAILED);
  360. assertThat(underTest.selectByUuid(db.getSession(), "TASK_1").get().getIsLast()).isFalse();
  361. assertThat(underTest.selectByUuid(db.getSession(), "TASK_2").get().getIsLast()).isTrue();
  362. assertThat(underTest.selectByUuid(db.getSession(), "TASK_3").get().getIsLast()).isTrue();
  363. // inserting a cancelled task does not change the last task
  364. insert("TASK_4", REPORT, ENTITY_1, CANCELED);
  365. assertThat(underTest.selectByUuid(db.getSession(), "TASK_1").get().getIsLast()).isFalse();
  366. assertThat(underTest.selectByUuid(db.getSession(), "TASK_2").get().getIsLast()).isTrue();
  367. assertThat(underTest.selectByUuid(db.getSession(), "TASK_3").get().getIsLast()).isTrue();
  368. assertThat(underTest.selectByUuid(db.getSession(), "TASK_4").get().getIsLast()).isFalse();
  369. }
  370. @Test
  371. public void test_selectByQuery() {
  372. insert("TASK_1", REPORT, ENTITY_1, SUCCESS);
  373. insert("TASK_2", REPORT, ENTITY_1, FAILED);
  374. insert("TASK_3", REPORT, MAINCOMPONENT_2, SUCCESS);
  375. insert("TASK_4", "views", null, SUCCESS);
  376. // no filters
  377. CeTaskQuery query = new CeTaskQuery().setStatuses(Collections.emptyList());
  378. List<CeActivityDto> dtos = underTest.selectByQuery(db.getSession(), query, forPage(1).andSize(10));
  379. assertThat(dtos).extracting("uuid").containsExactly("TASK_4", "TASK_3", "TASK_2", "TASK_1");
  380. // select by component uuid
  381. query = new CeTaskQuery().setEntityUuid(ENTITY_1);
  382. dtos = underTest.selectByQuery(db.getSession(), query, forPage(1).andSize(100));
  383. assertThat(dtos).extracting("uuid").containsExactly("TASK_2", "TASK_1");
  384. // select by status
  385. query = new CeTaskQuery().setStatuses(singletonList(SUCCESS.name()));
  386. dtos = underTest.selectByQuery(db.getSession(), query, forPage(1).andSize(100));
  387. assertThat(dtos).extracting("uuid").containsExactly("TASK_4", "TASK_3", "TASK_1");
  388. // select by type
  389. query = new CeTaskQuery().setType(REPORT);
  390. dtos = underTest.selectByQuery(db.getSession(), query, forPage(1).andSize(100));
  391. assertThat(dtos).extracting("uuid").containsExactly("TASK_3", "TASK_2", "TASK_1");
  392. query = new CeTaskQuery().setType("views");
  393. dtos = underTest.selectByQuery(db.getSession(), query, forPage(1).andSize(100));
  394. assertThat(dtos).extracting("uuid").containsExactly("TASK_4");
  395. // select by multiple conditions
  396. query = new CeTaskQuery().setType(REPORT).setOnlyCurrents(true).setEntityUuid(ENTITY_1);
  397. dtos = underTest.selectByQuery(db.getSession(), query, forPage(1).andSize(100));
  398. assertThat(dtos).extracting("uuid").containsExactly("TASK_2");
  399. }
  400. @Test
  401. public void test_selectByQuery_verify_order_if_same_date() {
  402. system2.setNow(INITIAL_TIME);
  403. insert("TASK_1", REPORT, ENTITY_1, SUCCESS);
  404. system2.setNow(INITIAL_TIME);
  405. insert("TASK_2", REPORT, ENTITY_1, FAILED);
  406. system2.setNow(INITIAL_TIME);
  407. insert("TASK_3", REPORT, MAINCOMPONENT_2, SUCCESS);
  408. system2.setNow(INITIAL_TIME);
  409. insert("TASK_4", "views", null, SUCCESS);
  410. // no filters
  411. CeTaskQuery query = new CeTaskQuery().setStatuses(Collections.emptyList());
  412. List<CeActivityDto> dtos = underTest.selectByQuery(db.getSession(), query, forPage(1).andSize(10));
  413. assertThat(dtos).extracting("uuid").containsExactly("TASK_4", "TASK_3", "TASK_2", "TASK_1");
  414. // select by component uuid
  415. query = new CeTaskQuery().setEntityUuid(ENTITY_1);
  416. dtos = underTest.selectByQuery(db.getSession(), query, forPage(1).andSize(100));
  417. assertThat(dtos).extracting("uuid").containsExactly("TASK_2", "TASK_1");
  418. // select by status
  419. query = new CeTaskQuery().setStatuses(singletonList(SUCCESS.name()));
  420. dtos = underTest.selectByQuery(db.getSession(), query, forPage(1).andSize(100));
  421. assertThat(dtos).extracting("uuid").containsExactly("TASK_4", "TASK_3", "TASK_1");
  422. // select by type
  423. query = new CeTaskQuery().setType(REPORT);
  424. dtos = underTest.selectByQuery(db.getSession(), query, forPage(1).andSize(100));
  425. assertThat(dtos).extracting("uuid").containsExactly("TASK_3", "TASK_2", "TASK_1");
  426. query = new CeTaskQuery().setType("views");
  427. dtos = underTest.selectByQuery(db.getSession(), query, forPage(1).andSize(100));
  428. assertThat(dtos).extracting("uuid").containsExactly("TASK_4");
  429. // select by multiple conditions
  430. query = new CeTaskQuery().setType(REPORT).setOnlyCurrents(true).setEntityUuid(ENTITY_1);
  431. dtos = underTest.selectByQuery(db.getSession(), query, forPage(1).andSize(100));
  432. assertThat(dtos).extracting("uuid").containsExactly("TASK_2");
  433. }
  434. @Test
  435. public void selectByQuery_does_not_populate_errorStacktrace_field() {
  436. insert("TASK_1", REPORT, ENTITY_1, FAILED);
  437. underTest.insert(db.getSession(), createActivityDto("TASK_2", REPORT, COMPONENT_1, ENTITY_1, FAILED).setErrorStacktrace("some stack"));
  438. List<CeActivityDto> dtos = underTest.selectByQuery(db.getSession(), new CeTaskQuery().setEntityUuid(ENTITY_1), forPage(1).andSize(100));
  439. assertThat(dtos)
  440. .hasSize(2)
  441. .extracting("errorStacktrace").containsOnly((String) null);
  442. }
  443. @Test
  444. public void selectByQuery_populates_hasScannerContext_flag() {
  445. insert("TASK_1", REPORT, ENTITY_1, SUCCESS);
  446. CeActivityDto dto2 = insert("TASK_2", REPORT, MAINCOMPONENT_2, SUCCESS);
  447. insertScannerContext(dto2.getUuid());
  448. CeActivityDto dto = underTest.selectByQuery(db.getSession(), new CeTaskQuery().setEntityUuid(ENTITY_1), forPage(1).andSize(100)).iterator().next();
  449. assertThat(dto.isHasScannerContext()).isFalse();
  450. dto = underTest.selectByQuery(db.getSession(), new CeTaskQuery().setEntityUuid(MAINCOMPONENT_2), forPage(1).andSize(100)).iterator().next();
  451. assertThat(dto.isHasScannerContext()).isTrue();
  452. }
  453. @Test
  454. public void selectByQuery_populates_messages() {
  455. CeActivityDto[] tasks = {
  456. insert("TASK_1", REPORT, "PROJECT_1", SUCCESS),
  457. insert("TASK_2", REPORT, "PROJECT_1", FAILED),
  458. insert("TASK_3", REPORT, "PROJECT_2", SUCCESS),
  459. insert("TASK_4", "views", null, SUCCESS)
  460. };
  461. int moreThan1 = 2 + new Random().nextInt(5);
  462. insertCeTaskMessage(tasks[0], moreThan1);
  463. insertCeTaskMessage(tasks[1], 30);
  464. insertCeTaskMessage(tasks[2], 10);
  465. insertCeTaskMessage(tasks[3], 60);
  466. // no filters
  467. CeTaskQuery query = new CeTaskQuery();
  468. assertThat(underTest.selectByQuery(db.getSession(), query, forPage(1).andSize(10)))
  469. .extracting(CeActivityDto::getUuid, ceActivityDto -> ceActivityDto.getCeTaskMessageDtos().size())
  470. .containsExactly(tuple("TASK_4", 60), tuple("TASK_3", 10), tuple("TASK_2", 30), tuple("TASK_1", moreThan1));
  471. // select by component uuid
  472. query = new CeTaskQuery().setEntityUuid("PROJECT_1");
  473. assertThat(underTest.selectByQuery(db.getSession(), query, forPage(1).andSize(100)))
  474. .extracting(CeActivityDto::getUuid, ceActivityDto -> ceActivityDto.getCeTaskMessageDtos().size())
  475. .containsExactly(tuple("TASK_2", 30), tuple("TASK_1", moreThan1));
  476. // select by status
  477. query = new CeTaskQuery().setStatuses(singletonList(SUCCESS.name()));
  478. assertThat(underTest.selectByQuery(db.getSession(), query, forPage(1).andSize(100)))
  479. .extracting(CeActivityDto::getUuid, ceActivityDto -> ceActivityDto.getCeTaskMessageDtos().size())
  480. .containsExactly(tuple("TASK_4", 60), tuple("TASK_3", 10), tuple("TASK_1", moreThan1));
  481. // select by type
  482. query = new CeTaskQuery().setType(REPORT);
  483. assertThat(underTest.selectByQuery(db.getSession(), query, forPage(1).andSize(100)))
  484. .extracting(CeActivityDto::getUuid, ceActivityDto -> ceActivityDto.getCeTaskMessageDtos().size())
  485. .containsExactly(tuple("TASK_3", 10), tuple("TASK_2", 30), tuple("TASK_1", moreThan1));
  486. query = new CeTaskQuery().setType("views");
  487. assertThat(underTest.selectByQuery(db.getSession(), query, forPage(1).andSize(100)))
  488. .extracting(CeActivityDto::getUuid, ceActivityDto -> ceActivityDto.getCeTaskMessageDtos().size())
  489. .containsExactly(tuple("TASK_4", 60));
  490. // select by multiple conditions
  491. query = new CeTaskQuery().setType(REPORT).setOnlyCurrents(true).setEntityUuid("PROJECT_1");
  492. assertThat(underTest.selectByQuery(db.getSession(), query, forPage(1).andSize(100)))
  493. .extracting(CeActivityDto::getUuid, ceActivityDto -> ceActivityDto.getCeTaskMessageDtos().size())
  494. .containsExactly(tuple("TASK_2", 30));
  495. }
  496. @Test
  497. public void selectByQuery_whenNoMessage_returnsEmptyList() {
  498. insert("TASK_1", REPORT, "PROJECT_1", SUCCESS);
  499. List<CeActivityDto> results = underTest.selectByQuery(db.getSession(), new CeTaskQuery(), Pagination.all());
  500. assertThat(results)
  501. .hasSize(1)
  502. .extracting(CeActivityDto::getCeTaskMessageDtos)
  503. .containsExactly(emptyList());
  504. }
  505. @Test
  506. public void selectByQuery_is_paginated_and_return_results_sorted_from_last_to_first() {
  507. insert("TASK_1", REPORT, ENTITY_1, SUCCESS);
  508. insert("TASK_2", REPORT, ENTITY_1, FAILED);
  509. insert("TASK_3", REPORT, MAINCOMPONENT_2, SUCCESS);
  510. insert("TASK_4", "views", null, SUCCESS);
  511. assertThat(selectPageOfUuids(forPage(1).andSize(1))).containsExactly("TASK_4");
  512. assertThat(selectPageOfUuids(forPage(2).andSize(1))).containsExactly("TASK_3");
  513. assertThat(selectPageOfUuids(forPage(1).andSize(3))).containsExactly("TASK_4", "TASK_3", "TASK_2");
  514. assertThat(selectPageOfUuids(forPage(1).andSize(4))).containsExactly("TASK_4", "TASK_3", "TASK_2", "TASK_1");
  515. assertThat(selectPageOfUuids(forPage(2).andSize(3))).containsExactly("TASK_1");
  516. assertThat(selectPageOfUuids(forPage(1).andSize(100))).containsExactly("TASK_4", "TASK_3", "TASK_2", "TASK_1");
  517. assertThat(selectPageOfUuids(forPage(5).andSize(2))).isEmpty();
  518. }
  519. @Test
  520. public void selectByQuery_no_results_if_shortcircuited_by_component_uuids() {
  521. insert("TASK_1", REPORT, ENTITY_1, SUCCESS);
  522. CeTaskQuery query = new CeTaskQuery();
  523. query.setEntityUuids(Collections.emptyList());
  524. assertThat(underTest.selectByQuery(db.getSession(), query, forPage(1).andSize(1))).isEmpty();
  525. }
  526. @Test
  527. public void select_and_count_by_date() {
  528. insertWithDates("UUID1", 1_450_000_000_000L, 1_470_000_000_000L);
  529. insertWithDates("UUID2", 1_460_000_000_000L, 1_480_000_000_000L);
  530. // search by min submitted date
  531. CeTaskQuery query = new CeTaskQuery().setMinSubmittedAt(1_455_000_000_000L);
  532. assertThat(underTest.selectByQuery(db.getSession(), query, forPage(1).andSize(5))).extracting("uuid").containsOnly("UUID2");
  533. // search by max executed date
  534. query = new CeTaskQuery().setMaxExecutedAt(1_475_000_000_000L);
  535. assertThat(underTest.selectByQuery(db.getSession(), query, forPage(1).andSize(5))).extracting("uuid").containsOnly("UUID1");
  536. // search by both dates
  537. query = new CeTaskQuery()
  538. .setMinSubmittedAt(1_400_000_000_000L)
  539. .setMaxExecutedAt(1_475_000_000_000L);
  540. assertThat(underTest.selectByQuery(db.getSession(), query, forPage(1).andSize(5))).extracting("uuid").containsOnly("UUID1");
  541. }
  542. @Test
  543. public void select_by_minExecutedAt() {
  544. insertWithDates("UUID1", 1_450_000_000_000L, 1_470_000_000_000L);
  545. insertWithDates("UUID2", 1_460_000_000_000L, 1_480_000_000_000L);
  546. CeTaskQuery query = new CeTaskQuery().setMinExecutedAt(1_460_000_000_000L);
  547. assertThat(underTest.selectByQuery(db.getSession(), query, forPage(1).andSize(5))).extracting("uuid").containsExactlyInAnyOrder("UUID1", "UUID2");
  548. query = new CeTaskQuery().setMinExecutedAt(1_475_000_000_000L);
  549. assertThat(underTest.selectByQuery(db.getSession(), query, forPage(1).andSize(5))).extracting("uuid").containsExactlyInAnyOrder("UUID2");
  550. query = new CeTaskQuery().setMinExecutedAt(1_485_000_000_000L);
  551. assertThat(underTest.selectByQuery(db.getSession(), query, forPage(1).andSize(5))).isEmpty();
  552. }
  553. private void insertWithDates(String uuid, long submittedAt, long executedAt) {
  554. CeQueueDto queueDto = new CeQueueDto();
  555. queueDto.setUuid(uuid);
  556. queueDto.setTaskType("fake");
  557. CeActivityDto dto = new CeActivityDto(queueDto);
  558. dto.setStatus(SUCCESS);
  559. dto.setSubmittedAt(submittedAt);
  560. dto.setExecutedAt(executedAt);
  561. underTest.insert(db.getSession(), dto);
  562. }
  563. @Test
  564. public void selectOlderThan() {
  565. insertWithCreationDate("TASK_1", 1_450_000_000_000L);
  566. insertWithCreationDate("TASK_2", 1_460_000_000_000L);
  567. insertWithCreationDate("TASK_3", 1_470_000_000_000L);
  568. List<CeActivityDto> dtos = underTest.selectOlderThan(db.getSession(), 1_465_000_000_000L);
  569. assertThat(dtos).extracting("uuid").containsOnly("TASK_1", "TASK_2");
  570. }
  571. @Test
  572. public void selectNewerThan() {
  573. insertWithCreationDate("TASK_1", 1_450_000_000_000L);
  574. insertWithCreationDate("TASK_2", 1_460_000_000_000L);
  575. insertWithCreationDate("TASK_3", 1_470_000_000_000L);
  576. List<CeActivityDto> dtos = underTest.selectNewerThan(db.getSession(), 1_455_000_000_000L);
  577. assertThat(dtos).extracting("uuid").containsOnly("TASK_2", "TASK_3");
  578. }
  579. @Test
  580. public void selectOlder_populates_hasScannerContext_flag() {
  581. insertWithCreationDate("TASK_1", 1_450_000_000_000L);
  582. CeActivityDto dto2 = insertWithCreationDate("TASK_2", 1_450_000_000_000L);
  583. insertScannerContext(dto2.getUuid());
  584. List<CeActivityDto> dtos = underTest.selectOlderThan(db.getSession(), 1_465_000_000_000L);
  585. assertThat(dtos).hasSize(2);
  586. dtos.forEach((dto) -> assertThat(dto.isHasScannerContext()).isEqualTo(dto.getUuid().equals("TASK_2")));
  587. }
  588. @Test
  589. public void selectOlderThan_does_not_populate_errorStacktrace() {
  590. insert("TASK_1", REPORT, ENTITY_1, FAILED);
  591. underTest.insert(db.getSession(), createActivityDto("TASK_2", REPORT, COMPONENT_1, ENTITY_1, FAILED).setErrorStacktrace("some stack"));
  592. List<CeActivityDto> dtos = underTest.selectOlderThan(db.getSession(), system2.now() + 1_000_000L);
  593. assertThat(dtos)
  594. .hasSize(2)
  595. .extracting("errorStacktrace").containsOnly((String) null);
  596. }
  597. @Test
  598. public void selectOlderThan_populatesCorrectly() {
  599. CeActivityDto activity1 = insert("TASK_1", REPORT, "PROJECT_1", FAILED);
  600. insertCeTaskMessage(activity1, 10);
  601. CeActivityDto activity2 = insert("TASK_2", REPORT, "PROJECT_1", SUCCESS);
  602. insertCeTaskMessage(activity2, 1);
  603. List<CeActivityDto> dtos = underTest.selectOlderThan(db.getSession(), system2.now() + 1_000_000L);
  604. assertThat(dtos)
  605. .hasSize(2)
  606. .extracting(ceActivityDto -> ceActivityDto.getCeTaskMessageDtos().size())
  607. .containsOnly(10, 1);
  608. }
  609. @Test
  610. public void deleteByUuids() {
  611. insert("TASK_1", "REPORT", ENTITY_1, SUCCESS);
  612. insert("TASK_2", "REPORT", ENTITY_1, SUCCESS);
  613. insert("TASK_3", "REPORT", ENTITY_1, SUCCESS);
  614. underTest.deleteByUuids(db.getSession(), ImmutableSet.of("TASK_1", "TASK_3"));
  615. assertThat(underTest.selectByUuid(db.getSession(), "TASK_1")).isEmpty();
  616. assertThat(underTest.selectByUuid(db.getSession(), "TASK_2")).isPresent();
  617. assertThat(underTest.selectByUuid(db.getSession(), "TASK_3")).isEmpty();
  618. }
  619. @Test
  620. public void deleteByUuids_does_nothing_if_uuid_does_not_exist() {
  621. insert("TASK_1", "REPORT", ENTITY_1, SUCCESS);
  622. // must not fail
  623. underTest.deleteByUuids(db.getSession(), singleton("TASK_2"));
  624. assertThat(underTest.selectByUuid(db.getSession(), "TASK_1")).isPresent();
  625. }
  626. @Test
  627. public void count_last_by_status_and_entity_uuid() {
  628. insert("TASK_1", CeTaskTypes.REPORT, ENTITY_1, SUCCESS);
  629. // component 2
  630. insert("TASK_2", CeTaskTypes.REPORT, MAINCOMPONENT_2, SUCCESS);
  631. // status failed
  632. insert("TASK_3", CeTaskTypes.REPORT, ENTITY_1, FAILED);
  633. // status canceled
  634. insert("TASK_4", CeTaskTypes.REPORT, ENTITY_1, CANCELED);
  635. insert("TASK_5", CeTaskTypes.REPORT, ENTITY_1, SUCCESS);
  636. db.commit();
  637. assertThat(underTest.countLastByStatusAndEntityUuid(dbSession, SUCCESS, ENTITY_1)).isOne();
  638. assertThat(underTest.countLastByStatusAndEntityUuid(dbSession, SUCCESS, null)).isEqualTo(2);
  639. }
  640. @Test
  641. public void selectLastByComponentUuidAndTaskType_returns_task_of_given_type() {
  642. insert("TASK_1", "VIEW_REFRESH", ENTITY_1, ENTITY_1, SUCCESS);
  643. insert("TASK_2", CeTaskTypes.REPORT, ENTITY_1, ENTITY_1, SUCCESS);
  644. insert("TASK_3", "PROJECT_EXPORT", ENTITY_1, ENTITY_1, SUCCESS);
  645. insert("TASK_4", "PROJECT_IMPORT", ENTITY_1, ENTITY_1, SUCCESS);
  646. db.commit();
  647. Optional<CeActivityDto> result = underTest.selectLastByComponentUuidAndTaskType(db.getSession(), ENTITY_1, "PROJECT_EXPORT");
  648. assertThat(result).hasValueSatisfying(value -> assertThat(value.getUuid()).isEqualTo("TASK_3"));
  649. }
  650. @Test
  651. public void selectLastByComponentUuidAndTaskType_returns_empty_if_task_of_given_type_does_not_exist() {
  652. insert("TASK_1", CeTaskTypes.REPORT, ENTITY_1, SUCCESS);
  653. db.commit();
  654. Optional<CeActivityDto> result = underTest.selectLastByComponentUuidAndTaskType(db.getSession(), ENTITY_1, "PROJECT_EXPORT");
  655. assertThat(result).isEmpty();
  656. }
  657. @Test
  658. public void selectByTaskType() {
  659. insert("TASK_1", CeTaskTypes.REPORT, ENTITY_1, SUCCESS);
  660. insert("TASK_2", CeTaskTypes.BRANCH_ISSUE_SYNC, ENTITY_1, SUCCESS);
  661. db.commit();
  662. assertThat(underTest.selectByTaskType(db.getSession(), CeTaskTypes.REPORT))
  663. .extracting("uuid")
  664. .containsExactly("TASK_1");
  665. assertThat(underTest.selectByTaskType(db.getSession(), CeTaskTypes.BRANCH_ISSUE_SYNC))
  666. .extracting("uuid")
  667. .containsExactly("TASK_2");
  668. assertThat(underTest.selectByTaskType(db.getSession(), "unknown-type")).isEmpty();
  669. }
  670. @Test
  671. public void hasAnyFailedOrCancelledIssueSyncTask() {
  672. assertThat(underTest.hasAnyFailedOrCancelledIssueSyncTask(db.getSession())).isFalse();
  673. insert("TASK_1", REPORT, ENTITY_1, SUCCESS);
  674. insert("TASK_2", REPORT, ENTITY_1, FAILED);
  675. ProjectDto projectDto1 = db.components().insertPrivateProject(
  676. branchDto -> branchDto.setNeedIssueSync(false), c -> {
  677. }, p -> {
  678. }).getProjectDto();
  679. insert("TASK_3", CeTaskTypes.BRANCH_ISSUE_SYNC, projectDto1.getUuid(), projectDto1.getUuid(), SUCCESS);
  680. ProjectDto projectDto2 = db.components().insertPrivateProject(branchDto -> branchDto.setNeedIssueSync(false), c -> {
  681. }, p -> {
  682. }).getProjectDto();
  683. insert("TASK_4", CeTaskTypes.BRANCH_ISSUE_SYNC, projectDto2.getUuid(), projectDto2.getUuid(), SUCCESS);
  684. assertThat(underTest.hasAnyFailedOrCancelledIssueSyncTask(db.getSession())).isFalse();
  685. ProjectDto projectDto3 = db.components().insertPrivateProject(branchDto -> branchDto.setNeedIssueSync(false), c -> {
  686. }, p -> {
  687. }).getProjectDto();
  688. insert("TASK_5", CeTaskTypes.BRANCH_ISSUE_SYNC, projectDto3.getUuid(), projectDto3.getUuid(), SUCCESS);
  689. BranchDto projectBranch1 = db.components()
  690. .insertProjectBranch(projectDto3, branchDto -> branchDto.setNeedIssueSync(true));
  691. insert("TASK_6", CeTaskTypes.BRANCH_ISSUE_SYNC, projectBranch1.getUuid(), projectDto3.getUuid(), FAILED);
  692. BranchDto projectBranch2 = db.components()
  693. .insertProjectBranch(projectDto3, branchDto -> branchDto.setNeedIssueSync(true));
  694. insert("TASK_7", CeTaskTypes.BRANCH_ISSUE_SYNC, projectBranch2.getUuid(), projectDto3.getUuid(), CANCELED);
  695. // failed task and project branch still exists and need sync
  696. assertThat(underTest.hasAnyFailedOrCancelledIssueSyncTask(db.getSession())).isTrue();
  697. // assume branch has been re-analysed
  698. db.getDbClient().branchDao().updateNeedIssueSync(db.getSession(), projectBranch1.getUuid(), false);
  699. // assume branch has been re-analysed
  700. db.getDbClient().branchDao().updateNeedIssueSync(db.getSession(), projectBranch2.getUuid(), false);
  701. assertThat(underTest.hasAnyFailedOrCancelledIssueSyncTask(db.getSession())).isFalse();
  702. // assume branch has been deleted
  703. db.getDbClient().purgeDao().deleteBranch(db.getSession(), projectBranch1.getUuid());
  704. db.getDbClient().purgeDao().deleteBranch(db.getSession(), projectBranch2.getUuid());
  705. // associated branch does not exist, so there is no failures - either it has been deleted or purged or reanalysed
  706. assertThat(underTest.hasAnyFailedOrCancelledIssueSyncTask(db.getSession())).isFalse();
  707. }
  708. private CeActivityDto insert(String uuid, String type, @Nullable String mainComponentUuid, CeActivityDto.Status status) {
  709. return insert(uuid, type, mainComponentUuid, mainComponentUuid, status);
  710. }
  711. private CeActivityDto insertAndCommit(String uuid, String type, @Nullable String componentUuid, @Nullable String entityUuid, CeActivityDto.Status status) {
  712. CeActivityDto res = insert(uuid, type, componentUuid, entityUuid, status);
  713. db.commit();
  714. return res;
  715. }
  716. private CeActivityDto insert(String uuid, String type, @Nullable String componentUuid, @Nullable String entityUuid, CeActivityDto.Status status) {
  717. CeActivityDto dto = createActivityDto(uuid, type, componentUuid, entityUuid, status);
  718. system2.tick();
  719. underTest.insert(db.getSession(), dto);
  720. return dto;
  721. }
  722. private CeActivityDto createActivityDto(String uuid, String type, @Nullable String componentUuid, @Nullable String entityUuid, CeActivityDto.Status status) {
  723. CeQueueDto creating = new CeQueueDto();
  724. creating.setUuid(uuid);
  725. creating.setStatus(PENDING);
  726. creating.setTaskType(type);
  727. creating.setComponentUuid(componentUuid);
  728. creating.setEntityUuid(entityUuid);
  729. creating.setSubmitterUuid("submitter uuid");
  730. creating.setCreatedAt(system2.now());
  731. db.getDbClient().ceQueueDao().insert(dbSession, creating);
  732. makeInProgress(dbSession, "worker uuid", 1_400_000_000_000L, creating);
  733. CeQueueDto ceQueueDto = db.getDbClient().ceQueueDao().selectByUuid(dbSession, uuid).get();
  734. CeActivityDto dto = new CeActivityDto(ceQueueDto);
  735. dto.setNodeName(NODE_NAME);
  736. dto.setStatus(status);
  737. dto.setStartedAt(1_500_000_000_000L);
  738. dto.setExecutedAt(1_500_000_000_500L);
  739. dto.setExecutionTimeMs(500L);
  740. dto.setAnalysisUuid(uuid + "_2");
  741. if (status == FAILED) {
  742. dto.setErrorMessage("error msg for " + uuid);
  743. dto.setErrorType("anErrorType");
  744. }
  745. return dto;
  746. }
  747. private CeActivityDto insertWithCreationDate(String uuid, long date) {
  748. CeQueueDto queueDto = new CeQueueDto();
  749. queueDto.setUuid(uuid);
  750. queueDto.setTaskType("fake");
  751. CeActivityDto dto = new CeActivityDto(queueDto);
  752. dto.setStatus(SUCCESS);
  753. dto.setAnalysisUuid(uuid + "_AA");
  754. system2.setNow(date);
  755. underTest.insert(db.getSession(), dto);
  756. return dto;
  757. }
  758. private void insertScannerContext(String taskUuid) {
  759. db.getDbClient().ceScannerContextDao().insert(dbSession, taskUuid, CloseableIterator.from(singletonList("scanner context of " + taskUuid).iterator()));
  760. dbSession.commit();
  761. }
  762. private List<String> selectPageOfUuids(Pagination pagination) {
  763. return underTest.selectByQuery(db.getSession(), new CeTaskQuery(), pagination).stream()
  764. .map(CeActivityToUuid.INSTANCE::apply)
  765. .toList();
  766. }
  767. private enum CeActivityToUuid implements Function<CeActivityDto, String> {
  768. INSTANCE;
  769. @Override
  770. public String apply(@Nonnull CeActivityDto input) {
  771. return input.getUuid();
  772. }
  773. }
  774. private static String newUuid() {
  775. return UuidFactoryFast.getInstance().create();
  776. }
  777. }