'''
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__))
    stack_advisor_path = os.path.join(self.test_directory, '../../main/resources/scripts/stack_advisor.py')
    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.assertEquals(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.assertEquals("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.assertEquals("-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.assertEquals("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"}},
        {"Hosts": {"host_name": "host2"}}
      ]
    }
    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.assertEquals(actualValidateConfigResponse, expectedValidationResponse)
    self.assertEquals(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.assertEquals(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-1",
              "components": []
            },
            {
              "name": "host-group-2",
              "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-1",
                "hosts": [{"fqdn": "host2"}]
              },
              {
                "name": "host-group-2",
                "hosts": [{"fqdn": "host1"}]
              }
            ]
          }
      }
    }
    self.assertEquals(actualRecommendLayoutResponse, expectedRecommendLayoutResponse)
