...

Source file src/helm.sh/helm/v3/pkg/repo/index_test.go

Documentation: helm.sh/helm/v3/pkg/repo

     1  /*
     2  Copyright The Helm Authors.
     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  	"bufio"
    21  	"bytes"
    22  	"encoding/json"
    23  	"fmt"
    24  	"net/http"
    25  	"os"
    26  	"path/filepath"
    27  	"sort"
    28  	"strings"
    29  	"testing"
    30  
    31  	"helm.sh/helm/v3/pkg/chart"
    32  	"helm.sh/helm/v3/pkg/cli"
    33  	"helm.sh/helm/v3/pkg/getter"
    34  	"helm.sh/helm/v3/pkg/helmpath"
    35  )
    36  
    37  const (
    38  	testfile            = "testdata/local-index.yaml"
    39  	annotationstestfile = "testdata/local-index-annotations.yaml"
    40  	chartmuseumtestfile = "testdata/chartmuseum-index.yaml"
    41  	unorderedTestfile   = "testdata/local-index-unordered.yaml"
    42  	jsonTestfile        = "testdata/local-index.json"
    43  	testRepo            = "test-repo"
    44  	indexWithDuplicates = `
    45  apiVersion: v1
    46  entries:
    47    nginx:
    48      - urls:
    49          - https://charts.helm.sh/stable/nginx-0.2.0.tgz
    50        name: nginx
    51        description: string
    52        version: 0.2.0
    53        home: https://github.com/something/else
    54        digest: "sha256:1234567890abcdef"
    55    nginx:
    56      - urls:
    57          - https://charts.helm.sh/stable/alpine-1.0.0.tgz
    58          - http://storage2.googleapis.com/kubernetes-charts/alpine-1.0.0.tgz
    59        name: alpine
    60        description: string
    61        version: 1.0.0
    62        home: https://github.com/something
    63        digest: "sha256:1234567890abcdef"
    64  `
    65  	indexWithEmptyEntry = `
    66  apiVersion: v1
    67  entries:
    68    grafana:
    69    - apiVersion: v2
    70      name: grafana
    71    foo:
    72    -
    73    bar:
    74    - digest: "sha256:1234567890abcdef"
    75      urls:
    76      - https://charts.helm.sh/stable/alpine-1.0.0.tgz
    77  `
    78  )
    79  
    80  func TestIndexFile(t *testing.T) {
    81  	i := NewIndexFile()
    82  	for _, x := range []struct {
    83  		md       *chart.Metadata
    84  		filename string
    85  		baseURL  string
    86  		digest   string
    87  	}{
    88  		{&chart.Metadata{APIVersion: "v2", Name: "clipper", Version: "0.1.0"}, "clipper-0.1.0.tgz", "http://example.com/charts", "sha256:1234567890"},
    89  		{&chart.Metadata{APIVersion: "v2", Name: "cutter", Version: "0.1.1"}, "cutter-0.1.1.tgz", "http://example.com/charts", "sha256:1234567890abc"},
    90  		{&chart.Metadata{APIVersion: "v2", Name: "cutter", Version: "0.1.0"}, "cutter-0.1.0.tgz", "http://example.com/charts", "sha256:1234567890abc"},
    91  		{&chart.Metadata{APIVersion: "v2", Name: "cutter", Version: "0.2.0"}, "cutter-0.2.0.tgz", "http://example.com/charts", "sha256:1234567890abc"},
    92  		{&chart.Metadata{APIVersion: "v2", Name: "setter", Version: "0.1.9+alpha"}, "setter-0.1.9+alpha.tgz", "http://example.com/charts", "sha256:1234567890abc"},
    93  		{&chart.Metadata{APIVersion: "v2", Name: "setter", Version: "0.1.9+beta"}, "setter-0.1.9+beta.tgz", "http://example.com/charts", "sha256:1234567890abc"},
    94  		{&chart.Metadata{APIVersion: "v2", Name: "setter", Version: "0.1.8"}, "setter-0.1.8.tgz", "http://example.com/charts", "sha256:1234567890abc"},
    95  		{&chart.Metadata{APIVersion: "v2", Name: "setter", Version: "0.1.8+beta"}, "setter-0.1.8+beta.tgz", "http://example.com/charts", "sha256:1234567890abc"},
    96  	} {
    97  		if err := i.MustAdd(x.md, x.filename, x.baseURL, x.digest); err != nil {
    98  			t.Errorf("unexpected error adding to index: %s", err)
    99  		}
   100  	}
   101  
   102  	i.SortEntries()
   103  
   104  	if i.APIVersion != APIVersionV1 {
   105  		t.Error("Expected API version v1")
   106  	}
   107  
   108  	if len(i.Entries) != 3 {
   109  		t.Errorf("Expected 3 charts. Got %d", len(i.Entries))
   110  	}
   111  
   112  	if i.Entries["clipper"][0].Name != "clipper" {
   113  		t.Errorf("Expected clipper, got %s", i.Entries["clipper"][0].Name)
   114  	}
   115  
   116  	if len(i.Entries["cutter"]) != 3 {
   117  		t.Error("Expected three cutters.")
   118  	}
   119  
   120  	// Test that the sort worked. 0.2 should be at the first index for Cutter.
   121  	if v := i.Entries["cutter"][0].Version; v != "0.2.0" {
   122  		t.Errorf("Unexpected first version: %s", v)
   123  	}
   124  
   125  	cv, err := i.Get("setter", "0.1.9")
   126  	if err == nil && !strings.Contains(cv.Metadata.Version, "0.1.9") {
   127  		t.Errorf("Unexpected version: %s", cv.Metadata.Version)
   128  	}
   129  
   130  	cv, err = i.Get("setter", "0.1.9+alpha")
   131  	if err != nil || cv.Metadata.Version != "0.1.9+alpha" {
   132  		t.Errorf("Expected version: 0.1.9+alpha")
   133  	}
   134  
   135  	cv, err = i.Get("setter", "0.1.8")
   136  	if err != nil || cv.Metadata.Version != "0.1.8" {
   137  		t.Errorf("Expected version: 0.1.8")
   138  	}
   139  }
   140  
   141  func TestLoadIndex(t *testing.T) {
   142  
   143  	tests := []struct {
   144  		Name     string
   145  		Filename string
   146  	}{
   147  		{
   148  			Name:     "regular index file",
   149  			Filename: testfile,
   150  		},
   151  		{
   152  			Name:     "chartmuseum index file",
   153  			Filename: chartmuseumtestfile,
   154  		},
   155  		{
   156  			Name:     "JSON index file",
   157  			Filename: jsonTestfile,
   158  		},
   159  	}
   160  
   161  	for _, tc := range tests {
   162  		tc := tc
   163  		t.Run(tc.Name, func(t *testing.T) {
   164  			t.Parallel()
   165  			i, err := LoadIndexFile(tc.Filename)
   166  			if err != nil {
   167  				t.Fatal(err)
   168  			}
   169  			verifyLocalIndex(t, i)
   170  		})
   171  	}
   172  }
   173  
   174  // TestLoadIndex_Duplicates is a regression to make sure that we don't non-deterministically allow duplicate packages.
   175  func TestLoadIndex_Duplicates(t *testing.T) {
   176  	if _, err := loadIndex([]byte(indexWithDuplicates), "indexWithDuplicates"); err == nil {
   177  		t.Errorf("Expected an error when duplicate entries are present")
   178  	}
   179  }
   180  
   181  func TestLoadIndex_EmptyEntry(t *testing.T) {
   182  	if _, err := loadIndex([]byte(indexWithEmptyEntry), "indexWithEmptyEntry"); err != nil {
   183  		t.Errorf("unexpected error: %s", err)
   184  	}
   185  }
   186  
   187  func TestLoadIndex_Empty(t *testing.T) {
   188  	if _, err := loadIndex([]byte(""), "indexWithEmpty"); err == nil {
   189  		t.Errorf("Expected an error when index.yaml is empty.")
   190  	}
   191  }
   192  
   193  func TestLoadIndexFileAnnotations(t *testing.T) {
   194  	i, err := LoadIndexFile(annotationstestfile)
   195  	if err != nil {
   196  		t.Fatal(err)
   197  	}
   198  	verifyLocalIndex(t, i)
   199  
   200  	if len(i.Annotations) != 1 {
   201  		t.Fatalf("Expected 1 annotation but got %d", len(i.Annotations))
   202  	}
   203  	if i.Annotations["helm.sh/test"] != "foo bar" {
   204  		t.Error("Did not get expected value for helm.sh/test annotation")
   205  	}
   206  }
   207  
   208  func TestLoadUnorderedIndex(t *testing.T) {
   209  	i, err := LoadIndexFile(unorderedTestfile)
   210  	if err != nil {
   211  		t.Fatal(err)
   212  	}
   213  	verifyLocalIndex(t, i)
   214  }
   215  
   216  func TestMerge(t *testing.T) {
   217  	ind1 := NewIndexFile()
   218  
   219  	if err := ind1.MustAdd(&chart.Metadata{APIVersion: "v2", Name: "dreadnought", Version: "0.1.0"}, "dreadnought-0.1.0.tgz", "http://example.com", "aaaa"); err != nil {
   220  		t.Fatalf("unexpected error: %s", err)
   221  	}
   222  
   223  	ind2 := NewIndexFile()
   224  
   225  	for _, x := range []struct {
   226  		md       *chart.Metadata
   227  		filename string
   228  		baseURL  string
   229  		digest   string
   230  	}{
   231  		{&chart.Metadata{APIVersion: "v2", Name: "dreadnought", Version: "0.2.0"}, "dreadnought-0.2.0.tgz", "http://example.com", "aaaabbbb"},
   232  		{&chart.Metadata{APIVersion: "v2", Name: "doughnut", Version: "0.2.0"}, "doughnut-0.2.0.tgz", "http://example.com", "ccccbbbb"},
   233  	} {
   234  		if err := ind2.MustAdd(x.md, x.filename, x.baseURL, x.digest); err != nil {
   235  			t.Errorf("unexpected error: %s", err)
   236  		}
   237  	}
   238  
   239  	ind1.Merge(ind2)
   240  
   241  	if len(ind1.Entries) != 2 {
   242  		t.Errorf("Expected 2 entries, got %d", len(ind1.Entries))
   243  	}
   244  
   245  	vs := ind1.Entries["dreadnought"]
   246  	if len(vs) != 2 {
   247  		t.Errorf("Expected 2 versions, got %d", len(vs))
   248  	}
   249  
   250  	if v := vs[1]; v.Version != "0.2.0" {
   251  		t.Errorf("Expected %q version to be 0.2.0, got %s", v.Name, v.Version)
   252  	}
   253  
   254  }
   255  
   256  func TestDownloadIndexFile(t *testing.T) {
   257  	t.Run("should  download index file", func(t *testing.T) {
   258  		srv, err := startLocalServerForTests(nil)
   259  		if err != nil {
   260  			t.Fatal(err)
   261  		}
   262  		defer srv.Close()
   263  
   264  		r, err := NewChartRepository(&Entry{
   265  			Name: testRepo,
   266  			URL:  srv.URL,
   267  		}, getter.All(&cli.EnvSettings{}))
   268  		if err != nil {
   269  			t.Errorf("Problem creating chart repository from %s: %v", testRepo, err)
   270  		}
   271  
   272  		idx, err := r.DownloadIndexFile()
   273  		if err != nil {
   274  			t.Fatalf("Failed to download index file to %s: %#v", idx, err)
   275  		}
   276  
   277  		if _, err := os.Stat(idx); err != nil {
   278  			t.Fatalf("error finding created index file: %#v", err)
   279  		}
   280  
   281  		i, err := LoadIndexFile(idx)
   282  		if err != nil {
   283  			t.Fatalf("Index %q failed to parse: %s", testfile, err)
   284  		}
   285  		verifyLocalIndex(t, i)
   286  
   287  		// Check that charts file is also created
   288  		idx = filepath.Join(r.CachePath, helmpath.CacheChartsFile(r.Config.Name))
   289  		if _, err := os.Stat(idx); err != nil {
   290  			t.Fatalf("error finding created charts file: %#v", err)
   291  		}
   292  
   293  		b, err := os.ReadFile(idx)
   294  		if err != nil {
   295  			t.Fatalf("error reading charts file: %#v", err)
   296  		}
   297  		verifyLocalChartsFile(t, b, i)
   298  	})
   299  
   300  	t.Run("should not decode the path in the repo url while downloading index", func(t *testing.T) {
   301  		chartRepoURLPath := "/some%2Fpath/test"
   302  		fileBytes, err := os.ReadFile("testdata/local-index.yaml")
   303  		if err != nil {
   304  			t.Fatal(err)
   305  		}
   306  		handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
   307  			if r.URL.RawPath == chartRepoURLPath+"/index.yaml" {
   308  				w.Write(fileBytes)
   309  			}
   310  		})
   311  		srv, err := startLocalServerForTests(handler)
   312  		if err != nil {
   313  			t.Fatal(err)
   314  		}
   315  		defer srv.Close()
   316  
   317  		r, err := NewChartRepository(&Entry{
   318  			Name: testRepo,
   319  			URL:  srv.URL + chartRepoURLPath,
   320  		}, getter.All(&cli.EnvSettings{}))
   321  		if err != nil {
   322  			t.Errorf("Problem creating chart repository from %s: %v", testRepo, err)
   323  		}
   324  
   325  		idx, err := r.DownloadIndexFile()
   326  		if err != nil {
   327  			t.Fatalf("Failed to download index file to %s: %#v", idx, err)
   328  		}
   329  
   330  		if _, err := os.Stat(idx); err != nil {
   331  			t.Fatalf("error finding created index file: %#v", err)
   332  		}
   333  
   334  		i, err := LoadIndexFile(idx)
   335  		if err != nil {
   336  			t.Fatalf("Index %q failed to parse: %s", testfile, err)
   337  		}
   338  		verifyLocalIndex(t, i)
   339  
   340  		// Check that charts file is also created
   341  		idx = filepath.Join(r.CachePath, helmpath.CacheChartsFile(r.Config.Name))
   342  		if _, err := os.Stat(idx); err != nil {
   343  			t.Fatalf("error finding created charts file: %#v", err)
   344  		}
   345  
   346  		b, err := os.ReadFile(idx)
   347  		if err != nil {
   348  			t.Fatalf("error reading charts file: %#v", err)
   349  		}
   350  		verifyLocalChartsFile(t, b, i)
   351  	})
   352  }
   353  
   354  func verifyLocalIndex(t *testing.T, i *IndexFile) {
   355  	numEntries := len(i.Entries)
   356  	if numEntries != 3 {
   357  		t.Errorf("Expected 3 entries in index file but got %d", numEntries)
   358  	}
   359  
   360  	alpine, ok := i.Entries["alpine"]
   361  	if !ok {
   362  		t.Fatalf("'alpine' section not found.")
   363  	}
   364  
   365  	if l := len(alpine); l != 1 {
   366  		t.Fatalf("'alpine' should have 1 chart, got %d", l)
   367  	}
   368  
   369  	nginx, ok := i.Entries["nginx"]
   370  	if !ok || len(nginx) != 2 {
   371  		t.Fatalf("Expected 2 nginx entries")
   372  	}
   373  
   374  	expects := []*ChartVersion{
   375  		{
   376  			Metadata: &chart.Metadata{
   377  				APIVersion:  "v2",
   378  				Name:        "alpine",
   379  				Description: "string",
   380  				Version:     "1.0.0",
   381  				Keywords:    []string{"linux", "alpine", "small", "sumtin"},
   382  				Home:        "https://github.com/something",
   383  			},
   384  			URLs: []string{
   385  				"https://charts.helm.sh/stable/alpine-1.0.0.tgz",
   386  				"http://storage2.googleapis.com/kubernetes-charts/alpine-1.0.0.tgz",
   387  			},
   388  			Digest: "sha256:1234567890abcdef",
   389  		},
   390  		{
   391  			Metadata: &chart.Metadata{
   392  				APIVersion:  "v2",
   393  				Name:        "nginx",
   394  				Description: "string",
   395  				Version:     "0.2.0",
   396  				Keywords:    []string{"popular", "web server", "proxy"},
   397  				Home:        "https://github.com/something/else",
   398  			},
   399  			URLs: []string{
   400  				"https://charts.helm.sh/stable/nginx-0.2.0.tgz",
   401  			},
   402  			Digest: "sha256:1234567890abcdef",
   403  		},
   404  		{
   405  			Metadata: &chart.Metadata{
   406  				APIVersion:  "v2",
   407  				Name:        "nginx",
   408  				Description: "string",
   409  				Version:     "0.1.0",
   410  				Keywords:    []string{"popular", "web server", "proxy"},
   411  				Home:        "https://github.com/something",
   412  			},
   413  			URLs: []string{
   414  				"https://charts.helm.sh/stable/nginx-0.1.0.tgz",
   415  			},
   416  			Digest: "sha256:1234567890abcdef",
   417  		},
   418  	}
   419  	tests := []*ChartVersion{alpine[0], nginx[0], nginx[1]}
   420  
   421  	for i, tt := range tests {
   422  		expect := expects[i]
   423  		if tt.Name != expect.Name {
   424  			t.Errorf("Expected name %q, got %q", expect.Name, tt.Name)
   425  		}
   426  		if tt.Description != expect.Description {
   427  			t.Errorf("Expected description %q, got %q", expect.Description, tt.Description)
   428  		}
   429  		if tt.Version != expect.Version {
   430  			t.Errorf("Expected version %q, got %q", expect.Version, tt.Version)
   431  		}
   432  		if tt.Digest != expect.Digest {
   433  			t.Errorf("Expected digest %q, got %q", expect.Digest, tt.Digest)
   434  		}
   435  		if tt.Home != expect.Home {
   436  			t.Errorf("Expected home %q, got %q", expect.Home, tt.Home)
   437  		}
   438  
   439  		for i, url := range tt.URLs {
   440  			if url != expect.URLs[i] {
   441  				t.Errorf("Expected URL %q, got %q", expect.URLs[i], url)
   442  			}
   443  		}
   444  		for i, kw := range tt.Keywords {
   445  			if kw != expect.Keywords[i] {
   446  				t.Errorf("Expected keywords %q, got %q", expect.Keywords[i], kw)
   447  			}
   448  		}
   449  	}
   450  }
   451  
   452  func verifyLocalChartsFile(t *testing.T, chartsContent []byte, indexContent *IndexFile) {
   453  	var expected, reald []string
   454  	for chart := range indexContent.Entries {
   455  		expected = append(expected, chart)
   456  	}
   457  	sort.Strings(expected)
   458  
   459  	scanner := bufio.NewScanner(bytes.NewReader(chartsContent))
   460  	for scanner.Scan() {
   461  		reald = append(reald, scanner.Text())
   462  	}
   463  	sort.Strings(reald)
   464  
   465  	if strings.Join(expected, " ") != strings.Join(reald, " ") {
   466  		t.Errorf("Cached charts file content unexpected. Expected:\n%s\ngot:\n%s", expected, reald)
   467  	}
   468  }
   469  
   470  func TestIndexDirectory(t *testing.T) {
   471  	dir := "testdata/repository"
   472  	index, err := IndexDirectory(dir, "http://localhost:8080")
   473  	if err != nil {
   474  		t.Fatal(err)
   475  	}
   476  
   477  	if l := len(index.Entries); l != 3 {
   478  		t.Fatalf("Expected 3 entries, got %d", l)
   479  	}
   480  
   481  	// Other things test the entry generation more thoroughly. We just test a
   482  	// few fields.
   483  
   484  	corpus := []struct{ chartName, downloadLink string }{
   485  		{"frobnitz", "http://localhost:8080/frobnitz-1.2.3.tgz"},
   486  		{"zarthal", "http://localhost:8080/universe/zarthal-1.0.0.tgz"},
   487  	}
   488  
   489  	for _, test := range corpus {
   490  		cname := test.chartName
   491  		frobs, ok := index.Entries[cname]
   492  		if !ok {
   493  			t.Fatalf("Could not read chart %s", cname)
   494  		}
   495  
   496  		frob := frobs[0]
   497  		if frob.Digest == "" {
   498  			t.Errorf("Missing digest of file %s.", frob.Name)
   499  		}
   500  		if frob.URLs[0] != test.downloadLink {
   501  			t.Errorf("Unexpected URLs: %v", frob.URLs)
   502  		}
   503  		if frob.Name != cname {
   504  			t.Errorf("Expected %q, got %q", cname, frob.Name)
   505  		}
   506  	}
   507  }
   508  
   509  func TestIndexAdd(t *testing.T) {
   510  	i := NewIndexFile()
   511  
   512  	for _, x := range []struct {
   513  		md       *chart.Metadata
   514  		filename string
   515  		baseURL  string
   516  		digest   string
   517  	}{
   518  
   519  		{&chart.Metadata{APIVersion: "v2", Name: "clipper", Version: "0.1.0"}, "clipper-0.1.0.tgz", "http://example.com/charts", "sha256:1234567890"},
   520  		{&chart.Metadata{APIVersion: "v2", Name: "alpine", Version: "0.1.0"}, "/home/charts/alpine-0.1.0.tgz", "http://example.com/charts", "sha256:1234567890"},
   521  		{&chart.Metadata{APIVersion: "v2", Name: "deis", Version: "0.1.0"}, "/home/charts/deis-0.1.0.tgz", "http://example.com/charts/", "sha256:1234567890"},
   522  	} {
   523  		if err := i.MustAdd(x.md, x.filename, x.baseURL, x.digest); err != nil {
   524  			t.Errorf("unexpected error adding to index: %s", err)
   525  		}
   526  	}
   527  
   528  	if i.Entries["clipper"][0].URLs[0] != "http://example.com/charts/clipper-0.1.0.tgz" {
   529  		t.Errorf("Expected http://example.com/charts/clipper-0.1.0.tgz, got %s", i.Entries["clipper"][0].URLs[0])
   530  	}
   531  	if i.Entries["alpine"][0].URLs[0] != "http://example.com/charts/alpine-0.1.0.tgz" {
   532  		t.Errorf("Expected http://example.com/charts/alpine-0.1.0.tgz, got %s", i.Entries["alpine"][0].URLs[0])
   533  	}
   534  	if i.Entries["deis"][0].URLs[0] != "http://example.com/charts/deis-0.1.0.tgz" {
   535  		t.Errorf("Expected http://example.com/charts/deis-0.1.0.tgz, got %s", i.Entries["deis"][0].URLs[0])
   536  	}
   537  
   538  	// test error condition
   539  	if err := i.MustAdd(&chart.Metadata{}, "error-0.1.0.tgz", "", ""); err == nil {
   540  		t.Fatal("expected error adding to index")
   541  	}
   542  }
   543  
   544  func TestIndexWrite(t *testing.T) {
   545  	i := NewIndexFile()
   546  	if err := i.MustAdd(&chart.Metadata{APIVersion: "v2", Name: "clipper", Version: "0.1.0"}, "clipper-0.1.0.tgz", "http://example.com/charts", "sha256:1234567890"); err != nil {
   547  		t.Fatalf("unexpected error: %s", err)
   548  	}
   549  	dir := t.TempDir()
   550  	testpath := filepath.Join(dir, "test")
   551  	i.WriteFile(testpath, 0600)
   552  
   553  	got, err := os.ReadFile(testpath)
   554  	if err != nil {
   555  		t.Fatal(err)
   556  	}
   557  	if !strings.Contains(string(got), "clipper-0.1.0.tgz") {
   558  		t.Fatal("Index files doesn't contain expected content")
   559  	}
   560  }
   561  
   562  func TestIndexJSONWrite(t *testing.T) {
   563  	i := NewIndexFile()
   564  	if err := i.MustAdd(&chart.Metadata{APIVersion: "v2", Name: "clipper", Version: "0.1.0"}, "clipper-0.1.0.tgz", "http://example.com/charts", "sha256:1234567890"); err != nil {
   565  		t.Fatalf("unexpected error: %s", err)
   566  	}
   567  	dir := t.TempDir()
   568  	testpath := filepath.Join(dir, "test")
   569  	i.WriteJSONFile(testpath, 0600)
   570  
   571  	got, err := os.ReadFile(testpath)
   572  	if err != nil {
   573  		t.Fatal(err)
   574  	}
   575  	if !json.Valid(got) {
   576  		t.Fatal("Index files doesn't contain valid JSON")
   577  	}
   578  	if !strings.Contains(string(got), "clipper-0.1.0.tgz") {
   579  		t.Fatal("Index files doesn't contain expected content")
   580  	}
   581  }
   582  
   583  func TestAddFileIndexEntriesNil(t *testing.T) {
   584  	i := NewIndexFile()
   585  	i.APIVersion = chart.APIVersionV1
   586  	i.Entries = nil
   587  	for _, x := range []struct {
   588  		md       *chart.Metadata
   589  		filename string
   590  		baseURL  string
   591  		digest   string
   592  	}{
   593  		{&chart.Metadata{APIVersion: "v2", Name: " ", Version: "8033-5.apinie+s.r"}, "setter-0.1.9+beta.tgz", "http://example.com/charts", "sha256:1234567890abc"},
   594  	} {
   595  		if err := i.MustAdd(x.md, x.filename, x.baseURL, x.digest); err == nil {
   596  			t.Errorf("expected err to be non-nil when entries not initialized")
   597  		}
   598  	}
   599  }
   600  
   601  func TestIgnoreSkippableChartValidationError(t *testing.T) {
   602  	type TestCase struct {
   603  		Input        error
   604  		ErrorSkipped bool
   605  	}
   606  	testCases := map[string]TestCase{
   607  		"nil": {
   608  			Input: nil,
   609  		},
   610  		"generic_error": {
   611  			Input: fmt.Errorf("foo"),
   612  		},
   613  		"non_skipped_validation_error": {
   614  			Input: chart.ValidationError("chart.metadata.type must be application or library"),
   615  		},
   616  		"skipped_validation_error": {
   617  			Input:        chart.ValidationErrorf("more than one dependency with name or alias %q", "foo"),
   618  			ErrorSkipped: true,
   619  		},
   620  	}
   621  
   622  	for name, tc := range testCases {
   623  		t.Run(name, func(t *testing.T) {
   624  			result := ignoreSkippableChartValidationError(tc.Input)
   625  
   626  			if tc.Input == nil {
   627  				if result != nil {
   628  					t.Error("expected nil result for nil input")
   629  				}
   630  				return
   631  			}
   632  
   633  			if tc.ErrorSkipped {
   634  				if result != nil {
   635  					t.Error("expected nil result for skipped error")
   636  				}
   637  				return
   638  			}
   639  
   640  			if tc.Input != result {
   641  				t.Error("expected the result equal to input")
   642  			}
   643  
   644  		})
   645  	}
   646  }
   647  

View as plain text