github.com/azure-devops-engineer/helm@v3.0.0-alpha.2+incompatible/cmd/helm/helm_test.go (about) 1 /* 2 Copyright The Helm Authors. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package main 18 19 import ( 20 "bytes" 21 "io/ioutil" 22 "os" 23 "strings" 24 "testing" 25 "time" 26 27 shellwords "github.com/mattn/go-shellwords" 28 "github.com/spf13/cobra" 29 30 "helm.sh/helm/internal/test" 31 "helm.sh/helm/pkg/action" 32 "helm.sh/helm/pkg/chartutil" 33 "helm.sh/helm/pkg/helmpath" 34 kubefake "helm.sh/helm/pkg/kube/fake" 35 "helm.sh/helm/pkg/release" 36 "helm.sh/helm/pkg/repo" 37 "helm.sh/helm/pkg/storage" 38 "helm.sh/helm/pkg/storage/driver" 39 ) 40 41 func testTimestamper() time.Time { return time.Unix(242085845, 0).UTC() } 42 43 func init() { 44 action.Timestamper = testTimestamper 45 } 46 47 func TestMain(m *testing.M) { 48 os.Unsetenv("HELM_HOME") 49 exitCode := m.Run() 50 os.Exit(exitCode) 51 } 52 53 func testTempDir(t *testing.T) string { 54 t.Helper() 55 d, err := ioutil.TempDir("", "helm") 56 if err != nil { 57 t.Fatal(err) 58 } 59 return d 60 } 61 62 func runTestCmd(t *testing.T, tests []cmdTestCase) { 63 t.Helper() 64 for _, tt := range tests { 65 t.Run(tt.name, func(t *testing.T) { 66 defer resetEnv()() 67 68 storage := storageFixture() 69 for _, rel := range tt.rels { 70 if err := storage.Create(rel); err != nil { 71 t.Fatal(err) 72 } 73 } 74 _, out, err := executeActionCommandC(storage, tt.cmd) 75 if (err != nil) != tt.wantError { 76 t.Errorf("expected error, got '%v'", err) 77 } 78 if tt.golden != "" { 79 test.AssertGoldenString(t, out, tt.golden) 80 } 81 }) 82 } 83 } 84 85 func runTestActionCmd(t *testing.T, tests []cmdTestCase) { 86 t.Helper() 87 for _, tt := range tests { 88 t.Run(tt.name, func(t *testing.T) { 89 defer resetEnv()() 90 91 store := storageFixture() 92 for _, rel := range tt.rels { 93 store.Create(rel) 94 } 95 _, out, err := executeActionCommandC(store, tt.cmd) 96 if (err != nil) != tt.wantError { 97 t.Errorf("expected error, got '%v'", err) 98 } 99 if tt.golden != "" { 100 test.AssertGoldenString(t, out, tt.golden) 101 } 102 }) 103 } 104 } 105 106 func storageFixture() *storage.Storage { 107 return storage.Init(driver.NewMemory()) 108 } 109 110 func executeActionCommandC(store *storage.Storage, cmd string) (*cobra.Command, string, error) { 111 args, err := shellwords.Parse(cmd) 112 if err != nil { 113 return nil, "", err 114 } 115 buf := new(bytes.Buffer) 116 117 actionConfig := &action.Configuration{ 118 Releases: store, 119 KubeClient: &kubefake.PrintingKubeClient{Out: ioutil.Discard}, 120 Capabilities: chartutil.DefaultCapabilities, 121 Log: func(format string, v ...interface{}) {}, 122 } 123 124 root := newRootCmd(actionConfig, buf, args) 125 root.SetOutput(buf) 126 root.SetArgs(args) 127 128 c, err := root.ExecuteC() 129 130 return c, buf.String(), err 131 } 132 133 // cmdTestCase describes a test case that works with releases. 134 type cmdTestCase struct { 135 name string 136 cmd string 137 golden string 138 wantError bool 139 // Rels are the available releases at the start of the test. 140 rels []*release.Release 141 } 142 143 func executeActionCommand(cmd string) (*cobra.Command, string, error) { 144 return executeActionCommandC(storageFixture(), cmd) 145 } 146 147 // ensureTestHome creates a home directory like ensureHome, but without remote references. 148 func ensureTestHome(t *testing.T, home helmpath.Home) { 149 t.Helper() 150 for _, p := range []string{ 151 home.String(), 152 home.Repository(), 153 home.Cache(), 154 home.Plugins(), 155 home.Starters(), 156 } { 157 if err := os.MkdirAll(p, 0755); err != nil { 158 t.Fatal(err) 159 } 160 } 161 162 repoFile := home.RepositoryFile() 163 if _, err := os.Stat(repoFile); err != nil { 164 rf := repo.NewFile() 165 rf.Add(&repo.Entry{ 166 Name: "charts", 167 URL: "http://example.com/foo", 168 Cache: "charts-index.yaml", 169 }) 170 if err := rf.WriteFile(repoFile, 0644); err != nil { 171 t.Fatal(err) 172 } 173 } 174 if r, err := repo.LoadFile(repoFile); err == repo.ErrRepoOutOfDate { 175 if err := r.WriteFile(repoFile, 0644); err != nil { 176 t.Fatal(err) 177 } 178 } 179 } 180 181 // testHelmHome sets up a Helm Home in a temp dir. 182 func testHelmHome(t *testing.T) helmpath.Home { 183 t.Helper() 184 dir := helmpath.Home(testTempDir(t)) 185 ensureTestHome(t, dir) 186 return dir 187 } 188 189 func resetEnv() func() { 190 origSettings, origEnv := settings, os.Environ() 191 return func() { 192 os.Clearenv() 193 settings = origSettings 194 for _, pair := range origEnv { 195 kv := strings.SplitN(pair, "=", 2) 196 os.Setenv(kv[0], kv[1]) 197 } 198 } 199 } 200 201 func testChdir(t *testing.T, dir string) func() { 202 t.Helper() 203 old, err := os.Getwd() 204 if err != nil { 205 t.Fatal(err) 206 } 207 if err := os.Chdir(dir); err != nil { 208 t.Fatal(err) 209 } 210 return func() { os.Chdir(old) } 211 }