github.com/appscode/helm@v3.0.0-alpha.1+incompatible/cmd/helm/dependency_update_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 main
    17  
    18  import (
    19  	"fmt"
    20  	"io/ioutil"
    21  	"os"
    22  	"path/filepath"
    23  	"strings"
    24  	"testing"
    25  
    26  	"helm.sh/helm/pkg/chart"
    27  	"helm.sh/helm/pkg/chartutil"
    28  	"helm.sh/helm/pkg/provenance"
    29  	"helm.sh/helm/pkg/repo"
    30  	"helm.sh/helm/pkg/repo/repotest"
    31  )
    32  
    33  func TestDependencyUpdateCmd(t *testing.T) {
    34  	defer resetEnv()()
    35  
    36  	hh := testHelmHome(t)
    37  	settings.Home = hh
    38  
    39  	srv := repotest.NewServer(hh.String())
    40  	defer srv.Stop()
    41  	copied, err := srv.CopyCharts("testdata/testcharts/*.tgz")
    42  	if err != nil {
    43  		t.Fatal(err)
    44  	}
    45  	t.Logf("Copied charts:\n%s", strings.Join(copied, "\n"))
    46  	t.Logf("Listening on directory %s", srv.Root())
    47  
    48  	chartname := "depup"
    49  	ch := createTestingMetadata(chartname, srv.URL())
    50  	md := ch.Metadata
    51  	if err := chartutil.SaveDir(ch, hh.String()); err != nil {
    52  		t.Fatal(err)
    53  	}
    54  
    55  	_, out, err := executeActionCommand(fmt.Sprintf("--home='%s' dependency update '%s'", hh.String(), hh.Path(chartname)))
    56  	if err != nil {
    57  		t.Logf("Output: %s", out)
    58  		t.Fatal(err)
    59  	}
    60  
    61  	// This is written directly to stdout, so we have to capture as is.
    62  	if !strings.Contains(out, `update from the "test" chart repository`) {
    63  		t.Errorf("Repo did not get updated\n%s", out)
    64  	}
    65  
    66  	// Make sure the actual file got downloaded.
    67  	expect := hh.Path(chartname, "charts/reqtest-0.1.0.tgz")
    68  	if _, err := os.Stat(expect); err != nil {
    69  		t.Fatal(err)
    70  	}
    71  
    72  	hash, err := provenance.DigestFile(expect)
    73  	if err != nil {
    74  		t.Fatal(err)
    75  	}
    76  
    77  	i, err := repo.LoadIndexFile(hh.CacheIndex("test"))
    78  	if err != nil {
    79  		t.Fatal(err)
    80  	}
    81  
    82  	reqver := i.Entries["reqtest"][0]
    83  	if h := reqver.Digest; h != hash {
    84  		t.Errorf("Failed hash match: expected %s, got %s", hash, h)
    85  	}
    86  
    87  	// Now change the dependencies and update. This verifies that on update,
    88  	// old dependencies are cleansed and new dependencies are added.
    89  	md.Dependencies = []*chart.Dependency{
    90  		{Name: "reqtest", Version: "0.1.0", Repository: srv.URL()},
    91  		{Name: "compressedchart", Version: "0.3.0", Repository: srv.URL()},
    92  	}
    93  	dir := hh.Path(chartname, "Chart.yaml")
    94  	if err := chartutil.SaveChartfile(dir, md); err != nil {
    95  		t.Fatal(err)
    96  	}
    97  
    98  	_, out, err = executeActionCommand(fmt.Sprintf("--home='%s' dependency update '%s'", hh, hh.Path(chartname)))
    99  	if err != nil {
   100  		t.Logf("Output: %s", out)
   101  		t.Fatal(err)
   102  	}
   103  
   104  	// In this second run, we should see compressedchart-0.3.0.tgz, and not
   105  	// the 0.1.0 version.
   106  	expect = hh.Path(chartname, "charts/compressedchart-0.3.0.tgz")
   107  	if _, err := os.Stat(expect); err != nil {
   108  		t.Fatalf("Expected %q: %s", expect, err)
   109  	}
   110  	dontExpect := hh.Path(chartname, "charts/compressedchart-0.1.0.tgz")
   111  	if _, err := os.Stat(dontExpect); err == nil {
   112  		t.Fatalf("Unexpected %q", dontExpect)
   113  	}
   114  }
   115  
   116  func TestDependencyUpdateCmd_SkipRefresh(t *testing.T) {
   117  	defer resetEnv()()
   118  
   119  	hh := testHelmHome(t)
   120  	settings.Home = hh
   121  
   122  	srv := repotest.NewServer(hh.String())
   123  	defer srv.Stop()
   124  	copied, err := srv.CopyCharts("testdata/testcharts/*.tgz")
   125  	if err != nil {
   126  		t.Fatal(err)
   127  	}
   128  	t.Logf("Copied charts:\n%s", strings.Join(copied, "\n"))
   129  	t.Logf("Listening on directory %s", srv.Root())
   130  
   131  	chartname := "depup"
   132  	if err := createTestingChart(hh.String(), chartname, srv.URL()); err != nil {
   133  		t.Fatal(err)
   134  	}
   135  
   136  	_, out, err := executeActionCommand(fmt.Sprintf("--home='%s' dependency update --skip-refresh %s", hh, hh.Path(chartname)))
   137  	if err == nil {
   138  		t.Fatal("Expected failure to find the repo with skipRefresh")
   139  	}
   140  
   141  	// This is written directly to stdout, so we have to capture as is.
   142  	if strings.Contains(out, `update from the "test" chart repository`) {
   143  		t.Errorf("Repo was unexpectedly updated\n%s", out)
   144  	}
   145  }
   146  
   147  func TestDependencyUpdateCmd_DontDeleteOldChartsOnError(t *testing.T) {
   148  	defer resetEnv()()
   149  
   150  	hh := testHelmHome(t)
   151  	settings.Home = hh
   152  
   153  	srv := repotest.NewServer(hh.String())
   154  	defer srv.Stop()
   155  	copied, err := srv.CopyCharts("testdata/testcharts/*.tgz")
   156  	if err != nil {
   157  		t.Fatal(err)
   158  	}
   159  	t.Logf("Copied charts:\n%s", strings.Join(copied, "\n"))
   160  	t.Logf("Listening on directory %s", srv.Root())
   161  
   162  	chartname := "depupdelete"
   163  	if err := createTestingChart(hh.String(), chartname, srv.URL()); err != nil {
   164  		t.Fatal(err)
   165  	}
   166  
   167  	_, output, err := executeActionCommand(fmt.Sprintf("--home='%s' dependency update %s", hh, hh.Path(chartname)))
   168  	if err != nil {
   169  		t.Logf("Output: %s", output)
   170  		t.Fatal(err)
   171  	}
   172  
   173  	// Chart repo is down
   174  	srv.Stop()
   175  
   176  	_, output, err = executeActionCommand(fmt.Sprintf("--home='%s' dependency update %s", hh, hh.Path(chartname)))
   177  	if err == nil {
   178  		t.Logf("Output: %s", output)
   179  		t.Fatal("Expected error, got nil")
   180  	}
   181  
   182  	// Make sure charts dir still has dependencies
   183  	files, err := ioutil.ReadDir(filepath.Join(hh.Path(chartname), "charts"))
   184  	if err != nil {
   185  		t.Fatal(err)
   186  	}
   187  	dependencies := []string{"compressedchart-0.1.0.tgz", "reqtest-0.1.0.tgz"}
   188  
   189  	if len(dependencies) != len(files) {
   190  		t.Fatalf("Expected %d chart dependencies, got %d", len(dependencies), len(files))
   191  	}
   192  	for index, file := range files {
   193  		if dependencies[index] != file.Name() {
   194  			t.Fatalf("Chart dependency %s not matching %s", dependencies[index], file.Name())
   195  		}
   196  	}
   197  
   198  	// Make sure tmpcharts is deleted
   199  	if _, err := os.Stat(filepath.Join(hh.Path(chartname), "tmpcharts")); !os.IsNotExist(err) {
   200  		t.Fatalf("tmpcharts dir still exists")
   201  	}
   202  }
   203  
   204  // createTestingMetadata creates a basic chart that depends on reqtest-0.1.0
   205  //
   206  // The baseURL can be used to point to a particular repository server.
   207  func createTestingMetadata(name, baseURL string) *chart.Chart {
   208  	return &chart.Chart{
   209  		Metadata: &chart.Metadata{
   210  			APIVersion: chart.APIVersionV1,
   211  			Name:       name,
   212  			Version:    "1.2.3",
   213  			Dependencies: []*chart.Dependency{
   214  				{Name: "reqtest", Version: "0.1.0", Repository: baseURL},
   215  				{Name: "compressedchart", Version: "0.1.0", Repository: baseURL},
   216  			},
   217  		},
   218  	}
   219  }
   220  
   221  // createTestingChart creates a basic chart that depends on reqtest-0.1.0
   222  //
   223  // The baseURL can be used to point to a particular repository server.
   224  func createTestingChart(dest, name, baseURL string) error {
   225  	cfile := createTestingMetadata(name, baseURL)
   226  	return chartutil.SaveDir(cfile, dest)
   227  }