-
Notifications
You must be signed in to change notification settings - Fork 125
Expand file tree
/
Copy pathpostgres.py
More file actions
185 lines (150 loc) · 5.16 KB
/
Copy pathpostgres.py
File metadata and controls
185 lines (150 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
"""PostgreSQL fixtures."""
from __future__ import annotations
import os
import time
import pytest
from tests.fixtures.utils import cleanup_connection, is_binary_port_open, run_cli
POSTGRES_HOST = os.environ.get("POSTGRES_HOST", "localhost")
POSTGRES_PORT = int(os.environ.get("POSTGRES_PORT", "5432"))
POSTGRES_USER = os.environ.get("POSTGRES_USER", "testuser")
POSTGRES_PASSWORD = os.environ.get("POSTGRES_PASSWORD", "TestPassword123!")
POSTGRES_DATABASE = os.environ.get("POSTGRES_DATABASE", "test_sqlit")
def postgres_available() -> bool:
"""Check if PostgreSQL is available."""
return is_binary_port_open(POSTGRES_HOST, POSTGRES_PORT)
@pytest.fixture(scope="session")
def postgres_server_ready() -> bool:
"""Check if PostgreSQL is ready and return True/False."""
if not postgres_available():
return False
time.sleep(1)
return True
@pytest.fixture(scope="function")
def postgres_db(postgres_server_ready: bool) -> str:
"""Set up PostgreSQL test database."""
if not postgres_server_ready:
pytest.skip("PostgreSQL is not available")
try:
import psycopg
except ImportError:
pytest.skip("psycopg is not installed")
try:
conn = psycopg.connect(
host=POSTGRES_HOST,
port=POSTGRES_PORT,
dbname=POSTGRES_DATABASE,
user=POSTGRES_USER,
password=POSTGRES_PASSWORD,
connect_timeout=10,
)
conn.autocommit = True
cursor = conn.cursor()
cursor.execute("DROP TABLE IF EXISTS test_users CASCADE")
cursor.execute("DROP TABLE IF EXISTS test_products CASCADE")
cursor.execute("DROP VIEW IF EXISTS test_user_emails")
cursor.execute("""
CREATE TABLE test_users (
id INTEGER PRIMARY KEY,
name VARCHAR(100) NOT NULL,
email VARCHAR(100) UNIQUE
)
""")
cursor.execute("""
CREATE TABLE test_products (
id INTEGER PRIMARY KEY,
name VARCHAR(100) NOT NULL,
price DECIMAL(10,2) NOT NULL,
stock INTEGER DEFAULT 0
)
""")
cursor.execute("""
CREATE VIEW test_user_emails AS
SELECT id, name, email FROM test_users WHERE email IS NOT NULL
""")
# Create test index for integration tests
cursor.execute("CREATE INDEX idx_test_users_email ON test_users(email)")
# Create test trigger for integration tests
cursor.execute("""
CREATE OR REPLACE FUNCTION test_audit_func() RETURNS TRIGGER AS $$
BEGIN
RETURN NEW;
END;
$$ LANGUAGE plpgsql
""")
cursor.execute("""
CREATE TRIGGER trg_test_users_audit
AFTER INSERT ON test_users
FOR EACH ROW EXECUTE FUNCTION test_audit_func()
""")
# Create test sequence for integration tests
cursor.execute("CREATE SEQUENCE test_sequence START 1")
cursor.execute("""
INSERT INTO test_users (id, name, email) VALUES
(1, 'Alice', 'alice@example.com'),
(2, 'Bob', 'bob@example.com'),
(3, 'Charlie', 'charlie@example.com')
""")
cursor.execute("""
INSERT INTO test_products (id, name, price, stock) VALUES
(1, 'Widget', 9.99, 100),
(2, 'Gadget', 19.99, 50),
(3, 'Gizmo', 29.99, 25)
""")
conn.close()
except Exception as e:
pytest.skip(f"Failed to setup PostgreSQL database: {e}")
yield POSTGRES_DATABASE
try:
conn = psycopg.connect(
host=POSTGRES_HOST,
port=POSTGRES_PORT,
dbname=POSTGRES_DATABASE,
user=POSTGRES_USER,
password=POSTGRES_PASSWORD,
connect_timeout=10,
)
conn.autocommit = True
cursor = conn.cursor()
cursor.execute("DROP TABLE IF EXISTS test_users CASCADE")
cursor.execute("DROP TABLE IF EXISTS test_products CASCADE")
cursor.execute("DROP VIEW IF EXISTS test_user_emails")
cursor.execute("DROP SEQUENCE IF EXISTS test_sequence")
cursor.execute("DROP FUNCTION IF EXISTS test_audit_func")
conn.close()
except Exception:
pass
@pytest.fixture(scope="function")
def postgres_connection(postgres_db: str) -> str:
"""Create a sqlit CLI connection for PostgreSQL and clean up after test."""
connection_name = f"test_postgres_{os.getpid()}"
cleanup_connection(connection_name)
run_cli(
"connections",
"add",
"postgresql",
"--name",
connection_name,
"--server",
POSTGRES_HOST,
"--port",
str(POSTGRES_PORT),
"--database",
postgres_db,
"--username",
POSTGRES_USER,
"--password",
POSTGRES_PASSWORD,
)
yield connection_name
cleanup_connection(connection_name)
__all__ = [
"POSTGRES_DATABASE",
"POSTGRES_HOST",
"POSTGRES_PASSWORD",
"POSTGRES_PORT",
"POSTGRES_USER",
"postgres_available",
"postgres_connection",
"postgres_db",
"postgres_server_ready",
]