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