Package org.apache.hadoop.mapred

Source Code of org.apache.hadoop.mapred.TestJobInProgressListener$MyListener

/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*     http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package org.apache.hadoop.mapred;

import java.util.ArrayList;
import java.io.IOException;
import java.util.List;

import org.apache.hadoop.hdfs.MiniDFSCluster;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.mapred.JobStatusChangeEvent.EventType;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import junit.framework.TestCase;

/**
* Test whether the JobInProgressListeners are informed as expected.
*/
public class TestJobInProgressListener extends TestCase {
  private static final Log LOG =
    LogFactory.getLog(TestJobInProgressListener.class);
  private final Path testDir = new Path("test-jip-listener-update");
 
  private JobConf configureJob(JobConf conf, int m, int r,
                               Path inDir, Path outputDir,
                               String mapSignalFile, String redSignalFile)
  throws IOException {
    TestJobTrackerRestart.configureWaitingJobConf(conf, inDir, outputDir,
                                                  m, r, "job-listener-test",
                                                  mapSignalFile, redSignalFile);
    return conf;
  }
 
  /**
   * This test case tests if external updates to JIP do not result into
   * undesirable effects
   * Test is as follows
   *   - submit 2 jobs of normal priority. job1 is a waiting job which waits and
   *     blocks the cluster
   *   - change one parameter of job2 such that the job bumps up in the queue
   *   - check if the queue looks ok
   *  
   */
  public void testJobQueueChanges() throws IOException {
    LOG.info("Testing job queue changes");
    JobConf conf = new JobConf();
    MiniDFSCluster dfs = new MiniDFSCluster(conf, 1, true, null, null);
    dfs.waitActive();
    FileSystem fileSys = dfs.getFileSystem();
   
    dfs.startDataNodes(conf, 1, true, null, null, null, null);
    dfs.waitActive();
   
    String namenode = (dfs.getFileSystem()).getUri().getHost() + ":"
                      + (dfs.getFileSystem()).getUri().getPort();
    MiniMRCluster mr = new MiniMRCluster(1, namenode, 1);
    JobClient jobClient = new JobClient(mr.createJobConf());
   
    // clean up
    fileSys.delete(testDir, true);
   
    if (!fileSys.mkdirs(testDir)) {
      throw new IOException("Mkdirs failed to create " + testDir.toString());
    }

    // Write the input file
    Path inDir = new Path(testDir, "input");
    Path shareDir = new Path(testDir, "share");
    String mapSignalFile = TestJobTrackerRestart.getMapSignalFile(shareDir);
    String redSignalFile = TestJobTrackerRestart.getReduceSignalFile(shareDir);
    TestRackAwareTaskPlacement.writeFile(dfs.getNameNode(), conf,
                                         new Path(inDir + "/file"),
                                         (short)1);
   
    JobQueueJobInProgressListener myListener =
      new JobQueueJobInProgressListener();
   
    // add the listener
    mr.getJobTrackerRunner().getJobTracker()
      .addJobInProgressListener(myListener);
   
    // big blocking job
    Path outputDir = new Path(testDir, "output");
    Path newOutputDir = outputDir.suffix("0");
    JobConf job1 = configureJob(mr.createJobConf(), 10, 0, inDir, newOutputDir,
                                mapSignalFile, redSignalFile);
   
    // short blocked job
    newOutputDir = outputDir.suffix("1");
    JobConf job2 = configureJob(mr.createJobConf(), 1, 0, inDir, newOutputDir,
                                mapSignalFile, redSignalFile);
   
    RunningJob rJob1 = jobClient.submitJob(job1);
    LOG.info("Running job " + rJob1.getID().toString());
   
    RunningJob rJob2 = jobClient.submitJob(job2);
    LOG.info("Running job " + rJob2.getID().toString());
   
    // I. Check job-priority change
    LOG.info("Testing job priority changes");
   
    // bump up job2's priority
    LOG.info("Increasing job2's priority to HIGH");
    rJob2.setJobPriority("HIGH");
   
    // check if the queue is sane
    assertTrue("Priority change garbles the queue",
               myListener.getJobQueue().size() == 2);
   
    JobInProgress[] queue =
      myListener.getJobQueue().toArray(new JobInProgress[0]);
   
    // check if the bump has happened
    assertTrue("Priority change failed to bump up job2 in the queue",
               queue[0].getJobID().equals(rJob2.getID()));
   
    assertTrue("Priority change failed to bump down job1 in the queue",
               queue[1].getJobID().equals(rJob1.getID()));
   
    assertEquals("Priority change has garbled the queue",
                 2, queue.length);
   
    // II. Check start-time change
    LOG.info("Testing job start-time changes");
   
    // reset the priority which will make the order as
    //  - job1
    //  - job2
    // this will help in bumping job2 on start-time change
    LOG.info("Increasing job2's priority to NORMAL");
    rJob2.setJobPriority("NORMAL");
   
    // create the change event
    JobInProgress jip2 = mr.getJobTrackerRunner().getJobTracker()
                          .getJob(rJob2.getID());
    JobInProgress jip1 = mr.getJobTrackerRunner().getJobTracker()
                           .getJob(rJob1.getID());
   
    JobStatus prevStatus = (JobStatus)jip2.getStatus().clone();
   
    // change job2's start-time and the status
    jip2.startTime =  jip1.startTime - 1;
    jip2.status.setStartTime(jip2.startTime);
   
   
    JobStatus newStatus = (JobStatus)jip2.getStatus().clone();
   
    // inform the listener
    LOG.info("Updating the listener about job2's start-time change");
    JobStatusChangeEvent event =
      new JobStatusChangeEvent(jip2, EventType.START_TIME_CHANGED,
                              prevStatus, newStatus);
    myListener.jobUpdated(event);
   
    // check if the queue is sane
    assertTrue("Start time change garbles the queue",
               myListener.getJobQueue().size() == 2);
   
    queue = myListener.getJobQueue().toArray(new JobInProgress[0]);
   
    // check if the bump has happened
    assertTrue("Start time change failed to bump up job2 in the queue",
               queue[0].getJobID().equals(rJob2.getID()));
   
    assertTrue("Start time change failed to bump down job1 in the queue",
               queue[1].getJobID().equals(rJob1.getID()));
   
    assertEquals("Start time change has garbled the queue",
                 2, queue.length);
   
    // signal the maps to complete
    TestJobTrackerRestart.signalTasks(dfs, fileSys, true,
                                      mapSignalFile, redSignalFile);
   
    // check if job completion leaves the queue sane
    while (rJob2.getJobState() != JobStatus.SUCCEEDED) {
      TestJobTrackerRestart.waitFor(10);
    }
   
    while (rJob1.getJobState() != JobStatus.SUCCEEDED) {
      TestJobTrackerRestart.waitFor(10);
    }
   
    assertTrue("Job completion garbles the queue",
               myListener.getJobQueue().size() == 0);
  }
 
  // A listener that inits the tasks one at a time and also listens to the
  // events
  public static class MyListener extends JobInProgressListener {
    private List<JobInProgress> wjobs = new ArrayList<JobInProgress>();
    private List<JobInProgress> jobs = new ArrayList<JobInProgress>();
   
    public boolean contains (JobID id) {
      return contains(id, true) || contains(id, false);
    }
   
    public boolean contains (JobID id, boolean waiting) {
      List<JobInProgress> queue = waiting ? wjobs : jobs;
      for (JobInProgress job : queue) {
        if (job.getJobID().equals(id)) {
          return true;
        }
      }
      return false;
    }
   
    public void jobAdded(JobInProgress job) {
      LOG.info("Job " + job.getJobID().toString() + " added");
      wjobs.add(job);
    }
   
    public void jobRemoved(JobInProgress job) {
      LOG.info("Job " + job.getJobID().toString() + " removed");
    }
   
    public void jobUpdated(JobChangeEvent event) {
      LOG.info("Job " + event.getJobInProgress().getJobID().toString() + " updated");
      // remove the job is the event is for a completed job
      if (event instanceof JobStatusChangeEvent) {
        JobStatusChangeEvent statusEvent = (JobStatusChangeEvent)event;
        if (statusEvent.getEventType() == EventType.RUN_STATE_CHANGED) {
          // check if the state changes from
          // RUNNING->COMPLETE(SUCCESS/KILLED/FAILED)
          JobInProgress jip = event.getJobInProgress();
          String jobId = jip.getJobID().toString();
          if (statusEvent.getJobInProgress().isComplete()) {
            LOG.info("Job " +  jobId + " deleted from the running queue");
            jobs.remove(jip);
          } else {
            // PREP->RUNNING
            LOG.info("Job " +  jobId + " deleted from the waiting queue");
            wjobs.remove(jip);
            jobs.add(jip);
          }
        }
      }
    }
  }
 
  public void testJobFailure() throws Exception {
    LOG.info("Testing job-success");
   
    MyListener myListener = new MyListener();
    MiniMRCluster mr = new MiniMRCluster(1, "file:///", 1);
   
    JobConf job = mr.createJobConf();
   
    mr.getJobTrackerRunner().getJobTracker()
      .addJobInProgressListener(myListener);
   
    // submit and kill the job  
    JobID id = TestJobKillAndFail.runJobFail(job);

    // check if the job failure was notified
    assertFalse("Missing event notification on failing a running job",
                myListener.contains(id));
   
  }
 
  public void testJobKill() throws Exception {
    LOG.info("Testing job-kill");
   
    MyListener myListener = new MyListener();
    MiniMRCluster mr = new MiniMRCluster(1, "file:///", 1);
   
    JobConf job = mr.createJobConf();
   
    mr.getJobTrackerRunner().getJobTracker()
      .addJobInProgressListener(myListener);
   
    // submit and kill the job  
    JobID id = TestJobKillAndFail.runJobKill(job);

    // check if the job failure was notified
    assertFalse("Missing event notification on killing a running job",
                myListener.contains(id));
   
  }
 
  public void testJobSuccess() throws Exception {
    LOG.info("Testing job-success");
    MyListener myListener = new MyListener();
   
    MiniMRCluster mr = new MiniMRCluster(1, "file:///", 1);
   
    JobConf job = mr.createJobConf();
   
    mr.getJobTrackerRunner().getJobTracker()
      .addJobInProgressListener(myListener);
   
    // submit the job  
    RunningJob rJob = TestJobKillAndFail.runJob(job);
   
    // wait for the job to be running
    while (rJob.getJobState() != JobStatus.RUNNING) {
      TestJobTrackerRestart.waitFor(10);
    }
   
    LOG.info("Job " +  rJob.getID().toString() + " started running");
   
    // check if the listener was updated about this change
    assertFalse("Missing event notification for a running job",
                myListener.contains(rJob.getID(), true));
   
    while (rJob.getJobState() != JobStatus.SUCCEEDED) {
      TestJobTrackerRestart.waitFor(10);
    }
   
    // check if the job success was notified
    assertFalse("Missing event notification for a successful job",
                myListener.contains(rJob.getID(), false));
  }
}
TOP

Related Classes of org.apache.hadoop.mapred.TestJobInProgressListener$MyListener

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.