@Test
  public void testDecommissonDatanodeAction() throws Exception {
    String cluster1 = getUniqueName();
    createCluster(cluster1);
    Cluster cluster = clusters.getCluster(cluster1);
    cluster.setDesiredStackVersion(new StackId("HDP-2.0.7"));
    String serviceName = "HDFS";
    createService(cluster1, serviceName, null);
    String componentName1 = "NAMENODE";
    String componentName2 = "DATANODE";
    String componentName3 = "HDFS_CLIENT";

    createServiceComponent(cluster1, serviceName, componentName1,
      State.INIT);
    createServiceComponent(cluster1, serviceName, componentName2,
      State.INIT);
    createServiceComponent(cluster1, serviceName, componentName3,
      State.INIT);

    // !!! for whatever reason, the assertions are alphabetical to hostnames
    final String host1 = "d" + getUniqueName();
    final String host2 = "e" + getUniqueName();

    addHostToCluster(host1, cluster1);
    addHostToCluster(host2, cluster1);

    createServiceComponentHost(cluster1, serviceName, componentName1,
      host1, null);
    createServiceComponentHost(cluster1, serviceName, componentName2,
      host1, null);
    createServiceComponentHost(cluster1, serviceName, componentName2,
      host2, null);
    createServiceComponentHost(cluster1, serviceName, componentName3,
      host1, null);
    createServiceComponentHost(cluster1, serviceName, componentName3,
      host2, null);

    RequestOperationLevel level = new RequestOperationLevel(
            Resource.Type.HostComponent, cluster1, null, null, null);

    // Install
    installService(cluster1, serviceName, false, false);

    // Create and attach config
    Map<String, String> configs = new HashMap<>();
    configs.put("a", "b");

    ConfigurationRequest cr1;
    cr1 = new ConfigurationRequest(cluster1, "hdfs-site","version1",
      configs, null);
    ClusterRequest crReq = new ClusterRequest(cluster.getClusterId(), cluster1, null, null);
    crReq.setDesiredConfig(Collections.singletonList(cr1));
    controller.updateClusters(Collections.singleton(crReq), null);

    // Start
    startService(cluster1, serviceName, false, false);

    cluster = clusters.getCluster(cluster1);
    Service s = cluster.getService(serviceName);
    Assert.assertEquals(State.STARTED, s.getDesiredState());
    ServiceComponentHost scHost = s.getServiceComponent("DATANODE").getServiceComponentHost(host2);
    Assert.assertEquals(HostComponentAdminState.INSERVICE, scHost.getComponentAdminState());

    // Decommission one datanode
    Map<String, String> params = new HashMap<String, String>(){{
      put("test", "test");
      put("excluded_hosts", host2);
      put("align_maintenance_state", "true");
    }};
    RequestResourceFilter resourceFilter = new RequestResourceFilter("HDFS", "NAMENODE", null);
    ArrayList<RequestResourceFilter> filters = new ArrayList<>();
    filters.add(resourceFilter);
    ExecuteActionRequest request = new ExecuteActionRequest(cluster1,
            "DECOMMISSION", null, filters, level, params, false);

    Map<String, String> requestProperties = new HashMap<>();
    requestProperties.put(REQUEST_CONTEXT_PROPERTY, "Called from a test");

    RequestStatusResponse response = controller.createAction(request,
      requestProperties);

    List<HostRoleCommand> storedTasks = actionDB.getRequestTasks(response.getRequestId());
    ExecutionCommand execCmd = storedTasks.get(0).getExecutionCommandWrapper
      ().getExecutionCommand();
    Assert.assertNotNull(storedTasks);
    Assert.assertEquals(1, storedTasks.size());
    Assert.assertEquals(HostComponentAdminState.DECOMMISSIONED, scHost.getComponentAdminState());
    Assert.assertEquals(MaintenanceState.ON, scHost.getMaintenanceState());
    HostRoleCommand command =  storedTasks.get(0);
    Assert.assertEquals(Role.NAMENODE, command.getRole());
    Assert.assertEquals(RoleCommand.CUSTOM_COMMAND, command.getRoleCommand());
    Assert.assertEquals("DECOMMISSION", execCmd.getCommandParams().get("custom_command"));
    Assert.assertEquals(host2, execCmd.getCommandParams().get("all_decommissioned_hosts"));
    Assert.assertEquals(requestProperties.get(REQUEST_CONTEXT_PROPERTY), response.getRequestContext());

    // Decommission the other datanode
    params = new HashMap<String, String>(){{
      put("test", "test");
      put("excluded_hosts", host1);
      put("align_maintenance_state", "true");
    }};
    resourceFilter = new RequestResourceFilter("HDFS", "NAMENODE", null);
    filters = new ArrayList<>();
    filters.add(resourceFilter);

    request = new ExecuteActionRequest(cluster1, "DECOMMISSION",
            null, filters, level, params, false);

    response = controller.createAction(request,
        requestProperties);

    storedTasks = actionDB.getRequestTasks(response.getRequestId());
    execCmd = storedTasks.get(0).getExecutionCommandWrapper
        ().getExecutionCommand();
    Map<String, String> cmdParams = execCmd.getCommandParams();
    Assert.assertTrue(cmdParams.containsKey("update_files_only"));
    Assert.assertTrue(cmdParams.get("update_files_only").equals("false"));
    Assert.assertNotNull(storedTasks);
    Assert.assertEquals(1, storedTasks.size());
    Assert.assertEquals(HostComponentAdminState.DECOMMISSIONED, scHost.getComponentAdminState());
    Assert.assertEquals(MaintenanceState.ON, scHost.getMaintenanceState());
    Assert.assertEquals("DECOMMISSION", execCmd.getCommandParams().get("custom_command"));
    Assert.assertTrue(execCmd.getCommandParams().get("all_decommissioned_hosts").contains(host1));
    Assert.assertTrue(execCmd.getCommandParams().get("all_decommissioned_hosts").contains(host2));
    Assert.assertTrue(execCmd.getCommandParams().get("all_decommissioned_hosts").equals(host1+","+host2) ||
      execCmd.getCommandParams().get("all_decommissioned_hosts").equals(host2+","+host1));
    Assert.assertEquals(requestProperties.get(REQUEST_CONTEXT_PROPERTY), response.getRequestContext());

    // Recommission the other datanode  (while adding NameNode HA)
    createServiceComponentHost(cluster1, serviceName, componentName1,
        host2, null);
    ServiceComponentHostRequest r = new ServiceComponentHostRequest(cluster1, serviceName,
        componentName1, host2, State.INSTALLED.toString());
    Set<ServiceComponentHostRequest> requests = new HashSet<>();
    requests.add(r);
    updateHostComponents(requests, Collections.emptyMap(), true);
    s.getServiceComponent(componentName1).getServiceComponentHost(host2).setState(State.INSTALLED);
    r = new ServiceComponentHostRequest(cluster1, serviceName,
        componentName1, host2, State.STARTED.toString());
    requests.clear();
    requests.add(r);
    updateHostComponents(requests, Collections.emptyMap(), true);
    s.getServiceComponent(componentName1).getServiceComponentHost(host2).setState(State.STARTED);

    params = new HashMap<String, String>(){{
      put("test", "test");
      put("included_hosts", host1 + " , " + host2);
      put("align_maintenance_state", "true");
    }};
    resourceFilter = new RequestResourceFilter("HDFS", "NAMENODE", null);
    filters = new ArrayList<>();
    filters.add(resourceFilter);
    request = new ExecuteActionRequest(cluster1, "DECOMMISSION", null,
            filters, level, params, false);

    response = controller.createAction(request,
        requestProperties);

    storedTasks = actionDB.getRequestTasks(response.getRequestId());
    Assert.assertNotNull(storedTasks);
    scHost = s.getServiceComponent("DATANODE").getServiceComponentHost(host2);
    Assert.assertEquals(HostComponentAdminState.INSERVICE, scHost.getComponentAdminState());
    Assert.assertEquals(MaintenanceState.OFF, scHost.getMaintenanceState());
    execCmd = storedTasks.get(0).getExecutionCommandWrapper().getExecutionCommand();
    Assert.assertNotNull(storedTasks);
    Assert.assertEquals(2, storedTasks.size());
    int countRefresh = 0;
    for(HostRoleCommand hrc : storedTasks) {
      Assert.assertEquals("DECOMMISSION", hrc.getCustomCommandName());
      // hostname order is not guaranteed
      Assert.assertTrue(hrc.getCommandDetail().contains("DECOMMISSION, Included: "));
      Assert.assertTrue(hrc.getCommandDetail().contains(host1));
      Assert.assertTrue(hrc.getCommandDetail().contains(host2));
      cmdParams = hrc.getExecutionCommandWrapper().getExecutionCommand().getCommandParams();
      if(!cmdParams.containsKey("update_files_only")
          || !cmdParams.get("update_files_only").equals("true")) {
        countRefresh++;
      }
      Assert.assertEquals("", cmdParams.get("all_decommissioned_hosts"));
    }
    Assert.assertEquals(2, countRefresh);

    // Slave components will have admin state as INSERVICE even if the state in DB is null
    scHost.setComponentAdminState(null);
    Assert.assertEquals(HostComponentAdminState.INSERVICE, scHost.getComponentAdminState());
    Assert.assertEquals(MaintenanceState.OFF, scHost.getMaintenanceState());
    Assert.assertEquals(requestProperties.get(REQUEST_CONTEXT_PROPERTY), response.getRequestContext());
  }
Create a cluster with a service, and verify that the request tasks have the correct output log and error log paths.
ambari-server/src/test/java/org/apache/ambari/server/controller/AmbariManagementControllerTest.java