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
7 changes: 5 additions & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ build-backend = "setuptools.build_meta"

[project]
name = "dataops-testgen"
version = "5.70.2"
version = "5.70.3"
description = "DataKitchen's Data Quality DataOps TestGen"
authors = [
{ "name" = "DataKitchen, Inc.", "email" = "info@datakitchen.io" },
Expand Down Expand Up @@ -92,7 +92,10 @@ dependencies = [

[project.optional-dependencies]
standalone = [
"pixeltable-pgserver>=0.5.1",
# Upper bound guards against a future release dropping a bundled PostgreSQL
# major that existing data dirs were initialized with (see start_server in
# common/standalone_postgres.py). Revisit deliberately before relaxing.
"pixeltable-pgserver>=0.6.0,<0.7.0",
]

dev = [
Expand Down
10 changes: 8 additions & 2 deletions testgen/common/standalone_postgres.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
STANDALONE_MODE_ENV_VAR = "TG_STANDALONE_MODE"
HOME_DIR_ENV_VAR = "TG_TESTGEN_HOME"
STANDALONE_URI_ENV_VAR = "_TG_STANDALONE_URI"
NEW_INSTALL_POSTGRES_VERSION = 18

# Stored as ``project_host`` in the demo-DB connection row so that the actual
# host/port — which can change across sessions on Windows (pgserver picks a
Expand Down Expand Up @@ -84,8 +85,13 @@ def start_server(data_dir: Path | None = None) -> None:
data_dir = get_home_dir() / "pgdata"
data_dir.mkdir(parents=True, exist_ok=True)

LOG.info("Starting embedded PostgreSQL (data: %s) ...", data_dir)
_server = pgserver.get_server(data_dir)
# pgserver bundles multiple PostgreSQL majors and defaults to its newest.
# Honor the major that initialized an existing data dir so upgrades never fail with a version mismatch.
existing_version = pgserver.pgdata_version(data_dir)
postgres_version = existing_version if existing_version is not None else NEW_INSTALL_POSTGRES_VERSION

LOG.info("Starting embedded PostgreSQL (data: %s, pg%s) ...", data_dir, postgres_version)
_server = pgserver.get_server(data_dir, postgres_version=postgres_version)
LOG.info("Embedded PostgreSQL ready: %s", _server.get_uri())

_reinitialize_orm_engine()
Expand Down
48 changes: 48 additions & 0 deletions tests/unit/common/test_standalone_postgres.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
"""Unit tests for embedded-PostgreSQL version selection in standalone mode."""

import sys
from unittest import mock

import pytest

from testgen.common import standalone_postgres


@pytest.fixture
def fake_pgserver():
"""Mock the ``pixeltable_pgserver`` module imported inside ``start_server``."""
fake = mock.MagicMock()
fake.get_server.return_value.get_uri.return_value = "postgresql:///db?host=/tmp/sock"
with mock.patch.dict(sys.modules, {"pixeltable_pgserver": fake}):
yield fake


@pytest.fixture(autouse=True)
def reset_module_state():
"""Isolate the module-level server singleton and skip real ORM/atexit side effects."""
standalone_postgres._server = None
with (
mock.patch.object(standalone_postgres, "_reinitialize_orm_engine"),
mock.patch("atexit.register"),
):
yield
standalone_postgres._server = None


def test_fresh_data_dir_uses_new_install_version(fake_pgserver, tmp_path):
fake_pgserver.pgdata_version.return_value = None

standalone_postgres.start_server(tmp_path / "pgdata")

assert fake_pgserver.get_server.call_args.kwargs["postgres_version"] == (
standalone_postgres.NEW_INSTALL_POSTGRES_VERSION
)


def test_existing_data_dir_honors_on_disk_version(fake_pgserver, tmp_path):
# A cluster initialized by an older bundled major must keep running on it.
fake_pgserver.pgdata_version.return_value = 16

standalone_postgres.start_server(tmp_path / "pgdata")

assert fake_pgserver.get_server.call_args.kwargs["postgres_version"] == 16
Loading