PageRenderTime 55ms CodeModel.GetById 26ms RepoModel.GetById 0ms app.codeStats 0ms

/source/commons-aerius/aerius-commons-repository/src/test/java/nl/overheid/aerius/db/calculator/JobRepositoryTest.java

https://gitlab.com/AERIUS/AERIUS
Java | 244 lines | 186 code | 37 blank | 21 comment | 0 complexity | b845fe214c3f1e2cbe2610858be97571 MD5 | raw file
  1. /*
  2. * Copyright the State of the Netherlands
  3. *
  4. * This program is free software: you can redistribute it and/or modify
  5. * it under the terms of the GNU Affero General Public License as published by
  6. * the Free Software Foundation, either version 3 of the License, or
  7. * (at your option) any later version.
  8. *
  9. * This program is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. * GNU Affero General Public License for more details.
  13. *
  14. * You should have received a copy of the GNU Affero General Public License
  15. * along with this program. If not, see http://www.gnu.org/licenses/.
  16. */
  17. package nl.overheid.aerius.db.calculator;
  18. import static org.junit.jupiter.api.Assertions.assertEquals;
  19. import static org.junit.jupiter.api.Assertions.assertFalse;
  20. import static org.junit.jupiter.api.Assertions.assertNotNull;
  21. import static org.junit.jupiter.api.Assertions.assertNull;
  22. import static org.junit.jupiter.api.Assertions.assertSame;
  23. import static org.junit.jupiter.api.Assertions.assertTrue;
  24. import java.sql.Connection;
  25. import java.sql.SQLException;
  26. import java.sql.Timestamp;
  27. import java.util.Calendar;
  28. import java.util.Collections;
  29. import java.util.Date;
  30. import java.util.List;
  31. import java.util.Optional;
  32. import java.util.UUID;
  33. import org.junit.jupiter.api.Test;
  34. import nl.overheid.aerius.db.calculator.JobRepository.RepositoryAttribute;
  35. import nl.overheid.aerius.db.connect.ConnectUserRepository;
  36. import nl.overheid.aerius.db.test.CalculationRepositoryTestBase;
  37. import nl.overheid.aerius.shared.domain.calculation.CalculationState;
  38. import nl.overheid.aerius.shared.domain.calculation.JobProgress;
  39. import nl.overheid.aerius.shared.domain.calculation.JobState;
  40. import nl.overheid.aerius.shared.domain.calculation.JobType;
  41. import nl.overheid.aerius.shared.domain.connect.ConnectUser;
  42. import nl.overheid.aerius.shared.exception.AeriusException;
  43. /**
  44. * Unit test for {@link JobRepository}.
  45. */
  46. class JobRepositoryTest extends CalculationRepositoryTestBase {
  47. private static final String TEST_API_KEY = "wnaR9FavGRGv8RXCmdfXKEqeIt1DTZUS";
  48. private static final String TEST_EMAIL = "test@example.com";
  49. @Test
  50. void testGetUnexistingJobId() throws SQLException {
  51. final int jobId = JobRepository.getJobId(getCalcConnection(), UUID.randomUUID().toString());
  52. assertEquals(0, jobId, "No job id should be found");
  53. }
  54. @Test
  55. void testGetUnexistingJobProgress() throws SQLException {
  56. final JobProgress jp = JobRepository.getProgress(getCalcConnection(), UUID.randomUUID().toString());
  57. assertNull(jp, "No job progress should be found");
  58. }
  59. @Test
  60. void testCreateEmptyJobWithoutCalculations() throws SQLException, AeriusException {
  61. final ConnectUser user = setupUser();
  62. final String correlationIdentifier = JobRepository.createJob(getCalcConnection(), user, JobType.CALCULATION);
  63. assertFalse(correlationIdentifier.isEmpty(), "correlationIdentifier shouldn't be empty");
  64. final JobProgress jp = JobRepository.getProgress(getCalcConnection(), correlationIdentifier);
  65. validateEmptyProgress(jp);
  66. assertSame(JobState.INITIALIZED, jp.getState(), "State may must be initialized");
  67. assertNull(jp.getCreationDateTime(), "Creation time may not be set");
  68. assertNull(jp.getName(), "Name should not be set");
  69. }
  70. @Test
  71. void testCreateEmptyJobWithCalculations() throws SQLException, AeriusException {
  72. final ConnectUser user = setupUser();
  73. final String correlationIdentifier = JobRepository.createJob(getCalcConnection(), user, JobType.CALCULATION);
  74. insertCalculationResults();
  75. JobRepository.attachCalculations(getCalcConnection(), correlationIdentifier, Collections.singletonList(calculation));
  76. final JobProgress jp = JobRepository.getProgress(getCalcConnection(), correlationIdentifier);
  77. validateEmptyProgress(jp);
  78. assertEquals(JobState.RUNNING, jp.getState(), "State must be initialized");
  79. assertNotNull(jp.getCreationDateTime(), "Creation time must be set");
  80. assertFalse(jp.getCreationDateTime().getTime() > new Date().getTime(), "Creation time can't be in the future");
  81. assertTrue(calculation.getCreationDate().getTime() < jp.getCreationDateTime().getTime(), "Creation time must match that of the calculation");
  82. }
  83. @Test
  84. void testUpdateJobProgress() throws SQLException, AeriusException {
  85. final ConnectUser user = setupUser();
  86. final String testName = "My very long and weird job name.. GI%4j5h4g4jgR$_ 43-A";
  87. final String correlationIdentifier = JobRepository.createJob(getCalcConnection(), user, JobType.CALCULATION, Optional.of(testName));
  88. JobProgress jp;
  89. JobRepository.increaseHexagonCounter(getCalcConnection(), correlationIdentifier, 1);
  90. jp = JobRepository.getProgress(getCalcConnection(), correlationIdentifier);
  91. assertEquals(JobType.CALCULATION, jp.getType(), "Type must be a calculation");
  92. assertEquals(1, jp.getHexagonCount(), "Hexagon counter must be incremented");
  93. assertEquals(testName, jp.getName(), "Name must be updated");
  94. assertNotNull(jp.getStartDateTime(), "Start time must be set");
  95. assertFalse(jp.getStartDateTime().getTime() > new Date().getTime(), "Start time can't be in the future");
  96. JobRepository.increaseHexagonCounter(getCalcConnection(), correlationIdentifier, 12345);
  97. jp = JobRepository.getProgress(getCalcConnection(), correlationIdentifier);
  98. assertEquals(1 + 12345, jp.getHexagonCount(), "Hexagon counter must be incremented");
  99. JobRepository.setEndTimeToNow(getCalcConnection(), correlationIdentifier);
  100. jp = JobRepository.getProgress(getCalcConnection(), correlationIdentifier);
  101. assertNotNull(jp.getEndDateTime(), "End time must be set");
  102. assertFalse(jp.getEndDateTime().getTime() > new Date().getTime(), "End time can't be in the future");
  103. JobRepository.setResultUrl(getCalcConnection(), correlationIdentifier, "abc");
  104. jp = JobRepository.getProgress(getCalcConnection(), correlationIdentifier);
  105. assertNotNull(jp.getResultUrl(), "Result url must be set");
  106. // Ensure getProgressForUser gives same result
  107. final List<JobProgress> jpl = JobRepository.getProgressForUser(getCalcConnection(), user);
  108. assertEquals(1, jpl.size(), "User must have 1 progress result");
  109. jp = jpl.get(0);
  110. assertEquals(1 + 12345, jp.getHexagonCount(), "Hexagon counter must be incremented");
  111. assertNotNull(jp.getStartDateTime(), "Start time must be set");
  112. assertFalse(jp.getStartDateTime().getTime() > new Date().getTime(), "Start time can't be in the future");
  113. assertNotNull(jp.getEndDateTime(), "End time must be set");
  114. assertFalse(jp.getEndDateTime().getTime() > new Date().getTime(), "End time can't be in the future");
  115. assertNotNull(jp.getResultUrl(), "Result url must be set");
  116. assertNotNull(jp.getKey(), "Key should be present");
  117. }
  118. @Test
  119. void testGetCalculationsProgressForUser() throws SQLException, AeriusException {
  120. List<JobProgress> progresses;
  121. final ConnectUser user = setupUser();
  122. assertJobProgressAmount(user, 0);
  123. final String correlationIdentifier1 = JobRepository.createJob(getCalcConnection(), user, JobType.CALCULATION);
  124. final String correlationIdentifier2 = JobRepository.createJob(getCalcConnection(), user, JobType.CALCULATION);
  125. assertJobProgressAmount(user, 2);
  126. progresses = JobRepository.getProgressForUser(getCalcConnection(), user);
  127. final JobProgress jp1a = progresses.get(0); // order by job_id
  128. final JobProgress jp2a = progresses.get(1);
  129. assertEquals(0, jp1a.getHexagonCount(), "Hexagon counter must be 0 (1st entry)");
  130. assertEquals(0, jp2a.getHexagonCount(), "Hexagon counter must be 0 (2nd entry)");
  131. assertNotNull(jp1a.getStartDateTime(), "Start time must be set (1st entry)");
  132. assertNotNull(jp2a.getStartDateTime(), "Start time must be set (2nd entry)");
  133. JobRepository.increaseHexagonCounter(getCalcConnection(), correlationIdentifier1, 12345);
  134. progresses = JobRepository.getProgressForUser(getCalcConnection(), user);
  135. final JobProgress jp1b = progresses.get(0);
  136. final JobProgress jp2b = progresses.get(1);
  137. assertEquals(12345, jp1b.getHexagonCount(), "Hexagon counter must be 0 (1st entry)");
  138. assertEquals(0, jp2b.getHexagonCount(), "Hexagon counter must still be 0 (2nd entry)");
  139. assertNotNull(jp1b.getStartDateTime(), "Start time must be set (2nd entry)");
  140. assertNotNull(jp2b.getStartDateTime(), "Start time must be set (2nd entry)");
  141. }
  142. @Test
  143. void testRemoveJobsWithMinAge() throws SQLException, AeriusException {
  144. final ConnectUser user = setupUser();
  145. final int jobCountOffset = JobRepository.removeJobsWithMinAge(getCalcConnection(), 5);
  146. final String correlationIdentifier1 = JobRepository.createJob(getCalcConnection(), user, JobType.CALCULATION);
  147. insertCalculationResults();
  148. JobRepository.attachCalculations(getCalcConnection(), correlationIdentifier1, Collections.singletonList(calculation));
  149. CalculationRepository.updateCalculationState(getCalcConnection(), calculation.getCalculationId(), CalculationState.COMPLETED);
  150. JobRepository.updateJobStatus(getCalcConnection(), correlationIdentifier1, JobState.COMPLETED);
  151. newCalculation();
  152. final String correlationIdentifier2 = JobRepository.createJob(getCalcConnection(), user, JobType.REPORT);
  153. insertCalculationResults();
  154. JobRepository.attachCalculations(getCalcConnection(), correlationIdentifier2, Collections.singletonList(calculation));
  155. CalculationRepository.updateCalculationState(getCalcConnection(), calculation.getCalculationId(), CalculationState.COMPLETED);
  156. JobRepository.updateJobStatus(getCalcConnection(), correlationIdentifier2, JobState.COMPLETED);
  157. newCalculation();
  158. final String correlationIdentifier3 = JobRepository.createJob(getCalcConnection(), user, JobType.CALCULATION);
  159. insertCalculationResults();
  160. JobRepository.attachCalculations(getCalcConnection(), correlationIdentifier3, Collections.singletonList(calculation));
  161. CalculationRepository.updateCalculationState(getCalcConnection(), calculation.getCalculationId(), CalculationState.COMPLETED);
  162. JobRepository.updateJobStatus(getCalcConnection(), correlationIdentifier3, JobState.COMPLETED);
  163. final Calendar calendar = Calendar.getInstance();
  164. calendar.add(Calendar.MINUTE, -10); // so the timestamps created have the amount of days + 10 minutes of age
  165. calendar.add(Calendar.DAY_OF_YEAR, -1);
  166. final Date endTimeJob1 = calendar.getTime();
  167. calendar.add(Calendar.DAY_OF_YEAR, -1);
  168. final Date startTimeJob2 = calendar.getTime();
  169. calendar.add(Calendar.DAY_OF_YEAR, -1);
  170. final Date endTimeJob3 = calendar.getTime();
  171. JobRepository.updateField(getCalcConnection(), correlationIdentifier1, RepositoryAttribute.END_TIME, new Timestamp(endTimeJob1.getTime()));
  172. JobRepository.updateField(getCalcConnection(), correlationIdentifier2, RepositoryAttribute.START_TIME, new Timestamp(startTimeJob2.getTime()));
  173. JobRepository.updateField(getCalcConnection(), correlationIdentifier2, RepositoryAttribute.END_TIME, null);
  174. JobRepository.updateField(getCalcConnection(), correlationIdentifier3, RepositoryAttribute.END_TIME, new Timestamp(endTimeJob3.getTime()));
  175. // start point - I am expecting 3 jobs
  176. assertJobProgressAmount(user, 3);
  177. assertEquals(jobCountOffset, JobRepository.removeJobsWithMinAge(getCalcConnection(), 5), "There should be 0 removals");
  178. assertJobProgressAmount(user, 3);
  179. assertEquals(jobCountOffset + 1, JobRepository.removeJobsWithMinAge(getCalcConnection(), 3), "There should be 1 removal");
  180. assertJobProgressAmount(user, 2);
  181. assertEquals(jobCountOffset + 2, JobRepository.removeJobsWithMinAge(getCalcConnection(), 0), "There should be 2 removals");
  182. assertJobProgressAmount(user, 0);
  183. }
  184. @Override
  185. protected Connection getConnection() throws SQLException {
  186. return getCalcConnection();
  187. }
  188. private ConnectUser setupUser() throws SQLException, AeriusException {
  189. final ConnectUser user = new ConnectUser();
  190. user.setApiKey(TEST_API_KEY);
  191. user.setEmailAddress(TEST_EMAIL);
  192. ConnectUserRepository.createUser(getCalcConnection(), user);
  193. return user;
  194. }
  195. private void assertJobProgressAmount(final ConnectUser user, final int amount) throws SQLException {
  196. assertEquals(amount, JobRepository.getProgressForUser(getCalcConnection(), user).size(), "Couldn't find the expected amount of jobs");
  197. }
  198. private void validateEmptyProgress(final JobProgress jp) throws SQLException {
  199. assertNotNull(jp, "Job progress should be found");
  200. assertEquals(JobType.CALCULATION, jp.getType(), "Job type must be a calculation");
  201. assertEquals(0, jp.getHexagonCount(), "Hexagon counter must be 0");
  202. assertNotNull(jp.getStartDateTime(), "Start time must be set");
  203. assertNull(jp.getEndDateTime(), "End time may not be set");
  204. assertNull(jp.getResultUrl(), "Result url may not be set");
  205. assertNotNull(jp.getKey(), "jobKey should be present");
  206. }
  207. }