/**
 * 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.IOException;

import javax.security.auth.login.LoginException;

import junit.framework.TestCase;
import org.apache.hadoop.hdfs.TestHDFSServerPorts;
import org.apache.hadoop.hdfs.server.datanode.DataNode;
import org.apache.hadoop.hdfs.server.namenode.NameNode;
import org.apache.hadoop.mapreduce.server.jobtracker.JTConfig;
import org.apache.hadoop.mapreduce.server.tasktracker.TTConfig;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileSystem;

/**
 * This test checks correctness of port usage by mapreduce components:
 * JobTracker, and TaskTracker.
 * 
 * The correct behavior is:<br> 
 * - when a specific port is provided the server must either start on that port 
 * or fail by throwing {@link java.net.BindException}.<br>
 * - if the port = 0 (ephemeral) then the server should choose 
 * a free port and start on it.
 */
public class TestMRServerPorts extends TestCase {
  static final String THIS_HOST = TestHDFSServerPorts.getFullHostName() + ":0";

  TestHDFSServerPorts hdfs = new TestHDFSServerPorts();

  // Runs the JT in a separate thread
  private static class JTRunner extends Thread {
    JobTracker jt;
    void setJobTracker(JobTracker jt) {
      this.jt = jt;
    }

    public void run() {
      if (jt != null) {
        try {
          jt.offerService();
        } catch (Exception ioe) {}
      }
    }
  }
  /**
   * Check whether the JobTracker can be started.
   */
  private JobTracker startJobTracker(JobConf conf, JTRunner runner) 
  throws IOException, LoginException {
    conf.set(JTConfig.JT_IPC_ADDRESS, "localhost:0");
    conf.set(JTConfig.JT_HTTP_ADDRESS, "0.0.0.0:0");
    JobTracker jt = null;
    try {
      jt = JobTracker.startTracker(conf);
      runner.setJobTracker(jt);
      runner.start();
      conf.set(JTConfig.JT_IPC_ADDRESS, "localhost:" + jt.getTrackerPort());
      conf.set(JTConfig.JT_HTTP_ADDRESS, 
                            "0.0.0.0:" + jt.getInfoPort());
    } catch(InterruptedException e) {
      throw new IOException(e.getLocalizedMessage());
    }
    return jt;
  }
  
  private void setDataNodePorts(Configuration conf) {
    conf.set("dfs.datanode.address", THIS_HOST);
    conf.set("dfs.datanode.http.address", THIS_HOST);
    conf.set("dfs.datanode.ipc.address", THIS_HOST);
  }

  /**
   * Check whether the JobTracker can be started.
   */
  private boolean canStartJobTracker(JobConf conf) 
  throws IOException, InterruptedException, LoginException {
    JobTracker jt = null;
    try {
      jt = JobTracker.startTracker(conf);
    } catch(IOException e) {
      if (e instanceof java.net.BindException)
        return false;
      throw e;
    }
    jt.fs.close();
    jt.stopTracker();
    return true;
  }

  /**
   * Check whether the TaskTracker can be started.
   */
  private boolean canStartTaskTracker(JobConf conf) 
  throws IOException, InterruptedException {
    TaskTracker tt = null;
    try {
      tt = new TaskTracker(conf);
    } catch(IOException e) {
      if (e instanceof java.net.BindException)
        return false;
      throw e;
    }
    tt.shutdown();
    return true;
  }

  /**
   * Verify JobTracker port usage.
   */
  public void testJobTrackerPorts() throws Exception {
    NameNode nn = null;
    DataNode dn = null;
    try {
      nn = hdfs.startNameNode();
      setDataNodePorts(hdfs.getConfig());
      dn = hdfs.startDataNode(1, hdfs.getConfig());

      // start job tracker on the same port as name-node
      JobConf conf2 = new JobConf(hdfs.getConfig());
      conf2.set(JTConfig.JT_IPC_ADDRESS,
                FileSystem.getDefaultUri(hdfs.getConfig()).toString());
      conf2.set(JTConfig.JT_HTTP_ADDRESS, THIS_HOST);
      boolean started = canStartJobTracker(conf2);
      assertFalse(started); // should fail

      // bind http server to the same port as name-node
      conf2.set(JTConfig.JT_IPC_ADDRESS, THIS_HOST);
      conf2.set(JTConfig.JT_HTTP_ADDRESS,
        hdfs.getConfig().get("dfs.http.address"));
      started = canStartJobTracker(conf2);
      assertFalse(started); // should fail again

      // both ports are different from the name-node ones
      conf2.set(JTConfig.JT_IPC_ADDRESS, THIS_HOST);
      conf2.set(JTConfig.JT_HTTP_ADDRESS, THIS_HOST);
      started = canStartJobTracker(conf2);
      assertTrue(started); // should start now

    } finally {
      hdfs.stopDataNode(dn);
      hdfs.stopNameNode(nn);
    }
  }

  /**
   * Verify JobTracker port usage.
   */
  public void testTaskTrackerPorts() throws Exception {
    NameNode nn = null;
    DataNode dn = null;
    JobTracker jt = null;
    JTRunner runner = null;
    try {
      nn = hdfs.startNameNode();
      setDataNodePorts(hdfs.getConfig());
      dn = hdfs.startDataNode(2, hdfs.getConfig());

      JobConf conf2 = new JobConf(hdfs.getConfig());
      runner = new JTRunner();
      jt = startJobTracker(conf2, runner);

      // start job tracker on the same port as name-node
      conf2.set(TTConfig.TT_REPORT_ADDRESS,
                FileSystem.getDefaultUri(hdfs.getConfig()).toString());
      conf2.set(TTConfig.TT_HTTP_ADDRESS, THIS_HOST);
      boolean started = canStartTaskTracker(conf2);
      assertFalse(started); // should fail

      // bind http server to the same port as name-node
      conf2.set(TTConfig.TT_REPORT_ADDRESS, THIS_HOST);
      conf2.set(TTConfig.TT_HTTP_ADDRESS,
        hdfs.getConfig().get("dfs.http.address"));
      started = canStartTaskTracker(conf2);
      assertFalse(started); // should fail again

      // both ports are different from the name-node ones
      conf2.set(TTConfig.TT_REPORT_ADDRESS, THIS_HOST);
      conf2.set(TTConfig.TT_HTTP_ADDRESS, THIS_HOST);
      started = canStartTaskTracker(conf2);
      assertTrue(started); // should start now
    } finally {
      if (jt != null) {
        jt.fs.close();
        jt.stopTracker();
        runner.interrupt();
        runner.join();
      }
      hdfs.stopDataNode(dn);
      hdfs.stopNameNode(nn);
    }
  }
}
