Skip to content

Empty the compliance database with one script - #12

Merged
lemenkov merged 1 commit into
masterfrom
reset-test-schema-script
Sep 12, 2026
Merged

lemenkov merged 1 commit into
masterfrom
reset-test-schema-script

Conversation

@lemenkov

Copy link
Copy Markdown
Member

prepare_test_schema.py builds the accounts the suite needs. Nothing emptied them afterwards.

The suite compares whole object lists — ComponentReflectionTest asserts on the set of tables a schema contains — so tables left by an earlier run fail tests that have nothing to do with them. CI never meets this because it starts a throwaway database per run; a database you keep accumulates, and the local pass count drifts away from CI's for reasons that look like driver bugs.

Measured against a database used for a day of work, through Mirror-over-PostgreSQL:

before:   50 failed, 963 passed
after:  1013 passed, 0 failed      <- the number CI reports

That was the first time the documented baseline has been reproduced locally.

How it works

Objects are found and dropped through the Oracle data dictionary over an ordinary connection, not with SQL for one particular backend, so the same script resets a real Oracle and a Mirror standing in front of PostgreSQL. Verified on both.

It only reports by default

Not ceremony. An earlier draft queried an unqualified user_tables and offered to drop pg_publication, pg_largeobject, sql_features — 103 objects, the server's own catalogs. The dry-run default is what caught it.

The dictionary lookups are schema-qualified for that reason: against Mirror-over-PostgreSQL, sys.user_tables answers with the 4 real leftovers where the bare name answers with 73 rows of PostgreSQL catalogs. That difference is a Mirror gap and will be reported separately — applications write FROM user_tables, not FROM sys.user_tables.

Two fallbacks for cross-backend behaviour

  • CASCADE CONSTRAINTS then plain DROP — Oracle will not drop a table a foreign key references without the former; the Mirror rejects that spelling (ORA-00900).
  • Bare name then quoted name — the dictionary reports names in Oracle's folded upper-case form, while the PostgreSQL table is really lower-case, so quoting asks for an object that does not exist. The quoted spelling still follows, for the mixed-case and reserved-word objects the suite creates on purpose.

Honest reporting

The run reports how many of the objects it found were actually removed, and exits non-zero when those differ. An earlier version of this script printed "4 object(s) dropped" when all four had failed — it counted what it found. A reset that claims success it did not achieve is worse than one that fails loudly, because the next suite run inherits the mess and blames itself.

prepare_test_schema.py builds the accounts the suite needs. Nothing emptied
them afterwards, and the suite compares whole object lists --
ComponentReflectionTest asserts on the set of tables a schema contains -- so
tables left by an earlier run fail tests that have nothing to do with them. CI
never meets this because it starts a throwaway database per run; a database you
keep accumulates, and the local pass count drifts away from CI's for reasons
that look like driver bugs. Measured against a database used for a day:
963 passed / 50 failed, where CI reports 1013 / 0. After this script: 1013 / 0.

Objects are found and dropped through the Oracle data dictionary over an
ordinary connection rather than with SQL for one backend, so the same script
resets a real Oracle and a Mirror standing in front of PostgreSQL. Verified on
both.

It only reports by default. That is not ceremony: the first run of an earlier
draft, which queried an unqualified user_tables, offered to drop pg_publication,
pg_largeobject and sql_features -- 103 objects, the server's own catalogs. The
dictionary lookups are schema-qualified for that reason; sys.user_tables answers
with the 4 real leftovers where the bare name answers with 73 rows of
PostgreSQL. That difference is a Mirror gap worth its own report.

Two fallbacks keep it working on both targets. A table is dropped with CASCADE
CONSTRAINTS first, because Oracle will not drop a table a foreign key references
without it, and with a plain DROP after, because the Mirror rejects that
spelling. The bare name is tried before the quoted one, because the dictionary
reports names in Oracle's folded upper-case form while the PostgreSQL table is
really lower-case, so quoting asks for an object that does not exist; the quoted
spelling still follows for the mixed-case objects the suite creates on purpose.

The run reports how many of the objects it found were actually removed, and
exits non-zero when those differ. A reset that claims success it did not achieve
is worse than one that fails loudly: the next suite run inherits the mess and
blames itself.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Signed-off-by: Peter Lemenkov <lemenkov@gmail.com>
@lemenkov
lemenkov merged commit dfb4bc4 into master Sep 12, 2026
15 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant