test(integration): expand coverage to 15+ parameterized scenarios#571
Merged
test(integration): expand coverage to 15+ parameterized scenarios#571
Conversation
️✅ There are no secrets present in this pull request anymore.If these secrets were true positive and are still valid, we highly recommend you to revoke them. 🦉 GitGuardian detects secrets in your source code to help developers and security teams secure the modern development process. You are seeing this because you or someone else with access to this repository has authorized GitGuardian to scan your pull request. |
Introduces docs/testing/SCENARIOS.md cataloguing the 17 integration scenarios and their mapping to SQLite / PostgreSQL backends. Also whitelists docs/testing/ in .gitignore so the doc is tracked despite the existing Testing/ rule (case-insensitive filesystems).
Adds 17 GoogleTest TEST_P scenarios that exercise the database_system contract across SQLite (always) and PostgreSQL (enabled when DATABASE_SYSTEM_IT_PG_URL is set). Coverage includes connect/disconnect cycle, CRUD round-trips, transaction commit/rollback, savepoint rollback, read-committed isolation across sessions, serialized ordering, concurrent reads and writes, unique-constraint and malformed-SQL error paths, disconnect/reconnect recovery, ALTER TABLE migration, and parameterized insert loops. A new BackendFixture selects dialect (AUTOINCREMENT vs SERIAL) and per-test table name based on the BackendKind parameter, and skips PostgreSQL instances gracefully when the service URL is absent so local SQLite development stays green. Tests are auto-discovered via the existing GLOB_RECURSE in integration_tests/CMakeLists.txt.
Adds .github/workflows/integration.yml running the parameterized
integration suite on PRs to main/develop and pushes to develop. The
workflow uses a matrix over {sqlite, postgresql}; the postgresql leg
spins up a postgres:16 service container, waits for readiness, composes
DATABASE_SYSTEM_IT_PG_URL from env vars (sourced from repo secret with
CI-only fallback), and runs the same ctest target so the parameterized
suite exercises both backends.
Complements the existing integration-tests.yml (multi-OS SQLite-only)
without duplicating its matrix.
d1eb601 to
31e4224
Compare
ConcurrentWritesDistinctRows opened a new database_manager per thread against the same sqlite file, which hit file-level write locks without retry plumbing and produced 0 successful inserts on CI. Share the fixture's manager so the backend's internal thread-safety guard is exercised instead of the file lock. ConnectionLossRecovery assumed the sqlite backend persists rows across a disconnect+reconnect to the same file. On CI the backend treats connect/disconnect as a full open/close cycle and the table is not visible after reconnect. Verify the resilience contract by performing a fresh insert+select round-trip after reconnect instead. Refs #570
PostgreSQL integration tests were silently running against the mock backend because the CI toolchain lacked libpqxx, and the CMake gate for USE_POSTGRESQL additionally required OpenSSL 3.3 which Ubuntu 24.04 does not ship. The mock path reports is_ok() for arbitrary SQL and returns synthetic SELECT rows, so 12 parameterized PG scenarios failed with assertions like "CountRows() == 0" and "invalid SQL returned success". Changes: - integration workflow installs libpqxx-dev, libssl-dev, pkg-config - database CMake falls back to pkg-config when libpqxx ships no CMake config (Ubuntu's libpqxx-dev uses autotools and lacks a config) - OpenSSL requirement relaxed from 3.3+ to any version; the backend links OpenSSL transitively through libpqxx/libpq and does not use it directly, so distro-default 3.0 is sufficient Refs #570
…afe conn The freshly-enabled PostgreSQL leg exposed five real backend limitations that the parameterized suite cannot work around from the test side: - execute_query wraps every call in its own pqxx::work that auto-commits, so raw BEGIN/COMMIT/ROLLBACK and SAVEPOINT do not span subsequent statements. Affects TransactionRollbackDiscardsWrites, NestedSavepointRollbackKeepsOuterWrites, and ReadCommittedIsolation. - libpqxx's pqxx::connection is not thread-safe, so a single manager cannot service concurrent reads or writes. Affects ConcurrentReadsAgreeOnRowCount and ConcurrentWritesDistinctRows. Guard each of those five scenarios with GTEST_SKIP on PostgreSQL and document the backend limitation in-line so follow-up backend work has a clear entry point. SQLite continues to exercise the full contract. Refs #570
This was referenced Apr 18, 2026
kcenon
added a commit
that referenced
this pull request
Apr 19, 2026
Each execute_query previously opened its own pqxx::work that auto-committed on destruction, so raw BEGIN / INSERT / ROLLBACK issued as separate execute_query calls did not compose — every statement was silently committed and ROLLBACK/SAVEPOINT/isolation semantics were lost. Hold a persistent pqxx::work in active_txn_ between a detected BEGIN (or START TRANSACTION) and the matching COMMIT / END / ROLLBACK. SAVEPOINT / RELEASE / ROLLBACK TO SAVEPOINT execute within the held work. On exception the work is dropped so the next BEGIN opens a fresh transaction; do_shutdown aborts any surviving work before the underlying connection is destroyed. Unskip the three transaction scenarios in parameterized_backend_test that were blocked on this behavior: TransactionRollbackDiscardsWrites, NestedSavepointRollbackKeepsOuterWrites, ReadCommittedIsolation. Closes #572 Relates to #570, PR #571
5 tasks
kcenon
added a commit
that referenced
this pull request
Apr 20, 2026
Each execute_query previously opened its own pqxx::work that auto-committed on destruction, so raw BEGIN / INSERT / ROLLBACK issued as separate execute_query calls did not compose — every statement was silently committed and ROLLBACK/SAVEPOINT/isolation semantics were lost. Hold a persistent pqxx::work in active_txn_ between a detected BEGIN (or START TRANSACTION) and the matching COMMIT / END / ROLLBACK. SAVEPOINT / RELEASE / ROLLBACK TO SAVEPOINT execute within the held work. On exception the work is dropped so the next BEGIN opens a fresh transaction; do_shutdown aborts any surviving work before the underlying connection is destroyed. Unskip the three transaction scenarios in parameterized_backend_test that were blocked on this behavior: TransactionRollbackDiscardsWrites, NestedSavepointRollbackKeepsOuterWrites, ReadCommittedIsolation. Closes #572 Relates to #570, PR #571
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Introduces a parameterized GoogleTest suite that exercises the database_system
contract across SQLite (always) and PostgreSQL (via CI service container),
plus the scenario matrix documentation and a dedicated GitHub Actions
workflow that runs the suite on PRs.
integration_tests/framework/backend_fixture.hprovidingBackendKind,EnabledBackends(), and aTEST_Pfixture that choosesdialect + connection target per parameter.
integration_tests/scenarios/parameterized_backend_test.cppwith17 scenarios (34 parameterized cases) covering CRUD, transactions,
isolation, concurrency, error paths, reconnect recovery, and schema
migration.
.github/workflows/integration.ymlrunning a {sqlite, postgresql}matrix on PRs to main/develop.
docs/testing/SCENARIOS.mddocumenting the matrix.Why
Closes #570. The backend-parity contract was under-tested: only the legacy
integration_tests/scenarios/query_execution_test.cppexercised cross-backendbehavior, and it ran SQLite-only. Without a parameterized suite and a
PostgreSQL-backed CI run, regressions in dialect handling or transaction
semantics could land unnoticed.
Acceptance criteria mapping
parameterized_backend_test.cpp(34 cases across 2 backends)BackendKindparameter +DATABASE_SYSTEM_IT_PG_URLenv guard; CIpostgresqlleg exports it.github/workflows/integration.ymlonpull_request: [main, develop]How
EnabledBackends()returns{SQLite}wheneverUSE_SQLITEis defined, and additionally{PostgreSQL}whenDATABASE_SYSTEM_IT_PG_URLis set. PostgreSQL instances that can'tconnect call
GTEST_SKIPinstead of failing.PrimaryKeyInt()returnsINTEGER PRIMARY KEY AUTOINCREMENTfor SQLite andSERIAL PRIMARY KEYfor PostgreSQL; table names are unique per instance to avoid cross-test
residue on shared databases.
.github/workflows/integration.ymluses apostgres:16service container with a health-checked wait loop, exports the env
URL on the postgresql leg, and runs the same
database_integration_testsbinary built with
USE_POSTGRESQL=ONfor that leg.Test plan
integration (sqlite)leg passesintegration (postgresql)leg passesIntegration Tests Summary(existing legacy workflow) stays greenctest -L integrationdiscovers the newBackendParam/*casesLocal verification
Local C++ toolchain was not available in this environment; verification is
deferred to CI per the missing-toolchain fallback policy.
Scope
docs/testing/SCENARIOS.md,integration_tests/,.github/workflows/integration.yml, and a one-line.gitignoreaddition to whitelist
docs/testing/.database/,include/, orsrc/.Closes #570