ambari-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From dmitriu...@apache.org
Subject [1/2] ambari git commit: AMBARI-8298. Distribute Repositories/Install Components - custom action script (dlysnichenko)
Date Tue, 18 Nov 2014 12:24:08 GMT
Repository: ambari
Updated Branches:
  refs/heads/trunk 03b45ee1d -> a518ede5d


http://git-wip-us.apache.org/repos/asf/ambari/blob/a518ede5/ambari-server/src/test/python/TestCheckHost.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/python/TestCheckHost.py b/ambari-server/src/test/python/TestCheckHost.py
deleted file mode 100644
index d68c903..0000000
--- a/ambari-server/src/test/python/TestCheckHost.py
+++ /dev/null
@@ -1,284 +0,0 @@
-# !/usr/bin/env python
-
-'''
-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.
-'''
-
-from stacks.utils.RMFTestCase import *
-import json
-import os
-import socket
-import subprocess
-from ambari_commons import inet_utils
-from resource_management import Script,ConfigDictionary
-from mock.mock import patch
-from mock.mock import MagicMock
-from unittest import TestCase
-
-check_host = __import__('check_host')
-from check_host import CheckHost
-
-class TestCheckHost(TestCase):
-
-  @patch("os.path.isfile")
-  @patch.object(Script, 'get_config')
-  @patch.object(Script, 'get_tmp_dir')
-  @patch("resource_management.libraries.script.Script.put_structured_out")
-  def testJavaHomeAvailableCheck(self, structured_out_mock, get_tmp_dir_mock, mock_config, os_isfile_mock):
-    # test, java home exists
-    os_isfile_mock.return_value = True
-    get_tmp_dir_mock.return_value = "/tmp"
-    mock_config.return_value = {"commandParams" : {"check_execute_list" : "java_home_check",
-                                                   "java_home" : "test_java_home"}}
-
-    checkHost = CheckHost()
-    checkHost.actionexecute(None)
-
-    self.assertEquals(os_isfile_mock.call_args[0][0], 'test_java_home/bin/java')
-    self.assertEquals(structured_out_mock.call_args[0][0], {'java_home_check': {'message': 'Java home exists!',
-                                                                                'exit_code': 0}})
-    # test, java home doesn't exist
-    os_isfile_mock.reset_mock()
-    os_isfile_mock.return_value = False
-
-    checkHost.actionexecute(None)
-
-    self.assertEquals(os_isfile_mock.call_args[0][0], 'test_java_home/bin/java')
-    self.assertEquals(structured_out_mock.call_args[0][0], {'java_home_check': {"message": "Java home doesn't exist!",
-                                                                                "exit_code" : 1}})
-
-
-  @patch.object(Script, 'get_config')
-  @patch.object(Script, 'get_tmp_dir')
-  @patch("check_host.download_file")
-  @patch("resource_management.libraries.script.Script.put_structured_out")
-  @patch("subprocess.Popen")
-  @patch("check_host.format")
-  @patch("os.path.isfile")
-  def testDBConnectionCheck(self, isfile_mock, format_mock, popenMock, structured_out_mock, download_file_mock, get_tmp_dir_mock, mock_config):
-    # test, download DBConnectionVerification.jar failed
-    mock_config.return_value = {"commandParams" : {"check_execute_list" : "db_connection_check",
-                                                   "java_home" : "test_java_home",
-                                                   "ambari_server_host" : "test_host",
-                                                   "jdk_location" : "test_jdk_location",
-                                                   "db_name" : "mysql",
-                                                   "db_connection_url" : "test_db_connection_url",
-                                                   "user_name" : "test_user_name",
-                                                   "user_passwd" : "test_user_passwd",
-                                                   "jdk_name" : "test_jdk_name"},
-                                "hostLevelParams": { "agentCacheDir": "/nonexistent_tmp" }}
-    get_tmp_dir_mock.return_value = "/tmp"
-    download_file_mock.side_effect = Exception("test exception")
-    isfile_mock.return_value = True
-    checkHost = CheckHost()
-    checkHost.actionexecute(None)
-
-    self.assertEquals(structured_out_mock.call_args[0][0], {'db_connection_check': {'message': 'Error downloading ' \
-                     'DBConnectionVerification.jar from Ambari Server resources. Check network access to Ambari ' \
-                     'Server.\ntest exception', 'exit_code': 1}})
-
-    # test, download jdbc driver failed
-    mock_config.return_value = {"commandParams" : {"check_execute_list" : "db_connection_check",
-                                                   "java_home" : "test_java_home",
-                                                   "ambari_server_host" : "test_host",
-                                                   "jdk_location" : "test_jdk_location",
-                                                   "db_name" : "oracle",
-                                                   "db_connection_url" : "test_db_connection_url",
-                                                   "user_name" : "test_user_name",
-                                                   "user_passwd" : "test_user_passwd",
-                                                   "jdk_name" : "test_jdk_name"},
-                                "hostLevelParams": { "agentCacheDir": "/nonexistent_tmp" }}
-    format_mock.reset_mock()
-    download_file_mock.reset_mock()
-    p = MagicMock()
-    download_file_mock.side_effect = [p, Exception("test exception")]
-
-    checkHost.actionexecute(None)
-
-    self.assertEquals(format_mock.call_args[0][0], 'Error: Ambari Server cannot download the database JDBC driver '
-                  'and is unable to test the database connection. You must run ambari-server setup '
-                  '--jdbc-db={db_name} --jdbc-driver=/path/to/your/{db_name}/driver.jar on the Ambari '
-                  'Server host to make the JDBC driver available for download and to enable testing '
-                  'the database connection.\n')
-    self.assertEquals(structured_out_mock.call_args[0][0]['db_connection_check']['exit_code'], 1)
-
-    # test, no connection to remote db
-    mock_config.return_value = {"commandParams" : {"check_execute_list" : "db_connection_check",
-                                                   "java_home" : "test_java_home",
-                                                   "ambari_server_host" : "test_host",
-                                                   "jdk_location" : "test_jdk_location",
-                                                   "db_name" : "postgres",
-                                                   "db_connection_url" : "test_db_connection_url",
-                                                   "user_name" : "test_user_name",
-                                                   "user_passwd" : "test_user_passwd",
-                                                   "jdk_name" : "test_jdk_name"},
-                                "hostLevelParams": { "agentCacheDir": "/nonexistent_tmp" }}
-    format_mock.reset_mock()
-    download_file_mock.reset_mock()
-    download_file_mock.side_effect = [p, p]
-    s = MagicMock()
-    s.communicate.return_value = ("test message", "")
-    s.returncode = 1
-    popenMock.return_value = s
-
-    checkHost.actionexecute(None)
-
-    self.assertEquals(structured_out_mock.call_args[0][0], {'db_connection_check': {'message': 'test message',
-                                                                                    'exit_code': 1}})
-    self.assertEquals(format_mock.call_args[0][0],'{java_exec} -cp '\
-            '{check_db_connection_path}{class_path_delimiter}{jdbc_path} -Djava.library.path={agent_cache_dir} '\
-            'org.apache.ambari.server.DBConnectionVerification {db_connection_url} '\
-            '{user_name} {user_passwd!p} {jdbc_driver}')
-
-    # test, db connection success
-    download_file_mock.reset_mock()
-    download_file_mock.side_effect = [p, p]
-    s.returncode = 0
-
-    checkHost.actionexecute(None)
-
-    self.assertEquals(structured_out_mock.call_args[0][0], {'db_connection_check':
-                                        {'message': 'DB connection check completed successfully!', 'exit_code': 0}})
-
-    #test jdk_name and java home are not available
-    mock_config.return_value = {"commandParams" : {"check_execute_list" : "db_connection_check",
-                                                   "java_home" : "test_java_home",
-                                                   "ambari_server_host" : "test_host",
-                                                   "jdk_location" : "test_jdk_location",
-                                                   "db_connection_url" : "test_db_connection_url",
-                                                   "user_name" : "test_user_name",
-                                                   "user_passwd" : "test_user_passwd",
-                                                   "db_name" : "postgres"},
-                                "hostLevelParams": { "agentCacheDir": "/nonexistent_tmp" }}
-
-    isfile_mock.return_value = False
-    checkHost.actionexecute(None)
-    self.assertEquals(structured_out_mock.call_args[0][0], {'db_connection_check': {'message': 'Custom java is not ' \
-            'available on host. Please install it. Java home should be the same as on server. \n', 'exit_code': 1}})
-
-
-
-  @patch("socket.gethostbyname")
-  @patch.object(Script, 'get_config')
-  @patch.object(Script, 'get_tmp_dir')
-  @patch("resource_management.libraries.script.Script.put_structured_out")
-  def testHostResolution(self, structured_out_mock, get_tmp_dir_mock, mock_config, mock_socket):
-    mock_socket.return_value = "192.168.1.1"    
-    jsonFilePath = os.path.join("../resources/custom_actions", "check_host_ip_addresses.json")
-    
-    with open(jsonFilePath, "r") as jsonFile:
-      jsonPayload = json.load(jsonFile)
- 
-    mock_config.return_value = ConfigDictionary(jsonPayload)
-    get_tmp_dir_mock.return_value = "/tmp"
-
-    checkHost = CheckHost()
-    checkHost.actionexecute(None)
-    
-    # ensure the correct function was called
-    self.assertTrue(structured_out_mock.called)
-    structured_out_mock.assert_called_with({'host_resolution_check': 
-      {'failures': [], 
-       'message': 'All hosts resolved to an IP address.', 
-       'failed_count': 0, 
-       'success_count': 5, 
-       'exit_code': 0}})
-    
-    # try it now with errors
-    mock_socket.side_effect = socket.error
-    checkHost.actionexecute(None)
-    
-    structured_out_mock.assert_called_with({'host_resolution_check': 
-      {'failures': [
-                    {'cause': (), 'host': u'c6401.ambari.apache.org', 'type': 'FORWARD_LOOKUP'}, 
-                    {'cause': (), 'host': u'c6402.ambari.apache.org', 'type': 'FORWARD_LOOKUP'}, 
-                    {'cause': (), 'host': u'c6403.ambari.apache.org', 'type': 'FORWARD_LOOKUP'}, 
-                    {'cause': (), 'host': u'foobar', 'type': 'FORWARD_LOOKUP'}, 
-                    {'cause': (), 'host': u'!!!', 'type': 'FORWARD_LOOKUP'}], 
-       'message': 'There were 5 host(s) that could not resolve to an IP address.', 
-       'failed_count': 5, 'success_count': 0, 'exit_code': 0}})
-    
-  @patch.object(Script, 'get_config')
-  @patch.object(Script, 'get_tmp_dir')
-  @patch("resource_management.libraries.script.Script.put_structured_out")
-  def testInvalidCheck(self, structured_out_mock, get_tmp_dir_mock, mock_config):
-    jsonFilePath = os.path.join("../resources/custom_actions", "invalid_check.json")
-    
-    with open(jsonFilePath, "r") as jsonFile:
-      jsonPayload = json.load(jsonFile)
- 
-    mock_config.return_value = ConfigDictionary(jsonPayload)
-    get_tmp_dir_mock.return_value = "tmp"
-
-    checkHost = CheckHost()
-    checkHost.actionexecute(None)
-    
-    # ensure the correct function was called
-    self.assertTrue(structured_out_mock.called)
-    structured_out_mock.assert_called_with({})
-
-  @patch.object(Script, 'get_config')
-  @patch.object(Script, 'get_tmp_dir')
-  @patch('resource_management.libraries.script.Script.put_structured_out')
-  @patch('ambari_agent.HostInfo.HostInfo.javaProcs')
-  @patch('ambari_agent.HostInfo.HostInfo.checkLiveServices')
-  @patch('ambari_agent.HostInfo.HostInfo.getUMask')
-  @patch('ambari_agent.HostInfo.HostInfo.getTransparentHugePage')
-  @patch('ambari_agent.HostInfo.HostInfo.checkIptables')
-  @patch('ambari_agent.HostInfo.HostInfo.checkReverseLookup')
-  @patch('time.time')
-  def testLastAgentEnv(self, time_mock, checkReverseLookup_mock, checkIptables_mock, getTransparentHugePage_mock,
-                       getUMask_mock, checkLiveServices_mock, javaProcs_mock, put_structured_out_mock,
-                       get_tmp_dir_mock, get_config_mock):
-    jsonFilePath = os.path.join("../resources/custom_actions", "check_last_agent_env.json")
-    with open(jsonFilePath, "r") as jsonFile:
-      jsonPayload = json.load(jsonFile)
-
-    get_config_mock.return_value = ConfigDictionary(jsonPayload)
-    get_tmp_dir_mock.return_value = "/tmp"
-
-    checkHost = CheckHost()
-    checkHost.actionexecute(None)
-
-    # ensure the correct function was called
-    self.assertTrue(time_mock.called)
-    self.assertTrue(checkReverseLookup_mock.called)
-    self.assertTrue(checkIptables_mock.called)
-    self.assertTrue(getTransparentHugePage_mock.called)
-    self.assertTrue(getUMask_mock.called)
-    self.assertTrue(checkLiveServices_mock.called)
-    self.assertTrue(javaProcs_mock.called)
-    self.assertTrue(put_structured_out_mock.called)
-    # ensure the correct keys are in the result map
-    last_agent_env_check_result = put_structured_out_mock.call_args[0][0]
-    self.assertTrue('last_agent_env_check' in last_agent_env_check_result)
-    self.assertTrue('hostHealth' in last_agent_env_check_result['last_agent_env_check'])
-    self.assertTrue('iptablesIsRunning' in last_agent_env_check_result['last_agent_env_check'])
-    self.assertTrue('reverseLookup' in last_agent_env_check_result['last_agent_env_check'])
-    self.assertTrue('alternatives' in last_agent_env_check_result['last_agent_env_check'])
-    self.assertTrue('umask' in last_agent_env_check_result['last_agent_env_check'])
-    self.assertTrue('stackFoldersAndFiles' in last_agent_env_check_result['last_agent_env_check'])
-    self.assertTrue('existingRepos' in last_agent_env_check_result['last_agent_env_check'])
-    self.assertTrue('installedPackages' in last_agent_env_check_result['last_agent_env_check'])
-    self.assertTrue('existingUsers' in last_agent_env_check_result['last_agent_env_check'])
-
-    # try it now with errors
-    javaProcs_mock.side_effect = Exception("test exception")
-    checkHost.actionexecute(None)
-
-    #ensure the correct response is returned
-    put_structured_out_mock.assert_called_with({'last_agent_env_check': {'message': 'test exception', 'exit_code': 1}})
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ambari/blob/a518ede5/ambari-server/src/test/python/custom_actions/TestCheckHost.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/python/custom_actions/TestCheckHost.py b/ambari-server/src/test/python/custom_actions/TestCheckHost.py
new file mode 100644
index 0000000..d1aeb16
--- /dev/null
+++ b/ambari-server/src/test/python/custom_actions/TestCheckHost.py
@@ -0,0 +1,283 @@
+# !/usr/bin/env python
+
+'''
+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.
+'''
+
+from stacks.utils.RMFTestCase import *
+import json
+import os
+import socket
+import subprocess
+from ambari_commons import inet_utils
+from resource_management import Script,ConfigDictionary
+from mock.mock import patch
+from mock.mock import MagicMock
+from unittest import TestCase
+
+from check_host import CheckHost
+
+class TestCheckHost(TestCase):
+
+  @patch("os.path.isfile")
+  @patch.object(Script, 'get_config')
+  @patch.object(Script, 'get_tmp_dir')
+  @patch("resource_management.libraries.script.Script.put_structured_out")
+  def testJavaHomeAvailableCheck(self, structured_out_mock, get_tmp_dir_mock, mock_config, os_isfile_mock):
+    # test, java home exists
+    os_isfile_mock.return_value = True
+    get_tmp_dir_mock.return_value = "/tmp"
+    mock_config.return_value = {"commandParams" : {"check_execute_list" : "java_home_check",
+                                                   "java_home" : "test_java_home"}}
+
+    checkHost = CheckHost()
+    checkHost.actionexecute(None)
+
+    self.assertEquals(os_isfile_mock.call_args[0][0], 'test_java_home/bin/java')
+    self.assertEquals(structured_out_mock.call_args[0][0], {'java_home_check': {'message': 'Java home exists!',
+                                                                                'exit_code': 0}})
+    # test, java home doesn't exist
+    os_isfile_mock.reset_mock()
+    os_isfile_mock.return_value = False
+
+    checkHost.actionexecute(None)
+
+    self.assertEquals(os_isfile_mock.call_args[0][0], 'test_java_home/bin/java')
+    self.assertEquals(structured_out_mock.call_args[0][0], {'java_home_check': {"message": "Java home doesn't exist!",
+                                                                                "exit_code" : 1}})
+
+
+  @patch.object(Script, 'get_config')
+  @patch.object(Script, 'get_tmp_dir')
+  @patch("check_host.download_file")
+  @patch("resource_management.libraries.script.Script.put_structured_out")
+  @patch("subprocess.Popen")
+  @patch("check_host.format")
+  @patch("os.path.isfile")
+  def testDBConnectionCheck(self, isfile_mock, format_mock, popenMock, structured_out_mock, download_file_mock, get_tmp_dir_mock, mock_config):
+    # test, download DBConnectionVerification.jar failed
+    mock_config.return_value = {"commandParams" : {"check_execute_list" : "db_connection_check",
+                                                   "java_home" : "test_java_home",
+                                                   "ambari_server_host" : "test_host",
+                                                   "jdk_location" : "test_jdk_location",
+                                                   "db_name" : "mysql",
+                                                   "db_connection_url" : "test_db_connection_url",
+                                                   "user_name" : "test_user_name",
+                                                   "user_passwd" : "test_user_passwd",
+                                                   "jdk_name" : "test_jdk_name"},
+                                "hostLevelParams": { "agentCacheDir": "/nonexistent_tmp" }}
+    get_tmp_dir_mock.return_value = "/tmp"
+    download_file_mock.side_effect = Exception("test exception")
+    isfile_mock.return_value = True
+    checkHost = CheckHost()
+    checkHost.actionexecute(None)
+
+    self.assertEquals(structured_out_mock.call_args[0][0], {'db_connection_check': {'message': 'Error downloading ' \
+                     'DBConnectionVerification.jar from Ambari Server resources. Check network access to Ambari ' \
+                     'Server.\ntest exception', 'exit_code': 1}})
+
+    # test, download jdbc driver failed
+    mock_config.return_value = {"commandParams" : {"check_execute_list" : "db_connection_check",
+                                                   "java_home" : "test_java_home",
+                                                   "ambari_server_host" : "test_host",
+                                                   "jdk_location" : "test_jdk_location",
+                                                   "db_name" : "oracle",
+                                                   "db_connection_url" : "test_db_connection_url",
+                                                   "user_name" : "test_user_name",
+                                                   "user_passwd" : "test_user_passwd",
+                                                   "jdk_name" : "test_jdk_name"},
+                                "hostLevelParams": { "agentCacheDir": "/nonexistent_tmp" }}
+    format_mock.reset_mock()
+    download_file_mock.reset_mock()
+    p = MagicMock()
+    download_file_mock.side_effect = [p, Exception("test exception")]
+
+    checkHost.actionexecute(None)
+
+    self.assertEquals(format_mock.call_args[0][0], 'Error: Ambari Server cannot download the database JDBC driver '
+                  'and is unable to test the database connection. You must run ambari-server setup '
+                  '--jdbc-db={db_name} --jdbc-driver=/path/to/your/{db_name}/driver.jar on the Ambari '
+                  'Server host to make the JDBC driver available for download and to enable testing '
+                  'the database connection.\n')
+    self.assertEquals(structured_out_mock.call_args[0][0]['db_connection_check']['exit_code'], 1)
+
+    # test, no connection to remote db
+    mock_config.return_value = {"commandParams" : {"check_execute_list" : "db_connection_check",
+                                                   "java_home" : "test_java_home",
+                                                   "ambari_server_host" : "test_host",
+                                                   "jdk_location" : "test_jdk_location",
+                                                   "db_name" : "postgres",
+                                                   "db_connection_url" : "test_db_connection_url",
+                                                   "user_name" : "test_user_name",
+                                                   "user_passwd" : "test_user_passwd",
+                                                   "jdk_name" : "test_jdk_name"},
+                                "hostLevelParams": { "agentCacheDir": "/nonexistent_tmp" }}
+    format_mock.reset_mock()
+    download_file_mock.reset_mock()
+    download_file_mock.side_effect = [p, p]
+    s = MagicMock()
+    s.communicate.return_value = ("test message", "")
+    s.returncode = 1
+    popenMock.return_value = s
+
+    checkHost.actionexecute(None)
+
+    self.assertEquals(structured_out_mock.call_args[0][0], {'db_connection_check': {'message': 'test message',
+                                                                                    'exit_code': 1}})
+    self.assertEquals(format_mock.call_args[0][0],'{java_exec} -cp '\
+            '{check_db_connection_path}{class_path_delimiter}{jdbc_path} -Djava.library.path={agent_cache_dir} '\
+            'org.apache.ambari.server.DBConnectionVerification {db_connection_url} '\
+            '{user_name} {user_passwd!p} {jdbc_driver}')
+
+    # test, db connection success
+    download_file_mock.reset_mock()
+    download_file_mock.side_effect = [p, p]
+    s.returncode = 0
+
+    checkHost.actionexecute(None)
+
+    self.assertEquals(structured_out_mock.call_args[0][0], {'db_connection_check':
+                                        {'message': 'DB connection check completed successfully!', 'exit_code': 0}})
+
+    #test jdk_name and java home are not available
+    mock_config.return_value = {"commandParams" : {"check_execute_list" : "db_connection_check",
+                                                   "java_home" : "test_java_home",
+                                                   "ambari_server_host" : "test_host",
+                                                   "jdk_location" : "test_jdk_location",
+                                                   "db_connection_url" : "test_db_connection_url",
+                                                   "user_name" : "test_user_name",
+                                                   "user_passwd" : "test_user_passwd",
+                                                   "db_name" : "postgres"},
+                                "hostLevelParams": { "agentCacheDir": "/nonexistent_tmp" }}
+
+    isfile_mock.return_value = False
+    checkHost.actionexecute(None)
+    self.assertEquals(structured_out_mock.call_args[0][0], {'db_connection_check': {'message': 'Custom java is not ' \
+            'available on host. Please install it. Java home should be the same as on server. \n', 'exit_code': 1}})
+
+
+
+  @patch("socket.gethostbyname")
+  @patch.object(Script, 'get_config')
+  @patch.object(Script, 'get_tmp_dir')
+  @patch("resource_management.libraries.script.Script.put_structured_out")
+  def testHostResolution(self, structured_out_mock, get_tmp_dir_mock, mock_config, mock_socket):
+    mock_socket.return_value = "192.168.1.1"    
+    jsonFilePath = os.path.join("../resources/custom_actions", "check_host_ip_addresses.json")
+    
+    with open(jsonFilePath, "r") as jsonFile:
+      jsonPayload = json.load(jsonFile)
+ 
+    mock_config.return_value = ConfigDictionary(jsonPayload)
+    get_tmp_dir_mock.return_value = "/tmp"
+
+    checkHost = CheckHost()
+    checkHost.actionexecute(None)
+    
+    # ensure the correct function was called
+    self.assertTrue(structured_out_mock.called)
+    structured_out_mock.assert_called_with({'host_resolution_check': 
+      {'failures': [], 
+       'message': 'All hosts resolved to an IP address.', 
+       'failed_count': 0, 
+       'success_count': 5, 
+       'exit_code': 0}})
+    
+    # try it now with errors
+    mock_socket.side_effect = socket.error
+    checkHost.actionexecute(None)
+    
+    structured_out_mock.assert_called_with({'host_resolution_check': 
+      {'failures': [
+                    {'cause': (), 'host': u'c6401.ambari.apache.org', 'type': 'FORWARD_LOOKUP'}, 
+                    {'cause': (), 'host': u'c6402.ambari.apache.org', 'type': 'FORWARD_LOOKUP'}, 
+                    {'cause': (), 'host': u'c6403.ambari.apache.org', 'type': 'FORWARD_LOOKUP'}, 
+                    {'cause': (), 'host': u'foobar', 'type': 'FORWARD_LOOKUP'}, 
+                    {'cause': (), 'host': u'!!!', 'type': 'FORWARD_LOOKUP'}], 
+       'message': 'There were 5 host(s) that could not resolve to an IP address.', 
+       'failed_count': 5, 'success_count': 0, 'exit_code': 0}})
+    
+  @patch.object(Script, 'get_config')
+  @patch.object(Script, 'get_tmp_dir')
+  @patch("resource_management.libraries.script.Script.put_structured_out")
+  def testInvalidCheck(self, structured_out_mock, get_tmp_dir_mock, mock_config):
+    jsonFilePath = os.path.join("../resources/custom_actions", "invalid_check.json")
+    
+    with open(jsonFilePath, "r") as jsonFile:
+      jsonPayload = json.load(jsonFile)
+ 
+    mock_config.return_value = ConfigDictionary(jsonPayload)
+    get_tmp_dir_mock.return_value = "tmp"
+
+    checkHost = CheckHost()
+    checkHost.actionexecute(None)
+    
+    # ensure the correct function was called
+    self.assertTrue(structured_out_mock.called)
+    structured_out_mock.assert_called_with({})
+
+  @patch.object(Script, 'get_config')
+  @patch.object(Script, 'get_tmp_dir')
+  @patch('resource_management.libraries.script.Script.put_structured_out')
+  @patch('ambari_agent.HostInfo.HostInfo.javaProcs')
+  @patch('ambari_agent.HostInfo.HostInfo.checkLiveServices')
+  @patch('ambari_agent.HostInfo.HostInfo.getUMask')
+  @patch('ambari_agent.HostInfo.HostInfo.getTransparentHugePage')
+  @patch('ambari_agent.HostInfo.HostInfo.checkIptables')
+  @patch('ambari_agent.HostInfo.HostInfo.checkReverseLookup')
+  @patch('time.time')
+  def testLastAgentEnv(self, time_mock, checkReverseLookup_mock, checkIptables_mock, getTransparentHugePage_mock,
+                       getUMask_mock, checkLiveServices_mock, javaProcs_mock, put_structured_out_mock,
+                       get_tmp_dir_mock, get_config_mock):
+    jsonFilePath = os.path.join("../resources/custom_actions", "check_last_agent_env.json")
+    with open(jsonFilePath, "r") as jsonFile:
+      jsonPayload = json.load(jsonFile)
+
+    get_config_mock.return_value = ConfigDictionary(jsonPayload)
+    get_tmp_dir_mock.return_value = "/tmp"
+
+    checkHost = CheckHost()
+    checkHost.actionexecute(None)
+
+    # ensure the correct function was called
+    self.assertTrue(time_mock.called)
+    self.assertTrue(checkReverseLookup_mock.called)
+    self.assertTrue(checkIptables_mock.called)
+    self.assertTrue(getTransparentHugePage_mock.called)
+    self.assertTrue(getUMask_mock.called)
+    self.assertTrue(checkLiveServices_mock.called)
+    self.assertTrue(javaProcs_mock.called)
+    self.assertTrue(put_structured_out_mock.called)
+    # ensure the correct keys are in the result map
+    last_agent_env_check_result = put_structured_out_mock.call_args[0][0]
+    self.assertTrue('last_agent_env_check' in last_agent_env_check_result)
+    self.assertTrue('hostHealth' in last_agent_env_check_result['last_agent_env_check'])
+    self.assertTrue('iptablesIsRunning' in last_agent_env_check_result['last_agent_env_check'])
+    self.assertTrue('reverseLookup' in last_agent_env_check_result['last_agent_env_check'])
+    self.assertTrue('alternatives' in last_agent_env_check_result['last_agent_env_check'])
+    self.assertTrue('umask' in last_agent_env_check_result['last_agent_env_check'])
+    self.assertTrue('stackFoldersAndFiles' in last_agent_env_check_result['last_agent_env_check'])
+    self.assertTrue('existingRepos' in last_agent_env_check_result['last_agent_env_check'])
+    self.assertTrue('installedPackages' in last_agent_env_check_result['last_agent_env_check'])
+    self.assertTrue('existingUsers' in last_agent_env_check_result['last_agent_env_check'])
+
+    # try it now with errors
+    javaProcs_mock.side_effect = Exception("test exception")
+    checkHost.actionexecute(None)
+
+    #ensure the correct response is returned
+    put_structured_out_mock.assert_called_with({'last_agent_env_check': {'message': 'test exception', 'exit_code': 1}})
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ambari/blob/a518ede5/ambari-server/src/test/python/custom_actions/TestInstallPackages.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/python/custom_actions/TestInstallPackages.py b/ambari-server/src/test/python/custom_actions/TestInstallPackages.py
new file mode 100644
index 0000000..51fc9e1
--- /dev/null
+++ b/ambari-server/src/test/python/custom_actions/TestInstallPackages.py
@@ -0,0 +1,104 @@
+#!/usr/bin/env python
+
+'''
+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.
+'''
+import json
+import os
+import socket
+from resource_management import Script,ConfigDictionary
+from mock.mock import patch
+from mock.mock import MagicMock
+from stacks.utils.RMFTestCase import *
+from install_packages import InstallPackages
+from mock.mock import patch, MagicMock
+
+
+class TestInstallPackages(RMFTestCase):
+
+  @patch("resource_management.libraries.script.Script.put_structured_out")
+  def test_normal_flow(self, put_structured_out):
+    self.executeScript("scripts/install_packages.py",
+                       classname="InstallPackages",
+                       command="actionexecute",
+                       config_file="install_packages_config.json",
+                       target=RMFTestCase.TARGET_CUSTOM_ACTIONS,
+                       os_type=('Suse', '11', 'Final'),
+    )
+    self.assertTrue(put_structured_out.called)
+    self.assertEquals(put_structured_out.call_args[0][0],
+                      {'package_installation_result': 'SUCCESS',
+                       'ambari_repositories': []})
+    self.assertResourceCalled('Repository', 'HDP-2.2.0.0-885',
+                              base_url=u'http://host1/hdp',
+                              action=['create'],
+                              components=[u'HDP-2.2.0.0-885', 'main'],
+                              repo_template='repo_suse_rhel.j2',
+                              repo_file_name=u'HDP-2.2.0.0-885',
+                              mirror_list=None,
+    )
+    self.assertResourceCalled('Repository', 'HDP-UTILS-1.0.0.20',
+                              base_url=u'http://host1/hdp-utils',
+                              action=['create'],
+                              components=[u'HDP-UTILS-1.0.0.20', 'main'],
+                              repo_template='repo_suse_rhel.j2',
+                              repo_file_name=u'HDP-UTILS-1.0.0.20',
+                              mirror_list=None,
+    )
+    self.assertResourceCalled('Package', 'python-rrdtool-1.4.5', )
+    self.assertResourceCalled('Package', 'libganglia-3.5.0-99', )
+    self.assertResourceCalled('Package', 'ganglia-*', )
+    self.assertNoMoreResources()
+
+
+  @patch("resource_management.libraries.functions.list_ambari_managed_repos.list_ambari_managed_repos",
+         new=MagicMock(return_value=["HDP-UTILS-1.0.0.20"]))
+  @patch("resource_management.libraries.script.Script.put_structured_out")
+  def test_exclude_existing_repo(self, put_structured_out):
+    self.executeScript("scripts/install_packages.py",
+                       classname="InstallPackages",
+                       command="actionexecute",
+                       config_file="install_packages_config.json",
+                       target=RMFTestCase.TARGET_CUSTOM_ACTIONS,
+                       os_type=('Suse', '11', 'Final'),
+    )
+    self.assertTrue(put_structured_out.called)
+    self.assertEquals(put_structured_out.call_args[0][0],
+                      {'package_installation_result': 'SUCCESS',
+                       'ambari_repositories': ["HDP-UTILS-1.0.0.20"]})
+    self.assertResourceCalled('Repository', 'HDP-2.2.0.0-885',
+                              base_url=u'http://host1/hdp',
+                              action=['create'],
+                              components=[u'HDP-2.2.0.0-885', 'main'],
+                              repo_template='repo_suse_rhel.j2',
+                              repo_file_name=u'HDP-2.2.0.0-885',
+                              mirror_list=None,
+    )
+    self.assertResourceCalled('Repository', 'HDP-UTILS-1.0.0.20',
+                              base_url=u'http://host1/hdp-utils',
+                              action=['create'],
+                              components=[u'HDP-UTILS-1.0.0.20', 'main'],
+                              repo_template='repo_suse_rhel.j2',
+                              repo_file_name=u'HDP-UTILS-1.0.0.20',
+                              mirror_list=None,
+    )
+    self.assertResourceCalled('Package', 'python-rrdtool-1.4.5', )
+    self.assertResourceCalled('Package', 'libganglia-3.5.0-99', )
+    self.assertResourceCalled('Package', 'ganglia-*', )
+    self.assertNoMoreResources()
+
+

http://git-wip-us.apache.org/repos/asf/ambari/blob/a518ede5/ambari-server/src/test/python/custom_actions/configs/install_packages_config.json
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/python/custom_actions/configs/install_packages_config.json b/ambari-server/src/test/python/custom_actions/configs/install_packages_config.json
new file mode 100644
index 0000000..1055a40
--- /dev/null
+++ b/ambari-server/src/test/python/custom_actions/configs/install_packages_config.json
@@ -0,0 +1,77 @@
+{
+    "configuration_attributes": {}, 
+    "roleCommand": "ACTIONEXECUTE", 
+    "clusterName": "cc", 
+    "hostname": "0b3.vm", 
+    "passiveInfo": [], 
+    "hostLevelParams": {
+        "jdk_location": "http://0b3.vm:8080/resources/", 
+        "ambari_db_rca_password": "mapred", 
+        "java_home": "/usr/jdk64/jdk1.7.0_67", 
+        "ambari_db_rca_url": "jdbc:postgresql://0b3.vm/ambarirca", 
+        "jce_name": "UnlimitedJCEPolicyJDK7.zip", 
+        "oracle_jdbc_url": "http://0b3.vm:8080/resources//ojdbc6.jar", 
+        "stack_version": "2.1", 
+        "stack_name": "HDP", 
+        "db_name": "ambari", 
+        "ambari_db_rca_driver": "org.postgresql.Driver", 
+        "jdk_name": "jdk-7u67-linux-x64.tar.gz", 
+        "ambari_db_rca_username": "mapred", 
+        "db_driver_filename": "mysql-connector-java.jar", 
+        "mysql_jdbc_url": "http://0b3.vm:8080/resources//mysql-connector-java.jar"
+    }, 
+    "commandType": "EXECUTION_COMMAND", 
+    "roleParams": {
+        "base_urls": "[{\"id\": \"HDP-2.2.0.0-885\", \"type\": \"HDP\",\"baseurl\": \"http://host1/hdp\"}, {\"id\": \"HDP-UTILS-1.0.0.20\", \"type\": \"HDP-UTILS\", \"baseurl\": \"http://host1/hdp-utils\"}]", 
+        "package_list": "[\"python-rrdtool-1.4.5\", \"libganglia-3.5.0-99\", \"ganglia-*\"]"
+    }, 
+    "serviceName": "null", 
+    "role": "install_packages", 
+    "forceRefreshConfigTags": [], 
+    "taskId": 61, 
+    "public_hostname": "0b3.vm", 
+    "configurations": {}, 
+    "commandParams": {
+        "command_timeout": "60", 
+        "script_type": "PYTHON", 
+        "base_urls": "[{\"id\": \"HDP-2.2.0.0-885\", \"type\": \"HDP\",\"baseurl\": \"http://host1/hdp\"}, {\"id\": \"HDP-UTILS-1.0.0.20\", \"type\": \"HDP-UTILS\", \"baseurl\": \"http://host1/hdp-utils\"}]", 
+        "package_list": "[\"python-rrdtool-1.4.5\", \"libganglia-3.5.0-99\", \"ganglia-*\"]", 
+        "script": "install_packages.py"
+    }, 
+    "commandId": "14-1", 
+    "clusterHostInfo": {
+        "snamenode_host": [
+            "0b3.vm"
+        ], 
+        "nm_hosts": [
+            "0b3.vm"
+        ], 
+        "app_timeline_server_hosts": [
+            "0b3.vm"
+        ], 
+        "all_ping_ports": [
+            "8670"
+        ], 
+        "rm_host": [
+            "0b3.vm"
+        ], 
+        "all_hosts": [
+            "0b3.vm"
+        ], 
+        "slave_hosts": [
+            "0b3.vm"
+        ], 
+        "namenode_host": [
+            "0b3.vm"
+        ], 
+        "ambari_server_host": [
+            "0b3.vm"
+        ], 
+        "zookeeper_hosts": [
+            "0b3.vm"
+        ], 
+        "hs_host": [
+            "0b3.vm"
+        ]
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ambari/blob/a518ede5/ambari-server/src/test/python/stacks/utils/RMFTestCase.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/python/stacks/utils/RMFTestCase.py b/ambari-server/src/test/python/stacks/utils/RMFTestCase.py
index 10865fe..70b6e6e 100644
--- a/ambari-server/src/test/python/stacks/utils/RMFTestCase.py
+++ b/ambari-server/src/test/python/stacks/utils/RMFTestCase.py
@@ -34,24 +34,41 @@ with patch("platform.linux_distribution", return_value = ('Suse','11','Final')):
   from resource_management.libraries.script.script import Script
   from resource_management.libraries.script.config_dictionary import UnknownConfiguration
 
+PATH_TO_STACKS = "main/resources/stacks/HDP"
+PATH_TO_STACK_TESTS = "test/python/stacks/"
+
+PATH_TO_CUSTOM_ACTIONS = "main/resources/custom_actions"
+PATH_TO_CUSTOM_ACTION_TESTS = "test/python/custom_actions"
 
-PATH_TO_STACKS = os.path.normpath("main/resources/stacks/HDP")
-PATH_TO_STACK_TESTS = os.path.normpath("test/python/stacks/")
 
 class RMFTestCase(TestCase):
+
+  # (default) build all paths to test stack scripts
+  TARGET_STACKS = 'TARGET_STACKS'
+
+  # (default) build all paths to test custom action scripts
+  TARGET_CUSTOM_ACTIONS = 'TARGET_CUSTOM_ACTIONS'
+
   def executeScript(self, path, classname=None, command=None, config_file=None,
                     config_dict=None,
                     # common mocks for all the scripts
                     config_overrides = None,
                     shell_mock_value = (0, "OK."), 
                     os_type=('Suse','11','Final'),
-                    kinit_path_local="/usr/bin/kinit"
+                    kinit_path_local="/usr/bin/kinit",
+                    target=TARGET_STACKS
                     ):
     norm_path = os.path.normpath(path)
     src_dir = RMFTestCase._getSrcFolder()
-    stack_version = norm_path.split(os.sep)[0]
-    stacks_path = os.path.join(src_dir, PATH_TO_STACKS)
-    configs_path = os.path.join(src_dir, PATH_TO_STACK_TESTS, stack_version, "configs")
+    if target == self.TARGET_STACKS:
+      stack_version = norm_path.split(os.sep)[0]
+      stacks_path = os.path.join(src_dir, PATH_TO_STACKS)
+      configs_path = os.path.join(src_dir, PATH_TO_STACK_TESTS, stack_version, "configs")
+    elif target == self.TARGET_CUSTOM_ACTIONS:
+      stacks_path = os.path.join(src_dir, PATH_TO_CUSTOM_ACTIONS)
+      configs_path = os.path.join(src_dir, PATH_TO_CUSTOM_ACTION_TESTS, "configs")
+    else:
+      raise RuntimeError("Wrong target value %s", target)
     script_path = os.path.join(stacks_path, norm_path)
     if config_file is not None and config_dict is None:
       config_file_path = os.path.join(configs_path, config_file)
@@ -80,8 +97,8 @@ class RMFTestCase(TestCase):
     try:
       with patch.object(platform, 'linux_distribution', return_value=os_type):
         script_module = imp.load_source(classname, script_path)
-    except IOError:
-      raise RuntimeError("Cannot load class %s from %s",classname, norm_path)
+    except IOError, err:
+      raise RuntimeError("Cannot load class %s from %s: %s" % (classname, norm_path, err.message))
     
     script_class_inst = RMFTestCase._get_attr(script_module, classname)()
     method = RMFTestCase._get_attr(script_class_inst, command)

http://git-wip-us.apache.org/repos/asf/ambari/blob/a518ede5/ambari-server/src/test/python/unitTests.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/python/unitTests.py b/ambari-server/src/test/python/unitTests.py
index f2ffacb..85591cf 100644
--- a/ambari-server/src/test/python/unitTests.py
+++ b/ambari-server/src/test/python/unitTests.py
@@ -30,6 +30,7 @@ SERVICE_EXCLUDE = ["configs"]
 
 TEST_MASK = '[Tt]est*.py'
 CUSTOM_TEST_MASK = '_[Tt]est*.py'
+
 def get_parent_path(base, directory_name):
   """
   Returns absolute path for directory_name, if directory_name present in base.
@@ -43,7 +44,8 @@ def get_parent_path(base, directory_name):
     done = True if os.path.split(base)[-1] == directory_name else False
   return base
 
-def get_test_files(path, mask = None, recursive=True):
+
+def get_test_files(path, mask=None, recursive=True):
   """
   Returns test files for path recursively
   """
@@ -52,13 +54,14 @@ def get_test_files(path, mask = None, recursive=True):
 
   for item in directory_items:
     add_to_pythonpath = False
-    if os.path.isfile(path + "/" + item):
+    p = os.path.join(path, item)
+    if os.path.isfile(p):
       if fnmatch.fnmatch(item, mask):
         add_to_pythonpath = True
         current.append(item)
-    elif os.path.isdir(path + "/" + item):
+    elif os.path.isdir(p):
       if recursive:
-        current.extend(get_test_files(path + "/" + item, mask = mask))
+        current.extend(get_test_files(p, mask = mask))
     if add_to_pythonpath:
       sys.path.append(path)
   return current
@@ -102,10 +105,12 @@ def stack_test_executor(base_folder, service, stack, custom_tests, executor_resu
   sys.stdout.flush()
   sys.stderr.flush()
   exit_code = 0 if textRunner.wasSuccessful() else 1
-  executor_result.put({'exit_code':exit_code,
-                  'tests_run':textRunner.testsRun,
-                  'errors':[(str(item[0]),str(item[1]),"ERROR") for item in textRunner.errors],
-                  'failures':[(str(item[0]),str(item[1]),"FAIL") for item in textRunner.failures]})
+  executor_result.put({'exit_code': exit_code,
+                       'tests_run': textRunner.testsRun,
+                       'errors': [(str(item[0]), str(item[1]), "ERROR") for item
+                                  in textRunner.errors],
+                       'failures': [(str(item[0]), str(item[1]), "FAIL") for
+                                    item in textRunner.failures]})
   executor_result.put(0) if textRunner.wasSuccessful() else executor_result.put(1)
 
 def main():
@@ -115,37 +120,36 @@ def main():
       custom_tests = True
   pwd = os.path.abspath(os.path.dirname(__file__))
 
-  ambari_server_folder = get_parent_path(pwd,'ambari-server')
-  ambari_agent_folder = os.path.join(ambari_server_folder,"../ambari-agent")
-  ambari_common_folder = os.path.join(ambari_server_folder,"../ambari-common")
-  sys.path.append(ambari_common_folder + "/src/main/python")
-  sys.path.append(ambari_common_folder + "/src/main/python/ambari_jinja2")
-  sys.path.append(ambari_common_folder + "/src/main/python")
-  sys.path.append(ambari_common_folder + "/src/test/python")
-  sys.path.append(ambari_agent_folder + "/src/main/python")
-  sys.path.append(ambari_server_folder + "/src/test/python")
-  sys.path.append(ambari_server_folder + "/src/main/python")
-  sys.path.append(ambari_server_folder + "/src/main/resources/scripts")
-  sys.path.append(ambari_server_folder + "/src/main/resources/custom_actions")
+  ambari_server_folder = get_parent_path(pwd, 'ambari-server')
+  ambari_agent_folder = os.path.join(ambari_server_folder, "../ambari-agent")
+  ambari_common_folder = os.path.join(ambari_server_folder, "../ambari-common")
+  sys.path.append(os.path.join(ambari_common_folder, "src/main/python"))
+  sys.path.append(os.path.join(ambari_common_folder, "src/main/python/ambari_jinja2"))
+  sys.path.append(os.path.join(ambari_common_folder, "src/test/python"))
+  sys.path.append(os.path.join(ambari_agent_folder, "src/main/python"))
+  sys.path.append(os.path.join(ambari_server_folder, "src/test/python"))
+  sys.path.append(os.path.join(ambari_server_folder, "src/main/python"))
+  sys.path.append(os.path.join(ambari_server_folder, "src/main/resources/scripts"))
+  sys.path.append(os.path.join(ambari_server_folder, "src/main/resources/custom_actions/scripts"))
   
-  stacks_folder = pwd+'/stacks'
+  stacks_folder = os.path.join(pwd, 'stacks')
   #generate test variants(path, service, stack)
   test_variants = []
   for stack in os.listdir(stacks_folder):
-    current_stack_dir = stacks_folder+"/"+stack
+    current_stack_dir = os.path.join(stacks_folder, stack)
     if os.path.isdir(current_stack_dir) and stack not in STACK_EXCLUDE:
       for service in os.listdir(current_stack_dir):
-        current_service_dir = current_stack_dir+"/"+service
+        current_service_dir = os.path.join(current_stack_dir, service)
         if os.path.isdir(current_service_dir) and service not in SERVICE_EXCLUDE:
           if service == 'hooks':
             for hook in os.listdir(current_service_dir):
-              test_variants.append({'directory':current_service_dir + "/" + hook,
-                                    'service':hook,
-                                    'stack':stack})
+              test_variants.append({'directory': os.path.join(current_service_dir, hook),
+                                    'service': hook,
+                                    'stack': stack})
           else:
-            test_variants.append({'directory':current_service_dir,
-                                  'service':service,
-                                  'stack':stack})
+            test_variants.append({'directory': current_service_dir,
+                                  'service': service,
+                                  'stack': stack})
 
   #run tests for every service in every stack in separate process
   has_failures = False
@@ -155,7 +159,7 @@ def main():
   for variant in test_variants:
     executor_result = multiprocessing.Queue()
     sys.stderr.write( "Running tests for stack:{0} service:{1}\n"
-                      .format(variant['stack'],variant['service']))
+                      .format(variant['stack'], variant['service']))
     process = multiprocessing.Process(target=stack_test_executor,
                                       args=(variant['directory'],
                                             variant['service'],
@@ -183,18 +187,27 @@ def main():
   else:
     test_mask = TEST_MASK
 
-  tests = get_test_files(pwd, mask=test_mask, recursive=False)
-  #TODO Add an option to randomize the tests' execution
-  #shuffle(tests)
-  modules = [os.path.basename(s)[:-3] for s in tests]
-  suites = [unittest.defaultTestLoader.loadTestsFromName(name) for name in
-    modules]
-  testSuite = unittest.TestSuite(suites)
-  textRunner = unittest.TextTestRunner(verbosity=2).run(testSuite)
-  test_runs += textRunner.testsRun
-  test_errors.extend([(str(item[0]),str(item[1]),"ERROR") for item in textRunner.errors])
-  test_failures.extend([(str(item[0]),str(item[1]),"FAIL") for item in textRunner.failures])
-  tests_status = textRunner.wasSuccessful() and not has_failures
+  test_dirs = [
+    (os.path.join(pwd, 'custom_actions'), "\nRunning tests for custom actions\n"),
+    (pwd, "\nRunning tests for ambari-server\n"),
+  ]
+
+  for test_dir, msg in test_dirs:
+    sys.stderr.write(msg)
+    tests = get_test_files(test_dir, mask=test_mask, recursive=False)
+    #TODO Add an option to randomize the tests' execution
+    #shuffle(tests)
+    modules = [os.path.basename(s)[:-3] for s in tests]
+    suites = [unittest.defaultTestLoader.loadTestsFromName(name) for name in
+      modules]
+    testSuite = unittest.TestSuite(suites)
+    textRunner = unittest.TextTestRunner(verbosity=2).run(testSuite)
+    test_runs += textRunner.testsRun
+    test_errors.extend(
+      [(str(item[0]), str(item[1]), "ERROR") for item in textRunner.errors])
+    test_failures.extend(
+      [(str(item[0]), str(item[1]), "FAIL") for item in textRunner.failures])
+    tests_status = textRunner.wasSuccessful() and not has_failures
 
   if not tests_status:
     sys.stderr.write("----------------------------------------------------------------------\n")


Mime
View raw message