Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 20 additions & 21 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
@@ -1,30 +1,29 @@
name: Run tests
name: Run parallel tests

on: ["push", "pull_request"]
on: [push, pull_request]

jobs:

test:

name: Tests / Python ${{ matrix.python-version }}
runs-on: ubuntu-latest
strategy:
matrix:
python-version: ["3.8", "3.9", "3.10", "3.11", "3.12"]
python-version: ["3.8", "3.9", "3.10", "3.11", "3.12", "3.13"]

steps:
- uses: actions/checkout@v3

- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v3
with:
python-version: ${{ matrix.python-version }}

- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install hatch

- name: Run tests
run: |
hatch run ci

- uses: actions/checkout@v3
- name: Set up Python
uses: actions/setup-python@v3
with:
python-version: ${{ matrix.python-version }}
- name: Install dependencies
run: |
sudo apt-get update && sudo apt-get -y install podman
podman --version
systemctl --user enable podman
systemctl --user start podman
python -m pip install --upgrade pip
pip install hatch
- name: Run tests
run: |
hatch run ci
10 changes: 10 additions & 0 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,16 @@ PG containers. You will need to do up to two extra things:
can set the DBTESTTOOLS_PG_IP_ADDR environment variable.


If you want to use Podman instead of Docker engine you will need to follow
these steps:

1. Enable and start podman on your host
```bash
systemctl --user enable podman
systemctl --user start podman
```
2. `export DBTESTTOOLS_USE_PODMAN=1` variable.

This code has been in use daily on a large project at Cisco for a few years
now, and is very stable.

Expand Down
22 changes: 21 additions & 1 deletion dbtesttools/engines/postgres.py
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,26 @@ def has_savepoint(self):
def setUp(self):
"""Do all the work to bring up a working Postgres fixture."""
super().setUp()
# Podman integration: optionally override Docker socket
if os.getenv("DBTESTTOOLS_USE_PODMAN") == "1":
if sys.platform == "darwin":
# MacOS Podman socket
podman_socket = (
f"unix://{os.getenv('HOME')}"
f"/.local/share/containers/podman/machine/podman.sock"
)
else:
# Linux Podman socket
podman_socket = (
f"unix:///run/user/{os.getuid()}/podman/podman.sock"
)
if os.path.exists(podman_socket.replace("unix://", "")):
os.environ["DOCKER_HOST"] = podman_socket
else:
raise FileNotFoundError(
f"Podman socket not found at {podman_socket}"
)

self.client = docker.from_env()
self.pull_image()
self.find_free_port()
Expand Down Expand Up @@ -156,7 +176,7 @@ def set_up_test_database(self):
cur.close()
c.close()

@retry(psycopg2.OperationalError, tries=30, delay=1)
@retry(psycopg2.OperationalError, tries=60, delay=1)
def wait_for_pg_start(self):
c = psycopg2.connect(
"user='postgres' host='{ip}' port='{port}'"
Expand Down
66 changes: 66 additions & 0 deletions dbtesttools/tests/test_pgfixture.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import os
import unittest
import warnings

import testscenarios
import testtools
from sqlalchemy import text

from dbtesttools.engines.postgres import PostgresContainerFixture

warnings.filterwarnings("ignore", category=UserWarning, module="urllib3")


class TestPostgresContainer(
testscenarios.TestWithScenarios, testtools.TestCase
):
"""Test that we can bring up a Postgres container."""

scenarios = [
("docker", {"podman": False}),
("podman", {"podman": True}),
]

def setUp(self):
self.pg_fixture = None
super().setUp()
if self.podman:
os.environ["DBTESTTOOLS_USE_PODMAN"] = "1"
else:
os.environ.pop("DBTESTTOOLS_USE_PODMAN", None)
try:
fixture = PostgresContainerFixture(future=True)
fixture.setUp()
self.pg_fixture = fixture
except Exception as e:
print(f'[ERROR] Failed to start Postgres fixture: {e}')

def tearDown(self):
if self.pg_fixture is not None:
if hasattr(self.pg_fixture, "engine"):
try:
self.pg_fixture.engine.dispose()
except Exception as e:
print(f"Warning: failed to dispose engine: {e}")
if hasattr(self.pg_fixture, "container"):
try:
self.pg_fixture.container.kill()
except Exception as e:
print(f"Warning: failed to kill container: {e}")
super().tearDown()

def test_connection(self):
if self.pg_fixture is None:
self.fail("Postgres fixture was not initialized")
# Actually test that the database is reachable
conn = self.pg_fixture.connect()
try:
result = conn.execute(text("SELECT 1;"))
value = result.scalar()
self.assertEqual(value, 1)
finally:
conn.close()


if __name__ == "__main__":
unittest.main()