// canary_region_e2e_test.go package main import ( "context" "errors" "fmt" "os" "strings" "testing" "time" "github.com/carlosframework/platform/internal/console" "github.com/carlosframework/platform/internal/provision" "github.com/carlosframework/platform/internal/release" ) // hasRefusalLine reports whether a whole output line is want, behind at most // the log package's own timestamp. A swap of two adjacent arguments in the // sentence is a different line and fails. func hasRefusalLine(out, want string) bool { for _, l := range strings.Split(out, "\n") { l = strings.TrimSpace(l) if l == want { return true } // "2006/01/02 15:04:05 " is 20 bytes. if len(l) > 20 && l[4] == '/' && l[7] == '/' && l[10] == ' ' && l[13] == ':' && l[16] == ':' && l[19] == ' ' && l[20:] == want { return true } } return false } // Two identical runs per case: the same refusal both times, and no write, // no new record, no manifest and no upload, before or after. func TestCanaryRegionRefusesBeforeAnyWrite(t *testing.T) { const existing = "probe-titogo.bab.oncarlos.test" cases := []struct { name, mode, region string fleet, canary bool ahead int // records whose hosts sort before the canary's unreadable bool // the canary's record cannot be read want string }{ {"fleet-placed app", "", "uk", true, false, 0, false, canaryRegionOnFleet("titogo", "acme")}, {"older console", "legacy", "uk", true, false, 0, false, canaryFleetUnknown("titogo")}, {"placement unknown", "placement-unknown", "uk", false, false, 0, false, canaryFleetUnknown("titogo")}, {"existing canary elsewhere", "", "ie", false, true, 0, false, canaryRegionMismatch(existing, "uk")}, // codex plan-R3 1: past the list's 500-record cap, and unreadable // (a list skips it), the canary's own record still decides. {"existing canary past the list cap", "", "ie", false, true, 520, false, canaryRegionMismatch(existing, "uk")}, {"existing canary unreadable", "", "ie", false, true, 0, true, canaryRegionUnconfirmed("probe")}, // codex plan-R4 1: a fleet-placed app whose stored region the console // could not read; R9a leaves effective empty, and the flag is refused. {"fleet, region unknown", "region-unknown", "uk", true, false, 0, false, canaryFleetUnknown("titogo")}, } for _, c := range cases { t.Run(c.name, func(t *testing.T) { e := regionE2EConsole(t, "") ctx := context.Background() if c.fleet { if err := e.cst.SetAppPlacement(console.OpsAccountID, "titogo", "fleet/acme"); err != nil { t.Fatal(err) } } for i := 0; i < c.ahead; i++ { h := fmt.Sprintf("a%03d.titogo.bab.oncarlos.test", i) rec := provision.Record{Schema: 1, Host: h, App: "titogo", Account: release.OpsAccount, Channel: "stable", CreatedAt: time.Now().UTC()} if err := provision.CreateRecord(ctx, e.store, rec); err != nil { t.Fatal(err) } } if c.canary { rec := provision.Record{Schema: 1, Host: existing, App: "titogo", Account: release.OpsAccount, Region: "uk", Channel: "canary/probe", CreatedAt: time.Now().UTC()} if err := provision.CreateRecord(ctx, e.store, rec); err != nil { t.Fatal(err) } } if c.unreadable { e.failGet.Store(provision.RecordKey(release.OpsAccount, "titogo", existing)) } e.mode.Store(c.mode) for run := 0; run < 2; run++ { out, err := e.run(t, "canary", "deploy", "--app", "titogo", "--name", "probe", "--region", c.region, "--console", e.url, "--version", "abc1234", "--timeout", "1s", artifact(t)) if err == nil || !hasRefusalLine(out, "canary: "+c.want) { t.Fatalf("run %d: err=%v out=%s, want the whole line %q", run, err, out, "canary: "+c.want) } } recs, _, err := provision.ListRecords(ctx, e.store, release.OpsAccount, "titogo", 1000) if err != nil { t.Fatal(err) } wantRecs := c.ahead if c.canary { wantRecs++ } if len(recs) != wantRecs || e.writes.Load() != 0 || e.releases(t) != 0 { t.Fatalf("records %d (want %d), writes %d, releases %d; want nothing written", len(recs), wantRecs, e.writes.Load(), e.releases(t)) } if c.canary { rec, err := provision.GetRecord(ctx, e.store, release.OpsAccount, "titogo", existing) if err != nil || rec.Region != "uk" { t.Fatalf("the existing canary = %+v %v, want it still in uk", rec, err) } } if _, err := provision.GetManifest(ctx, e.store, release.OpsAccount, "titogo"); !errors.Is(err, os.ErrNotExist) { t.Fatalf("an instances manifest was written: %v", err) } }) } } // codex plan-R5 1: a same-region canary past the list's 500-record cap is // the record the command reuses, found by the direct read, never re-created. // On its own channel it is left as it is; on another it is rechannelled. // Either way there is no create request and the run goes on to ship. func TestCanaryRegionReusesACanaryPastTheListCap(t *testing.T) { const existing = "probe-titogo.bab.oncarlos.test" for _, c := range []struct{ name, channel, env string }{ {"same channel", "canary/probe", ""}, {"different channel", "canary/old", ""}, // The environment bind follows the same decision: an existing // record gets its own bind write, never a create carrying it. {"same channel, with --environment", "canary/probe", "beta"}, } { t.Run(c.name, func(t *testing.T) { e := regionE2EConsole(t, "") ctx := context.Background() for i := 0; i < 520; i++ { rec := provision.Record{Schema: 1, Host: fmt.Sprintf("a%03d.titogo.bab.oncarlos.test", i), App: "titogo", Account: release.OpsAccount, Channel: "stable", CreatedAt: time.Now().UTC()} if err := provision.CreateRecord(ctx, e.store, rec); err != nil { t.Fatal(err) } } rec := provision.Record{Schema: 1, Host: existing, App: "titogo", Account: release.OpsAccount, Region: "uk", Channel: c.channel, CreatedAt: time.Now().UTC()} if err := provision.CreateRecord(ctx, e.store, rec); err != nil { t.Fatal(err) } args := []string{"canary", "deploy", "--app", "titogo", "--name", "probe", "--region", "uk", "--console", e.url, "--version", "abc1234", "--timeout", "1s"} if c.env != "" { args = append(args, "--environment", c.env) } out, _ := e.run(t, append(args, artifact(t))...) if n := e.creates.Load(); n != 0 { t.Fatalf("%d create request(s) for a canary that exists:\n%s", n, out) } if e.releases(t) == 0 { t.Fatalf("the run never shipped:\n%s", out) } got, err := provision.GetRecord(ctx, e.store, release.OpsAccount, "titogo", existing) if err != nil || got.Region != "uk" || got.Channel != "canary/probe" || got.Environment != c.env { t.Fatalf("the canary = %+v %v, want it in uk on canary/probe, environment %q", got, err, c.env) } if recs, _, err := provision.ListRecords(ctx, e.store, release.OpsAccount, "titogo", 1000); err != nil || len(recs) != 521 { t.Fatalf("records = %d %v, want the 521 there were", len(recs), err) } }) } } // codex plan-R3 6: a successful replica create prints C14 with its place, // not an older console's "(channel X)". This console has no secrets key, // so no box is eligible and the place falls back to its code. func TestInstancesCreateReplicaPrintsItsPlace(t *testing.T) { e := regionE2EConsole(t, "") ctx := context.Background() m := provision.Manifest{Schema: 1, App: "titogo", Domain: "bab.oncarlos.test", Channel: "beta"} if err := provision.PutManifest(ctx, e.store, release.OpsAccount, "titogo", m); err != nil { t.Fatal(err) } box := `{"v":1,"box":"uk-box","eip":"1.2.3.4","region":"eu-west-2","placement":"uk","hibernation_configured":true,"hosts":{}}` if _, err := e.store.Put(ctx, "control/edges/uk-box.json", []byte(box), ""); err != nil { t.Fatal(err) } const host = "r.bab.oncarlos.test" out, err := e.run(t, "instances", "create", "--app", "titogo", "--host", host, "--region", "uk", "--role", "replica", "--console", e.url) if err != nil { t.Fatalf("create: %v\n%s", err, out) } if want := "created instance " + host + " (" + instanceCreatedSuffix("beta", "uk") + ")"; !hasRefusalLine(out, want) { t.Fatalf("stdout = %q, want the whole line %q", out, want) } }