conf.setSpeculativeExecution(true);
conf.setNumMapTasks(4);
conf.setNumReduceTasks(4);
//use processing rate for speculation
conf.setBoolean("mapreduce.job.speculative.using.processing.rate", true);
FakeJobInProgress job = new FakeJobInProgress(conf, jobTracker);
job.initTasks();
//schedule reduces
taskAttemptID[0] = job.findReduceTask(trackers[0]);
taskAttemptID[1] = job.findReduceTask(trackers[1]);
taskAttemptID[2] = job.findReduceTask(trackers[2]);
taskAttemptID[3] = job.findReduceTask(trackers[3]);
clock.advance(1000);
//task 0 just starts copying, while task 1, 2, 3 are already in the reducing
//phase. If we compared the progress rate, then we should speculate 0.
//However, by comparing the processing rate in the copy phase, among all 4
//tasks, task 0 is fast, and we should not speculate it.
//for task 1, 2, 3, they are all in the reducing phase, with same progress,
//however, task 1 has smaller processing rate(the statistics of the reduce
//phase for all the tasks will also include statistics for task 0, whose
//processing rate is 0)
job.finishCopy(taskAttemptID[1], clock.getTime(), 10000);
job.finishCopy(taskAttemptID[2], clock.getTime(), 10000);
job.finishCopy(taskAttemptID[3], clock.getTime(), 10000);
clock.advance(1000);
job.finishSort(taskAttemptID[1], clock.getTime());
job.finishSort(taskAttemptID[2], clock.getTime());
job.finishSort(taskAttemptID[3], clock.getTime());
job.processingRate(taskAttemptID[0], Task.Counter.REDUCE_SHUFFLE_BYTES,
100000000, 0.1f, TaskStatus.Phase.SHUFFLE);
job.processingRate(taskAttemptID[1], Task.Counter.REDUCE_INPUT_BYTES,
1000, 0.8f, TaskStatus.Phase.REDUCE);
job.processingRate(taskAttemptID[2], Task.Counter.REDUCE_INPUT_BYTES,
100000000, 0.8f, TaskStatus.Phase.REDUCE);
job.processingRate(taskAttemptID[3], Task.Counter.REDUCE_INPUT_BYTES,
100000000, 0.8f, TaskStatus.Phase.REDUCE);
clock.advanceBySpeculativeLag();
//we should get a speculative task now
job.refresh(clock.getTime());
taskAttemptID[4] = job.findReduceTask(trackers[4]);
assertEquals(taskAttemptID[4].getTaskID().getId(),1);
}