Repository: ambari Updated Branches: refs/heads/branch-feature-AMBARI-14714 4e575a59a -> 61f02394c
AMBARI-22649. Library for querying cluster_settings and stack_settings in command*.json. Project: http://git-wip-us.apache.org/repos/asf/ambari/repo Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/61f02394 Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/61f02394 Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/61f02394 Branch: refs/heads/branch-feature-AMBARI-14714 Commit: 61f02394cb5d84d6e9034bc3e9855ba9a6c14879 Parents: 4e575a5 Author: Swapan Shridhar <sshrid...@hortonworks.com> Authored: Tue Dec 19 05:55:04 2017 -0800 Committer: Swapan Shridhar <sshrid...@hortonworks.com> Committed: Tue Dec 19 06:04:40 2017 -0800 ---------------------------------------------------------------------- .../libraries/functions/cluster_settings.py | 60 ++++++ .../libraries/functions/settings.py | 112 ++++++++++ .../libraries/functions/stack_features.py | 15 +- .../libraries/functions/stack_select.py | 13 +- .../libraries/functions/stack_settings.py | 71 ++++++ .../libraries/functions/stack_tools.py | 15 +- ambari-server/src/test/python/TestSettings.py | 216 +++++++++++++++++++ 7 files changed, 490 insertions(+), 12 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ambari/blob/61f02394/ambari-common/src/main/python/resource_management/libraries/functions/cluster_settings.py ---------------------------------------------------------------------- diff --git a/ambari-common/src/main/python/resource_management/libraries/functions/cluster_settings.py b/ambari-common/src/main/python/resource_management/libraries/functions/cluster_settings.py new file mode 100644 index 0000000..610aed5 --- /dev/null +++ b/ambari-common/src/main/python/resource_management/libraries/functions/cluster_settings.py @@ -0,0 +1,60 @@ +#!/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. + +""" + +SECURITY_ENABLED_SETTING_NAME = "security_enabled" + + +from resource_management.core.logger import Logger +from resource_management.libraries.functions import settings + +def get_cluster_setting_entries(setting_names): + """ + Retrieves the passed-in cluster setting entr(y/ies) and their values as a map. + If 'setting_names' is passed-in as None : all the settings names and their corresponding values + will be returned as map. + If 'setting_names' is passed-in as empty set : None will be returned. + + :argument setting_names: A set/frozenset/tuple/list of settings passed-in for retrieval + :return map of setting_names and their respective values or None. + + :type setting_names: set + """ + return settings.get_setting_type_entries(settings.CLUSTER_SETTINGS_TYPE, setting_names) + + + +def get_cluster_setting_value(setting_name): + """ + Retrieves the passed-in cluster setting entry's value. + + :argument setting_name: cluster setting to be retrieved. + :return value of the passed-in 'setting_name' + + :type setting_name: string. + """ + return settings.get_setting_value(settings.CLUSTER_SETTINGS_TYPE, setting_name) + +def is_security_enabled(): + """ + Retrieves the cluster's security status. + + :return cluster's security status + """ + return settings.get_setting_value(settings.CLUSTER_SETTINGS_TYPE, SECURITY_ENABLED_SETTING_NAME) http://git-wip-us.apache.org/repos/asf/ambari/blob/61f02394/ambari-common/src/main/python/resource_management/libraries/functions/settings.py ---------------------------------------------------------------------- diff --git a/ambari-common/src/main/python/resource_management/libraries/functions/settings.py b/ambari-common/src/main/python/resource_management/libraries/functions/settings.py new file mode 100644 index 0000000..42be6d6 --- /dev/null +++ b/ambari-common/src/main/python/resource_management/libraries/functions/settings.py @@ -0,0 +1,112 @@ +#!/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 resource_management.core.logger import Logger + +# Setting types currently supported. +STACK_SETTINGS_TYPE = "/stackSettings" +CLUSTER_SETTINGS_TYPE = "/clusterSettings" + + +def get_setting_type_entries(setting_type, setting_names=None): + """ + Retrieves the passed-in settingType's settings entr(y/ies) and their values as a map. + Caters to Setting types : '/stackSettings' and '/clusterSettings'. + + If 'setting_names' is passed-in as None, all the settings names and their corresponding values + will be returned as map. + If 'setting_names' is passed-in is empty : {} will be returned. + + :argument setting_type: Setting type + :argument setting_names: A set/frozenset/tuple/list of settings passed-in for retrieval + :return map of setting_names and their respective values or None. + + :type setting_names: set + """ + from resource_management.libraries.functions.default import default + + Logger.info("In get_setting_type_entries(). Passed-in settings type : {0}, setting(s) : {1}".format(setting_type, setting_names)) + + if not is_setting_type_supported(setting_type): + Logger.error("Does not support retrieving settings for settings_type : {0}".format(setting_type)) + return None + + settings = default(setting_type, None) + + if settings is None: + Logger.info("Couldn't retrieve '"+setting_type+"'.") + return None + + if setting_names is None: # Return all settings + return settings + + if not isinstance(setting_names, (set, frozenset, tuple, list)): + Logger.error("'setting_names' type expected to be either a : set, frozenset, tuple, or list. " + "Passed-in type is : {0}".format(type(setting_names))) + return None + + elif len(setting_names) == 0: + Logger.error("Passed-in settings set is EMPTY") + return None + else: + result = dict((setting, settings[setting]) for setting in setting_names if setting in settings) + if not result: + Logger.error("Passed-in setting(s) in set not present.") + return {} + else: + return result + +def get_setting_value(setting_type, setting_name): + """ + Retrieves the passed-in settingType's setting entry's value. + + :argument setting_type: Setting type + :argument setting_name: setting name to be retrieved. + :return value of the passed-in 'setting_name' + + :type setting_name: string. + """ + from resource_management.libraries.functions.default import default + + Logger.info("In get_setting_value(). Passed-in settings type : {0}, setting(s) : {1}".format(setting_type, setting_name)) + + if not is_setting_type_supported(setting_type): + Logger.error("Does not support retrieving settings for settings_type : {0}".format(setting_type)) + return None + + if setting_name is None: + return None + + settings = default(setting_type, None) + + if settings is None: + Logger.info("Couldn't retrieve '"+setting_type+"'.") + return None + + return settings.get(setting_name) + + +def is_setting_type_supported(setting_type): + """ + Checks if the passed in setting type is supported or not. + :argument setting_type: Setting type + :return: True or False + """ + return setting_type in (STACK_SETTINGS_TYPE, CLUSTER_SETTINGS_TYPE) http://git-wip-us.apache.org/repos/asf/ambari/blob/61f02394/ambari-common/src/main/python/resource_management/libraries/functions/stack_features.py ---------------------------------------------------------------------- diff --git a/ambari-common/src/main/python/resource_management/libraries/functions/stack_features.py b/ambari-common/src/main/python/resource_management/libraries/functions/stack_features.py index 92823b0..3e73310 100644 --- a/ambari-common/src/main/python/resource_management/libraries/functions/stack_features.py +++ b/ambari-common/src/main/python/resource_management/libraries/functions/stack_features.py @@ -24,6 +24,7 @@ from resource_management.core.exceptions import Fail from resource_management.core.logger import Logger from resource_management.libraries.functions.constants import Direction from resource_management.libraries.functions.version import format_stack_version +from resource_management.libraries.functions import stack_settings # executionCommand for STOP _ROLE_COMMAND_STOP = 'STOP' @@ -49,14 +50,20 @@ def check_stack_feature(stack_feature, stack_version): Logger.warning("Cannot find the stack name in the command. Stack features cannot be loaded") return False - stack_features_config = default("/configurations/cluster-env/stack_features", None) + stack_features_setting = stack_settings.get_stack_setting_value(stack_settings.STACK_FEATURES_SETTING) + # TODO : Removed the below if of reading from cluster_env, once we have removed stack_features from there + # and have started using /stackSettings as source of truth. + if stack_features_setting is None: + Logger.info("Couldn't retrieve 'stack_features' from /stackSettings. Retrieving from cluster_env now.") + stack_features_setting = default("/configurations/cluster-env/"+stack_settings.STACK_FEATURES_SETTING, None) + if not stack_version: Logger.debug("Cannot determine if feature %s is supported since did not provide a stack version." % stack_feature) return False - if stack_features_config: - data = json.loads(stack_features_config) + if stack_features_setting: + data = json.loads(stack_features_setting) if stack_name not in data: Logger.warning("Cannot find stack features for the stack named {0}".format(stack_name)) @@ -64,7 +71,7 @@ def check_stack_feature(stack_feature, stack_version): data = data[stack_name] - for feature in data["stack_features"]: + for feature in data[stack_settings.STACK_FEATURES_SETTING]: if feature["name"] == stack_feature: if "min_version" in feature: min_version = feature["min_version"] http://git-wip-us.apache.org/repos/asf/ambari/blob/61f02394/ambari-common/src/main/python/resource_management/libraries/functions/stack_select.py ---------------------------------------------------------------------- diff --git a/ambari-common/src/main/python/resource_management/libraries/functions/stack_select.py b/ambari-common/src/main/python/resource_management/libraries/functions/stack_select.py index b741a33..6678588 100644 --- a/ambari-common/src/main/python/resource_management/libraries/functions/stack_select.py +++ b/ambari-common/src/main/python/resource_management/libraries/functions/stack_select.py @@ -34,6 +34,7 @@ from resource_management.libraries.functions.get_stack_version import get_stack_ from resource_management.libraries.functions.format import format from resource_management.libraries.script.script import Script from resource_management.libraries.functions import stack_tools +from resource_management.libraries.functions import stack_settings from resource_management.core import shell from resource_management.core import sudo from resource_management.core.shell import call @@ -181,11 +182,17 @@ def get_packages(scope, service_name = None, component_name = None): if stack_name is None: raise Fail("The stack name is not present in the command. Packages for stack-select tool cannot be loaded.") - stack_packages_config = default("/configurations/cluster-env/stack_packages", None) - if stack_packages_config is None: + stack_packages_setting = stack_settings.get_stack_setting_value(stack_settings.STACK_PACKAGES_SETTING) + # TODO : Removed the below if of reading from cluster_env, once we have removed stack_packages from there + # and have started using /stackSettings as source of truth. + if stack_packages_setting is None: + Logger.info("Couldn't retrieve 'stack_packages' from /stackSettings. Retrieving from cluster_env now.") + stack_packages_setting = default("/configurations/cluster-env/"+stack_settings.STACK_PACKAGES_SETTING, None) + + if stack_packages_setting is None: raise Fail("The stack packages are not defined on the command. Unable to load packages for the stack-select tool") - data = json.loads(stack_packages_config) + data = json.loads(stack_packages_setting) if stack_name not in data: raise Fail( http://git-wip-us.apache.org/repos/asf/ambari/blob/61f02394/ambari-common/src/main/python/resource_management/libraries/functions/stack_settings.py ---------------------------------------------------------------------- diff --git a/ambari-common/src/main/python/resource_management/libraries/functions/stack_settings.py b/ambari-common/src/main/python/resource_management/libraries/functions/stack_settings.py new file mode 100644 index 0000000..8174f6a --- /dev/null +++ b/ambari-common/src/main/python/resource_management/libraries/functions/stack_settings.py @@ -0,0 +1,71 @@ +#!/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 resource_management.core.logger import Logger +from resource_management.libraries.functions import settings + +# Stack related configs from stack's stack_settings.json +STACK_NAME_SETTING = "stack_name" +STACK_TOOLS_SETTING = "stack_tools" +STACK_FEATURES_SETTING = "stack_features" +STACK_PACKAGES_SETTING = "stack_packages" +STACK_ROOT_SETTING = "stack_root" + +STACK_SELECT_SETTING = "stack_select" + + +def get_stack_setting_entries(setting_names): + """ + Retrieves the passed-in stack setting entr(y/ies) and their values as a map. + + :argument setting_names: A set/frozenset/tuple/list of settings passed-in for retrieval + :return map of setting_names and their respective values or None. + + :type setting_names: set + """ + return settings.get_setting_type_entries(settings.STACK_SETTINGS_TYPE, setting_names) + +def get_stack_setting_value(setting_name): + """ + Retrieves the passed-in stack setting entry's value. + + :argument setting_name: stack setting to be retrieved. + :return value of the passed-in 'setting_name' + + :type setting_name: string. + """ + return settings.get_setting_value(settings.STACK_SETTINGS_TYPE, setting_name) + +def get_stack_name(): + """ + Retrieves the stack name. + + :return: stack name as string. + """ + return settings.get_setting_value(settings.STACK_SETTINGS_TYPE, STACK_NAME_SETTING) + + +def get_stack_root(): + """ + Retrieves the stack root. + + :return: stack root as string + """ + return settings.get_setting_value(settings.STACK_SETTINGS_TYPE, STACK_ROOT_SETTING) \ No newline at end of file http://git-wip-us.apache.org/repos/asf/ambari/blob/61f02394/ambari-common/src/main/python/resource_management/libraries/functions/stack_tools.py ---------------------------------------------------------------------- diff --git a/ambari-common/src/main/python/resource_management/libraries/functions/stack_tools.py b/ambari-common/src/main/python/resource_management/libraries/functions/stack_tools.py index d9233a3..997cf28 100644 --- a/ambari-common/src/main/python/resource_management/libraries/functions/stack_tools.py +++ b/ambari-common/src/main/python/resource_management/libraries/functions/stack_tools.py @@ -27,7 +27,7 @@ import ambari_simplejson as json from resource_management.core.exceptions import Fail from resource_management.core.logger import Logger from resource_management.core.utils import pad - +from resource_management.libraries.functions import stack_settings STACK_SELECTOR_NAME = "stack_selector" CONF_SELECTOR_NAME = "conf_selector" @@ -46,10 +46,15 @@ def get_stack_tool(name): Logger.warning("Cannot find the stack name in the command. Stack tools cannot be loaded") return None, None, None - stack_tools = None - stack_tools_config = default("/configurations/cluster-env/stack_tools", None) - if stack_tools_config: - stack_tools = json.loads(stack_tools_config) + stack_tools_setting = stack_settings.get_stack_setting_value(stack_settings.STACK_TOOLS_SETTING) + # TODO : Removed the below if of reading from cluster_env, once we have removed stack_tools from there + # and have started using /stackSettings as source of truth. + if stack_tools_setting is None: + Logger.info("Couldn't retrieve 'stack_tools' from /stackSettings. Retrieving from cluster_env now.") + stack_tools_setting = default("/configurations/cluster-env/"+stack_settings.STACK_TOOLS_SETTING, None) + + if stack_tools_setting: + stack_tools = json.loads(stack_tools_setting) if stack_tools is None: Logger.warning("The stack tools could not be found in cluster-env") http://git-wip-us.apache.org/repos/asf/ambari/blob/61f02394/ambari-server/src/test/python/TestSettings.py ---------------------------------------------------------------------- diff --git a/ambari-server/src/test/python/TestSettings.py b/ambari-server/src/test/python/TestSettings.py new file mode 100644 index 0000000..e117747 --- /dev/null +++ b/ambari-server/src/test/python/TestSettings.py @@ -0,0 +1,216 @@ +# !/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 resource_management.core.logger import Logger +from resource_management.libraries.functions import settings +from resource_management.libraries.script import Script + +from unittest import TestCase + +Logger.initialize_logger() + +class TestSettings(TestCase): + + + ###### For get_setting_type_entries() + + def test_entries_for_nonexistent_setting_type_is_none(self): + Script.config = TestSettings._get_simple_command() + + self.assertTrue(settings.get_setting_type_entries('/non_existing_setting_type', None) is None) + self.assertTrue(settings.get_setting_type_entries('/non_existing_setting_type', 'non_existing_key') is None) + self.assertTrue(settings.get_setting_type_entries('/non_existing_setting_type', set(['non_existing_key'])) is None) + + + def test_entries_for_unsupported_setting_type_is_none(self): + Script.config = TestSettings._get_simple_command() + + self.assertTrue(settings.get_setting_type_entries('/agentConfigParams', None) is None) + self.assertTrue(settings.get_setting_type_entries('/agentConfigParams', 'agent') is None) + self.assertTrue(settings.get_setting_type_entries('/agentConfigParams', set(['agent'])) is None) + + + def test_entries_for_supported_type(self): + Script.config = TestSettings._get_simple_command() + + # For stackSettings + self.assertEquals(Script.config['stackSettings'], settings.get_setting_type_entries(settings.STACK_SETTINGS_TYPE, None)) + self.assertEquals(Script.config['stackSettings'], settings.get_setting_type_entries(settings.STACK_SETTINGS_TYPE)) + + # For clusterSettings + self.assertEquals(Script.config['clusterSettings'], settings.get_setting_type_entries(settings.CLUSTER_SETTINGS_TYPE, None)) + self.assertEquals(Script.config['clusterSettings'], settings.get_setting_type_entries(settings.CLUSTER_SETTINGS_TYPE)) + + + def test_full_subset_of_entries_for_supported_type(self): + Script.config = TestSettings._get_simple_command() + + # For stackSettings + stackSettings = Script.config['stackSettings'] + self.assertEquals(stackSettings, settings.get_setting_type_entries(settings.STACK_SETTINGS_TYPE, set(stackSettings.keys()))) + self.assertEquals(stackSettings, settings.get_setting_type_entries(settings.STACK_SETTINGS_TYPE, frozenset(stackSettings.keys()))) + self.assertEquals(stackSettings, settings.get_setting_type_entries(settings.STACK_SETTINGS_TYPE, tuple(stackSettings.keys()))) + self.assertEquals(stackSettings, settings.get_setting_type_entries(settings.STACK_SETTINGS_TYPE, list(stackSettings.keys()))) + + # For clusterSettings + clusterSettings = Script.config['clusterSettings'] + self.assertEquals(clusterSettings, settings.get_setting_type_entries(settings.CLUSTER_SETTINGS_TYPE, set(clusterSettings.keys()))) + self.assertEquals(clusterSettings, settings.get_setting_type_entries(settings.CLUSTER_SETTINGS_TYPE, frozenset(clusterSettings.keys()))) + self.assertEquals(clusterSettings, settings.get_setting_type_entries(settings.CLUSTER_SETTINGS_TYPE, tuple(clusterSettings.keys()))) + self.assertEquals(clusterSettings, settings.get_setting_type_entries(settings.CLUSTER_SETTINGS_TYPE, list(clusterSettings.keys()))) + + def test_real_subset_of_entries_for_supported_type(self): + Script.config = TestSettings._get_simple_command() + + # For stackSettings + self.assertEquals({'stack_name':'HDP'}, settings.get_setting_type_entries(settings.STACK_SETTINGS_TYPE, set(['stack_name']))) + self.assertEquals({'stack_name':'HDP'}, settings.get_setting_type_entries(settings.STACK_SETTINGS_TYPE, frozenset(['stack_name']))) + self.assertEquals({'stack_name':'HDP'}, settings.get_setting_type_entries(settings.STACK_SETTINGS_TYPE, tuple(['stack_name']))) + self.assertEquals({'stack_name':'HDP'}, settings.get_setting_type_entries(settings.STACK_SETTINGS_TYPE, list(['stack_name']))) + self.assertEquals({'stack_name': 'HDP', 'stack_version': '2.4'}, settings.get_setting_type_entries(settings.STACK_SETTINGS_TYPE, list(['stack_name','stack_name', 'stack_version']))) + + # For clusterSettings + self.assertEquals({'smokeuser': 'ambari-qa'}, settings.get_setting_type_entries(settings.CLUSTER_SETTINGS_TYPE, set(['smokeuser']))) + self.assertEquals({'smokeuser': 'ambari-qa'}, settings.get_setting_type_entries(settings.CLUSTER_SETTINGS_TYPE, frozenset(['smokeuser']))) + self.assertEquals({'smokeuser': 'ambari-qa'}, settings.get_setting_type_entries(settings.CLUSTER_SETTINGS_TYPE, tuple(['smokeuser']))) + self.assertEquals({'smokeuser': 'ambari-qa'}, settings.get_setting_type_entries(settings.CLUSTER_SETTINGS_TYPE, list(['smokeuser']))) + self.assertEquals({'recovery_type': 'AUTO_START', 'smokeuser': 'ambari-qa'}, settings.get_setting_type_entries(settings.CLUSTER_SETTINGS_TYPE, list(['smokeuser', 'recovery_type', 'smokeuser']))) + + def test_empty_subset_of_entries_for_supported_type(self): + Script.config = TestSettings._get_simple_command() + + # For stackSettings + self.assertEquals({}, settings.get_setting_type_entries(settings.STACK_SETTINGS_TYPE, set(['non_existing_key']))) + self.assertEquals({}, settings.get_setting_type_entries(settings.STACK_SETTINGS_TYPE, frozenset(['non_existing_key']))) + self.assertEquals({}, settings.get_setting_type_entries(settings.STACK_SETTINGS_TYPE, tuple(['non_existing_key']))) + self.assertEquals({}, settings.get_setting_type_entries(settings.STACK_SETTINGS_TYPE, list(['non_existing_key']))) + + # For clusterSettings + self.assertEquals({}, settings.get_setting_type_entries(settings.CLUSTER_SETTINGS_TYPE, set(['non_existing_key']))) + self.assertEquals({}, settings.get_setting_type_entries(settings.CLUSTER_SETTINGS_TYPE, frozenset(['non_existing_key']))) + self.assertEquals({}, settings.get_setting_type_entries(settings.CLUSTER_SETTINGS_TYPE, tuple(['non_existing_key']))) + self.assertEquals({}, settings.get_setting_type_entries(settings.CLUSTER_SETTINGS_TYPE, list(['non_existing_key']))) + + def test_empty_string_entries_for_supported_type(self): + Script.config = TestSettings._get_simple_command() + + # For stackSettings + self.assertEquals({}, settings.get_setting_type_entries(settings.STACK_SETTINGS_TYPE, set([""]))) + self.assertEquals({}, settings.get_setting_type_entries(settings.STACK_SETTINGS_TYPE, set(["", ""]))) + self.assertEquals({}, settings.get_setting_type_entries(settings.STACK_SETTINGS_TYPE, frozenset(["", ""]))) + self.assertEquals({}, settings.get_setting_type_entries(settings.STACK_SETTINGS_TYPE, tuple(["", ""]))) + self.assertEquals({}, settings.get_setting_type_entries(settings.STACK_SETTINGS_TYPE, list(["", ""]))) + + # For clusterSettings + self.assertEquals({}, settings.get_setting_type_entries(settings.CLUSTER_SETTINGS_TYPE, set([""]))) + self.assertEquals({}, settings.get_setting_type_entries(settings.CLUSTER_SETTINGS_TYPE, set(["", ""]))) + self.assertEquals({}, settings.get_setting_type_entries(settings.CLUSTER_SETTINGS_TYPE, frozenset(["", ""]))) + self.assertEquals({}, settings.get_setting_type_entries(settings.CLUSTER_SETTINGS_TYPE, tuple(["", ""]))) + self.assertEquals({}, settings.get_setting_type_entries(settings.CLUSTER_SETTINGS_TYPE, list(["", ""]))) + + ###### For get_setting_value() + + def test_value_of_nonexistent_setting_type_is_none(self): + Script.config = TestSettings._get_simple_command() + + self.assertTrue(settings.get_setting_value('/non_existing_setting_type', None) is None) + self.assertTrue(settings.get_setting_value('/non_existing_setting_type', 'non_existing_key') is None) + + + def test_value_of_unsupported_setting_type_is_none(self): + Script.config = TestSettings._get_simple_command() + + self.assertTrue(settings.get_setting_value('/agentConfigParams', None) is None) + self.assertTrue(settings.get_setting_value('/agentConfigParams', 'non_existing_key') is None) + self.assertTrue(settings.get_setting_value('/agentConfigParams', 'agent') is None) + self.assertTrue(settings.get_setting_value('/agentConfigParams', set(['agent'])) is None) + self.assertTrue(settings.get_setting_value('/agentConfigParams', frozenset(['agent'])) is None) + self.assertTrue(settings.get_setting_value('/agentConfigParams', tuple(['agent'])) is None) + self.assertTrue(settings.get_setting_value('/agentConfigParams', list(['agent'])) is None) + + + def test_value_of_supported_setting_type_non_existent_name(self): + Script.config = TestSettings._get_simple_command() + + # For stackSettings + self.assertTrue(settings.get_setting_value(settings.STACK_SETTINGS_TYPE, 'non_existing_key') is None) + + # For clusterSettings + self.assertTrue(settings.get_setting_value(settings.CLUSTER_SETTINGS_TYPE, 'non_existing_key') is None) + + def test_value_of_supported_setting_type_empy_string_name(self): + Script.config = TestSettings._get_simple_command() + + # For stackSettings + self.assertTrue(settings.get_setting_value(settings.STACK_SETTINGS_TYPE, "") is None) + + # For clusterSettings + self.assertTrue(settings.get_setting_value(settings.CLUSTER_SETTINGS_TYPE, "") is None) + + def test_value_of_supported_setting_type_setting_name_none(self): + Script.config = TestSettings._get_simple_command() + + # For stackSettings + self.assertTrue(settings.get_setting_value(settings.STACK_SETTINGS_TYPE, None) is None) + + # For clusterSettings + self.assertTrue(settings.get_setting_value(settings.CLUSTER_SETTINGS_TYPE, None) is None) + + def test_value_of_supported_setting_type_and_name(self): + Script.config = TestSettings._get_simple_command() + + # For stackSettings + stack_settings = Script.config['stackSettings'] + for k in stack_settings.keys(): + self.assertEquals(stack_settings[k], settings.get_setting_value(settings.STACK_SETTINGS_TYPE, k)) + + # For clusterSettings + cluster_settings = Script.config['clusterSettings'] + for k in cluster_settings.keys(): + self.assertEquals(cluster_settings[k], settings.get_setting_value(settings.CLUSTER_SETTINGS_TYPE, k)) + + + @staticmethod + def _get_simple_command(): + """ + A simple command with stackSettings, clusterSettings, and some other data. + """ + return { + "stackSettings": { + "stack_name": "HDP", + "stack_version": "2.4", + }, + "clusterSettings": { + "recovery_enabled": "false", + "smokeuser": "ambari-qa", + "recovery_type": "AUTO_START", + "user_group": "hadoop", + }, + "agentConfigParams": { + "agent": { + "parallel_execution": 1, + } + }, + "localComponents": [ + "INFRA_SOLR_CLIENT", + "MYSQL_SERVER", + "SECONDARY_NAMENODE", + ] + }