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 }