github.com/doitroot/helm@v3.0.0-beta.3+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 "helm.sh/helm/pkg/storage"
    18  
    19  import (
    20  	"fmt"
    21  	"reflect"
    22  	"testing"
    23  
    24  	rspb "helm.sh/helm/pkg/release"
    25  	"helm.sh/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 %v, got %v", 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.StatusDeployed,
    59  	}.ToRelease()
    60  
    61  	assertErrNil(t.Fatal, storage.Create(rls), "StoreRelease")
    62  
    63  	// modify the release
    64  	rls.Info.Status = rspb.StatusUninstalled
    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 %v, got %v", 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 %v, got %v", 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.StatusSuperseded}.ToRelease()
   126  		rls1 := ReleaseTestData{Name: "livid-human", Status: rspb.StatusSuperseded}.ToRelease()
   127  		rls2 := ReleaseTestData{Name: "relaxed-cat", Status: rspb.StatusSuperseded}.ToRelease()
   128  		rls3 := ReleaseTestData{Name: "hungry-hippo", Status: rspb.StatusDeployed}.ToRelease()
   129  		rls4 := ReleaseTestData{Name: "angry-beaver", Status: rspb.StatusDeployed}.ToRelease()
   130  		rls5 := ReleaseTestData{Name: "opulent-frog", Status: rspb.StatusUninstalled}.ToRelease()
   131  		rls6 := ReleaseTestData{Name: "happy-liger", Status: rspb.StatusUninstalled}.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  		{"ListDeployed", 2, storage.ListDeployed},
   149  		{"ListReleases", 7, storage.ListReleases},
   150  		{"ListUninstalled", 2, storage.ListUninstalled},
   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 = 4
   173  
   174  	// setup storage with test releases
   175  	setup := func() {
   176  		// release records
   177  		rls0 := ReleaseTestData{Name: name, Version: 1, Status: rspb.StatusSuperseded}.ToRelease()
   178  		rls1 := ReleaseTestData{Name: name, Version: 2, Status: rspb.StatusSuperseded}.ToRelease()
   179  		rls2 := ReleaseTestData{Name: name, Version: 3, Status: rspb.StatusSuperseded}.ToRelease()
   180  		rls3 := ReleaseTestData{Name: name, Version: 4, Status: rspb.StatusDeployed}.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 != rspb.StatusDeployed:
   204  		t.Fatalf("Expected release status 'DEPLOYED', actual %s\n", rls.Info.Status.String())
   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.StatusSuperseded}.ToRelease()
   217  		rls1 := ReleaseTestData{Name: name, Version: 2, Status: rspb.StatusSuperseded}.ToRelease()
   218  		rls2 := ReleaseTestData{Name: name, Version: 3, Status: rspb.StatusSuperseded}.ToRelease()
   219  		rls3 := ReleaseTestData{Name: name, Version: 4, Status: rspb.StatusDeployed}.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.StatusSuperseded}.ToRelease()
   252  		rls1 := ReleaseTestData{Name: name, Version: 2, Status: rspb.StatusSuperseded}.ToRelease()
   253  		rls2 := ReleaseTestData{Name: name, Version: 3, Status: rspb.StatusSuperseded}.ToRelease()
   254  		rls3 := ReleaseTestData{Name: name, Version: 4, Status: rspb.StatusDeployed}.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.StatusDeployed}.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 := 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 TestStorageLast(t *testing.T) {
   297  	storage := Init(driver.NewMemory())
   298  
   299  	const name = "angry-bird"
   300  
   301  	// Set up storage with test releases.
   302  	setup := func() {
   303  		// release records
   304  		rls0 := ReleaseTestData{Name: name, Version: 1, Status: rspb.StatusSuperseded}.ToRelease()
   305  		rls1 := ReleaseTestData{Name: name, Version: 2, Status: rspb.StatusSuperseded}.ToRelease()
   306  		rls2 := ReleaseTestData{Name: name, Version: 3, Status: rspb.StatusSuperseded}.ToRelease()
   307  		rls3 := ReleaseTestData{Name: name, Version: 4, Status: rspb.StatusFailed}.ToRelease()
   308  
   309  		// create the release records in the storage
   310  		assertErrNil(t.Fatal, storage.Create(rls0), "Storing release 'angry-bird' (v1)")
   311  		assertErrNil(t.Fatal, storage.Create(rls1), "Storing release 'angry-bird' (v2)")
   312  		assertErrNil(t.Fatal, storage.Create(rls2), "Storing release 'angry-bird' (v3)")
   313  		assertErrNil(t.Fatal, storage.Create(rls3), "Storing release 'angry-bird' (v4)")
   314  	}
   315  
   316  	setup()
   317  
   318  	h, err := storage.Last(name)
   319  	if err != nil {
   320  		t.Fatalf("Failed to query for release history (%q): %s\n", name, err)
   321  	}
   322  
   323  	if h.Version != 4 {
   324  		t.Errorf("Expected revision 4, got %d", h.Version)
   325  	}
   326  }
   327  
   328  type ReleaseTestData struct {
   329  	Name      string
   330  	Version   int
   331  	Manifest  string
   332  	Namespace string
   333  	Status    rspb.Status
   334  }
   335  
   336  func (test ReleaseTestData) ToRelease() *rspb.Release {
   337  	return &rspb.Release{
   338  		Name:      test.Name,
   339  		Version:   test.Version,
   340  		Manifest:  test.Manifest,
   341  		Namespace: test.Namespace,
   342  		Info:      &rspb.Info{Status: test.Status},
   343  	}
   344  }
   345  
   346  func assertErrNil(eh func(args ...interface{}), err error, message string) {
   347  	if err != nil {
   348  		eh(fmt.Sprintf("%s: %q", message, err))
   349  	}
   350  }