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