-
Notifications
You must be signed in to change notification settings - Fork 1.6k
Expand file tree
/
Copy pathconftest.py
More file actions
193 lines (152 loc) · 5.16 KB
/
Copy pathconftest.py
File metadata and controls
193 lines (152 loc) · 5.16 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
# (C) Datadog, Inc. 2010-present
# All rights reserved
# Licensed under Simplified BSD License (see LICENSE)
import copy
import os
from collections.abc import Callable
from typing import Optional
import psycopg
import pytest
from semver import VersionInfo
from datadog_checks.dev import WaitFor, docker_run
from datadog_checks.postgres import PostgreSql
from datadog_checks.postgres.config import build_config
from datadog_checks.postgres.metrics_cache import PostgresMetricsCache
from .common import (
DB_NAME,
HOST,
PASSWORD,
PORT,
PORT_REPLICA,
PORT_REPLICA2,
PORT_REPLICA_LOGICAL,
POSTGRES_IMAGE,
POSTGRES_LOCALE,
POSTGRES_VERSION,
USER,
)
HERE = os.path.dirname(os.path.abspath(__file__))
INSTANCE = {
'host': HOST,
'port': PORT,
'username': USER,
'password': PASSWORD,
'dbname': DB_NAME,
'tags': ['foo:bar'],
'disable_generic_tags': True,
'collect_settings': {'enabled': True, 'run_sync': True},
}
E2E_METADATA = {
'start_commands': [
'apt update',
'apt install -y --no-install-recommends build-essential python3-dev libpq-dev',
],
}
def connect_to_pg():
psycopg.connect(host=HOST, dbname=DB_NAME, user=USER, password=PASSWORD)
if float(POSTGRES_VERSION) >= 10.0:
psycopg.connect(host=HOST, dbname=DB_NAME, user=USER, port=PORT_REPLICA, password=PASSWORD)
psycopg.connect(host=HOST, dbname=DB_NAME, user=USER, port=PORT_REPLICA2, password=PASSWORD)
psycopg.connect(host=HOST, dbname=DB_NAME, user=USER, port=PORT_REPLICA_LOGICAL, password=PASSWORD)
@pytest.fixture(scope='session')
def dd_environment(e2e_instance, skip_env):
"""
Start a standalone postgres server requiring authentication.
"""
if skip_env:
yield e2e_instance, E2E_METADATA
return
compose_file = 'docker-compose.yaml'
if float(POSTGRES_VERSION) >= 10.0:
compose_file = 'docker-compose-replication.yaml'
with docker_run(
os.path.join(HERE, 'compose', compose_file),
conditions=[WaitFor(connect_to_pg)],
env_vars={
"POSTGRES_IMAGE": POSTGRES_IMAGE,
"POSTGRES_LOCALE": POSTGRES_LOCALE,
"PGDATA": "/var/lib/postgresql/$PG_MAJOR/docker",
},
):
yield e2e_instance, E2E_METADATA
# Skip environment setup
# This is helpful for running tests locally without having to spin up the environment repeatedly
# To use this, launch the necessary docker compose files manually and then run the tests with --skip-env
def pytest_addoption(parser: pytest.Parser):
parser.addoption(
"--skip-env",
action="store_true",
default=False,
help="skip environment setup",
)
@pytest.fixture(scope='session')
def skip_env(request):
return request.config.getoption("--skip-env")
@pytest.fixture
def check():
c = PostgreSql('postgres', {}, [{'dbname': 'dbname', 'host': 'localhost', 'port': '5432', 'username': USER}])
c._version = VersionInfo(9, 2, 0)
return c
@pytest.fixture(scope="function")
def integration_check() -> Callable[[dict, Optional[dict]], PostgreSql]:
checks = []
def _check(instance: dict, init_config: dict = None):
nonlocal checks
c = PostgreSql('postgres', init_config or {}, [instance])
checks.append(c)
return c
yield _check
for c in checks:
c.cancel()
@pytest.fixture
def pg_instance():
return copy.deepcopy(INSTANCE)
@pytest.fixture
def pg_replica_instance():
instance = copy.deepcopy(INSTANCE)
instance['port'] = PORT_REPLICA
return instance
@pytest.fixture
def pg_replica_instance2():
instance = copy.deepcopy(INSTANCE)
instance['port'] = PORT_REPLICA2
return instance
@pytest.fixture
def pg_replica_logical():
instance = copy.deepcopy(INSTANCE)
instance['port'] = PORT_REPLICA_LOGICAL
return instance
@pytest.fixture
def metrics_cache(pg_instance, integration_check):
check = integration_check(pg_instance)
check.warning = print
config, _ = build_config(check)
return PostgresMetricsCache(config)
@pytest.fixture
def metrics_cache_replica(pg_replica_instance, integration_check):
check = integration_check(pg_replica_instance)
check.warning = print
config, _ = build_config(check)
return PostgresMetricsCache(config)
@pytest.fixture(scope='session')
def e2e_instance():
instance = copy.deepcopy(INSTANCE)
instance['dbm'] = True
return instance
@pytest.fixture(scope='function', autouse=False)
def reset_pg_stat_statements(pg_instance):
"""
Resets pg_stat_statements before each test to ensure clean state.
This prevents test isolation issues when incremental_query_metrics is enabled.
Usage: Add this fixture as a parameter to any test that needs a clean pg_stat_statements state.
"""
from .utils import _get_superconn
try:
with _get_superconn(pg_instance) as superconn:
with superconn.cursor() as cur:
cur.execute("SELECT pg_stat_statements_reset();")
except Exception:
# If pg_stat_statements is not available or we can't reset, that's okay
# Some tests might run on versions without pg_stat_statements
pass
yield