github.com/koderover/helm@v2.17.0+incompatible/pkg/storage/storage_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 storage // import "k8s.io/helm/pkg/storage"
    18  
    19  import (
    20  	"fmt"
    21  	"reflect"
    22  	"testing"
    23  
    24  	rspb "k8s.io/helm/pkg/proto/hapi/release"
    25  	"k8s.io/helm/pkg/storage/driver"
    26  )
    27  
    28  func TestStorageCreate(t *testing.T) {
    29  	// initialize storage
    30  	storage := Init(driver.NewMemory())
    31  
    32  	// create fake release
    33  	rls := ReleaseTestData{
    34  		Name:    "angry-beaver",
    35  		Version: 1,
    36  	}.ToRelease()
    37  
    38  	assertErrNil(t.Fatal, storage.Create(rls), "StoreRelease")
    39  
    40  	// fetch the release
    41  	res, err := storage.Get(rls.Name, rls.Version)
    42  	assertErrNil(t.Fatal, err, "QueryRelease")
    43  
    44  	// verify the fetched and created release are the same
    45  	if !reflect.DeepEqual(rls, res) {
    46  		t.Fatalf("Expected %q, got %q", rls, res)
    47  	}
    48  }
    49  
    50  func TestStorageUpdate(t *testing.T) {
    51  	// initialize storage
    52  	storage := Init(driver.NewMemory())
    53  
    54  	// create fake release
    55  	rls := ReleaseTestData{
    56  		Name:    "angry-beaver",
    57  		Version: 1,
    58  		Status:  rspb.Status_DEPLOYED,
    59  	}.ToRelease()
    60  
    61  	assertErrNil(t.Fatal, storage.Create(rls), "StoreRelease")
    62  
    63  	// modify the release
    64  	rls.Info.Status.Code = rspb.Status_DELETED
    65  	assertErrNil(t.Fatal, storage.Update(rls), "UpdateRelease")
    66  
    67  	// retrieve the updated release
    68  	res, err := storage.Get(rls.Name, rls.Version)
    69  	assertErrNil(t.Fatal, err, "QueryRelease")
    70  
    71  	// verify updated and fetched releases are the same.
    72  	if !reflect.DeepEqual(rls, res) {
    73  		t.Fatalf("Expected %q, got %q", rls, res)
    74  	}
    75  }
    76  
    77  func TestStorageDelete(t *testing.T) {
    78  	// initialize storage
    79  	storage := Init(driver.NewMemory())
    80  
    81  	// create fake release
    82  	rls := ReleaseTestData{
    83  		Name:    "angry-beaver",
    84  		Version: 1,
    85  	}.ToRelease()
    86  	rls2 := ReleaseTestData{
    87  		Name:    "angry-beaver",
    88  		Version: 2,
    89  	}.ToRelease()
    90  
    91  	assertErrNil(t.Fatal, storage.Create(rls), "StoreRelease")
    92  	assertErrNil(t.Fatal, storage.Create(rls2), "StoreRelease")
    93  
    94  	// delete the release
    95  	res, err := storage.Delete(rls.Name, rls.Version)
    96  	assertErrNil(t.Fatal, err, "DeleteRelease")
    97  
    98  	// verify updated and fetched releases are the same.
    99  	if !reflect.DeepEqual(rls, res) {
   100  		t.Fatalf("Expected %q, got %q", rls, res)
   101  	}
   102  
   103  	hist, err := storage.History(rls.Name)
   104  	if err != nil {
   105  		t.Errorf("unexpected error: %s", err)
   106  	}
   107  
   108  	// We have now deleted one of the two records.
   109  	if len(hist) != 1 {
   110  		t.Errorf("expected 1 record for deleted release version, got %d", len(hist))
   111  	}
   112  
   113  	if hist[0].Version != 2 {
   114  		t.Errorf("Expected version to be 2, got %d", hist[0].Version)
   115  	}
   116  }
   117  
   118  func TestStorageList(t *testing.T) {
   119  	// initialize storage
   120  	storage := Init(driver.NewMemory())
   121  
   122  	// setup storage with test releases
   123  	setup := func() {
   124  		// release records
   125  		rls0 := ReleaseTestData{Name: "happy-catdog", Status: rspb.Status_SUPERSEDED}.ToRelease()
   126  		rls1 := ReleaseTestData{Name: "livid-human", Status: rspb.Status_SUPERSEDED}.ToRelease()
   127  		rls2 := ReleaseTestData{Name: "relaxed-cat", Status: rspb.Status_SUPERSEDED}.ToRelease()
   128  		rls3 := ReleaseTestData{Name: "hungry-hippo", Status: rspb.Status_DEPLOYED}.ToRelease()
   129  		rls4 := ReleaseTestData{Name: "angry-beaver", Status: rspb.Status_DEPLOYED}.ToRelease()
   130  		rls5 := ReleaseTestData{Name: "opulent-frog", Status: rspb.Status_DELETED}.ToRelease()
   131  		rls6 := ReleaseTestData{Name: "happy-liger", Status: rspb.Status_DELETED}.ToRelease()
   132  
   133  		// create the release records in the storage
   134  		assertErrNil(t.Fatal, storage.Create(rls0), "Storing release 'rls0'")
   135  		assertErrNil(t.Fatal, storage.Create(rls1), "Storing release 'rls1'")
   136  		assertErrNil(t.Fatal, storage.Create(rls2), "Storing release 'rls2'")
   137  		assertErrNil(t.Fatal, storage.Create(rls3), "Storing release 'rls3'")
   138  		assertErrNil(t.Fatal, storage.Create(rls4), "Storing release 'rls4'")
   139  		assertErrNil(t.Fatal, storage.Create(rls5), "Storing release 'rls5'")
   140  		assertErrNil(t.Fatal, storage.Create(rls6), "Storing release 'rls6'")
   141  	}
   142  
   143  	var listTests = []struct {
   144  		Description string
   145  		NumExpected int
   146  		ListFunc    func() ([]*rspb.Release, error)
   147  	}{
   148  		{"ListDeleted", 2, storage.ListDeleted},
   149  		{"ListDeployed", 2, storage.ListDeployed},
   150  		{"ListReleases", 7, storage.ListReleases},
   151  	}
   152  
   153  	setup()
   154  
   155  	for _, tt := range listTests {
   156  		list, err := tt.ListFunc()
   157  		assertErrNil(t.Fatal, err, tt.Description)
   158  		// verify the count of releases returned
   159  		if len(list) != tt.NumExpected {
   160  			t.Errorf("ListReleases(%s): expected %d, actual %d",
   161  				tt.Description,
   162  				tt.NumExpected,
   163  				len(list))
   164  		}
   165  	}
   166  }
   167  
   168  func TestStorageDeployed(t *testing.T) {
   169  	storage := Init(driver.NewMemory())
   170  
   171  	const name = "angry-bird"
   172  	const vers = int32(4)
   173  
   174  	// setup storage with test releases
   175  	setup := func() {
   176  		// release records
   177  		rls0 := ReleaseTestData{Name: name, Version: 1, Status: rspb.Status_SUPERSEDED}.ToRelease()
   178  		rls1 := ReleaseTestData{Name: name, Version: 2, Status: rspb.Status_SUPERSEDED}.ToRelease()
   179  		rls2 := ReleaseTestData{Name: name, Version: 3, Status: rspb.Status_SUPERSEDED}.ToRelease()
   180  		rls3 := ReleaseTestData{Name: name, Version: 4, Status: rspb.Status_DEPLOYED}.ToRelease()
   181  
   182  		// create the release records in the storage
   183  		assertErrNil(t.Fatal, storage.Create(rls0), "Storing release 'angry-bird' (v1)")
   184  		assertErrNil(t.Fatal, storage.Create(rls1), "Storing release 'angry-bird' (v2)")
   185  		assertErrNil(t.Fatal, storage.Create(rls2), "Storing release 'angry-bird' (v3)")
   186  		assertErrNil(t.Fatal, storage.Create(rls3), "Storing release 'angry-bird' (v4)")
   187  	}
   188  
   189  	setup()
   190  
   191  	rls, err := storage.Last(name)
   192  	if err != nil {
   193  		t.Fatalf("Failed to query for deployed release: %s\n", err)
   194  	}
   195  
   196  	switch {
   197  	case rls == nil:
   198  		t.Fatalf("Release is nil")
   199  	case rls.Name != name:
   200  		t.Fatalf("Expected release name %q, actual %q\n", name, rls.Name)
   201  	case rls.Version != vers:
   202  		t.Fatalf("Expected release version %d, actual %d\n", vers, rls.Version)
   203  	case rls.Info.Status.Code != rspb.Status_DEPLOYED:
   204  		t.Fatalf("Expected release status 'DEPLOYED', actual %s\n", rls.Info.Status.Code)
   205  	}
   206  }
   207  
   208  func TestStorageDeployedWithCorruption(t *testing.T) {
   209  	storage := Init(driver.NewMemory())
   210  
   211  	const name = "angry-bird"
   212  	const vers = int32(4)
   213  
   214  	// setup storage with test releases
   215  	setup := func() {
   216  		// release records (notice odd order and corruption)
   217  		rls0 := ReleaseTestData{Name: name, Version: 1, Status: rspb.Status_SUPERSEDED}.ToRelease()
   218  		rls1 := ReleaseTestData{Name: name, Version: 4, Status: rspb.Status_DEPLOYED}.ToRelease()
   219  		rls2 := ReleaseTestData{Name: name, Version: 3, Status: rspb.Status_SUPERSEDED}.ToRelease()
   220  		rls3 := ReleaseTestData{Name: name, Version: 2, Status: rspb.Status_DEPLOYED}.ToRelease()
   221  
   222  		// create the release records in the storage
   223  		assertErrNil(t.Fatal, storage.Create(rls0), "Storing release 'angry-bird' (v1)")
   224  		assertErrNil(t.Fatal, storage.Create(rls1), "Storing release 'angry-bird' (v2)")
   225  		assertErrNil(t.Fatal, storage.Create(rls2), "Storing release 'angry-bird' (v3)")
   226  		assertErrNil(t.Fatal, storage.Create(rls3), "Storing release 'angry-bird' (v4)")
   227  	}
   228  
   229  	setup()
   230  
   231  	rls, err := storage.Deployed(name)
   232  	if err != nil {
   233  		t.Fatalf("Failed to query for deployed release: %s\n", err)
   234  	}
   235  
   236  	switch {
   237  	case rls == nil:
   238  		t.Fatalf("Release is nil")
   239  	case rls.Name != name:
   240  		t.Fatalf("Expected release name %q, actual %q\n", name, rls.Name)
   241  	case rls.Version != vers:
   242  		t.Fatalf("Expected release version %d, actual %d\n", vers, rls.Version)
   243  	case rls.Info.Status.Code != rspb.Status_DEPLOYED:
   244  		t.Fatalf("Expected release status 'DEPLOYED', actual %s\n", rls.Info.Status.Code)
   245  	}
   246  }
   247  
   248  func TestStorageHistory(t *testing.T) {
   249  	storage := Init(driver.NewMemory())
   250  
   251  	const name = "angry-bird"
   252  
   253  	// setup storage with test releases
   254  	setup := func() {
   255  		// release records
   256  		rls0 := ReleaseTestData{Name: name, Version: 1, Status: rspb.Status_SUPERSEDED}.ToRelease()
   257  		rls1 := ReleaseTestData{Name: name, Version: 2, Status: rspb.Status_SUPERSEDED}.ToRelease()
   258  		rls2 := ReleaseTestData{Name: name, Version: 3, Status: rspb.Status_SUPERSEDED}.ToRelease()
   259  		rls3 := ReleaseTestData{Name: name, Version: 4, Status: rspb.Status_DEPLOYED}.ToRelease()
   260  
   261  		// create the release records in the storage
   262  		assertErrNil(t.Fatal, storage.Create(rls0), "Storing release 'angry-bird' (v1)")
   263  		assertErrNil(t.Fatal, storage.Create(rls1), "Storing release 'angry-bird' (v2)")
   264  		assertErrNil(t.Fatal, storage.Create(rls2), "Storing release 'angry-bird' (v3)")
   265  		assertErrNil(t.Fatal, storage.Create(rls3), "Storing release 'angry-bird' (v4)")
   266  	}
   267  
   268  	setup()
   269  
   270  	h, err := storage.History(name)
   271  	if err != nil {
   272  		t.Fatalf("Failed to query for release history (%q): %s\n", name, err)
   273  	}
   274  	if len(h) != 4 {
   275  		t.Fatalf("Release history (%q) is empty\n", name)
   276  	}
   277  }
   278  
   279  func TestStorageRemoveLeastRecent(t *testing.T) {
   280  	storage := Init(driver.NewMemory())
   281  	storage.Log = t.Logf
   282  
   283  	// Make sure that specifying this at the outset doesn't cause any bugs.
   284  	storage.MaxHistory = 10
   285  
   286  	const name = "angry-bird"
   287  
   288  	// setup storage with test releases
   289  	setup := func() {
   290  		// release records
   291  		rls0 := ReleaseTestData{Name: name, Version: 1, Status: rspb.Status_SUPERSEDED}.ToRelease()
   292  		rls1 := ReleaseTestData{Name: name, Version: 2, Status: rspb.Status_SUPERSEDED}.ToRelease()
   293  		rls2 := ReleaseTestData{Name: name, Version: 3, Status: rspb.Status_SUPERSEDED}.ToRelease()
   294  		rls3 := ReleaseTestData{Name: name, Version: 4, Status: rspb.Status_DEPLOYED}.ToRelease()
   295  
   296  		// create the release records in the storage
   297  		assertErrNil(t.Fatal, storage.Create(rls0), "Storing release 'angry-bird' (v1)")
   298  		assertErrNil(t.Fatal, storage.Create(rls1), "Storing release 'angry-bird' (v2)")
   299  		assertErrNil(t.Fatal, storage.Create(rls2), "Storing release 'angry-bird' (v3)")
   300  		assertErrNil(t.Fatal, storage.Create(rls3), "Storing release 'angry-bird' (v4)")
   301  	}
   302  	setup()
   303  
   304  	// Because we have not set a limit, we expect 4.
   305  	expect := 4
   306  	if hist, err := storage.History(name); err != nil {
   307  		t.Fatal(err)
   308  	} else if len(hist) != expect {
   309  		t.Fatalf("expected %d items in history, got %d", expect, len(hist))
   310  	}
   311  
   312  	storage.MaxHistory = 3
   313  	rls5 := ReleaseTestData{Name: name, Version: 5, Status: rspb.Status_DEPLOYED}.ToRelease()
   314  	assertErrNil(t.Fatal, storage.Create(rls5), "Storing release 'angry-bird' (v5)")
   315  
   316  	// On inserting the 5th record, we expect two records to be pruned from history.
   317  	hist, err := storage.History(name)
   318  	if err != nil {
   319  		t.Fatal(err)
   320  	} else if len(hist) != storage.MaxHistory {
   321  		for _, item := range hist {
   322  			t.Logf("%s %v", item.Name, item.Version)
   323  		}
   324  		t.Fatalf("expected %d items in history, got %d", storage.MaxHistory, len(hist))
   325  	}
   326  
   327  	// We expect the existing records to be 3, 4, and 5.
   328  	for i, item := range hist {
   329  		v := int(item.Version)
   330  		if expect := i + 3; v != expect {
   331  			t.Errorf("Expected release %d, got %d", expect, v)
   332  		}
   333  	}
   334  }
   335  
   336  func TestStorageDontDeleteDeployed(t *testing.T) {
   337  	storage := Init(driver.NewMemory())
   338  	storage.Log = t.Logf
   339  	storage.MaxHistory = 3
   340  
   341  	const name = "angry-bird"
   342  
   343  	// setup storage with test releases
   344  	setup := func() {
   345  		// release records
   346  		rls0 := ReleaseTestData{Name: name, Version: 1, Status: rspb.Status_SUPERSEDED}.ToRelease()
   347  		rls1 := ReleaseTestData{Name: name, Version: 2, Status: rspb.Status_DEPLOYED}.ToRelease()
   348  		rls2 := ReleaseTestData{Name: name, Version: 3, Status: rspb.Status_FAILED}.ToRelease()
   349  		rls3 := ReleaseTestData{Name: name, Version: 4, Status: rspb.Status_FAILED}.ToRelease()
   350  
   351  		// create the release records in the storage
   352  		assertErrNil(t.Fatal, storage.Create(rls0), "Storing release 'angry-bird' (v1)")
   353  		assertErrNil(t.Fatal, storage.Create(rls1), "Storing release 'angry-bird' (v2)")
   354  		assertErrNil(t.Fatal, storage.Create(rls2), "Storing release 'angry-bird' (v3)")
   355  		assertErrNil(t.Fatal, storage.Create(rls3), "Storing release 'angry-bird' (v4)")
   356  	}
   357  	setup()
   358  
   359  	rls5 := ReleaseTestData{Name: name, Version: 5, Status: rspb.Status_FAILED}.ToRelease()
   360  	assertErrNil(t.Fatal, storage.Create(rls5), "Storing release 'angry-bird' (v5)")
   361  
   362  	// On inserting the 5th record, we expect a total of 3 releases, but we expect version 2
   363  	// (the only deployed release), to still exist
   364  	hist, err := storage.History(name)
   365  	if err != nil {
   366  		t.Fatal(err)
   367  	} else if len(hist) != storage.MaxHistory {
   368  		for _, item := range hist {
   369  			t.Logf("%s %v", item.Name, item.Version)
   370  		}
   371  		t.Fatalf("expected %d items in history, got %d", storage.MaxHistory, len(hist))
   372  	}
   373  
   374  	expectedVersions := map[int32]bool{
   375  		2: true,
   376  		4: true,
   377  		5: true,
   378  	}
   379  
   380  	for _, item := range hist {
   381  		if !expectedVersions[item.GetVersion()] {
   382  			t.Errorf("Release version %d, found when not expected", item.GetVersion())
   383  		}
   384  	}
   385  }
   386  
   387  func TestStorageLast(t *testing.T) {
   388  	storage := Init(driver.NewMemory())
   389  
   390  	const name = "angry-bird"
   391  
   392  	// Set up storage with test releases.
   393  	setup := func() {
   394  		// release records
   395  		rls0 := ReleaseTestData{Name: name, Version: 1, Status: rspb.Status_SUPERSEDED}.ToRelease()
   396  		rls1 := ReleaseTestData{Name: name, Version: 2, Status: rspb.Status_SUPERSEDED}.ToRelease()
   397  		rls2 := ReleaseTestData{Name: name, Version: 3, Status: rspb.Status_SUPERSEDED}.ToRelease()
   398  		rls3 := ReleaseTestData{Name: name, Version: 4, Status: rspb.Status_FAILED}.ToRelease()
   399  
   400  		// create the release records in the storage
   401  		assertErrNil(t.Fatal, storage.Create(rls0), "Storing release 'angry-bird' (v1)")
   402  		assertErrNil(t.Fatal, storage.Create(rls1), "Storing release 'angry-bird' (v2)")
   403  		assertErrNil(t.Fatal, storage.Create(rls2), "Storing release 'angry-bird' (v3)")
   404  		assertErrNil(t.Fatal, storage.Create(rls3), "Storing release 'angry-bird' (v4)")
   405  	}
   406  
   407  	setup()
   408  
   409  	h, err := storage.Last(name)
   410  	if err != nil {
   411  		t.Fatalf("Failed to query for release history (%q): %s\n", name, err)
   412  	}
   413  
   414  	if h.Version != 4 {
   415  		t.Errorf("Expected revision 4, got %d", h.Version)
   416  	}
   417  }
   418  
   419  type ReleaseTestData struct {
   420  	Name      string
   421  	Version   int32
   422  	Manifest  string
   423  	Namespace string
   424  	Status    rspb.Status_Code
   425  }
   426  
   427  func (test ReleaseTestData) ToRelease() *rspb.Release {
   428  	return &rspb.Release{
   429  		Name:      test.Name,
   430  		Version:   test.Version,
   431  		Manifest:  test.Manifest,
   432  		Namespace: test.Namespace,
   433  		Info:      &rspb.Info{Status: &rspb.Status{Code: test.Status}},
   434  	}
   435  }
   436  
   437  func assertErrNil(eh func(args ...interface{}), err error, message string) {
   438  	if err != nil {
   439  		eh(fmt.Sprintf("%s: %q", message, err))
   440  	}
   441  }