/**
* Copyright (c) 2009-2011, The HATS Consortium. All rights reserved.
* This file is licensed under the terms of the Modified BSD License.
*/
package org.absmodels.abs.plugin.debug.scheduling;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import static org.mockito.Matchers.any;
import static org.mockito.Mockito.doCallRealMethod;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import org.absmodels.abs.plugin.debug.scheduling.GUIScheduler;
import org.absmodels.abs.plugin.debug.scheduling.NStepScheduler;
import org.absmodels.abs.plugin.debug.scheduling.RandomScheduler;
import org.absmodels.abs.plugin.debug.scheduling.RunToLineScheduler;
import org.absmodels.abs.plugin.debug.scheduling.SchedulingStrategy;
import org.absmodels.abs.plugin.debug.scheduling.StepOverScheduler;
import org.absmodels.abs.plugin.debug.scheduling.TotalScheduler;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.mockito.Mockito;
import org.mockito.stubbing.OngoingStubbing;
import abs.backend.java.observing.TaskStackFrameView;
import abs.backend.java.observing.TaskStackView;
import abs.backend.java.observing.TaskView;
import abs.backend.java.scheduling.ScheduleAction;
import abs.backend.java.scheduling.ScheduleOptions;
import abs.backend.java.scheduling.SimpleTaskScheduler.TaskInfo;
import abs.backend.java.scheduling.TaskScheduler;
public class SchedulingTest {
@Before
public void setUp() throws Exception {
}
@After
public void tearDown() throws Exception {
}
@Test
public void testRandomScheduler(){
RandomScheduler rs = new RandomScheduler(new Random());
ScheduleOptions so = mock(ScheduleOptions.class);
List<ScheduleAction> sal = new ArrayList<ScheduleAction>();
for(int i=0; i<100; i++){
sal.add(mock(ScheduleAction.class));
}
when(so.allOptions()).thenReturn(sal);
when(so.numOptions()).thenReturn(100);
ScheduleAction chosenActions;
long seed = new Random().nextLong();
rs = new RandomScheduler(new Random(seed));
List<ScheduleAction> testActions = new ArrayList<ScheduleAction>();
for(int i=0; i<20; i++){
chosenActions = rs.choose(so);
assertTrue(sal.contains(chosenActions));
testActions.add(chosenActions);
}
RandomScheduler rs2 = new RandomScheduler(new Random(seed));
List<ScheduleAction> testActions2 = new ArrayList<ScheduleAction>();
for(int i=0; i<20; i++){
chosenActions = rs2.choose(so);
assertTrue(sal.contains(chosenActions));
testActions2.add(chosenActions);
}
for(int i=0; i<testActions.size(); i++){
assertTrue("Element "+i+" should be equal!", testActions.get(i).equals(testActions2.get(i)));
}
//TODO maybe write test for scheduling
}
// @Test
// public void testRunTaskScheduler(){
// SchedulingStrategy ss = mock(SchedulingStrategy.class);
// TaskView tv = mock(TaskView.class);
// COGView cogv = mock(COGView.class);
// int testCogId = new Random().nextInt();
// int testTaskId = new Random().nextInt();
// when(cogv.getID()).thenReturn(testCogId);
// when(tv.getCOG()).thenReturn(cogv);
// when(tv.getID()).thenReturn(testTaskId);
// RunTaskScheduler rts = new RunTaskScheduler(ss);
// rts.setTask(tv);
//
// ScheduleOptions so = mock(ScheduleOptions.class);
// List<ScheduleAction> sal = new ArrayList<ScheduleAction>();
// ScheduleTask st;
// COG cogfa;
// int cogId = testCogId;
// Random cogIdRandom = new Random();
// for(int i=0; i<40; i++){
// st = mock(ScheduleTask.class);
// while(cogId==testCogId){
// cogId = cogIdRandom.nextInt();
// }
// cogfa = mock(COG.class);
// when(cogfa.getID()).thenReturn(cogId);
// when(st.getCOG()).thenReturn(cogfa);
// sal.add(st);
// }
//
// ScheduleAction sa;
// TaskView tvfa;
// int taskId = testTaskId;
// for(int i=0; i<40; i++){
// sa = mock(ScheduleAction.class);
// while(taskId==testTaskId){
// taskId = cogIdRandom.nextInt();
// }
// tvfa = mock(TaskView.class);
// when(tvfa.getID()).thenReturn(taskId);
// when(sa.getTask()).thenReturn(tvfa);
// sal.add(sa);
// }
//
//
// for(int i=0; i<10; i++){
// st = mock(ScheduleTask.class);
// cogfa = mock(COG.class);
// when(cogfa.getID()).thenReturn(testCogId);
// when(st.getCOG()).thenReturn(cogfa);
// sal.add(st);
// }
// for(int i=0; i<10; i++){
// sa = mock(ScheduleAction.class);
// tvfa = mock(TaskView.class);
// when(tvfa.getID()).thenReturn(testTaskId);
// when(sa.getTask()).thenReturn(tvfa);
// sal.add(sa);
// }
// when(so.allOptions()).thenReturn(sal);
// when(so.numOptions()).thenReturn(100);
//
// //TODO choose and remove actions till no more actions to choose -> switch to GUI
// ScheduleAction csa;
// for(int i=0; i<20; i++){
// csa = rts.choose(so);
// if(csa instanceof ScheduleTask){
// assertEquals("Element "+i+" must correspond to the task.", csa.getCOG().getID(), testCogId);
// } else{
// assertEquals("Element "+i+" must correspond to the task.", csa.getTask().getID(), testTaskId);
// }
// }
// }
@Test
public void testGUIScheduler(){
SchedulingStrategy ss = mock(SchedulingStrategy.class);
doCallRealMethod().when(ss).setBaseScheduler(any(TotalScheduler.class));
doCallRealMethod().when(ss).setCurrentScheduler(any(TotalScheduler.class));
doCallRealMethod().when(ss).doSingleStep();
TotalScheduler ts = mock(TotalScheduler.class);
ScheduleAction scheduleAction = mock(ScheduleAction.class, Mockito.RETURNS_DEEP_STUBS);
when(ts.choose(any(ScheduleOptions.class))).thenReturn(scheduleAction);
TaskInfo taskInfo = mock(TaskInfo.class);
when(ts.schedule(any(TaskScheduler.class), any(List.class))).thenReturn(taskInfo);
ss.setBaseScheduler(ts);
final GUIScheduler gs = new GUIScheduler(ss);
ss.setCurrentScheduler(gs);
Thread schedulingThread = new Thread(new Runnable() {
@Override
public void run() {
ScheduleOptions scheduleOptions = mock(ScheduleOptions.class, Mockito.RETURNS_DEEP_STUBS);
ScheduleAction chosenAction = gs.choose(scheduleOptions);
}
});
try {
schedulingThread.start();
ss.doSingleStep();
schedulingThread.join(1000);
assertEquals(gs, ss.curScheduler);
assertEquals(ts, ss.baseScheduler);
} catch (InterruptedException e) {
fail();
}
}
@Test
public void testNStepScheduler(){
final SchedulingStrategy ss = mock(SchedulingStrategy.class);
doCallRealMethod().when(ss).setBaseScheduler(any(TotalScheduler.class));
doCallRealMethod().when(ss).setCurrentScheduler(any(TotalScheduler.class));
doCallRealMethod().when(ss).doSingleStep();
TotalScheduler ts = mock(TotalScheduler.class);
ScheduleAction scheduleAction = mock(ScheduleAction.class, Mockito.RETURNS_DEEP_STUBS);
when(ts.choose(any(ScheduleOptions.class))).thenReturn(scheduleAction);
TaskInfo taskInfo = mock(TaskInfo.class);
when(ts.schedule(any(TaskScheduler.class), any(List.class))).thenReturn(taskInfo);
ss.setBaseScheduler(ts);
final int numberSteps = new Random().nextInt(100);
final NStepScheduler nss = new NStepScheduler(ss, numberSteps);
ss.setCurrentScheduler(nss);
Thread schedulingThread = new Thread(new Runnable() {
@Override
public void run() {
ScheduleOptions scheduleOptions = mock(ScheduleOptions.class, Mockito.RETURNS_DEEP_STUBS);
for(int i=0; i<numberSteps; i++){
ss.curScheduler.choose(scheduleOptions);
}
assertEquals(nss, ss.curScheduler);
ss.curScheduler.choose(scheduleOptions);
}
});
try {
schedulingThread.start();
schedulingThread.join();
verify(ss).awaitGUIAction(any(ScheduleOptions.class));
} catch (InterruptedException e) {
fail();
}
}
@Test
public void testRunToLineScheduler(){
final SchedulingStrategy ss = mock(SchedulingStrategy.class);
doCallRealMethod().when(ss).setBaseScheduler(any(TotalScheduler.class));
doCallRealMethod().when(ss).setCurrentScheduler(any(TotalScheduler.class));
doCallRealMethod().when(ss).doSingleStep();
TotalScheduler ts = mock(TotalScheduler.class);
ScheduleAction scheduleAction = mock(ScheduleAction.class, Mockito.RETURNS_DEEP_STUBS);
when(ts.choose(any(ScheduleOptions.class))).thenReturn(scheduleAction);
TaskInfo taskInfo = mock(TaskInfo.class);
when(ts.schedule(any(TaskScheduler.class), any(List.class))).thenReturn(taskInfo);
ss.setBaseScheduler(ts);
final int line = new Random().nextInt(1000);
final String fileName = "filename";
abs.backend.java.debugging.TaskInfo ti = mock(abs.backend.java.debugging.TaskInfo.class);
when(ti.getCurrentFile()).thenReturn("filename");
when(ti.getCurrentLine()).thenReturn(line-5)
.thenReturn(line-4)
.thenReturn(line-3)
.thenReturn(line-2)
.thenReturn(line-1)
.thenReturn(line);
ss.steppedTask = ti;
RunToLineScheduler rtls = new RunToLineScheduler(ss, fileName, line);
ss.setCurrentScheduler(rtls);
ScheduleOptions scheduleOptions = mock(ScheduleOptions.class, Mockito.RETURNS_DEEP_STUBS);
for(int i=0; i<6; i++){
ss.curScheduler.choose(scheduleOptions);
}
verify(ss).awaitGUIAction(any(ScheduleOptions.class));
}
@Test
public void testStepOverScheduler(){
final SchedulingStrategy ss = mock(SchedulingStrategy.class);
doCallRealMethod().when(ss).setBaseScheduler(any(TotalScheduler.class));
doCallRealMethod().when(ss).setCurrentScheduler(any(TotalScheduler.class));
doCallRealMethod().when(ss).doSingleStep();
TotalScheduler ts = mock(TotalScheduler.class);
ScheduleAction scheduleAction = mock(ScheduleAction.class, Mockito.RETURNS_DEEP_STUBS);
when(ts.choose(any(ScheduleOptions.class))).thenReturn(scheduleAction);
TaskInfo taskInfo = mock(TaskInfo.class);
when(ts.schedule(any(TaskScheduler.class), any(List.class))).thenReturn(taskInfo);
ss.setBaseScheduler(ts);
TaskStackFrameView tsfv = mock(TaskStackFrameView.class);
StepOverScheduler sos = new StepOverScheduler(ss, tsfv);
ss.setCurrentScheduler(sos);
ScheduleOptions scheduleOptions = mock(ScheduleOptions.class, Mockito.RETURNS_DEEP_STUBS);
ss.curScheduler.choose(scheduleOptions);
verify(ts).reset();
verify(ts).choose(any(ScheduleOptions.class));
abs.backend.java.debugging.TaskInfo ti = mock(abs.backend.java.debugging.TaskInfo.class);
TaskView tv = mock(TaskView.class);
TaskStackView tsv = mock(TaskStackView.class);
when(tsv.hasFrames()).thenReturn(true);
TaskStackFrameView testStackFrame = mock(TaskStackFrameView.class);
OngoingStubbing<TaskStackFrameView> ongoingStubbing = when(tsv.getCurrentFrame()).thenReturn(testStackFrame);
for(int i=0; i<9; i++){
testStackFrame = mock(TaskStackFrameView.class);
ongoingStubbing = ongoingStubbing.thenReturn(testStackFrame);
}
ongoingStubbing.thenReturn(tsfv);
when(tv.getStack()).thenReturn(tsv);
when(ti.getTaskView()).thenReturn(tv);
ss.steppedTask = ti;
for(int i=0; i<10; i++){
ss.curScheduler.choose(scheduleOptions);
}
assertEquals(sos, ss.curScheduler);
verify(ss, never()).awaitGUIAction(any(ScheduleOptions.class));
ss.curScheduler.choose(scheduleOptions);
verify(ss).awaitGUIAction(any(ScheduleOptions.class));
}
}