|
@@ -19,9 +19,11 @@
|
|
package org.apache.hadoop.mapreduce.v2.app;
|
|
package org.apache.hadoop.mapreduce.v2.app;
|
|
|
|
|
|
import static org.junit.Assert.assertEquals;
|
|
import static org.junit.Assert.assertEquals;
|
|
|
|
+import static org.junit.Assert.assertFalse;
|
|
import static org.junit.Assert.assertTrue;
|
|
import static org.junit.Assert.assertTrue;
|
|
import static org.mockito.Mockito.atLeast;
|
|
import static org.mockito.Mockito.atLeast;
|
|
import static org.mockito.Mockito.mock;
|
|
import static org.mockito.Mockito.mock;
|
|
|
|
+
|
|
import static org.mockito.Mockito.verify;
|
|
import static org.mockito.Mockito.verify;
|
|
import static org.mockito.Mockito.when;
|
|
import static org.mockito.Mockito.when;
|
|
|
|
|
|
@@ -43,6 +45,7 @@ import org.apache.hadoop.fs.Path;
|
|
import org.apache.hadoop.io.NullWritable;
|
|
import org.apache.hadoop.io.NullWritable;
|
|
import org.apache.hadoop.io.Text;
|
|
import org.apache.hadoop.io.Text;
|
|
import org.apache.hadoop.mapred.JobConf;
|
|
import org.apache.hadoop.mapred.JobConf;
|
|
|
|
+import org.apache.hadoop.mapred.JobContext;
|
|
import org.apache.hadoop.mapreduce.Counters;
|
|
import org.apache.hadoop.mapreduce.Counters;
|
|
import org.apache.hadoop.mapreduce.JobCounter;
|
|
import org.apache.hadoop.mapreduce.JobCounter;
|
|
import org.apache.hadoop.mapreduce.JobID;
|
|
import org.apache.hadoop.mapreduce.JobID;
|
|
@@ -452,6 +455,8 @@ public class TestRecovery {
|
|
public static class TestFileOutputCommitter extends
|
|
public static class TestFileOutputCommitter extends
|
|
org.apache.hadoop.mapred.FileOutputCommitter {
|
|
org.apache.hadoop.mapred.FileOutputCommitter {
|
|
|
|
|
|
|
|
+ private boolean abortJobCalled;
|
|
|
|
+
|
|
@Override
|
|
@Override
|
|
public boolean isRecoverySupported(
|
|
public boolean isRecoverySupported(
|
|
org.apache.hadoop.mapred.JobContext jobContext) {
|
|
org.apache.hadoop.mapred.JobContext jobContext) {
|
|
@@ -462,6 +467,16 @@ public class TestRecovery {
|
|
}
|
|
}
|
|
return isRecoverySupported;
|
|
return isRecoverySupported;
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+ @Override
|
|
|
|
+ public void abortJob(JobContext context, int runState) throws IOException {
|
|
|
|
+ super.abortJob(context, runState);
|
|
|
|
+ this.abortJobCalled = true;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ private boolean isAbortJobCalled() {
|
|
|
|
+ return this.abortJobCalled;
|
|
|
|
+ }
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
/**
|
|
@@ -1009,6 +1024,73 @@ public class TestRecovery {
|
|
validateOutput();
|
|
validateOutput();
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ @Test
|
|
|
|
+ public void testPreviousJobOutputCleanedWhenNoRecovery() throws Exception {
|
|
|
|
+ int runCount = 0;
|
|
|
|
+ MRApp app = new MRAppWithHistory(1, 2, false, this.getClass().getName(),
|
|
|
|
+ true, ++runCount);
|
|
|
|
+ Configuration conf = new Configuration();
|
|
|
|
+ conf.setBoolean(MRJobConfig.MR_AM_JOB_RECOVERY_ENABLE, false);
|
|
|
|
+ conf.setClass("mapred.output.committer.class",
|
|
|
|
+ TestFileOutputCommitter.class,
|
|
|
|
+ org.apache.hadoop.mapred.OutputCommitter.class);
|
|
|
|
+ conf.setBoolean(MRJobConfig.JOB_UBERTASK_ENABLE, false);
|
|
|
|
+ conf.set(FileOutputFormat.OUTDIR, outputDir.toString());
|
|
|
|
+ Job job = app.submit(conf);
|
|
|
|
+ app.waitForState(job, JobState.RUNNING);
|
|
|
|
+ Assert.assertEquals("No of tasks not correct", 3, job.getTasks().size());
|
|
|
|
+ //stop the app before the job completes.
|
|
|
|
+ app.stop();
|
|
|
|
+ app.close();
|
|
|
|
+
|
|
|
|
+ //rerun
|
|
|
|
+ app = new MRAppWithHistory(1, 2, false, this.getClass().getName(), false,
|
|
|
|
+ ++runCount);
|
|
|
|
+ job = app.submit(conf);
|
|
|
|
+ app.waitForState(job, JobState.RUNNING);
|
|
|
|
+ Assert.assertEquals("No of tasks not correct", 3, job.getTasks().size());
|
|
|
|
+ TestFileOutputCommitter committer = (
|
|
|
|
+ TestFileOutputCommitter) app.getCommitter();
|
|
|
|
+ assertTrue("commiter.abortJob() has not been called",
|
|
|
|
+ committer.isAbortJobCalled());
|
|
|
|
+ app.close();
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ @Test
|
|
|
|
+ public void testPreviousJobIsNotCleanedWhenRecovery()
|
|
|
|
+ throws Exception {
|
|
|
|
+ int runCount = 0;
|
|
|
|
+ MRApp app = new MRAppWithHistory(1, 2, false, this.getClass().getName(),
|
|
|
|
+ true, ++runCount);
|
|
|
|
+ Configuration conf = new Configuration();
|
|
|
|
+ conf.setBoolean(MRJobConfig.MR_AM_JOB_RECOVERY_ENABLE, true);
|
|
|
|
+ conf.setClass("mapred.output.committer.class",
|
|
|
|
+ TestFileOutputCommitter.class,
|
|
|
|
+ org.apache.hadoop.mapred.OutputCommitter.class);
|
|
|
|
+ conf.setBoolean(MRJobConfig.JOB_UBERTASK_ENABLE, false);
|
|
|
|
+ // TestFileOutputCommitter supports recovery if want.am.recovery=true
|
|
|
|
+ conf.setBoolean("want.am.recovery", true);
|
|
|
|
+ conf.set(FileOutputFormat.OUTDIR, outputDir.toString());
|
|
|
|
+ Job job = app.submit(conf);
|
|
|
|
+ app.waitForState(job, JobState.RUNNING);
|
|
|
|
+ Assert.assertEquals("No of tasks not correct", 3, job.getTasks().size());
|
|
|
|
+ //stop the app before the job completes.
|
|
|
|
+ app.stop();
|
|
|
|
+ app.close();
|
|
|
|
+
|
|
|
|
+ //rerun
|
|
|
|
+ app = new MRAppWithHistory(1, 2, false, this.getClass().getName(), false,
|
|
|
|
+ ++runCount);
|
|
|
|
+ job = app.submit(conf);
|
|
|
|
+ app.waitForState(job, JobState.RUNNING);
|
|
|
|
+ Assert.assertEquals("No of tasks not correct", 3, job.getTasks().size());
|
|
|
|
+ TestFileOutputCommitter committer = (
|
|
|
|
+ TestFileOutputCommitter) app.getCommitter();
|
|
|
|
+ assertFalse("commiter.abortJob() has been called",
|
|
|
|
+ committer.isAbortJobCalled());
|
|
|
|
+ app.close();
|
|
|
|
+ }
|
|
|
|
+
|
|
@Test
|
|
@Test
|
|
public void testOutputRecoveryMapsOnly() throws Exception {
|
|
public void testOutputRecoveryMapsOnly() throws Exception {
|
|
int runCount = 0;
|
|
int runCount = 0;
|