Esempio n. 1
0
def test_config(test_case, extra_config, expected_http_kwargs, mocker):
    instance = extra_config
    check = ConsulCheck(common.CHECK_NAME, {}, instances=[instance])
    mocker.patch("datadog_checks.base.utils.serialization.json.loads")

    with mock.patch('datadog_checks.base.utils.http.requests') as r:
        r.get.return_value = mock.MagicMock(status_code=200)

        check.check(None)

        http_wargs = dict(
            auth=mock.ANY,
            cert=mock.ANY,
            headers=mock.ANY,
            proxies=mock.ANY,
            timeout=mock.ANY,
            verify=mock.ANY,
            allow_redirects=mock.ANY,
        )
        http_wargs.update(expected_http_kwargs)
        r.get.assert_called_with('/v1/status/leader', **http_wargs)
Esempio n. 2
0
def test_prometheus_endpoint(aggregator, dd_environment, instance_prometheus,
                             caplog):
    consul_check = ConsulCheck(common.CHECK_NAME, {}, [instance_prometheus])
    common_tags = instance_prometheus['tags']

    if common.PROMETHEUS_ENDPOINT_AVAILABLE:
        consul_check.check(instance_prometheus)

        aggregator.assert_service_check(
            'consul.prometheus.health',
            tags=common_tags + [
                'endpoint:{}/v1/agent/metrics?format=prometheus'.format(
                    common.URL)
            ],
        )

        for metric in common.PROMETHEUS_METRICS:
            aggregator.assert_metric(metric, tags=common_tags, count=1)

        aggregator.assert_metric('consul.peers', value=3, count=1)

        aggregator.assert_all_metrics_covered()

    else:
        caplog.at_level(logging.WARNING)
        consul_check.check(instance_prometheus)

        assert (
            "does not support the prometheus endpoint. "
            "Update Consul or set back `use_prometheus_endpoint` to false to remove this warning."
            in caplog.text)
Esempio n. 3
0
def test_get_nodes_with_service_warning(aggregator):
    consul_check = ConsulCheck(common.CHECK_NAME, {}, [{}])
    my_mocks = consul_mocks._get_consul_mocks()
    my_mocks[
        'get_nodes_with_service'] = consul_mocks.mock_get_nodes_with_service_warning
    consul_mocks.mock_check(consul_check, my_mocks)
    consul_check.check(consul_mocks.MOCK_CONFIG)

    expected_tags = [
        'consul_datacenter:dc1',
        'consul_service_id:service-1',
        'consul_service-1_service_tag:az-us-east-1a',
        'consul_service:az-us-east-1a',
    ]
    aggregator.assert_metric('consul.catalog.nodes_up',
                             value=1,
                             tags=expected_tags)
    aggregator.assert_metric('consul.catalog.nodes_passing',
                             value=0,
                             tags=expected_tags)
    aggregator.assert_metric('consul.catalog.nodes_warning',
                             value=1,
                             tags=expected_tags)
    aggregator.assert_metric('consul.catalog.nodes_critical',
                             value=0,
                             tags=expected_tags)

    expected_tags = ['consul_datacenter:dc1', 'consul_node_id:node-1']
    aggregator.assert_metric('consul.catalog.services_up',
                             value=6,
                             tags=expected_tags)
    aggregator.assert_metric('consul.catalog.services_passing',
                             value=0,
                             tags=expected_tags)
    aggregator.assert_metric('consul.catalog.services_warning',
                             value=6,
                             tags=expected_tags)
    aggregator.assert_metric('consul.catalog.services_critical',
                             value=0,
                             tags=expected_tags)
Esempio n. 4
0
def test_service_checks_disable_service_tag(aggregator):
    consul_check = ConsulCheck(common.CHECK_NAME, {}, [consul_mocks.MOCK_CONFIG_DISABLE_SERVICE_TAG])
    my_mocks = consul_mocks._get_consul_mocks()
    my_mocks['consul_request'] = consul_mocks.mock_get_health_check
    consul_mocks.mock_check(consul_check, my_mocks)
    consul_check.check(None)

    expected_tags = [
        'consul_datacenter:dc1',
        'check:server-loadbalancer',
        'consul_service_id:server-loadbalancer',
        'consul_service:server-loadbalancer',
    ]
    aggregator.assert_service_check('consul.check', status=ConsulCheck.CRITICAL, tags=expected_tags, count=1)

    expected_tags = [
        'consul_datacenter:dc1',
        'check:server-api',
        'consul_service_id:server-loadbalancer',
        'consul_service:server-loadbalancer',
    ]
    aggregator.assert_service_check('consul.check', status=ConsulCheck.OK, tags=expected_tags, count=1)

    expected_tags = ['consul_datacenter:dc1', 'check:server-api', 'consul_service:server-loadbalancer']
    aggregator.assert_service_check('consul.check', status=ConsulCheck.OK, tags=expected_tags, count=1)

    expected_tags = ['consul_datacenter:dc1', 'check:server-api', 'consul_service_id:server-loadbalancer']
    aggregator.assert_service_check('consul.check', status=ConsulCheck.OK, tags=expected_tags, count=1)

    expected_tags = [
        'consul_datacenter:dc1',
        'check:server-status-empty',
        'consul_service_id:server-empty',
        'consul_service:server-empty',
    ]
    aggregator.assert_service_check('consul.check', status=ConsulCheck.UNKNOWN, tags=expected_tags, count=1)

    aggregator.assert_service_check('consul.check', count=5)
Esempio n. 5
0
def test_service_checks(aggregator):
    consul_check = ConsulCheck(common.CHECK_NAME, {}, [{}])
    my_mocks = consul_mocks._get_consul_mocks()
    my_mocks['consul_request'] = consul_mocks.mock_get_health_check
    consul_mocks.mock_check(consul_check, my_mocks)
    consul_check.check(consul_mocks.MOCK_CONFIG)

    expected_tags = [
        "consul_datacenter:dc1",
        "check:server-loadbalancer",
        "consul_service_id:server-loadbalancer",
        "service:server-loadbalancer",
    ]
    aggregator.assert_service_check('consul.check', status=ConsulCheck.CRITICAL, tags=expected_tags, count=1)

    expected_tags = [
        "consul_datacenter:dc1",
        "check:server-api",
        "consul_service_id:server-loadbalancer",
        "service:server-loadbalancer",
    ]
    aggregator.assert_service_check('consul.check', status=ConsulCheck.OK, tags=expected_tags, count=1)

    expected_tags = ["consul_datacenter:dc1", "check:server-api", "service:server-loadbalancer"]
    aggregator.assert_service_check('consul.check', status=ConsulCheck.OK, tags=expected_tags, count=1)

    expected_tags = ["consul_datacenter:dc1", "check:server-api", "consul_service_id:server-loadbalancer"]
    aggregator.assert_service_check('consul.check', status=ConsulCheck.OK, tags=expected_tags, count=1)

    expected_tags = [
        "consul_datacenter:dc1",
        "check:server-status-empty",
        "consul_service_id:server-empty",
        "service:server-empty",
    ]
    aggregator.assert_service_check('consul.check', status=ConsulCheck.UNKNOWN, tags=expected_tags, count=1)

    aggregator.assert_service_check('consul.check', count=5)
Esempio n. 6
0
def test_get_nodes_with_service_warning(aggregator):
    consul_check = ConsulCheck(common.CHECK_NAME, {}, [consul_mocks.MOCK_CONFIG])
    my_mocks = consul_mocks._get_consul_mocks()
    my_mocks['get_nodes_with_service'] = consul_mocks.mock_get_nodes_with_service_warning
    consul_mocks.mock_check(consul_check, my_mocks)
    consul_check.check(None)

    expected_tags = [
        'consul_datacenter:dc1',
        'consul_service_id:service-1',
        'consul_service-1_service_tag:active',
        'consul_service-1_service_tag:standby',
        'consul_service_tag:active',
        'consul_service_tag:standby',
    ]
    aggregator.assert_metric('consul.catalog.nodes_up', value=4, tags=expected_tags)
    aggregator.assert_metric('consul.catalog.nodes_passing', value=0, tags=expected_tags)
    aggregator.assert_metric('consul.catalog.nodes_warning', value=4, tags=expected_tags)
    aggregator.assert_metric('consul.catalog.nodes_critical', value=0, tags=expected_tags)

    expected_tags = ['consul_datacenter:dc1', 'consul_node_id:node-1']
    aggregator.assert_metric('consul.catalog.services_up', value=24, tags=expected_tags)
    aggregator.assert_metric('consul.catalog.services_passing', value=0, tags=expected_tags)
    aggregator.assert_metric('consul.catalog.services_warning', value=24, tags=expected_tags)
    aggregator.assert_metric('consul.catalog.services_critical', value=0, tags=expected_tags)

    expected_tags = [
        'consul_datacenter:dc1',
        'consul_service-1_service_tag:standby',
        'consul_service_id:service-1',
        'consul_node_id:node-1',
        'consul_status:warning',
    ]
    aggregator.assert_metric('consul.catalog.services_count', value=3, tags=expected_tags)
    expected_tags.append('consul_service-1_service_tag:active')
    aggregator.assert_metric('consul.catalog.services_count', value=1, tags=expected_tags)
Esempio n. 7
0
def test_prometheus_endpoint(aggregator, dd_environment, instance_prometheus,
                             caplog):
    consul_check = ConsulCheck(common.CHECK_NAME, {}, [instance_prometheus])
    common_tags = instance_prometheus['tags']

    if common.PROMETHEUS_ENDPOINT_AVAILABLE:
        consul_check.check(instance_prometheus)

        aggregator.assert_service_check(
            'consul.prometheus.health',
            tags=common_tags + [
                'endpoint:{}/v1/agent/metrics?format=prometheus'.format(
                    common.URL)
            ],
        )

        for metric in common.PROMETHEUS_METRICS:
            aggregator.assert_metric(metric, tags=common_tags, count=1)

        aggregator.assert_metric('consul.peers', value=3, count=1)
        aggregator.assert_metric_has_tag_prefix(
            'consul.raft.replication.appendEntries.logs', 'peer_id', count=2)

        for hist_suffix in ['count', 'sum', 'quantile']:
            aggregator.assert_metric_has_tag(
                'consul.http.request.{}'.format(hist_suffix),
                'method:GET',
                at_least=0)
            for metric in common.PROMETHEUS_HIST_METRICS:
                for tag in common_tags:
                    aggregator.assert_metric_has_tag(metric + hist_suffix,
                                                     tag,
                                                     at_least=1)

        aggregator.assert_all_metrics_covered()

        # Some of the metrics documented in the metadata.csv were sent through DogStatsD as `timer` as well.
        # We end up with some of the prometheus metrics having a different in-app type.
        # Example with `consul.raft.commitTime.count`:
        #  * It is a rate when submitting metrics with DogStatsD
        #  * It is a rate when submitting metrics with OpenMetricsBaseCheck
        # TODO: solve conflict
        # aggregator.assert_metrics_using_metadata(get_metadata_metrics(), check_submission_type=True)

    else:
        caplog.at_level(logging.WARNING)
        consul_check.check(instance_prometheus)

        assert (
            "does not support the prometheus endpoint. "
            "Update Consul or set back `use_prometheus_endpoint` to false to remove this warning."
            in caplog.text)
Esempio n. 8
0
def test_get_peers_in_cluster(aggregator):
    my_mocks = consul_mocks._get_consul_mocks()
    consul_check = ConsulCheck(common.CHECK_NAME, {}, [consul_mocks.MOCK_CONFIG])
    consul_mocks.mock_check(consul_check, my_mocks)
    consul_check.check(None)

    # When node is leader
    aggregator.assert_metric('consul.peers', value=3, tags=['consul_datacenter:dc1', 'mode:leader'])

    my_mocks['_get_cluster_leader'] = consul_mocks.mock_get_cluster_leader_B
    consul_mocks.mock_check(consul_check, my_mocks)
    consul_check.check(None)

    aggregator.assert_metric('consul.peers', value=3, tags=['consul_datacenter:dc1', 'mode:follower'])
Esempio n. 9
0
def test_consul_request(aggregator, instance):
    consul_check = ConsulCheck(common.CHECK_NAME, {}, [consul_mocks.MOCK_CONFIG])
    with mock.patch("datadog_checks.consul.consul.requests.get") as mock_requests_get:
        consul_check.consul_request("foo")
        url = "{}/{}".format(instance["url"], "foo")
        aggregator.assert_service_check("consul.can_connect", ConsulCheck.OK, tags=["url:{}".format(url)], count=1)

        aggregator.reset()
        mock_requests_get.side_effect = Exception("message")
        with pytest.raises(Exception):
            consul_check.consul_request("foo")
        aggregator.assert_service_check(
            "consul.can_connect",
            ConsulCheck.CRITICAL,
            tags=["url:{}".format(url)],
            count=1,
            message="Consul request to {} failed: message".format(url),
        )
Esempio n. 10
0
def test_prometheus_endpoint(aggregator, dd_environment, instance_prometheus,
                             caplog):
    consul_check = ConsulCheck(common.CHECK_NAME, {}, [instance_prometheus])
    common_tags = instance_prometheus['tags']

    if common.PROMETHEUS_ENDPOINT_AVAILABLE:
        consul_check.check(instance_prometheus)

        aggregator.assert_service_check(
            'consul.prometheus.health',
            tags=common_tags + [
                'endpoint:{}/v1/agent/metrics?format=prometheus'.format(
                    common.URL)
            ],
        )

        for metric in common.PROMETHEUS_METRICS:
            aggregator.assert_metric(metric, tags=common_tags, count=1)

        aggregator.assert_metric('consul.peers', value=3, count=1)
        aggregator.assert_metric_has_tag_prefix(
            'consul.raft.replication.appendEntries.logs', 'peer_id', count=2)

        for hist_suffix in ['count', 'sum', 'quantile']:
            aggregator.assert_metric_has_tag(
                'consul.http.request.{}'.format(hist_suffix),
                'method:GET',
                at_least=0)
            for metric in common.PROMETHEUS_HIST_METRICS:
                for tag in common_tags:
                    aggregator.assert_metric_has_tag(metric + hist_suffix,
                                                     tag,
                                                     at_least=1)

        aggregator.assert_all_metrics_covered()

    else:
        caplog.at_level(logging.WARNING)
        consul_check.check(instance_prometheus)

        assert (
            "does not support the prometheus endpoint. "
            "Update Consul or set back `use_prometheus_endpoint` to false to remove this warning."
            in caplog.text)
Esempio n. 11
0
def test_self_leader_event(aggregator):
    consul_check = ConsulCheck(common.CHECK_NAME, {},
                               [consul_mocks.MOCK_CONFIG_SELF_LEADER_CHECK])
    my_mocks = consul_mocks._get_consul_mocks()

    consul_check._last_known_leader = 'My Old Leader'

    our_url = consul_mocks.mock_get_cluster_leader_A()
    other_url = consul_mocks.mock_get_cluster_leader_B()

    # We become the leader
    my_mocks['_get_cluster_leader'] = consul_mocks.mock_get_cluster_leader_A
    consul_mocks.mock_check(consul_check, my_mocks)
    consul_check.check(None)
    assert len(aggregator.events) == 1
    assert our_url == consul_check._last_known_leader
    event = aggregator.events[0]
    assert event['event_type'] == 'consul.new_leader'
    assert 'prev_consul_leader:My Old Leader' in event['tags']
    assert 'curr_consul_leader:{}'.format(our_url) in event['tags']

    # We are already the leader, no new events
    aggregator.reset()
    consul_check.check(None)
    assert len(aggregator.events) == 0

    # We lose the leader, no new events
    my_mocks['_get_cluster_leader'] = consul_mocks.mock_get_cluster_leader_B
    consul_mocks.mock_check(consul_check, my_mocks)
    aggregator.reset()
    consul_check.check(None)
    assert len(aggregator.events) == 0
    assert other_url == consul_check._last_known_leader

    # We regain the leadership
    my_mocks['_get_cluster_leader'] = consul_mocks.mock_get_cluster_leader_A
    consul_mocks.mock_check(consul_check, my_mocks)
    aggregator.reset()
    consul_check.check(None)
    assert len(aggregator.events) == 1
    assert our_url == consul_check._last_known_leader
    event = aggregator.events[0]
    assert event['event_type'] == 'consul.new_leader'
    assert 'prev_consul_leader:{}'.format(other_url) in event['tags']
    assert 'curr_consul_leader:{}'.format(our_url) in event['tags']
Esempio n. 12
0
def test_cull_services_list():
    consul_check = ConsulCheck(common.CHECK_NAME, {},
                               [consul_mocks.MOCK_CONFIG_LEADER_CHECK])
    my_mocks = consul_mocks._get_consul_mocks()
    consul_mocks.mock_check(consul_check, my_mocks)

    # Pad num_services to kick in truncation logic
    num_services = MAX_SERVICES + 20

    # Max services parameter (from consul.yaml) set to be bigger than MAX_SERVICES and smaller than total of services
    max_services = num_services - 10

    # Big include list
    services = consul_mocks.mock_get_n_services_in_cluster(num_services)
    consul_check.services_include = [
        'service_{}'.format(k) for k in range(num_services)
    ]
    assert len(consul_check._cull_services_list(services)) == MAX_SERVICES

    # Big include list with max_services
    consul_check.max_services = max_services
    assert len(consul_check._cull_services_list(services)) == max_services

    # include list < MAX_SERVICES should spit out the include list
    consul_check.services_include = [
        'service_{}'.format(k) for k in range(MAX_SERVICES - 1)
    ]
    assert set(consul_check._cull_services_list(services)) == set(
        consul_check.services_include)

    # include list < max_services param should spit out the include list
    consul_check.services_include = [
        'service_{}'.format(k) for k in range(max_services - 1)
    ]
    assert set(consul_check._cull_services_list(services)) == set(
        consul_check.services_include)

    # No include list, still triggers truncation
    consul_check.services_include = []
    consul_check.max_services = MAX_SERVICES
    assert len(consul_check._cull_services_list(services)) == MAX_SERVICES

    # No include list with max_services set, also triggers truncation
    consul_check.services_include = []
    consul_check.max_services = max_services
    assert len(consul_check._cull_services_list(services)) == max_services

    # Num. services < MAX_SERVICES should be no-op in absence of include list
    num_services = MAX_SERVICES - 1
    services = consul_mocks.mock_get_n_services_in_cluster(num_services)
    assert len(consul_check._cull_services_list(services)) == num_services

    # Num. services < MAX_SERVICES should spit out only the include list when one is defined
    consul_check.services_include = ['service_1', 'service_2', 'service_3']
    assert set(consul_check._cull_services_list(services)) == set(
        consul_check.services_include)

    # Num. services < max_services (from consul.yaml) should be no-op in absence of include list
    num_services = max_services - 1
    consul_check.services_include = []
    services = consul_mocks.mock_get_n_services_in_cluster(num_services)
    assert len(consul_check._cull_services_list(services)) == num_services

    # Num. services < max_services should spit out only the include list when one is defined
    consul_check.services_include = ['service_1', 'service_2', 'service_3']
    assert set(consul_check._cull_services_list(services)) == set(
        consul_check.services_include)

    # Excluded services will not be in final service list
    consul_check.services_exclude = ['service_1', 'service_2', 'service_3']
    assert set(consul_check.services_exclude) not in set(
        consul_check._cull_services_list(services))

    # Excluded services will be prioritized over include list services
    consul_check.services_exclude = ['service_1', 'service_2', 'service_3']
    consul_check.services_include = ['service_4', 'service_5', 'service_6']
    test_include_length = len(consul_check.services_include)
    test_service_list_length = len(
        set(consul_check._cull_services_list(services)))
    assert (set(consul_check.services_exclude) not in set(
        consul_check._cull_services_list(services))
            and test_service_list_length > test_include_length)

    # Use of services exclude will still trigger truncation logic
    services = consul_mocks.mock_get_n_services_in_cluster(num_services)
    consul_check.services_exclude = ['service_1', 'service_2', 'service_3']
    consul_check.max_services = MAX_SERVICES
    assert len(consul_check._cull_services_list(
        services)) == consul_check.max_services

    # Num. services < MAX_SERVICES (from consul.yaml) should be no-op in absence of services exclude
    num_services = MAX_SERVICES + 1
    consul_check.services_exclude = []
    services = consul_mocks.mock_get_n_services_in_cluster(num_services)
    assert len(consul_check._cull_services_list(services)) == MAX_SERVICES
Esempio n. 13
0
def test_cull_services_list():
    consul_check = ConsulCheck(common.CHECK_NAME, {},
                               [consul_mocks.MOCK_CONFIG_LEADER_CHECK])
    my_mocks = consul_mocks._get_consul_mocks()
    consul_mocks.mock_check(consul_check, my_mocks)

    # Pad num_services to kick in truncation logic
    num_services = MAX_SERVICES + 20

    # Max services parameter (from consul.yaml) set to be bigger than MAX_SERVICES and smaller than total of services
    max_services = num_services - 10

    # Big whitelist
    services = consul_mocks.mock_get_n_services_in_cluster(num_services)
    consul_check.service_whitelist = [
        'service_{}'.format(k) for k in range(num_services)
    ]
    assert len(consul_check._cull_services_list(services)) == MAX_SERVICES

    # Big whitelist with max_services
    consul_check.max_services = max_services
    assert len(consul_check._cull_services_list(services)) == max_services

    # Whitelist < MAX_SERVICES should spit out the whitelist
    consul_check.service_whitelist = [
        'service_{}'.format(k) for k in range(MAX_SERVICES - 1)
    ]
    assert set(consul_check._cull_services_list(services)) == set(
        consul_check.service_whitelist)

    # Whitelist < max_services param should spit out the whitelist
    consul_check.service_whitelist = [
        'service_{}'.format(k) for k in range(max_services - 1)
    ]
    assert set(consul_check._cull_services_list(services)) == set(
        consul_check.service_whitelist)

    # No whitelist, still triggers truncation
    consul_check.service_whitelist = []
    consul_check.max_services = MAX_SERVICES
    assert len(consul_check._cull_services_list(services)) == MAX_SERVICES

    # No whitelist with max_services set, also triggers truncation
    consul_check.service_whitelist = []
    consul_check.max_services = max_services
    assert len(consul_check._cull_services_list(services)) == max_services

    # Num. services < MAX_SERVICES should be no-op in absence of whitelist
    num_services = MAX_SERVICES - 1
    services = consul_mocks.mock_get_n_services_in_cluster(num_services)
    assert len(consul_check._cull_services_list(services, )) == num_services

    # Num. services < MAX_SERVICES should spit out only the whitelist when one is defined
    consul_check.service_whitelist = ['service_1', 'service_2', 'service_3']
    assert set(consul_check._cull_services_list(services)) == set(
        consul_check.service_whitelist)

    # Num. services < max_services (from consul.yaml) should be no-op in absence of whitelist
    num_services = max_services - 1
    consul_check.service_whitelist = []
    services = consul_mocks.mock_get_n_services_in_cluster(num_services)
    assert len(consul_check._cull_services_list(services)) == num_services

    # Num. services < max_services should spit out only the whitelist when one is defined
    consul_check.service_whitelist = ['service_1', 'service_2', 'service_3']
    assert set(consul_check._cull_services_list(services)) == set(
        consul_check.service_whitelist)