# (C) Datadog, Inc. 2010-2016
# All rights reserved
# Licensed under Simplified BSD License (see LICENSE)

# stdlib

# 3p
import mock
import json

# project
from tests.checks.common import AgentCheckTest
from checks import AgentCheck, CheckException


def mock__process_and_cache_relation_types(*args):
    return


def mock__process_components(*args):
    return


def mock__process_component_relations(*args):
    return


def mock_collect_components():
    """
    Mock behaviour(response) from ServiceNow API for Components(CIs)
    """
    response = {'result': [{'sys_class_name': 'cmdb_ci_computer', 'sys_id': '00a96c0d3790200044e0bfc8bcbe5db4',
                            'sys_created_on': '2012-02-18 08:14:21', 'name': 'MacBook Pro 15'}]}
    return json.dumps(response)


def mock_relation_types():
    """
    Mock behaviour for relation types
    """
    response = {'result': [{'parent_descriptor': 'Cools', 'sys_id': '53979c53c0a801640116ad2044643fb2'}]}
    return json.dumps(response)


def mock_relation_components():
    """
    Mock response from ServiceNow API for relation between components
    """
    response = {'result': [
        {'type': {'link': 'https://dev60476.service-now.com/api/now/table/cmdb_rel_type/1a9cb166f1571100a92eb60da2bce5c5',
                  'value': '1a9cb166f1571100a92eb60da2bce5c5'},
         'parent': {'link': 'https://dev60476.service-now.com/api/now/table/cmdb_ci/451047c6c0a8016400de0ae6df9b9d76',
                    'value': '451047c6c0a8016400de0ae6df9b9d76'},
         'child': {'link': 'https://dev60476.service-now.com/api/now/table/cmdb_ci/53979c53c0a801640116ad2044643fb2',
                   'value': '53979c53c0a801640116ad2044643fb2'}}
    ]}
    return json.dumps(response)


class InstanceInfo():
    def __init__(self, instance_key, instance_tags, base_url, auth):
        self.instance_key = instance_key
        self.instance_tags = instance_tags
        self.base_url = base_url
        self.auth = auth


instance = {
    'url': "https://dev6047.service-now.com",
    'basic_auth': {'user': 'admin', 'password': '<PASSWORD>'},
    'batch_size': 100
}

CONFIG = {
    'init_config': {'default_timeout': 10, 'min_collection_interval': 5},
    'instances': [
        {
            'url': "https://dev60479.service-now.com",
            'basic_auth': {'user': 'admin', 'password': '<PASSWORD>'},
            'batch_size': 100
        }
    ]
}

instance_config = InstanceInfo({"key": "dummy"}, [], instance.get('url'), ('admin', 'Service@123'))


class TestServicenow(AgentCheckTest):
    """Basic Test for servicenow integration."""
    CHECK_NAME = 'servicenow'
    SERVICE_CHECK_NAME = "servicenow.cmdb.topology_information"

    def test_check(self):
        """
        Testing Servicenow check.
        """

        self.base_url = instance['url']

        self.run_check(CONFIG, mocks={
            '_process_and_cache_relation_types': mock__process_and_cache_relation_types,
            '_process_components': mock__process_components,
            '_process_component_relations': mock__process_component_relations
        })

        instances = self.check.get_topology_instances()
        self.assertEqual(len(instances), 1)
        self.assertEqual(len(instances[0]['components']), 0)
        self.assertEquals(len(instances[0]['relations']), 0)

    def test_collect_components(self):
        """
        Test to raise a check exception when collecting components
        """
        self.load_check(CONFIG)
        self.assertRaises(CheckException, self.check._collect_components, instance_config, 10)

    def test_process_components(self):
        """
        Test _process_components to return topology for components
        """
        self.load_check(CONFIG)
        self.check._collect_components = mock.MagicMock()
        self.check._collect_components.return_value = json.loads(mock_collect_components())
        self.check._process_components(instance_config, 10)
        instances = self.check.get_topology_instances()
        self.assertEqual(len(instances), 1)
        self.assertEqual(instances[0]['components'][0]['type']['name'], 'cmdb_ci_computer')
        self.assertEquals(len(instances[0]['relations']), 0)

    def test_collect_relation_types(self):
        """
        Test to raise a check exception when collecting relation types
        """
        self.load_check(CONFIG)
        self.assertRaises(CheckException, self.check._collect_relation_types, instance_config, 10)

    def test_process_and_cache_relation_types(self):
        """
        Test to collect relation types from ServiceNow API and put in relation_types
        """
        self.load_check(CONFIG)
        self.check._collect_relation_types = mock.MagicMock()
        self.check._collect_relation_types.return_value = json.loads(mock_relation_types())
        out = self.check._process_and_cache_relation_types(instance_config, 10)

        self.assertEqual(len(out), 1)

    def test_collect_component_relations(self):
        """
        Test to raise a check Exception while collecting component relations from ServiceNow API
        """
        self.load_check(CONFIG)
        self.assertRaises(CheckException, self.check._collect_component_relations, instance_config, 10, 0, 100)

    def test_process_component_relations(self):
        """
        Test to collect the component relations and process it as a topology
        """
        self.load_check(CONFIG)
        relation_types = {'1a9cb166f1571100a92eb60da2bce5c5': 'Cools'}
        self.check._collect_component_relations = mock.MagicMock()
        self.check._collect_component_relations.return_value = json.loads(mock_relation_components())
        self.check._process_component_relations(instance_config, 100, 10, relation_types)
        instances = self.check.get_topology_instances()
        self.assertEqual(len(instances), 1)
        self.assertEqual(len(instances[0]['components']), 0)
        self.assertEquals(instances[0]['relations'][0]['type']['name'], 'Cools')

    @mock.patch('check.requests.get')
    def test__get_json(self, mock_req_get):
        """
        Test to check the method _get_json with positive response and get a OK service check
        """
        url = instance.get('url') + "/api/now/table/cmdb_ci"
        auth = (instance.get('basic_auth')['user'], instance.get('basic_auth')['password'])
        self.load_check(instance)
        mock_req_get.return_value = mock.MagicMock(status_code=200, response=json.dumps({'key':'value'}))
        self.check._get_json(url, timeout=10, auth=auth)
        sc = self.check.get_service_checks()
        self.assertEqual(len(sc), 0)

        # Test for Check Exception if response code is not 200
        mock_req_get.return_value = mock.MagicMock(status_code=300, response=json.dumps({'key': 'value'}))
        self.assertRaises(CheckException, self.check._get_json, url, 10, auth)
        sc = self.check.get_service_checks()
        self.assertEqual(len(sc), 1)
        self.assertEqual(sc[0]['check'], self.SERVICE_CHECK_NAME)
        self.assertEqual(sc[0]['status'], AgentCheck.CRITICAL)

# (C) Datadog, Inc. 2010-2016
# All rights reserved
# Licensed under Simplified BSD License (see LICENSE)

# stdlib

# 3p
import mock
import json

# project
from tests.checks.common import AgentCheckTest
from checks import AgentCheck, CheckException


def mock__process_and_cache_relation_types(*args):
    return


def mock__process_components(*args):
    return


def mock__process_component_relations(*args):
    return


def mock_collect_components():
    """
    Mock behaviour(response) from ServiceNow API for Components(CIs)
    """
    response = {'result': [{'sys_class_name': 'cmdb_ci_computer', 'sys_id': '00a96c0d3790200044e0bfc8bcbe5db4',
                            'sys_created_on': '2012-02-18 08:14:21', 'name': 'MacBook Pro 15'}]}
    return json.dumps(response)


def mock_relation_types():
    """
    Mock behaviour for relation types
    """
    response = {'result': [{'parent_descriptor': 'Cools', 'sys_id': '53979c53c0a801640116ad2044643fb2'}]}
    return json.dumps(response)


def mock_relation_components():
    """
    Mock response from ServiceNow API for relation between components
    """
    response = {'result': [
        {'type': {'link': 'https://dev60476.service-now.com/api/now/table/cmdb_rel_type/1a9cb166f1571100a92eb60da2bce5c5',
                  'value': '1a9cb166f1571100a92eb60da2bce5c5'},
         'parent': {'link': 'https://dev60476.service-now.com/api/now/table/cmdb_ci/451047c6c0a8016400de0ae6df9b9d76',
                    'value': '451047c6c0a8016400de0ae6df9b9d76'},
         'child': {'link': 'https://dev60476.service-now.com/api/now/table/cmdb_ci/53979c53c0a801640116ad2044643fb2',
                   'value': '53979c53c0a801640116ad2044643fb2'}}
    ]}
    return json.dumps(response)


class InstanceInfo():
    def __init__(self, instance_key, instance_tags, base_url, auth):
        self.instance_key = instance_key
        self.instance_tags = instance_tags
        self.base_url = base_url
        self.auth = auth


instance = {
    'url': "https://dev6047.service-now.com",
    'basic_auth': {'user': 'admin', 'password': '<PASSWORD>'},
    'batch_size': 100
}

CONFIG = {
    'init_config': {'default_timeout': 10, 'min_collection_interval': 5},
    'instances': [
        {
            'url': "https://dev60479.service-now.com",
            'basic_auth': {'user': 'admin', 'password': '<PASSWORD>'},
            'batch_size': 100
        }
    ]
}

instance_config = InstanceInfo({"key": "dummy"}, [], instance.get('url'), ('admin', 'Service@123'))


class TestServicenow(AgentCheckTest):
    """Basic Test for servicenow integration."""
    CHECK_NAME = 'servicenow'
    SERVICE_CHECK_NAME = "servicenow.cmdb.topology_information"

    def test_check(self):
        """
        Testing Servicenow check.
        """

        self.base_url = instance['url']

        self.run_check(CONFIG, mocks={
            '_process_and_cache_relation_types': mock__process_and_cache_relation_types,
            '_process_components': mock__process_components,
            '_process_component_relations': mock__process_component_relations
        })

        instances = self.check.get_topology_instances()
        self.assertEqual(len(instances), 1)
        self.assertEqual(len(instances[0]['components']), 0)
        self.assertEquals(len(instances[0]['relations']), 0)

    def test_collect_components(self):
        """
        Test to raise a check exception when collecting components
        """
        self.load_check(CONFIG)
        self.assertRaises(CheckException, self.check._collect_components, instance_config, 10)

    def test_process_components(self):
        """
        Test _process_components to return topology for components
        """
        self.load_check(CONFIG)
        self.check._collect_components = mock.MagicMock()
        self.check._collect_components.return_value = json.loads(mock_collect_components())
        self.check._process_components(instance_config, 10)
        instances = self.check.get_topology_instances()
        self.assertEqual(len(instances), 1)
        self.assertEqual(instances[0]['components'][0]['type']['name'], 'cmdb_ci_computer')
        self.assertEquals(len(instances[0]['relations']), 0)

    def test_collect_relation_types(self):
        """
        Test to raise a check exception when collecting relation types
        """
        self.load_check(CONFIG)
        self.assertRaises(CheckException, self.check._collect_relation_types, instance_config, 10)

    def test_process_and_cache_relation_types(self):
        """
        Test to collect relation types from ServiceNow API and put in relation_types
        """
        self.load_check(CONFIG)
        self.check._collect_relation_types = mock.MagicMock()
        self.check._collect_relation_types.return_value = json.loads(mock_relation_types())
        out = self.check._process_and_cache_relation_types(instance_config, 10)

        self.assertEqual(len(out), 1)

    def test_collect_component_relations(self):
        """
        Test to raise a check Exception while collecting component relations from ServiceNow API
        """
        self.load_check(CONFIG)
        self.assertRaises(CheckException, self.check._collect_component_relations, instance_config, 10, 0, 100)

    def test_process_component_relations(self):
        """
        Test to collect the component relations and process it as a topology
        """
        self.load_check(CONFIG)
        relation_types = {'1a9cb166f1571100a92eb60da2bce5c5': 'Cools'}
        self.check._collect_component_relations = mock.MagicMock()
        self.check._collect_component_relations.return_value = json.loads(mock_relation_components())
        self.check._process_component_relations(instance_config, 100, 10, relation_types)
        instances = self.check.get_topology_instances()
        self.assertEqual(len(instances), 1)
        self.assertEqual(len(instances[0]['components']), 0)
        self.assertEquals(instances[0]['relations'][0]['type']['name'], 'Cools')

    @mock.patch('check.requests.get')
    def test__get_json(self, mock_req_get):
        """
        Test to check the method _get_json with positive response and get a OK service check
        """
        url = instance.get('url') + "/api/now/table/cmdb_ci"
        auth = (instance.get('basic_auth')['user'], instance.get('basic_auth')['password'])
        self.load_check(instance)
        mock_req_get.return_value = mock.MagicMock(status_code=200, response=json.dumps({'key':'value'}))
        self.check._get_json(url, timeout=10, auth=auth)
        sc = self.check.get_service_checks()
        self.assertEqual(len(sc), 0)

        # Test for Check Exception if response code is not 200
        mock_req_get.return_value = mock.MagicMock(status_code=300, response=json.dumps({'key': 'value'}))
        self.assertRaises(CheckException, self.check._get_json, url, 10, auth)
        sc = self.check.get_service_checks()
        self.assertEqual(len(sc), 1)
        self.assertEqual(sc[0]['check'], self.SERVICE_CHECK_NAME)
        self.assertEqual(sc[0]['status'], AgentCheck.CRITICAL)

# (C) Datadog, Inc. 2010-2016 # All rights reserved # Licensed under Simplified BSD License (see LICENSE) # stdlib # 3p # project Mock behaviour(response) from ServiceNow API for Components(CIs) Mock behaviour for relation types Mock response from ServiceNow API for relation between components Basic Test for servicenow integration. Testing Servicenow check. Test to raise a check exception when collecting components Test _process_components to return topology for components Test to raise a check exception when collecting relation types Test to collect relation types from ServiceNow API and put in relation_types Test to raise a check Exception while collecting component relations from ServiceNow API Test to collect the component relations and process it as a topology Test to check the method _get_json with positive response and get a OK service check # Test for Check Exception if response code is not 200