X-Git-Url: http://source.jalview.org/gitweb/?a=blobdiff_plain;f=test%2Fjalview%2Fworkers%2FAlignCaclManager2Test.java;fp=test%2Fjalview%2Fworkers%2FAlignCaclManager2Test.java;h=343ad1490f030784c61268307850a6cb37bf0b25;hb=9bad93b13896b84a60fb327acfb496c06a3308d9;hp=0000000000000000000000000000000000000000;hpb=4898f0ae429e0c61ddba72ca46be89b34bb4df8b;p=jalview.git diff --git a/test/jalview/workers/AlignCaclManager2Test.java b/test/jalview/workers/AlignCaclManager2Test.java new file mode 100644 index 0000000..343ad14 --- /dev/null +++ b/test/jalview/workers/AlignCaclManager2Test.java @@ -0,0 +1,377 @@ +package jalview.workers; + +import static org.testng.Assert.*; + +import java.util.ArrayList; +import java.util.concurrent.CancellationException; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.Future; +import org.testng.annotations.AfterMethod; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Test; + +import jalview.api.AlignCalcManagerI2; +import jalview.api.AlignCalcWorkerI; +import jalview.datamodel.Alignment; +import jalview.datamodel.AlignmentAnnotation; +import jalview.datamodel.AlignmentI; +import jalview.datamodel.Annotation; +import jalview.datamodel.Sequence; +import jalview.datamodel.SequenceI; +import jalview.gui.AlignFrame; +import jalview.gui.JvOptionPane; + +@Test(singleThreaded = true) +public class AlignCaclManager2Test +{ + AlignFrame alignFrame; + + AlignCalcManagerI2 calcManager; + + @BeforeClass(alwaysRun = true) + public void setUpClass() + { + JvOptionPane.setInteractiveMode(false); + JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION); + } + + @BeforeMethod(alwaysRun = true) + public void setUp() + { + AlignmentI al = new Alignment( + new SequenceI[] { new Sequence("Seq1", "ABC") }); + al.setDataset(null); + alignFrame = new AlignFrame(al, 3, 1); + calcManager = alignFrame.getViewport().getCalcManager(); + } + + @AfterMethod(alwaysRun = true) + public void tearDown() + { + calcManager.shutdown(); + } + + // Running workers + + @Test(groups = "Functional") + public void testStartRegisteredWorker() throws InterruptedException + { + var sentinel = new Object(); + var job = CompletableFuture.completedFuture(sentinel); + var worker = new AlignCalcWorkerMock(job); + calcManager.registerWorker(worker); + Thread.sleep(10); + assertSame(worker.getLastResult(), sentinel); + } + + @Test(groups = "Functional") + public void testIsWorking() throws InterruptedException + { + var job = new CompletableFuture(); + var worker = new AlignCalcWorkerMock(job); + calcManager.registerWorker(worker); + assertTrue(calcManager.isWorking(worker)); + assertTrue(calcManager.isWorking()); + job.complete(null); + Thread.sleep(10); + assertFalse(calcManager.isWorking(worker)); + assertFalse(calcManager.isWorking()); + } + + @Test(groups = "Functional") + public void testIsWorkingWithAnnotation() throws InterruptedException + { + var job = new CompletableFuture(); + var worker1 = new AlignCalcWorkerMock(job); + var annot = worker1.annotation = newAlignmentAnnotation(); + var otherAnnot = newAlignmentAnnotation(); + calcManager.registerWorker(worker1); + assertTrue(calcManager.isWorkingWithAnnotation(annot)); + assertFalse(calcManager.isWorkingWithAnnotation(otherAnnot)); + job.complete(null); + Thread.sleep(10); + assertFalse(calcManager.isWorkingWithAnnotation(annot)); + } + + @Test(groups = "Functional") + public void testRestartCompletedWorkers() throws Throwable + { + var sentinel1 = new Object(); + var sentinel2 = new Object(); + var job = CompletableFuture.completedFuture(sentinel1); + var worker = new AlignCalcWorkerMock(job); + calcManager.registerWorker(worker); + Thread.sleep(10); + assertSame(worker.getLastResult(), sentinel1); + job.obtrudeValue(sentinel2); + calcManager.restartWorkers(); + Thread.sleep(10); + assertSame(worker.getLastResult(), sentinel2); + } + + @Test(groups = "Functional") + public void testRestartCancelsWorkers() throws Throwable + { + var job = new CompletableFuture(); + var worker = new AlignCalcWorkerMock(job); + var sentinel = new Object(); + calcManager.registerWorker(worker); + Thread.sleep(10); + calcManager.restartWorkers(); + Thread.sleep(10); + assertTrue(worker.wasCancelled()); + job.obtrudeValue(sentinel); + Thread.sleep(10); + assertSame(worker.getLastResult(), sentinel); + } + + // Disabling workers + + @Test(groups = "Functional") + public void testDisableWorker() + { + var worker = new AlignCalcWorkerMock(null); + calcManager.registerWorker(worker); + calcManager.disableWorker(worker); + assertTrue(calcManager.isDisabled(worker)); + calcManager.enableWorker(worker); + assertFalse(calcManager.isDisabled(worker)); + } + + @Test(groups = "Functional") + public void testRestartDisabledWorker() throws InterruptedException + { + var worker = new AlignCalcWorkerMock(null); + calcManager.registerWorker(worker); + Thread.sleep(10); + assertEquals(worker.getCallCount(), 1); + calcManager.disableWorker(worker); + calcManager.restartWorkers(); + Thread.sleep(10); + assertEquals(worker.getCallCount(), 1); + calcManager.enableWorker(worker); + calcManager.restartWorkers(); + Thread.sleep(10); + assertEquals(worker.getCallCount(), 2); + } + + // Canceling workers + + @Test(groups = "Functional") + public void testCancelWorker() throws InterruptedException + { + var worker = new AlignCalcWorkerMock(new CompletableFuture<>()); + calcManager.registerWorker(worker); + Thread.sleep(10); + calcManager.cancelWorker(worker); + Thread.sleep(10); + assertTrue(worker.wasCancelled()); + } + + // One-shot workers + + @Test(groups = "Functional") + public void testStartOneShotWorker() throws InterruptedException + { + var job = CompletableFuture.completedFuture("result"); + var worker = new AlignCalcWorkerMock(job); + calcManager.startWorker(worker); + Thread.sleep(10); + assertEquals(worker.getLastResult(), "result"); + } + + @Test(groups = "Functional") + public void testCancelOneShotWorker() throws InterruptedException + { + var worker = new AlignCalcWorkerMock(new CompletableFuture<>()); + calcManager.startWorker(worker); + Thread.sleep(10); + calcManager.cancelWorker(worker); + Thread.sleep(10); + assertTrue(worker.wasCancelled()); + } + + @Test(groups = "Functional") + public void restartOneShotWorker() throws InterruptedException + { + var job = CompletableFuture.completedFuture("result1"); + var worker = new AlignCalcWorkerMock(job); + calcManager.startWorker(worker); + Thread.sleep(10); + job.obtrudeValue("result2"); + calcManager.restartWorkers(); + Thread.sleep(10); + + } + + + // Retrieving workers + + @Test(groups = "Functional") + public void testGetWorkersOfClass() throws InterruptedException + { + var worker1 = new AlignCalcWorkerMock(null); + var worker2 = new AlignCalcWorkerMock(null); + var worker3 = new AlignCalcWorkerMock(null) {}; + calcManager.registerWorker(worker1); + calcManager.registerWorker(worker2); + calcManager.registerWorker(worker3); + final var workers = calcManager + .getWorkersOfClass(AlignCalcWorkerMock.class); + assertTrue(workers.contains(worker1) && workers.contains(worker2)); + assertFalse(workers.contains(worker3)); + } + + // Removing workers + + @Test(groups = "Functional") + public void testRemoveWorker() + { + var worker = new AlignCalcWorkerMock(null); + calcManager.registerWorker(worker); + calcManager.removeWorker(worker); + assertFalse(calcManager.getWorkers().contains(worker)); + } + + @Test(groups = "Functional") + public void testRemoveWorkersOfClass() + { + var worker1 = new AlignCalcWorkerMock(null); + var worker2 = new AlignCalcWorkerMock(null); + var worker3 = new AlignCalcWorkerMock(null) {}; + calcManager.registerWorker(worker1); + calcManager.registerWorker(worker2); + calcManager.registerWorker(worker3); + calcManager.removeWorkersOfClass(worker1.getClass()); + assertFalse(calcManager.getWorkers().contains(worker1) + || calcManager.getWorkers().contains(worker2)); + assertTrue(calcManager.getWorkers().contains(worker3)); + } + + @Test(groups = "Functional") + public void testRemoveWorkersForAnnotation() + { + var worker1 = new AlignCalcWorkerMock(null); + var worker2 = new AlignCalcWorkerMock(null); + var annot = worker1.annotation = newAlignmentAnnotation(); + calcManager.registerWorker(worker1); + calcManager.registerWorker(worker2); + calcManager.removeWorkerForAnnotation(annot); + var workers = calcManager.getWorkers(); + assertFalse(workers.contains(worker1)); + assertTrue(workers.contains(worker2)); + } + + @Test(groups = "Functional") + public void testRemoveNonRemovableWorker() + { + var worker = new AlignCalcWorkerMock(null); + worker.deletable = false; + calcManager.registerWorker(worker); + calcManager.removeWorker(worker); + assertTrue(calcManager.getWorkers().contains(worker)); + } + + @Test(groups = "Functional") + public void testRemoveNonRemovableWorkersOfClass() + { + var worker1 = new AlignCalcWorkerMock(null); + var worker2 = new AlignCalcWorkerMock(null); + worker2.deletable = false; + calcManager.registerWorker(worker1); + calcManager.registerWorker(worker2); + calcManager.removeWorkersOfClass(worker1.getClass()); + var workers = calcManager.getWorkers(); + assertFalse(workers.contains(worker1)); + assertTrue(workers.contains(worker2)); + } + + private int annotationCount = 0; + + private AlignmentAnnotation newAlignmentAnnotation() + { + return new AlignmentAnnotation("Ann" + annotationCount++, "description", + new Annotation[] {}); + } +} + +class AlignCalcWorkerMock implements AlignCalcWorkerI +{ + AlignmentAnnotation annotation = null; + Future job; + ArrayList values = new ArrayList<>(); + int callCount = 0; + boolean deletable = true; + + AlignCalcWorkerMock(Future job) + { + this.job = job; + } + + public Object getLastResult() + { + return values.isEmpty() ? null : values.get(values.size() - 1); + } + + public Throwable getException() + { + var result = getLastResult(); + return (result instanceof Throwable) ? (Throwable) result : null; + } + + public int getCallCount() { + return callCount; + } + + public boolean wasCancelled() + { + return getException() instanceof InterruptedException; + } + + @Override + public boolean involves(AlignmentAnnotation annot) + { + if (annotation == null) + return false; + else + return annot == annotation; + } + + @Override + public void updateAnnotation() + { + } + + @Override + public void removeAnnotation() + { + } + + @Override + public void run() throws Throwable + { + callCount++; + if (job != null) + { + try + { + values.add(job.get()); + } + catch (InterruptedException e) { values.add(e); } + catch (CancellationException e) { + values.add(new InterruptedException()); + } catch (ExecutionException e) + { + values.add(e.getCause()); + } + } + } + + @Override + public boolean isDeletable() + { + return deletable; + } +}