github.com/cloudposse/helm@v2.2.3+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  	indexFilePath := filepath.Join(dirName, testRepo+"-index.yaml")
   136  	r, err := NewChartRepository(&Entry{
   137  		Name:  testRepo,
   138  		URL:   srv.URL,
   139  		Cache: indexFilePath,
   140  	})
   141  	if err != nil {
   142  		t.Errorf("Problem creating chart repository from %s: %v", testRepo, err)
   143  	}
   144  
   145  	if err := r.DownloadIndexFile(""); err != nil {
   146  		t.Errorf("%#v", err)
   147  	}
   148  
   149  	if _, err := os.Stat(indexFilePath); err != nil {
   150  		t.Errorf("error finding created index file: %#v", err)
   151  	}
   152  
   153  	b, err := ioutil.ReadFile(indexFilePath)
   154  	if err != nil {
   155  		t.Errorf("error reading index file: %#v", err)
   156  	}
   157  
   158  	i, err := loadIndex(b)
   159  	if err != nil {
   160  		t.Errorf("Index %q failed to parse: %s", testfile, err)
   161  		return
   162  	}
   163  
   164  	verifyLocalIndex(t, i)
   165  }
   166  
   167  func verifyLocalIndex(t *testing.T, i *IndexFile) {
   168  	numEntries := len(i.Entries)
   169  	if numEntries != 2 {
   170  		t.Errorf("Expected 2 entries in index file but got %d", numEntries)
   171  	}
   172  
   173  	alpine, ok := i.Entries["alpine"]
   174  	if !ok {
   175  		t.Errorf("'alpine' section not found.")
   176  		return
   177  	}
   178  
   179  	if l := len(alpine); l != 1 {
   180  		t.Errorf("'alpine' should have 1 chart, got %d", l)
   181  		return
   182  	}
   183  
   184  	nginx, ok := i.Entries["nginx"]
   185  	if !ok || len(nginx) != 2 {
   186  		t.Error("Expected 2 nginx entries")
   187  		return
   188  	}
   189  
   190  	expects := []*ChartVersion{
   191  		{
   192  			Metadata: &chart.Metadata{
   193  				Name:        "alpine",
   194  				Description: "string",
   195  				Version:     "1.0.0",
   196  				Keywords:    []string{"linux", "alpine", "small", "sumtin"},
   197  				Home:        "https://github.com/something",
   198  			},
   199  			URLs: []string{
   200  				"https://kubernetes-charts.storage.googleapis.com/alpine-1.0.0.tgz",
   201  				"http://storage2.googleapis.com/kubernetes-charts/alpine-1.0.0.tgz",
   202  			},
   203  			Digest: "sha256:1234567890abcdef",
   204  		},
   205  		{
   206  			Metadata: &chart.Metadata{
   207  				Name:        "nginx",
   208  				Description: "string",
   209  				Version:     "0.2.0",
   210  				Keywords:    []string{"popular", "web server", "proxy"},
   211  				Home:        "https://github.com/something/else",
   212  			},
   213  			URLs: []string{
   214  				"https://kubernetes-charts.storage.googleapis.com/nginx-0.2.0.tgz",
   215  			},
   216  			Digest: "sha256:1234567890abcdef",
   217  		},
   218  		{
   219  			Metadata: &chart.Metadata{
   220  				Name:        "nginx",
   221  				Description: "string",
   222  				Version:     "0.1.0",
   223  				Keywords:    []string{"popular", "web server", "proxy"},
   224  				Home:        "https://github.com/something",
   225  			},
   226  			URLs: []string{
   227  				"https://kubernetes-charts.storage.googleapis.com/nginx-0.1.0.tgz",
   228  			},
   229  			Digest: "sha256:1234567890abcdef",
   230  		},
   231  	}
   232  	tests := []*ChartVersion{alpine[0], nginx[0], nginx[1]}
   233  
   234  	for i, tt := range tests {
   235  		expect := expects[i]
   236  		if tt.Name != expect.Name {
   237  			t.Errorf("Expected name %q, got %q", expect.Name, tt.Name)
   238  		}
   239  		if tt.Description != expect.Description {
   240  			t.Errorf("Expected description %q, got %q", expect.Description, tt.Description)
   241  		}
   242  		if tt.Version != expect.Version {
   243  			t.Errorf("Expected version %q, got %q", expect.Version, tt.Version)
   244  		}
   245  		if tt.Digest != expect.Digest {
   246  			t.Errorf("Expected digest %q, got %q", expect.Digest, tt.Digest)
   247  		}
   248  		if tt.Home != expect.Home {
   249  			t.Errorf("Expected home %q, got %q", expect.Home, tt.Home)
   250  		}
   251  
   252  		for i, url := range tt.URLs {
   253  			if url != expect.URLs[i] {
   254  				t.Errorf("Expected URL %q, got %q", expect.URLs[i], url)
   255  			}
   256  		}
   257  		for i, kw := range tt.Keywords {
   258  			if kw != expect.Keywords[i] {
   259  				t.Errorf("Expected keywords %q, got %q", expect.Keywords[i], kw)
   260  			}
   261  		}
   262  	}
   263  }
   264  
   265  func TestIndexDirectory(t *testing.T) {
   266  	dir := "testdata/repository"
   267  	index, err := IndexDirectory(dir, "http://localhost:8080")
   268  	if err != nil {
   269  		t.Fatal(err)
   270  	}
   271  
   272  	if l := len(index.Entries); l != 2 {
   273  		t.Fatalf("Expected 2 entries, got %d", l)
   274  	}
   275  
   276  	// Other things test the entry generation more thoroughly. We just test a
   277  	// few fields.
   278  	cname := "frobnitz"
   279  	frobs, ok := index.Entries[cname]
   280  	if !ok {
   281  		t.Fatalf("Could not read chart %s", cname)
   282  	}
   283  
   284  	frob := frobs[0]
   285  	if len(frob.Digest) == 0 {
   286  		t.Errorf("Missing digest of file %s.", frob.Name)
   287  	}
   288  	if frob.URLs[0] != "http://localhost:8080/frobnitz-1.2.3.tgz" {
   289  		t.Errorf("Unexpected URLs: %v", frob.URLs)
   290  	}
   291  	if frob.Name != "frobnitz" {
   292  		t.Errorf("Expected frobnitz, got %q", frob.Name)
   293  	}
   294  }
   295  
   296  func TestLoadUnversionedIndex(t *testing.T) {
   297  	data, err := ioutil.ReadFile("testdata/unversioned-index.yaml")
   298  	if err != nil {
   299  		t.Fatal(err)
   300  	}
   301  
   302  	ind, err := loadUnversionedIndex(data)
   303  	if err != nil {
   304  		t.Fatal(err)
   305  	}
   306  
   307  	if l := len(ind.Entries); l != 2 {
   308  		t.Fatalf("Expected 2 entries, got %d", l)
   309  	}
   310  
   311  	if l := len(ind.Entries["mysql"]); l != 3 {
   312  		t.Fatalf("Expected 3 mysql versions, got %d", l)
   313  	}
   314  }
   315  
   316  func TestIndexAdd(t *testing.T) {
   317  	i := NewIndexFile()
   318  	i.Add(&chart.Metadata{Name: "clipper", Version: "0.1.0"}, "clipper-0.1.0.tgz", "http://example.com/charts", "sha256:1234567890")
   319  
   320  	if i.Entries["clipper"][0].URLs[0] != "http://example.com/charts/clipper-0.1.0.tgz" {
   321  		t.Errorf("Expected http://example.com/charts/clipper-0.1.0.tgz, got %s", i.Entries["clipper"][0].URLs[0])
   322  	}
   323  
   324  	i.Add(&chart.Metadata{Name: "alpine", Version: "0.1.0"}, "/home/charts/alpine-0.1.0.tgz", "http://example.com/charts", "sha256:1234567890")
   325  
   326  	if i.Entries["alpine"][0].URLs[0] != "http://example.com/charts/alpine-0.1.0.tgz" {
   327  		t.Errorf("Expected http://example.com/charts/alpine-0.1.0.tgz, got %s", i.Entries["alpine"][0].URLs[0])
   328  	}
   329  
   330  	i.Add(&chart.Metadata{Name: "deis", Version: "0.1.0"}, "/home/charts/deis-0.1.0.tgz", "http://example.com/charts/", "sha256:1234567890")
   331  
   332  	if i.Entries["deis"][0].URLs[0] != "http://example.com/charts/deis-0.1.0.tgz" {
   333  		t.Errorf("Expected http://example.com/charts/deis-0.1.0.tgz, got %s", i.Entries["deis"][0].URLs[0])
   334  	}
   335  }