github.com/koderover/helm@v2.17.0+incompatible/pkg/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 helm // import "k8s.io/helm/pkg/helm"
    18  
    19  import (
    20  	"errors"
    21  	"os/exec"
    22  	"path/filepath"
    23  	"reflect"
    24  	"strings"
    25  	"testing"
    26  
    27  	"github.com/golang/protobuf/proto"
    28  	"golang.org/x/net/context"
    29  
    30  	"k8s.io/helm/pkg/chartutil"
    31  	cpb "k8s.io/helm/pkg/proto/hapi/chart"
    32  	rls "k8s.io/helm/pkg/proto/hapi/release"
    33  	tpb "k8s.io/helm/pkg/proto/hapi/services"
    34  )
    35  
    36  // Path to example charts relative to pkg/helm.
    37  const chartsDir = "../../docs/examples/"
    38  
    39  // Sentinel error to indicate to the Helm client to not send the request to Tiller.
    40  var errSkip = errors.New("test: skip")
    41  
    42  // Verify each ReleaseListOption is applied to a ListReleasesRequest correctly.
    43  func TestListReleases_VerifyOptions(t *testing.T) {
    44  	// Options testdata
    45  	var limit = 2
    46  	var offset = "offset"
    47  	var filter = "filter"
    48  	var sortBy = int32(2)
    49  	var sortOrd = int32(1)
    50  	var codes = []rls.Status_Code{
    51  		rls.Status_FAILED,
    52  		rls.Status_DELETED,
    53  		rls.Status_DEPLOYED,
    54  		rls.Status_SUPERSEDED,
    55  	}
    56  	var namespace = "namespace"
    57  
    58  	// Expected ListReleasesRequest message
    59  	exp := &tpb.ListReleasesRequest{
    60  		Limit:       int64(limit),
    61  		Offset:      offset,
    62  		Filter:      filter,
    63  		SortBy:      tpb.ListSort_SortBy(sortBy),
    64  		SortOrder:   tpb.ListSort_SortOrder(sortOrd),
    65  		StatusCodes: codes,
    66  		Namespace:   namespace,
    67  	}
    68  
    69  	// Options used in ListReleases
    70  	ops := []ReleaseListOption{
    71  		ReleaseListSort(sortBy),
    72  		ReleaseListOrder(sortOrd),
    73  		ReleaseListLimit(limit),
    74  		ReleaseListOffset(offset),
    75  		ReleaseListFilter(filter),
    76  		ReleaseListStatuses(codes),
    77  		ReleaseListNamespace(namespace),
    78  	}
    79  
    80  	// BeforeCall option to intercept Helm client ListReleasesRequest
    81  	b4c := BeforeCall(func(_ context.Context, msg proto.Message) error {
    82  		switch act := msg.(type) {
    83  		case *tpb.ListReleasesRequest:
    84  			t.Logf("ListReleasesRequest: %#+v\n", act)
    85  			assert(t, exp, act)
    86  		default:
    87  			t.Fatalf("expected message of type ListReleasesRequest, got %T\n", act)
    88  		}
    89  		return errSkip
    90  	})
    91  
    92  	client := NewClient(b4c)
    93  
    94  	if _, err := client.ListReleases(ops...); err != errSkip {
    95  		t.Fatalf("did not expect error but got (%v)\n``", err)
    96  	}
    97  
    98  	// ensure options for call are not saved to client
    99  	assert(t, "", client.opts.listReq.Filter)
   100  }
   101  
   102  // Verify each InstallOption is applied to an InstallReleaseRequest correctly.
   103  func TestInstallRelease_VerifyOptions(t *testing.T) {
   104  	// Options testdata
   105  	var disableHooks = true
   106  	var releaseName = "test"
   107  	var namespace = "default"
   108  	var reuseName = true
   109  	var dryRun = true
   110  	var chartName = "alpine"
   111  	var chartPath = filepath.Join(chartsDir, chartName)
   112  	var overrides = []byte("key1=value1,key2=value2")
   113  
   114  	// Expected InstallReleaseRequest message
   115  	exp := &tpb.InstallReleaseRequest{
   116  		Chart:        loadChart(t, chartName),
   117  		Values:       &cpb.Config{Raw: string(overrides)},
   118  		DryRun:       dryRun,
   119  		Name:         releaseName,
   120  		DisableHooks: disableHooks,
   121  		Namespace:    namespace,
   122  		ReuseName:    reuseName,
   123  	}
   124  
   125  	// Options used in InstallRelease
   126  	ops := []InstallOption{
   127  		ValueOverrides(overrides),
   128  		InstallDryRun(dryRun),
   129  		ReleaseName(releaseName),
   130  		InstallReuseName(reuseName),
   131  		InstallDisableHooks(disableHooks),
   132  	}
   133  
   134  	// BeforeCall option to intercept Helm client InstallReleaseRequest
   135  	b4c := BeforeCall(func(_ context.Context, msg proto.Message) error {
   136  		switch act := msg.(type) {
   137  		case *tpb.InstallReleaseRequest:
   138  			t.Logf("InstallReleaseRequest: %#+v\n", act)
   139  			assert(t, exp, act)
   140  		default:
   141  			t.Fatalf("expected message of type InstallReleaseRequest, got %T\n", act)
   142  		}
   143  		return errSkip
   144  	})
   145  
   146  	client := NewClient(b4c)
   147  	if _, err := client.InstallRelease(chartPath, namespace, ops...); err != errSkip {
   148  		t.Fatalf("did not expect error but got (%v)\n``", err)
   149  	}
   150  
   151  	// ensure options for call are not saved to client
   152  	assert(t, "", client.opts.instReq.Name)
   153  }
   154  
   155  // Verify each DeleteOptions is applied to an UninstallReleaseRequest correctly.
   156  func TestDeleteRelease_VerifyOptions(t *testing.T) {
   157  	// Options testdata
   158  	var releaseName = "test"
   159  	var disableHooks = true
   160  	var purgeFlag = true
   161  
   162  	// Expected DeleteReleaseRequest message
   163  	exp := &tpb.UninstallReleaseRequest{
   164  		Name:         releaseName,
   165  		Purge:        purgeFlag,
   166  		DisableHooks: disableHooks,
   167  	}
   168  
   169  	// Options used in DeleteRelease
   170  	ops := []DeleteOption{
   171  		DeletePurge(purgeFlag),
   172  		DeleteDisableHooks(disableHooks),
   173  	}
   174  
   175  	// BeforeCall option to intercept Helm client DeleteReleaseRequest
   176  	b4c := BeforeCall(func(_ context.Context, msg proto.Message) error {
   177  		switch act := msg.(type) {
   178  		case *tpb.UninstallReleaseRequest:
   179  			t.Logf("UninstallReleaseRequest: %#+v\n", act)
   180  			assert(t, exp, act)
   181  		default:
   182  			t.Fatalf("expected message of type UninstallReleaseRequest, got %T\n", act)
   183  		}
   184  		return errSkip
   185  	})
   186  
   187  	client := NewClient(b4c)
   188  	if _, err := client.DeleteRelease(releaseName, ops...); err != errSkip {
   189  		t.Fatalf("did not expect error but got (%v)\n``", err)
   190  	}
   191  
   192  	// ensure options for call are not saved to client
   193  	assert(t, "", client.opts.uninstallReq.Name)
   194  }
   195  
   196  // Verify each UpdateOption is applied to an UpdateReleaseRequest correctly.
   197  func TestUpdateRelease_VerifyOptions(t *testing.T) {
   198  	// Options testdata
   199  	var chartName = "alpine"
   200  	var chartPath = filepath.Join(chartsDir, chartName)
   201  	var releaseName = "test"
   202  	var disableHooks = true
   203  	var overrides = []byte("key1=value1,key2=value2")
   204  	var dryRun = false
   205  
   206  	// Expected UpdateReleaseRequest message
   207  	exp := &tpb.UpdateReleaseRequest{
   208  		Name:         releaseName,
   209  		Chart:        loadChart(t, chartName),
   210  		Values:       &cpb.Config{Raw: string(overrides)},
   211  		DryRun:       dryRun,
   212  		DisableHooks: disableHooks,
   213  	}
   214  
   215  	// Options used in UpdateRelease
   216  	ops := []UpdateOption{
   217  		UpgradeDryRun(dryRun),
   218  		UpdateValueOverrides(overrides),
   219  		UpgradeDisableHooks(disableHooks),
   220  	}
   221  
   222  	// BeforeCall option to intercept Helm client UpdateReleaseRequest
   223  	b4c := BeforeCall(func(_ context.Context, msg proto.Message) error {
   224  		switch act := msg.(type) {
   225  		case *tpb.UpdateReleaseRequest:
   226  			t.Logf("UpdateReleaseRequest: %#+v\n", act)
   227  			assert(t, exp, act)
   228  		default:
   229  			t.Fatalf("expected message of type UpdateReleaseRequest, got %T\n", act)
   230  		}
   231  		return errSkip
   232  	})
   233  
   234  	client := NewClient(b4c)
   235  	if _, err := client.UpdateRelease(releaseName, chartPath, ops...); err != errSkip {
   236  		t.Fatalf("did not expect error but got (%v)\n``", err)
   237  	}
   238  
   239  	// ensure options for call are not saved to client
   240  	assert(t, "", client.opts.updateReq.Name)
   241  }
   242  
   243  // Verify each RollbackOption is applied to a RollbackReleaseRequest correctly.
   244  func TestRollbackRelease_VerifyOptions(t *testing.T) {
   245  	// Options testdata
   246  	var disableHooks = true
   247  	var releaseName = "test"
   248  	var revision = int32(2)
   249  	var dryRun = true
   250  
   251  	// Expected RollbackReleaseRequest message
   252  	exp := &tpb.RollbackReleaseRequest{
   253  		Name:         releaseName,
   254  		DryRun:       dryRun,
   255  		Version:      revision,
   256  		DisableHooks: disableHooks,
   257  	}
   258  
   259  	// Options used in RollbackRelease
   260  	ops := []RollbackOption{
   261  		RollbackDryRun(dryRun),
   262  		RollbackVersion(revision),
   263  		RollbackDisableHooks(disableHooks),
   264  	}
   265  
   266  	// BeforeCall option to intercept Helm client RollbackReleaseRequest
   267  	b4c := BeforeCall(func(_ context.Context, msg proto.Message) error {
   268  		switch act := msg.(type) {
   269  		case *tpb.RollbackReleaseRequest:
   270  			t.Logf("RollbackReleaseRequest: %#+v\n", act)
   271  			assert(t, exp, act)
   272  		default:
   273  			t.Fatalf("expected message of type RollbackReleaseRequest, got %T\n", act)
   274  		}
   275  		return errSkip
   276  	})
   277  
   278  	client := NewClient(b4c)
   279  	if _, err := client.RollbackRelease(releaseName, ops...); err != errSkip {
   280  		t.Fatalf("did not expect error but got (%v)\n``", err)
   281  	}
   282  
   283  	// ensure options for call are not saved to client
   284  	assert(t, "", client.opts.rollbackReq.Name)
   285  }
   286  
   287  // Verify each StatusOption is applied to a GetReleaseStatusRequest correctly.
   288  func TestReleaseStatus_VerifyOptions(t *testing.T) {
   289  	// Options testdata
   290  	var releaseName = "test"
   291  	var revision = int32(2)
   292  
   293  	// Expected GetReleaseStatusRequest message
   294  	exp := &tpb.GetReleaseStatusRequest{
   295  		Name:    releaseName,
   296  		Version: revision,
   297  	}
   298  
   299  	// BeforeCall option to intercept Helm client GetReleaseStatusRequest
   300  	b4c := BeforeCall(func(_ context.Context, msg proto.Message) error {
   301  		switch act := msg.(type) {
   302  		case *tpb.GetReleaseStatusRequest:
   303  			t.Logf("GetReleaseStatusRequest: %#+v\n", act)
   304  			assert(t, exp, act)
   305  		default:
   306  			t.Fatalf("expected message of type GetReleaseStatusRequest, got %T\n", act)
   307  		}
   308  		return errSkip
   309  	})
   310  
   311  	client := NewClient(b4c)
   312  	if _, err := client.ReleaseStatus(releaseName, StatusReleaseVersion(revision)); err != errSkip {
   313  		t.Fatalf("did not expect error but got (%v)\n``", err)
   314  	}
   315  
   316  	// ensure options for call are not saved to client
   317  	assert(t, "", client.opts.statusReq.Name)
   318  }
   319  
   320  // Verify each ContentOption is applied to a GetReleaseContentRequest correctly.
   321  func TestReleaseContent_VerifyOptions(t *testing.T) {
   322  	// Options testdata
   323  	var releaseName = "test"
   324  	var revision = int32(2)
   325  
   326  	// Expected GetReleaseContentRequest message
   327  	exp := &tpb.GetReleaseContentRequest{
   328  		Name:    releaseName,
   329  		Version: revision,
   330  	}
   331  
   332  	// BeforeCall option to intercept Helm client GetReleaseContentRequest
   333  	b4c := BeforeCall(func(_ context.Context, msg proto.Message) error {
   334  		switch act := msg.(type) {
   335  		case *tpb.GetReleaseContentRequest:
   336  			t.Logf("GetReleaseContentRequest: %#+v\n", act)
   337  			assert(t, exp, act)
   338  		default:
   339  			t.Fatalf("expected message of type GetReleaseContentRequest, got %T\n", act)
   340  		}
   341  		return errSkip
   342  	})
   343  
   344  	client := NewClient(b4c)
   345  	if _, err := client.ReleaseContent(releaseName, ContentReleaseVersion(revision)); err != errSkip {
   346  		t.Fatalf("did not expect error but got (%v)\n``", err)
   347  	}
   348  
   349  	// ensure options for call are not saved to client
   350  	assert(t, "", client.opts.contentReq.Name)
   351  }
   352  
   353  func assert(t *testing.T, expect, actual interface{}) {
   354  	if !reflect.DeepEqual(expect, actual) {
   355  		t.Fatalf("expected %#+v, actual %#+v\n", expect, actual)
   356  	}
   357  }
   358  
   359  func loadChart(t *testing.T, name string) *cpb.Chart {
   360  	c, err := chartutil.Load(filepath.Join(chartsDir, name))
   361  	if err != nil {
   362  		t.Fatalf("failed to load test chart (%q): %s\n", name, err)
   363  	}
   364  	return c
   365  }
   366  
   367  func TestDoesNotImportKubernetes(t *testing.T) {
   368  	cmd := exec.Command("go", "list", "-f", "{{.Deps}}", ".")
   369  	output, err := cmd.CombinedOutput()
   370  	if err != nil {
   371  		t.Fatalf("Failed to execute %s %s: %s", cmd.Path, strings.Join(cmd.Args, " "), err)
   372  	}
   373  
   374  	if strings.Contains(string(output), "k8s.io/kubernetes") {
   375  		t.Fatal("k8s.io/helm/pkg/helm contains a dependency on k8s.io/kubernetes. See https://github.com/helm/helm/pull/4499 for more details.")
   376  	}
   377  }