/**
 * 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 static org.junit.Assert.*;

import java.io.IOException;
import java.util.LinkedHashMap;

import org.apache.hadoop.mapred.TaskTracker.TaskInProgress;
import org.apache.hadoop.mapred.TaskTracker.TaskLauncher;
import org.apache.hadoop.mapreduce.TaskType;
import org.apache.hadoop.mapreduce.server.tasktracker.TTConfig;
import org.junit.Test;

/**
 * Tests {@link TaskLauncher}
 * 
 */
public class TestTaskLauncher {
  private static int expectedLaunchAttemptId = 1;

  private static class MyTaskTracker extends TaskTracker {
    // override startNewTask just to set the runState, 
    // not to launch the task really 
    @Override
    void startNewTask(TaskInProgress tip) {
      assertEquals(expectedLaunchAttemptId, tip.getTask().getTaskID().getId());
      tip.getStatus().setRunState(TaskStatus.State.RUNNING);
    }
  }

  /**
   * Tests the case "task waiting to be launched is killed externally".
   * 
   * Launches a task which will wait for ever to get slots. Kill the
   * task and see if launcher is able to come out of the wait and pickup a
   * another task.
   * 
   * @throws IOException
   */
  @Test
  public void testExternalKillForLaunchTask() throws IOException {
    // setup a TaskTracker
    JobConf ttConf = new JobConf();
    ttConf.setInt(TTConfig.TT_MAP_SLOTS, 4);
    TaskTracker tt = new MyTaskTracker();
    tt.runningTasks = new LinkedHashMap<TaskAttemptID, TaskInProgress>();
    tt.setConf(ttConf);
    tt.setIndexCache(new IndexCache(ttConf));
    tt.setTaskMemoryManagerEnabledFlag(); 

    // Set up TaskTracker instrumentation
    tt.setTaskTrackerInstrumentation(
        TaskTracker.createInstrumentation(tt, tt.getJobConf()));

    // start map-task launcher with four slots
    TaskLauncher mapLauncher = tt.new TaskLauncher(TaskType.MAP, 4);
    mapLauncher.start();
    
    // launch a task which requires five slots
    String jtId = "test";
    TaskAttemptID attemptID = new TaskAttemptID(jtId, 1, TaskType.MAP, 0, 0);
    Task task = new MapTask(null, attemptID, 0, null, 5);
    mapLauncher.addToTaskQueue(new LaunchTaskAction(task));
    // verify that task is added to runningTasks
    TaskInProgress killTip = tt.runningTasks.get(attemptID);
    assertNotNull(killTip);

    // wait for a while for launcher to pick up the task
    // this loop waits atmost for 30 seconds
    for (int i = 0; i < 300; i++) {
      if (mapLauncher.getNumWaitingTasksToLaunch() == 0) {
        break;
      }
      UtilsForTests.waitFor(100);
    }
    assertEquals("Launcher didnt pick up the task " + attemptID + "to launch",
        0, mapLauncher.getNumWaitingTasksToLaunch());

    // Now, that launcher has picked up the task, it waits until all five slots
    // are available. i.e. it waits for-ever
    // lets kill the task so that map launcher comes out
    tt.processKillTaskAction(new KillTaskAction(attemptID));
    assertEquals(TaskStatus.State.KILLED, killTip.getRunState());

    // launch another attempt which requires only one slot
    TaskAttemptID runningAttemptID = new TaskAttemptID(jtId, 1, TaskType.MAP,
        0, expectedLaunchAttemptId);
    mapLauncher.addToTaskQueue(new LaunchTaskAction(new MapTask(null,
        runningAttemptID, 0, null, 1)));
    TaskInProgress runningTip = tt.runningTasks.get(runningAttemptID);
    assertNotNull(runningTip);

    // wait for a while for the task to be launched
    // this loop waits at most for 30 seconds
    for (int i = 0; i < 300; i++) {
      if (runningTip.getRunState().equals(TaskStatus.State.RUNNING)) {
        break;
      }
      UtilsForTests.waitFor(100);
    }

    // verify that the task went to running
    assertEquals(TaskStatus.State.RUNNING, runningTip.getRunState());
  }

}
