github.com/darkowlzz/helm@v2.5.1-0.20171213183701-6707fe0468d4+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/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  	getter, err := provider.New(srv.URL, "", "", "")
   103  	if err != nil {
   104  		t.Fatal(err)
   105  	}
   106  	got, err := getter.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  	defer basicAuthSrv.Close()
   124  
   125  	u, _ := url.ParseRequestURI(basicAuthSrv.URL)
   126  	u.User = url.UserPassword("username", "password")
   127  	got, err = getter.Get(u.String())
   128  	if err != nil {
   129  		t.Fatal(err)
   130  	}
   131  
   132  	if got.String() != expect {
   133  		t.Errorf("Expected %q, got %q", expect, got.String())
   134  	}
   135  }
   136  
   137  func TestIsTar(t *testing.T) {
   138  	tests := map[string]bool{
   139  		"foo.tgz":           true,
   140  		"foo/bar/baz.tgz":   true,
   141  		"foo-1.2.3.4.5.tgz": true,
   142  		"foo.tar.gz":        false, // for our purposes
   143  		"foo.tgz.1":         false,
   144  		"footgz":            false,
   145  	}
   146  
   147  	for src, expect := range tests {
   148  		if isTar(src) != expect {
   149  			t.Errorf("%q should be %t", src, expect)
   150  		}
   151  	}
   152  }
   153  
   154  func TestDownloadTo(t *testing.T) {
   155  	tmp, err := ioutil.TempDir("", "helm-downloadto-")
   156  	if err != nil {
   157  		t.Fatal(err)
   158  	}
   159  	defer os.RemoveAll(tmp)
   160  
   161  	hh := helmpath.Home(tmp)
   162  	dest := filepath.Join(hh.String(), "dest")
   163  	configDirectories := []string{
   164  		hh.String(),
   165  		hh.Repository(),
   166  		hh.Cache(),
   167  		dest,
   168  	}
   169  	for _, p := range configDirectories {
   170  		if fi, err := os.Stat(p); err != nil {
   171  			if err := os.MkdirAll(p, 0755); err != nil {
   172  				t.Fatalf("Could not create %s: %s", p, err)
   173  			}
   174  		} else if !fi.IsDir() {
   175  			t.Fatalf("%s must be a directory", p)
   176  		}
   177  	}
   178  
   179  	// Set up a fake repo
   180  	srv := repotest.NewServer(tmp)
   181  	defer srv.Stop()
   182  	if _, err := srv.CopyCharts("testdata/*.tgz*"); err != nil {
   183  		t.Error(err)
   184  		return
   185  	}
   186  	if err := srv.LinkIndices(); err != nil {
   187  		t.Fatal(err)
   188  	}
   189  
   190  	c := ChartDownloader{
   191  		HelmHome: hh,
   192  		Out:      os.Stderr,
   193  		Verify:   VerifyAlways,
   194  		Keyring:  "testdata/helm-test-key.pub",
   195  		Getters:  getter.All(environment.EnvSettings{}),
   196  	}
   197  	cname := "/signtest-0.1.0.tgz"
   198  	where, v, err := c.DownloadTo(srv.URL()+cname, "", dest)
   199  	if err != nil {
   200  		t.Error(err)
   201  		return
   202  	}
   203  
   204  	if expect := filepath.Join(dest, cname); where != expect {
   205  		t.Errorf("Expected download to %s, got %s", expect, where)
   206  	}
   207  
   208  	if v.FileHash == "" {
   209  		t.Error("File hash was empty, but verification is required.")
   210  	}
   211  
   212  	if _, err := os.Stat(filepath.Join(dest, cname)); err != nil {
   213  		t.Error(err)
   214  		return
   215  	}
   216  }
   217  
   218  func TestDownloadTo_VerifyLater(t *testing.T) {
   219  	tmp, err := ioutil.TempDir("", "helm-downloadto-")
   220  	if err != nil {
   221  		t.Fatal(err)
   222  	}
   223  	defer os.RemoveAll(tmp)
   224  
   225  	hh := helmpath.Home(tmp)
   226  	dest := filepath.Join(hh.String(), "dest")
   227  	configDirectories := []string{
   228  		hh.String(),
   229  		hh.Repository(),
   230  		hh.Cache(),
   231  		dest,
   232  	}
   233  	for _, p := range configDirectories {
   234  		if fi, err := os.Stat(p); err != nil {
   235  			if err := os.MkdirAll(p, 0755); err != nil {
   236  				t.Fatalf("Could not create %s: %s", p, err)
   237  			}
   238  		} else if !fi.IsDir() {
   239  			t.Fatalf("%s must be a directory", p)
   240  		}
   241  	}
   242  
   243  	// Set up a fake repo
   244  	srv := repotest.NewServer(tmp)
   245  	defer srv.Stop()
   246  	if _, err := srv.CopyCharts("testdata/*.tgz*"); err != nil {
   247  		t.Error(err)
   248  		return
   249  	}
   250  	if err := srv.LinkIndices(); err != nil {
   251  		t.Fatal(err)
   252  	}
   253  
   254  	c := ChartDownloader{
   255  		HelmHome: hh,
   256  		Out:      os.Stderr,
   257  		Verify:   VerifyLater,
   258  		Getters:  getter.All(environment.EnvSettings{}),
   259  	}
   260  	cname := "/signtest-0.1.0.tgz"
   261  	where, _, err := c.DownloadTo(srv.URL()+cname, "", dest)
   262  	if err != nil {
   263  		t.Error(err)
   264  		return
   265  	}
   266  
   267  	if expect := filepath.Join(dest, cname); where != expect {
   268  		t.Errorf("Expected download to %s, got %s", expect, where)
   269  	}
   270  
   271  	if _, err := os.Stat(filepath.Join(dest, cname)); err != nil {
   272  		t.Error(err)
   273  		return
   274  	}
   275  	if _, err := os.Stat(filepath.Join(dest, cname+".prov")); err != nil {
   276  		t.Error(err)
   277  		return
   278  	}
   279  }
   280  
   281  func TestScanReposForURL(t *testing.T) {
   282  	hh := helmpath.Home("testdata/helmhome")
   283  	c := ChartDownloader{
   284  		HelmHome: hh,
   285  		Out:      os.Stderr,
   286  		Verify:   VerifyLater,
   287  		Getters:  getter.All(environment.EnvSettings{}),
   288  	}
   289  
   290  	u := "http://example.com/alpine-0.2.0.tgz"
   291  	rf, err := repo.LoadRepositoriesFile(c.HelmHome.RepositoryFile())
   292  	if err != nil {
   293  		t.Fatal(err)
   294  	}
   295  
   296  	entry, err := c.scanReposForURL(u, rf)
   297  	if err != nil {
   298  		t.Fatal(err)
   299  	}
   300  
   301  	if entry.Name != "testing" {
   302  		t.Errorf("Unexpected repo %q for URL %q", entry.Name, u)
   303  	}
   304  
   305  	// A lookup failure should produce an ErrNoOwnerRepo
   306  	u = "https://no.such.repo/foo/bar-1.23.4.tgz"
   307  	if _, err = c.scanReposForURL(u, rf); err != ErrNoOwnerRepo {
   308  		t.Fatalf("expected ErrNoOwnerRepo, got %v", err)
   309  	}
   310  }