package edge import ( "strings" "testing" "github.com/carlosframework/platform/internal/registry" ) // A hibernate-flagged instance route on a box with no activator has nothing // on that box that would ever spawn its process, and before this it said so // nowhere: the row is real and the socket path is derived, so a request // reaching it here dials a socket nothing will bind and comes back as a // bodiless 502 that reads as a broken backend. Reload must name the host, // the socket, and the fix. // // The message is deliberately careful about what it claims — it reports what // this box knows, not that every request 502s, since it cannot see whether // something outside the platform is already bound to that socket. func TestReloadNamesAHibernatingRouteWithNoActivator(t *testing.T) { buf := captureLog(t) reg := openReg(t) // Socket-backed and hibernate-flagged: exactly what provision.Reconcile // mints for a plain instance record, which is the shape that stranded. if err := reg.Upsert(registry.Route{ Host: "region-probe.example.com", Kind: "instance", Socket: "/run/carlos/region-probe.example.com.sock", Status: "ready", Hibernate: true, }); err != nil { t.Fatalf("upsert: %v", err) } // A nil activator is the whole point: this is a box whose host.env never // named a CARLOS_HIBERNATE_BUCKET, so internal/host armed nothing. if _, err := New(reg, nil); err != nil { t.Fatalf("New: %v", err) } got := buf.String() for _, want := range []string{ "region-probe.example.com", "/run/carlos/region-probe.example.com.sock", "CARLOS_HIBERNATE_BUCKET", "carlos edge", } { if !strings.Contains(got, want) { t.Errorf("reload log does not mention %q — an operator reading the journal still cannot tell this from a broken app.\ngot: %s", want, got) } } } // The complaint is about the ACTIVATOR, not about instances in general: a box // with an activator armed is working exactly as designed and must say // nothing, or the line becomes noise on every healthy box in the fleet. func TestReloadIsSilentWhenTheActivatorIsArmed(t *testing.T) { buf := captureLog(t) reg := openReg(t) if err := reg.Upsert(registry.Route{ Host: "healthy.example.com", Kind: "instance", Socket: "/run/carlos/healthy.example.com.sock", Status: "ready", Hibernate: true, }); err != nil { t.Fatalf("upsert: %v", err) } if _, err := New(reg, &fakeActivator{}); err != nil { t.Fatalf("New: %v", err) } if got := buf.String(); strings.Contains(got, "no activator") { t.Errorf("complained about an armed box: %s", got) } } // An UNFLAGGED instance is proxied straight by design — that is the // deploy-safety property that lets the hibernate env ship fleet-wide as a // no-op before any host is flagged — so a box with no activator must not // complain about one either. func TestReloadIsSilentForAnUnflaggedInstance(t *testing.T) { buf := captureLog(t) reg := openReg(t) if err := reg.Upsert(registry.Route{ Host: "unflagged.example.com", Kind: "instance", Socket: "/run/carlos/unflagged.example.com.sock", Status: "ready", }); err != nil { t.Fatalf("upsert: %v", err) } if _, err := New(reg, nil); err != nil { t.Fatalf("New: %v", err) } if got := buf.String(); strings.Contains(got, "no activator") { t.Errorf("complained about an unflagged instance: %s", got) } }