ry-testkit 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- ry_testkit-0.1.0/PKG-INFO +20 -0
- ry_testkit-0.1.0/README.md +9 -0
- ry_testkit-0.1.0/pyproject.toml +22 -0
- ry_testkit-0.1.0/setup.cfg +4 -0
- ry_testkit-0.1.0/src/ry_testkit/__init__.py +6 -0
- ry_testkit-0.1.0/src/ry_testkit/postgres.py +83 -0
- ry_testkit-0.1.0/src/ry_testkit/redis.py +75 -0
- ry_testkit-0.1.0/src/ry_testkit.egg-info/PKG-INFO +20 -0
- ry_testkit-0.1.0/src/ry_testkit.egg-info/SOURCES.txt +10 -0
- ry_testkit-0.1.0/src/ry_testkit.egg-info/dependency_links.txt +1 -0
- ry_testkit-0.1.0/src/ry_testkit.egg-info/requires.txt +3 -0
- ry_testkit-0.1.0/src/ry_testkit.egg-info/top_level.txt +1 -0
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: ry-testkit
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Shared integration test base classes for Redis and Postgres containers
|
|
5
|
+
Author: Ross Yeager
|
|
6
|
+
Requires-Python: >=3.12
|
|
7
|
+
Description-Content-Type: text/markdown
|
|
8
|
+
Requires-Dist: psycopg2-binary
|
|
9
|
+
Requires-Dist: redis
|
|
10
|
+
Requires-Dist: testcontainers
|
|
11
|
+
|
|
12
|
+
# ry-testkit
|
|
13
|
+
|
|
14
|
+
Shared Redis/Postgres integration test base classes.
|
|
15
|
+
|
|
16
|
+
## Install
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
pip install ry-testkit
|
|
20
|
+
```
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=68", "wheel"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "ry-testkit"
|
|
7
|
+
version = "0.1.0"
|
|
8
|
+
description = "Shared integration test base classes for Redis and Postgres containers"
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
requires-python = ">=3.12"
|
|
11
|
+
authors = [{ name = "Ross Yeager" }]
|
|
12
|
+
dependencies = [
|
|
13
|
+
"psycopg2-binary",
|
|
14
|
+
"redis",
|
|
15
|
+
"testcontainers",
|
|
16
|
+
]
|
|
17
|
+
|
|
18
|
+
[tool.setuptools]
|
|
19
|
+
package-dir = {"" = "src"}
|
|
20
|
+
|
|
21
|
+
[tool.setuptools.packages.find]
|
|
22
|
+
where = ["src"]
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import os
|
|
2
|
+
import time
|
|
3
|
+
import typing as T
|
|
4
|
+
import unittest
|
|
5
|
+
|
|
6
|
+
import psycopg2
|
|
7
|
+
from psycopg2 import OperationalError
|
|
8
|
+
from testcontainers.core.container import DockerContainer # type: ignore[import-untyped]
|
|
9
|
+
from testcontainers.core.waiting_utils import wait_for_logs # type: ignore[import-untyped]
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class PostgresOnlyTestBase(unittest.TestCase):
|
|
13
|
+
container: T.Optional[DockerContainer] = None
|
|
14
|
+
_started = False
|
|
15
|
+
|
|
16
|
+
IMAGE = os.getenv("TEST_POSTGRES_IMAGE", "postgres:latest")
|
|
17
|
+
USER = os.getenv("TEST_POSTGRES_USER", "test")
|
|
18
|
+
PASSWORD = os.getenv("TEST_POSTGRES_PASSWORD", "test")
|
|
19
|
+
DB = os.getenv("TEST_POSTGRES_DB", "testdb")
|
|
20
|
+
READY_TIMEOUT_S = int(os.getenv("TEST_POSTGRES_READY_TIMEOUT_S", "60"))
|
|
21
|
+
READY_SLEEP_S = float(os.getenv("TEST_POSTGRES_READY_SLEEP_S", "0.5"))
|
|
22
|
+
|
|
23
|
+
@classmethod
|
|
24
|
+
def _dsn(cls) -> str:
|
|
25
|
+
assert cls.container is not None
|
|
26
|
+
return (
|
|
27
|
+
f"dbname={cls.DB} user={cls.USER} password={cls.PASSWORD} "
|
|
28
|
+
f"host={cls.container.get_container_host_ip()} "
|
|
29
|
+
f"port={cls.container.get_exposed_port(5432)}"
|
|
30
|
+
)
|
|
31
|
+
|
|
32
|
+
@classmethod
|
|
33
|
+
def _wait_ready(cls) -> None:
|
|
34
|
+
deadline = time.time() + cls.READY_TIMEOUT_S
|
|
35
|
+
while time.time() < deadline:
|
|
36
|
+
try:
|
|
37
|
+
conn = psycopg2.connect(cls._dsn())
|
|
38
|
+
conn.close()
|
|
39
|
+
return
|
|
40
|
+
except OperationalError:
|
|
41
|
+
time.sleep(cls.READY_SLEEP_S)
|
|
42
|
+
raise RuntimeError("Postgres test container did not become ready")
|
|
43
|
+
|
|
44
|
+
@classmethod
|
|
45
|
+
def setUpClass(cls) -> None:
|
|
46
|
+
super().setUpClass()
|
|
47
|
+
if cls._started:
|
|
48
|
+
return
|
|
49
|
+
|
|
50
|
+
c = DockerContainer(cls.IMAGE)
|
|
51
|
+
c.with_env("POSTGRES_USER", cls.USER)
|
|
52
|
+
c.with_env("POSTGRES_PASSWORD", cls.PASSWORD)
|
|
53
|
+
c.with_env("POSTGRES_DB", cls.DB)
|
|
54
|
+
c.with_exposed_ports(5432)
|
|
55
|
+
c.start()
|
|
56
|
+
|
|
57
|
+
try:
|
|
58
|
+
wait_for_logs(c, "database system is ready to accept connections", timeout=cls.READY_TIMEOUT_S)
|
|
59
|
+
except Exception:
|
|
60
|
+
pass
|
|
61
|
+
|
|
62
|
+
cls.container = c
|
|
63
|
+
cls._wait_ready()
|
|
64
|
+
cls._started = True
|
|
65
|
+
|
|
66
|
+
@classmethod
|
|
67
|
+
def tearDownClass(cls) -> None:
|
|
68
|
+
if cls.container is not None:
|
|
69
|
+
cls.container.stop()
|
|
70
|
+
cls.container = None
|
|
71
|
+
cls._started = False
|
|
72
|
+
super().tearDownClass()
|
|
73
|
+
|
|
74
|
+
@classmethod
|
|
75
|
+
def postgres_connection_info(cls) -> T.Dict[str, T.Any]:
|
|
76
|
+
assert cls.container is not None
|
|
77
|
+
return {
|
|
78
|
+
"host": cls.container.get_container_host_ip(),
|
|
79
|
+
"port": int(cls.container.get_exposed_port(5432)),
|
|
80
|
+
"user": cls.USER,
|
|
81
|
+
"password": cls.PASSWORD,
|
|
82
|
+
"db": cls.DB,
|
|
83
|
+
}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import os
|
|
2
|
+
import time
|
|
3
|
+
import typing as T
|
|
4
|
+
import unittest
|
|
5
|
+
|
|
6
|
+
import redis
|
|
7
|
+
from redis import RedisError
|
|
8
|
+
from testcontainers.core.container import DockerContainer # type: ignore[import-untyped]
|
|
9
|
+
from testcontainers.core.waiting_utils import wait_for_logs # type: ignore[import-untyped]
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class RedisOnlyTestBase(unittest.TestCase):
|
|
13
|
+
container: T.Optional[DockerContainer] = None
|
|
14
|
+
_started = False
|
|
15
|
+
|
|
16
|
+
IMAGE = os.getenv("TEST_REDIS_IMAGE", "redis:latest")
|
|
17
|
+
READY_TIMEOUT_S = int(os.getenv("TEST_REDIS_READY_TIMEOUT_S", "60"))
|
|
18
|
+
READY_SLEEP_S = float(os.getenv("TEST_REDIS_READY_SLEEP_S", "0.5"))
|
|
19
|
+
|
|
20
|
+
@classmethod
|
|
21
|
+
def _client(cls) -> redis.Redis:
|
|
22
|
+
assert cls.container is not None
|
|
23
|
+
return redis.Redis(
|
|
24
|
+
host=cls.container.get_container_host_ip(),
|
|
25
|
+
port=int(cls.container.get_exposed_port(6379)),
|
|
26
|
+
db=0,
|
|
27
|
+
decode_responses=True,
|
|
28
|
+
)
|
|
29
|
+
|
|
30
|
+
@classmethod
|
|
31
|
+
def _wait_ready(cls) -> None:
|
|
32
|
+
deadline = time.time() + cls.READY_TIMEOUT_S
|
|
33
|
+
while time.time() < deadline:
|
|
34
|
+
try:
|
|
35
|
+
if cls._client().ping():
|
|
36
|
+
return
|
|
37
|
+
except RedisError:
|
|
38
|
+
time.sleep(cls.READY_SLEEP_S)
|
|
39
|
+
raise RuntimeError("Redis test container did not become ready")
|
|
40
|
+
|
|
41
|
+
@classmethod
|
|
42
|
+
def setUpClass(cls) -> None:
|
|
43
|
+
super().setUpClass()
|
|
44
|
+
if cls._started:
|
|
45
|
+
return
|
|
46
|
+
|
|
47
|
+
c = DockerContainer(cls.IMAGE)
|
|
48
|
+
c.with_exposed_ports(6379)
|
|
49
|
+
c.start()
|
|
50
|
+
|
|
51
|
+
try:
|
|
52
|
+
wait_for_logs(c, "Ready to accept connections", timeout=cls.READY_TIMEOUT_S)
|
|
53
|
+
except Exception:
|
|
54
|
+
pass
|
|
55
|
+
|
|
56
|
+
cls.container = c
|
|
57
|
+
cls._wait_ready()
|
|
58
|
+
cls._started = True
|
|
59
|
+
|
|
60
|
+
@classmethod
|
|
61
|
+
def tearDownClass(cls) -> None:
|
|
62
|
+
if cls.container is not None:
|
|
63
|
+
cls.container.stop()
|
|
64
|
+
cls.container = None
|
|
65
|
+
cls._started = False
|
|
66
|
+
super().tearDownClass()
|
|
67
|
+
|
|
68
|
+
@classmethod
|
|
69
|
+
def redis_connection_info(cls) -> T.Dict[str, T.Any]:
|
|
70
|
+
assert cls.container is not None
|
|
71
|
+
return {
|
|
72
|
+
"host": cls.container.get_container_host_ip(),
|
|
73
|
+
"port": int(cls.container.get_exposed_port(6379)),
|
|
74
|
+
"db": 0,
|
|
75
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: ry-testkit
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Shared integration test base classes for Redis and Postgres containers
|
|
5
|
+
Author: Ross Yeager
|
|
6
|
+
Requires-Python: >=3.12
|
|
7
|
+
Description-Content-Type: text/markdown
|
|
8
|
+
Requires-Dist: psycopg2-binary
|
|
9
|
+
Requires-Dist: redis
|
|
10
|
+
Requires-Dist: testcontainers
|
|
11
|
+
|
|
12
|
+
# ry-testkit
|
|
13
|
+
|
|
14
|
+
Shared Redis/Postgres integration test base classes.
|
|
15
|
+
|
|
16
|
+
## Install
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
pip install ry-testkit
|
|
20
|
+
```
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
README.md
|
|
2
|
+
pyproject.toml
|
|
3
|
+
src/ry_testkit/__init__.py
|
|
4
|
+
src/ry_testkit/postgres.py
|
|
5
|
+
src/ry_testkit/redis.py
|
|
6
|
+
src/ry_testkit.egg-info/PKG-INFO
|
|
7
|
+
src/ry_testkit.egg-info/SOURCES.txt
|
|
8
|
+
src/ry_testkit.egg-info/dependency_links.txt
|
|
9
|
+
src/ry_testkit.egg-info/requires.txt
|
|
10
|
+
src/ry_testkit.egg-info/top_level.txt
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
ry_testkit
|