public void testJobRetire() throws Exception { MiniMRCluster mr = null; try { JobConf conf = new JobConf(); mr = startCluster(conf, 1); JobConf jobConf = mr.createJobConf(); JobTracker jobtracker = mr.getJobTrackerRunner().getJobTracker(); Path inDir = new Path(testDir, "input1"); Path outDir = new Path(testDir, "output1"); JobID id1 = validateJobRetire(jobConf, inDir, outDir, jobtracker); outDir = new Path(testDir, "output2"); JobID id2 = validateJobRetire(jobConf, inDir, outDir, jobtracker); assertNull("Job not removed from cache", jobtracker.getJobStatus(id1)); assertEquals("Total job in cache not correct", 1, jobtracker.getAllJobs().length); } finally { if (mr != null) { mr.shutdown(); } FileUtil.fullyDelete(new File(testDir.toString())); } }
@AfterClass public static void tearDown() throws Exception { if (mrCluster != null) mrCluster.shutdown(); mrCluster = null; if (dfsCluster != null) dfsCluster.shutdown(); dfsCluster = null; }
public static void main(String[] args) throws IOException { LOG.info("Bringing up Jobtracker and tasktrackers."); MiniMRCluster mr = new MiniMRCluster(4, "file:///", 1); LOG.info("JobTracker and TaskTrackers are up."); mr.shutdown(); LOG.info("JobTracker and TaskTrackers brought down."); }
@AfterClass public static void tearDown() throws IOException { FileUtil.fullyDelete(workDir); FileSystem fs = FileSystem.get(mrConf); if (fs.exists(warehousedir)) { fs.delete(warehousedir, true); } if (mrCluster != null) { mrCluster.shutdown(); } }
private void myTearDown() throws Exception { if (cnode != null) { cnode.stop(); cnode.join(); } if (mr != null) { mr.shutdown(); } if (dfsCluster != null) { dfsCluster.shutdown(); } }
/** (Mock)Test JobTracker.removeJobTasks() which is called only when the job retires. */ public void testJobRemoval() throws Exception { MiniMRCluster mr = null; try { JobConf conf = new JobConf(); mr = startCluster(conf, 0); JobTracker jobtracker = mr.getJobTrackerRunner().getJobTracker(); // test map task removal testRemoveJobTasks(jobtracker, conf, TaskType.MAP); // test reduce task removal testRemoveJobTasks(jobtracker, conf, TaskType.REDUCE); // test job setup removal testRemoveJobTasks(jobtracker, conf, TaskType.JOB_SETUP); // test job cleanup removal testRemoveJobTasks(jobtracker, conf, TaskType.JOB_CLEANUP); } finally { if (mr != null) { mr.shutdown(); } // cleanup FileUtil.fullyDelete(new File(testDir.toString())); } }
/** Check refreshNodes for decommissioning blacklisted nodes. */ public void testBlacklistedNodeDecommissioning() throws Exception { LOG.info("Testing blacklisted node decommissioning"); MiniMRCluster mr = null; JobTracker jt = null; try { // start mini mr JobConf jtConf = new JobConf(); jtConf.set("mapred.max.tracker.blacklists", "1"); mr = new MiniMRCluster(0, 0, 2, "file:///", 1, null, null, null, jtConf); jt = mr.getJobTrackerRunner().getJobTracker(); assertEquals("Trackers not up", 2, jt.taskTrackers().size()); // validate the total tracker count assertEquals( "Active tracker count mismatch", 2, jt.getClusterStatus(false).getTaskTrackers()); // validate blacklisted count assertEquals( "Blacklisted tracker count mismatch", 0, jt.getClusterStatus(false).getBlacklistedTrackers()); // run a failing job to blacklist the tracker JobConf jConf = mr.createJobConf(); jConf.set("mapred.max.tracker.failures", "1"); jConf.setJobName("test-job-fail-once"); jConf.setMapperClass(FailOnceMapper.class); jConf.setReducerClass(IdentityReducer.class); jConf.setNumMapTasks(1); jConf.setNumReduceTasks(0); RunningJob job = UtilsForTests.runJob(jConf, new Path(TEST_DIR, "in"), new Path(TEST_DIR, "out")); job.waitForCompletion(); // validate the total tracker count assertEquals( "Active tracker count mismatch", 1, jt.getClusterStatus(false).getTaskTrackers()); // validate blacklisted count assertEquals( "Blacklisted tracker count mismatch", 1, jt.getClusterStatus(false).getBlacklistedTrackers()); // find the blacklisted tracker String trackerName = null; for (TaskTrackerStatus status : jt.taskTrackers()) { if (jt.isBlacklisted(status.getTrackerName())) { trackerName = status.getTrackerName(); break; } } // get the hostname String hostToDecommission = JobInProgress.convertTrackerNameToHostName(trackerName); LOG.info("Decommissioning tracker " + hostToDecommission); // decommission the node HashSet<String> decom = new HashSet<String>(1); decom.add(hostToDecommission); jt.decommissionNodes(decom); // validate // check the cluster status and tracker size assertEquals( "Tracker is not lost upon host decommissioning", 1, jt.getClusterStatus(false).getTaskTrackers()); assertEquals( "Blacklisted tracker count incorrect in cluster status " + "after decommissioning", 0, jt.getClusterStatus(false).getBlacklistedTrackers()); assertEquals("Tracker is not lost upon host decommissioning", 1, jt.taskTrackers().size()); } finally { if (mr != null) { mr.shutdown(); mr = null; jt = null; FileUtil.fullyDelete(new File(TEST_DIR.toString())); } } }
public MiniMRCluster( int jobTrackerPort, int taskTrackerPort, int numTaskTrackers, String namenode, int numDir, String[] racks, String[] hosts, UserGroupInformation ugi, JobConf conf, int numTrackerToExclude) throws IOException { if (racks != null && racks.length < numTaskTrackers) { LOG.error( "Invalid number of racks specified. It should be at least " + "equal to the number of tasktrackers"); shutdown(); } if (hosts != null && numTaskTrackers > hosts.length) { throw new IllegalArgumentException( "The length of hosts [" + hosts.length + "] is less than the number of tasktrackers [" + numTaskTrackers + "]."); } // Generate rack names if required if (racks == null) { System.out.println("Generating rack names for tasktrackers"); racks = new String[numTaskTrackers]; for (int i = 0; i < racks.length; ++i) { racks[i] = NetworkTopology.DEFAULT_RACK; } } // Generate some hostnames if required if (hosts == null) { System.out.println("Generating host names for tasktrackers"); hosts = new String[numTaskTrackers]; for (int i = 0; i < numTaskTrackers; i++) { hosts[i] = "host" + i + ".foo.com"; } } this.jobTrackerPort = jobTrackerPort; this.taskTrackerPort = taskTrackerPort; this.jobTrackerInfoPort = 0; this.numTaskTrackers = 0; this.namenode = namenode; this.ugi = ugi; this.conf = conf; // this is the conf the mr starts with this.numTrackerToExclude = numTrackerToExclude; // start the jobtracker startJobTracker(); // Create the TaskTrackers for (int idx = 0; idx < numTaskTrackers; idx++) { String rack = null; String host = null; if (racks != null) { rack = racks[idx]; } if (hosts != null) { host = hosts[idx]; } startTaskTracker(host, rack, idx, numDir); } this.job = createJobConf(conf); waitUntilIdle(); }
/** Check that we can reach a NameNode or a JobTracker using a specific socket factory */ public void testSocketFactory() throws IOException { // Create a standard mini-cluster Configuration sconf = new Configuration(); MiniDFSCluster cluster = new MiniDFSCluster(sconf, 1, true, null); final int nameNodePort = cluster.getNameNodePort(); // Get a reference to its DFS directly FileSystem fs = cluster.getFileSystem(); assertTrue(fs instanceof DistributedFileSystem); DistributedFileSystem directDfs = (DistributedFileSystem) fs; // Get another reference via network using a specific socket factory Configuration cconf = new Configuration(); FileSystem.setDefaultUri(cconf, String.format("hdfs://localhost:%s/", nameNodePort + 10)); cconf.set( "hadoop.rpc.socket.factory.class.default", "org.apache.hadoop.ipc.DummySocketFactory"); cconf.set( "hadoop.rpc.socket.factory.class.ClientProtocol", "org.apache.hadoop.ipc.DummySocketFactory"); cconf.set( "hadoop.rpc.socket.factory.class.JobSubmissionProtocol", "org.apache.hadoop.ipc.DummySocketFactory"); fs = FileSystem.get(cconf); assertTrue(fs instanceof DistributedFileSystem); DistributedFileSystem dfs = (DistributedFileSystem) fs; JobClient client = null; MiniMRCluster mr = null; try { // This will test RPC to the NameNode only. // could we test Client-DataNode connections? Path filePath = new Path("/dir"); assertFalse(directDfs.exists(filePath)); assertFalse(dfs.exists(filePath)); directDfs.mkdirs(filePath); assertTrue(directDfs.exists(filePath)); assertTrue(dfs.exists(filePath)); // This will test TPC to a JobTracker mr = new MiniMRCluster(1, fs.getUri().toString(), 1); final int jobTrackerPort = mr.getJobTrackerPort(); JobConf jconf = new JobConf(cconf); jconf.set("mapred.job.tracker", String.format("localhost:%d", jobTrackerPort + 10)); client = new JobClient(jconf); JobStatus[] jobs = client.jobsToComplete(); assertTrue(jobs.length == 0); } finally { try { if (client != null) client.close(); } catch (Exception ignored) { // nothing we can do ignored.printStackTrace(); } try { if (dfs != null) dfs.close(); } catch (Exception ignored) { // nothing we can do ignored.printStackTrace(); } try { if (directDfs != null) directDfs.close(); } catch (Exception ignored) { // nothing we can do ignored.printStackTrace(); } try { if (cluster != null) cluster.shutdown(); } catch (Exception ignored) { // nothing we can do ignored.printStackTrace(); } if (mr != null) { try { mr.shutdown(); } catch (Exception ignored) { ignored.printStackTrace(); } } } }
/** * Test job retire with tasks that report their *first* status only after the job retires. Steps : * - Start a mini-mr cluster with 1 task-tracker having only map slots. Note that this * task-tracker will take care of setup/cleanup and the map tasks. - Submit a job with 1 map task * and 1 reduce task - Wait for the job to finish the map task - Start a 2nd tracker that waits * for a long time after contacting the JT. - Wait for the 2nd tracker to get stuck - Kill the job * - Wait for the job to retire - Check if the tip mappings are cleaned up. */ public void testJobRetireWithUnreportedTasks() throws Exception { MiniMRCluster mr = null; try { JobConf conf = new JobConf(); // set the num-map-slots to 1 so that no reduce tasks but setup/cleanup // can run on it conf.setInt("mapred.tasktracker.map.tasks.maximum", 1); conf.setInt("mapred.tasktracker.reduce.tasks.maximum", 0); mr = startCluster(conf, 1); JobTracker jobtracker = mr.getJobTrackerRunner().getJobTracker(); RunningJob job = UtilsForTests.runJob( mr.createJobConf(), new Path(testDir, "in-1"), new Path(testDir, "out-1"), 1, 1); JobID id = JobID.downgrade(job.getID()); JobInProgress jip = jobtracker.getJob(id); // wait 100 secs for the job to complete its map task for (int i = 0; i < 1000 && jip.finishedMaps() < 1; i++) { UtilsForTests.waitFor(100); } assertEquals(jip.finishedMaps(), 1); // start a tracker that will wait LOG.info("Adding a waiting tracker"); TaskTrackerRunner testTrackerRunner = mr.new TaskTrackerRunner(1, 1, null, mr.createJobConf()) { @Override TaskTracker createTaskTracker(JobConf conf) throws InterruptedException, IOException { return new WaitingTaskTracker(conf); } }; mr.addTaskTracker(testTrackerRunner); LOG.info("Waiting tracker added"); WaitingTaskTracker testTT = (WaitingTaskTracker) testTrackerRunner.getTaskTracker(); // wait 100 secs for the newly started task-tracker to join for (int i = 0; i < 1000 && jobtracker.taskTrackers().size() < 2; i++) { UtilsForTests.waitFor(100); } assertEquals(jobtracker.taskTrackers().size(), 2); LOG.info("Cluster is now up with 2 trackers"); // stop the test-tt as its no longer required mr.stopTaskTracker(mr.getTaskTrackerID(testTT.getName())); // 1 reduce task should be scheduled assertEquals("TestTT contacted but no reduce task scheduled on it", 1, jip.runningReduces()); // kill the job LOG.info("Killing job " + id); job.killJob(); // check if the reduce task attempt status is missing TaskInProgress tip = jip.getTasks(TaskType.REDUCE)[0]; assertNull(tip.getTaskStatus(tip.getAllTaskAttemptIDs()[0])); // wait for the job to retire waitTillRetire(id, jobtracker); // check the taskidToTIPMap for (TaskAttemptID tid : jobtracker.taskidToTIPMap.keySet()) { LOG.info("TaskidToTIP : " + tid); } assertEquals("'taskid' to TIP mapping still exists", 0, jobtracker.taskidToTIPMap.size()); } finally { if (mr != null) { mr.shutdown(); } // cleanup FileUtil.fullyDelete(new File(testDir.toString())); } }
/** Test if {@link CurrentJHParser} can read events from current JH files. */ @Test public void testCurrentJHParser() throws Exception { final Configuration conf = new Configuration(); final FileSystem lfs = FileSystem.getLocal(conf); final Path rootTempDir = new Path(System.getProperty("test.build.data", "/tmp")).makeQualified(lfs); final Path tempDir = new Path(rootTempDir, "TestCurrentJHParser"); lfs.delete(tempDir, true); String queueName = "testQueue"; // Run a MR job // create a MR cluster conf.setInt("mapred.tasktracker.map.tasks.maximum", 1); conf.setInt("mapred.tasktracker.reduce.tasks.maximum", 1); conf.set("mapred.queue.names", queueName); MiniMRCluster mrCluster = new MiniMRCluster(1, "file:///", 1, null, null, new JobConf(conf)); // run a job Path inDir = new Path(tempDir, "input"); Path outDir = new Path(tempDir, "output"); JobHistoryParser parser = null; RewindableInputStream ris = null; ArrayList<String> seenEvents = new ArrayList<String>(10); RunningJob rJob = null; try { JobConf jobConf = mrCluster.createJobConf(); jobConf.setQueueName(queueName); // construct a job with 1 map and 1 reduce task. rJob = UtilsForTests.runJob(jobConf, inDir, outDir, 1, 1); rJob.waitForCompletion(); assertTrue("Job failed", rJob.isSuccessful()); JobID id = rJob.getID(); // get the jobhistory filepath Path inputPath = new Path(JobHistory.getHistoryFilePath(org.apache.hadoop.mapred.JobID.downgrade(id))); // wait for 10 secs for the jobhistory file to move into the done folder for (int i = 0; i < 100; ++i) { if (lfs.exists(inputPath)) { break; } TimeUnit.MILLISECONDS.wait(100); } assertTrue("Missing job history file", lfs.exists(inputPath)); InputDemuxer inputDemuxer = new DefaultInputDemuxer(); inputDemuxer.bindTo(inputPath, conf); Pair<String, InputStream> filePair = inputDemuxer.getNext(); assertNotNull(filePair); ris = new RewindableInputStream(filePair.second()); // Test if the JobHistoryParserFactory can detect the parser correctly parser = JobHistoryParserFactory.getParser(ris); // Get ParsedJob String jobId = TraceBuilder.extractJobID(filePair.first()); JobBuilder builder = new JobBuilder(jobId); HistoryEvent e; while ((e = parser.nextEvent()) != null) { String eventString = e.getEventType().toString(); System.out.println(eventString); seenEvents.add(eventString); if (builder != null) { builder.process(e); } } ParsedJob parsedJob = builder.build(); // validate the obtainXXX api of ParsedJob, ParsedTask and // ParsedTaskAttempt. validateParsedJob(parsedJob, 1, 1, queueName); } finally { // stop the MR cluster mrCluster.shutdown(); if (ris != null) { ris.close(); } if (parser != null) { parser.close(); } // cleanup the filesystem lfs.delete(tempDir, true); } // Check against the gold standard System.out.println("testCurrentJHParser validating using gold std "); String[] goldLines = new String[] { "JOB_SUBMITTED", "JOB_PRIORITY_CHANGED", "JOB_STATUS_CHANGED", "JOB_INITED", "JOB_INFO_CHANGED", "TASK_STARTED", "MAP_ATTEMPT_STARTED", "MAP_ATTEMPT_FINISHED", "MAP_ATTEMPT_FINISHED", "TASK_UPDATED", "TASK_FINISHED", "JOB_STATUS_CHANGED", "TASK_STARTED", "MAP_ATTEMPT_STARTED", "MAP_ATTEMPT_FINISHED", "MAP_ATTEMPT_FINISHED", "TASK_UPDATED", "TASK_FINISHED", "TASK_STARTED", "MAP_ATTEMPT_STARTED", "MAP_ATTEMPT_FINISHED", "REDUCE_ATTEMPT_FINISHED", "TASK_UPDATED", "TASK_FINISHED", "TASK_STARTED", "MAP_ATTEMPT_STARTED", "MAP_ATTEMPT_FINISHED", "MAP_ATTEMPT_FINISHED", "TASK_UPDATED", "TASK_FINISHED", "JOB_STATUS_CHANGED", "JOB_FINISHED" }; // Check the output with gold std assertEquals("Size mismatch", goldLines.length, seenEvents.size()); int index = 0; for (String goldLine : goldLines) { assertEquals("Content mismatch", goldLine, seenEvents.get(index++)); } }
@Override public void shutdown() throws IOException { mr.shutdown(); }
public void testSymLink() { try { boolean mayExit = false; MiniMRCluster mr = null; MiniDFSCluster dfs = null; try { Configuration conf = new Configuration(); dfs = new MiniDFSCluster(conf, 1, true, null); FileSystem fileSys = dfs.getFileSystem(); String namenode = fileSys.getUri().toString(); mr = new MiniMRCluster(1, namenode, 3); // During tests, the default Configuration will use a local mapred // So don't specify -config or -cluster String strJobtracker = "mapred.job.tracker=" + "localhost:" + mr.getJobTrackerPort(); String strNamenode = "fs.default.name=" + namenode; String argv[] = new String[] { "-input", INPUT_FILE, "-output", OUTPUT_DIR, "-mapper", map, "-reducer", reduce, // "-verbose", // "-jobconf", "stream.debug=set" "-jobconf", strNamenode, "-jobconf", strJobtracker, "-jobconf", "stream.tmpdir=" + System.getProperty("test.build.data", "/tmp"), "-jobconf", "mapred.child.java.opts=-Dcontrib.name=" + System.getProperty("contrib.name") + " " + "-Dbuild.test=" + System.getProperty("build.test") + " " + conf.get("mapred.child.java.opts", ""), "-cacheFile", fileSys.getUri() + CACHE_FILE + "#testlink" }; fileSys.delete(new Path(OUTPUT_DIR), true); DataOutputStream file = fileSys.create(new Path(INPUT_FILE)); file.writeBytes(mapString); file.close(); file = fileSys.create(new Path(CACHE_FILE)); file.writeBytes(cacheString); file.close(); job = new StreamJob(argv, mayExit); job.go(); fileSys = dfs.getFileSystem(); String line = null; Path[] fileList = FileUtil.stat2Paths(fileSys.listStatus(new Path(OUTPUT_DIR), new OutputLogFilter())); for (int i = 0; i < fileList.length; i++) { System.out.println(fileList[i].toString()); BufferedReader bread = new BufferedReader(new InputStreamReader(fileSys.open(fileList[i]))); line = bread.readLine(); System.out.println(line); } assertEquals(cacheString + "\t", line); } finally { if (dfs != null) { dfs.shutdown(); } if (mr != null) { mr.shutdown(); } } } catch (Exception e) { failTrace(e); } }