github.com/latiif/helm@v2.15.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 TestStorageHistory(t *testing.T) {
   209  	storage := Init(driver.NewMemory())
   210  
   211  	const name = "angry-bird"
   212  
   213  	// setup storage with test releases
   214  	setup := func() {
   215  		// release records
   216  		rls0 := ReleaseTestData{Name: name, Version: 1, Status: rspb.Status_SUPERSEDED}.ToRelease()
   217  		rls1 := ReleaseTestData{Name: name, Version: 2, Status: rspb.Status_SUPERSEDED}.ToRelease()
   218  		rls2 := ReleaseTestData{Name: name, Version: 3, Status: rspb.Status_SUPERSEDED}.ToRelease()
   219  		rls3 := ReleaseTestData{Name: name, Version: 4, Status: rspb.Status_DEPLOYED}.ToRelease()
   220  
   221  		// create the release records in the storage
   222  		assertErrNil(t.Fatal, storage.Create(rls0), "Storing release 'angry-bird' (v1)")
   223  		assertErrNil(t.Fatal, storage.Create(rls1), "Storing release 'angry-bird' (v2)")
   224  		assertErrNil(t.Fatal, storage.Create(rls2), "Storing release 'angry-bird' (v3)")
   225  		assertErrNil(t.Fatal, storage.Create(rls3), "Storing release 'angry-bird' (v4)")
   226  	}
   227  
   228  	setup()
   229  
   230  	h, err := storage.History(name)
   231  	if err != nil {
   232  		t.Fatalf("Failed to query for release history (%q): %s\n", name, err)
   233  	}
   234  	if len(h) != 4 {
   235  		t.Fatalf("Release history (%q) is empty\n", name)
   236  	}
   237  }
   238  
   239  func TestStorageRemoveLeastRecent(t *testing.T) {
   240  	storage := Init(driver.NewMemory())
   241  	storage.Log = t.Logf
   242  
   243  	// Make sure that specifying this at the outset doesn't cause any bugs.
   244  	storage.MaxHistory = 10
   245  
   246  	const name = "angry-bird"
   247  
   248  	// setup storage with test releases
   249  	setup := func() {
   250  		// release records
   251  		rls0 := ReleaseTestData{Name: name, Version: 1, Status: rspb.Status_SUPERSEDED}.ToRelease()
   252  		rls1 := ReleaseTestData{Name: name, Version: 2, Status: rspb.Status_SUPERSEDED}.ToRelease()
   253  		rls2 := ReleaseTestData{Name: name, Version: 3, Status: rspb.Status_SUPERSEDED}.ToRelease()
   254  		rls3 := ReleaseTestData{Name: name, Version: 4, Status: rspb.Status_DEPLOYED}.ToRelease()
   255  
   256  		// create the release records in the storage
   257  		assertErrNil(t.Fatal, storage.Create(rls0), "Storing release 'angry-bird' (v1)")
   258  		assertErrNil(t.Fatal, storage.Create(rls1), "Storing release 'angry-bird' (v2)")
   259  		assertErrNil(t.Fatal, storage.Create(rls2), "Storing release 'angry-bird' (v3)")
   260  		assertErrNil(t.Fatal, storage.Create(rls3), "Storing release 'angry-bird' (v4)")
   261  	}
   262  	setup()
   263  
   264  	// Because we have not set a limit, we expect 4.
   265  	expect := 4
   266  	if hist, err := storage.History(name); err != nil {
   267  		t.Fatal(err)
   268  	} else if len(hist) != expect {
   269  		t.Fatalf("expected %d items in history, got %d", expect, len(hist))
   270  	}
   271  
   272  	storage.MaxHistory = 3
   273  	rls5 := ReleaseTestData{Name: name, Version: 5, Status: rspb.Status_DEPLOYED}.ToRelease()
   274  	assertErrNil(t.Fatal, storage.Create(rls5), "Storing release 'angry-bird' (v5)")
   275  
   276  	// On inserting the 5th record, we expect two records to be pruned from history.
   277  	hist, err := storage.History(name)
   278  	if err != nil {
   279  		t.Fatal(err)
   280  	} else if len(hist) != storage.MaxHistory {
   281  		for _, item := range hist {
   282  			t.Logf("%s %v", item.Name, item.Version)
   283  		}
   284  		t.Fatalf("expected %d items in history, got %d", storage.MaxHistory, len(hist))
   285  	}
   286  
   287  	// We expect the existing records to be 3, 4, and 5.
   288  	for i, item := range hist {
   289  		v := int(item.Version)
   290  		if expect := i + 3; v != expect {
   291  			t.Errorf("Expected release %d, got %d", expect, v)
   292  		}
   293  	}
   294  }
   295  
   296  func TestStorageDontDeleteDeployed(t *testing.T) {
   297  	storage := Init(driver.NewMemory())
   298  	storage.Log = t.Logf
   299  	storage.MaxHistory = 3
   300  
   301  	const name = "angry-bird"
   302  
   303  	// setup storage with test releases
   304  	setup := func() {
   305  		// release records
   306  		rls0 := ReleaseTestData{Name: name, Version: 1, Status: rspb.Status_SUPERSEDED}.ToRelease()
   307  		rls1 := ReleaseTestData{Name: name, Version: 2, Status: rspb.Status_DEPLOYED}.ToRelease()
   308  		rls2 := ReleaseTestData{Name: name, Version: 3, Status: rspb.Status_FAILED}.ToRelease()
   309  		rls3 := ReleaseTestData{Name: name, Version: 4, Status: rspb.Status_FAILED}.ToRelease()
   310  
   311  		// create the release records in the storage
   312  		assertErrNil(t.Fatal, storage.Create(rls0), "Storing release 'angry-bird' (v1)")
   313  		assertErrNil(t.Fatal, storage.Create(rls1), "Storing release 'angry-bird' (v2)")
   314  		assertErrNil(t.Fatal, storage.Create(rls2), "Storing release 'angry-bird' (v3)")
   315  		assertErrNil(t.Fatal, storage.Create(rls3), "Storing release 'angry-bird' (v4)")
   316  	}
   317  	setup()
   318  
   319  	rls5 := ReleaseTestData{Name: name, Version: 5, Status: rspb.Status_FAILED}.ToRelease()
   320  	assertErrNil(t.Fatal, storage.Create(rls5), "Storing release 'angry-bird' (v5)")
   321  
   322  	// On inserting the 5th record, we expect a total of 3 releases, but we expect version 2
   323  	// (the only deployed release), to still exist
   324  	hist, err := storage.History(name)
   325  	if err != nil {
   326  		t.Fatal(err)
   327  	} else if len(hist) != storage.MaxHistory {
   328  		for _, item := range hist {
   329  			t.Logf("%s %v", item.Name, item.Version)
   330  		}
   331  		t.Fatalf("expected %d items in history, got %d", storage.MaxHistory, len(hist))
   332  	}
   333  
   334  	expectedVersions := map[int32]bool{
   335  		2: true,
   336  		4: true,
   337  		5: true,
   338  	}
   339  
   340  	for _, item := range hist {
   341  		if !expectedVersions[item.GetVersion()] {
   342  			t.Errorf("Release version %d, found when not expected", item.GetVersion())
   343  		}
   344  	}
   345  }
   346  
   347  func TestStorageLast(t *testing.T) {
   348  	storage := Init(driver.NewMemory())
   349  
   350  	const name = "angry-bird"
   351  
   352  	// Set up storage with test releases.
   353  	setup := func() {
   354  		// release records
   355  		rls0 := ReleaseTestData{Name: name, Version: 1, Status: rspb.Status_SUPERSEDED}.ToRelease()
   356  		rls1 := ReleaseTestData{Name: name, Version: 2, Status: rspb.Status_SUPERSEDED}.ToRelease()
   357  		rls2 := ReleaseTestData{Name: name, Version: 3, Status: rspb.Status_SUPERSEDED}.ToRelease()
   358  		rls3 := ReleaseTestData{Name: name, Version: 4, Status: rspb.Status_FAILED}.ToRelease()
   359  
   360  		// create the release records in the storage
   361  		assertErrNil(t.Fatal, storage.Create(rls0), "Storing release 'angry-bird' (v1)")
   362  		assertErrNil(t.Fatal, storage.Create(rls1), "Storing release 'angry-bird' (v2)")
   363  		assertErrNil(t.Fatal, storage.Create(rls2), "Storing release 'angry-bird' (v3)")
   364  		assertErrNil(t.Fatal, storage.Create(rls3), "Storing release 'angry-bird' (v4)")
   365  	}
   366  
   367  	setup()
   368  
   369  	h, err := storage.Last(name)
   370  	if err != nil {
   371  		t.Fatalf("Failed to query for release history (%q): %s\n", name, err)
   372  	}
   373  
   374  	if h.Version != 4 {
   375  		t.Errorf("Expected revision 4, got %d", h.Version)
   376  	}
   377  }
   378  
   379  type ReleaseTestData struct {
   380  	Name      string
   381  	Version   int32
   382  	Manifest  string
   383  	Namespace string
   384  	Status    rspb.Status_Code
   385  }
   386  
   387  func (test ReleaseTestData) ToRelease() *rspb.Release {
   388  	return &rspb.Release{
   389  		Name:      test.Name,
   390  		Version:   test.Version,
   391  		Manifest:  test.Manifest,
   392  		Namespace: test.Namespace,
   393  		Info:      &rspb.Info{Status: &rspb.Status{Code: test.Status}},
   394  	}
   395  }
   396  
   397  func assertErrNil(eh func(args ...interface{}), err error, message string) {
   398  	if err != nil {
   399  		eh(fmt.Sprintf("%s: %q", message, err))
   400  	}
   401  }