/**
 * 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.io.DataOutputStream;
import java.io.IOException;
import java.net.URI;
import java.security.PrivilegedExceptionAction;
import java.util.HashMap;
import java.util.Map;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FSDataOutputStream;
import org.apache.hadoop.fs.FileStatus;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.fs.permission.FsPermission;
import org.apache.hadoop.hdfs.MiniDFSCluster;
import org.apache.hadoop.hdfs.protocol.HdfsFileStatus;
import org.apache.hadoop.hdfs.server.namenode.NameNode;
import org.apache.hadoop.io.DataOutputBuffer;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.ipc.RPC;
import org.apache.hadoop.ipc.RemoteException;
import org.apache.hadoop.mapred.lib.IdentityMapper;
import org.apache.hadoop.mapred.lib.IdentityReducer;
import org.apache.hadoop.mapreduce.MRConfig;
import org.apache.hadoop.mapreduce.SleepJob;
import org.apache.hadoop.net.NetUtils;
import org.apache.hadoop.security.UserGroupInformation;
import org.apache.hadoop.mapreduce.protocol.ClientProtocol;
import org.apache.hadoop.mapreduce.server.jobtracker.JTConfig;
import org.apache.hadoop.mapreduce.split.JobSplit.SplitMetaInfo;
import org.apache.hadoop.util.ToolRunner;

import junit.framework.TestCase;

/**
 * Test job submission. This test checks if 
 *   - basic   : job submission via jobclient
 *   - cleanup : job client crashes while submitting
 *   - invalid job config
 *     - invalid memory config
 *   
 */
public class TestSubmitJob extends TestCase {
  static final Log LOG = LogFactory.getLog(TestSubmitJob.class);
  
  private MiniMRCluster mrCluster;

  private MiniDFSCluster dfsCluster;
  private JobTracker jt;
  private FileSystem fs;
  private static Path TEST_DIR = 
    new Path(System.getProperty("test.build.data","/tmp"), 
             "job-submission-testing");
  private static int numSlaves = 1;

  private void startCluster() throws Exception {
    super.setUp();
    Configuration conf = new Configuration();
    dfsCluster = new MiniDFSCluster(conf, numSlaves, true, null);
    JobConf jConf = new JobConf(conf);
    jConf.setLong("mapred.job.submission.expiry.interval", 6 * 1000);
    mrCluster = new MiniMRCluster(0, 0, numSlaves, 
        dfsCluster.getFileSystem().getUri().toString(), 1, null, null, null, 
        jConf);
    jt = mrCluster.getJobTrackerRunner().getJobTracker();
    fs = FileSystem.get(mrCluster.createJobConf());
  }
  
  private void stopCluster() throws Exception {
    mrCluster.shutdown();
    mrCluster = null;
    dfsCluster.shutdown();
    dfsCluster = null;
    jt = null;
    fs = null;
  }

  /**
   * Test to verify that jobs with invalid memory requirements are killed at the
   * JT.
   * 
   * @throws Exception
   */
  public void testJobWithInvalidMemoryReqs()
      throws Exception {
    JobConf jtConf = new JobConf();
    jtConf
        .setLong(MRConfig.MAPMEMORY_MB, 1 * 1024L);
    jtConf.setLong(MRConfig.REDUCEMEMORY_MB,
        2 * 1024L);
    jtConf.setLong(JTConfig.JT_MAX_MAPMEMORY_MB,
        3 * 1024L);
    jtConf.setLong(JTConfig.JT_MAX_REDUCEMEMORY_MB,
        4 * 1024L);

    mrCluster = new MiniMRCluster(0, "file:///", 0, null, null, jtConf);

    JobConf clusterConf = mrCluster.createJobConf();

    // No map-memory configuration
    JobConf jobConf = new JobConf(clusterConf);
    jobConf.setMemoryForReduceTask(1 * 1024L);
    runJobAndVerifyFailure(jobConf, JobConf.DISABLED_MEMORY_LIMIT, 1 * 1024L,
        "Invalid job requirements.");

    // No reduce-memory configuration
    jobConf = new JobConf(clusterConf);
    jobConf.setMemoryForMapTask(1 * 1024L);
    runJobAndVerifyFailure(jobConf, 1 * 1024L, JobConf.DISABLED_MEMORY_LIMIT,
        "Invalid job requirements.");

    // Invalid map-memory configuration
    jobConf = new JobConf(clusterConf);
    jobConf.setMemoryForMapTask(4 * 1024L);
    jobConf.setMemoryForReduceTask(1 * 1024L);
    runJobAndVerifyFailure(jobConf, 4 * 1024L, 1 * 1024L,
        "Exceeds the cluster's max-memory-limit.");

    // No reduce-memory configuration
    jobConf = new JobConf(clusterConf);
    jobConf.setMemoryForMapTask(1 * 1024L);
    jobConf.setMemoryForReduceTask(5 * 1024L);
    runJobAndVerifyFailure(jobConf, 1 * 1024L, 5 * 1024L,
        "Exceeds the cluster's max-memory-limit.");
    
    mrCluster.shutdown();
    mrCluster = null;
  }

  private void runJobAndVerifyFailure(JobConf jobConf, long memForMapTasks,
      long memForReduceTasks, String expectedMsg)
      throws Exception,
      IOException {
    String[] args = { "-m", "0", "-r", "0", "-mt", "0", "-rt", "0" };
    boolean throwsException = false;
    String msg = null;
    try {
      ToolRunner.run(jobConf, new SleepJob(), args);
    } catch (RemoteException re) {
      throwsException = true;
      msg = re.unwrapRemoteException().getMessage();
    }
    assertTrue(throwsException);
    assertNotNull(msg);

    String overallExpectedMsg =
        "(" + memForMapTasks + " memForMapTasks " + memForReduceTasks
            + " memForReduceTasks): " + expectedMsg;
    assertTrue("Observed message - " + msg
        + " - doesn't contain expected message - " + overallExpectedMsg, msg
        .contains(overallExpectedMsg));
  }
  
  static ClientProtocol getJobSubmitClient(JobConf conf, 
                                           UserGroupInformation ugi) 
  throws IOException {
    return (ClientProtocol) RPC.getProxy(ClientProtocol.class, 
        ClientProtocol.versionID, JobTracker.getAddress(conf), ugi, 
        conf, NetUtils.getSocketFactory(conf, ClientProtocol.class));
  }

  static org.apache.hadoop.hdfs.protocol.ClientProtocol getDFSClient(
      Configuration conf, UserGroupInformation ugi) 
  throws IOException {
    return (org.apache.hadoop.hdfs.protocol.ClientProtocol) 
      RPC.getProxy(org.apache.hadoop.hdfs.protocol.ClientProtocol.class, 
        org.apache.hadoop.hdfs.protocol.ClientProtocol.versionID, 
        NameNode.getAddress(conf), ugi, 
        conf, 
        NetUtils.getSocketFactory(conf, 
            org.apache.hadoop.hdfs.protocol.ClientProtocol.class));
  }
  
  /**
   * Submit a job and check if the files are accessible to other users.
   */
  public void testSecureJobExecution() throws Exception {
    LOG.info("Testing secure job submission/execution");
    MiniMRCluster mr = null;
    Configuration conf = new Configuration();
    final MiniDFSCluster dfs = new MiniDFSCluster(conf, 1, true, null);
    try {
      FileSystem fs = 
        TestMiniMRWithDFSWithDistinctUsers.DFS_UGI.doAs(new PrivilegedExceptionAction<FileSystem>() {
          public FileSystem run() throws IOException {
            return dfs.getFileSystem();
          }
        });
      TestMiniMRWithDFSWithDistinctUsers.mkdir(fs, "/user", "mapred", "mapred", (short)01777);
      TestMiniMRWithDFSWithDistinctUsers.mkdir(fs, "/mapred", "mapred", "mapred", (short)01777);
      TestMiniMRWithDFSWithDistinctUsers.mkdir(fs, conf.get(JTConfig.JT_STAGING_AREA_ROOT),
                                               "mapred", "mapred", (short)01777);

      UserGroupInformation MR_UGI = UserGroupInformation.getLoginUser();
      mr = new MiniMRCluster(0, 0, 1, dfs.getFileSystem().getUri().toString(),
                             1, null, null, MR_UGI);
      JobTracker jt = mr.getJobTrackerRunner().getJobTracker();
      String jobTrackerName = "localhost:" + mr.getJobTrackerPort();

      // cleanup
      dfs.getFileSystem().delete(TEST_DIR, true);

      final Path mapSignalFile = new Path(TEST_DIR, "map-signal");
      final Path reduceSignalFile = new Path(TEST_DIR, "reduce-signal");
      
      // create a ugi for user 1
      UserGroupInformation user1 = 
        TestMiniMRWithDFSWithDistinctUsers.createUGI("user1", false);
      Path inDir = new Path("/user/input");
      Path outDir = new Path("/user/output");
      final JobConf job = mr.createJobConf();

      UtilsForTests.configureWaitingJobConf(job, inDir, outDir, 2, 0, 
        "test-submit-job", mapSignalFile.toString(), 
        reduceSignalFile.toString());
      job.set(UtilsForTests.getTaskSignalParameter(true), 
      mapSignalFile.toString());
      job.set(UtilsForTests.getTaskSignalParameter(false), 
      reduceSignalFile.toString());
      LOG.info("Submit job as the actual user (" + user1.getUserName() + ")");
      final JobClient jClient = 
        user1.doAs(new PrivilegedExceptionAction<JobClient>() {
          public JobClient run() throws IOException {
            return new JobClient(job);
          }
        });
      RunningJob rJob = user1.doAs(new PrivilegedExceptionAction<RunningJob>() {
        public RunningJob run() throws IOException {
          return jClient.submitJob(job);
        }
      });
      JobID id = rJob.getID();
      LOG.info("Running job " + id);

      // create user2
      UserGroupInformation user2 = 
        TestMiniMRWithDFSWithDistinctUsers.createUGI("user2", false);
      JobConf conf_other = mr.createJobConf();
      org.apache.hadoop.hdfs.protocol.ClientProtocol client = 
        getDFSClient(conf_other, user2);

      // try accessing mapred.system.dir/jobid/*
      try {
        String path = new URI(jt.getSystemDir()).getPath();
        LOG.info("Try listing the mapred-system-dir as the user (" 
                 + user2.getUserName() + ")");
        client.getListing(path, HdfsFileStatus.EMPTY_NAME, false);
        fail("JobTracker system dir is accessible to others");
      } catch (IOException ioe) {
        assertTrue(ioe.toString(),
          ioe.toString().contains("Permission denied"));
      }
      // try accessing ~/.staging/jobid/*
      JobInProgress jip = jt.getJob(id);
      Path jobSubmitDirpath = 
        new Path(jip.getJobConf().get("mapreduce.job.dir"));
      try {
        LOG.info("Try accessing the job folder for job " + id + " as the user (" 
                 + user2.getUserName() + ")");
        client.getListing(jobSubmitDirpath.toUri().getPath(),
          HdfsFileStatus.EMPTY_NAME, false);
        fail("User's staging folder is accessible to others");
      } catch (IOException ioe) {
        assertTrue(ioe.toString(),
          ioe.toString().contains("Permission denied"));
      }
      UtilsForTests.signalTasks(dfs, fs, true, mapSignalFile.toString(), 
      reduceSignalFile.toString());
      // wait for job to be done
      UtilsForTests.waitTillDone(jClient);

      // check if the staging area is cleaned up
      LOG.info("Check if job submit dir is cleanup or not");
      assertFalse(fs.exists(jobSubmitDirpath));
    } finally {
      if (mr != null) {
        mr.shutdown();
      }
      if (dfs != null) {
        dfs.shutdown();
      }
    }
  }
}
