github.com/cloudposse/helm@v2.2.3+incompatible/pkg/downloader/chart_downloader_test.go (about) 1 /* 2 Copyright 2016 The Kubernetes Authors All rights reserved. 3 Licensed under the Apache License, Version 2.0 (the "License"); 4 you may not use this file except in compliance with the License. 5 You may obtain a copy of the License at 6 7 http://www.apache.org/licenses/LICENSE-2.0 8 9 Unless required by applicable law or agreed to in writing, software 10 distributed under the License is distributed on an "AS IS" BASIS, 11 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 See the License for the specific language governing permissions and 13 limitations under the License. 14 */ 15 16 package downloader 17 18 import ( 19 "fmt" 20 "io/ioutil" 21 "net/http" 22 "net/http/httptest" 23 "net/url" 24 "os" 25 "path/filepath" 26 "testing" 27 28 "k8s.io/helm/cmd/helm/helmpath" 29 "k8s.io/helm/pkg/repo" 30 "k8s.io/helm/pkg/repo/repotest" 31 ) 32 33 func TestResolveChartRef(t *testing.T) { 34 tests := []struct { 35 name, ref, expect, version string 36 fail bool 37 }{ 38 {name: "full URL", ref: "http://example.com/foo-1.2.3.tgz", expect: "http://example.com/foo-1.2.3.tgz"}, 39 {name: "full URL, HTTPS", ref: "https://example.com/foo-1.2.3.tgz", expect: "https://example.com/foo-1.2.3.tgz"}, 40 {name: "full URL, with authentication", ref: "http://username:password@example.com/foo-1.2.3.tgz", expect: "http://username:password@example.com/foo-1.2.3.tgz"}, 41 {name: "reference, testing repo", ref: "testing/alpine", expect: "http://example.com/alpine-1.2.3.tgz"}, 42 {name: "reference, version, testing repo", ref: "testing/alpine", version: "0.2.0", expect: "http://example.com/alpine-0.2.0.tgz"}, 43 {name: "full URL, HTTPS, irrelevant version", ref: "https://example.com/foo-1.2.3.tgz", version: "0.1.0", expect: "https://example.com/foo-1.2.3.tgz", fail: true}, 44 {name: "full URL, file", ref: "file:///foo-1.2.3.tgz", fail: true}, 45 {name: "invalid", ref: "invalid-1.2.3", fail: true}, 46 {name: "not found", ref: "nosuchthing/invalid-1.2.3", fail: true}, 47 } 48 49 c := ChartDownloader{ 50 HelmHome: helmpath.Home("testdata/helmhome"), 51 Out: os.Stderr, 52 } 53 54 for _, tt := range tests { 55 u, _, err := c.ResolveChartVersion(tt.ref, tt.version) 56 if err != nil { 57 if tt.fail { 58 continue 59 } 60 t.Errorf("%s: failed with error %s", tt.name, err) 61 continue 62 } 63 if got := u.String(); got != tt.expect { 64 t.Errorf("%s: expected %s, got %s", tt.name, tt.expect, got) 65 } 66 } 67 } 68 69 func TestVerifyChart(t *testing.T) { 70 v, err := VerifyChart("testdata/signtest-0.1.0.tgz", "testdata/helm-test-key.pub") 71 if err != nil { 72 t.Fatal(err) 73 } 74 // The verification is tested at length in the provenance package. Here, 75 // we just want a quick sanity check that the v is not empty. 76 if len(v.FileHash) == 0 { 77 t.Error("Digest missing") 78 } 79 } 80 81 func TestDownload(t *testing.T) { 82 expect := "Call me Ishmael" 83 srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 84 fmt.Fprint(w, expect) 85 })) 86 defer srv.Close() 87 88 got, err := download(srv.URL, http.DefaultClient) 89 if err != nil { 90 t.Fatal(err) 91 } 92 93 if got.String() != expect { 94 t.Errorf("Expected %q, got %q", expect, got.String()) 95 } 96 97 // test with server backed by basic auth 98 basicAuthSrv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 99 username, password, ok := r.BasicAuth() 100 if !ok || username != "username" && password != "password" { 101 t.Errorf("Expected request to use basic auth and for username == 'username' and password == 'password', got '%v', '%s', '%s'", ok, username, password) 102 } 103 fmt.Fprint(w, expect) 104 })) 105 defer basicAuthSrv.Close() 106 107 u, _ := url.ParseRequestURI(basicAuthSrv.URL) 108 u.User = url.UserPassword("username", "password") 109 got, err = download(u.String(), http.DefaultClient) 110 if err != nil { 111 t.Fatal(err) 112 } 113 114 if got.String() != expect { 115 t.Errorf("Expected %q, got %q", expect, got.String()) 116 } 117 } 118 119 func TestIsTar(t *testing.T) { 120 tests := map[string]bool{ 121 "foo.tgz": true, 122 "foo/bar/baz.tgz": true, 123 "foo-1.2.3.4.5.tgz": true, 124 "foo.tar.gz": false, // for our purposes 125 "foo.tgz.1": false, 126 "footgz": false, 127 } 128 129 for src, expect := range tests { 130 if isTar(src) != expect { 131 t.Errorf("%q should be %t", src, expect) 132 } 133 } 134 } 135 136 func TestDownloadTo(t *testing.T) { 137 tmp, err := ioutil.TempDir("", "helm-downloadto-") 138 if err != nil { 139 t.Fatal(err) 140 } 141 defer os.RemoveAll(tmp) 142 143 hh := helmpath.Home(tmp) 144 dest := filepath.Join(hh.String(), "dest") 145 configDirectories := []string{ 146 hh.String(), 147 hh.Repository(), 148 hh.Cache(), 149 dest, 150 } 151 for _, p := range configDirectories { 152 if fi, err := os.Stat(p); err != nil { 153 if err := os.MkdirAll(p, 0755); err != nil { 154 t.Fatalf("Could not create %s: %s", p, err) 155 } 156 } else if !fi.IsDir() { 157 t.Fatalf("%s must be a directory", p) 158 } 159 } 160 161 // Set up a fake repo 162 srv := repotest.NewServer(tmp) 163 defer srv.Stop() 164 if _, err := srv.CopyCharts("testdata/*.tgz*"); err != nil { 165 t.Error(err) 166 return 167 } 168 if err := srv.LinkIndices(); err != nil { 169 t.Fatal(err) 170 } 171 172 c := ChartDownloader{ 173 HelmHome: hh, 174 Out: os.Stderr, 175 Verify: VerifyAlways, 176 Keyring: "testdata/helm-test-key.pub", 177 } 178 cname := "/signtest-0.1.0.tgz" 179 where, v, err := c.DownloadTo(srv.URL()+cname, "", dest) 180 if err != nil { 181 t.Error(err) 182 return 183 } 184 185 if expect := filepath.Join(dest, cname); where != expect { 186 t.Errorf("Expected download to %s, got %s", expect, where) 187 } 188 189 if v.FileHash == "" { 190 t.Error("File hash was empty, but verification is required.") 191 } 192 193 if _, err := os.Stat(filepath.Join(dest, cname)); err != nil { 194 t.Error(err) 195 return 196 } 197 } 198 199 func TestDownloadTo_VerifyLater(t *testing.T) { 200 tmp, err := ioutil.TempDir("", "helm-downloadto-") 201 if err != nil { 202 t.Fatal(err) 203 } 204 defer os.RemoveAll(tmp) 205 206 hh := helmpath.Home(tmp) 207 dest := filepath.Join(hh.String(), "dest") 208 configDirectories := []string{ 209 hh.String(), 210 hh.Repository(), 211 hh.Cache(), 212 dest, 213 } 214 for _, p := range configDirectories { 215 if fi, err := os.Stat(p); err != nil { 216 if err := os.MkdirAll(p, 0755); err != nil { 217 t.Fatalf("Could not create %s: %s", p, err) 218 } 219 } else if !fi.IsDir() { 220 t.Fatalf("%s must be a directory", p) 221 } 222 } 223 224 // Set up a fake repo 225 srv := repotest.NewServer(tmp) 226 defer srv.Stop() 227 if _, err := srv.CopyCharts("testdata/*.tgz*"); err != nil { 228 t.Error(err) 229 return 230 } 231 if err := srv.LinkIndices(); err != nil { 232 t.Fatal(err) 233 } 234 235 c := ChartDownloader{ 236 HelmHome: hh, 237 Out: os.Stderr, 238 Verify: VerifyLater, 239 } 240 cname := "/signtest-0.1.0.tgz" 241 where, _, err := c.DownloadTo(srv.URL()+cname, "", dest) 242 if err != nil { 243 t.Error(err) 244 return 245 } 246 247 if expect := filepath.Join(dest, cname); where != expect { 248 t.Errorf("Expected download to %s, got %s", expect, where) 249 } 250 251 if _, err := os.Stat(filepath.Join(dest, cname)); err != nil { 252 t.Error(err) 253 return 254 } 255 if _, err := os.Stat(filepath.Join(dest, cname+".prov")); err != nil { 256 t.Error(err) 257 return 258 } 259 } 260 261 func TestScanReposForURL(t *testing.T) { 262 hh := helmpath.Home("testdata/helmhome") 263 c := ChartDownloader{ 264 HelmHome: hh, 265 Out: os.Stderr, 266 Verify: VerifyLater, 267 } 268 269 u := "http://example.com/alpine-0.2.0.tgz" 270 rf, err := repo.LoadRepositoriesFile(c.HelmHome.RepositoryFile()) 271 if err != nil { 272 t.Fatal(err) 273 } 274 275 entry, err := c.scanReposForURL(u, rf) 276 if err != nil { 277 t.Fatal(err) 278 } 279 280 if entry.Name != "testing" { 281 t.Errorf("Unexpected repo %q for URL %q", entry.Name, u) 282 } 283 284 // A lookup failure should produce an ErrNoOwnerRepo 285 u = "https://no.such.repo/foo/bar-1.23.4.tgz" 286 if _, err = c.scanReposForURL(u, rf); err != ErrNoOwnerRepo { 287 t.Fatalf("expected ErrNoOwnerRepo, got %v", err) 288 } 289 }