33# Licensed under a 3-clause BSD style license (see LICENSE)
44from unittest import mock
55
6+ import pytest
7+
68from datadog_checks .base .checks .db import DatabaseCheck
79from datadog_checks .base .stubs .datadog_agent import datadog_agent
810
@@ -12,18 +14,10 @@ class FakeDatabaseCheck(DatabaseCheck):
1214 def reported_hostname (self ):
1315 return None
1416
15- @property
16- def database_identifier (self ):
17- return "test-db"
18-
1917 @property
2018 def dbms_version (self ):
2119 return "1.0.0"
2220
23- @property
24- def tags (self ):
25- return []
26-
2721 @property
2822 def cloud_metadata (self ):
2923 return {}
@@ -36,3 +30,62 @@ def test_agent_hostname_resolves_once_and_caches():
3630 assert check .agent_hostname == "my-agent-host"
3731 assert check .agent_hostname == "my-agent-host"
3832 assert get_hostname .call_count == 1
33+
34+
35+ @pytest .mark .parametrize (
36+ ("tags" , "template" , "connection_params" , "expected" ),
37+ [
38+ pytest .param ([], "$resolved_hostname" , {"resolved_hostname" : "my-host" }, "my-host" , id = "connection_params" ),
39+ pytest .param (["env:prod" ], "$env" , None , "prod" , id = "substitutes_tags" ),
40+ # Tags are sorted before merging, so the result is deterministic regardless of input order.
41+ pytest .param (["team:b" , "team:a" ], "$team" , None , "a,b" , id = "merges_duplicate_keys_sorted" ),
42+ pytest .param (["host:tag-host" ], "$host" , {"host" : "conn-host" }, "conn-host" , id = "connection_params_override" ),
43+ # Tags without a ':' are not exposed as template variables.
44+ pytest .param (["keyless" ], "$keyless" , None , "$keyless" , id = "ignores_keyless_tags" ),
45+ pytest .param ([], "$missing" , None , "$missing" , id = "unknown_variables_intact" ),
46+ ],
47+ )
48+ def test_build_database_identifier (tags , template , connection_params , expected ):
49+ check = FakeDatabaseCheck ("test" , {}, [{}])
50+ check .tag_manager .set_tags_from_list (tags )
51+ assert check ._build_database_identifier (template , connection_params ) == expected
52+
53+
54+ @pytest .mark .parametrize (
55+ ("template" , "params" , "tags" , "tags_after" , "expected" ),
56+ [
57+ # template=None / params=None delegate to the base hooks (default template "$resolved_hostname").
58+ pytest .param (None , None , ["resolved_hostname:my-host" ], None , "my-host" , id = "default_template_uses_tags" ),
59+ # Non-string param values are stringified by the template engine, so no casting is needed.
60+ pytest .param ("$host:$port" , {"host" : "db-host" , "port" : 5432 }, [], None , "db-host:5432" , id = "overridden_hooks" ),
61+ # Connection params take precedence over tags of the same name.
62+ pytest .param (
63+ "$host:$port" ,
64+ {"host" : "db-host" , "port" : 5432 },
65+ ["host:tag-host" , "port:1111" ],
66+ None ,
67+ "db-host:5432" ,
68+ id = "params_override_tags" ,
69+ ),
70+ # Mutating tags after first access has no effect: the identifier is built once and cached.
71+ pytest .param (
72+ None , None , ["resolved_hostname:first" ], ["resolved_hostname:second" ], "first" , id = "built_once_and_cached"
73+ ),
74+ ],
75+ )
76+ def test_database_identifier (template , params , tags , tags_after , expected ):
77+ class EmbeddedDatabaseCheck (FakeDatabaseCheck ):
78+ @property
79+ def database_identifier_template (self ):
80+ return super ().database_identifier_template if template is None else template
81+
82+ @property
83+ def database_identifier_params (self ):
84+ return super ().database_identifier_params if params is None else params
85+
86+ check = EmbeddedDatabaseCheck ("test" , {}, [{}])
87+ check .tag_manager .set_tags_from_list (tags )
88+ assert check .database_identifier == expected
89+ if tags_after is not None :
90+ check .tag_manager .set_tags_from_list (tags_after , replace = True )
91+ assert check .database_identifier == expected
0 commit comments