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