1 package jalview.workers;
3 import static org.testng.Assert.*;
5 import java.util.ArrayList;
6 import java.util.concurrent.CancellationException;
7 import java.util.concurrent.CompletableFuture;
8 import java.util.concurrent.ExecutionException;
9 import java.util.concurrent.Future;
10 import org.testng.annotations.AfterMethod;
11 import org.testng.annotations.BeforeClass;
12 import org.testng.annotations.BeforeMethod;
13 import org.testng.annotations.Test;
15 import jalview.api.AlignCalcManagerI2;
16 import jalview.api.AlignCalcWorkerI;
17 import jalview.datamodel.Alignment;
18 import jalview.datamodel.AlignmentAnnotation;
19 import jalview.datamodel.AlignmentI;
20 import jalview.datamodel.Annotation;
21 import jalview.datamodel.Sequence;
22 import jalview.datamodel.SequenceI;
23 import jalview.gui.AlignFrame;
24 import jalview.gui.JvOptionPane;
26 @Test(singleThreaded = true)
27 public class AlignCaclManager2Test
29 AlignFrame alignFrame;
31 AlignCalcManagerI2 calcManager;
33 @BeforeClass(alwaysRun = true)
34 public void setUpClass()
36 JvOptionPane.setInteractiveMode(false);
37 JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
40 @BeforeMethod(alwaysRun = true)
43 AlignmentI al = new Alignment(
44 new SequenceI[] { new Sequence("Seq1", "ABC") });
46 alignFrame = new AlignFrame(al, 3, 1);
47 calcManager = alignFrame.getViewport().getCalcManager();
50 @AfterMethod(alwaysRun = true)
51 public void tearDown()
53 calcManager.shutdown();
58 @Test(groups = "Functional")
59 public void testStartRegisteredWorker() throws InterruptedException
61 var sentinel = new Object();
62 var job = CompletableFuture.completedFuture(sentinel);
63 var worker = new AlignCalcWorkerMock(job);
64 calcManager.registerWorker(worker);
66 assertSame(worker.getLastResult(), sentinel);
69 @Test(groups = "Functional")
70 public void testIsWorking() throws InterruptedException
72 var job = new CompletableFuture<Object>();
73 var worker = new AlignCalcWorkerMock(job);
74 calcManager.registerWorker(worker);
75 assertTrue(calcManager.isWorking(worker));
76 assertTrue(calcManager.isWorking());
79 assertFalse(calcManager.isWorking(worker));
80 assertFalse(calcManager.isWorking());
83 @Test(groups = "Functional")
84 public void testIsWorkingWithAnnotation() throws InterruptedException
86 var job = new CompletableFuture<Void>();
87 var worker1 = new AlignCalcWorkerMock(job);
88 var annot = worker1.annotation = newAlignmentAnnotation();
89 var otherAnnot = newAlignmentAnnotation();
90 calcManager.registerWorker(worker1);
91 assertTrue(calcManager.isWorkingWithAnnotation(annot));
92 assertFalse(calcManager.isWorkingWithAnnotation(otherAnnot));
95 assertFalse(calcManager.isWorkingWithAnnotation(annot));
98 @Test(groups = "Functional")
99 public void testRestartCompletedWorkers() throws Throwable
101 var sentinel1 = new Object();
102 var sentinel2 = new Object();
103 var job = CompletableFuture.completedFuture(sentinel1);
104 var worker = new AlignCalcWorkerMock(job);
105 calcManager.registerWorker(worker);
107 assertSame(worker.getLastResult(), sentinel1);
108 job.obtrudeValue(sentinel2);
109 calcManager.restartWorkers();
111 assertSame(worker.getLastResult(), sentinel2);
114 @Test(groups = "Functional")
115 public void testRestartCancelsWorkers() throws Throwable
117 var job = new CompletableFuture<Object>();
118 var worker = new AlignCalcWorkerMock(job);
119 var sentinel = new Object();
120 calcManager.registerWorker(worker);
122 calcManager.restartWorkers();
124 assertTrue(worker.wasCancelled());
125 job.obtrudeValue(sentinel);
127 assertSame(worker.getLastResult(), sentinel);
132 @Test(groups = "Functional")
133 public void testDisableWorker()
135 var worker = new AlignCalcWorkerMock(null);
136 calcManager.registerWorker(worker);
137 calcManager.disableWorker(worker);
138 assertTrue(calcManager.isDisabled(worker));
139 calcManager.enableWorker(worker);
140 assertFalse(calcManager.isDisabled(worker));
143 @Test(groups = "Functional")
144 public void testRestartDisabledWorker() throws InterruptedException
146 var worker = new AlignCalcWorkerMock(null);
147 calcManager.registerWorker(worker);
149 assertEquals(worker.getCallCount(), 1);
150 calcManager.disableWorker(worker);
151 calcManager.restartWorkers();
153 assertEquals(worker.getCallCount(), 1);
154 calcManager.enableWorker(worker);
155 calcManager.restartWorkers();
157 assertEquals(worker.getCallCount(), 2);
162 @Test(groups = "Functional")
163 public void testCancelWorker() throws InterruptedException
165 var worker = new AlignCalcWorkerMock(new CompletableFuture<>());
166 calcManager.registerWorker(worker);
168 calcManager.cancelWorker(worker);
170 assertTrue(worker.wasCancelled());
175 @Test(groups = "Functional")
176 public void testStartOneShotWorker() throws InterruptedException
178 var job = CompletableFuture.completedFuture("result");
179 var worker = new AlignCalcWorkerMock(job);
180 calcManager.startWorker(worker);
182 assertEquals(worker.getLastResult(), "result");
185 @Test(groups = "Functional")
186 public void testCancelOneShotWorker() throws InterruptedException
188 var worker = new AlignCalcWorkerMock(new CompletableFuture<>());
189 calcManager.startWorker(worker);
191 calcManager.cancelWorker(worker);
193 assertTrue(worker.wasCancelled());
196 @Test(groups = "Functional")
197 public void restartOneShotWorker() throws InterruptedException
199 var job = CompletableFuture.completedFuture("result1");
200 var worker = new AlignCalcWorkerMock(job);
201 calcManager.startWorker(worker);
203 job.obtrudeValue("result2");
204 calcManager.restartWorkers();
210 // Retrieving workers
212 @Test(groups = "Functional")
213 public void testGetWorkersOfClass() throws InterruptedException
215 var worker1 = new AlignCalcWorkerMock(null);
216 var worker2 = new AlignCalcWorkerMock(null);
217 var worker3 = new AlignCalcWorkerMock(null) {};
218 calcManager.registerWorker(worker1);
219 calcManager.registerWorker(worker2);
220 calcManager.registerWorker(worker3);
221 final var workers = calcManager
222 .getWorkersOfClass(AlignCalcWorkerMock.class);
223 assertTrue(workers.contains(worker1) && workers.contains(worker2));
224 assertFalse(workers.contains(worker3));
229 @Test(groups = "Functional")
230 public void testRemoveWorker()
232 var worker = new AlignCalcWorkerMock(null);
233 calcManager.registerWorker(worker);
234 calcManager.removeWorker(worker);
235 assertFalse(calcManager.getWorkers().contains(worker));
238 @Test(groups = "Functional")
239 public void testRemoveWorkersOfClass()
241 var worker1 = new AlignCalcWorkerMock(null);
242 var worker2 = new AlignCalcWorkerMock(null);
243 var worker3 = new AlignCalcWorkerMock(null) {};
244 calcManager.registerWorker(worker1);
245 calcManager.registerWorker(worker2);
246 calcManager.registerWorker(worker3);
247 calcManager.removeWorkersOfClass(worker1.getClass());
248 assertFalse(calcManager.getWorkers().contains(worker1)
249 || calcManager.getWorkers().contains(worker2));
250 assertTrue(calcManager.getWorkers().contains(worker3));
253 @Test(groups = "Functional")
254 public void testRemoveWorkersForAnnotation()
256 var worker1 = new AlignCalcWorkerMock(null);
257 var worker2 = new AlignCalcWorkerMock(null);
258 var annot = worker1.annotation = newAlignmentAnnotation();
259 calcManager.registerWorker(worker1);
260 calcManager.registerWorker(worker2);
261 calcManager.removeWorkerForAnnotation(annot);
262 var workers = calcManager.getWorkers();
263 assertFalse(workers.contains(worker1));
264 assertTrue(workers.contains(worker2));
267 @Test(groups = "Functional")
268 public void testRemoveNonRemovableWorker()
270 var worker = new AlignCalcWorkerMock(null);
271 worker.deletable = false;
272 calcManager.registerWorker(worker);
273 calcManager.removeWorker(worker);
274 assertTrue(calcManager.getWorkers().contains(worker));
277 @Test(groups = "Functional")
278 public void testRemoveNonRemovableWorkersOfClass()
280 var worker1 = new AlignCalcWorkerMock(null);
281 var worker2 = new AlignCalcWorkerMock(null);
282 worker2.deletable = false;
283 calcManager.registerWorker(worker1);
284 calcManager.registerWorker(worker2);
285 calcManager.removeWorkersOfClass(worker1.getClass());
286 var workers = calcManager.getWorkers();
287 assertFalse(workers.contains(worker1));
288 assertTrue(workers.contains(worker2));
291 private int annotationCount = 0;
293 private AlignmentAnnotation newAlignmentAnnotation()
295 return new AlignmentAnnotation("Ann" + annotationCount++, "description",
296 new Annotation[] {});
300 class AlignCalcWorkerMock implements AlignCalcWorkerI
302 AlignmentAnnotation annotation = null;
304 ArrayList<Object> values = new ArrayList<>();
306 boolean deletable = true;
308 AlignCalcWorkerMock(Future<?> job)
313 public Object getLastResult()
315 return values.isEmpty() ? null : values.get(values.size() - 1);
318 public Throwable getException()
320 var result = getLastResult();
321 return (result instanceof Throwable) ? (Throwable) result : null;
324 public int getCallCount() {
328 public boolean wasCancelled()
330 return getException() instanceof InterruptedException;
334 public boolean involves(AlignmentAnnotation annot)
336 if (annotation == null)
339 return annot == annotation;
343 public void updateAnnotation()
348 public void removeAnnotation()
353 public void run() throws Throwable
360 values.add(job.get());
362 catch (InterruptedException e) { values.add(e); }
363 catch (CancellationException e) {
364 values.add(new InterruptedException());
365 } catch (ExecutionException e)
367 values.add(e.getCause());
373 public boolean isDeletable()