PageRenderTime 43ms CodeModel.GetById 27ms app.highlight 13ms RepoModel.GetById 1ms 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 */
 17package nl.overheid.aerius.db.calculator;
 18
 19import static org.junit.jupiter.api.Assertions.assertEquals;
 20import static org.junit.jupiter.api.Assertions.assertFalse;
 21import static org.junit.jupiter.api.Assertions.assertNotNull;
 22import static org.junit.jupiter.api.Assertions.assertNull;
 23import static org.junit.jupiter.api.Assertions.assertSame;
 24import static org.junit.jupiter.api.Assertions.assertTrue;
 25
 26import java.sql.Connection;
 27import java.sql.SQLException;
 28import java.sql.Timestamp;
 29import java.util.Calendar;
 30import java.util.Collections;
 31import java.util.Date;
 32import java.util.List;
 33import java.util.Optional;
 34import java.util.UUID;
 35
 36import org.junit.jupiter.api.Test;
 37
 38import nl.overheid.aerius.db.calculator.JobRepository.RepositoryAttribute;
 39import nl.overheid.aerius.db.connect.ConnectUserRepository;
 40import nl.overheid.aerius.db.test.CalculationRepositoryTestBase;
 41import nl.overheid.aerius.shared.domain.calculation.CalculationState;
 42import nl.overheid.aerius.shared.domain.calculation.JobProgress;
 43import nl.overheid.aerius.shared.domain.calculation.JobState;
 44import nl.overheid.aerius.shared.domain.calculation.JobType;
 45import nl.overheid.aerius.shared.domain.connect.ConnectUser;
 46import nl.overheid.aerius.shared.exception.AeriusException;
 47
 48/**
 49 * Unit test for {@link JobRepository}.
 50 */
 51class JobRepositoryTest extends CalculationRepositoryTestBase {
 52
 53  private static final String TEST_API_KEY = "wnaR9FavGRGv8RXCmdfXKEqeIt1DTZUS";
 54  private static final String TEST_EMAIL = "test@example.com";
 55
 56  @Test
 57  void testGetUnexistingJobId() throws SQLException {
 58    final int jobId = JobRepository.getJobId(getCalcConnection(), UUID.randomUUID().toString());
 59    assertEquals(0, jobId, "No job id should be found");
 60  }
 61
 62  @Test
 63  void testGetUnexistingJobProgress() throws SQLException {
 64    final JobProgress jp = JobRepository.getProgress(getCalcConnection(), UUID.randomUUID().toString());
 65    assertNull(jp, "No job progress should be found");
 66  }
 67
 68  @Test
 69  void testCreateEmptyJobWithoutCalculations() throws SQLException, AeriusException {
 70    final ConnectUser user = setupUser();
 71    final String correlationIdentifier = JobRepository.createJob(getCalcConnection(), user, JobType.CALCULATION);
 72    assertFalse(correlationIdentifier.isEmpty(), "correlationIdentifier shouldn't be empty");
 73
 74    final JobProgress jp = JobRepository.getProgress(getCalcConnection(), correlationIdentifier);
 75    validateEmptyProgress(jp);
 76    assertSame(JobState.INITIALIZED, jp.getState(), "State may must be initialized");
 77    assertNull(jp.getCreationDateTime(), "Creation time may not be set");
 78    assertNull(jp.getName(), "Name should not be set");
 79  }
 80
 81  @Test
 82  void testCreateEmptyJobWithCalculations() throws SQLException, AeriusException {
 83    final ConnectUser user = setupUser();
 84    final String correlationIdentifier = JobRepository.createJob(getCalcConnection(), user, JobType.CALCULATION);
 85    insertCalculationResults();
 86    JobRepository.attachCalculations(getCalcConnection(), correlationIdentifier, Collections.singletonList(calculation));
 87
 88    final JobProgress jp = JobRepository.getProgress(getCalcConnection(), correlationIdentifier);
 89    validateEmptyProgress(jp);
 90    assertEquals(JobState.RUNNING, jp.getState(), "State must be initialized");
 91    assertNotNull(jp.getCreationDateTime(), "Creation time must be set");
 92    assertFalse(jp.getCreationDateTime().getTime() > new Date().getTime(), "Creation time can't be in the future");
 93    assertTrue(calculation.getCreationDate().getTime() < jp.getCreationDateTime().getTime(), "Creation time must match that of the calculation");
 94  }
 95
 96  @Test
 97  void testUpdateJobProgress() throws SQLException, AeriusException {
 98    final ConnectUser user = setupUser();
 99    final String testName = "My very long and weird job name.. GI%4j5h4g4jgR$_ 43-A";
100    final String correlationIdentifier = JobRepository.createJob(getCalcConnection(), user, JobType.CALCULATION, Optional.of(testName));
101    JobProgress jp;
102
103    JobRepository.increaseHexagonCounter(getCalcConnection(), correlationIdentifier, 1);
104    jp = JobRepository.getProgress(getCalcConnection(), correlationIdentifier);
105    assertEquals(JobType.CALCULATION, jp.getType(), "Type must be a calculation");
106    assertEquals(1, jp.getHexagonCount(), "Hexagon counter must be incremented");
107    assertEquals(testName, jp.getName(), "Name must be updated");
108    assertNotNull(jp.getStartDateTime(), "Start time must be set");
109    assertFalse(jp.getStartDateTime().getTime() > new Date().getTime(), "Start time can't be in the future");
110
111    JobRepository.increaseHexagonCounter(getCalcConnection(), correlationIdentifier, 12345);
112    jp = JobRepository.getProgress(getCalcConnection(), correlationIdentifier);
113    assertEquals(1 + 12345, jp.getHexagonCount(), "Hexagon counter must be incremented");
114
115    JobRepository.setEndTimeToNow(getCalcConnection(), correlationIdentifier);
116    jp = JobRepository.getProgress(getCalcConnection(), correlationIdentifier);
117    assertNotNull(jp.getEndDateTime(), "End time must be set");
118    assertFalse(jp.getEndDateTime().getTime() > new Date().getTime(), "End time can't be in the future");
119
120    JobRepository.setResultUrl(getCalcConnection(), correlationIdentifier, "abc");
121    jp = JobRepository.getProgress(getCalcConnection(), correlationIdentifier);
122    assertNotNull(jp.getResultUrl(), "Result url must be set");
123
124    // Ensure getProgressForUser gives same result
125    final List<JobProgress> jpl = JobRepository.getProgressForUser(getCalcConnection(), user);
126    assertEquals(1, jpl.size(), "User must have 1 progress result");
127    jp = jpl.get(0);
128    assertEquals(1 + 12345, jp.getHexagonCount(), "Hexagon counter must be incremented");
129    assertNotNull(jp.getStartDateTime(), "Start time must be set");
130    assertFalse(jp.getStartDateTime().getTime() > new Date().getTime(), "Start time can't be in the future");
131    assertNotNull(jp.getEndDateTime(), "End time must be set");
132    assertFalse(jp.getEndDateTime().getTime() > new Date().getTime(), "End time can't be in the future");
133    assertNotNull(jp.getResultUrl(), "Result url must be set");
134    assertNotNull(jp.getKey(), "Key should be present");
135  }
136
137  @Test
138  void testGetCalculationsProgressForUser() throws SQLException, AeriusException {
139    List<JobProgress> progresses;
140
141    final ConnectUser user = setupUser();
142    assertJobProgressAmount(user, 0);
143
144    final String correlationIdentifier1 = JobRepository.createJob(getCalcConnection(), user, JobType.CALCULATION);
145    final String correlationIdentifier2 = JobRepository.createJob(getCalcConnection(), user, JobType.CALCULATION);
146
147    assertJobProgressAmount(user, 2);
148
149    progresses = JobRepository.getProgressForUser(getCalcConnection(), user);
150    final JobProgress jp1a = progresses.get(0); // order by job_id
151    final JobProgress jp2a = progresses.get(1);
152    assertEquals(0, jp1a.getHexagonCount(), "Hexagon counter must be 0 (1st entry)");
153    assertEquals(0, jp2a.getHexagonCount(), "Hexagon counter must be 0 (2nd entry)");
154    assertNotNull(jp1a.getStartDateTime(), "Start time must be set (1st entry)");
155    assertNotNull(jp2a.getStartDateTime(), "Start time must be set (2nd entry)");
156
157    JobRepository.increaseHexagonCounter(getCalcConnection(), correlationIdentifier1, 12345);
158    progresses = JobRepository.getProgressForUser(getCalcConnection(), user);
159    final JobProgress jp1b = progresses.get(0);
160    final JobProgress jp2b = progresses.get(1);
161    assertEquals(12345, jp1b.getHexagonCount(), "Hexagon counter must be 0 (1st entry)");
162    assertEquals(0, jp2b.getHexagonCount(), "Hexagon counter must still be 0 (2nd entry)");
163    assertNotNull(jp1b.getStartDateTime(), "Start time must be set (2nd entry)");
164    assertNotNull(jp2b.getStartDateTime(), "Start time must be set (2nd entry)");
165  }
166
167  @Test
168  void testRemoveJobsWithMinAge() throws SQLException, AeriusException {
169    final ConnectUser user = setupUser();
170    final int jobCountOffset = JobRepository.removeJobsWithMinAge(getCalcConnection(), 5);
171
172    final String correlationIdentifier1 = JobRepository.createJob(getCalcConnection(), user, JobType.CALCULATION);
173    insertCalculationResults();
174    JobRepository.attachCalculations(getCalcConnection(), correlationIdentifier1, Collections.singletonList(calculation));
175    CalculationRepository.updateCalculationState(getCalcConnection(), calculation.getCalculationId(), CalculationState.COMPLETED);
176    JobRepository.updateJobStatus(getCalcConnection(), correlationIdentifier1, JobState.COMPLETED);
177    newCalculation();
178    final String correlationIdentifier2 = JobRepository.createJob(getCalcConnection(), user, JobType.REPORT);
179    insertCalculationResults();
180    JobRepository.attachCalculations(getCalcConnection(), correlationIdentifier2, Collections.singletonList(calculation));
181    CalculationRepository.updateCalculationState(getCalcConnection(), calculation.getCalculationId(), CalculationState.COMPLETED);
182    JobRepository.updateJobStatus(getCalcConnection(), correlationIdentifier2, JobState.COMPLETED);
183    newCalculation();
184    final String correlationIdentifier3 = JobRepository.createJob(getCalcConnection(), user, JobType.CALCULATION);
185    insertCalculationResults();
186    JobRepository.attachCalculations(getCalcConnection(), correlationIdentifier3, Collections.singletonList(calculation));
187    CalculationRepository.updateCalculationState(getCalcConnection(), calculation.getCalculationId(), CalculationState.COMPLETED);
188    JobRepository.updateJobStatus(getCalcConnection(), correlationIdentifier3, JobState.COMPLETED);
189
190    final Calendar calendar = Calendar.getInstance();
191    calendar.add(Calendar.MINUTE, -10); // so the timestamps created have the amount of days + 10 minutes of age
192    calendar.add(Calendar.DAY_OF_YEAR, -1);
193    final Date endTimeJob1 = calendar.getTime();
194    calendar.add(Calendar.DAY_OF_YEAR, -1);
195    final Date startTimeJob2 = calendar.getTime();
196    calendar.add(Calendar.DAY_OF_YEAR, -1);
197    final Date endTimeJob3 = calendar.getTime();
198
199    JobRepository.updateField(getCalcConnection(), correlationIdentifier1, RepositoryAttribute.END_TIME, new Timestamp(endTimeJob1.getTime()));
200    JobRepository.updateField(getCalcConnection(), correlationIdentifier2, RepositoryAttribute.START_TIME, new Timestamp(startTimeJob2.getTime()));
201    JobRepository.updateField(getCalcConnection(), correlationIdentifier2, RepositoryAttribute.END_TIME, null);
202    JobRepository.updateField(getCalcConnection(), correlationIdentifier3, RepositoryAttribute.END_TIME, new Timestamp(endTimeJob3.getTime()));
203
204    // start point - I am expecting 3 jobs
205    assertJobProgressAmount(user, 3);
206
207    assertEquals(jobCountOffset, JobRepository.removeJobsWithMinAge(getCalcConnection(), 5), "There should be 0 removals");
208    assertJobProgressAmount(user, 3);
209
210    assertEquals(jobCountOffset + 1, JobRepository.removeJobsWithMinAge(getCalcConnection(), 3), "There should be 1 removal");
211    assertJobProgressAmount(user, 2);
212
213    assertEquals(jobCountOffset + 2, JobRepository.removeJobsWithMinAge(getCalcConnection(), 0), "There should be 2 removals");
214    assertJobProgressAmount(user, 0);
215  }
216
217  @Override
218  protected Connection getConnection() throws SQLException {
219    return getCalcConnection();
220  }
221
222  private ConnectUser setupUser() throws SQLException, AeriusException {
223    final ConnectUser user = new ConnectUser();
224    user.setApiKey(TEST_API_KEY);
225    user.setEmailAddress(TEST_EMAIL);
226    ConnectUserRepository.createUser(getCalcConnection(), user);
227    return user;
228  }
229
230  private void assertJobProgressAmount(final ConnectUser user, final int amount) throws SQLException {
231    assertEquals(amount, JobRepository.getProgressForUser(getCalcConnection(), user).size(), "Couldn't find the expected amount of jobs");
232  }
233
234  private void validateEmptyProgress(final JobProgress jp) throws SQLException {
235    assertNotNull(jp, "Job progress should be found");
236    assertEquals(JobType.CALCULATION, jp.getType(), "Job type must be a calculation");
237    assertEquals(0, jp.getHexagonCount(), "Hexagon counter must be 0");
238    assertNotNull(jp.getStartDateTime(), "Start time must be set");
239    assertNull(jp.getEndDateTime(), "End time may not be set");
240    assertNull(jp.getResultUrl(), "Result url may not be set");
241    assertNotNull(jp.getKey(), "jobKey should be present");
242  }
243
244}