public void testBasicSpeculation(boolean withProgress) throws Exception { DAG dag = DAG.create("test"); Vertex vA = Vertex.create("A", ProcessorDescriptor.create("Proc.class"), 5); dag.addVertex(vA); MockTezClient tezClient = createTezSession(); DAGClient dagClient = tezClient.submitDAG(dag); DAGImpl dagImpl = (DAGImpl) mockApp.getContext().getCurrentDAG(); TezVertexID vertexId = TezVertexID.getInstance(dagImpl.getID(), 0); // original attempt is killed and speculative one is successful TezTaskAttemptID killedTaId = TezTaskAttemptID.getInstance(TezTaskID.getInstance(vertexId, 0), 0); TezTaskAttemptID successTaId = TezTaskAttemptID.getInstance(TezTaskID.getInstance(vertexId, 0), 1); mockLauncher.updateProgress(withProgress); // cause speculation trigger mockLauncher.setStatusUpdatesForTask(killedTaId, 100); mockLauncher.startScheduling(true); dagClient.waitForCompletion(); Assert.assertEquals(DAGStatus.State.SUCCEEDED, dagClient.getDAGStatus(null).getState()); Task task = dagImpl.getTask(killedTaId.getTaskID()); Assert.assertEquals(2, task.getAttempts().size()); Assert.assertEquals(successTaId, task.getSuccessfulAttempt().getID()); TaskAttempt killedAttempt = task.getAttempt(killedTaId); Joiner.on(",").join(killedAttempt.getDiagnostics()).contains("Killed as speculative attempt"); Assert.assertEquals( TaskAttemptTerminationCause.TERMINATED_EFFECTIVE_SPECULATION, killedAttempt.getTerminationCause()); if (withProgress) { // without progress updates occasionally more than 1 task speculates Assert.assertEquals( 1, task.getCounters().findCounter(TaskCounter.NUM_SPECULATIONS).getValue()); Assert.assertEquals( 1, dagImpl.getAllCounters().findCounter(TaskCounter.NUM_SPECULATIONS).getValue()); org.apache.tez.dag.app.dag.Vertex v = dagImpl.getVertex(killedTaId.getTaskID().getVertexID()); Assert.assertEquals( 1, v.getAllCounters().findCounter(TaskCounter.NUM_SPECULATIONS).getValue()); } tezClient.stop(); }
@Override public TaskReport getReport() { // TODO TEZPB This is broken. Records will not work without the PBImpl, which // is in a different package. TaskReport report = Records.newRecord(TaskReport.class); readLock.lock(); try { report.setTaskId(taskId); report.setStartTime(getLaunchTime()); report.setFinishTime(getFinishTime()); report.setTaskState(getState()); report.setProgress(getProgress()); for (TaskAttempt attempt : attempts.values()) { if (TaskAttemptState.RUNNING.equals(attempt.getState())) { report.addRunningAttempt(attempt.getID()); } } report.setSuccessfulAttempt(successfulAttempt); for (TaskAttempt att : attempts.values()) { String prefix = "AttemptID:" + att.getID() + " Info:"; for (CharSequence cs : att.getDiagnostics()) { report.addDiagnostics(prefix + cs); } } // Add a copy of counters as the last step so that their lifetime on heap // is as small as possible. report.setCounters(getCounters()); return report; } finally { readLock.unlock(); } }