github.com/werf/3p-helm@v2.8.1+incompatible/cmd/helm/helm_test.go (about)

     1  /*
     2  Copyright 2016 The Kubernetes Authors All rights reserved.
     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  	"fmt"
    22  	"io"
    23  	"io/ioutil"
    24  	"os"
    25  	"path/filepath"
    26  	"regexp"
    27  	"strings"
    28  	"testing"
    29  
    30  	"github.com/spf13/cobra"
    31  
    32  	"k8s.io/helm/pkg/helm"
    33  	"k8s.io/helm/pkg/helm/helmpath"
    34  	"k8s.io/helm/pkg/proto/hapi/release"
    35  	"k8s.io/helm/pkg/repo"
    36  )
    37  
    38  // releaseCmd is a command that works with a FakeClient
    39  type releaseCmd func(c *helm.FakeClient, out io.Writer) *cobra.Command
    40  
    41  // runReleaseCases runs a set of release cases through the given releaseCmd.
    42  func runReleaseCases(t *testing.T, tests []releaseCase, rcmd releaseCmd) {
    43  
    44  	var buf bytes.Buffer
    45  	for _, tt := range tests {
    46  		c := &helm.FakeClient{
    47  			Rels: tt.rels,
    48  		}
    49  		cmd := rcmd(c, &buf)
    50  		cmd.ParseFlags(tt.flags)
    51  		err := cmd.RunE(cmd, tt.args)
    52  		if (err != nil) != tt.err {
    53  			t.Errorf("%q. expected error, got '%v'", tt.name, err)
    54  		}
    55  		re := regexp.MustCompile(tt.expected)
    56  		if !re.Match(buf.Bytes()) {
    57  			t.Errorf("%q. expected\n%q\ngot\n%q", tt.name, tt.expected, buf.String())
    58  		}
    59  		buf.Reset()
    60  	}
    61  }
    62  
    63  // releaseCase describes a test case that works with releases.
    64  type releaseCase struct {
    65  	name  string
    66  	args  []string
    67  	flags []string
    68  	// expected is the string to be matched. This supports regular expressions.
    69  	expected string
    70  	err      bool
    71  	resp     *release.Release
    72  	// Rels are the available releases at the start of the test.
    73  	rels []*release.Release
    74  }
    75  
    76  // tempHelmHome sets up a Helm Home in a temp dir.
    77  //
    78  // This does not clean up the directory. You must do that yourself.
    79  // You  must also set helmHome yourself.
    80  func tempHelmHome(t *testing.T) (helmpath.Home, error) {
    81  	oldhome := settings.Home
    82  	dir, err := ioutil.TempDir("", "helm_home-")
    83  	if err != nil {
    84  		return helmpath.Home("n/"), err
    85  	}
    86  
    87  	settings.Home = helmpath.Home(dir)
    88  	if err := ensureTestHome(settings.Home, t); err != nil {
    89  		return helmpath.Home("n/"), err
    90  	}
    91  	settings.Home = oldhome
    92  	return helmpath.Home(dir), nil
    93  }
    94  
    95  // ensureTestHome creates a home directory like ensureHome, but without remote references.
    96  //
    97  // t is used only for logging.
    98  func ensureTestHome(home helmpath.Home, t *testing.T) error {
    99  	configDirectories := []string{home.String(), home.Repository(), home.Cache(), home.LocalRepository(), home.Plugins(), home.Starters()}
   100  	for _, p := range configDirectories {
   101  		if fi, err := os.Stat(p); err != nil {
   102  			if err := os.MkdirAll(p, 0755); err != nil {
   103  				return fmt.Errorf("Could not create %s: %s", p, err)
   104  			}
   105  		} else if !fi.IsDir() {
   106  			return fmt.Errorf("%s must be a directory", p)
   107  		}
   108  	}
   109  
   110  	repoFile := home.RepositoryFile()
   111  	if fi, err := os.Stat(repoFile); err != nil {
   112  		rf := repo.NewRepoFile()
   113  		rf.Add(&repo.Entry{
   114  			Name:  "charts",
   115  			URL:   "http://example.com/foo",
   116  			Cache: "charts-index.yaml",
   117  		}, &repo.Entry{
   118  			Name:  "local",
   119  			URL:   "http://localhost.com:7743/foo",
   120  			Cache: "local-index.yaml",
   121  		})
   122  		if err := rf.WriteFile(repoFile, 0644); err != nil {
   123  			return err
   124  		}
   125  	} else if fi.IsDir() {
   126  		return fmt.Errorf("%s must be a file, not a directory", repoFile)
   127  	}
   128  	if r, err := repo.LoadRepositoriesFile(repoFile); err == repo.ErrRepoOutOfDate {
   129  		t.Log("Updating repository file format...")
   130  		if err := r.WriteFile(repoFile, 0644); err != nil {
   131  			return err
   132  		}
   133  	}
   134  
   135  	localRepoIndexFile := home.LocalRepository(localRepositoryIndexFile)
   136  	if fi, err := os.Stat(localRepoIndexFile); err != nil {
   137  		i := repo.NewIndexFile()
   138  		if err := i.WriteFile(localRepoIndexFile, 0644); err != nil {
   139  			return err
   140  		}
   141  
   142  		//TODO: take this out and replace with helm update functionality
   143  		os.Symlink(localRepoIndexFile, home.CacheIndex("local"))
   144  	} else if fi.IsDir() {
   145  		return fmt.Errorf("%s must be a file, not a directory", localRepoIndexFile)
   146  	}
   147  
   148  	t.Logf("$HELM_HOME has been configured at %s.\n", settings.Home.String())
   149  	return nil
   150  
   151  }
   152  
   153  func TestRootCmd(t *testing.T) {
   154  	cleanup := resetEnv()
   155  	defer cleanup()
   156  
   157  	tests := []struct {
   158  		name   string
   159  		args   []string
   160  		envars map[string]string
   161  		home   string
   162  	}{
   163  		{
   164  			name: "defaults",
   165  			args: []string{"home"},
   166  			home: filepath.Join(os.Getenv("HOME"), "/.helm"),
   167  		},
   168  		{
   169  			name: "with --home set",
   170  			args: []string{"--home", "/foo"},
   171  			home: "/foo",
   172  		},
   173  		{
   174  			name: "subcommands with --home set",
   175  			args: []string{"home", "--home", "/foo"},
   176  			home: "/foo",
   177  		},
   178  		{
   179  			name:   "with $HELM_HOME set",
   180  			args:   []string{"home"},
   181  			envars: map[string]string{"HELM_HOME": "/bar"},
   182  			home:   "/bar",
   183  		},
   184  		{
   185  			name:   "subcommands with $HELM_HOME set",
   186  			args:   []string{"home"},
   187  			envars: map[string]string{"HELM_HOME": "/bar"},
   188  			home:   "/bar",
   189  		},
   190  		{
   191  			name:   "with $HELM_HOME and --home set",
   192  			args:   []string{"home", "--home", "/foo"},
   193  			envars: map[string]string{"HELM_HOME": "/bar"},
   194  			home:   "/foo",
   195  		},
   196  	}
   197  
   198  	// ensure not set locally
   199  	os.Unsetenv("HELM_HOME")
   200  
   201  	for _, tt := range tests {
   202  		t.Run(tt.name, func(t *testing.T) {
   203  			defer os.Unsetenv("HELM_HOME")
   204  
   205  			for k, v := range tt.envars {
   206  				os.Setenv(k, v)
   207  			}
   208  
   209  			cmd := newRootCmd(tt.args)
   210  			cmd.SetOutput(ioutil.Discard)
   211  			cmd.SetArgs(tt.args)
   212  			cmd.Run = func(*cobra.Command, []string) {}
   213  			if err := cmd.Execute(); err != nil {
   214  				t.Errorf("unexpected error: %s", err)
   215  			}
   216  
   217  			if settings.Home.String() != tt.home {
   218  				t.Errorf("expected home %q, got %q", tt.home, settings.Home)
   219  			}
   220  			homeFlag := cmd.Flag("home").Value.String()
   221  			homeFlag = os.ExpandEnv(homeFlag)
   222  			if homeFlag != tt.home {
   223  				t.Errorf("expected home %q, got %q", tt.home, homeFlag)
   224  			}
   225  		})
   226  	}
   227  }
   228  
   229  func resetEnv() func() {
   230  	origSettings := settings
   231  	origEnv := os.Environ()
   232  	return func() {
   233  		settings = origSettings
   234  		for _, pair := range origEnv {
   235  			kv := strings.SplitN(pair, "=", 2)
   236  			os.Setenv(kv[0], kv[1])
   237  		}
   238  	}
   239  }