Skip to content

Flaky: DatabaseWithTablesTests.detect_and_apply_schema_changes races other collections over the shared 'public' schema #407

Description

@jeremydmiller

Found while validating #405. Pre-existing on master — not introduced by any open PR.

Symptom

DatabaseWithTablesTests.detect_and_apply_schema_changes fails intermittently in a full-suite run, roughly 1 in 3–6 runs locally, with either of two errors:

Npgsql.PostgresException : XX000: could not open relation with OID 659774
  at Weasel.Postgresql.Tables.Table.readIndexesAsync(...) Table.FetchExisting.cs:365
  at Weasel.Postgresql.Tables.Table.readExistingAsync(...) Table.FetchExisting.cs:174
  at Weasel.Core.SchemaMigration.DetermineAsync(...) SchemaMigration.cs:84
  at ...DatabaseWithTablesTests.detect_and_apply_schema_changes() line 66
Npgsql.PostgresException : 42P01: relation "public.dwt_contacts" does not exist

Reproduced on clean master (3 runs to first failure) and on a feature branch (4 runs). It never fails when the class is run in isolation — 8 filtered runs, zero failures. So it is cross-collection interference, not a bug in the test's own logic.

Cause

The test creates its tables in the public schema:

var db = new DatabaseWithTables("test", theDataSource);
var table = db.AddTable(new PostgresqlObjectName("public", "dwt_contacts"));

but its ResetSchema() resets SchemaName"integration" for this class — so public is never isolated. Meanwhile at least ten other test files also work in public:

PostgresqlMigratorTests, create_and_teardown_schemas, Tables/TableTests, Tables/IndexDefinitionTests, Tables/creating_tables_in_database, Tables/ForeignKeyTests, Tables/Indexes/FullTextIndexDefinitionTests, Functions/FunctionBodyTests, Views/ViewTests.

[Collection("integration")] serialises this class against others in that collection, but xUnit runs different collections in parallel. So another collection can drop or recreate objects in public while this test's introspection query is mid-flight:

  • 42P01 — the table is dropped between apply and assert.
  • XX000: could not open relation with OID — classic Postgres catalog race: readIndexesAsync scans pg_index/pg_class, and the relation is dropped between the catalog row being read and the relation being opened.

Suggested direction

Give the test its own schema instead of public, e.g. new PostgresqlObjectName("integration", "dwt_contacts") so ResetSchema() actually covers it. The sibling apply_migration_creates_tables (public.dwt_users) has the same exposure.

More broadly, tests sharing public across parallel collections is a standing hazard here — worth deciding whether public should be off-limits for anything that creates or drops objects.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions