github.com/valdemarpavesi/helm@v2.9.1+incompatible/cmd/helm/helm_test.go (about) 1 /* 2 Copyright 2016 The Kubernetes Authors All rights reserved. 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 "fmt" 22 "io" 23 "io/ioutil" 24 "os" 25 "path/filepath" 26 "regexp" 27 "strings" 28 "testing" 29 30 "github.com/spf13/cobra" 31 32 "k8s.io/helm/pkg/helm" 33 "k8s.io/helm/pkg/helm/helmpath" 34 "k8s.io/helm/pkg/proto/hapi/release" 35 "k8s.io/helm/pkg/repo" 36 ) 37 38 // releaseCmd is a command that works with a FakeClient 39 type releaseCmd func(c *helm.FakeClient, out io.Writer) *cobra.Command 40 41 // runReleaseCases runs a set of release cases through the given releaseCmd. 42 func runReleaseCases(t *testing.T, tests []releaseCase, rcmd releaseCmd) { 43 var buf bytes.Buffer 44 for _, tt := range tests { 45 t.Run(tt.name, func(t *testing.T) { 46 c := &helm.FakeClient{Rels: tt.rels} 47 cmd := rcmd(c, &buf) 48 cmd.ParseFlags(tt.flags) 49 err := cmd.RunE(cmd, tt.args) 50 if (err != nil) != tt.err { 51 t.Errorf("expected error, got '%v'", err) 52 } 53 re := regexp.MustCompile(tt.expected) 54 if !re.Match(buf.Bytes()) { 55 t.Errorf("expected\n%q\ngot\n%q", tt.expected, buf.String()) 56 } 57 buf.Reset() 58 }) 59 } 60 } 61 62 // releaseCase describes a test case that works with releases. 63 type releaseCase struct { 64 name string 65 args []string 66 flags []string 67 // expected is the string to be matched. This supports regular expressions. 68 expected string 69 err bool 70 resp *release.Release 71 // Rels are the available releases at the start of the test. 72 rels []*release.Release 73 } 74 75 // tempHelmHome sets up a Helm Home in a temp dir. 76 // 77 // This does not clean up the directory. You must do that yourself. 78 // You must also set helmHome yourself. 79 func tempHelmHome(t *testing.T) (helmpath.Home, error) { 80 oldhome := settings.Home 81 dir, err := ioutil.TempDir("", "helm_home-") 82 if err != nil { 83 return helmpath.Home("n/"), err 84 } 85 86 settings.Home = helmpath.Home(dir) 87 if err := ensureTestHome(settings.Home, t); err != nil { 88 return helmpath.Home("n/"), err 89 } 90 settings.Home = oldhome 91 return helmpath.Home(dir), nil 92 } 93 94 // ensureTestHome creates a home directory like ensureHome, but without remote references. 95 // 96 // t is used only for logging. 97 func ensureTestHome(home helmpath.Home, t *testing.T) error { 98 configDirectories := []string{home.String(), home.Repository(), home.Cache(), home.LocalRepository(), home.Plugins(), home.Starters()} 99 for _, p := range configDirectories { 100 if fi, err := os.Stat(p); err != nil { 101 if err := os.MkdirAll(p, 0755); err != nil { 102 return fmt.Errorf("Could not create %s: %s", p, err) 103 } 104 } else if !fi.IsDir() { 105 return fmt.Errorf("%s must be a directory", p) 106 } 107 } 108 109 repoFile := home.RepositoryFile() 110 if fi, err := os.Stat(repoFile); err != nil { 111 rf := repo.NewRepoFile() 112 rf.Add(&repo.Entry{ 113 Name: "charts", 114 URL: "http://example.com/foo", 115 Cache: "charts-index.yaml", 116 }, &repo.Entry{ 117 Name: "local", 118 URL: "http://localhost.com:7743/foo", 119 Cache: "local-index.yaml", 120 }) 121 if err := rf.WriteFile(repoFile, 0644); err != nil { 122 return err 123 } 124 } else if fi.IsDir() { 125 return fmt.Errorf("%s must be a file, not a directory", repoFile) 126 } 127 if r, err := repo.LoadRepositoriesFile(repoFile); err == repo.ErrRepoOutOfDate { 128 t.Log("Updating repository file format...") 129 if err := r.WriteFile(repoFile, 0644); err != nil { 130 return err 131 } 132 } 133 134 localRepoIndexFile := home.LocalRepository(localRepositoryIndexFile) 135 if fi, err := os.Stat(localRepoIndexFile); err != nil { 136 i := repo.NewIndexFile() 137 if err := i.WriteFile(localRepoIndexFile, 0644); err != nil { 138 return err 139 } 140 141 //TODO: take this out and replace with helm update functionality 142 os.Symlink(localRepoIndexFile, home.CacheIndex("local")) 143 } else if fi.IsDir() { 144 return fmt.Errorf("%s must be a file, not a directory", localRepoIndexFile) 145 } 146 147 t.Logf("$HELM_HOME has been configured at %s.\n", settings.Home.String()) 148 return nil 149 150 } 151 152 func TestRootCmd(t *testing.T) { 153 cleanup := resetEnv() 154 defer cleanup() 155 156 tests := []struct { 157 name string 158 args []string 159 envars map[string]string 160 home string 161 }{ 162 { 163 name: "defaults", 164 args: []string{"home"}, 165 home: filepath.Join(os.Getenv("HOME"), "/.helm"), 166 }, 167 { 168 name: "with --home set", 169 args: []string{"--home", "/foo"}, 170 home: "/foo", 171 }, 172 { 173 name: "subcommands with --home set", 174 args: []string{"home", "--home", "/foo"}, 175 home: "/foo", 176 }, 177 { 178 name: "with $HELM_HOME set", 179 args: []string{"home"}, 180 envars: map[string]string{"HELM_HOME": "/bar"}, 181 home: "/bar", 182 }, 183 { 184 name: "subcommands with $HELM_HOME set", 185 args: []string{"home"}, 186 envars: map[string]string{"HELM_HOME": "/bar"}, 187 home: "/bar", 188 }, 189 { 190 name: "with $HELM_HOME and --home set", 191 args: []string{"home", "--home", "/foo"}, 192 envars: map[string]string{"HELM_HOME": "/bar"}, 193 home: "/foo", 194 }, 195 } 196 197 // ensure not set locally 198 os.Unsetenv("HELM_HOME") 199 200 for _, tt := range tests { 201 t.Run(tt.name, func(t *testing.T) { 202 defer os.Unsetenv("HELM_HOME") 203 204 for k, v := range tt.envars { 205 os.Setenv(k, v) 206 } 207 208 cmd := newRootCmd(tt.args) 209 cmd.SetOutput(ioutil.Discard) 210 cmd.SetArgs(tt.args) 211 cmd.Run = func(*cobra.Command, []string) {} 212 if err := cmd.Execute(); err != nil { 213 t.Errorf("unexpected error: %s", err) 214 } 215 216 if settings.Home.String() != tt.home { 217 t.Errorf("expected home %q, got %q", tt.home, settings.Home) 218 } 219 homeFlag := cmd.Flag("home").Value.String() 220 homeFlag = os.ExpandEnv(homeFlag) 221 if homeFlag != tt.home { 222 t.Errorf("expected home %q, got %q", tt.home, homeFlag) 223 } 224 }) 225 } 226 } 227 228 func resetEnv() func() { 229 origSettings := settings 230 origEnv := os.Environ() 231 return func() { 232 settings = origSettings 233 for _, pair := range origEnv { 234 kv := strings.SplitN(pair, "=", 2) 235 os.Setenv(kv[0], kv[1]) 236 } 237 } 238 }