github.com/appscode/helm@v3.0.0-alpha.1+incompatible/cmd/helm/helm_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 main
    18  
    19  import (
    20  	"bytes"
    21  	"io/ioutil"
    22  	"os"
    23  	"strings"
    24  	"testing"
    25  	"time"
    26  
    27  	shellwords "github.com/mattn/go-shellwords"
    28  	"github.com/spf13/cobra"
    29  
    30  	"helm.sh/helm/internal/test"
    31  	"helm.sh/helm/pkg/action"
    32  	"helm.sh/helm/pkg/chartutil"
    33  	"helm.sh/helm/pkg/helmpath"
    34  	"helm.sh/helm/pkg/kube"
    35  	"helm.sh/helm/pkg/release"
    36  	"helm.sh/helm/pkg/repo"
    37  	"helm.sh/helm/pkg/storage"
    38  	"helm.sh/helm/pkg/storage/driver"
    39  )
    40  
    41  func testTimestamper() time.Time { return time.Unix(242085845, 0).UTC() }
    42  
    43  func init() {
    44  	action.Timestamper = testTimestamper
    45  }
    46  
    47  func TestMain(m *testing.M) {
    48  	os.Unsetenv("HELM_HOME")
    49  	exitCode := m.Run()
    50  	os.Exit(exitCode)
    51  }
    52  
    53  func testTempDir(t *testing.T) string {
    54  	t.Helper()
    55  	d, err := ioutil.TempDir("", "helm")
    56  	if err != nil {
    57  		t.Fatal(err)
    58  	}
    59  	return d
    60  }
    61  
    62  func runTestCmd(t *testing.T, tests []cmdTestCase) {
    63  	t.Helper()
    64  	for _, tt := range tests {
    65  		t.Run(tt.name, func(t *testing.T) {
    66  			defer resetEnv()()
    67  
    68  			storage := storageFixture()
    69  			for _, rel := range tt.rels {
    70  				if err := storage.Create(rel); err != nil {
    71  					t.Fatal(err)
    72  				}
    73  			}
    74  			_, out, err := executeActionCommandC(storage, tt.cmd)
    75  			if (err != nil) != tt.wantError {
    76  				t.Errorf("expected error, got '%v'", err)
    77  			}
    78  			if tt.golden != "" {
    79  				test.AssertGoldenString(t, out, tt.golden)
    80  			}
    81  		})
    82  	}
    83  }
    84  
    85  func runTestActionCmd(t *testing.T, tests []cmdTestCase) {
    86  	t.Helper()
    87  	for _, tt := range tests {
    88  		t.Run(tt.name, func(t *testing.T) {
    89  			defer resetEnv()()
    90  
    91  			store := storageFixture()
    92  			for _, rel := range tt.rels {
    93  				store.Create(rel)
    94  			}
    95  			_, out, err := executeActionCommandC(store, tt.cmd)
    96  			if (err != nil) != tt.wantError {
    97  				t.Errorf("expected error, got '%v'", err)
    98  			}
    99  			if tt.golden != "" {
   100  				test.AssertGoldenString(t, out, tt.golden)
   101  			}
   102  		})
   103  	}
   104  }
   105  
   106  func storageFixture() *storage.Storage {
   107  	return storage.Init(driver.NewMemory())
   108  }
   109  
   110  func executeActionCommandC(store *storage.Storage, cmd string) (*cobra.Command, string, error) {
   111  	args, err := shellwords.Parse(cmd)
   112  	if err != nil {
   113  		return nil, "", err
   114  	}
   115  	buf := new(bytes.Buffer)
   116  
   117  	actionConfig := &action.Configuration{
   118  		Releases:     store,
   119  		KubeClient:   &kube.PrintingKubeClient{Out: ioutil.Discard},
   120  		Capabilities: chartutil.DefaultCapabilities,
   121  		Log:          func(format string, v ...interface{}) {},
   122  	}
   123  
   124  	root := newRootCmd(actionConfig, buf, args)
   125  	root.SetOutput(buf)
   126  	root.SetArgs(args)
   127  
   128  	c, err := root.ExecuteC()
   129  
   130  	return c, buf.String(), err
   131  }
   132  
   133  // cmdTestCase describes a test case that works with releases.
   134  type cmdTestCase struct {
   135  	name      string
   136  	cmd       string
   137  	golden    string
   138  	wantError bool
   139  	// Rels are the available releases at the start of the test.
   140  	rels []*release.Release
   141  }
   142  
   143  func executeActionCommand(cmd string) (*cobra.Command, string, error) {
   144  	return executeActionCommandC(storageFixture(), cmd)
   145  }
   146  
   147  // ensureTestHome creates a home directory like ensureHome, but without remote references.
   148  func ensureTestHome(t *testing.T, home helmpath.Home) {
   149  	t.Helper()
   150  	for _, p := range []string{
   151  		home.String(),
   152  		home.Repository(),
   153  		home.Cache(),
   154  		home.Plugins(),
   155  		home.Starters(),
   156  	} {
   157  		if err := os.MkdirAll(p, 0755); err != nil {
   158  			t.Fatal(err)
   159  		}
   160  	}
   161  
   162  	repoFile := home.RepositoryFile()
   163  	if _, err := os.Stat(repoFile); err != nil {
   164  		rf := repo.NewFile()
   165  		rf.Add(&repo.Entry{
   166  			Name:  "charts",
   167  			URL:   "http://example.com/foo",
   168  			Cache: "charts-index.yaml",
   169  		})
   170  		if err := rf.WriteFile(repoFile, 0644); err != nil {
   171  			t.Fatal(err)
   172  		}
   173  	}
   174  	if r, err := repo.LoadFile(repoFile); err == repo.ErrRepoOutOfDate {
   175  		if err := r.WriteFile(repoFile, 0644); err != nil {
   176  			t.Fatal(err)
   177  		}
   178  	}
   179  }
   180  
   181  // testHelmHome sets up a Helm Home in a temp dir.
   182  func testHelmHome(t *testing.T) helmpath.Home {
   183  	t.Helper()
   184  	dir := helmpath.Home(testTempDir(t))
   185  	ensureTestHome(t, dir)
   186  	return dir
   187  }
   188  
   189  func resetEnv() func() {
   190  	origSettings, origEnv := settings, os.Environ()
   191  	return func() {
   192  		os.Clearenv()
   193  		settings = origSettings
   194  		for _, pair := range origEnv {
   195  			kv := strings.SplitN(pair, "=", 2)
   196  			os.Setenv(kv[0], kv[1])
   197  		}
   198  	}
   199  }
   200  
   201  func testChdir(t *testing.T, dir string) func() {
   202  	t.Helper()
   203  	old, err := os.Getwd()
   204  	if err != nil {
   205  		t.Fatal(err)
   206  	}
   207  	if err := os.Chdir(dir); err != nil {
   208  		t.Fatal(err)
   209  	}
   210  	return func() { os.Chdir(old) }
   211  }