| 1 | package rollout |
| 2 | |
| 3 | import ( |
| 4 | "fmt" |
| 5 | "strings" |
| 6 | "testing" |
| 7 | "time" |
| 8 | |
| 9 | "github.com/carlosframework/platform/internal/activator" |
| 10 | "github.com/carlosframework/platform/internal/rolloutwords" |
| 11 | "github.com/carlosframework/platform/internal/status" |
| 12 | ) |
| 13 | |
| 14 | // textHead is the event text up to its first argument the caller does not |
| 15 | // know: sentinel is that argument, as the text function was given it. It |
| 16 | // keeps the other tests' pins on the wording itself (rolloutwords), so a |
| 17 | // copy change re-keys once. |
| 18 | func textHead(text, sentinel string) string { |
| 19 | head, _, _ := strings.Cut(text, sentinel) |
| 20 | return head |
| 21 | } |
| 22 | |
| 23 | // The text functions take reason WORDS (status.Reason*), as the emit sites |
| 24 | // give them after reasonWord; each is worded through rolloutwords.Reason and |
| 25 | // is not mapped again (reasonWord("exit") would read as a health failure). |
| 26 | func TestEventTextsAreTheApprovedOnes(t *testing.T) { |
| 27 | cases := map[string][2]string{ |
| 28 | "swapping": {textSwapping("v2", activator.CauseRelease), fmt.Sprintf(rolloutwords.EventSwapping, "v2", rolloutwords.Cause("release"))}, |
| 29 | "swapped": {textSwapped("v2", 1234*time.Millisecond), fmt.Sprintf(rolloutwords.EventSwapped, "v2", "1.2s")}, |
| 30 | "swap failed": {textSwapFailed("v2", "v1", status.ReasonHealth), fmt.Sprintf(rolloutwords.EventSwapFailed, "v2", rolloutwords.Reason(status.ReasonHealth), "v1")}, |
| 31 | "down": {textSwapDown("v2"), fmt.Sprintf(rolloutwords.EventHoldDown, "v2")}, |
| 32 | "halted": {textCohortHalted("v2", "box-7", status.ReasonSettle), fmt.Sprintf(rolloutwords.EventCohortHalted, "v2", "box-7", rolloutwords.Reason(status.ReasonSettle))}, |
| 33 | "fallback": {textFallback("v2", "v1"), fmt.Sprintf(rolloutwords.EventFallbackServed, "v2", "v1")}, |
| 34 | "config pending": {textConfigPending(status.ReasonExit, 2*time.Minute), fmt.Sprintf(rolloutwords.EventConfigPending, rolloutwords.Reason(status.ReasonExit), (2 * time.Minute).String())}, |
| 35 | "staging refused": {textStagingRefused("v2"), fmt.Sprintf(rolloutwords.EventStagingRefused, "v2")}, |
| 36 | } |
| 37 | for name, c := range cases { |
| 38 | if c[0] != c[1] { |
| 39 | t.Errorf("%s: %q, want the approved %q", name, c[0], c[1]) |
| 40 | } |
| 41 | } |
| 42 | } |
| 43 | |
| 44 | // Every closed reason word is worded as itself: none is folded into another |
| 45 | // by a second mapping. |
| 46 | func TestEventTextsKeepEachReasonWord(t *testing.T) { |
| 47 | for _, w := range []string{status.ReasonHealth, status.ReasonSettle, status.ReasonExit, status.ReasonStaging, status.ReasonReused} { |
| 48 | want := rolloutwords.Reason(w) |
| 49 | for name, s := range map[string]string{ |
| 50 | "swap failed": textSwapFailed("v2", "v1", w), |
| 51 | "halted": textCohortHalted("v2", "box-7", w), |
| 52 | "config pending": textConfigPending(w, time.Minute), |
| 53 | } { |
| 54 | if !strings.Contains(s, want) { |
| 55 | t.Errorf("%s with reason word %q: %q does not say %q", name, w, s, want) |
| 56 | } |
| 57 | } |
| 58 | } |
| 59 | } |
| 60 | |