blob: 7d4466c3be130b62c39589253cd9663dca205cc3 [file]
#!/usr/bin/env python3
"""
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 unittest import TestCase
import os
class TestStackAdvisorInitialization(TestCase):
def setUp(self):
import imp
self.test_directory = os.path.dirname(os.path.abspath(__file__))
resources_path = os.path.join(self.test_directory, "../../main/resources")
stack_advisor_path = os.path.abspath(
os.path.join(resources_path, "scripts/stack_advisor.py")
)
ambari_configuration_path = os.path.abspath(
os.path.join(resources_path, "stacks/ambari_configuration.py")
)
with open(ambari_configuration_path, "rb") as fp:
imp.load_module(
"ambari_configuration",
fp,
ambari_configuration_path,
(".py", "rb", imp.PY_SOURCE),
)
with open(stack_advisor_path, "rb") as fp:
self.stack_advisor = imp.load_module(
"stack_advisor", fp, stack_advisor_path, (".py", "rb", imp.PY_SOURCE)
)
def test_stackAdvisorLoadedForNotHDPStack(self):
path_template = os.path.join(
self.test_directory, "../resources/stacks/{0}/{1}/services/stack_advisor.py"
)
path_template_name = "STACK_ADVISOR_IMPL_PATH_TEMPLATE"
setattr(self.stack_advisor, path_template_name, path_template)
self.assertEqual(path_template, getattr(self.stack_advisor, path_template_name))
instantiate_stack_advisor_method_name = "instantiateStackAdvisor"
instantiate_stack_advisor_method = getattr(
self.stack_advisor, instantiate_stack_advisor_method_name
)
stack_advisor = instantiate_stack_advisor_method("XYZ", "1.0.1", ["1.0.0"])
self.assertEqual("XYZ101StackAdvisor", stack_advisor.__class__.__name__)
services = {
"Versions": {"stack_name": "XYZ", "stack_version": "1.0.1"},
"services": [
{
"StackServices": {"service_name": "YARN"},
"components": [
{"StackServiceComponents": {"component_name": "RESOURCEMANAGER"}},
{"StackServiceComponents": {"component_name": "APP_TIMELINE_SERVER"}},
{"StackServiceComponents": {"component_name": "YARN_CLIENT"}},
{"StackServiceComponents": {"component_name": "NODEMANAGER"}},
],
}
],
}
hosts = {
"items": [{"Hosts": {"host_name": "host1"}}, {"Hosts": {"host_name": "host2"}}]
}
config_recommendations = stack_advisor.recommendConfigurations(services, hosts)
yarn_configs = config_recommendations["recommendations"]["blueprint"][
"configurations"
]["yarn-site"]["properties"]
"""Check that value is populated from child class, not parent"""
self.assertEqual("-Xmx101m", yarn_configs["yarn.nodemanager.resource.memory-mb"])
def test_stackAdvisorDefaultImpl(self):
instantiate_stack_advisor_method_name = "instantiateStackAdvisor"
instantiate_stack_advisor_method = getattr(
self.stack_advisor, instantiate_stack_advisor_method_name
)
"""Not existent stack - to return default implementation"""
default_stack_advisor = instantiate_stack_advisor_method("HDP1", "2.0.6", [])
self.assertEqual("DefaultStackAdvisor", default_stack_advisor.__class__.__name__)
services = {
"Versions": {"stack_name": "HDP1", "stack_version": "2.0.6"},
"services": [
{
"StackServices": {
"service_name": "GANGLIA",
"service_version": "3.5.0",
},
"components": [
{
"StackServiceComponents": {
"cardinality": "ALL",
"component_name": "GANGLIA_MONITOR",
"is_master": False,
"hostnames": [],
}
},
{
"StackServiceComponents": {
"cardinality": "1",
"component_name": "GANGLIA_SERVER",
"is_master": True,
"hostnames": [],
}
},
],
},
{
"StackServices": {"service_name": "HBASE", "service_version": "0.98.0.2.1"},
"components": [
{
"StackServiceComponents": {
"cardinality": "1+",
"component_name": "HBASE_CLIENT",
"is_master": False,
"hostnames": [],
}
},
{
"StackServiceComponents": {
"cardinality": "1+",
"component_name": "HBASE_MASTER",
"is_master": True,
"hostnames": [],
}
},
{
"StackServiceComponents": {
"cardinality": "1+",
"component_name": "HBASE_REGIONSERVER",
"is_master": False,
"hostnames": [],
}
},
],
},
{
"StackServices": {"service_name": "HDFS", "service_version": "2.4.0.2.1"},
"components": [
{
"StackServiceComponents": {
"cardinality": "1+",
"component_name": "DATANODE",
"is_master": False,
"hostnames": [],
}
},
{
"StackServiceComponents": {
"cardinality": "1+",
"component_name": "HDFS_CLIENT",
"is_master": False,
"hostnames": [],
}
},
{
"StackServiceComponents": {
"cardinality": "0+",
"component_name": "JOURNALNODE",
"is_master": False,
"hostnames": [],
}
},
{
"StackServiceComponents": {
"cardinality": "1-2",
"component_name": "NAMENODE",
"is_master": True,
"hostnames": [],
}
},
{
"StackServiceComponents": {
"cardinality": "1",
"component_name": "SECONDARY_NAMENODE",
"is_master": True,
"hostnames": [],
}
},
{
"StackServiceComponents": {
"cardinality": "0+",
"component_name": "ZKFC",
"is_master": False,
"hostnames": [],
}
},
],
},
{
"StackServices": {"service_name": "PIG", "service_version": "0.12.1.2.1"},
"components": [
{
"StackServiceComponents": {
"cardinality": "0+",
"component_name": "PIG",
"is_master": False,
"hostnames": [],
}
}
],
},
{
"StackServices": {"service_name": "TEZ", "service_version": "0.4.0.2.1"},
"components": [
{
"StackServiceComponents": {
"cardinality": "0+",
"component_name": "TEZ_CLIENT",
"is_master": False,
"hostnames": [],
}
}
],
},
{
"StackServices": {
"service_name": "ZOOKEEPER",
"service_version": "3.4.5.2.1",
},
"components": [
{
"StackServiceComponents": {
"cardinality": "1+",
"component_category": "CLIENT",
"component_name": "ZOOKEEPER_CLIENT",
"is_master": False,
"hostnames": [],
}
},
{
"StackServiceComponents": {
"cardinality": "1+",
"component_name": "ZOOKEEPER_SERVER",
"is_master": True,
"hostnames": [],
}
},
],
},
],
"configurations": {},
}
hosts = {
"items": [
{
"Hosts": {
"host_name": "host1",
"cpu_count": 1,
"total_mem": 2097152,
"disk_info": [{"size": "80000000", "mountpoint": "/"}],
}
},
{
"Hosts": {
"host_name": "host2",
"cpu_count": 1,
"total_mem": 2097152,
"disk_info": [{"size": "80000000", "mountpoint": "/"}],
}
},
]
}
actualValidateConfigResponse = default_stack_advisor.validateConfigurations(
services, hosts
)
actualValidateLayoutResponse = default_stack_advisor.validateComponentLayout(
services, hosts
)
expectedValidationResponse = {
"Versions": {"stack_name": "HDP1", "stack_version": "2.0.6"},
"items": [],
}
self.assertEqual(actualValidateConfigResponse, expectedValidationResponse)
self.assertEqual(actualValidateLayoutResponse, expectedValidationResponse)
actualRecommendConfigResponse = default_stack_advisor.recommendConfigurations(
services, hosts
)
expectedRecommendConfigResponse = {
"Versions": {"stack_name": "HDP1", "stack_version": "2.0.6"},
"hosts": ["host1", "host2"],
"services": ["GANGLIA", "HBASE", "HDFS", "PIG", "TEZ", "ZOOKEEPER"],
"recommendations": {
"blueprint": {"configurations": {}, "host_groups": []},
"blueprint_cluster_binding": {"host_groups": []},
},
}
self.assertEqual(actualRecommendConfigResponse, expectedRecommendConfigResponse)
actualRecommendLayoutResponse = default_stack_advisor.recommendComponentLayout(
services, hosts
)
expectedRecommendLayoutResponse = {
"Versions": {"stack_name": "HDP1", "stack_version": "2.0.6"},
"hosts": ["host1", "host2"],
"services": ["GANGLIA", "HBASE", "HDFS", "PIG", "TEZ", "ZOOKEEPER"],
"recommendations": {
"blueprint": {
"host_groups": [
{"name": "host-group-2", "components": []},
{
"name": "host-group-1",
"components": [
{"name": "GANGLIA_SERVER"},
{"name": "HBASE_MASTER"},
{"name": "NAMENODE"},
{"name": "SECONDARY_NAMENODE"},
{"name": "ZOOKEEPER_SERVER"},
{"name": "ZOOKEEPER_CLIENT"},
],
},
]
},
"blueprint_cluster_binding": {
"host_groups": [
{"name": "host-group-2", "hosts": [{"fqdn": "host2"}]},
{"name": "host-group-1", "hosts": [{"fqdn": "host1"}]},
]
},
},
}
self.assertEqual(actualRecommendLayoutResponse, expectedRecommendLayoutResponse)
# Test with maintenance_state. One host is in maintenance mode.
hosts = {
"items": [
{"Hosts": {"host_name": "host1", "maintenance_state": "OFF", "cpu_count": 1}},
{"Hosts": {"host_name": "host2", "maintenance_state": "ON", "cpu_count": 1}},
]
}
actualRecommendLayoutResponse = default_stack_advisor.recommendComponentLayout(
services, hosts
)
expectedRecommendLayoutResponse = {
"services": ["GANGLIA", "HBASE", "HDFS", "PIG", "TEZ", "ZOOKEEPER"],
"recommendations": {
"blueprint": {
"host_groups": [
{
"name": "host-group-1",
"components": [
{"name": "GANGLIA_SERVER"},
{"name": "HBASE_MASTER"},
{"name": "NAMENODE"},
{"name": "SECONDARY_NAMENODE"},
{"name": "ZOOKEEPER_SERVER"},
{"name": "ZOOKEEPER_CLIENT"},
],
}
]
},
"blueprint_cluster_binding": {
"host_groups": [{"hosts": [{"fqdn": "host1"}], "name": "host-group-1"}]
},
},
"hosts": ["host1"],
"Versions": {"stack_name": "HDP1", "stack_version": "2.0.6"},
}
self.assertEqual(actualRecommendLayoutResponse, expectedRecommendLayoutResponse)
# Test with maintenance_state. Both hosts are in maintenance mode.
hosts = {
"items": [
{
"Hosts": {
"host_name": "host1",
"maintenance_state": "ON",
"cpu_count": 1,
"total_mem": 2097152,
"disk_info": [{"size": "80000000", "mountpoint": "/"}],
}
},
{
"Hosts": {
"host_name": "host2",
"maintenance_state": "ON",
"cpu_count": 1,
"total_mem": 2097152,
"disk_info": [{"size": "80000000", "mountpoint": "/"}],
}
},
]
}
actualRecommendLayoutResponse = default_stack_advisor.recommendComponentLayout(
services, hosts
)
expectedRecommendLayoutResponse = {
"Versions": {"stack_name": "HDP1", "stack_version": "2.0.6"},
"hosts": [],
"services": ["GANGLIA", "HBASE", "HDFS", "PIG", "TEZ", "ZOOKEEPER"],
"recommendations": {
"blueprint": {"host_groups": []},
"blueprint_cluster_binding": {"host_groups": []},
},
}
self.assertEqual(actualRecommendLayoutResponse, expectedRecommendLayoutResponse)
# Config groups support by default
services["config-groups"] = [{"configurations": {}, "hosts": ["host2"]}]
actualConfigGroupRecommendConfigResponse = (
default_stack_advisor.recommendConfigurations(services, hosts)
)
expectedConfigGroupRecommendConfigResponse = {
"Versions": {"stack_name": "HDP1", "stack_version": "2.0.6"},
"hosts": ["host1", "host2"],
"services": ["GANGLIA", "HBASE", "HDFS", "PIG", "TEZ", "ZOOKEEPER"],
"recommendations": {
"config-groups": [
{"configurations": {}, "dependent_configurations": {}, "hosts": ["host2"]}
],
"blueprint": {"configurations": {}, "host_groups": []},
"blueprint_cluster_binding": {"host_groups": []},
},
}
self.assertEqual(
actualConfigGroupRecommendConfigResponse,
expectedConfigGroupRecommendConfigResponse,
)
services = {
"services": [
{
"StackServices": {
"service_name": "YARN",
"stack_name": "HDP",
"stack_version": "2.3",
},
"configurations": [
{
"StackConfigurations": {
"property_depended_by": [
{
"type": "yarn-site",
"name": "yarn.scheduler.minimum-allocation-vcores",
},
{
"type": "yarn-site",
"name": "yarn.scheduler.maximum-allocation-vcores",
},
],
"property_name": "yarn.nodemanager.resource.cpu-vcores",
"type": "yarn-site.xml",
},
"dependencies": [],
},
{
"StackConfigurations": {
"property_name": "yarn.nodemanager.resource.memory-mb",
"type": "yarn-site.xml",
},
"dependencies": [
{
"StackConfigurationDependency": {
"dependency_name": "yarn.scheduler.maximum-allocation-mb",
"dependency_type": "yarn-site",
}
},
{
"StackConfigurationDependency": {
"dependency_name": "yarn.scheduler.minimum-allocation-mb",
"dependency_type": "yarn-site",
}
},
],
},
{
"StackConfigurations": {
"property_depended_by": [
{"type": "mapred-site", "name": "yarn.app.mapreduce.am.resource.mb"},
{"type": "mapred-site", "name": "mapreduce.map.memory.mb"},
{"type": "mapred-site", "name": "mapreduce.reduce.memory.mb"},
],
"property_name": "yarn.scheduler.maximum-allocation-mb",
"type": "yarn-site.xml",
},
"dependencies": [],
},
{
"StackConfigurations": {
"property_depended_by": [],
"property_name": "yarn.scheduler.maximum-allocation-vcores",
"type": "yarn-site.xml",
},
"dependencies": [],
},
{
"StackConfigurations": {
"property_name": "yarn.scheduler.minimum-allocation-mb",
"type": "yarn-site.xml",
},
"dependencies": [
{
"StackConfigurationDependency": {
"dependency_name": "hive.tez.container.size",
"dependency_type": "hive-site",
}
},
{
"StackConfigurationDependency": {
"dependency_name": "yarn.app.mapreduce.am.resource.mb",
"dependency_type": "mapred-site",
}
},
{
"StackConfigurationDependency": {
"dependency_name": "mapreduce.map.memory.mb",
"dependency_type": "mapred-site",
}
},
{
"StackConfigurationDependency": {
"dependency_name": "mapreduce.reduce.memory.mb",
"dependency_type": "mapred-site",
}
},
],
},
{
"StackConfigurations": {
"property_name": "yarn.scheduler.minimum-allocation-vcores",
"type": "yarn-site.xml",
},
"dependencies": [],
},
],
}
],
"changed-configurations": [
{"type": "yarn-site", "name": "yarn.nodemanager.resource.memory-mb"}
],
}
properties_dict = default_stack_advisor.getAffectedConfigs(services)
expected_properties_dict = [
{"name": "yarn.scheduler.maximum-allocation-mb", "type": "yarn-site"},
{"name": "yarn.scheduler.minimum-allocation-mb", "type": "yarn-site"},
{"name": "hive.tez.container.size", "type": "hive-site"},
{"name": "yarn.app.mapreduce.am.resource.mb", "type": "mapred-site"},
{"name": "mapreduce.map.memory.mb", "type": "mapred-site"},
{"name": "mapreduce.reduce.memory.mb", "type": "mapred-site"},
]
self.assertEqual(properties_dict, expected_properties_dict)