carlos / platform Public

Clone
git clone https://amadan.net/carlos/platform

Plain git — no account needed to clone.

Download

Download this file

1package main
2
3import (
4 "strings"
5 "testing"
6 "time"
7
8 "github.com/carlosframework/platform/internal/dbdoor"
9)
10
11func TestParseDBAt(t *testing.T) {
12 now := time.Date(2026, 10, 8, 12, 0, 0, 0, time.UTC)
13 for _, ok := range []string{"2026-10-07T14:00:00Z", "2026-10-07T15:00:00+01:00", "2026-10-07T14:00:00.5Z"} {
14 got, err := parseDBAt(ok, now)
15 if err != nil {
16 t.Errorf("parseDBAt(%q) = %v, want a time", ok, err)
17 } else if !got.Before(now) {
18 t.Errorf("parseDBAt(%q) = %v, want before %v", ok, got, now)
19 }
20 }
21 // An explicit time that is Go's zero time must not read as "no --at"
22 // (found in Astra's review).
23 for _, early := range []string{"0001-01-01T00:00:00Z", "0001-01-01T01:00:00+01:00"} {
24 if got, err := parseDBAt(early, now); err != nil || got.IsZero() {
25 t.Errorf("parseDBAt(%q) = %v, %v, want a non-zero time before any history", early, got, err)
26 }
27 }
28 if got, _ := parseDBAt("", now); !got.IsZero() {
29 t.Errorf("parseDBAt(\"\") = %v, want zero (the newest copy)", got)
30 }
31 bad := map[string]string{
32 "2026-10-07 14:00": `--at "2026-10-07 14:00" is not a time. Write it in RFC 3339 with a time zone, for example 2026-10-07T14:00:00Z for UTC`,
33 "2026-10-07T14:00:00": `--at "2026-10-07T14:00:00" is not a time. Write it in RFC 3339 with a time zone, for example 2026-10-07T14:00:00Z for UTC`,
34 "yesterday": `--at "yesterday" is not a time. Write it in RFC 3339 with a time zone, for example 2026-10-07T14:00:00Z for UTC`,
35 "2026-10-09T00:00:00Z": `--at 2026-10-09T00:00:00Z is in the future. Leave --at out to read the newest copy`,
36 }
37 for in, want := range bad {
38 if _, err := parseDBAt(in, now); err == nil || err.Error() != want {
39 t.Errorf("parseDBAt(%q) = %v, want %q", in, err, want)
40 }
41 }
42}
43
44func TestDBRestoreErrorsForAnAsOfRead(t *testing.T) {
45 oldest := time.Date(2026, 10, 1, 9, 12, 44, 0, time.UTC)
46 cases := map[error]string{
47 &dbdoor.BeforeHistoryError{Oldest: oldest}: "a.go.tito.io's replica does not go back that far. The oldest point it keeps is 2026-10-01 09:12:44 UTC",
48 dbdoor.ErrNoTimes: "a.go.tito.io's replica can't be read as of a time yet. Leave --at out to read the newest copy",
49 }
50 for err, want := range cases {
51 if got := dbRestoreError("a.go.tito.io", err).Error(); got != want {
52 t.Errorf("%v -> %q, want %q", err, got, want)
53 }
54 }
55}
56
57func TestDBAsOfLines(t *testing.T) {
58 r := &dbdoor.Restored{TXID: 42, At: time.Date(2026, 10, 7, 13, 58, 2, 0, time.UTC)}
59 at := time.Date(2026, 10, 7, 15, 0, 0, 0, time.FixedZone("", 3600))
60 if got, want := dbPullHolds(r, at), "It holds every change up to transaction 42, written 2026-10-07 13:58:02 UTC, the last one replicated before 2026-10-07 14:00:00 UTC.\n"; got != want {
61 t.Errorf("pull with --at:\n got %q\nwant %q", got, want)
62 }
63 if got, want := dbPullHolds(r, time.Time{}), "It holds every change up to transaction 42, written 2026-10-07 13:58:02 UTC.\n"; got != want {
64 t.Errorf("pull without --at:\n got %q\nwant %q", got, want)
65 }
66 if got, want := dbQueryStatus("a.go.tito.io", r, at), "Querying a copy of a.go.tito.io's database as it was before 2026-10-07 14:00:00 UTC, up to transaction 42, written 2026-10-07 13:58:02 UTC. Nothing you run here reaches a.go.tito.io.\n"; got != want {
67 t.Errorf("query with --at:\n got %q\nwant %q", got, want)
68 }
69 if got, want := dbQueryStatus("a.go.tito.io", r, time.Time{}), "Querying a copy of a.go.tito.io's database, up to transaction 42, written 2026-10-07 13:58:02 UTC. Nothing you run here reaches a.go.tito.io.\n"; got != want {
70 t.Errorf("query without --at:\n got %q\nwant %q", got, want)
71 }
72 if !strings.Contains(dbUsage, "Add --at <time> to either verb") {
73 t.Error("dbUsage does not explain --at")
74 }
75}
76