forked from testcontainers/testcontainers-python
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathtest_postgres.py
More file actions
153 lines (122 loc) · 6.05 KB
/
test_postgres.py
File metadata and controls
153 lines (122 loc) · 6.05 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
from pathlib import Path
import pytest
import sqlalchemy
from testcontainers.postgres import PostgresContainer
# https://www.postgresql.org/support/versioning/
@pytest.mark.parametrize("version", ["12", "13", "14", "15", "16", "latest"])
def test_docker_run_postgres(version: str, monkeypatch):
def fail(*args, **kwargs):
raise AssertionError("SQLA was called during PG container setup")
monkeypatch.setattr(sqlalchemy, "create_engine", fail)
postgres_container = PostgresContainer(f"postgres:{version}")
with postgres_container as postgres:
status, msg = postgres.exec(f"pg_isready -hlocalhost -p{postgres.port} -U{postgres.username}")
assert msg.decode("utf-8").endswith("accepting connections\n")
assert status == 0
status, msg = postgres.exec(
f"psql -hlocalhost -p{postgres.port} -U{postgres.username} -c 'select 2*3*5*7*11*13*17 as a;' "
)
assert "510510" in msg.decode("utf-8")
assert "(1 row)" in msg.decode("utf-8")
assert status == 0
@pytest.mark.inside_docker_check
def test_docker_run_postgres_with_sqlalchemy():
postgres_container = PostgresContainer("postgres:9.5")
with postgres_container as postgres:
engine = sqlalchemy.create_engine(postgres.get_connection_url())
with engine.begin() as connection:
result = connection.execute(sqlalchemy.text("select version()"))
for row in result:
assert row[0].lower().startswith("postgresql 9.5")
def test_docker_run_postgres_with_driver_pg8000():
postgres_container = PostgresContainer("postgres:9.5", driver="pg8000")
with postgres_container as postgres:
engine = sqlalchemy.create_engine(postgres.get_connection_url())
with engine.begin() as connection:
connection.execute(sqlalchemy.text("select 1=1"))
def test_password_with_quotes():
postgres_container = PostgresContainer("postgres:9.5", password="'''''")
with postgres_container as postgres:
engine = sqlalchemy.create_engine(postgres.get_connection_url())
with engine.begin() as connection:
result = connection.execute(sqlalchemy.text("select version()"))
for row in result:
assert row[0].lower().startswith("postgresql 9.5")
# This is a feature in the generic DbContainer class
# but it can't be tested on its own
# so is tested in various database modules:
# - mysql / mariadb
# - postgresql
# - sqlserver
# - mongodb
# - db2
def test_quoted_password():
user = "root"
password = "p@$%25+0&%rd :/!=?"
quoted_password = "p%40%24%2525+0%26%25rd %3A%2F%21%3D%3F"
driver = "psycopg2"
kwargs = {
"driver": driver,
"username": user,
"password": password,
}
with PostgresContainer("postgres:16-alpine", **kwargs) as container:
port = container.get_exposed_port(5432)
host = container.get_container_host_ip()
expected_url = f"postgresql+{driver}://{user}:{quoted_password}@{host}:{port}/test"
url = container.get_connection_url()
assert url == expected_url
with sqlalchemy.create_engine(expected_url).begin() as connection:
connection.execute(sqlalchemy.text("select 1=1"))
raw_pass_url = f"postgresql+{driver}://{user}:{password}@{host}:{port}/test"
with pytest.raises(Exception):
# it raises ValueError, but auth (OperationalError) = more interesting
with sqlalchemy.create_engine(raw_pass_url).begin() as connection:
connection.execute(sqlalchemy.text("select 1=1"))
def test_show_how_to_initialize_db_via_initdb_dir():
postgres_container = PostgresContainer("postgres:16-alpine")
script = Path(__file__).parent / "fixtures" / "postgres_create_example_table.sql"
postgres_container.with_volume_mapping(host=str(script), container=f"/docker-entrypoint-initdb.d/{script.name}")
insert_query = "insert into example(name, description) VALUES ('sally', 'sells seashells');"
select_query = "select id, name, description from example;"
with postgres_container as postgres:
engine = sqlalchemy.create_engine(postgres.get_connection_url())
with engine.begin() as connection:
connection.execute(sqlalchemy.text(insert_query))
result = connection.execute(sqlalchemy.text(select_query))
result = result.fetchall()
assert len(result) == 1
assert result[0] == (1, "sally", "sells seashells")
def test_none_driver_urls():
user = "root"
password = "pass"
kwargs = {
"username": user,
"password": password,
}
with PostgresContainer("postgres:16-alpine", driver=None, **kwargs) as container:
port = container.get_exposed_port(5432)
host = container.get_container_host_ip()
expected_url = f"postgresql://{user}:{password}@{host}:{port}/test"
url = container.get_connection_url()
assert url == expected_url
with PostgresContainer("postgres:16-alpine", **kwargs) as container:
port = container.get_exposed_port(5432)
host = container.get_container_host_ip()
expected_url = f"postgresql://{user}:{password}@{host}:{port}/test"
url = container.get_connection_url(driver=None)
assert url == expected_url
def test_psycopg_versions():
"""Test that both psycopg2 and psycopg (v2 and v3) work with the container."""
postgres_container = PostgresContainer("postgres:16-alpine", driver="psycopg2")
with postgres_container as postgres:
engine = sqlalchemy.create_engine(postgres.get_connection_url())
with engine.begin() as connection:
result = connection.execute(sqlalchemy.text("SELECT 1 as test"))
assert result.scalar() == 1
postgres_container = PostgresContainer("postgres:16-alpine", driver="psycopg")
with postgres_container as postgres:
engine = sqlalchemy.create_engine(postgres.get_connection_url())
with engine.begin() as connection:
result = connection.execute(sqlalchemy.text("SELECT 1 as test"))
assert result.scalar() == 1