package org.drugis.common.threading.status;
import static org.easymock.EasyMock.verify;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.drugis.common.JUnitUtil;
import org.drugis.common.threading.AbstractIterativeComputation;
import org.drugis.common.threading.CompositeTask;
import org.drugis.common.threading.FailureException;
import org.drugis.common.threading.IterativeTask;
import org.drugis.common.threading.NullTask;
import org.drugis.common.threading.SimpleTask;
import org.drugis.common.threading.TaskListener;
import org.drugis.common.threading.activity.MockTask;
import org.drugis.common.threading.event.ListenerManager;
import org.junit.Test;
public class TaskProgressModelTest {
private final class MockComposite implements CompositeTask {
private boolean d_started = false;
public ListenerManager d_mgr = new ListenerManager(this);
private boolean d_finished = false;
private String d_str = null;
public MockComposite() { }
public MockComposite(String str) { d_str = str; }
@Override public String toString() { return d_str != null ? d_str : mkString(); }
public void addTaskListener(TaskListener l) { d_mgr.addTaskListener(l); }
public void removeTaskListener(TaskListener l) { d_mgr.removeTaskListener(l); }
public boolean isStarted() { return d_started; }
public void start() { d_started = true; d_mgr.fireTaskStarted(); }
public boolean isFinished() { return d_finished ; }
public void finish() { d_finished = true; d_mgr.fireTaskFinished(); }
// NI
public boolean isFailed() { return false; }
public boolean isAborted() { return false; }
public Throwable getFailureCause() { return null; }
public List<SimpleTask> getNextTasks() { return null; }
public String mkString() {
return super.toString().substring(super.toString().indexOf('@'));
}
}
static class ShortComputation extends AbstractIterativeComputation {
public ShortComputation(int max) {
super(max);
}
public void doStep() {}
@Override
public String toString() {
return super.toString().substring(super.toString().indexOf('@'));
}
}
@Test
public void testGetSetTask() {
ShortComputation comp = new ShortComputation(100);
IterativeTask task = new IterativeTask(comp);
TaskProgressModel mod = new TaskProgressModel(new NullTask());
mod.setTask(task);
assertTrue(mod.getTask()== task);
}
@Test
public void testSimpleProgress() {
IterativeTask task = new IterativeTask(new ShortComputation(10000));
task.setReportingInterval(10);
TextProgressModel model = new TaskProgressModel(task);
assertEquals(task.toString() + " (waiting)", model.getText());
assertFalse(model.getDeterminate());
task.run();
assertEquals(TaskProgressModel.DONE_TEXT, model.getText());
assertTrue(model.getDeterminate());
assertEquals(1.0, model.getProgress(), 0.0);
}
@Test
public void testSimpleProgressEvents() {
final IterativeTask task = new IterativeTask(new ShortComputation(10000));
task.setReportingInterval(2000);
final TextProgressModel model = new TaskProgressModel(task);
final List<Double> progressEvents = new ArrayList<Double>();
final List<String> textEvents = new ArrayList<String>();
model.addPropertyChangeListener(new PropertyChangeListener() {
public void propertyChange(PropertyChangeEvent evt) {
if (evt.getPropertyName().equals(TextProgressModel.PROPERTY_PROGRESS)) {
progressEvents.add((Double)evt.getNewValue());
}
if (evt.getPropertyName().equals(TextProgressModel.PROPERTY_TEXT)) {
textEvents.add((String)evt.getNewValue());
}
}
});
task.run();
Double[] expected = new Double[] {0.0, 0.0, 0.2, 0.4, 0.6, 0.8, 1.0, 1.0};
assertEquals(Arrays.asList(expected), progressEvents);
String[] expectedStr = new String[] {
task.toString() + ": ?",
task.toString() + ": 0%",
task.toString() + ": 20%",
task.toString() + ": 40%",
task.toString() + ": 60%",
task.toString() + ": 80%",
task.toString() + ": 100%",
TaskProgressModel.DONE_TEXT
};
assertEquals(Arrays.asList(expectedStr), textEvents);
}
@Test
public void testDeterminate() {
final MockTask task = new MockTask();
final TextProgressModel model = new TaskProgressModel(task);
task.start();
PropertyChangeListener mock = JUnitUtil.mockListener(model, TextProgressModel.PROPERTY_DETERMINATE, false, true);
model.addPropertyChangeListener(mock);
task.progress(0, 1000);
verify(mock);
}
@Test
public void testFinishedDeterminate() {
final MockTask task = new MockTask();
final TextProgressModel model = new TaskProgressModel(task);
task.start();
PropertyChangeListener mock = JUnitUtil.mockListener(model, TextProgressModel.PROPERTY_DETERMINATE, false, true);
model.addPropertyChangeListener(mock);
task.finish();
verify(mock);
}
@Test
public void testFailed() {
final MockTask task = new MockTask();
final TextProgressModel model = new TaskProgressModel(task);
task.start();
String failText = task + " " + TaskProgressModel.FAILED_TEXT +": " + "Argh!";
PropertyChangeListener mock1 = JUnitUtil.mockListener(model, TextProgressModel.PROPERTY_DETERMINATE, false, true);
PropertyChangeListener mock2 = JUnitUtil.mockListener(model, TextProgressModel.PROPERTY_TEXT, null, failText);
PropertyChangeListener mock3 = JUnitUtil.mockListener(model, TextProgressModel.PROPERTY_PROGRESS, 0.0, 0.0);
model.addPropertyChangeListener(mock1);
model.addPropertyChangeListener(mock2);
model.addPropertyChangeListener(mock3);
task.fail(new FailureException("Argh!"));
verify(mock1);
verify(mock2);
verify(mock3);
}
@Test
public void testAborted() {
final MockTask task = new MockTask();
final TextProgressModel model = new TaskProgressModel(task);
task.start();
PropertyChangeListener mock1 = JUnitUtil.mockListener(model, TextProgressModel.PROPERTY_DETERMINATE, false, true);
PropertyChangeListener mock2 = JUnitUtil.mockListener(model, TextProgressModel.PROPERTY_TEXT, null,
task.toString() + ": " + TaskProgressModel.ABORTED_TEXT);
PropertyChangeListener mock3 = JUnitUtil.mockListener(model, TextProgressModel.PROPERTY_PROGRESS, 0.0, 0.0);
model.addPropertyChangeListener(mock1);
model.addPropertyChangeListener(mock2);
model.addPropertyChangeListener(mock3);
task.abort();
verify(mock1);
verify(mock2);
verify(mock3);
}
@Test
public void testPhasedProgress() {
MockComposite ctask = new MockComposite();
IterativeTask phase1 = new IterativeTask(new ShortComputation(10000));
IterativeTask phase2 = new IterativeTask(new ShortComputation(10000));
phase1.setReportingInterval(3000);
final TextProgressModel model = new TaskProgressModel(ctask);
assertEquals(ctask.toString() + " (waiting)", model.getText());
ctask.start();
assertEquals(ctask.toString() + ": ?", model.getText());
final List<String> textEvents = new ArrayList<String>();
model.addPropertyChangeListener(new PropertyChangeListener() {
public void propertyChange(PropertyChangeEvent evt) {
if (evt.getPropertyName().equals(TextProgressModel.PROPERTY_TEXT)) {
textEvents.add(model.getText());
}
}
});
ctask.d_mgr.firePhaseStarted(phase1);
phase1.run();
String title1 = ctask.toString() + " (" + phase1.toString() + ": ";
String title2 = ctask.toString() + " (" + phase2.toString() + ": ";
String[] expected = new String[] {
title1 + "?)",
title1 + "0%)",
title1 + "30%)",
title1 + "60%)",
title1 + "90%)",
title1 + "100%)",
ctask.toString() + ": ?",
title2 + "?)",
ctask.toString() + ": ?",
TaskProgressModel.DONE_TEXT
};
ctask.d_mgr.firePhaseFinished(phase1);
ctask.d_mgr.firePhaseStarted(phase2);
assertEquals(false, model.getDeterminate());
ctask.d_mgr.firePhaseFinished(phase2);
ctask.finish();
assertTrue(model.getDeterminate());
assertEquals(Arrays.asList(expected), textEvents);
}
@Test
public void testParallelProgress() {
MockComposite ctask = new MockComposite();
MockComposite phase1 = new MockComposite("phase1");
MockComposite phase2 = new MockComposite("phase2");
final TextProgressModel model = new TaskProgressModel(ctask);
final List<String> text = new ArrayList<String>();
final List<Boolean> determinate = new ArrayList<Boolean>();
model.addPropertyChangeListener(new PropertyChangeListener() {
public void propertyChange(PropertyChangeEvent evt) {
if (evt.getPropertyName().equals(TaskProgressModel.PROPERTY_TEXT)) {
text.add(model.getText());
determinate.add(model.getDeterminate());
}
}
});
final List<String> expStrings = new ArrayList<String>();
final List<Boolean> expDeterminate = new ArrayList<Boolean>();
ctask.start();
expStrings.add(ctask.toString() + ": ?");
expDeterminate.add(false);
ctask.d_mgr.firePhaseStarted(phase1);
expStrings.add(ctask.toString() + " (" + phase1.toString() + ": ?)");
expDeterminate.add(false);
phase1.d_mgr.fireTaskProgress(30, 100);
expStrings.add(ctask.toString() + " (" + phase1.toString() + ": 30%)");
expDeterminate.add(true);
ctask.d_mgr.firePhaseStarted(phase2);
expStrings.add(ctask.toString() + " (" + phase1.toString() + ": 30%, " + phase2.toString() + ": ?)");
expDeterminate.add(false);
assertEquals(expStrings, text);
assertEquals(expDeterminate, determinate);
}
}