github.com/stefanmcshane/helm@v0.0.0-20221213002717-88a4a2c6e77d/pkg/chart/loader/load_test.go (about)

     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 loader
    18  
    19  import (
    20  	"archive/tar"
    21  	"bytes"
    22  	"compress/gzip"
    23  	"io"
    24  	"io/ioutil"
    25  	"log"
    26  	"os"
    27  	"path/filepath"
    28  	"runtime"
    29  	"strings"
    30  	"testing"
    31  	"time"
    32  
    33  	"github.com/stefanmcshane/helm/pkg/chart"
    34  )
    35  
    36  func TestLoadDir(t *testing.T) {
    37  	l, err := Loader("testdata/frobnitz")
    38  	if err != nil {
    39  		t.Fatalf("Failed to load testdata: %s", err)
    40  	}
    41  	c, err := l.Load()
    42  	if err != nil {
    43  		t.Fatalf("Failed to load testdata: %s", err)
    44  	}
    45  	verifyFrobnitz(t, c)
    46  	verifyChart(t, c)
    47  	verifyDependencies(t, c)
    48  	verifyDependenciesLock(t, c)
    49  }
    50  
    51  func TestLoadDirWithDevNull(t *testing.T) {
    52  	if runtime.GOOS == "windows" {
    53  		t.Skip("test only works on unix systems with /dev/null present")
    54  	}
    55  
    56  	l, err := Loader("testdata/frobnitz_with_dev_null")
    57  	if err != nil {
    58  		t.Fatalf("Failed to load testdata: %s", err)
    59  	}
    60  	if _, err := l.Load(); err == nil {
    61  		t.Errorf("packages with an irregular file (/dev/null) should not load")
    62  	}
    63  }
    64  
    65  func TestLoadDirWithSymlink(t *testing.T) {
    66  	sym := filepath.Join("..", "LICENSE")
    67  	link := filepath.Join("testdata", "frobnitz_with_symlink", "LICENSE")
    68  
    69  	if err := os.Symlink(sym, link); err != nil {
    70  		t.Fatal(err)
    71  	}
    72  
    73  	defer os.Remove(link)
    74  
    75  	l, err := Loader("testdata/frobnitz_with_symlink")
    76  	if err != nil {
    77  		t.Fatalf("Failed to load testdata: %s", err)
    78  	}
    79  
    80  	c, err := l.Load()
    81  	if err != nil {
    82  		t.Fatalf("Failed to load testdata: %s", err)
    83  	}
    84  	verifyFrobnitz(t, c)
    85  	verifyChart(t, c)
    86  	verifyDependencies(t, c)
    87  	verifyDependenciesLock(t, c)
    88  }
    89  
    90  func TestBomTestData(t *testing.T) {
    91  	testFiles := []string{"frobnitz_with_bom/.helmignore", "frobnitz_with_bom/templates/template.tpl", "frobnitz_with_bom/Chart.yaml"}
    92  	for _, file := range testFiles {
    93  		data, err := ioutil.ReadFile("testdata/" + file)
    94  		if err != nil || !bytes.HasPrefix(data, utf8bom) {
    95  			t.Errorf("Test file has no BOM or is invalid: testdata/%s", file)
    96  		}
    97  	}
    98  
    99  	archive, err := ioutil.ReadFile("testdata/frobnitz_with_bom.tgz")
   100  	if err != nil {
   101  		t.Fatalf("Error reading archive frobnitz_with_bom.tgz: %s", err)
   102  	}
   103  	unzipped, err := gzip.NewReader(bytes.NewReader(archive))
   104  	if err != nil {
   105  		t.Fatalf("Error reading archive frobnitz_with_bom.tgz: %s", err)
   106  	}
   107  	defer unzipped.Close()
   108  	for _, testFile := range testFiles {
   109  		data := make([]byte, 3)
   110  		err := unzipped.Reset(bytes.NewReader(archive))
   111  		if err != nil {
   112  			t.Fatalf("Error reading archive frobnitz_with_bom.tgz: %s", err)
   113  		}
   114  		tr := tar.NewReader(unzipped)
   115  		for {
   116  			file, err := tr.Next()
   117  			if err == io.EOF {
   118  				break
   119  			}
   120  			if err != nil {
   121  				t.Fatalf("Error reading archive frobnitz_with_bom.tgz: %s", err)
   122  			}
   123  			if file != nil && strings.EqualFold(file.Name, testFile) {
   124  				_, err := tr.Read(data)
   125  				if err != nil {
   126  					t.Fatalf("Error reading archive frobnitz_with_bom.tgz: %s", err)
   127  				} else {
   128  					break
   129  				}
   130  			}
   131  		}
   132  		if !bytes.Equal(data, utf8bom) {
   133  			t.Fatalf("Test file has no BOM or is invalid: frobnitz_with_bom.tgz/%s", testFile)
   134  		}
   135  	}
   136  }
   137  
   138  func TestLoadDirWithUTFBOM(t *testing.T) {
   139  	l, err := Loader("testdata/frobnitz_with_bom")
   140  	if err != nil {
   141  		t.Fatalf("Failed to load testdata: %s", err)
   142  	}
   143  	c, err := l.Load()
   144  	if err != nil {
   145  		t.Fatalf("Failed to load testdata: %s", err)
   146  	}
   147  	verifyFrobnitz(t, c)
   148  	verifyChart(t, c)
   149  	verifyDependencies(t, c)
   150  	verifyDependenciesLock(t, c)
   151  	verifyBomStripped(t, c.Files)
   152  }
   153  
   154  func TestLoadArchiveWithUTFBOM(t *testing.T) {
   155  	l, err := Loader("testdata/frobnitz_with_bom.tgz")
   156  	if err != nil {
   157  		t.Fatalf("Failed to load testdata: %s", err)
   158  	}
   159  	c, err := l.Load()
   160  	if err != nil {
   161  		t.Fatalf("Failed to load testdata: %s", err)
   162  	}
   163  	verifyFrobnitz(t, c)
   164  	verifyChart(t, c)
   165  	verifyDependencies(t, c)
   166  	verifyDependenciesLock(t, c)
   167  	verifyBomStripped(t, c.Files)
   168  }
   169  
   170  func TestLoadV1(t *testing.T) {
   171  	l, err := Loader("testdata/frobnitz.v1")
   172  	if err != nil {
   173  		t.Fatalf("Failed to load testdata: %s", err)
   174  	}
   175  	c, err := l.Load()
   176  	if err != nil {
   177  		t.Fatalf("Failed to load testdata: %s", err)
   178  	}
   179  	verifyDependencies(t, c)
   180  	verifyDependenciesLock(t, c)
   181  }
   182  
   183  func TestLoadFileV1(t *testing.T) {
   184  	l, err := Loader("testdata/frobnitz.v1.tgz")
   185  	if err != nil {
   186  		t.Fatalf("Failed to load testdata: %s", err)
   187  	}
   188  	c, err := l.Load()
   189  	if err != nil {
   190  		t.Fatalf("Failed to load testdata: %s", err)
   191  	}
   192  	verifyDependencies(t, c)
   193  	verifyDependenciesLock(t, c)
   194  }
   195  
   196  func TestLoadFile(t *testing.T) {
   197  	l, err := Loader("testdata/frobnitz-1.2.3.tgz")
   198  	if err != nil {
   199  		t.Fatalf("Failed to load testdata: %s", err)
   200  	}
   201  	c, err := l.Load()
   202  	if err != nil {
   203  		t.Fatalf("Failed to load testdata: %s", err)
   204  	}
   205  	verifyFrobnitz(t, c)
   206  	verifyChart(t, c)
   207  	verifyDependencies(t, c)
   208  }
   209  
   210  func TestLoadFiles_BadCases(t *testing.T) {
   211  	for _, tt := range []struct {
   212  		name          string
   213  		bufferedFiles []*BufferedFile
   214  		expectError   string
   215  	}{
   216  		{
   217  			name: "These files contain only requirements.lock",
   218  			bufferedFiles: []*BufferedFile{
   219  				{
   220  					Name: "requirements.lock",
   221  					Data: []byte(""),
   222  				},
   223  			},
   224  			expectError: "validation: chart.metadata.apiVersion is required"},
   225  	} {
   226  		_, err := LoadFiles(tt.bufferedFiles)
   227  		if err == nil {
   228  			t.Fatal("expected error when load illegal files")
   229  		}
   230  		if !strings.Contains(err.Error(), tt.expectError) {
   231  			t.Errorf("Expected error to contain %q, got %q for %s", tt.expectError, err.Error(), tt.name)
   232  		}
   233  	}
   234  }
   235  
   236  func TestLoadFiles(t *testing.T) {
   237  	goodFiles := []*BufferedFile{
   238  		{
   239  			Name: "Chart.yaml",
   240  			Data: []byte(`apiVersion: v1
   241  name: frobnitz
   242  description: This is a frobnitz.
   243  version: "1.2.3"
   244  keywords:
   245    - frobnitz
   246    - sprocket
   247    - dodad
   248  maintainers:
   249    - name: The Helm Team
   250      email: helm@example.com
   251    - name: Someone Else
   252      email: nobody@example.com
   253  sources:
   254    - https://example.com/foo/bar
   255  home: http://example.com
   256  icon: https://example.com/64x64.png
   257  `),
   258  		},
   259  		{
   260  			Name: "values.yaml",
   261  			Data: []byte("var: some values"),
   262  		},
   263  		{
   264  			Name: "values.schema.json",
   265  			Data: []byte("type: Values"),
   266  		},
   267  		{
   268  			Name: "templates/deployment.yaml",
   269  			Data: []byte("some deployment"),
   270  		},
   271  		{
   272  			Name: "templates/service.yaml",
   273  			Data: []byte("some service"),
   274  		},
   275  	}
   276  
   277  	c, err := LoadFiles(goodFiles)
   278  	if err != nil {
   279  		t.Errorf("Expected good files to be loaded, got %v", err)
   280  	}
   281  
   282  	if c.Name() != "frobnitz" {
   283  		t.Errorf("Expected chart name to be 'frobnitz', got %s", c.Name())
   284  	}
   285  
   286  	if c.Values["var"] != "some values" {
   287  		t.Error("Expected chart values to be populated with default values")
   288  	}
   289  
   290  	if len(c.Raw) != 5 {
   291  		t.Errorf("Expected %d files, got %d", 5, len(c.Raw))
   292  	}
   293  
   294  	if !bytes.Equal(c.Schema, []byte("type: Values")) {
   295  		t.Error("Expected chart schema to be populated with default values")
   296  	}
   297  
   298  	if len(c.Templates) != 2 {
   299  		t.Errorf("Expected number of templates == 2, got %d", len(c.Templates))
   300  	}
   301  
   302  	if _, err = LoadFiles([]*BufferedFile{}); err == nil {
   303  		t.Fatal("Expected err to be non-nil")
   304  	}
   305  	if err.Error() != "Chart.yaml file is missing" {
   306  		t.Errorf("Expected chart metadata missing error, got '%s'", err.Error())
   307  	}
   308  }
   309  
   310  // Test the order of file loading. The Chart.yaml file needs to come first for
   311  // later comparison checks. See https://github.com/helm/helm/pull/8948
   312  func TestLoadFilesOrder(t *testing.T) {
   313  	goodFiles := []*BufferedFile{
   314  		{
   315  			Name: "requirements.yaml",
   316  			Data: []byte("dependencies:"),
   317  		},
   318  		{
   319  			Name: "values.yaml",
   320  			Data: []byte("var: some values"),
   321  		},
   322  
   323  		{
   324  			Name: "templates/deployment.yaml",
   325  			Data: []byte("some deployment"),
   326  		},
   327  		{
   328  			Name: "templates/service.yaml",
   329  			Data: []byte("some service"),
   330  		},
   331  		{
   332  			Name: "Chart.yaml",
   333  			Data: []byte(`apiVersion: v1
   334  name: frobnitz
   335  description: This is a frobnitz.
   336  version: "1.2.3"
   337  keywords:
   338    - frobnitz
   339    - sprocket
   340    - dodad
   341  maintainers:
   342    - name: The Helm Team
   343      email: helm@example.com
   344    - name: Someone Else
   345      email: nobody@example.com
   346  sources:
   347    - https://example.com/foo/bar
   348  home: http://example.com
   349  icon: https://example.com/64x64.png
   350  `),
   351  		},
   352  	}
   353  
   354  	// Capture stderr to make sure message about Chart.yaml handle dependencies
   355  	// is not present
   356  	r, w, err := os.Pipe()
   357  	if err != nil {
   358  		t.Fatalf("Unable to create pipe: %s", err)
   359  	}
   360  	stderr := log.Writer()
   361  	log.SetOutput(w)
   362  	defer func() {
   363  		log.SetOutput(stderr)
   364  	}()
   365  
   366  	_, err = LoadFiles(goodFiles)
   367  	if err != nil {
   368  		t.Errorf("Expected good files to be loaded, got %v", err)
   369  	}
   370  	w.Close()
   371  
   372  	var text bytes.Buffer
   373  	io.Copy(&text, r)
   374  	if text.String() != "" {
   375  		t.Errorf("Expected no message to Stderr, got %s", text.String())
   376  	}
   377  
   378  }
   379  
   380  // Packaging the chart on a Windows machine will produce an
   381  // archive that has \\ as delimiters. Test that we support these archives
   382  func TestLoadFileBackslash(t *testing.T) {
   383  	c, err := Load("testdata/frobnitz_backslash-1.2.3.tgz")
   384  	if err != nil {
   385  		t.Fatalf("Failed to load testdata: %s", err)
   386  	}
   387  	verifyChartFileAndTemplate(t, c, "frobnitz_backslash")
   388  	verifyChart(t, c)
   389  	verifyDependencies(t, c)
   390  }
   391  
   392  func TestLoadV2WithReqs(t *testing.T) {
   393  	l, err := Loader("testdata/frobnitz.v2.reqs")
   394  	if err != nil {
   395  		t.Fatalf("Failed to load testdata: %s", err)
   396  	}
   397  	c, err := l.Load()
   398  	if err != nil {
   399  		t.Fatalf("Failed to load testdata: %s", err)
   400  	}
   401  	verifyDependencies(t, c)
   402  	verifyDependenciesLock(t, c)
   403  }
   404  
   405  func TestLoadInvalidArchive(t *testing.T) {
   406  	tmpdir := t.TempDir()
   407  
   408  	writeTar := func(filename, internalPath string, body []byte) {
   409  		dest, err := os.Create(filename)
   410  		if err != nil {
   411  			t.Fatal(err)
   412  		}
   413  		zipper := gzip.NewWriter(dest)
   414  		tw := tar.NewWriter(zipper)
   415  
   416  		h := &tar.Header{
   417  			Name:    internalPath,
   418  			Mode:    0755,
   419  			Size:    int64(len(body)),
   420  			ModTime: time.Now(),
   421  		}
   422  		if err := tw.WriteHeader(h); err != nil {
   423  			t.Fatal(err)
   424  		}
   425  		if _, err := tw.Write(body); err != nil {
   426  			t.Fatal(err)
   427  		}
   428  		tw.Close()
   429  		zipper.Close()
   430  		dest.Close()
   431  	}
   432  
   433  	for _, tt := range []struct {
   434  		chartname   string
   435  		internal    string
   436  		expectError string
   437  	}{
   438  		{"illegal-dots.tgz", "../../malformed-helm-test", "chart illegally references parent directory"},
   439  		{"illegal-dots2.tgz", "/foo/../../malformed-helm-test", "chart illegally references parent directory"},
   440  		{"illegal-dots3.tgz", "/../../malformed-helm-test", "chart illegally references parent directory"},
   441  		{"illegal-dots4.tgz", "./../../malformed-helm-test", "chart illegally references parent directory"},
   442  		{"illegal-name.tgz", "./.", "chart illegally contains content outside the base directory"},
   443  		{"illegal-name2.tgz", "/./.", "chart illegally contains content outside the base directory"},
   444  		{"illegal-name3.tgz", "missing-leading-slash", "chart illegally contains content outside the base directory"},
   445  		{"illegal-name4.tgz", "/missing-leading-slash", "Chart.yaml file is missing"},
   446  		{"illegal-abspath.tgz", "//foo", "chart illegally contains absolute paths"},
   447  		{"illegal-abspath2.tgz", "///foo", "chart illegally contains absolute paths"},
   448  		{"illegal-abspath3.tgz", "\\\\foo", "chart illegally contains absolute paths"},
   449  		{"illegal-abspath3.tgz", "\\..\\..\\foo", "chart illegally references parent directory"},
   450  
   451  		// Under special circumstances, this can get normalized to things that look like absolute Windows paths
   452  		{"illegal-abspath4.tgz", "\\.\\c:\\\\foo", "chart contains illegally named files"},
   453  		{"illegal-abspath5.tgz", "/./c://foo", "chart contains illegally named files"},
   454  		{"illegal-abspath6.tgz", "\\\\?\\Some\\windows\\magic", "chart illegally contains absolute paths"},
   455  	} {
   456  		illegalChart := filepath.Join(tmpdir, tt.chartname)
   457  		writeTar(illegalChart, tt.internal, []byte("hello: world"))
   458  		_, err := Load(illegalChart)
   459  		if err == nil {
   460  			t.Fatal("expected error when unpacking illegal files")
   461  		}
   462  		if !strings.Contains(err.Error(), tt.expectError) {
   463  			t.Errorf("Expected error to contain %q, got %q for %s", tt.expectError, err.Error(), tt.chartname)
   464  		}
   465  	}
   466  
   467  	// Make sure that absolute path gets interpreted as relative
   468  	illegalChart := filepath.Join(tmpdir, "abs-path.tgz")
   469  	writeTar(illegalChart, "/Chart.yaml", []byte("hello: world"))
   470  	_, err := Load(illegalChart)
   471  	if err.Error() != "validation: chart.metadata.name is required" {
   472  		t.Error(err)
   473  	}
   474  
   475  	// And just to validate that the above was not spurious
   476  	illegalChart = filepath.Join(tmpdir, "abs-path2.tgz")
   477  	writeTar(illegalChart, "files/whatever.yaml", []byte("hello: world"))
   478  	_, err = Load(illegalChart)
   479  	if err.Error() != "Chart.yaml file is missing" {
   480  		t.Errorf("Unexpected error message: %s", err)
   481  	}
   482  
   483  	// Finally, test that drive letter gets stripped off on Windows
   484  	illegalChart = filepath.Join(tmpdir, "abs-winpath.tgz")
   485  	writeTar(illegalChart, "c:\\Chart.yaml", []byte("hello: world"))
   486  	_, err = Load(illegalChart)
   487  	if err.Error() != "validation: chart.metadata.name is required" {
   488  		t.Error(err)
   489  	}
   490  }
   491  
   492  func verifyChart(t *testing.T, c *chart.Chart) {
   493  	t.Helper()
   494  	if c.Name() == "" {
   495  		t.Fatalf("No chart metadata found on %v", c)
   496  	}
   497  	t.Logf("Verifying chart %s", c.Name())
   498  	if len(c.Templates) != 1 {
   499  		t.Errorf("Expected 1 template, got %d", len(c.Templates))
   500  	}
   501  
   502  	numfiles := 6
   503  	if len(c.Files) != numfiles {
   504  		t.Errorf("Expected %d extra files, got %d", numfiles, len(c.Files))
   505  		for _, n := range c.Files {
   506  			t.Logf("\t%s", n.Name)
   507  		}
   508  	}
   509  
   510  	if len(c.Dependencies()) != 2 {
   511  		t.Errorf("Expected 2 dependencies, got %d (%v)", len(c.Dependencies()), c.Dependencies())
   512  		for _, d := range c.Dependencies() {
   513  			t.Logf("\tSubchart: %s\n", d.Name())
   514  		}
   515  	}
   516  
   517  	expect := map[string]map[string]string{
   518  		"alpine": {
   519  			"version": "0.1.0",
   520  		},
   521  		"mariner": {
   522  			"version": "4.3.2",
   523  		},
   524  	}
   525  
   526  	for _, dep := range c.Dependencies() {
   527  		if dep.Metadata == nil {
   528  			t.Fatalf("expected metadata on dependency: %v", dep)
   529  		}
   530  		exp, ok := expect[dep.Name()]
   531  		if !ok {
   532  			t.Fatalf("Unknown dependency %s", dep.Name())
   533  		}
   534  		if exp["version"] != dep.Metadata.Version {
   535  			t.Errorf("Expected %s version %s, got %s", dep.Name(), exp["version"], dep.Metadata.Version)
   536  		}
   537  	}
   538  
   539  }
   540  
   541  func verifyDependencies(t *testing.T, c *chart.Chart) {
   542  	if len(c.Metadata.Dependencies) != 2 {
   543  		t.Errorf("Expected 2 dependencies, got %d", len(c.Metadata.Dependencies))
   544  	}
   545  	tests := []*chart.Dependency{
   546  		{Name: "alpine", Version: "0.1.0", Repository: "https://example.com/charts"},
   547  		{Name: "mariner", Version: "4.3.2", Repository: "https://example.com/charts"},
   548  	}
   549  	for i, tt := range tests {
   550  		d := c.Metadata.Dependencies[i]
   551  		if d.Name != tt.Name {
   552  			t.Errorf("Expected dependency named %q, got %q", tt.Name, d.Name)
   553  		}
   554  		if d.Version != tt.Version {
   555  			t.Errorf("Expected dependency named %q to have version %q, got %q", tt.Name, tt.Version, d.Version)
   556  		}
   557  		if d.Repository != tt.Repository {
   558  			t.Errorf("Expected dependency named %q to have repository %q, got %q", tt.Name, tt.Repository, d.Repository)
   559  		}
   560  	}
   561  }
   562  
   563  func verifyDependenciesLock(t *testing.T, c *chart.Chart) {
   564  	if len(c.Metadata.Dependencies) != 2 {
   565  		t.Errorf("Expected 2 dependencies, got %d", len(c.Metadata.Dependencies))
   566  	}
   567  	tests := []*chart.Dependency{
   568  		{Name: "alpine", Version: "0.1.0", Repository: "https://example.com/charts"},
   569  		{Name: "mariner", Version: "4.3.2", Repository: "https://example.com/charts"},
   570  	}
   571  	for i, tt := range tests {
   572  		d := c.Metadata.Dependencies[i]
   573  		if d.Name != tt.Name {
   574  			t.Errorf("Expected dependency named %q, got %q", tt.Name, d.Name)
   575  		}
   576  		if d.Version != tt.Version {
   577  			t.Errorf("Expected dependency named %q to have version %q, got %q", tt.Name, tt.Version, d.Version)
   578  		}
   579  		if d.Repository != tt.Repository {
   580  			t.Errorf("Expected dependency named %q to have repository %q, got %q", tt.Name, tt.Repository, d.Repository)
   581  		}
   582  	}
   583  }
   584  
   585  func verifyFrobnitz(t *testing.T, c *chart.Chart) {
   586  	verifyChartFileAndTemplate(t, c, "frobnitz")
   587  }
   588  
   589  func verifyChartFileAndTemplate(t *testing.T, c *chart.Chart, name string) {
   590  	if c.Metadata == nil {
   591  		t.Fatal("Metadata is nil")
   592  	}
   593  	if c.Name() != name {
   594  		t.Errorf("Expected %s, got %s", name, c.Name())
   595  	}
   596  	if len(c.Templates) != 1 {
   597  		t.Fatalf("Expected 1 template, got %d", len(c.Templates))
   598  	}
   599  	if c.Templates[0].Name != "templates/template.tpl" {
   600  		t.Errorf("Unexpected template: %s", c.Templates[0].Name)
   601  	}
   602  	if len(c.Templates[0].Data) == 0 {
   603  		t.Error("No template data.")
   604  	}
   605  	if len(c.Files) != 6 {
   606  		t.Fatalf("Expected 6 Files, got %d", len(c.Files))
   607  	}
   608  	if len(c.Dependencies()) != 2 {
   609  		t.Fatalf("Expected 2 Dependency, got %d", len(c.Dependencies()))
   610  	}
   611  	if len(c.Metadata.Dependencies) != 2 {
   612  		t.Fatalf("Expected 2 Dependencies.Dependency, got %d", len(c.Metadata.Dependencies))
   613  	}
   614  	if len(c.Lock.Dependencies) != 2 {
   615  		t.Fatalf("Expected 2 Lock.Dependency, got %d", len(c.Lock.Dependencies))
   616  	}
   617  
   618  	for _, dep := range c.Dependencies() {
   619  		switch dep.Name() {
   620  		case "mariner":
   621  		case "alpine":
   622  			if len(dep.Templates) != 1 {
   623  				t.Fatalf("Expected 1 template, got %d", len(dep.Templates))
   624  			}
   625  			if dep.Templates[0].Name != "templates/alpine-pod.yaml" {
   626  				t.Errorf("Unexpected template: %s", dep.Templates[0].Name)
   627  			}
   628  			if len(dep.Templates[0].Data) == 0 {
   629  				t.Error("No template data.")
   630  			}
   631  			if len(dep.Files) != 1 {
   632  				t.Fatalf("Expected 1 Files, got %d", len(dep.Files))
   633  			}
   634  			if len(dep.Dependencies()) != 2 {
   635  				t.Fatalf("Expected 2 Dependency, got %d", len(dep.Dependencies()))
   636  			}
   637  		default:
   638  			t.Errorf("Unexpected dependency %s", dep.Name())
   639  		}
   640  	}
   641  }
   642  
   643  func verifyBomStripped(t *testing.T, files []*chart.File) {
   644  	for _, file := range files {
   645  		if bytes.HasPrefix(file.Data, utf8bom) {
   646  			t.Errorf("Byte Order Mark still present in processed file %s", file.Name)
   647  		}
   648  	}
   649  }