| new file mode 100644 |
| index 000000000..3ca2ce158 |
| --- /dev/null |
| +++ b/internal/console/regiondrift_test.go |
| @@ -0,0 +1,121 @@ |
| +package console |
| + |
| +import ( |
| + "context" |
| + "strings" |
| + "testing" |
| + "time" |
| + |
| + "github.com/carlosframework/platform/internal/provision" |
| + "github.com/carlosframework/platform/internal/release" |
| +) |
| + |
| +// codex R2-6: shapes that never inherit the app default are not listed; |
| +// a no-region socket-backed instance created after the app is. |
| +func TestPlacementDiscrepancyLog(t *testing.T) { |
| + fx := newConsoleFixture(t) |
| + fx.srv.cfg.HomeRegion = "ie" |
| + created := time.Now().Add(-time.Hour) |
| + fx.st.CreateAppInRegion(OpsAccountID, "blog", "p@k.dev", "uk", "chosen", created) |
| + ctx := context.Background() |
| + put := func(r provision.Record) { |
| + r.Schema, r.App, r.Account, r.Channel, r.CreatedAt = 1, "blog", release.OpsAccount, "stable", time.Now() |
| + if err := provision.CreateRecord(ctx, fx.rel, r); err != nil { |
| + t.Fatal(err) |
| + } |
| + } |
| + put(provision.Record{Host: "blog.go.tito.io", Kind: "static"}) |
| + put(provision.Record{Host: "svc.go.tito.io", Kind: "service", Addrs: []string{"10.0.0.4:8080"}}) |
| + put(provision.Record{Host: "r.go.tito.io", Region: "au", Role: "replica"}) |
| + put(provision.Record{Host: "pooled.go.tito.io", Pool: "tito"}) |
| + put(provision.Record{Host: "uk.go.tito.io", Region: "uk"}) |
| + put(provision.Record{Host: "drift.go.tito.io"}) |
| + var logs strings.Builder |
| + restore := captureLog(&logs) |
| + fx.srv.LogPlacementDiscrepancies(ctx) |
| + restore() |
| + out := logs.String() |
| + if !strings.Contains(out, msgPlacementDiscrepancy("drift.go.tito.io", "blog", "uk")) { |
| + t.Fatalf("drift not listed: %s", out) |
| + } |
| + for _, quiet := range []string{"blog.go.tito.io", "svc.go.tito.io", "r.go.tito.io", "pooled.go.tito.io", "uk.go.tito.io"} { |
| + if strings.Contains(out, quiet+" of") { |
| + t.Errorf("%s listed", quiet) |
| + } |
| + } |
| +} |
| + |
| +// A record older than its app cannot be the roll-forward's work, so it is |
| +// not listed. |
| +func TestPlacementDiscrepancyLogSkipsRecordsOlderThanTheApp(t *testing.T) { |
| + fx := newConsoleFixture(t) |
| + fx.st.CreateAppInRegion(OpsAccountID, "blog", "p@k.dev", "uk", "chosen", time.Now().Add(-time.Hour)) |
| + ctx := context.Background() |
| + err := provision.CreateRecord(ctx, fx.rel, provision.Record{ |
| + Schema: 1, Host: "old.go.tito.io", App: "blog", Account: release.OpsAccount, |
| + Channel: "stable", CreatedAt: time.Now().Add(-2 * time.Hour), |
| + }) |
| + if err != nil { |
| + t.Fatal(err) |
| + } |
| + var logs strings.Builder |
| + restore := captureLog(&logs) |
| + fx.srv.LogPlacementDiscrepancies(ctx) |
| + restore() |
| + if strings.Contains(logs.String(), "old.go.tito.io") { |
| + t.Fatalf("older record listed: %s", logs.String()) |
| + } |
| +} |
| + |
| +// A bucket that cannot be listed is logged (O18) and never fails or panics: |
| +// the check is advisory. |
| +func TestPlacementDiscrepancyLogListError(t *testing.T) { |
| + fx := newConsoleFixture(t) |
| + fx.st.CreateAppInRegion(OpsAccountID, "blog", "p@k.dev", "uk", "chosen", time.Now()) |
| + fx.srv.cfg.Releases = failingList{fx.rel} |
| + var logs strings.Builder |
| + restore := captureLog(&logs) |
| + fx.srv.LogPlacementDiscrepancies(context.Background()) |
| + restore() |
| + want := "console: placement discrepancy check " + release.OpsAccount + "/blog: bucket unreachable" |
| + if !strings.Contains(logs.String(), want) { |
| + t.Fatalf("want %q in %s", want, logs.String()) |
| + } |
| +} |
| + |
| +// Past the cap the check says so (O9) instead of silently stopping. |
| +func TestPlacementDiscrepancyLogTruncated(t *testing.T) { |
| + fx := newConsoleFixture(t) |
| + fx.st.CreateAppInRegion(OpsAccountID, "blog", "p@k.dev", "uk", "chosen", time.Now().Add(-time.Hour)) |
| + ctx := context.Background() |
| + for _, h := range []string{"a.go.tito.io", "b.go.tito.io"} { |
| + err := provision.CreateRecord(ctx, fx.rel, provision.Record{ |
| + Schema: 1, Host: h, App: "blog", Account: release.OpsAccount, |
| + Channel: "stable", CreatedAt: time.Now(), |
| + }) |
| + if err != nil { |
| + t.Fatal(err) |
| + } |
| + } |
| + var logs strings.Builder |
| + restore := captureLog(&logs) |
| + fx.srv.logPlacementDiscrepancies(ctx, 1) |
| + restore() |
| + want := "console: placement discrepancy check " + release.OpsAccount + "/blog: only the first 1 records were checked" |
| + if !strings.Contains(logs.String(), want) { |
| + t.Fatalf("want %q in %s", want, logs.String()) |
| + } |
| +} |
| + |
| +// No deployment bucket: nothing to check, nothing logged. |
| +func TestPlacementDiscrepancyLogNoBucket(t *testing.T) { |
| + fx := newConsoleFixture(t) |
| + fx.srv.cfg.Releases = nil |
| + var logs strings.Builder |
| + restore := captureLog(&logs) |
| + fx.srv.LogPlacementDiscrepancies(context.Background()) |
| + restore() |
| + if logs.Len() != 0 { |
| + t.Fatalf("logged: %s", logs.String()) |
| + } |
| +} |