You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by sw...@apache.org on 2016/04/20 08:35:36 UTC

ambari git commit: AMBARI-15959. HiveServerInteractive. LLAP status check code

Repository: ambari
Updated Branches:
  refs/heads/trunk a02ae60d1 -> 172eb1111


AMBARI-15959. HiveServerInteractive. LLAP status check code


Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/172eb111
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/172eb111
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/172eb111

Branch: refs/heads/trunk
Commit: 172eb111144afce79d91d6029945366bd4f0628c
Parents: a02ae60
Author: swapan <sw...@apache.org>
Authored: Tue Apr 19 21:28:36 2016 -0700
Committer: swapan <sw...@apache.org>
Committed: Tue Apr 19 23:07:40 2016 -0700

----------------------------------------------------------------------
 .../package/scripts/hive_server_interactive.py  | 125 +++++++++-
 .../0.12.0.2.0/package/scripts/params_linux.py  |   1 +
 .../HIVE/configuration/hive-interactive-env.xml |  12 +
 .../configuration/hive-interactive-site.xml     |   2 +-
 .../python/stacks/2.5/HIVE/appComplete.json     |  10 +
 .../test/python/stacks/2.5/HIVE/invalidApp.json |   3 +
 .../stacks/2.5/HIVE/oneContainerDown.json       |  33 +++
 .../stacks/2.5/HIVE/oneContainerDown1.json      |  33 +++
 .../test/python/stacks/2.5/HIVE/running.json    |  41 +++
 .../test/python/stacks/2.5/HIVE/starting.json   |  16 ++
 .../stacks/2.5/HIVE/test_hive_server_int.py     | 250 ++++++++++++++++++-
 .../python/stacks/2.5/configs/hsi_default.json  |   3 +-
 12 files changed, 518 insertions(+), 11 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/172eb111/ambari-server/src/main/resources/common-services/HIVE/0.12.0.2.0/package/scripts/hive_server_interactive.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/common-services/HIVE/0.12.0.2.0/package/scripts/hive_server_interactive.py b/ambari-server/src/main/resources/common-services/HIVE/0.12.0.2.0/package/scripts/hive_server_interactive.py
index 0a2105d..8af82f0 100644
--- a/ambari-server/src/main/resources/common-services/HIVE/0.12.0.2.0/package/scripts/hive_server_interactive.py
+++ b/ambari-server/src/main/resources/common-services/HIVE/0.12.0.2.0/package/scripts/hive_server_interactive.py
@@ -24,6 +24,7 @@ import re
 import time
 import shutil
 from datetime import datetime
+import json
 
 # Ambari Commons & Resource Management imports
 from resource_management.libraries.script.script import Script
@@ -43,7 +44,9 @@ from resource_management.core.exceptions import Fail
 from resource_management.core.logger import Logger
 from ambari_commons import OSCheck, OSConst
 from ambari_commons.os_family_impl import OsFamilyImpl
-from pwd import getpwnam
+
+from resource_management.core.exceptions import ComponentIsNotRunning
+from resource_management.libraries.functions.decorator import retry
 
 # Local Imports
 from setup_ranger_hive import setup_ranger_hive
@@ -135,14 +138,23 @@ class HiveServerInteractiveDefault(HiveServerInteractive):
 
       self._llap_stop(env)
 
+    """
+    Checks the status of Hive Server Interactive and LLAP app.
+    If any of them is down, status is shown STOPPED.
+    """
     def status(self, env):
       import status_params
       env.set_params(status_params)
+
+      status = self.check_llap_app_status("llap0", 0)
+      if not status:
+        Logger.error("Slider app 'llap' not in running state.")
+        raise ComponentIsNotRunning()
+
       pid_file = format("{hive_pid_dir}/{hive_interactive_pid}")
 
       # Recursively check all existing gmetad pid files
       check_process_status(pid_file)
-      # TODO : Check the LLAP app status as well.
 
     def security_status(self, env):
       HiveServerDefault.security_status(env)
@@ -195,6 +207,7 @@ class HiveServerInteractiveDefault(HiveServerInteractive):
       import params
       env.set_params(params)
       Logger.info("Starting LLAP")
+      LLAP_APP_NAME = 'llap0'
 
       # TODO, start only if not already running.
       # TODO : Currently hardcoded the params. Need to read the suggested values from hive2/hive-site.xml.
@@ -204,7 +217,7 @@ class HiveServerInteractiveDefault(HiveServerInteractive):
       unique_name = "llap-slider%s" % datetime.utcnow().strftime('%Y-%m-%d_%H-%M-%S')
 
       cmd = format("{stack_root}/current/hive-server2-hive2/bin/hive --service llap --instances 1 "
-                   "-slider-am-container-mb {slider_am_container_mb} --loglevel INFO --output {unique_name}")
+                   "--slider-am-container-mb {slider_am_container_mb} --loglevel INFO --output {unique_name}")
 
       if params.security_enabled:
         cmd += format(" --slider-keytab-dir .slider/keytabs/{params.hive_user}/ --slider-keytab "
@@ -238,8 +251,14 @@ class HiveServerInteractiveDefault(HiveServerInteractive):
           Logger.info("Sleeping for 30 secs")
           # Important to mock this sleep call during unit tests.
           time.sleep(30)
-          Logger.info("LLAP app deployed successfully.")
-          return True
+          Logger.info("Submitted LLAP app name : {0}".format(LLAP_APP_NAME))
+
+          status = self.check_llap_app_status(LLAP_APP_NAME, params.num_retries_for_checking_llap_status)
+          if status:
+            Logger.info("LLAP app '{0}' deployed successfully.".format(LLAP_APP_NAME))
+            return True
+          else:
+            return False
         else:
           raise Fail(format("Did not find run file {run_file_path}"))
       except:
@@ -254,7 +273,6 @@ class HiveServerInteractiveDefault(HiveServerInteractive):
 
         # throw the original exception
         raise
-      return False
 
     """
     Does kinit and copies keytab for Hive/LLAP to HDFS.
@@ -274,6 +292,101 @@ class HiveServerInteractiveDefault(HiveServerInteractive):
       hive_interactive_kinit_cmd = format("{kinit_path_local} -kt {hive_server2_keytab} {hive_principal}; ")
       Execute(hive_interactive_kinit_cmd, user=params.hive_user)
 
+    """
+    Get llap app status data.
+    """
+    def _get_llap_app_status_info(self, app_name):
+      import status_params
+
+      llap_status_cmd = format("{stack_root}/current/hive-server2-hive2/bin/hive --service llapstatus --name {app_name}")
+      code, output, error = shell.checked_call(llap_status_cmd, user=status_params.hive_user, stderr=subprocess.PIPE,
+                                               logoutput=False)
+      llap_app_info = json.loads(output)
+      return llap_app_info
+
+
+    """
+    Checks llap app status. The states can be : 'COMPLETE', 'APP_NOT_FOUND', 'RUNNING_PARTIAL', 'RUNNING_ALL' & 'LAUNCHING'.
+
+    If app is in 'APP_NOT_FOUND', 'RUNNING_PARTIAL' and 'LAUNCHING' state, we wait for 'num_times_to_wait' to have app
+    in (1). 'RUNNING_ALL' (2). 'LAUNCHING' or (3). 'RUNNING_PARTIAL' state with 80% or more 'desiredInstances' running.
+
+    Parameters: llap_app_name : deployed llap app name.
+                num_retries :   Number of retries to check the LLAP app status.
+    """
+    def check_llap_app_status(self, llap_app_name, num_retries):
+      # counters based on various states.
+      curr_time = time.time()
+
+      if num_retries <= 0:
+        num_retries = 2
+      if num_retries > 20:
+        num_retries = 20
+
+      @retry(times=num_retries, sleep_time=15, err_class=Fail)
+      def do_retries():
+        live_instances = 0
+        desired_instances = 0
+
+        percent_desired_instances_to_be_up = 80 # Used in 'RUNNING_PARTIAL' state.
+        llap_app_info = self._get_llap_app_status_info(llap_app_name)
+
+        if llap_app_info is None or 'state' not in llap_app_info:
+          Logger.error("Malformed JSON data received for LLAP app. Exiting ....")
+          return False
+
+        if llap_app_info['state'].upper() in ['RUNNING_ALL', 'LAUNCHING']:
+          Logger.info(
+            "LLAP app '{0}' in '{1}' state.".format(llap_app_name, llap_app_info['state']))
+          return True
+        elif llap_app_info['state'].upper() == 'RUNNING_PARTIAL':
+          # Check how many instances were up.
+          if 'liveInstances' in llap_app_info and 'desiredInstances' in llap_app_info:
+            live_instances = llap_app_info['liveInstances']
+            desired_instances = llap_app_info['desiredInstances']
+          else:
+            Logger.info(
+              "LLAP app '{0}' is in '{1}' state, but 'instances' information not available in JSON received. " \
+              "Exiting ....".format(llap_app_name, llap_app_info['state']))
+            Logger.info(llap_app_info)
+            return False
+          if desired_instances == 0:
+            Logger.info("LLAP app '{0}' desired instance are set to 0. Exiting ....".format(llap_app_name))
+            return False
+
+          percentInstancesUp = 0
+          if live_instances > 0:
+            percentInstancesUp = float(live_instances) / desired_instances * 100
+          if percentInstancesUp >= percent_desired_instances_to_be_up:
+            Logger.info("Slider app '{0}' in '{1}' state. Live Instances : '{2}'  >= {3}% of Desired Instances : " \
+                        "'{4}'".format(llap_app_name, llap_app_info['state'],
+                                       llap_app_info['liveInstances'],
+                                       percent_desired_instances_to_be_up,
+                                       llap_app_info['desiredInstances']))
+            return True
+          else:
+            Logger.info("Slider app '{0}' in '{1}' state. Live Instances : '{2}'. Desired Instances : " \
+                        "'{3}' after {4} secs.".format(llap_app_name, llap_app_info['state'],
+                                                       llap_app_info['liveInstances'],
+                                                       llap_app_info['desiredInstances'],
+                                                       time.time() - curr_time))
+            raise Fail('App state is RUNNING_PARTIAL.')
+        elif llap_app_info['state'].upper() == 'APP_NOT_FOUND':
+          status_str = format("Slider app '{0}' current state is {1}.".format(llap_app_name, llap_app_info['state']))
+          Logger.info(status_str)
+          raise Fail(status_str)
+        else:  # Covers state "COMPLETE" and any unknown that we get.
+          Logger.info(
+            "Slider app '{0}' current state is '{1}'. Expected : 'RUNNING'".format(llap_app_name, llap_app_info['state']))
+          return False
+
+      try:
+        status = do_retries()
+        return status
+      except Exception, e:
+        Logger.info("App '{0}' did not come up after a wait of {1} seconds".format(llap_app_name,
+                                                                                          time.time() - curr_time))
+        return False
 
 @OsFamilyImpl(os_family=OSConst.WINSRV_FAMILY)
 class HiveServerInteractiveWindows(HiveServerInteractive):

http://git-wip-us.apache.org/repos/asf/ambari/blob/172eb111/ambari-server/src/main/resources/common-services/HIVE/0.12.0.2.0/package/scripts/params_linux.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/common-services/HIVE/0.12.0.2.0/package/scripts/params_linux.py b/ambari-server/src/main/resources/common-services/HIVE/0.12.0.2.0/package/scripts/params_linux.py
index ca227b5..2414e8b 100644
--- a/ambari-server/src/main/resources/common-services/HIVE/0.12.0.2.0/package/scripts/params_linux.py
+++ b/ambari-server/src/main/resources/common-services/HIVE/0.12.0.2.0/package/scripts/params_linux.py
@@ -509,6 +509,7 @@ if has_hive_interactive:
   # Tez for Hive interactive related
   tez_interactive_config_dir = "/etc/tez_hive2/conf"
   tez_interactive_user = config['configurations']['tez-env']['tez_user']
+  num_retries_for_checking_llap_status = default('/configurations/hive-interactive-env/num_retries_for_checking_llap_status', 10)
   if security_enabled:
     hive_llap_keytab_file = config['configurations']['hive-interactive-site']['hive.llap.zk.sm.keytab.file']
     hive_headless_keytab = config['configurations']['hive-interactive-site']['hive.llap.zk.sm.principal']

http://git-wip-us.apache.org/repos/asf/ambari/blob/172eb111/ambari-server/src/main/resources/stacks/HDP/2.5/services/HIVE/configuration/hive-interactive-env.xml
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/stacks/HDP/2.5/services/HIVE/configuration/hive-interactive-env.xml b/ambari-server/src/main/resources/stacks/HDP/2.5/services/HIVE/configuration/hive-interactive-env.xml
index 88541bd..816e207 100644
--- a/ambari-server/src/main/resources/stacks/HDP/2.5/services/HIVE/configuration/hive-interactive-env.xml
+++ b/ambari-server/src/main/resources/stacks/HDP/2.5/services/HIVE/configuration/hive-interactive-env.xml
@@ -81,6 +81,18 @@
       <increment-step>1</increment-step>
     </value-attributes>
   </property>
+  <property>
+    <name>num_retries_for_checking_llap_status</name>
+    <value>10</value>
+    <description>After starting LLAP app, retry count to check LLAP status before starting HiveServer2.</description>
+    <display-name>Number of retries while checking LLAP app status</display-name>
+    <value-attributes>
+      <type>int</type>
+      <minimum>0</minimum>
+      <maximum>20</maximum>
+      <increment-step>1</increment-step>
+    </value-attributes>
+  </property>
 
   <!-- hive-env.sh -->
   <property>

http://git-wip-us.apache.org/repos/asf/ambari/blob/172eb111/ambari-server/src/main/resources/stacks/HDP/2.5/services/HIVE/configuration/hive-interactive-site.xml
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/stacks/HDP/2.5/services/HIVE/configuration/hive-interactive-site.xml b/ambari-server/src/main/resources/stacks/HDP/2.5/services/HIVE/configuration/hive-interactive-site.xml
index 0b3de15..21d1109 100644
--- a/ambari-server/src/main/resources/stacks/HDP/2.5/services/HIVE/configuration/hive-interactive-site.xml
+++ b/ambari-server/src/main/resources/stacks/HDP/2.5/services/HIVE/configuration/hive-interactive-site.xml
@@ -357,7 +357,7 @@ limitations under the License.
 
   <property>
     <name>hive.llap.daemon.service.hosts</name>
-    <value>@{cluster_name}</value>
+    <value>@llap0</value>
   </property>
 
   <property>

http://git-wip-us.apache.org/repos/asf/ambari/blob/172eb111/ambari-server/src/test/python/stacks/2.5/HIVE/appComplete.json
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/python/stacks/2.5/HIVE/appComplete.json b/ambari-server/src/test/python/stacks/2.5/HIVE/appComplete.json
new file mode 100644
index 0000000..43c276f
--- /dev/null
+++ b/ambari-server/src/test/python/stacks/2.5/HIVE/appComplete.json
@@ -0,0 +1,10 @@
+{
+  "amInfo" : {
+    "appName" : "llap",
+    "appType" : "org-apache-slider",
+    "appId" : "application_1455662455106_10882"
+  },
+  "state" : "COMPLETE",
+  "appStartTime" : 1459625790218,
+  "appFinishTime" : 1459625939033
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ambari/blob/172eb111/ambari-server/src/test/python/stacks/2.5/HIVE/invalidApp.json
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/python/stacks/2.5/HIVE/invalidApp.json b/ambari-server/src/test/python/stacks/2.5/HIVE/invalidApp.json
new file mode 100644
index 0000000..4f7e82f
--- /dev/null
+++ b/ambari-server/src/test/python/stacks/2.5/HIVE/invalidApp.json
@@ -0,0 +1,3 @@
+{
+  "state" : "APP_NOT_FOUND"
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ambari/blob/172eb111/ambari-server/src/test/python/stacks/2.5/HIVE/oneContainerDown.json
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/python/stacks/2.5/HIVE/oneContainerDown.json b/ambari-server/src/test/python/stacks/2.5/HIVE/oneContainerDown.json
new file mode 100644
index 0000000..b601104
--- /dev/null
+++ b/ambari-server/src/test/python/stacks/2.5/HIVE/oneContainerDown.json
@@ -0,0 +1,33 @@
+{
+  "amInfo" : {
+    "appName" : "llap",
+    "appType" : "org-apache-slider",
+    "appId" : "application_1455662455106_10882",
+    "containerId" : "container_e14_1455662455106_10882_01_000001",
+    "hostname" : "HOST_REPLACED",
+    "amWebUrl" : "http://HOST_REPLACED:1025/"
+  },
+  "state" : "RUNNING_PARTIAL",
+  "originalConfigurationPath" : "hdfs://HOST_REPLACED:8020/user/USER_REPLACED/.slider/cluster/llap/snapshot",
+  "generatedConfigurationPath" : "hdfs://HOST_REPLACED:8020/user/USER_REPLACED/.slider/cluster/llap/generated",
+  "desiredInstances" : 3,
+  "liveInstances" : 2,
+  "appStartTime" : 1459625802169,
+  "llapInstances" : [ {
+    "hostname" : "HOST_REPLACED",
+    "containerId" : "container_e14_1455662455106_10882_01_000003",
+    "statusUrl" : "http://HOST_REPLACED:15002/status",
+    "webUrl" : "http://HOST_REPLACED:15002",
+    "rpcPort" : 15001,
+    "mgmtPort" : 15004,
+    "shufflePort" : 15551
+  }, {
+    "hostname" : "HOST_REPLACED",
+    "containerId" : "container_e14_1455662455106_10882_01_000002",
+    "statusUrl" : "http://HOST_REPLACED:15002/status",
+    "webUrl" : "http://HOST_REPLACED:15002",
+    "rpcPort" : 15001,
+    "mgmtPort" : 15004,
+    "shufflePort" : 15551
+  } ]
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ambari/blob/172eb111/ambari-server/src/test/python/stacks/2.5/HIVE/oneContainerDown1.json
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/python/stacks/2.5/HIVE/oneContainerDown1.json b/ambari-server/src/test/python/stacks/2.5/HIVE/oneContainerDown1.json
new file mode 100644
index 0000000..eb96bce
--- /dev/null
+++ b/ambari-server/src/test/python/stacks/2.5/HIVE/oneContainerDown1.json
@@ -0,0 +1,33 @@
+{
+  "amInfo" : {
+    "appName" : "llap",
+    "appType" : "org-apache-slider",
+    "appId" : "application_1455662455106_10882",
+    "containerId" : "container_e14_1455662455106_10882_01_000001",
+    "hostname" : "HOST_REPLACED",
+    "amWebUrl" : "http://HOST_REPLACED:1025/"
+  },
+  "state" : "RUNNING_PARTIAL",
+  "originalConfigurationPath" : "hdfs://HOST_REPLACED:8020/user/USER_REPLACED/.slider/cluster/llap/snapshot",
+  "generatedConfigurationPath" : "hdfs://HOST_REPLACED:8020/user/USER_REPLACED/.slider/cluster/llap/generated",
+  "desiredInstances" : 12,
+  "liveInstances" : 10,
+  "appStartTime" : 1459625802169,
+  "llapInstances" : [ {
+    "hostname" : "HOST_REPLACED",
+    "containerId" : "container_e14_1455662455106_10882_01_000003",
+    "statusUrl" : "http://HOST_REPLACED:15002/status",
+    "webUrl" : "http://HOST_REPLACED:15002",
+    "rpcPort" : 15001,
+    "mgmtPort" : 15004,
+    "shufflePort" : 15551
+  }, {
+    "hostname" : "HOST_REPLACED",
+    "containerId" : "container_e14_1455662455106_10882_01_000002",
+    "statusUrl" : "http://HOST_REPLACED:15002/status",
+    "webUrl" : "http://HOST_REPLACED:15002",
+    "rpcPort" : 15001,
+    "mgmtPort" : 15004,
+    "shufflePort" : 15551
+  } ]
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ambari/blob/172eb111/ambari-server/src/test/python/stacks/2.5/HIVE/running.json
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/python/stacks/2.5/HIVE/running.json b/ambari-server/src/test/python/stacks/2.5/HIVE/running.json
new file mode 100644
index 0000000..73bdf17
--- /dev/null
+++ b/ambari-server/src/test/python/stacks/2.5/HIVE/running.json
@@ -0,0 +1,41 @@
+{
+  "amInfo" : {
+    "appName" : "llap",
+    "appType" : "org-apache-slider",
+    "appId" : "application_1455662455106_10882",
+    "containerId" : "container_e14_1455662455106_10882_01_000001",
+    "hostname" : "HOST_REPLACED",
+    "amWebUrl" : "http://HOST_REPLACED:1025/"
+  },
+  "state" : "RUNNING_ALL",
+  "originalConfigurationPath" : "hdfs://HOST_REPLACED:8020/user/USER_REPLACED/.slider/cluster/llap/snapshot",
+  "generatedConfigurationPath" : "hdfs://HOST_REPLACED:8020/user/USER_REPLACED/.slider/cluster/llap/generated",
+  "desiredInstances" : 3,
+  "liveInstances" : 3,
+  "appStartTime" : 1459625802169,
+  "llapInstances" : [ {
+    "hostname" : "HOST_REPLACED",
+    "containerId" : "container_e14_1455662455106_10882_01_000003",
+    "statusUrl" : "http://HOST_REPLACED:15002/status",
+    "webUrl" : "http://HOST_REPLACED:15002",
+    "rpcPort" : 15001,
+    "mgmtPort" : 15004,
+    "shufflePort" : 15551
+  }, {
+    "hostname" : "HOST_REPLACED",
+    "containerId" : "container_e14_1455662455106_10882_01_000002",
+    "statusUrl" : "http://HOST_REPLACED:15002/status",
+    "webUrl" : "http://HOST_REPLACED:15002",
+    "rpcPort" : 15001,
+    "mgmtPort" : 15004,
+    "shufflePort" : 15551
+  }, {
+    "hostname" : "HOST_REPLACED",
+    "containerId" : "container_e14_1455662455106_10882_01_000004",
+    "statusUrl" : "http://HOST_REPLACED:15002/status",
+    "webUrl" : "http://HOST_REPLACED:15002",
+    "rpcPort" : 15001,
+    "mgmtPort" : 15004,
+    "shufflePort" : 15551
+  } ]
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ambari/blob/172eb111/ambari-server/src/test/python/stacks/2.5/HIVE/starting.json
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/python/stacks/2.5/HIVE/starting.json b/ambari-server/src/test/python/stacks/2.5/HIVE/starting.json
new file mode 100644
index 0000000..b2be3c1
--- /dev/null
+++ b/ambari-server/src/test/python/stacks/2.5/HIVE/starting.json
@@ -0,0 +1,16 @@
+{
+  "amInfo" : {
+    "appName" : "llap",
+    "appType" : "org-apache-slider",
+    "appId" : "application_1455662455106_10882",
+    "containerId" : "container_e14_1455662455106_10882_01_000001",
+    "hostname" : "HOST_REPLACED",
+    "amWebUrl" : "http://HOST_REPLACED:1025/"
+  },
+  "state" : "LAUNCHING",
+  "originalConfigurationPath" : "hdfs://HOST_REPLACED:8020/user/USER_REPLACED/.slider/cluster/llap/snapshot",
+  "generatedConfigurationPath" : "hdfs://HOST_REPLACED:8020/user/USER_REPLACED/.slider/cluster/llap/generated",
+  "desiredInstances" : 3,
+  "liveInstances" : 0,
+  "appStartTime" : 1459625802169
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ambari/blob/172eb111/ambari-server/src/test/python/stacks/2.5/HIVE/test_hive_server_int.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/python/stacks/2.5/HIVE/test_hive_server_int.py b/ambari-server/src/test/python/stacks/2.5/HIVE/test_hive_server_int.py
index 845459a..44759a9 100644
--- a/ambari-server/src/test/python/stacks/2.5/HIVE/test_hive_server_int.py
+++ b/ambari-server/src/test/python/stacks/2.5/HIVE/test_hive_server_int.py
@@ -18,13 +18,16 @@ See the License for the specific language governing permissions and
 limitations under the License.
 '''
 
+import json
+import os
+
 from stacks.utils.RMFTestCase import *
 
 from mock.mock import MagicMock, patch
 from resource_management.libraries import functions
 from resource_management.core.logger import Logger
 from resource_management.libraries.script.config_dictionary import UnknownConfiguration
-
+from hive_server_interactive import HiveServerInteractiveDefault
 
 @patch.object(functions, "get_stack_version", new=MagicMock(return_value="2.0.0.0-1234"))
 @patch("resource_management.libraries.functions.check_thrift_port_sasl", new=MagicMock())
@@ -38,6 +41,18 @@ class TestHiveServerInteractive(RMFTestCase):
 
   def setUp(self):
     Logger.logger = MagicMock()
+    self.testDirectory = os.path.dirname(os.path.abspath(__file__))
+    # llap state related tests.
+    self.hsi = HiveServerInteractiveDefault()
+    self.llap_app_name='llap'
+    self.num_times_to_iterate = 3
+    self.wait_time = 1
+
+  def load_json(self, filename):
+    file = os.path.join(self.testDirectory, filename)
+    with open(file, 'rb') as f:
+      data = json.load(f)
+    return data
 
   @patch("resource_management.libraries.functions.copy_tarball.copy_to_hdfs")
   def test_configure_default(self, copy_to_hdfs_mock):
@@ -68,7 +83,8 @@ class TestHiveServerInteractive(RMFTestCase):
                        config_file=self.get_src_folder() + "/test/python/stacks/2.5/configs/hsi_default.json",
                        stack_version=self.STACK_VERSION,
                        target=RMFTestCase.TARGET_COMMON_SERVICES,
-                       checked_call_mocks=[(0, "Prepared llap-slider-05Apr2016/run.sh for running LLAP", ""), (0, "OK.", "")],
+                       checked_call_mocks=[(0, "Prepared llap-slider-05Apr2016/run.sh for running LLAP", ""),
+                                           (0, "{\"state\":\"RUNNING_ALL\"}", ""), (0, "OK.", "")],
     )
 
     self.assert_configure_default()
@@ -294,4 +310,232 @@ class TestHiveServerInteractive(RMFTestCase):
                               group='hadoop',
                               create_parents=True,
                               cd_access='a',
-    )
\ No newline at end of file
+    )
+
+
+
+  # llap app 'status check' related tests
+
+  # Status : RUNNING
+  @patch("time.sleep")
+  @patch('hive_server_interactive.HiveServerInteractiveDefault._get_llap_app_status_info')
+  def test_check_llap_app_status_running_all_wait_negative(self, mock_get_llap_app_status_data, sleep_mock):
+    sleep_mock.return_value = 1
+
+    llap_app_json = self.load_json('running.json')
+    mock_get_llap_app_status_data.return_value = llap_app_json
+
+    status = self.hsi.check_llap_app_status(self.llap_app_name, -1)
+    self.assertEqual(status, True)
+
+  @patch("time.sleep")
+  @patch('hive_server_interactive.HiveServerInteractiveDefault._get_llap_app_status_info')
+  def test_check_llap_app_status_running_all_wait_0(self, mock_get_llap_app_status_data, sleep_mock):
+    sleep_mock.return_value = 1
+
+    llap_app_json = self.load_json('running.json')
+    mock_get_llap_app_status_data.return_value = llap_app_json
+
+    status = self.hsi.check_llap_app_status(self.llap_app_name, 0)
+    self.assertEqual(status, True)
+
+
+  @patch("time.sleep")
+  @patch('hive_server_interactive.HiveServerInteractiveDefault._get_llap_app_status_info')
+  def test_check_llap_app_status_running_all_wait_2(self, mock_get_llap_app_status_data, sleep_mock):
+    sleep_mock.return_value = 1
+
+    llap_app_json = self.load_json('running.json')
+    mock_get_llap_app_status_data.return_value = llap_app_json
+
+    status = self.hsi.check_llap_app_status(self.llap_app_name, 2)
+    self.assertEqual(status, True)
+
+
+
+
+  # Status : RUNNING_PARTIAL (2 out of 3 running -> < 80% instances ON)
+  @patch("time.sleep")
+  @patch('hive_server_interactive.HiveServerInteractiveDefault._get_llap_app_status_info')
+  def test_check_llap_app_status_one_container_down_wait_negative(self, mock_get_llap_app_status_data, sleep_mock):
+    sleep_mock.return_value = 1
+
+    llap_app_json = self.load_json('oneContainerDown.json')
+    mock_get_llap_app_status_data.return_value = llap_app_json
+
+    status = self.hsi.check_llap_app_status(self.llap_app_name, -1)
+    self.assertEqual(status, False)
+
+  @patch("time.sleep")
+  @patch('hive_server_interactive.HiveServerInteractiveDefault._get_llap_app_status_info')
+  def test_check_llap_app_status_one_container_down_wait_0(self, mock_get_llap_app_status_data, sleep_mock):
+    sleep_mock.return_value = 1
+
+    llap_app_json = self.load_json('oneContainerDown.json')
+    mock_get_llap_app_status_data.return_value = llap_app_json
+
+    status = self.hsi.check_llap_app_status(self.llap_app_name, 0)
+    self.assertEqual(status, False)
+
+  @patch("time.sleep")
+  @patch('hive_server_interactive.HiveServerInteractiveDefault._get_llap_app_status_info')
+  def test_check_llap_app_status_one_container_down_wait_2(self, mock_get_llap_app_status_data, sleep_mock):
+    sleep_mock.return_value = 1
+
+    llap_app_json = self.load_json('oneContainerDown.json')
+    mock_get_llap_app_status_data.return_value = llap_app_json
+
+    status = self.hsi.check_llap_app_status(self.llap_app_name, 2)
+    self.assertEqual(status, False)
+
+
+
+
+  # Status : RUNNING_PARTIAL (4 out of 5 running -> > 80% instances ON)
+  @patch("time.sleep")
+  @patch('hive_server_interactive.HiveServerInteractiveDefault._get_llap_app_status_info')
+  def test_check_llap_app_status_two_container_down_1_wait_negative(self, mock_get_llap_app_status_data, sleep_mock):
+    sleep_mock.return_value = 1
+
+    llap_app_json = self.load_json('oneContainerDown1.json')
+    mock_get_llap_app_status_data.return_value = llap_app_json
+
+    status = self.hsi.check_llap_app_status(self.llap_app_name, -1)
+    self.assertEqual(status, True)
+
+  @patch("time.sleep")
+  @patch('hive_server_interactive.HiveServerInteractiveDefault._get_llap_app_status_info')
+  def test_check_llap_app_status_two_container_down_1_wait_0(self, mock_get_llap_app_status_data, sleep_mock):
+    sleep_mock.return_value = 1
+
+    llap_app_json = self.load_json('oneContainerDown1.json')
+    mock_get_llap_app_status_data.return_value = llap_app_json
+
+    status = self.hsi.check_llap_app_status(self.llap_app_name, 0)
+    self.assertEqual(status, True)
+
+
+  @patch("time.sleep")
+  @patch('hive_server_interactive.HiveServerInteractiveDefault._get_llap_app_status_info')
+  def test_check_llap_app_status_two_container_down_1_wait_2(self, mock_get_llap_app_status_data, sleep_mock):
+    sleep_mock.return_value = 1
+
+    llap_app_json = self.load_json('oneContainerDown1.json')
+    mock_get_llap_app_status_data.return_value = llap_app_json
+
+    status = self.hsi.check_llap_app_status(self.llap_app_name, 2)
+    self.assertEqual(status, True)
+
+
+
+
+  # Status : LAUNCHING
+  @patch("time.sleep")
+  @patch('hive_server_interactive.HiveServerInteractiveDefault._get_llap_app_status_info')
+  def test_check_llap_app_status_starting_wait_negative(self, mock_get_llap_app_status_data, sleep_mock):
+    sleep_mock.return_value = 1
+
+    llap_app_json = self.load_json('starting.json')
+    mock_get_llap_app_status_data.return_value = llap_app_json
+
+    status = self.hsi.check_llap_app_status(self.llap_app_name, -1)
+    self.assertEqual(status, True)
+
+  @patch("time.sleep")
+  @patch('hive_server_interactive.HiveServerInteractiveDefault._get_llap_app_status_info')
+  def test_check_llap_app_status_starting_wait_0(self, mock_get_llap_app_status_data, sleep_mock):
+    sleep_mock.return_value = 1
+
+    llap_app_json = self.load_json('starting.json')
+    mock_get_llap_app_status_data.return_value = llap_app_json
+
+    status = self.hsi.check_llap_app_status(self.llap_app_name, 0)
+    self.assertEqual(status, True)
+
+  @patch("time.sleep")
+  @patch('hive_server_interactive.HiveServerInteractiveDefault._get_llap_app_status_info')
+  def test_check_llap_app_status_starting_wait_2(self, mock_get_llap_app_status_data, sleep_mock):
+    sleep_mock.return_value = 1
+
+    llap_app_json = self.load_json('starting.json')
+    mock_get_llap_app_status_data.return_value = llap_app_json
+
+    status = self.hsi.check_llap_app_status(self.llap_app_name, 2)
+    self.assertEqual(status, True)
+
+
+
+
+
+  # Status : COMPLETE
+  @patch("time.sleep")
+  @patch('hive_server_interactive.HiveServerInteractiveDefault._get_llap_app_status_info')
+  def test_check_llap_app_status_complete_wait_negative(self, mock_get_llap_app_status_data, sleep_mock):
+    sleep_mock.return_value = 1
+
+    llap_app_json = self.load_json('appComplete.json')
+    mock_get_llap_app_status_data.return_value = llap_app_json
+
+    status = self.hsi.check_llap_app_status(self.llap_app_name, -1)
+    self.assertEqual(status, False)
+
+  @patch("time.sleep")
+  @patch('hive_server_interactive.HiveServerInteractiveDefault._get_llap_app_status_info')
+  def test_check_llap_app_status_complete_wait_0(self, mock_get_llap_app_status_data, sleep_mock):
+    sleep_mock.return_value = 1
+
+    llap_app_json = self.load_json('appComplete.json')
+    mock_get_llap_app_status_data.return_value = llap_app_json
+
+    status = self.hsi.check_llap_app_status(self.llap_app_name, 0)
+    self.assertEqual(status, False)
+
+  @patch("time.sleep")
+  @patch('hive_server_interactive.HiveServerInteractiveDefault._get_llap_app_status_info')
+  def test_check_llap_app_status_complete_wait_2(self, mock_get_llap_app_status_data, sleep_mock):
+    sleep_mock.return_value = 1
+
+    llap_app_json = self.load_json('appComplete.json')
+    mock_get_llap_app_status_data.return_value = llap_app_json
+
+    status = self.hsi.check_llap_app_status(self.llap_app_name, 2)
+    self.assertEqual(status, False)
+
+
+
+
+  # Status : APP_NOT_FOUND
+  @patch("time.sleep")
+  @patch('hive_server_interactive.HiveServerInteractiveDefault._get_llap_app_status_info')
+  def test_check_llap_app_status_invalid_wait_negative(self, mock_get_llap_app_status_data, sleep_mock):
+    sleep_mock.return_value = 1
+
+    llap_app_json = self.load_json('invalidApp.json')
+    mock_get_llap_app_status_data.return_value = llap_app_json
+
+    status = self.hsi.check_llap_app_status(self.llap_app_name, -1)
+    self.assertEqual(status, False)
+
+
+  @patch("time.sleep")
+  @patch('hive_server_interactive.HiveServerInteractiveDefault._get_llap_app_status_info')
+  def test_check_llap_app_status_invalid_wait_0(self, mock_get_llap_app_status_data, sleep_mock):
+    sleep_mock.return_value = 1
+
+    llap_app_json = self.load_json('invalidApp.json')
+    mock_get_llap_app_status_data.return_value = llap_app_json
+
+    status = self.hsi.check_llap_app_status(self.llap_app_name, 0)
+    self.assertEqual(status, False)
+
+
+  @patch("time.sleep")
+  @patch('hive_server_interactive.HiveServerInteractiveDefault._get_llap_app_status_info')
+  def test_check_llap_app_status_invalid_wait_2(self, mock_get_llap_app_status_data, sleep_mock):
+    sleep_mock.return_value = 1
+
+    llap_app_json = self.load_json('invalidApp.json')
+    mock_get_llap_app_status_data.return_value = llap_app_json
+
+    status = self.hsi.check_llap_app_status(self.llap_app_name, 2)
+    self.assertEqual(status, False)
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ambari/blob/172eb111/ambari-server/src/test/python/stacks/2.5/configs/hsi_default.json
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/python/stacks/2.5/configs/hsi_default.json b/ambari-server/src/test/python/stacks/2.5/configs/hsi_default.json
index d077c35..1cb2a02 100644
--- a/ambari-server/src/test/python/stacks/2.5/configs/hsi_default.json
+++ b/ambari-server/src/test/python/stacks/2.5/configs/hsi_default.json
@@ -395,7 +395,8 @@
           "enable_hive_interactive" : "true",
           "hive_server_interactive_host" : "c6401.ambari.apache.org",
           "llap_queue_capacity" : "0",
-          "num_llap_nodes" : "1"
+          "num_llap_nodes" : "1",
+          "num_retries_for_checking_llap_status" : 2
         },
         "hive-interactive-site": {
             "hive.enforce.sorting": "true",