github.com/codefresh-io/kcfi@v0.0.0-20230301195427-c1578715cc46/pkg/helm-internal/resolver/resolver_test.go (about)

     1  /*
     2  Copyright The Helm Authors.
     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 resolver
    17  
    18  import (
    19  	"testing"
    20  
    21  	"helm.sh/helm/v3/pkg/chart"
    22  )
    23  
    24  func TestResolve(t *testing.T) {
    25  	tests := []struct {
    26  		name   string
    27  		req    []*chart.Dependency
    28  		expect *chart.Lock
    29  		err    bool
    30  	}{
    31  		{
    32  			name: "version failure",
    33  			req: []*chart.Dependency{
    34  				{Name: "oedipus-rex", Repository: "http://example.com", Version: ">a1"},
    35  			},
    36  			err: true,
    37  		},
    38  		{
    39  			name: "cache index failure",
    40  			req: []*chart.Dependency{
    41  				{Name: "oedipus-rex", Repository: "http://example.com", Version: "1.0.0"},
    42  			},
    43  			expect: &chart.Lock{
    44  				Dependencies: []*chart.Dependency{
    45  					{Name: "oedipus-rex", Repository: "http://example.com", Version: "1.0.0"},
    46  				},
    47  			},
    48  		},
    49  		{
    50  			name: "chart not found failure",
    51  			req: []*chart.Dependency{
    52  				{Name: "redis", Repository: "http://example.com", Version: "1.0.0"},
    53  			},
    54  			err: true,
    55  		},
    56  		{
    57  			name: "constraint not satisfied failure",
    58  			req: []*chart.Dependency{
    59  				{Name: "alpine", Repository: "http://example.com", Version: ">=1.0.0"},
    60  			},
    61  			err: true,
    62  		},
    63  		{
    64  			name: "valid lock",
    65  			req: []*chart.Dependency{
    66  				{Name: "alpine", Repository: "http://example.com", Version: ">=0.1.0"},
    67  			},
    68  			expect: &chart.Lock{
    69  				Dependencies: []*chart.Dependency{
    70  					{Name: "alpine", Repository: "http://example.com", Version: "0.2.0"},
    71  				},
    72  			},
    73  		},
    74  		{
    75  			name: "repo from valid local path",
    76  			req: []*chart.Dependency{
    77  				{Name: "signtest", Repository: "file://../../../../cmd/helm/testdata/testcharts/signtest", Version: "0.1.0"},
    78  			},
    79  			expect: &chart.Lock{
    80  				Dependencies: []*chart.Dependency{
    81  					{Name: "signtest", Repository: "file://../../../../cmd/helm/testdata/testcharts/signtest", Version: "0.1.0"},
    82  				},
    83  			},
    84  		},
    85  		{
    86  			name: "repo from invalid local path",
    87  			req: []*chart.Dependency{
    88  				{Name: "notexist", Repository: "file://../testdata/notexist", Version: "0.1.0"},
    89  			},
    90  			err: true,
    91  		},
    92  		{
    93  			name: "repo from valid path under charts path",
    94  			req: []*chart.Dependency{
    95  				{Name: "localdependency", Repository: "", Version: "0.1.0"},
    96  			},
    97  			expect: &chart.Lock{
    98  				Dependencies: []*chart.Dependency{
    99  					{Name: "localdependency", Repository: "", Version: "0.1.0"},
   100  				},
   101  			},
   102  		},
   103  		{
   104  			name: "repo from invalid path under charts path",
   105  			req: []*chart.Dependency{
   106  				{Name: "nonexistentdependency", Repository: "", Version: "0.1.0"},
   107  			},
   108  			expect: &chart.Lock{
   109  				Dependencies: []*chart.Dependency{
   110  					{Name: "nonexistentlocaldependency", Repository: "", Version: "0.1.0"},
   111  				},
   112  			},
   113  			err: true,
   114  		},
   115  	}
   116  
   117  	repoNames := map[string]string{"alpine": "kubernetes-charts", "redis": "kubernetes-charts"}
   118  	r := New("testdata/chartpath", "testdata/repository")
   119  	for _, tt := range tests {
   120  		t.Run(tt.name, func(t *testing.T) {
   121  			l, err := r.Resolve(tt.req, repoNames)
   122  			if err != nil {
   123  				if tt.err {
   124  					return
   125  				}
   126  				t.Fatal(err)
   127  			}
   128  
   129  			if tt.err {
   130  				t.Fatalf("Expected error in test %q", tt.name)
   131  			}
   132  
   133  			if h, err := HashReq(tt.req, tt.expect.Dependencies); err != nil {
   134  				t.Fatal(err)
   135  			} else if h != l.Digest {
   136  				t.Errorf("%q: hashes don't match.", tt.name)
   137  			}
   138  
   139  			// Check fields.
   140  			if len(l.Dependencies) != len(tt.req) {
   141  				t.Errorf("%s: wrong number of dependencies in lock", tt.name)
   142  			}
   143  			d0 := l.Dependencies[0]
   144  			e0 := tt.expect.Dependencies[0]
   145  			if d0.Name != e0.Name {
   146  				t.Errorf("%s: expected name %s, got %s", tt.name, e0.Name, d0.Name)
   147  			}
   148  			if d0.Repository != e0.Repository {
   149  				t.Errorf("%s: expected repo %s, got %s", tt.name, e0.Repository, d0.Repository)
   150  			}
   151  			if d0.Version != e0.Version {
   152  				t.Errorf("%s: expected version %s, got %s", tt.name, e0.Version, d0.Version)
   153  			}
   154  		})
   155  	}
   156  }
   157  
   158  func TestHashReq(t *testing.T) {
   159  	expect := "sha256:fb239e836325c5fa14b29d1540a13b7d3ba13151b67fe719f820e0ef6d66aaaf"
   160  
   161  	tests := []struct {
   162  		name         string
   163  		chartVersion string
   164  		lockVersion  string
   165  		wantError    bool
   166  	}{
   167  		{
   168  			name:         "chart with the expected digest",
   169  			chartVersion: "0.1.0",
   170  			lockVersion:  "0.1.0",
   171  			wantError:    false,
   172  		},
   173  		{
   174  			name:         "ranged version but same resolved lock version",
   175  			chartVersion: "^0.1.0",
   176  			lockVersion:  "0.1.0",
   177  			wantError:    true,
   178  		},
   179  		{
   180  			name:         "ranged version resolved as higher version",
   181  			chartVersion: "^0.1.0",
   182  			lockVersion:  "0.1.2",
   183  			wantError:    true,
   184  		},
   185  		{
   186  			name:         "different version",
   187  			chartVersion: "0.1.2",
   188  			lockVersion:  "0.1.2",
   189  			wantError:    true,
   190  		},
   191  		{
   192  			name:         "different version with a range",
   193  			chartVersion: "^0.1.2",
   194  			lockVersion:  "0.1.2",
   195  			wantError:    true,
   196  		},
   197  	}
   198  
   199  	for _, tt := range tests {
   200  		t.Run(tt.name, func(t *testing.T) {
   201  			req := []*chart.Dependency{
   202  				{Name: "alpine", Version: tt.chartVersion, Repository: "http://localhost:8879/charts"},
   203  			}
   204  			lock := []*chart.Dependency{
   205  				{Name: "alpine", Version: tt.lockVersion, Repository: "http://localhost:8879/charts"},
   206  			}
   207  			h, err := HashReq(req, lock)
   208  			if err != nil {
   209  				t.Fatal(err)
   210  			}
   211  			if !tt.wantError && expect != h {
   212  				t.Errorf("Expected %q, got %q", expect, h)
   213  			} else if tt.wantError && expect == h {
   214  				t.Errorf("Expected not %q, but same", expect)
   215  			}
   216  		})
   217  	}
   218  }
   219  
   220  func TestGetLocalPath(t *testing.T) {
   221  	tests := []struct {
   222  		name      string
   223  		repo      string
   224  		chartpath string
   225  		expect    string
   226  		err       bool
   227  	}{
   228  		{
   229  			name:   "absolute path",
   230  			repo:   "file:////tmp",
   231  			expect: "/tmp",
   232  		},
   233  		{
   234  			name:      "relative path",
   235  			repo:      "file://../../../../cmd/helm/testdata/testcharts/signtest",
   236  			chartpath: "foo/bar",
   237  			expect:    "../../cmd/helm/testdata/testcharts/signtest",
   238  		},
   239  		{
   240  			name:      "current directory path",
   241  			repo:      "../charts/localdependency",
   242  			chartpath: "testdata/chartpath/charts",
   243  			expect:    "testdata/chartpath/charts/localdependency",
   244  		},
   245  		{
   246  			name:      "invalid local path",
   247  			repo:      "file://../testdata/notexist",
   248  			chartpath: "testdata/chartpath",
   249  			err:       true,
   250  		},
   251  		{
   252  			name:      "invalid path under current directory",
   253  			repo:      "../charts/nonexistentdependency",
   254  			chartpath: "testdata/chartpath/charts",
   255  			err:       true,
   256  		},
   257  	}
   258  
   259  	for _, tt := range tests {
   260  		t.Run(tt.name, func(t *testing.T) {
   261  			p, err := GetLocalPath(tt.repo, tt.chartpath)
   262  			if err != nil {
   263  				if tt.err {
   264  					return
   265  				}
   266  				t.Fatal(err)
   267  			}
   268  			if tt.err {
   269  				t.Fatalf("Expected error in test %q", tt.name)
   270  			}
   271  			if p != tt.expect {
   272  				t.Errorf("%q: expected %q, got %q", tt.name, tt.expect, p)
   273  			}
   274  		})
   275  	}
   276  }