|
1 | 1 | # (C) Datadog, Inc. 2022-present |
2 | 2 | # All rights reserved |
3 | 3 | # Licensed under a 3-clause BSD style license (see LICENSE) |
| 4 | +import os |
| 5 | + |
4 | 6 | from datadog_checks.ibm_ace.check import IbmAceCheck |
| 7 | +from datadog_checks.ibm_ace.resources import get_resource |
5 | 8 | from datadog_checks.ibm_ace.subscription import FlowMonitoringSubscription, ResourceStatisticsSubscription |
6 | 9 |
|
| 10 | +from .common import HERE |
| 11 | + |
7 | 12 |
|
8 | 13 | def test_flow_monitoring_subscription(instance, global_tags): |
9 | 14 | check = IbmAceCheck('ibm_ace', {}, [instance]) |
@@ -118,3 +123,82 @@ def test_non_truncation_error_given_connection_broken_returns_critical(instance, |
118 | 123 | sc_calls = [c for c in check.service_check.call_args_list if c[0][0] == 'mq.subscription'] |
119 | 124 | assert len(sc_calls) == 1 |
120 | 125 | assert sc_calls[0][0][1] == ServiceCheck.CRITICAL |
| 126 | + |
| 127 | + |
| 128 | +def test_parse_tags_with_name(): |
| 129 | + resource = get_resource('JDBCConnectionPools') |
| 130 | + metric_data = {'name': 'MyDataSource', 'NameOfJDBCProvider': 'Oracle'} |
| 131 | + |
| 132 | + tags = resource.parse_tags(['mq_server:x'], metric_data) |
| 133 | + |
| 134 | + assert tags == ['group:MyDataSource', 'mq_server:x', 'jdbc_provider:Oracle'] |
| 135 | + |
| 136 | + |
| 137 | +def test_parse_tags_without_name(): |
| 138 | + # ACE can omit `name`; this must not raise. |
| 139 | + resource = get_resource('JDBCConnectionPools') |
| 140 | + metric_data = {'NameOfJDBCProvider': 'Oracle'} |
| 141 | + |
| 142 | + tags = resource.parse_tags(['mq_server:x'], metric_data) |
| 143 | + |
| 144 | + assert tags == ['mq_server:x', 'jdbc_provider:Oracle'] |
| 145 | + |
| 146 | + |
| 147 | +def test_collect_survives_malformed_resource_identifier(instance, global_tags, caplog): |
| 148 | + # ACE 12.0.9 payload where repeated `resourceIdentifier` entries |
| 149 | + # have their `name` key replaced with an empty string. Must not crash. |
| 150 | + import logging |
| 151 | + from unittest.mock import MagicMock, PropertyMock, patch |
| 152 | + |
| 153 | + caplog.set_level(logging.DEBUG) |
| 154 | + |
| 155 | + fixture_path = os.path.join(HERE, 'fixtures', 'resource_statistics_malformed_jdbc.json') |
| 156 | + with open(fixture_path, 'rb') as f: |
| 157 | + payload = f.read() |
| 158 | + |
| 159 | + mock_config = MagicMock() |
| 160 | + mock_config.max_message_length = 65536 |
| 161 | + |
| 162 | + check = IbmAceCheck('ibm_ace', {}, [instance]) |
| 163 | + check.gauge = MagicMock() |
| 164 | + check.count = MagicMock() |
| 165 | + check.service_check = MagicMock() |
| 166 | + |
| 167 | + sub = ResourceStatisticsSubscription(check, global_tags) |
| 168 | + |
| 169 | + mock_sub = MagicMock() |
| 170 | + mock_sub.get.side_effect = [payload] |
| 171 | + |
| 172 | + with ( |
| 173 | + patch.object(type(check), 'config', new_callable=PropertyMock, return_value=mock_config), |
| 174 | + patch.object(type(sub), 'sub', new_callable=PropertyMock, return_value=mock_sub), |
| 175 | + patch.object(sub, '_get_elapsed_time', return_value=25), |
| 176 | + ): |
| 177 | + sub.collect() # must not raise |
| 178 | + |
| 179 | + submitted = check.count.call_args_list + check.gauge.call_args_list |
| 180 | + submitted_metrics = {c.args[0] for c in submitted} |
| 181 | + |
| 182 | + # `self.check.count`/`.gauge` are mocked directly, so the `ibm_ace.` namespace |
| 183 | + # prefix (normally applied inside AgentCheck.count/gauge) isn't present here. |
| 184 | + assert 'JDBCConnectionPools.CumulativeRequests' in submitted_metrics |
| 185 | + # The malformed entries' empty-string key must never become a metric name. |
| 186 | + assert not any(c.args[0].endswith('.') for c in submitted) |
| 187 | + |
| 188 | + # The well-formed entry still gets its `group` tag; the malformed ones don't. |
| 189 | + well_formed_call = next( |
| 190 | + c for c in submitted if 'jdbc_provider:jdbc_DataSourceA' in c.kwargs['tags'] and c.args[1] == 891 |
| 191 | + ) |
| 192 | + assert any(tag.startswith('group:') for tag in well_formed_call.kwargs['tags']) |
| 193 | + |
| 194 | + malformed_calls = [c for c in submitted if 'jdbc_provider:jdbc_DataSourceB' in c.kwargs['tags']] |
| 195 | + assert malformed_calls |
| 196 | + assert not any(tag.startswith('group:') for c in malformed_calls for tag in c.kwargs['tags']) |
| 197 | + |
| 198 | + # The fixture has two malformed entries; each is logged at debug level when skipped. |
| 199 | + skip_lines = [r for r in caplog.records if 'Skipping resourceIdentifier entry with malformed key' in r.message] |
| 200 | + assert len(skip_lines) == 2 |
| 201 | + for record in skip_lines: |
| 202 | + assert record.levelname == 'DEBUG' |
| 203 | + assert 'JDBCConnectionPools' in record.message |
| 204 | + assert "value='summary0'" in record.message |
0 commit comments