github.com/koderover/helm@v2.17.0+incompatible/pkg/downloader/chart_downloader_test.go (about) 1 /* 2 Copyright The Helm Authors. 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/pkg/getter" 29 "k8s.io/helm/pkg/helm/environment" 30 "k8s.io/helm/pkg/helm/helmpath" 31 "k8s.io/helm/pkg/repo" 32 "k8s.io/helm/pkg/repo/repotest" 33 ) 34 35 func TestResolveChartRef(t *testing.T) { 36 tests := []struct { 37 name, ref, expect, version string 38 fail bool 39 }{ 40 {name: "full URL", ref: "http://example.com/foo-1.2.3.tgz", expect: "http://example.com/foo-1.2.3.tgz"}, 41 {name: "full URL, HTTPS", ref: "https://example.com/foo-1.2.3.tgz", expect: "https://example.com/foo-1.2.3.tgz"}, 42 {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"}, 43 {name: "reference, testing repo", ref: "testing/alpine", expect: "http://example.com/alpine-1.2.3.tgz"}, 44 {name: "reference, version, testing repo", ref: "testing/alpine", version: "0.2.0", expect: "http://example.com/alpine-0.2.0.tgz"}, 45 {name: "reference, version, malformed repo", ref: "malformed/alpine", version: "1.2.3", expect: "http://dl.example.com/alpine-1.2.3.tgz"}, 46 {name: "reference, querystring repo", ref: "testing-querystring/alpine", expect: "http://example.com/alpine-1.2.3.tgz?key=value"}, 47 {name: "reference, testing-relative repo", ref: "testing-relative/foo", expect: "http://example.com/helm/charts/foo-1.2.3.tgz"}, 48 {name: "reference, testing-relative repo", ref: "testing-relative/bar", expect: "http://example.com/helm/bar-1.2.3.tgz"}, 49 {name: "reference, testing-relative-trailing-slash repo", ref: "testing-relative-trailing-slash/foo", expect: "http://example.com/helm/charts/foo-1.2.3.tgz"}, 50 {name: "reference, testing-relative-trailing-slash repo", ref: "testing-relative-trailing-slash/bar", expect: "http://example.com/helm/bar-1.2.3.tgz"}, 51 {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}, 52 {name: "full URL, file", ref: "file:///foo-1.2.3.tgz", fail: true}, 53 {name: "invalid", ref: "invalid-1.2.3", fail: true}, 54 {name: "not found", ref: "nosuchthing/invalid-1.2.3", fail: true}, 55 } 56 57 c := ChartDownloader{ 58 HelmHome: helmpath.Home("testdata/helmhome"), 59 Out: os.Stderr, 60 Getters: getter.All(environment.EnvSettings{}), 61 } 62 63 for _, tt := range tests { 64 u, _, err := c.ResolveChartVersion(tt.ref, tt.version) 65 if err != nil { 66 if tt.fail { 67 continue 68 } 69 t.Errorf("%s: failed with error %s", tt.name, err) 70 continue 71 } 72 if got := u.String(); got != tt.expect { 73 t.Errorf("%s: expected %s, got %s", tt.name, tt.expect, got) 74 } 75 } 76 } 77 78 func TestVerifyChart(t *testing.T) { 79 v, err := VerifyChart("testdata/signtest-0.1.0.tgz", "testdata/helm-test-key.pub") 80 if err != nil { 81 t.Fatal(err) 82 } 83 // The verification is tested at length in the provenance package. Here, 84 // we just want a quick sanity check that the v is not empty. 85 if len(v.FileHash) == 0 { 86 t.Error("Digest missing") 87 } 88 } 89 90 func TestDownload(t *testing.T) { 91 expect := "Call me Ishmael" 92 srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 93 fmt.Fprint(w, expect) 94 })) 95 defer srv.Close() 96 97 provider, err := getter.ByScheme("http", environment.EnvSettings{}) 98 if err != nil { 99 t.Fatal("No http provider found") 100 } 101 102 g, err := provider.New(srv.URL, "", "", "") 103 if err != nil { 104 t.Fatal(err) 105 } 106 got, err := g.Get(srv.URL) 107 if err != nil { 108 t.Fatal(err) 109 } 110 111 if got.String() != expect { 112 t.Errorf("Expected %q, got %q", expect, got.String()) 113 } 114 115 // test with server backed by basic auth 116 basicAuthSrv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 117 username, password, ok := r.BasicAuth() 118 if !ok || username != "username" || password != "password" { 119 t.Errorf("Expected request to use basic auth and for username == 'username' and password == 'password', got '%v', '%s', '%s'", ok, username, password) 120 } 121 fmt.Fprint(w, expect) 122 })) 123 124 defer basicAuthSrv.Close() 125 126 u, _ := url.ParseRequestURI(basicAuthSrv.URL) 127 httpgetter, err := getter.NewHTTPGetter(u.String(), "", "", "") 128 if err != nil { 129 t.Fatal(err) 130 } 131 httpgetter.SetCredentials("username", "password") 132 got, err = httpgetter.Get(u.String()) 133 if err != nil { 134 t.Fatal(err) 135 } 136 137 if got.String() != expect { 138 t.Errorf("Expected %q, got %q", expect, got.String()) 139 } 140 } 141 142 func TestIsTar(t *testing.T) { 143 tests := map[string]bool{ 144 "foo.tgz": true, 145 "foo/bar/baz.tgz": true, 146 "foo-1.2.3.4.5.tgz": true, 147 "foo.tar.gz": false, // for our purposes 148 "foo.tgz.1": false, 149 "footgz": false, 150 } 151 152 for src, expect := range tests { 153 if isTar(src) != expect { 154 t.Errorf("%q should be %t", src, expect) 155 } 156 } 157 } 158 159 func TestDownloadTo(t *testing.T) { 160 tmp, err := ioutil.TempDir("", "helm-downloadto-") 161 if err != nil { 162 t.Fatal(err) 163 } 164 defer os.RemoveAll(tmp) 165 166 hh := helmpath.Home(tmp) 167 dest := filepath.Join(hh.String(), "dest") 168 configDirectories := []string{ 169 hh.String(), 170 hh.Repository(), 171 hh.Cache(), 172 dest, 173 } 174 for _, p := range configDirectories { 175 if fi, err := os.Stat(p); err != nil { 176 if err := os.MkdirAll(p, 0755); err != nil { 177 t.Fatalf("Could not create %s: %s", p, err) 178 } 179 } else if !fi.IsDir() { 180 t.Fatalf("%s must be a directory", p) 181 } 182 } 183 184 // Set up a fake repo 185 srv := repotest.NewServer(tmp) 186 defer srv.Stop() 187 if _, err := srv.CopyCharts("testdata/*.tgz*"); err != nil { 188 t.Error(err) 189 return 190 } 191 if err := srv.LinkIndices(); err != nil { 192 t.Fatal(err) 193 } 194 195 c := ChartDownloader{ 196 HelmHome: hh, 197 Out: os.Stderr, 198 Verify: VerifyAlways, 199 Keyring: "testdata/helm-test-key.pub", 200 Getters: getter.All(environment.EnvSettings{}), 201 } 202 cname := "/signtest-0.1.0.tgz" 203 where, v, err := c.DownloadTo(srv.URL()+cname, "", dest) 204 if err != nil { 205 t.Error(err) 206 return 207 } 208 209 if expect := filepath.Join(dest, cname); where != expect { 210 t.Errorf("Expected download to %s, got %s", expect, where) 211 } 212 213 if v.FileHash == "" { 214 t.Error("File hash was empty, but verification is required.") 215 } 216 217 if _, err := os.Stat(filepath.Join(dest, cname)); err != nil { 218 t.Error(err) 219 return 220 } 221 } 222 223 func TestDownloadTo_VerifyLater(t *testing.T) { 224 tmp, err := ioutil.TempDir("", "helm-downloadto-") 225 if err != nil { 226 t.Fatal(err) 227 } 228 defer os.RemoveAll(tmp) 229 230 hh := helmpath.Home(tmp) 231 dest := filepath.Join(hh.String(), "dest") 232 configDirectories := []string{ 233 hh.String(), 234 hh.Repository(), 235 hh.Cache(), 236 dest, 237 } 238 for _, p := range configDirectories { 239 if fi, err := os.Stat(p); err != nil { 240 if err := os.MkdirAll(p, 0755); err != nil { 241 t.Fatalf("Could not create %s: %s", p, err) 242 } 243 } else if !fi.IsDir() { 244 t.Fatalf("%s must be a directory", p) 245 } 246 } 247 248 // Set up a fake repo 249 srv := repotest.NewServer(tmp) 250 defer srv.Stop() 251 if _, err := srv.CopyCharts("testdata/*.tgz*"); err != nil { 252 t.Error(err) 253 return 254 } 255 if err := srv.LinkIndices(); err != nil { 256 t.Fatal(err) 257 } 258 259 c := ChartDownloader{ 260 HelmHome: hh, 261 Out: os.Stderr, 262 Verify: VerifyLater, 263 Getters: getter.All(environment.EnvSettings{}), 264 } 265 cname := "/signtest-0.1.0.tgz" 266 where, _, err := c.DownloadTo(srv.URL()+cname, "", dest) 267 if err != nil { 268 t.Error(err) 269 return 270 } 271 272 if expect := filepath.Join(dest, cname); where != expect { 273 t.Errorf("Expected download to %s, got %s", expect, where) 274 } 275 276 if _, err := os.Stat(filepath.Join(dest, cname)); err != nil { 277 t.Error(err) 278 return 279 } 280 if _, err := os.Stat(filepath.Join(dest, cname+".prov")); err != nil { 281 t.Error(err) 282 return 283 } 284 } 285 286 func TestScanReposForURL(t *testing.T) { 287 hh := helmpath.Home("testdata/helmhome") 288 c := ChartDownloader{ 289 HelmHome: hh, 290 Out: os.Stderr, 291 Verify: VerifyLater, 292 Getters: getter.All(environment.EnvSettings{}), 293 } 294 295 u := "http://example.com/alpine-0.2.0.tgz" 296 rf, err := repo.LoadRepositoriesFile(c.HelmHome.RepositoryFile()) 297 if err != nil { 298 t.Fatal(err) 299 } 300 301 entry, err := c.scanReposForURL(u, rf) 302 if err != nil { 303 t.Fatal(err) 304 } 305 306 if entry.Name != "testing" { 307 t.Errorf("Unexpected repo %q for URL %q", entry.Name, u) 308 } 309 310 // A lookup failure should produce an ErrNoOwnerRepo 311 u = "https://no.such.repo/foo/bar-1.23.4.tgz" 312 if _, err = c.scanReposForURL(u, rf); err != ErrNoOwnerRepo { 313 t.Fatalf("expected ErrNoOwnerRepo, got %v", err) 314 } 315 }