github.com/umeshredd/helm@v3.0.0-alpha.1+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  	"helm.sh/helm/pkg/cli"
    29  	"helm.sh/helm/pkg/getter"
    30  	"helm.sh/helm/pkg/helmpath"
    31  	"helm.sh/helm/pkg/repo"
    32  	"helm.sh/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(cli.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", cli.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(cli.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(cli.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(cli.EnvSettings{}),
   293  	}
   294  
   295  	u := "http://example.com/alpine-0.2.0.tgz"
   296  	rf, err := repo.LoadFile(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  }