carlos / platform Public

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

Plain git — no account needed to clone.

Download

Download this file

1package console
2
3import (
4 "context"
5 "fmt"
6 "net/http"
7 "net/url"
8 "strings"
9 "testing"
10 "time"
11
12 "github.com/carlosframework/platform/internal/registry"
13 "github.com/carlosframework/platform/internal/rolloutwords"
14 "github.com/carlosframework/platform/internal/status"
15)
16
17// Astra plan 6 R1 #8: the retry confirmation promises no fallback. A retry
18// that fails in hold mode leaves the instance down, so "stays on its last
19// good build" was false there; the host is held again either way.
20func TestBrowserRetryConfirmationPromisesNoFallback(t *testing.T) {
21 fx := heldFixture(t)
22 c := signInPaul(t, fx)
23 csrf := sessionToken(t, fx, c)
24 code, _, body := postForm(t, c, fx.u("/apps/kass/instances/"+heldHost+"/retry"), url.Values{"csrf": {csrf}})
25 want := "This clears the failure hold on " + heldHost + ". Its next attempt at v2 runs as a canary. If that fails too, " + heldHost + " is held again."
26 if code != http.StatusOK || !strings.Contains(body, want) {
27 t.Fatalf("confirm = %d, lacks %q", code, want)
28 }
29 if strings.Contains(body, "last good build") {
30 t.Fatal("the confirmation still promises a fallback to the last good build")
31 }
32}
33
34// Astra plan 6 R1 #8: a hold-mode failure leaves nothing serving
35// (attempt down), so the page's hold row must not say the instance "stays
36// on" a build there. Both renders: a held instance that serves its good
37// build keeps the hold text; a down one gets the down text.
38func TestInstancePageHoldTextTellsDownFromHeld(t *testing.T) {
39 fx := newConsoleFixture(t)
40 const down = "down.kass.carlosapp.dev"
41 for _, h := range []string{heldHost, down} {
42 fx.addRoute(t, registry.Route{Host: h, App: "kass", Account: fx.sqid, Kind: "instance", Status: "ready", Version: "v2", Channel: "stable"})
43 sibling(t, fx, "kass", h, "stable")
44 }
45 box := status.CollectBox(nil, status.Probes{MachineID: "box1"}, time.Now())
46 box.Metrics = &status.BoxMetrics{Rollout: &status.RolloutReport{Hosts: map[string]status.HostRollout{
47 heldHost: {Account: fx.sqid, App: "kass", Installed: "v2", Serving: "v1", Good: "v1", Awake: true, HeldBy: "v2", Reason: status.ReasonHealth,
48 HeldEpoch: heldEpoch, HeldBook: heldBook, RetryV: status.HostRetryV},
49 down: {Account: fx.sqid, App: "kass", Installed: "v2", Good: "v1", Attempt: status.AttemptDown, AttemptBuild: "v2",
50 HeldBy: "v2", Reason: status.ReasonExit, HeldEpoch: heldEpoch, HeldBook: heldBook, RetryV: status.HostRetryV},
51 }}}
52 if err := status.WriteBox(context.Background(), fx.rel, box); err != nil {
53 t.Fatal(err)
54 }
55 c := signInPaul(t, fx)
56 _, _, held := get(t, c, fx.u("/apps/kass/instances/"+heldHost))
57 if want := fmt.Sprintf(swapCopy.HoldText, "v2", rolloutwords.Reason(status.ReasonHealth), "v1"); !strings.Contains(held, want) {
58 t.Errorf("held page lacks %q", want)
59 }
60 _, _, body := get(t, c, fx.u("/apps/kass/instances/"+down))
61 want := "Build v2 failed in hold mode on this box, and nothing is serving this instance. Roll back with carlos rollback, or retry it."
62 if !strings.Contains(body, want) {
63 t.Errorf("down page lacks %q", want)
64 }
65 if strings.Contains(body, "stays on") {
66 t.Error("the down page says the instance stays on a build")
67 }
68 if !strings.Contains(body, `/instances/`+down+`/retry"`) {
69 t.Error("the down page lost its Retry")
70 }
71}
72