package com.constellio.model.services.batch.xml.list; import static junit.framework.TestCase.fail; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.Mockito.never; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import org.jdom2.Document; import org.jdom2.Element; import org.joda.time.LocalDateTime; import org.junit.Before; import org.junit.Test; import org.mockito.Mock; import com.constellio.model.entities.batchprocess.BatchProcess; import com.constellio.model.entities.batchprocess.BatchProcessAction; import com.constellio.model.entities.batchprocess.BatchProcessStatus; import com.constellio.sdk.tests.ConstellioTest; public class BatchProcessListWriterTest extends ConstellioTest { private static final String ERRORS = "errors"; private static final String PROGRESSION = "progression"; private static final String ID = "id"; private static final String STRING = "collection"; private static final String BATCH_PROCESS = "batchProcess"; private static final String PREVIOUS_BATCH_PROCESSES = "previousBatchProcesses"; private static final String CURRENT_BATCH_PROCESS = "currentBatchProcess"; private static final String PENDING_BATCH_PROCESSES = "pendingBatchProcesses"; private static final String STANDBY_BATCH_PROCESSES = "standbyBatchProcesses"; Document document; BatchProcessListWriter listWriter; Element rootElement; @Mock BatchProcess batchProcess1; @Mock BatchProcess batchProcess2; @Mock BatchProcess inexistentBatchProcess; @Mock BatchProcessAction action; LocalDateTime localDateTime = aDateTime(); @Before public void setup() throws Exception { when(action.getInstanceParameters()).thenReturn(new Object[] { }); document = new Document(); listWriter = spy(new BatchProcessListWriter(document)); listWriter.createEmptyProcessList(); rootElement = spy(document.getRootElement()); } @Test public void whenCreateEmptyProcessListThenStructureCreated() throws Exception { assertThat(rootElement.getName()).isEqualTo("root"); assertThat(rootElement.getChildren()).hasSize(4); assertThat(rootElement.getChild(PREVIOUS_BATCH_PROCESSES).getContent()).isEmpty(); assertThat(rootElement.getChild(CURRENT_BATCH_PROCESS).getContent()).isEmpty(); assertThat(rootElement.getChild(PENDING_BATCH_PROCESSES).getContent()).isEmpty(); assertThat(rootElement.getChild(STANDBY_BATCH_PROCESSES).getContent()).isEmpty(); } @Test public void whenAddOneBatchProcessThenItIsAddedInPreviousBatchProcessesList() throws Exception { listWriter.addBatchProcess("1", "zeQuery", "zeUltimateCollection", new LocalDateTime(), 1000, action); assertThat(rootElement.getChild(STANDBY_BATCH_PROCESSES).getChildren()).hasSize(1); assertThat(rootElement.getChild(STANDBY_BATCH_PROCESSES).getChild(BATCH_PROCESS).getAttributeValue(ID)).isEqualTo("1"); assertThat(rootElement.getChild(PENDING_BATCH_PROCESSES).getContent()).isEmpty(); assertThat(rootElement.getChild(CURRENT_BATCH_PROCESS).getContent()).isEmpty(); assertThat(rootElement.getChild(PREVIOUS_BATCH_PROCESSES).getContent()).isEmpty(); } @Test public void whenAddTwoBatchProcessesThenTheyAreAddedInStandbyBatchProcessesList() throws Exception { listWriter.addBatchProcess("1", "zeQuery1", "zeUltimateCollection", new LocalDateTime(), 1000, action); listWriter.addBatchProcess("2", "zeQuery2", "zeUltimateCollection", new LocalDateTime(), 1000, action); assertThat(rootElement.getChild(STANDBY_BATCH_PROCESSES).getChildren()).hasSize(2); assertThat(rootElement.getChild(CURRENT_BATCH_PROCESS).getContent()).isEmpty(); assertThat(rootElement.getChild(PENDING_BATCH_PROCESSES).getContent()).isEmpty(); assertThat(rootElement.getChild(PREVIOUS_BATCH_PROCESSES).getContent()).isEmpty(); } @Test public void givenTwoStandbyBatchProcessesWhenCancellingOneThenDeletedAndOtherStillInStandby() throws Exception { listWriter.addBatchProcess("1", "zeQuery1", "zeUltimateCollection", new LocalDateTime(), 1000, action); listWriter.addBatchProcess("2", "zeQuery2", "zeUltimateCollection", new LocalDateTime(), 1000, action); listWriter.cancelStandByBatchProcess("2"); assertThat(rootElement.getChild(STANDBY_BATCH_PROCESSES).getChildren()).hasSize(1); Element firstElement = rootElement.getChild(STANDBY_BATCH_PROCESSES).getChildren().get(0); String id = firstElement.getAttributeValue("id"); assertThat(id).isEqualTo("1"); assertThat(rootElement.getChild(CURRENT_BATCH_PROCESS).getContent()).isEmpty(); assertThat(rootElement.getChild(PENDING_BATCH_PROCESSES).getContent()).isEmpty(); assertThat(rootElement.getChild(PREVIOUS_BATCH_PROCESSES).getContent()).isEmpty(); } @Test public void givenTwoPendingBatchProcessesWhenStartNextBatchProcessThenNextBatchIsMovedToCurrentBactchProcessAndStartTimeIsUpdate() throws Exception { listWriter.addBatchProcess("1", "zeQuery1", "zeUltimateCollection", new LocalDateTime(), 1000, action); listWriter.addBatchProcess("2", "zeQuery2", "zeUltimateCollection", new LocalDateTime(), 1000, action); listWriter.markAllBatchProcessAsPending(); listWriter.startNextBatchProcess(localDateTime); assertThat(rootElement.getChild(PENDING_BATCH_PROCESSES).getChildren()).hasSize(1); assertThat(rootElement.getChild(PENDING_BATCH_PROCESSES).getChild(BATCH_PROCESS).getAttribute(ID).getValue()).isEqualTo( "2"); assertThat(rootElement.getChild(CURRENT_BATCH_PROCESS).getChildren()).hasSize(1); assertThat(rootElement.getChild(CURRENT_BATCH_PROCESS).getChild(BATCH_PROCESS).getAttribute(ID).getValue()) .isEqualTo("1"); assertThat(rootElement.getChild(CURRENT_BATCH_PROCESS).getChild(BATCH_PROCESS).getChild("startDateTime").getText()) .isEqualTo(localDateTime.toString()); assertThat(rootElement.getChild(PREVIOUS_BATCH_PROCESSES).getChildren()).isEmpty(); } @Test(expected = BatchProcessListWriterRuntimeException.NoPendingBatchProcessesInList.class) public void givenNoPendingBacthProcessesWhenStartNextBatchProcessThenException() throws Exception { try { listWriter.startNextBatchProcess(localDateTime); } finally { assertThat(rootElement.getChild(STANDBY_BATCH_PROCESSES).getChildren()).isEmpty(); assertThat(rootElement.getChild(PENDING_BATCH_PROCESSES).getChildren()).isEmpty(); assertThat(rootElement.getChild(CURRENT_BATCH_PROCESS).getChildren()).isEmpty(); assertThat(rootElement.getChild(PREVIOUS_BATCH_PROCESSES).getChildren()).isEmpty(); } } @Test(expected = BatchProcessListWriterRuntimeException.CannotHaveTwoBatchProcessInCurrentBatchProcessList.class) public void givenABatchProcessInCurrentBatchProcessListWhenStartNextBatchProcessThenException() throws Exception { listWriter.addBatchProcess("1", "zeQuery1", "zeUltimateCollection", new LocalDateTime(), 1000, action); listWriter.addBatchProcess("2", "zeQuery2", "zeUltimateCollection", new LocalDateTime(), 1000, action); listWriter.markAllBatchProcessAsPending(); listWriter.startNextBatchProcess(localDateTime); try { listWriter.startNextBatchProcess(localDateTime); } finally { assertThat(rootElement.getChild(STANDBY_BATCH_PROCESSES).getChildren()).isEmpty(); assertThat(rootElement.getChild(PENDING_BATCH_PROCESSES).getChildren()).hasSize(1); assertThat(rootElement.getChild(PREVIOUS_BATCH_PROCESSES).getContent()).isEmpty(); assertThat(rootElement.getChild(CURRENT_BATCH_PROCESS).getChildren()).hasSize(1); } } @Test public void givenABatchProcessInCurrentBatchProcessListWhenMarkBatchProcessAsFinishedThenBatchProcessIsMovedToPreviousProcessesList() throws Exception { when(batchProcess1.getId()).thenReturn("1"); listWriter.addBatchProcess("1", "zeQuery1", "zeUltimateCollection", new LocalDateTime(), 1000, action); listWriter.addBatchProcess("2", "zeQuery2", "zeUltimateCollection", new LocalDateTime(), 1000, action); listWriter.markAllBatchProcessAsPending(); listWriter.startNextBatchProcess(localDateTime); listWriter.markBatchProcessAsFinished(batchProcess1, 0); assertThat(rootElement.getChild(STANDBY_BATCH_PROCESSES).getChildren()).isEmpty(); assertThat(rootElement.getChild(PREVIOUS_BATCH_PROCESSES).getChildren()).hasSize(1); assertThat(rootElement.getChild(PREVIOUS_BATCH_PROCESSES).getChild(BATCH_PROCESS).getAttributeValue(ID)).isEqualTo("1"); assertThat(rootElement.getChild(CURRENT_BATCH_PROCESS).getContent()).isEmpty(); assertThat(rootElement.getChild(PENDING_BATCH_PROCESSES).getChildren()).hasSize(1); } @Test public void givenABatchProcessInPendingBatchProcessListWhenMarkBatchProcessAsFinishedThenBatchProcessIsMovedToPreviousProcessesList() throws Exception { when(batchProcess2.getId()).thenReturn("2"); listWriter.addBatchProcess("1", "zeQuery1", "zeUltimateCollection", new LocalDateTime(), 1000, action); listWriter.addBatchProcess("2", "zeQuery2", "zeUltimateCollection", new LocalDateTime(), 1000, action); listWriter.markBatchProcessAsPending("2"); ; listWriter.startNextBatchProcess(localDateTime); listWriter.markBatchProcessAsFinished(batchProcess2, 0); assertThat(rootElement.getChild(STANDBY_BATCH_PROCESSES).getChildren()).hasSize(1); assertThat(rootElement.getChild(PREVIOUS_BATCH_PROCESSES).getChildren()).hasSize(1); assertThat(rootElement.getChild(CURRENT_BATCH_PROCESS).getChild(BATCH_PROCESS)).isNull(); assertThat(rootElement.getChild(PENDING_BATCH_PROCESSES).getContent()).hasSize(0); } @Test public void givenABatchProcessInPreviousBatchProcessListWhenMarkBatchProcessAsFinishedThenException() throws Exception { when(batchProcess2.getId()).thenReturn("2"); listWriter.addBatchProcess("1", "zeQuery1", "zeUltimateCollection", new LocalDateTime(), 1000, action); listWriter.addBatchProcess("2", "zeQuery2", "zeUltimateCollection", new LocalDateTime(), 1000, action); listWriter.markBatchProcessAsPending("2"); listWriter.startNextBatchProcess(localDateTime); listWriter.markBatchProcessAsFinished(batchProcess2, 0); try { listWriter.markBatchProcessAsFinished(batchProcess2, 0); fail("BatchProcessListWriterRuntimeException.BatchProcessAlreadyFinished expected"); } catch (BatchProcessListWriterRuntimeException.BatchProcessAlreadyFinished e) { //OK } assertThat(rootElement.getChild(STANDBY_BATCH_PROCESSES).getChildren()).hasSize(1); assertThat(rootElement.getChild(PREVIOUS_BATCH_PROCESSES).getChildren()).hasSize(1); assertThat(rootElement.getChild(CURRENT_BATCH_PROCESS).getChild(BATCH_PROCESS)).isNull(); assertThat(rootElement.getChild(PENDING_BATCH_PROCESSES).getContent()).isEmpty(); } @Test(expected = BatchProcessListWriterRuntimeException.BatchProcessNotFound.class) public void givenAInexistentBatchProcessIdWhenMarkBatchProcessAsFinishedThenException() throws Exception { when(inexistentBatchProcess.getId()).thenReturn("3"); listWriter.addBatchProcess("1", "zeQuery1", "zeUltimateCollection", new LocalDateTime(), 1000, action); listWriter.addBatchProcess("2", "zeQuery2", "zeUltimateCollection", new LocalDateTime(), 1000, action); listWriter.markBatchProcessAsPending("1"); listWriter.markBatchProcessAsPending("2"); try { listWriter.markBatchProcessAsFinished(inexistentBatchProcess, 0); } finally { assertThat(rootElement.getChild(PREVIOUS_BATCH_PROCESSES).getContent()).isEmpty(); assertThat(rootElement.getChild(CURRENT_BATCH_PROCESS).getContent()).isEmpty(); assertThat(rootElement.getChild(PENDING_BATCH_PROCESSES).getChildren()).hasSize(2); } } @Test public void whenIncrementProgressionThenHandledRecordsCountAndProgressionAreUpdated() throws Exception { when(batchProcess1.getId()).thenReturn("1"); listWriter.addBatchProcess("1", "zeQuery1", "zeUltimateCollection", new LocalDateTime(), 100, action); listWriter.markBatchProcessAsPending("1"); listWriter.startNextBatchProcess(localDateTime); listWriter.incrementProgression(batchProcess1, 50, 0); assertThat(rootElement.getChild(CURRENT_BATCH_PROCESS).getChild(BATCH_PROCESS).getChild(PROGRESSION).getText()) .isEqualTo("50"); listWriter.incrementProgression(batchProcess1, 30, 0); assertThat(rootElement.getChild(CURRENT_BATCH_PROCESS).getChild(BATCH_PROCESS).getChild(PROGRESSION).getText()) .isEqualTo("80"); } @Test(expected = BatchProcessListWriterRuntimeException.BatchProcessNotFound.class) public void givenInexistentBatchProcessInListWhenIncrementProgressionThenException() throws Exception { when(batchProcess1.getId()).thenReturn("1"); when(batchProcess2.getId()).thenReturn("2"); listWriter.addBatchProcess("1", "zeQuery1", "zeUltimateCollection", new LocalDateTime(), 100, action); listWriter.markBatchProcessAsPending("1"); listWriter.startNextBatchProcess(localDateTime); listWriter.incrementProgression(batchProcess2, 50, 0); } @Test public void givenProgressionCountEqualToRecordsCountWhenIncrementProgressionThenMarkBatchAsFinished() throws Exception { when(batchProcess1.getId()).thenReturn("1"); listWriter.addBatchProcess("1", "zeQuery1", "zeUltimateCollection", new LocalDateTime(), 100, action); listWriter.markBatchProcessAsPending("1"); listWriter.startNextBatchProcess(localDateTime); listWriter.incrementProgression(batchProcess1, 100, 0); verify(listWriter).markBatchProcessAsFinished(batchProcess1, 0); assertThat(batchProcess1.getStatus() == BatchProcessStatus.FINISHED); } @Test public void givenProgressionCountLessThanRecordsCountWhenIncrementProgressionThenBatchProcessNotFinished() throws Exception { when(batchProcess1.getId()).thenReturn("1"); listWriter.addBatchProcess("1", "zeQuery1", "zeUltimateCollection", new LocalDateTime(), 100, action); listWriter.markBatchProcessAsPending("1"); listWriter.startNextBatchProcess(localDateTime); listWriter.incrementProgression(batchProcess1, 50, 0); verify(listWriter, never()).markBatchProcessAsFinished(batchProcess1, 0); assertThat(batchProcess1.getStatus() == BatchProcessStatus.CURRENT); } @Test public void givenErrorsWhenMarkBatchProcessAsFinishedThenErrosCountInErrorList() throws Exception { when(batchProcess1.getId()).thenReturn("1"); listWriter.addBatchProcess("1", "zeQuery1", "zeUltimateCollection", new LocalDateTime(), 1000, action); listWriter.markBatchProcessAsPending("1"); listWriter.startNextBatchProcess(localDateTime); listWriter.markBatchProcessAsFinished(batchProcess1, 20); assertThat(rootElement.getChild(PREVIOUS_BATCH_PROCESSES).getChild(BATCH_PROCESS).getChild(ERRORS).getText()).isEqualTo( "20"); } @Test public void givenErrorsWhenIncrementProgressionThenErrosCountInErrorList() throws Exception { when(batchProcess1.getId()).thenReturn("1"); listWriter.addBatchProcess("1", "zeQuery1", "zeUltimateCollection", new LocalDateTime(), 1000, action); listWriter.markBatchProcessAsPending("1"); listWriter.startNextBatchProcess(localDateTime); listWriter.incrementProgression(batchProcess1, 1000, 100); assertThat(rootElement.getChild(PREVIOUS_BATCH_PROCESSES).getChild(BATCH_PROCESS).getChild(ERRORS).getText()).isEqualTo( "100"); } @Test public void givenTwoBatchProcessPartWith10ErrorsEachWhenIncrementProgressionThenErrosIncremented() throws Exception { when(batchProcess1.getId()).thenReturn("1"); listWriter.addBatchProcess("1", "zeQuery1", "zeUltimateCollection", new LocalDateTime(), 1000, action); listWriter.markBatchProcessAsPending("1"); listWriter.startNextBatchProcess(localDateTime); listWriter.incrementProgression(batchProcess1, 500, 10); listWriter.incrementProgression(batchProcess1, 500, 10); assertThat(rootElement.getChild(PREVIOUS_BATCH_PROCESSES).getChild(BATCH_PROCESS).getChild(ERRORS).getText()).isEqualTo( "20"); } }