Skip to content

feat: parallel testing infrastructure and PostgreSQL backend improvements - #55

Merged
vistart merged 31 commits into
release/v1.0.0.dev17from
feature/parallel-testing
Aug 28, 2026
Merged

vistart merged 31 commits into
release/v1.0.0.dev17from
feature/parallel-testing

Conversation

@vistart

@vistart vistart commented Aug 28, 2026 •

Copy link
Copy Markdown
Contributor

Description

This PR brings parallel testing support and coordinated PostgreSQL backend changes to the release/v1.0.0.dev17 line, aligned with python-activerecord PR #118 (feature/parallel-testing merged into release/v1.0.0.dev30).

Issues: (add issue numbers here)

Type of change

  • feat: A new feature
  • docs: Documentation only changes (if related to the new feature)
  • perf: A code change that improves performance (if part of the feature)
  • test: Adding missing tests or correcting existing tests (for the new feature)
  • chore: Changes to the build process or auxiliary tools and libraries such as documentation generation (if related to the new feature)
  • ci: Changes to our CI configuration files and scripts (if related to the new feature)
  • build: Changes that affect the build system or external dependencies (if related to the new feature)
  • revert: Reverts a previous commit

Breaking Change

  • No breaking changes

Related Repositories/Packages

Changes

CI / Infrastructure

  • ci: update rhosocial-activerecord branch to release/v1.0.0.dev30
  • ci: update rhosocial-activerecord-testsuite branch to release/v1.0.0.dev17
  • feat: parallel scenario tests with per-worker database pooling
  • fix(test): load testsuite conftest plugin and guard --scenarios registration
  • fix(test): apply pooled database names in backend and connection feature conftests
  • fix(test): apply pooled database names in worker connection params
  • fix(test): check for simultaneous double-hold instead of id uniqueness

pgvector / Vector Search

  • feat(postgres): add vector_search function module with pgvector search capabilities
  • feat(postgres): extend expression types with pgvector-related serialization
  • test: add vector search and example compile test coverage

PostgreSQL-Specific Features

  • feat(postgres): add named expression/procedure example modules
  • feat(dialect): declare supports_schema capability and schema DDL tests
  • feat(dialect): declare supports_schema and supports_schema_authorization in PostgresSchemaSupport
  • fix(dialect): translate is_auto_increment to GENERATED BY DEFAULT AS IDENTITY
  • feat(test): provide cross-schema fixtures for testsuite
  • feat(test): provision mixed default/non-default schema fixtures

Adapter / Data Type Fixes

  • fix(adapters): parse array literals on read for list fields in TEXT columns
  • fix(hstore): pass raw % operator to format_binary_operator to avoid double escaping
  • test(adapters): offline adapter round-trip coverage for all types
  • test: add is_auto_increment/DDL regression tests
  • test(expression): add serialization round-trip coverage for PostgreSQL expressions

Dialect / Expression

  • fix(config): declare missing autocommit field on PostgresConnectionConfig
  • test: cover column qualifier resolution under JOINs
  • test: cover dynamic table/schema names as supported usage
  • fix(expression): hstore operator % escaping

CLI

  • feat: CLI async unification, --ssl param; postgres backend fixes
  • fix(test): use a non-empty LSN range for pg_get_wal_records_info

Testing

  • I have added new tests to cover my changes.
  • I have updated existing tests to reflect my changes.
  • All existing tests pass.
  • This change has been tested on [PostgreSQL, with xdist/local].

Test Plan:

PYTHONPATH=src .venv3.8/bin/pytest tests/ -v --tb=short

(Skipped local verification; CI will run full PostgreSQL matrix after PR creation.)

Checklist

  • My code follows the project's code style guidelines.
  • I have performed a self-review of my own code.
  • I have commented my code, particularly in hard-to-understand areas.
  • I have made corresponding changes to the documentation (Docstrings, README.md, etc.).
  • My changes generate no new warnings.
  • I have added a Changelog fragment (changelog.d/<issue_number>.<type>.md).
  • I have verified that my changes do not introduce SQL injection vulnerabilities.
  • I have checked for potential performance regressions.

Additional Notes

Targets release: release/v1.0.0.dev17

vistart added 27 commits August 18, 2026 12:30
Wire the testsuite database pool for postgres: register the pool reset
handler, make scenario resolution pool-aware, install core and testsuite
from the feature/parallel-testing branches, and run tests with -n 8.
…tration

Without -p rhosocial.activerecord.testsuite.conftest the pooling hooks never
run, so configure_pool_size stays 0 and every xdist worker falls back to the
shared scenario database, racing on schema DDL. Load the plugin and guard the
backend's own --scenarios option so both conftests coexist.
- Add named_expressions order_expressions (import-safe, prepare_orders_demo helper)
- Add named_procedures order_workflow (OrderProcessingProcedure, max_concurrency=1
  for psycopg single-connection concurrency limit)
- Update bash scripts to reference real module paths instead of placeholders
  and full module paths for --list (package path returns no entries)
…IDENTITY

ColumnConstraint(is_auto_increment=True) on PRIMARY_KEY was silently ignored,
producing INTEGER PRIMARY KEY without auto-increment. PostgreSQL requires
explicit GENERATED BY DEFAULT AS IDENTITY for auto-increment columns.
The existing dialect_options['identity'] path is unaffected.
Dialect-level tests (no DB needed) verifying:
1. is_auto_increment=True produces correct auto-increment DDL keyword
2. All standard types (Integer/Text/Boolean/VarChar/Timestamp) compile
3. BooleanType + DEFAULT True is accepted
4. TimestampType maps to correct backend-specific type

Prevents recurrence of bugs found in rbac cross-backend testing.
…nfig

The backend read config.autocommit (requires_manual_commit and the
auto-commit handlers in sync/async backends) to decide whether an
explicit COMMIT is needed outside managed transactions, but the field
did not exist on the dataclass, so passing autocommit=True raised a
TypeError and the option was effectively dead. All other backends
(mysql, sqlserver, clickhouse, snowflake, firebird) already declare it.

Replace the defensive getattr() fallbacks with direct attribute access
and add unit tests covering the default value, explicit assignment,
conninfo exclusion, and requires_manual_commit() for both backends.
Regression tests for qualifier generation vs FROM context: plain field
accessors, mixed/partial aliases, prebuilt-predicate reuse across
contexts, explicit-alias joins, and an xfail sentinel documenting the
accepted dynamic __table_name__ drift limitation. Companion to the
python-activerecord fix that stops forcing table-name aliases on JOIN
ranges.
Replace the R4 xfail sentinel with positive tests for the documented
contract: after changing __table_name__ / __schema_name__, expressions
built through field proxies pick up the new identity, and full DQL stays
consistent across FROM / WHERE / SELECT. Seed an archive table and a
second tenant-style schema so both switch directions assert real data.
Implements the optional setup_schema_fixtures capability: provisions
ar_crm / ar_shop schemas with customers and orders tables (sync + async
variants; DDL runs through a short-lived sync connection for async),
tracks created schemas, and drops them in cleanup_after_test. Declares
supports_schema() == True.
…ouble escaping

hstore_to_array_operator passed the already-escaped '%%' operator to
format_binary_operator, which escapes '%' again to '%%%%' (psycopg folds
to '%%' instead of the expected '%'). Pass the raw '%' so
format_binary_operator performs the single %->%% escape as the sole
collection point.
…olumns

PostgresListAdapter now parses JSON and PostgreSQL array literals via psycopg's
array loader when reading list fields stored in TEXT columns, fixing the
cross-backend round-trip exposed by stateflow tests.
…pe support

- Add vector_search.py function module with pgvector search capabilities
- Extend expression types with pgvector-related serialization
- Add data_type_formatting mixin improvements
- Add vector search and example compile test coverage
@vistart vistart self-assigned this Aug 28, 2026
@codecov

codecov Bot commented Aug 28, 2026 •

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 91.81287% with 14 lines in your changes missing coverage. Please review.
✅ Project coverage is 77.15%. Comparing base (beb040a) to head (7137cce).

Files with missing lines Patch % Lines
...tiverecord/backend/impl/postgres/cli/introspect.py 22.22% 7 Missing ⚠️
...d/backend/impl/postgres/functions/vector_search.py 95.91% 1 Missing and 1 partial ⚠️
...ackend/impl/postgres/introspection/introspector.py 77.77% 0 Missing and 2 partials ⚠️
...cord/backend/impl/postgres/mixins/introspection.py 81.81% 0 Missing and 2 partials ⚠️
...verecord/backend/impl/postgres/protocols/schema.py 50.00% 0 Missing and 1 partial ⚠️
Additional details and impacted files
@@                   Coverage Diff                    @@
##           release/v1.0.0.dev17      #55      +/-   ##
========================================================
+ Coverage                 74.67%   77.15%   +2.47%     
========================================================
  Files                       305      306       +1     
  Lines                     12380    12530     +150     
  Branches                   2001     2033      +32     
========================================================
+ Hits                       9245     9667     +422     
+ Misses                     2502     2172     -330     
- Partials                    633      691      +58     
Flag Coverage Δ
postgres-18 77.15% <91.81%> (+2.47%) ⬆️
python-3.14 77.15% <91.81%> (+2.47%) ⬆️
unittests 77.15% <91.81%> (+2.47%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

- extend PostgresListAdapter string parsing tests (JSON + PG array literal)
- add HALFVEC/SPARSEVEC DDL format/parse and eq/hash coverage
- cover vector_search edge cases (ip similarity, index options, invalid metric)
- add _get_default_schema config-aware resolution tests for both introspection stacks
- cover backend autocommit handler branches (sync + async, True/False)
- add CLI --ssl mapping and --async flag tests
- add CLI blackbox tests for introspect/status --async

fix(cli): correct async introspect method names (remove _async suffix)

The _handle_introspect_async path called nonexistent list_tables_async,
list_views_async etc. Async introspector methods use the same names as
sync (no _async suffix). Fixes broken async introspect branch.
CI runs against a fresh test_db where 'introspect tables' returns [],
so assert json.loads(out) (truthy) fails. Assert the parsed JSON is a
list instead, which holds whether or not tables exist.
The file name stateflow-cross-backend-issues.fixed.md does not follow
the <issue_number>.<type>.md convention. Its content was already
merged into the relevant fix commit.
@sonarqubecloud

Copy link
Copy Markdown

@vistart
vistart merged commit 6779f08 into release/v1.0.0.dev17 Aug 28, 2026
17 checks passed
vistart added a commit that referenced this pull request Sep 24, 2026
…ents (#55)

* feat: parallel scenario tests with per-worker database pooling

Wire the testsuite database pool for postgres: register the pool reset
handler, make scenario resolution pool-aware, install core and testsuite
from the feature/parallel-testing branches, and run tests with -n 8.

* fix(test): load testsuite conftest plugin and guard --scenarios registration

Without -p rhosocial.activerecord.testsuite.conftest the pooling hooks never
run, so configure_pool_size stays 0 and every xdist worker falls back to the
shared scenario database, racing on schema DDL. Load the plugin and guard the
backend's own --scenarios option so both conftests coexist.

* fix(test): apply pooled database names in backend and connection feature conftests

* fix(test): apply pooled database names in worker connection params

* fix(test): check for simultaneous double-hold instead of id uniqueness

* fix(test): use a non-empty LSN range for pg_get_wal_records_info

* feat: CLI async unification, --ssl param; postgres backend fixes

* feat(postgres): add named expression/procedure example modules

- Add named_expressions order_expressions (import-safe, prepare_orders_demo helper)
- Add named_procedures order_workflow (OrderProcessingProcedure, max_concurrency=1
  for psycopg single-connection concurrency limit)
- Update bash scripts to reference real module paths instead of placeholders
  and full module paths for --list (package path returns no entries)

* test(expression): add serialization round-trip coverage for PostgreSQL expressions

* fix(dialect): translate is_auto_increment to GENERATED BY DEFAULT AS IDENTITY

ColumnConstraint(is_auto_increment=True) on PRIMARY_KEY was silently ignored,
producing INTEGER PRIMARY KEY without auto-increment. PostgreSQL requires
explicit GENERATED BY DEFAULT AS IDENTITY for auto-increment columns.
The existing dialect_options['identity'] path is unaffected.

* test: add is_auto_increment/DDL regression tests

Dialect-level tests (no DB needed) verifying:
1. is_auto_increment=True produces correct auto-increment DDL keyword
2. All standard types (Integer/Text/Boolean/VarChar/Timestamp) compile
3. BooleanType + DEFAULT True is accepted
4. TimestampType maps to correct backend-specific type

Prevents recurrence of bugs found in rbac cross-backend testing.

* fix(config): declare missing autocommit field on PostgresConnectionConfig

The backend read config.autocommit (requires_manual_commit and the
auto-commit handlers in sync/async backends) to decide whether an
explicit COMMIT is needed outside managed transactions, but the field
did not exist on the dataclass, so passing autocommit=True raised a
TypeError and the option was effectively dead. All other backends
(mysql, sqlserver, clickhouse, snowflake, firebird) already declare it.

Replace the defensive getattr() fallbacks with direct attribute access
and add unit tests covering the default value, explicit assignment,
conninfo exclusion, and requires_manual_commit() for both backends.

* test: cover column qualifier resolution under JOINs

Regression tests for qualifier generation vs FROM context: plain field
accessors, mixed/partial aliases, prebuilt-predicate reuse across
contexts, explicit-alias joins, and an xfail sentinel documenting the
accepted dynamic __table_name__ drift limitation. Companion to the
python-activerecord fix that stops forcing table-name aliases on JOIN
ranges.

* test: cover dynamic table/schema names as supported usage

Replace the R4 xfail sentinel with positive tests for the documented
contract: after changing __table_name__ / __schema_name__, expressions
built through field proxies pick up the new identity, and full DQL stays
consistent across FROM / WHERE / SELECT. Seed an archive table and a
second tenant-style schema so both switch directions assert real data.

* feat(test): provide cross-schema fixtures for testsuite

Implements the optional setup_schema_fixtures capability: provisions
ar_crm / ar_shop schemas with customers and orders tables (sync + async
variants; DDL runs through a short-lived sync connection for async),
tracks created schemas, and drops them in cleanup_after_test. Declares
supports_schema() == True.

* feat(dialect): declare supports_schema capability and schema DDL tests

* fix(protocols): declare supports_schema and supports_schema_authorization in PostgresSchemaSupport

* test(provider): provision mixed default/non-default schema fixtures

* test(adapters): offline adapter round-trip coverage for all types

* docs: record stateflow cross-backend test issues (JSON/bool/RETURNING)

* fix(hstore): pass raw % operator to format_binary_operator to avoid double escaping

hstore_to_array_operator passed the already-escaped '%%' operator to
format_binary_operator, which escapes '%' again to '%%%%' (psycopg folds
to '%%' instead of the expected '%'). Pass the raw '%' so
format_binary_operator performs the single %->%% escape as the sole
collection point.

* fix(adapters): parse array literals on read for list fields in TEXT columns

PostgresListAdapter now parses JSON and PostgreSQL array literals via psycopg's
array loader when reading list fields stored in TEXT columns, fixing the
cross-backend round-trip exposed by stateflow tests.

* test: add format_binary_operator % escaping and hstore operator tests

* ci: update testsuite branch to release/v1.0.0.dev17

* ci: update rhosocial-activerecord branch to release/v1.0.0.dev30

* ci: update testsuite branch to release/v1.0.0.dev17

* feat(postgres): add pgvector vector_search function and expression type support

- Add vector_search.py function module with pgvector search capabilities
- Extend expression types with pgvector-related serialization
- Add data_type_formatting mixin improvements
- Add vector search and example compile test coverage

* test: add targeted coverage for low-coverage patch areas

- extend PostgresListAdapter string parsing tests (JSON + PG array literal)
- add HALFVEC/SPARSEVEC DDL format/parse and eq/hash coverage
- cover vector_search edge cases (ip similarity, index options, invalid metric)
- add _get_default_schema config-aware resolution tests for both introspection stacks
- cover backend autocommit handler branches (sync + async, True/False)
- add CLI --ssl mapping and --async flag tests
- add CLI blackbox tests for introspect/status --async

fix(cli): correct async introspect method names (remove _async suffix)

The _handle_introspect_async path called nonexistent list_tables_async,
list_views_async etc. Async introspector methods use the same names as
sync (no _async suffix). Fixes broken async introspect branch.

* fix(test): tolerate empty table list in introspect blackbox tests

CI runs against a fresh test_db where 'introspect tables' returns [],
so assert json.loads(out) (truthy) fails. Assert the parsed JSON is a
list instead, which holds whether or not tables exist.

* chore: add changelog fragment for PR #55

* docs: remove non-standard changelog fragment

The file name stateflow-cross-backend-issues.fixed.md does not follow
the <issue_number>.<type>.md convention. Its content was already
merged into the relevant fix commit.
@vistart
vistart deleted the feature/parallel-testing branch October 1, 2026 03:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant