Skip to content

Cover dbtest's infrastructure-failure branches behind a testing.T interface #19

Description

@jbrahy

Follow-up from #6, which was closed with this explicitly left open.

internal/dbtest is the lowest-coverage package (~66%). Every remaining uncovered line in SetupDB is a t.Fatalf branch that fires only when MySQL breaks mid-call: CREATE DATABASE fails, the fresh pool cannot ping, migrations fail against a database created a moment earlier.

Those cannot be reached today, because triggering them means the helper fails its own test.

The approach

Introduce a narrow interface over the testing.T methods SetupDB actually uses:

type testingT interface {
    Helper()
    Skipf(format string, args ...any)
    Fatalf(format string, args ...any)
    Logf(format string, args ...any)
    Cleanup(func())
}

Keep SetupDB(t *testing.T) *sql.DB as the public signature so no caller changes, and have it delegate to setupDB(t testingT). Tests then pass a fake that records calls instead of aborting.

The one subtlety: real Fatalf calls runtime.Goexit(), so a fake has to stop execution somehow — panic with a sentinel and recover in the test is the usual approach. Get that right or the tests will pass for the wrong reason.

To actually trigger a CREATE DATABASE failure you will likely want a privilege-restricted MySQL user (GRANT SELECT ON *.* only). That is why this was not done inline: it couples the suite to environment setup, including CI. Worth doing if you can keep the coupling contained — e.g. skip those specific tests when the restricted user is absent, rather than requiring it everywhere.

Why it matters

SetupDB is called by every database-backed test in the repo. Its failure paths are the ones that decide whether a broken environment is reported or silently skipped — and there is prior art for getting that wrong here: SetupDB used to skip under CI, which meant a wrong DSN produced a green run that exercised no SQL at all (fixed in 6d82e77).

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    area:backendGo / MySQL sidegood-first-issueSmall, well-scoped, no deep system knowledge required. Start here.

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions