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