Files
goclaw/internal/backup/db_dump_test.go
T
Duc Nguyen 52f48e5ea6 fix(backup): detect pg server major for version-aware pg_dump hints (#829) (#830)
* fix(backup): detect pg server major for version-aware pg_dump hints

pg_dump aborts when its major version is older than the server's, so
backup preflight now runs SHOW server_version_num against the live PG
server and uses the detected major to drive:

- the missing-pg_dump hint (names the exact postgresqlNN-client)
- a new compat check that flags an installed-but-too-old pg_dump as
  not-ready, instead of letting backup fail partway through the dump

Adds ParsePgDumpMajor helper for Debian/Homebrew/EDB output shapes,
covered by table-driven unit tests. Normalizes nil ctx once at
RunPreflight boundary so downstream exec.CommandContext calls are safe.
Stubs detectPGServerMajor + checkPgDumpServerCompat for the sqliteonly
build.

UI: removes the duplicate static hint from the preflight alert box so
the dynamic, actionable warning is the single source of truth. Drops
the obsolete pgDumpHint i18n key from en/vi/zh locale files.

Refs #829

* fix(docker): bump runtime base alpine 3.22 → 3.23

Alpine 3.23 main ships postgresql16-client, postgresql17-client, and
postgresql18-client simultaneously. Alpine 3.22 only shipped up to
postgresql17-client, so the backup preflight's dynamic hint to install
postgresql18-client previously failed with "no such package" on PG 18
deployments.

No client package is pre-bundled: the on-demand install via the
Packages page now resolves for any supported PG major.

Refs #829
2026-04-11 21:22:04 +07:00

32 lines
719 B
Go

//go:build !sqliteonly
package backup
import "testing"
func TestParsePgDumpMajor(t *testing.T) {
cases := []struct {
in string
want int
}{
{"pg_dump (PostgreSQL) 17.9 (Debian 17.9-1.pgdg12+1)", 17},
{"pg_dump (PostgreSQL) 18.3", 18},
{"pg_dump (PostgreSQL) 18.3 (Homebrew)", 18},
{"pg_dump (PostgreSQL) 10.21", 10},
{"pg_dump (PostgreSQL) 9.6.24", 9},
{"pg_dump (PostgreSQL) 18", 18},
// Parse failures → 0
{"", 0},
{"pg_dump unknown", 0},
{"pg_dump (PostgreSQL) vNext", 0},
}
for _, tc := range cases {
t.Run(tc.in, func(t *testing.T) {
got := ParsePgDumpMajor(tc.in)
if got != tc.want {
t.Errorf("ParsePgDumpMajor(%q) = %d, want %d", tc.in, got, tc.want)
}
})
}
}