github.com/felipejfc/helm@v2.1.2+incompatible/pkg/repo/index_test.go (about)

     1  /*
     2  Copyright 2016 The Kubernetes Authors All rights reserved.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8      http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package repo
    18  
    19  import (
    20  	"io/ioutil"
    21  	"net/http"
    22  	"net/http/httptest"
    23  	"os"
    24  	"path/filepath"
    25  	"testing"
    26  
    27  	"k8s.io/helm/pkg/proto/hapi/chart"
    28  )
    29  
    30  const (
    31  	testfile = "testdata/local-index.yaml"
    32  	testRepo = "test-repo"
    33  )
    34  
    35  func TestIndexFile(t *testing.T) {
    36  	i := NewIndexFile()
    37  	i.Add(&chart.Metadata{Name: "clipper", Version: "0.1.0"}, "clipper-0.1.0.tgz", "http://example.com/charts", "sha256:1234567890")
    38  	i.Add(&chart.Metadata{Name: "cutter", Version: "0.1.1"}, "cutter-0.1.1.tgz", "http://example.com/charts", "sha256:1234567890abc")
    39  	i.Add(&chart.Metadata{Name: "cutter", Version: "0.1.0"}, "cutter-0.1.0.tgz", "http://example.com/charts", "sha256:1234567890abc")
    40  	i.Add(&chart.Metadata{Name: "cutter", Version: "0.2.0"}, "cutter-0.2.0.tgz", "http://example.com/charts", "sha256:1234567890abc")
    41  	i.SortEntries()
    42  
    43  	if i.APIVersion != APIVersionV1 {
    44  		t.Error("Expected API version v1")
    45  	}
    46  
    47  	if len(i.Entries) != 2 {
    48  		t.Errorf("Expected 2 charts. Got %d", len(i.Entries))
    49  	}
    50  
    51  	if i.Entries["clipper"][0].Name != "clipper" {
    52  		t.Errorf("Expected clipper, got %s", i.Entries["clipper"][0].Name)
    53  	}
    54  
    55  	if len(i.Entries["cutter"]) != 3 {
    56  		t.Error("Expected two cutters.")
    57  	}
    58  
    59  	// Test that the sort worked. 0.2 should be at the first index for Cutter.
    60  	if v := i.Entries["cutter"][0].Version; v != "0.2.0" {
    61  		t.Errorf("Unexpected first version: %s", v)
    62  	}
    63  }
    64  
    65  func TestLoadIndex(t *testing.T) {
    66  	b, err := ioutil.ReadFile(testfile)
    67  	if err != nil {
    68  		t.Fatal(err)
    69  	}
    70  	i, err := LoadIndex(b)
    71  	if err != nil {
    72  		t.Fatal(err)
    73  	}
    74  	verifyLocalIndex(t, i)
    75  }
    76  
    77  func TestLoadIndexFile(t *testing.T) {
    78  	i, err := LoadIndexFile(testfile)
    79  	if err != nil {
    80  		t.Fatal(err)
    81  	}
    82  	verifyLocalIndex(t, i)
    83  }
    84  
    85  func TestMerge(t *testing.T) {
    86  	ind1 := NewIndexFile()
    87  	ind1.Add(&chart.Metadata{
    88  		Name:    "dreadnought",
    89  		Version: "0.1.0",
    90  	}, "dreadnought-0.1.0.tgz", "http://example.com", "aaaa")
    91  
    92  	ind2 := NewIndexFile()
    93  	ind2.Add(&chart.Metadata{
    94  		Name:    "dreadnought",
    95  		Version: "0.2.0",
    96  	}, "dreadnought-0.2.0.tgz", "http://example.com", "aaaabbbb")
    97  	ind2.Add(&chart.Metadata{
    98  		Name:    "doughnut",
    99  		Version: "0.2.0",
   100  	}, "doughnut-0.2.0.tgz", "http://example.com", "ccccbbbb")
   101  
   102  	ind1.Merge(ind2)
   103  
   104  	if len(ind1.Entries) != 2 {
   105  		t.Errorf("Expected 2 entries, got %d", len(ind1.Entries))
   106  		vs := ind1.Entries["dreadnaught"]
   107  		if len(vs) != 2 {
   108  			t.Errorf("Expected 2 versions, got %d", len(vs))
   109  		}
   110  		v := vs[0]
   111  		if v.Version != "0.2.0" {
   112  			t.Errorf("Expected %q version to be 0.2.0, got %s", v.Name, v.Version)
   113  		}
   114  	}
   115  
   116  }
   117  
   118  func TestDownloadIndexFile(t *testing.T) {
   119  	fileBytes, err := ioutil.ReadFile("testdata/local-index.yaml")
   120  	if err != nil {
   121  		t.Fatal(err)
   122  	}
   123  
   124  	srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
   125  		w.Write(fileBytes)
   126  	}))
   127  	defer srv.Close()
   128  
   129  	dirName, err := ioutil.TempDir("", "tmp")
   130  	if err != nil {
   131  		t.Fatal(err)
   132  	}
   133  	defer os.RemoveAll(dirName)
   134  
   135  	path := filepath.Join(dirName, testRepo+"-index.yaml")
   136  	if err := DownloadIndexFile(testRepo, srv.URL, path); err != nil {
   137  		t.Errorf("%#v", err)
   138  	}
   139  
   140  	if _, err := os.Stat(path); err != nil {
   141  		t.Errorf("error finding created index file: %#v", err)
   142  	}
   143  
   144  	b, err := ioutil.ReadFile(path)
   145  	if err != nil {
   146  		t.Errorf("error reading index file: %#v", err)
   147  	}
   148  
   149  	i, err := LoadIndex(b)
   150  	if err != nil {
   151  		t.Errorf("Index %q failed to parse: %s", testfile, err)
   152  		return
   153  	}
   154  
   155  	verifyLocalIndex(t, i)
   156  }
   157  
   158  func verifyLocalIndex(t *testing.T, i *IndexFile) {
   159  	numEntries := len(i.Entries)
   160  	if numEntries != 2 {
   161  		t.Errorf("Expected 2 entries in index file but got %d", numEntries)
   162  	}
   163  
   164  	alpine, ok := i.Entries["alpine"]
   165  	if !ok {
   166  		t.Errorf("'alpine' section not found.")
   167  		return
   168  	}
   169  
   170  	if l := len(alpine); l != 1 {
   171  		t.Errorf("'alpine' should have 1 chart, got %d", l)
   172  		return
   173  	}
   174  
   175  	nginx, ok := i.Entries["nginx"]
   176  	if !ok || len(nginx) != 2 {
   177  		t.Error("Expected 2 nginx entries")
   178  		return
   179  	}
   180  
   181  	expects := []*ChartVersion{
   182  		{
   183  			Metadata: &chart.Metadata{
   184  				Name:        "alpine",
   185  				Description: "string",
   186  				Version:     "1.0.0",
   187  				Keywords:    []string{"linux", "alpine", "small", "sumtin"},
   188  				Home:        "https://github.com/something",
   189  			},
   190  			URLs: []string{
   191  				"https://kubernetes-charts.storage.googleapis.com/alpine-1.0.0.tgz",
   192  				"http://storage2.googleapis.com/kubernetes-charts/alpine-1.0.0.tgz",
   193  			},
   194  			Digest: "sha256:1234567890abcdef",
   195  		},
   196  		{
   197  			Metadata: &chart.Metadata{
   198  				Name:        "nginx",
   199  				Description: "string",
   200  				Version:     "0.2.0",
   201  				Keywords:    []string{"popular", "web server", "proxy"},
   202  				Home:        "https://github.com/something/else",
   203  			},
   204  			URLs: []string{
   205  				"https://kubernetes-charts.storage.googleapis.com/nginx-0.2.0.tgz",
   206  			},
   207  			Digest: "sha256:1234567890abcdef",
   208  		},
   209  		{
   210  			Metadata: &chart.Metadata{
   211  				Name:        "nginx",
   212  				Description: "string",
   213  				Version:     "0.1.0",
   214  				Keywords:    []string{"popular", "web server", "proxy"},
   215  				Home:        "https://github.com/something",
   216  			},
   217  			URLs: []string{
   218  				"https://kubernetes-charts.storage.googleapis.com/nginx-0.1.0.tgz",
   219  			},
   220  			Digest: "sha256:1234567890abcdef",
   221  		},
   222  	}
   223  	tests := []*ChartVersion{alpine[0], nginx[0], nginx[1]}
   224  
   225  	for i, tt := range tests {
   226  		expect := expects[i]
   227  		if tt.Name != expect.Name {
   228  			t.Errorf("Expected name %q, got %q", expect.Name, tt.Name)
   229  		}
   230  		if tt.Description != expect.Description {
   231  			t.Errorf("Expected description %q, got %q", expect.Description, tt.Description)
   232  		}
   233  		if tt.Version != expect.Version {
   234  			t.Errorf("Expected version %q, got %q", expect.Version, tt.Version)
   235  		}
   236  		if tt.Digest != expect.Digest {
   237  			t.Errorf("Expected digest %q, got %q", expect.Digest, tt.Digest)
   238  		}
   239  		if tt.Home != expect.Home {
   240  			t.Errorf("Expected home %q, got %q", expect.Home, tt.Home)
   241  		}
   242  
   243  		for i, url := range tt.URLs {
   244  			if url != expect.URLs[i] {
   245  				t.Errorf("Expected URL %q, got %q", expect.URLs[i], url)
   246  			}
   247  		}
   248  		for i, kw := range tt.Keywords {
   249  			if kw != expect.Keywords[i] {
   250  				t.Errorf("Expected keywords %q, got %q", expect.Keywords[i], kw)
   251  			}
   252  		}
   253  	}
   254  }
   255  
   256  func TestIndexDirectory(t *testing.T) {
   257  	dir := "testdata/repository"
   258  	index, err := IndexDirectory(dir, "http://localhost:8080")
   259  	if err != nil {
   260  		t.Fatal(err)
   261  	}
   262  
   263  	if l := len(index.Entries); l != 2 {
   264  		t.Fatalf("Expected 2 entries, got %d", l)
   265  	}
   266  
   267  	// Other things test the entry generation more thoroughly. We just test a
   268  	// few fields.
   269  	cname := "frobnitz"
   270  	frobs, ok := index.Entries[cname]
   271  	if !ok {
   272  		t.Fatalf("Could not read chart %s", cname)
   273  	}
   274  
   275  	frob := frobs[0]
   276  	if len(frob.Digest) == 0 {
   277  		t.Errorf("Missing digest of file %s.", frob.Name)
   278  	}
   279  	if frob.URLs[0] != "http://localhost:8080/frobnitz-1.2.3.tgz" {
   280  		t.Errorf("Unexpected URLs: %v", frob.URLs)
   281  	}
   282  	if frob.Name != "frobnitz" {
   283  		t.Errorf("Expected frobnitz, got %q", frob.Name)
   284  	}
   285  }
   286  
   287  func TestLoadUnversionedIndex(t *testing.T) {
   288  	data, err := ioutil.ReadFile("testdata/unversioned-index.yaml")
   289  	if err != nil {
   290  		t.Fatal(err)
   291  	}
   292  
   293  	ind, err := loadUnversionedIndex(data)
   294  	if err != nil {
   295  		t.Fatal(err)
   296  	}
   297  
   298  	if l := len(ind.Entries); l != 2 {
   299  		t.Fatalf("Expected 2 entries, got %d", l)
   300  	}
   301  
   302  	if l := len(ind.Entries["mysql"]); l != 3 {
   303  		t.Fatalf("Expected 3 mysql versions, got %d", l)
   304  	}
   305  }
   306  
   307  func TestIndexAdd(t *testing.T) {
   308  
   309  	i := NewIndexFile()
   310  	i.Add(&chart.Metadata{Name: "clipper", Version: "0.1.0"}, "clipper-0.1.0.tgz", "http://example.com/charts", "sha256:1234567890")
   311  
   312  	if i.Entries["clipper"][0].URLs[0] != "http://example.com/charts/clipper-0.1.0.tgz" {
   313  		t.Errorf("Expected http://example.com/charts/clipper-0.1.0.tgz, got %s", i.Entries["clipper"][0].URLs[0])
   314  	}
   315  
   316  	i.Add(&chart.Metadata{Name: "alpine", Version: "0.1.0"}, "/home/charts/alpine-0.1.0.tgz", "http://example.com/charts", "sha256:1234567890")
   317  
   318  	if i.Entries["alpine"][0].URLs[0] != "http://example.com/charts/alpine-0.1.0.tgz" {
   319  		t.Errorf("Expected http://example.com/charts/alpine-0.1.0.tgz, got %s", i.Entries["alpine"][0].URLs[0])
   320  	}
   321  
   322  	i.Add(&chart.Metadata{Name: "deis", Version: "0.1.0"}, "/home/charts/deis-0.1.0.tgz", "http://example.com/charts/", "sha256:1234567890")
   323  
   324  	if i.Entries["deis"][0].URLs[0] != "http://example.com/charts/deis-0.1.0.tgz" {
   325  		t.Errorf("Expected http://example.com/charts/deis-0.1.0.tgz, got %s", i.Entries["deis"][0].URLs[0])
   326  	}
   327  }
   328  
   329  func TestUrlJoin(t *testing.T) {
   330  	tests := []struct {
   331  		name, url, expect string
   332  		paths             []string
   333  	}{
   334  		{name: "URL, one path", url: "http://example.com", paths: []string{"hello"}, expect: "http://example.com/hello"},
   335  		{name: "Long URL, one path", url: "http://example.com/but/first", paths: []string{"slurm"}, expect: "http://example.com/but/first/slurm"},
   336  		{name: "URL, two paths", url: "http://example.com", paths: []string{"hello", "world"}, expect: "http://example.com/hello/world"},
   337  		{name: "URL, no paths", url: "http://example.com", paths: []string{}, expect: "http://example.com"},
   338  		{name: "basepath, two paths", url: "../example.com", paths: []string{"hello", "world"}, expect: "../example.com/hello/world"},
   339  	}
   340  
   341  	for _, tt := range tests {
   342  		if got, err := urlJoin(tt.url, tt.paths...); err != nil {
   343  			t.Errorf("%s: error %q", tt.name, err)
   344  		} else if got != tt.expect {
   345  			t.Errorf("%s: expected %q, got %q", tt.name, tt.expect, got)
   346  		}
   347  	}
   348  }