package appbackup import ( "compress/gzip" "errors" "os" "path/filepath" "testing" ) // R-640: CheckDumpComplete reads the END of the copy. pg_dump 17.6+ prints `\unrestrict ` after // its marker, so the marker need not be the last line. func TestR640_CheckDumpComplete(t *testing.T) { dir := t.TempDir() big := make([]byte, 200*1024) // longer than the kept tail: the marker must be found at the END for i := range big { big[i] = 'x' } cases := []struct { name, body string t DBType gz, ok bool }{ {"pg complete", "-- PostgreSQL database dump\nCOPY t FROM stdin;\n1\n\\.\n\n--\n-- PostgreSQL database dump complete\n--\n\n\\unrestrict abc\n", DBTypePostgres, false, true}, {"pg cut inside COPY", "-- PostgreSQL database dump\nCOPY t FROM stdin;\n1\n", DBTypePostgres, false, false}, {"pg marker only at the start is not an end", "-- PostgreSQL database dump complete\n" + string(big) + "\n", DBTypePostgres, false, false}, {"pg complete, gzipped", "-- PostgreSQL database dump\n" + string(big) + "\n-- PostgreSQL database dump complete\n", DBTypePostgres, true, true}, {"pg cut, gzipped", "-- PostgreSQL database dump\n" + string(big), DBTypePostgres, true, false}, {"mariadb complete", "-- MariaDB dump 10.19\nINSERT INTO `t` VALUES (1);\n-- Dump completed on 2026-09-23\n", DBTypeMariaDB, false, true}, {"mariadb cut", "-- MariaDB dump 10.19\nINSERT INTO `t` VALUES (1),(2", DBTypeMariaDB, false, false}, {"unknown engine never passes", "anything\n-- Dump completed\n", DBType("sqlite"), false, false}, } for i, c := range cases { p := filepath.Join(dir, "d"+string(rune('a'+i))+".sql") if c.gz { p += ".gz" f, _ := os.Create(p) w := gzip.NewWriter(f) w.Write([]byte(c.body)) w.Close() f.Close() } else if err := os.WriteFile(p, []byte(c.body), 0o644); err != nil { t.Fatal(err) } err := CheckDumpComplete(p, c.t) if (err == nil) != c.ok { t.Errorf("%s: ok=%v, got err=%v", c.name, c.ok, err) } if !c.ok && c.t != "sqlite" && !errors.Is(err, ErrDumpIncomplete) { t.Errorf("%s: want ErrDumpIncomplete, got %v", c.name, err) } } }