userver: /data/code/userver/testsuite/pytest_plugins/pytest_userver/plugins/postgresql.py Source File
Loading...
Searching...
No Matches
postgresql.py
1"""
2Plugin that imports the required fixtures to start the database
3and adjusts the PostgreSQL "dbconnection" static config value.
4"""
5
6from contextlib import contextmanager
7from enum import Enum
8
9import pytest
10
11from pytest_userver import sql
12
13pytest_plugins = [
14 'testsuite.databases.pgsql.pytest_plugin',
15 'pytest_userver.plugins.core',
16]
17
18
19USERVER_CONFIG_HOOKS = ['userver_pg_config']
20
21
23 Error = 1
24 LogicError = 2
25 RuntimeError = 3
26 ConnectionError = 4
27
28
30 def __init__(self, testpoint):
31 self._registered_ntrx = dict()
32 self._testpoint = testpoint
33
34 def _enable_failure(
35 self,
36 name: str,
37 failure_type: RegisteredNtrxFailureType,
38 ) -> None:
39 self._registered_ntrx[name] = failure_type
40
41 @self._testpoint(f'pg_ntrx_execute::{name}')
42 def _failure_tp(data):
43 return {
44 'inject_failure': self.is_failure_enabled(name),
45 'failure_type': self._get_failure_type(name).name,
46 }
47
48 def _disable_failure(self, name: str) -> None:
49 if self.is_failure_enabled(name):
50 del self._registered_ntrx[name]
51
52 def _get_failure_type(self, name: str) -> RegisteredNtrxFailureType:
53 return self._registered_ntrx[name]
54
55 def is_failure_enabled(self, name: str) -> bool:
56 return name in self._registered_ntrx
57
58 @contextmanager
59 def mock_failure(
60 self,
61 name: str,
62 failure_type: RegisteredNtrxFailureType = RegisteredNtrxFailureType.Error,
63 ):
64 self._enable_failure(name, failure_type)
65 try:
66 yield
67 finally:
68 self._disable_failure(name)
69
70
71@pytest.fixture(scope='session')
72def userver_pg_config(pgsql_local):
73 """
74 Returns a function that adjusts the static configuration file for
75 the testsuite.
76 Sets the `dbconnection` to the testsuite started PostgreSQL credentials
77 if there's only one `dbconnection` in static config.
78
79 @ingroup userver_testsuite_fixtures
80 """
81
82 if not pgsql_local:
83 raise ValueError(
84 'Override the "pgsql_local" fixture so that testsuite knowns how to start the PostgreSQL database',
85 )
86
87 if len(pgsql_local) > 1:
88 raise ValueError(
89 f'Found more than one entry in "pgsql_local": '
90 f'{list(pgsql_local.keys())}. '
91 f'The "userver_pg_config" fixture supports '
92 f'only one entry in "pgsql_local" fixture. The '
93 f'"userver_pg_config" fixture should be overridden and '
94 f'the "dbconnection" for the components::Postgres '
95 f'components should be adjusted via the overridden fixture.',
96 )
97
98 uri = list(pgsql_local.values())[0].get_uri()
99
100 def _patch_config(config_yaml, config_vars):
101 components = config_yaml['components_manager']['components']
102 postgre_dbs = {
103 name: params
104 for name, params in components.items()
105 if params and ('dbconnection' in params or 'dbconnection#env' in params)
106 }
107
108 if len(postgre_dbs) > 1:
109 raise ValueError(
110 f'Found more than one components with "dbconnection": '
111 f'{list(postgre_dbs.keys())}. '
112 f'The "userver_pg_config" fixture should be overridden and '
113 f'the "dbconnection" for the components::Postgres '
114 f'components should be adjusted via the overridden fixture.',
115 )
116
117 for config in postgre_dbs.values():
118 config['dbconnection'] = uri
119 config.pop('dbalias', None)
120
121 return _patch_config
122
123
124@pytest.fixture
125def userver_pg_trx(testpoint) -> sql.RegisteredTrx:
126 """
127 The fixture maintains transaction fault injection state using
128 RegisteredTrx class.
129
130 @see pytest_userver.sql.RegisteredTrx
131
132 @snippet postgresql/functional_tests/integration_tests/tests/test_trx_failure.py fault injection
133
134 @ingroup userver_testsuite_fixtures
135 """
136
137 registered = sql.RegisteredTrx()
138
139 @testpoint('pg_trx_commit')
140 def _pg_trx_tp(data):
141 should_fail = registered.is_failure_enabled(data['trx_name'])
142 return {'trx_should_fail': should_fail}
143
144 return registered
145
146
147@pytest.fixture
148def userver_pg_ntrx(testpoint) -> RegisteredNtrx:
149 """
150 The fixture maintains single query fault injection state using
151 RegisteredNtrx class.
152
153 @see pytest_userver.plugins.postgresql.RegisteredNtrx
154
155 @snippet postgresql/functional_tests/integration_tests/tests/test_ntrx_failure.py fault injection
156
157 @ingroup userver_testsuite_fixtures
158 """
159
160 return RegisteredNtrx(testpoint)