| 1 | package appconfig |
| 2 | |
| 3 | import ( |
| 4 | "encoding/json" |
| 5 | "strings" |
| 6 | "testing" |
| 7 | ) |
| 8 | |
| 9 | func TestKeyIsAccountScoped(t *testing.T) { |
| 10 | got := Key("bab", "keymail") |
| 11 | want := "apps/bab/keymail/config.json" |
| 12 | if got != want { |
| 13 | t.Fatalf("Key(bab, keymail) = %q, want %q", got, want) |
| 14 | } |
| 15 | } |
| 16 | |
| 17 | func TestValidVarName(t *testing.T) { |
| 18 | valid := []string{"LOG_LEVEL", "_FOO", "A", "SES_SECRET_2", "lower_case"} |
| 19 | invalid := []string{"", "1FOO", "has-hyphen", "has space", "has=equals"} |
| 20 | for _, k := range valid { |
| 21 | if !ValidVarName(k) { |
| 22 | t.Errorf("ValidVarName(%q) = false, want true", k) |
| 23 | } |
| 24 | } |
| 25 | for _, k := range invalid { |
| 26 | if ValidVarName(k) { |
| 27 | t.Errorf("ValidVarName(%q) = true, want false", k) |
| 28 | } |
| 29 | } |
| 30 | } |
| 31 | |
| 32 | // The swap policy (zero-downtime spec §4.1) is additive to schema 1: a |
| 33 | // manifest written before it parses with zero values, and a manifest with no |
| 34 | // policy marshals with no new keys, byte for byte as before. |
| 35 | func TestSwapPolicyIsAdditive(t *testing.T) { |
| 36 | var old Manifest |
| 37 | if err := json.Unmarshal([]byte(`{"schema":1,"app":"blog","vars":{}}`), &old); err != nil { |
| 38 | t.Fatal(err) |
| 39 | } |
| 40 | if old.Swap != "" || old.SwapConcurrency != 0 { |
| 41 | t.Fatalf("old manifest parsed as %q/%d", old.Swap, old.SwapConcurrency) |
| 42 | } |
| 43 | raw, err := json.Marshal(Manifest{Schema: 1, App: "blog", Vars: map[string]Var{}}) |
| 44 | if err != nil { |
| 45 | t.Fatal(err) |
| 46 | } |
| 47 | if strings.Contains(string(raw), "swap") { |
| 48 | t.Fatalf("a manifest with no policy marshals %s", raw) |
| 49 | } |
| 50 | var m Manifest |
| 51 | if err := json.Unmarshal([]byte(`{"schema":1,"app":"blog","vars":{},"swap":"hold","swap_concurrency":3}`), &m); err != nil { |
| 52 | t.Fatal(err) |
| 53 | } |
| 54 | if m.Swap != SwapHold || m.SwapConcurrency != 3 { |
| 55 | t.Fatalf("parsed %q/%d", m.Swap, m.SwapConcurrency) |
| 56 | } |
| 57 | for v, want := range map[string]bool{"": true, "overlap": true, "hold": true, "Hold": false, "stop": false} { |
| 58 | if ValidSwap(v) != want { |
| 59 | t.Errorf("ValidSwap(%q) = %v", v, !want) |
| 60 | } |
| 61 | } |
| 62 | for n, want := range map[int]bool{-1: false, 0: true, 1: true, 64: true} { |
| 63 | if ValidSwapConcurrency(n) != want { |
| 64 | t.Errorf("ValidSwapConcurrency(%d) = %v", n, !want) |
| 65 | } |
| 66 | } |
| 67 | } |
| 68 | |