mirror of
https://tangled.org/evan.jarrett.net/at-container-registry
synced 2026-09-23 10:44:16 +00:00
`go fix` carries the modernize analyzers now, and the tree had drifted behind
them. This is the mechanical result, reviewed rather than trusted: the tool is
capable of rewriting code into something that no longer tests or does what it
did, so every non-test change was read individually and the concurrency-bearing
packages were re-run under -race.
Production code, four changes, all semantics-preserving:
- leases/manager.go: wg.Add(1) + go + defer wg.Done() becomes wg.Go. The
comment above that function turns on Add happening before the goroutine
starts, so that a Wait cannot return before the worker has run. wg.Go does
the Add synchronously on the calling goroutine, so the invariant it
describes still holds.
- auth/token/handler.go: strings.Fields -> strings.FieldsSeq, same splitting,
iterated rather than allocated.
- hold/gc/gc.go: a hand-written map copy -> maps.Copy.
- hold/pds/scan_broadcaster.go: three-clause loop -> range over int.
The rest are tests. The one worth naming is carstore_contention_test.go, where a
careless rewrite could have quietly stopped exercising contention: go fix
converted the reader and side-table goroutines to loopWG.Go but correctly
declined to touch the writer loop, which passes its index as a parameter. The
writer/reader/side-table shape and the stop channel are unchanged, so the test
still contends over the same carstore transactions.
Verified: go build for hold and appview, `make lint` 0 issues, the deploy and
credential-helper modules 0 issues, `make test` green across all 43 packages,
and -race green on leases, hold/pds, hold/gc and auth/token. The scanner module's
two lint findings are unchanged from HEAD and are in files go fix never touched.
Kept separate from the HTTP/2 commit so that one stays readable, and so this can
be reverted on its own if a modernization turns out to matter.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TA9D4DjaLZTvzQ7dJbu4eg
94 lines
2.6 KiB
Go
94 lines
2.6 KiB
Go
package db
|
|
|
|
import (
|
|
"context"
|
|
"database/sql"
|
|
"path/filepath"
|
|
"testing"
|
|
)
|
|
|
|
// assertPoolSettings checks journal mode and busy_timeout on several
|
|
// simultaneously held connections. Holding them at once forces database/sql to
|
|
// open distinct connections: busy_timeout is per-connection, so a regression to
|
|
// a one-shot "PRAGMA busy_timeout" on the pool shows up on conn 1 onward.
|
|
func assertPoolSettings(t *testing.T, label string, db *sql.DB, wantJournal string, wantBusy int) {
|
|
t.Helper()
|
|
ctx := context.Background()
|
|
|
|
const n = 4
|
|
conns := make([]*sql.Conn, 0, n)
|
|
defer func() {
|
|
for _, c := range conns {
|
|
_ = c.Close()
|
|
}
|
|
}()
|
|
for i := range n {
|
|
c, err := db.Conn(ctx)
|
|
if err != nil {
|
|
t.Fatalf("%s: open conn %d: %v", label, i, err)
|
|
}
|
|
conns = append(conns, c)
|
|
}
|
|
|
|
for i, c := range conns {
|
|
var journal string
|
|
if err := c.QueryRowContext(ctx, "PRAGMA journal_mode").Scan(&journal); err != nil {
|
|
t.Fatalf("%s conn %d: read journal_mode: %v", label, i, err)
|
|
}
|
|
if journal != wantJournal {
|
|
t.Errorf("%s conn %d: journal_mode = %q, want %q", label, i, journal, wantJournal)
|
|
}
|
|
|
|
var busy int
|
|
if err := c.QueryRowContext(ctx, "PRAGMA busy_timeout").Scan(&busy); err != nil {
|
|
t.Fatalf("%s conn %d: read busy_timeout: %v", label, i, err)
|
|
}
|
|
if busy != wantBusy {
|
|
t.Errorf("%s conn %d: busy_timeout = %d, want %d", label, i, busy, wantBusy)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestOpenLocalDBSettingsOnEveryConnection(t *testing.T) {
|
|
path := filepath.Join(t.TempDir(), "db.sqlite3")
|
|
db, err := OpenLocalDB(path)
|
|
if err != nil {
|
|
t.Fatalf("OpenLocalDB: %v", err)
|
|
}
|
|
defer db.Close()
|
|
assertPoolSettings(t, "OpenLocalDB", db, "wal", DefaultBusyTimeoutMs)
|
|
}
|
|
|
|
func TestOpenHoldDBSettingsOnEveryConnection(t *testing.T) {
|
|
path := filepath.Join(t.TempDir(), "db.sqlite3")
|
|
h, err := OpenHoldDB(path, LibsqlConfig{})
|
|
if err != nil {
|
|
t.Fatalf("OpenHoldDB: %v", err)
|
|
}
|
|
defer h.Close()
|
|
assertPoolSettings(t, "OpenHoldDB", h.DB, "wal", DefaultBusyTimeoutMs)
|
|
}
|
|
|
|
func TestCarstoreSettingsOnEveryConnection(t *testing.T) {
|
|
sqs, err := NewSqliteStore(t.TempDir())
|
|
if err != nil {
|
|
t.Fatalf("NewSqliteStore: %v", err)
|
|
}
|
|
defer sqs.Close()
|
|
assertPoolSettings(t, "carstore", sqs.DB(), "wal", DefaultBusyTimeoutMs)
|
|
}
|
|
|
|
// TestOpenLocalDBMemory documents that ":memory:" is left unwrapped: libsql
|
|
// gives each connection its own private database, so there is no shared lock to
|
|
// wait on and WAL does not apply.
|
|
func TestOpenLocalDBMemory(t *testing.T) {
|
|
db, err := OpenLocalDB(":memory:")
|
|
if err != nil {
|
|
t.Fatalf("OpenLocalDB(:memory:): %v", err)
|
|
}
|
|
defer db.Close()
|
|
if err := db.Ping(); err != nil {
|
|
t.Fatalf("ping in-memory db: %v", err)
|
|
}
|
|
}
|