github.com/qsis/helm@v3.0.0-beta.3+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  	"net/http"
    20  	"os"
    21  	"path/filepath"
    22  	"testing"
    23  
    24  	"helm.sh/helm/internal/test/ensure"
    25  	"helm.sh/helm/pkg/cli"
    26  	"helm.sh/helm/pkg/getter"
    27  	"helm.sh/helm/pkg/repo"
    28  	"helm.sh/helm/pkg/repo/repotest"
    29  )
    30  
    31  const (
    32  	repoConfig = "testdata/repositories.yaml"
    33  	repoCache  = "testdata/repository"
    34  )
    35  
    36  func TestResolveChartRef(t *testing.T) {
    37  	tests := []struct {
    38  		name, ref, expect, version string
    39  		fail                       bool
    40  	}{
    41  		{name: "full URL", ref: "http://example.com/foo-1.2.3.tgz", expect: "http://example.com/foo-1.2.3.tgz"},
    42  		{name: "full URL, HTTPS", ref: "https://example.com/foo-1.2.3.tgz", expect: "https://example.com/foo-1.2.3.tgz"},
    43  		{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"},
    44  		{name: "reference, testing repo", ref: "testing/alpine", expect: "http://example.com/alpine-1.2.3.tgz"},
    45  		{name: "reference, version, testing repo", ref: "testing/alpine", version: "0.2.0", expect: "http://example.com/alpine-0.2.0.tgz"},
    46  		{name: "reference, version, malformed repo", ref: "malformed/alpine", version: "1.2.3", expect: "http://dl.example.com/alpine-1.2.3.tgz"},
    47  		{name: "reference, querystring repo", ref: "testing-querystring/alpine", expect: "http://example.com/alpine-1.2.3.tgz?key=value"},
    48  		{name: "reference, testing-relative repo", ref: "testing-relative/foo", expect: "http://example.com/helm/charts/foo-1.2.3.tgz"},
    49  		{name: "reference, testing-relative repo", ref: "testing-relative/bar", expect: "http://example.com/helm/bar-1.2.3.tgz"},
    50  		{name: "reference, testing-relative-trailing-slash repo", ref: "testing-relative-trailing-slash/foo", expect: "http://example.com/helm/charts/foo-1.2.3.tgz"},
    51  		{name: "reference, testing-relative-trailing-slash repo", ref: "testing-relative-trailing-slash/bar", expect: "http://example.com/helm/bar-1.2.3.tgz"},
    52  		{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},
    53  		{name: "full URL, file", ref: "file:///foo-1.2.3.tgz", fail: true},
    54  		{name: "invalid", ref: "invalid-1.2.3", fail: true},
    55  		{name: "not found", ref: "nosuchthing/invalid-1.2.3", fail: true},
    56  	}
    57  
    58  	c := ChartDownloader{
    59  		Out:              os.Stderr,
    60  		RepositoryConfig: repoConfig,
    61  		RepositoryCache:  repoCache,
    62  		Getters: getter.All(&cli.EnvSettings{
    63  			RepositoryConfig: repoConfig,
    64  			RepositoryCache:  repoCache,
    65  		}),
    66  	}
    67  
    68  	for _, tt := range tests {
    69  		u, err := c.ResolveChartVersion(tt.ref, tt.version)
    70  		if err != nil {
    71  			if tt.fail {
    72  				continue
    73  			}
    74  			t.Errorf("%s: failed with error %s", tt.name, err)
    75  			continue
    76  		}
    77  		if got := u.String(); got != tt.expect {
    78  			t.Errorf("%s: expected %s, got %s", tt.name, tt.expect, got)
    79  		}
    80  	}
    81  }
    82  
    83  func TestVerifyChart(t *testing.T) {
    84  	v, err := VerifyChart("testdata/signtest-0.1.0.tgz", "testdata/helm-test-key.pub")
    85  	if err != nil {
    86  		t.Fatal(err)
    87  	}
    88  	// The verification is tested at length in the provenance package. Here,
    89  	// we just want a quick sanity check that the v is not empty.
    90  	if len(v.FileHash) == 0 {
    91  		t.Error("Digest missing")
    92  	}
    93  }
    94  
    95  func TestIsTar(t *testing.T) {
    96  	tests := map[string]bool{
    97  		"foo.tgz":           true,
    98  		"foo/bar/baz.tgz":   true,
    99  		"foo-1.2.3.4.5.tgz": true,
   100  		"foo.tar.gz":        false, // for our purposes
   101  		"foo.tgz.1":         false,
   102  		"footgz":            false,
   103  	}
   104  
   105  	for src, expect := range tests {
   106  		if isTar(src) != expect {
   107  			t.Errorf("%q should be %t", src, expect)
   108  		}
   109  	}
   110  }
   111  
   112  func TestDownloadTo(t *testing.T) {
   113  	// Set up a fake repo with basic auth enabled
   114  	srv, err := repotest.NewTempServer("testdata/*.tgz*")
   115  	srv.Stop()
   116  	if err != nil {
   117  		t.Fatal(err)
   118  	}
   119  	srv.WithMiddleware(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
   120  		username, password, ok := r.BasicAuth()
   121  		if !ok || username != "username" || password != "password" {
   122  			t.Errorf("Expected request to use basic auth and for username == 'username' and password == 'password', got '%v', '%s', '%s'", ok, username, password)
   123  		}
   124  	}))
   125  	srv.Start()
   126  	defer srv.Stop()
   127  	if err := srv.CreateIndex(); err != nil {
   128  		t.Fatal(err)
   129  	}
   130  
   131  	if err := srv.LinkIndices(); err != nil {
   132  		t.Fatal(err)
   133  	}
   134  
   135  	c := ChartDownloader{
   136  		Out:              os.Stderr,
   137  		Verify:           VerifyAlways,
   138  		Keyring:          "testdata/helm-test-key.pub",
   139  		RepositoryConfig: repoConfig,
   140  		RepositoryCache:  repoCache,
   141  		Getters: getter.All(&cli.EnvSettings{
   142  			RepositoryConfig: repoConfig,
   143  			RepositoryCache:  repoCache,
   144  		}),
   145  		Options: []getter.Option{
   146  			getter.WithBasicAuth("username", "password"),
   147  		},
   148  	}
   149  	cname := "/signtest-0.1.0.tgz"
   150  	dest := srv.Root()
   151  	where, v, err := c.DownloadTo(srv.URL()+cname, "", dest)
   152  	if err != nil {
   153  		t.Fatal(err)
   154  	}
   155  
   156  	if expect := filepath.Join(dest, cname); where != expect {
   157  		t.Errorf("Expected download to %s, got %s", expect, where)
   158  	}
   159  
   160  	if v.FileHash == "" {
   161  		t.Error("File hash was empty, but verification is required.")
   162  	}
   163  
   164  	if _, err := os.Stat(filepath.Join(dest, cname)); err != nil {
   165  		t.Error(err)
   166  	}
   167  }
   168  
   169  func TestDownloadTo_VerifyLater(t *testing.T) {
   170  	defer ensure.HelmHome(t)()
   171  
   172  	dest := ensure.TempDir(t)
   173  
   174  	// Set up a fake repo
   175  	srv, err := repotest.NewTempServer("testdata/*.tgz*")
   176  	if err != nil {
   177  		t.Fatal(err)
   178  	}
   179  	defer srv.Stop()
   180  	if err := srv.LinkIndices(); err != nil {
   181  		t.Fatal(err)
   182  	}
   183  
   184  	c := ChartDownloader{
   185  		Out:              os.Stderr,
   186  		Verify:           VerifyLater,
   187  		RepositoryConfig: repoConfig,
   188  		RepositoryCache:  repoCache,
   189  		Getters: getter.All(&cli.EnvSettings{
   190  			RepositoryConfig: repoConfig,
   191  			RepositoryCache:  repoCache,
   192  		}),
   193  	}
   194  	cname := "/signtest-0.1.0.tgz"
   195  	where, _, err := c.DownloadTo(srv.URL()+cname, "", dest)
   196  	if err != nil {
   197  		t.Fatal(err)
   198  	}
   199  
   200  	if expect := filepath.Join(dest, cname); where != expect {
   201  		t.Errorf("Expected download to %s, got %s", expect, where)
   202  	}
   203  
   204  	if _, err := os.Stat(filepath.Join(dest, cname)); err != nil {
   205  		t.Fatal(err)
   206  	}
   207  	if _, err := os.Stat(filepath.Join(dest, cname+".prov")); err != nil {
   208  		t.Fatal(err)
   209  	}
   210  }
   211  
   212  func TestScanReposForURL(t *testing.T) {
   213  	c := ChartDownloader{
   214  		Out:              os.Stderr,
   215  		Verify:           VerifyLater,
   216  		RepositoryConfig: repoConfig,
   217  		RepositoryCache:  repoCache,
   218  		Getters: getter.All(&cli.EnvSettings{
   219  			RepositoryConfig: repoConfig,
   220  			RepositoryCache:  repoCache,
   221  		}),
   222  	}
   223  
   224  	u := "http://example.com/alpine-0.2.0.tgz"
   225  	rf, err := repo.LoadFile(repoConfig)
   226  	if err != nil {
   227  		t.Fatal(err)
   228  	}
   229  
   230  	entry, err := c.scanReposForURL(u, rf)
   231  	if err != nil {
   232  		t.Fatal(err)
   233  	}
   234  
   235  	if entry.Name != "testing" {
   236  		t.Errorf("Unexpected repo %q for URL %q", entry.Name, u)
   237  	}
   238  
   239  	// A lookup failure should produce an ErrNoOwnerRepo
   240  	u = "https://no.such.repo/foo/bar-1.23.4.tgz"
   241  	if _, err = c.scanReposForURL(u, rf); err != ErrNoOwnerRepo {
   242  		t.Fatalf("expected ErrNoOwnerRepo, got %v", err)
   243  	}
   244  }