github.com/kyma-project/kyma-environment-broker@v0.0.1/internal/storage/driver/postsql/instance_test.go (about) 1 package postsql_test 2 3 import ( 4 "context" 5 "fmt" 6 "math/rand" 7 "sort" 8 "testing" 9 "time" 10 11 "github.com/kyma-project/kyma-environment-broker/internal/broker" 12 13 "github.com/kyma-project/kyma-environment-broker/internal/ptr" 14 15 "github.com/kyma-project/kyma-environment-broker/common/orchestration" 16 "github.com/kyma-project/kyma-environment-broker/internal" 17 "github.com/kyma-project/kyma-environment-broker/internal/events" 18 "github.com/kyma-project/kyma-environment-broker/internal/fixture" 19 "github.com/kyma-project/kyma-environment-broker/internal/storage" 20 "github.com/kyma-project/kyma-environment-broker/internal/storage/dberr" 21 "github.com/kyma-project/kyma-environment-broker/internal/storage/dbmodel" 22 "github.com/kyma-project/kyma-environment-broker/internal/storage/predicate" 23 "github.com/pivotal-cf/brokerapi/v8/domain" 24 "github.com/sirupsen/logrus" 25 "github.com/stretchr/testify/assert" 26 "github.com/stretchr/testify/require" 27 ) 28 29 func TestInstance(t *testing.T) { 30 31 ctx := context.Background() 32 33 t.Run("Should create and update instance", func(t *testing.T) { 34 containerCleanupFunc, cfg, err := storage.InitTestDBContainer(t.Logf, ctx, "test_DB_1") 35 require.NoError(t, err) 36 defer containerCleanupFunc() 37 38 tablesCleanupFunc, err := storage.InitTestDBTables(t, cfg.ConnectionURL()) 39 require.NoError(t, err) 40 defer tablesCleanupFunc() 41 42 cipher := storage.NewEncrypter(cfg.SecretKey) 43 brokerStorage, _, err := storage.NewFromConfig(cfg, events.Config{Enabled: true}, cipher, logrus.StandardLogger()) 44 require.NoError(t, err) 45 require.NotNil(t, brokerStorage) 46 47 // given 48 testInstanceId := "test" 49 expiredID := "expired-id" 50 fixInstance := fixture.FixInstance(testInstanceId) 51 expiredInstance := fixture.FixInstance(expiredID) 52 expiredInstance.ExpiredAt = ptr.Time(time.Now()) 53 54 err = brokerStorage.Instances().Insert(fixInstance) 55 require.NoError(t, err) 56 err = brokerStorage.Instances().Insert(expiredInstance) 57 require.NoError(t, err) 58 59 fixInstance.DashboardURL = "diff" 60 fixInstance.Provider = "OpenStack" 61 _, err = brokerStorage.Instances().Update(fixInstance) 62 require.NoError(t, err) 63 64 fixProvisioningOperation1 := fixture.FixProvisioningOperation("op-id", fixInstance.InstanceID) 65 66 err = brokerStorage.Operations().InsertOperation(fixProvisioningOperation1) 67 require.NoError(t, err) 68 69 fixProvisioningOperation2 := fixture.FixProvisioningOperation("latest-op-id", fixInstance.InstanceID) 70 71 err = brokerStorage.Operations().InsertOperation(fixProvisioningOperation2) 72 require.NoError(t, err) 73 74 upgradeOperation := fixture.FixUpgradeKymaOperation("operation-id-3", "inst-id") 75 upgradeOperation.State = orchestration.Pending 76 upgradeOperation.CreatedAt = time.Now().Truncate(time.Millisecond).Add(2 * time.Hour) 77 upgradeOperation.UpdatedAt = time.Now().Truncate(time.Millisecond).Add(2 * time.Hour).Add(10 * time.Minute) 78 upgradeOperation.ProvisionerOperationID = "target-op-id" 79 upgradeOperation.Description = "pending-operation" 80 upgradeOperation.Version = 1 81 upgradeOperation.OrchestrationID = "orch-id" 82 upgradeOperation.RuntimeOperation = fixRuntimeOperation("operation-id-3") 83 84 err = brokerStorage.Operations().InsertUpgradeKymaOperation(upgradeOperation) 85 require.NoError(t, err) 86 87 // then 88 inst, err := brokerStorage.Instances().GetByID(testInstanceId) 89 assert.NoError(t, err) 90 expired, err := brokerStorage.Instances().GetByID(expiredID) 91 assert.NoError(t, err) 92 require.NotNil(t, inst) 93 94 assert.Equal(t, fixInstance.InstanceID, inst.InstanceID) 95 assert.Equal(t, fixInstance.RuntimeID, inst.RuntimeID) 96 assert.Equal(t, fixInstance.GlobalAccountID, inst.GlobalAccountID) 97 assert.Equal(t, fixInstance.SubscriptionGlobalAccountID, inst.SubscriptionGlobalAccountID) 98 assert.Equal(t, fixInstance.ServiceID, inst.ServiceID) 99 assert.Equal(t, fixInstance.ServicePlanID, inst.ServicePlanID) 100 assert.Equal(t, fixInstance.DashboardURL, inst.DashboardURL) 101 assert.Equal(t, fixInstance.Parameters, inst.Parameters) 102 assert.Equal(t, fixInstance.Provider, inst.Provider) 103 assert.False(t, inst.IsExpired()) 104 assert.NotEmpty(t, inst.CreatedAt) 105 assert.NotEmpty(t, inst.UpdatedAt) 106 assert.Equal(t, "0001-01-01 00:00:00 +0000 UTC", inst.DeletedAt.String()) 107 assert.True(t, expired.IsExpired()) 108 109 // insert event 110 events.Infof(fixInstance.InstanceID, fixProvisioningOperation2.ID, "some event") 111 events.Errorf(fixInstance.InstanceID, fixProvisioningOperation2.ID, fmt.Errorf(""), "asdasd %s", "") 112 113 // when 114 err = brokerStorage.Instances().Delete(fixInstance.InstanceID) 115 116 // then 117 assert.NoError(t, err) 118 _, err = brokerStorage.Instances().GetByID(fixInstance.InstanceID) 119 assert.True(t, dberr.IsNotFound(err)) 120 121 // when 122 err = brokerStorage.Instances().Delete(fixInstance.InstanceID) 123 assert.NoError(t, err, "deletion non existing instance must not cause any error") 124 }) 125 126 t.Run("Should fetch instance statistics", func(t *testing.T) { 127 containerCleanupFunc, cfg, err := storage.InitTestDBContainer(t.Logf, ctx, "test_DB_1") 128 require.NoError(t, err) 129 defer containerCleanupFunc() 130 131 tablesCleanupFunc, err := storage.InitTestDBTables(t, cfg.ConnectionURL()) 132 require.NoError(t, err) 133 defer tablesCleanupFunc() 134 135 cipher := storage.NewEncrypter(cfg.SecretKey) 136 brokerStorage, _, err := storage.NewFromConfig(cfg, events.Config{}, cipher, logrus.StandardLogger()) 137 require.NoError(t, err) 138 require.NotNil(t, brokerStorage) 139 140 // populate database with samples 141 fixInstances := []internal.Instance{ 142 *fixInstance(instanceData{val: "A1", globalAccountID: "A"}), 143 *fixInstance(instanceData{val: "A2", globalAccountID: "A", deletedAt: time.Time{}}), 144 *fixInstance(instanceData{val: "C1", globalAccountID: "C"}), 145 *fixInstance(instanceData{val: "C2", globalAccountID: "C", deletedAt: time.Now()}), 146 *fixInstance(instanceData{val: "B1", globalAccountID: "B", deletedAt: time.Now()}), 147 } 148 149 for _, i := range fixInstances { 150 err = brokerStorage.Instances().Insert(i) 151 require.NoError(t, err) 152 } 153 154 // when 155 stats, err := brokerStorage.Instances().GetInstanceStats() 156 require.NoError(t, err) 157 numberOfInstancesA, err := brokerStorage.Instances().GetNumberOfInstancesForGlobalAccountID("A") 158 require.NoError(t, err) 159 numberOfInstancesC, err := brokerStorage.Instances().GetNumberOfInstancesForGlobalAccountID("C") 160 require.NoError(t, err) 161 numberOfInstancesB, err := brokerStorage.Instances().GetNumberOfInstancesForGlobalAccountID("B") 162 require.NoError(t, err) 163 164 t.Logf("%+v", stats) 165 166 // then 167 assert.Equal(t, internal.InstanceStats{ 168 TotalNumberOfInstances: 3, 169 PerGlobalAccountID: map[string]int{"A": 2, "C": 1}, 170 }, stats) 171 assert.Equal(t, 2, numberOfInstancesA) 172 assert.Equal(t, 1, numberOfInstancesC) 173 assert.Equal(t, 0, numberOfInstancesB) 174 }) 175 176 t.Run("Should fetch instances along with their operations", func(t *testing.T) { 177 containerCleanupFunc, cfg, err := storage.InitTestDBContainer(t.Logf, ctx, "test_DB_1") 178 require.NoError(t, err) 179 defer containerCleanupFunc() 180 181 tablesCleanupFunc, err := storage.InitTestDBTables(t, cfg.ConnectionURL()) 182 require.NoError(t, err) 183 defer tablesCleanupFunc() 184 185 cipher := storage.NewEncrypter(cfg.SecretKey) 186 brokerStorage, _, err := storage.NewFromConfig(cfg, events.Config{}, cipher, logrus.StandardLogger()) 187 require.NoError(t, err) 188 require.NotNil(t, brokerStorage) 189 190 // populate database with samples 191 fixInstances := []internal.Instance{ 192 *fixInstance(instanceData{val: "A1"}), 193 *fixInstance(instanceData{val: "B1"}), 194 *fixInstance(instanceData{val: "C1"}), 195 } 196 197 for _, i := range fixInstances { 198 err = brokerStorage.Instances().Insert(i) 199 require.NoError(t, err) 200 } 201 202 fixProvisionOps := []internal.Operation{ 203 fixProvisionOperation("A1"), 204 fixProvisionOperation("B1"), 205 fixProvisionOperation("C1"), 206 } 207 208 for _, op := range fixProvisionOps { 209 err = brokerStorage.Operations().InsertOperation(op) 210 require.NoError(t, err) 211 } 212 213 fixDeprovisionOps := []internal.DeprovisioningOperation{ 214 fixDeprovisionOperation("A1"), 215 fixDeprovisionOperation("B1"), 216 fixDeprovisionOperation("C1"), 217 } 218 219 for _, op := range fixDeprovisionOps { 220 err = brokerStorage.Operations().InsertDeprovisioningOperation(op) 221 require.NoError(t, err) 222 } 223 224 // then 225 out, err := brokerStorage.Instances().FindAllJoinedWithOperations(predicate.SortAscByCreatedAt()) 226 require.NoError(t, err) 227 228 require.Len(t, out, 6) 229 230 // checks order of instance, the oldest should be first 231 sorted := sort.SliceIsSorted(out, func(i, j int) bool { 232 return out[i].CreatedAt.Before(out[j].CreatedAt) 233 }) 234 assert.True(t, sorted) 235 236 // ignore time as this is set internally by database so will be different 237 assertInstanceByIgnoreTime(t, fixInstances[0], out[0].Instance) 238 assertInstanceByIgnoreTime(t, fixInstances[0], out[1].Instance) 239 assertInstanceByIgnoreTime(t, fixInstances[1], out[2].Instance) 240 assertInstanceByIgnoreTime(t, fixInstances[1], out[3].Instance) 241 assertInstanceByIgnoreTime(t, fixInstances[2], out[4].Instance) 242 assertInstanceByIgnoreTime(t, fixInstances[2], out[5].Instance) 243 244 assertEqualOperation(t, fixProvisionOps[0], out[0]) 245 assertEqualOperation(t, fixDeprovisionOps[0], out[1]) 246 assertEqualOperation(t, fixProvisionOps[1], out[2]) 247 assertEqualOperation(t, fixDeprovisionOps[1], out[3]) 248 assertEqualOperation(t, fixProvisionOps[2], out[4]) 249 assertEqualOperation(t, fixDeprovisionOps[2], out[5]) 250 }) 251 252 t.Run("Should fetch instances based on subaccount list", func(t *testing.T) { 253 containerCleanupFunc, cfg, err := storage.InitTestDBContainer(t.Logf, ctx, "test_DB_1") 254 require.NoError(t, err) 255 defer containerCleanupFunc() 256 257 tablesCleanupFunc, err := storage.InitTestDBTables(t, cfg.ConnectionURL()) 258 require.NoError(t, err) 259 defer tablesCleanupFunc() 260 261 cipher := storage.NewEncrypter(cfg.SecretKey) 262 brokerStorage, _, err := storage.NewFromConfig(cfg, events.Config{}, cipher, logrus.StandardLogger()) 263 require.NoError(t, err) 264 require.NotNil(t, brokerStorage) 265 266 // populate database with samples 267 subaccounts := []string{"sa1", "sa2", "sa3"} 268 fixInstances := []internal.Instance{ 269 *fixInstance(instanceData{val: "1", subAccountID: subaccounts[0]}), 270 *fixInstance(instanceData{val: "2", subAccountID: "someSU"}), 271 *fixInstance(instanceData{val: "3", subAccountID: subaccounts[1]}), 272 *fixInstance(instanceData{val: "4", subAccountID: subaccounts[2]}), 273 } 274 275 for _, i := range fixInstances { 276 err = brokerStorage.Instances().Insert(i) 277 require.NoError(t, err) 278 } 279 280 // when 281 out, err := brokerStorage.Instances().FindAllInstancesForSubAccounts(subaccounts) 282 283 // then 284 require.NoError(t, err) 285 require.Len(t, out, 3) 286 287 require.Contains(t, []string{"1", "3", "4"}, out[0].InstanceID) 288 require.Contains(t, []string{"1", "3", "4"}, out[1].InstanceID) 289 require.Contains(t, []string{"1", "3", "4"}, out[2].InstanceID) 290 }) 291 292 t.Run("Should list instances based on page and page size", func(t *testing.T) { 293 containerCleanupFunc, cfg, err := storage.InitTestDBContainer(t.Logf, ctx, "test_DB_1") 294 require.NoError(t, err) 295 defer containerCleanupFunc() 296 297 tablesCleanupFunc, err := storage.InitTestDBTables(t, cfg.ConnectionURL()) 298 require.NoError(t, err) 299 defer tablesCleanupFunc() 300 301 cipher := storage.NewEncrypter(cfg.SecretKey) 302 brokerStorage, _, err := storage.NewFromConfig(cfg, events.Config{}, cipher, logrus.StandardLogger()) 303 require.NoError(t, err) 304 require.NotNil(t, brokerStorage) 305 306 // populate database with samples 307 fixInstances := []internal.Instance{ 308 *fixInstance(instanceData{val: "1"}), 309 *fixInstance(instanceData{val: "2"}), 310 *fixInstance(instanceData{val: "3"}), 311 } 312 fixOperations := []internal.Operation{ 313 fixture.FixProvisioningOperation("op1", "1"), 314 fixture.FixProvisioningOperation("op2", "2"), 315 fixture.FixProvisioningOperation("op3", "3"), 316 } 317 for i, v := range fixInstances { 318 v.InstanceDetails = fixture.FixInstanceDetails(v.InstanceID) 319 fixInstances[i] = v 320 fixInstances[i].Reconcilable = true 321 err = brokerStorage.Instances().Insert(v) 322 require.NoError(t, err) 323 } 324 for _, i := range fixOperations { 325 err = brokerStorage.Operations().InsertOperation(i) 326 require.NoError(t, err) 327 } 328 // when 329 out, count, totalCount, err := brokerStorage.Instances().List(dbmodel.InstanceFilter{PageSize: 2, Page: 1}) 330 331 // then 332 require.NoError(t, err) 333 require.Equal(t, 2, count) 334 require.Equal(t, 3, totalCount) 335 336 assertInstanceByIgnoreTime(t, fixInstances[0], out[0]) 337 assertInstanceByIgnoreTime(t, fixInstances[1], out[1]) 338 339 // when 340 out, count, totalCount, err = brokerStorage.Instances().List(dbmodel.InstanceFilter{PageSize: 2, Page: 2}) 341 342 // then 343 require.NoError(t, err) 344 require.Equal(t, 1, count) 345 require.Equal(t, 3, totalCount) 346 347 assert.Equal(t, fixInstances[2].InstanceID, out[0].InstanceID) 348 }) 349 350 t.Run("Should list instances based on filters", func(t *testing.T) { 351 containerCleanupFunc, cfg, err := storage.InitTestDBContainer(t.Logf, ctx, "test_DB_1") 352 require.NoError(t, err) 353 defer containerCleanupFunc() 354 355 tablesCleanupFunc, err := storage.InitTestDBTables(t, cfg.ConnectionURL()) 356 require.NoError(t, err) 357 defer tablesCleanupFunc() 358 359 cipher := storage.NewEncrypter(cfg.SecretKey) 360 brokerStorage, _, err := storage.NewFromConfig(cfg, events.Config{}, cipher, logrus.StandardLogger()) 361 require.NoError(t, err) 362 require.NotNil(t, brokerStorage) 363 364 // populate database with samples 365 fixInstances := []internal.Instance{ 366 *fixInstance(instanceData{val: "inst1"}), 367 *fixInstance(instanceData{val: "inst2"}), 368 *fixInstance(instanceData{val: "inst3"}), 369 *fixInstance(instanceData{val: "expiredinstance", expired: true}), 370 } 371 fixOperations := []internal.Operation{ 372 fixture.FixProvisioningOperation("op1", "inst1"), 373 fixture.FixProvisioningOperation("op2", "inst2"), 374 fixture.FixProvisioningOperation("op3", "inst3"), 375 fixture.FixProvisioningOperation("op4", "expiredinstance"), 376 } 377 for i, v := range fixInstances { 378 v.InstanceDetails = fixture.FixInstanceDetails(v.InstanceID) 379 fixInstances[i] = v 380 err = brokerStorage.Instances().Insert(v) 381 require.NoError(t, err) 382 } 383 for _, i := range fixOperations { 384 err = brokerStorage.Operations().InsertOperation(i) 385 require.NoError(t, err) 386 } 387 // when 388 out, count, totalCount, err := brokerStorage.Instances().List(dbmodel.InstanceFilter{InstanceIDs: []string{fixInstances[0].InstanceID}}) 389 390 // then 391 require.NoError(t, err) 392 require.Equal(t, 1, count) 393 require.Equal(t, 1, totalCount) 394 395 assert.Equal(t, fixInstances[0].InstanceID, out[0].InstanceID) 396 397 // when 398 out, count, totalCount, err = brokerStorage.Instances().List(dbmodel.InstanceFilter{GlobalAccountIDs: []string{fixInstances[1].GlobalAccountID}}) 399 400 // then 401 require.NoError(t, err) 402 require.Equal(t, 1, count) 403 require.Equal(t, 1, totalCount) 404 405 assert.Equal(t, fixInstances[1].InstanceID, out[0].InstanceID) 406 407 // when 408 out, count, totalCount, err = brokerStorage.Instances().List(dbmodel.InstanceFilter{SubAccountIDs: []string{fixInstances[1].SubAccountID}}) 409 410 // then 411 require.NoError(t, err) 412 require.Equal(t, 1, count) 413 require.Equal(t, 1, totalCount) 414 415 assert.Equal(t, fixInstances[1].InstanceID, out[0].InstanceID) 416 417 // when 418 out, count, totalCount, err = brokerStorage.Instances().List(dbmodel.InstanceFilter{RuntimeIDs: []string{fixInstances[1].RuntimeID}}) 419 420 // then 421 require.NoError(t, err) 422 require.Equal(t, 1, count) 423 require.Equal(t, 1, totalCount) 424 425 assert.Equal(t, fixInstances[1].InstanceID, out[0].InstanceID) 426 427 // when 428 out, count, totalCount, err = brokerStorage.Instances().List(dbmodel.InstanceFilter{Plans: []string{fixInstances[1].ServicePlanName}}) 429 430 // then 431 require.NoError(t, err) 432 require.Equal(t, 1, count) 433 require.Equal(t, 1, totalCount) 434 435 assert.Equal(t, fixInstances[1].InstanceID, out[0].InstanceID) 436 437 // when 438 out, count, totalCount, err = brokerStorage.Instances().List(dbmodel.InstanceFilter{Shoots: []string{"Shoot-inst2"}}) 439 440 // then 441 require.NoError(t, err) 442 require.Equal(t, 1, count) 443 require.Equal(t, 1, totalCount) 444 445 assert.Equal(t, fixInstances[1].InstanceID, out[0].InstanceID) 446 447 // when 448 out, count, totalCount, err = brokerStorage.Instances().List(dbmodel.InstanceFilter{Regions: []string{"inst2"}}) 449 450 // then 451 require.NoError(t, err) 452 require.Equal(t, 1, count) 453 require.Equal(t, 1, totalCount) 454 455 assert.Equal(t, fixInstances[1].InstanceID, out[0].InstanceID) 456 457 // when 458 out, count, totalCount, err = brokerStorage.Instances().List(dbmodel.InstanceFilter{Expired: ptr.Bool(true)}) 459 require.NoError(t, err) 460 require.Equal(t, 1, count) 461 require.Equal(t, 1, totalCount) 462 463 assert.Equal(t, fixInstances[3].InstanceID, out[0].InstanceID) 464 465 // when 466 out, count, totalCount, err = brokerStorage.Instances().List(dbmodel.InstanceFilter{Expired: ptr.Bool(false)}) 467 require.NoError(t, err) 468 require.Equal(t, 3, count) 469 require.Equal(t, 3, totalCount) 470 471 }) 472 473 t.Run("Should list instances based on filters", func(t *testing.T) { 474 containerCleanupFunc, cfg, err := storage.InitTestDBContainer(t.Logf, ctx, "test_DB_1") 475 require.NoError(t, err) 476 defer containerCleanupFunc() 477 478 tablesCleanupFunc, err := storage.InitTestDBTables(t, cfg.ConnectionURL()) 479 require.NoError(t, err) 480 defer tablesCleanupFunc() 481 482 cipher := storage.NewEncrypter(cfg.SecretKey) 483 brokerStorage, _, err := storage.NewFromConfig(cfg, events.Config{}, cipher, logrus.StandardLogger()) 484 require.NoError(t, err) 485 require.NotNil(t, brokerStorage) 486 487 // populate database with samples 488 fixInstances := []internal.Instance{ 489 *fixInstance(instanceData{val: "inst1"}), 490 *fixInstance(instanceData{val: "inst2"}), 491 *fixInstance(instanceData{val: "inst3"}), 492 *fixInstance(instanceData{val: "expiredinstance", expired: true}), 493 } 494 fixOperations := []internal.Operation{ 495 fixture.FixProvisioningOperation("op1", "inst1"), 496 fixture.FixProvisioningOperation("op2", "inst2"), 497 fixture.FixProvisioningOperation("op3", "inst3"), 498 fixture.FixProvisioningOperation("op4", "expiredinstance"), 499 } 500 for i, v := range fixInstances { 501 v.InstanceDetails = fixture.FixInstanceDetails(v.InstanceID) 502 fixInstances[i] = v 503 err = brokerStorage.Instances().Insert(v) 504 require.NoError(t, err) 505 } 506 for _, i := range fixOperations { 507 err = brokerStorage.Operations().InsertOperation(i) 508 require.NoError(t, err) 509 } 510 // when 511 out, count, totalCount, err := brokerStorage.Instances().List(dbmodel.InstanceFilter{InstanceIDs: []string{fixInstances[0].InstanceID}}) 512 513 // then 514 require.NoError(t, err) 515 require.Equal(t, 1, count) 516 require.Equal(t, 1, totalCount) 517 518 assert.Equal(t, fixInstances[0].InstanceID, out[0].InstanceID) 519 520 // when 521 out, count, totalCount, err = brokerStorage.Instances().List(dbmodel.InstanceFilter{GlobalAccountIDs: []string{fixInstances[1].GlobalAccountID}}) 522 523 // then 524 require.NoError(t, err) 525 require.Equal(t, 1, count) 526 require.Equal(t, 1, totalCount) 527 528 assert.Equal(t, fixInstances[1].InstanceID, out[0].InstanceID) 529 530 // when 531 out, count, totalCount, err = brokerStorage.Instances().List(dbmodel.InstanceFilter{SubAccountIDs: []string{fixInstances[1].SubAccountID}}) 532 533 // then 534 require.NoError(t, err) 535 require.Equal(t, 1, count) 536 require.Equal(t, 1, totalCount) 537 538 assert.Equal(t, fixInstances[1].InstanceID, out[0].InstanceID) 539 540 // when 541 out, count, totalCount, err = brokerStorage.Instances().List(dbmodel.InstanceFilter{RuntimeIDs: []string{fixInstances[1].RuntimeID}}) 542 543 // then 544 require.NoError(t, err) 545 require.Equal(t, 1, count) 546 require.Equal(t, 1, totalCount) 547 548 assert.Equal(t, fixInstances[1].InstanceID, out[0].InstanceID) 549 550 // when 551 out, count, totalCount, err = brokerStorage.Instances().List(dbmodel.InstanceFilter{Plans: []string{fixInstances[1].ServicePlanName}}) 552 553 // then 554 require.NoError(t, err) 555 require.Equal(t, 1, count) 556 require.Equal(t, 1, totalCount) 557 558 assert.Equal(t, fixInstances[1].InstanceID, out[0].InstanceID) 559 560 // when 561 out, count, totalCount, err = brokerStorage.Instances().List(dbmodel.InstanceFilter{Shoots: []string{"Shoot-inst2"}}) 562 563 // then 564 require.NoError(t, err) 565 require.Equal(t, 1, count) 566 require.Equal(t, 1, totalCount) 567 568 assert.Equal(t, fixInstances[1].InstanceID, out[0].InstanceID) 569 570 // when 571 out, count, totalCount, err = brokerStorage.Instances().List(dbmodel.InstanceFilter{Regions: []string{"inst2"}}) 572 573 // then 574 require.NoError(t, err) 575 require.Equal(t, 1, count) 576 require.Equal(t, 1, totalCount) 577 578 assert.Equal(t, fixInstances[1].InstanceID, out[0].InstanceID) 579 580 // when 581 out, count, totalCount, err = brokerStorage.Instances().List(dbmodel.InstanceFilter{Expired: ptr.Bool(true)}) 582 require.NoError(t, err) 583 require.Equal(t, 1, count) 584 require.Equal(t, 1, totalCount) 585 586 assert.Equal(t, fixInstances[3].InstanceID, out[0].InstanceID) 587 588 // when 589 out, count, totalCount, err = brokerStorage.Instances().List(dbmodel.InstanceFilter{Expired: ptr.Bool(false)}) 590 require.NoError(t, err) 591 require.Equal(t, 3, count) 592 require.Equal(t, 3, totalCount) 593 594 }) 595 596 t.Run("Should list trial instances", func(t *testing.T) { 597 containerCleanupFunc, cfg, err := storage.InitTestDBContainer(t.Logf, ctx, "test_DB_1") 598 require.NoError(t, err) 599 defer containerCleanupFunc() 600 601 tablesCleanupFunc, err := storage.InitTestDBTables(t, cfg.ConnectionURL()) 602 require.NoError(t, err) 603 defer tablesCleanupFunc() 604 605 cipher := storage.NewEncrypter(cfg.SecretKey) 606 brokerStorage, _, err := storage.NewFromConfig(cfg, events.Config{}, cipher, logrus.StandardLogger()) 607 require.NoError(t, err) 608 require.NotNil(t, brokerStorage) 609 610 // populate database with samples 611 inst1 := fixInstance(instanceData{val: "inst1"}) 612 inst2 := fixInstance(instanceData{val: "inst2", trial: true, expired: true}) 613 inst3 := fixInstance(instanceData{val: "inst3", trial: true}) 614 inst4 := fixInstance(instanceData{val: "inst4"}) 615 fixInstances := []internal.Instance{*inst1, *inst2, *inst3, *inst4} 616 617 for _, i := range fixInstances { 618 err = brokerStorage.Instances().Insert(i) 619 require.NoError(t, err) 620 } 621 622 // inst1 is in succeeded state 623 provOp1 := fixProvisionOperation("inst1") 624 provOp1.State = domain.Succeeded 625 err = brokerStorage.Operations().InsertOperation(provOp1) 626 require.NoError(t, err) 627 628 // inst2 is in error state 629 provOp2 := fixProvisionOperation("inst2") 630 provOp2.State = domain.Succeeded 631 err = brokerStorage.Operations().InsertOperation(provOp2) 632 require.NoError(t, err) 633 upgrOp2 := fixUpgradeKymaOperation("inst2") 634 upgrOp2.CreatedAt = upgrOp2.CreatedAt.Add(time.Minute) 635 upgrOp2.State = domain.Failed 636 err = brokerStorage.Operations().InsertUpgradeKymaOperation(upgrOp2) 637 require.NoError(t, err) 638 639 // inst3 is in suspended state 640 provOp3 := fixProvisionOperation("inst3") 641 provOp3.State = domain.Succeeded 642 err = brokerStorage.Operations().InsertOperation(provOp3) 643 require.NoError(t, err) 644 upgrOp3 := fixUpgradeKymaOperation("inst3") 645 upgrOp3.CreatedAt = upgrOp2.CreatedAt.Add(time.Minute) 646 upgrOp3.State = domain.Failed 647 err = brokerStorage.Operations().InsertUpgradeKymaOperation(upgrOp3) 648 require.NoError(t, err) 649 deprovOp3 := fixDeprovisionOperation("inst3") 650 deprovOp3.Temporary = true 651 deprovOp3.State = domain.Succeeded 652 deprovOp3.CreatedAt = deprovOp3.CreatedAt.Add(2 * time.Minute) 653 err = brokerStorage.Operations().InsertDeprovisioningOperation(deprovOp3) 654 require.NoError(t, err) 655 656 // inst4 is in failed state 657 provOp4 := fixProvisionOperation("inst4") 658 provOp4.State = domain.Failed 659 err = brokerStorage.Operations().InsertOperation(provOp4) 660 require.NoError(t, err) 661 662 // when 663 nonExpiredTrialInstancesFilter := dbmodel.InstanceFilter{PlanIDs: []string{broker.TrialPlanID}, Expired: &[]bool{false}[0]} 664 out, count, totalCount, err := brokerStorage.Instances().List(nonExpiredTrialInstancesFilter) 665 666 // then 667 require.NoError(t, err) 668 require.Equal(t, 1, count) 669 require.Equal(t, 1, totalCount) 670 require.Equal(t, inst3.InstanceID, out[0].InstanceID) 671 672 // when 673 trialInstancesFilter := dbmodel.InstanceFilter{PlanIDs: []string{broker.TrialPlanID}} 674 out, count, totalCount, err = brokerStorage.Instances().List(trialInstancesFilter) 675 676 // then 677 require.NoError(t, err) 678 require.Equal(t, 2, count) 679 require.Equal(t, 2, totalCount) 680 require.Equal(t, inst2.InstanceID, out[0].InstanceID) 681 require.Equal(t, inst3.InstanceID, out[1].InstanceID) 682 }) 683 684 t.Run("Should list regular instances and not completely deprovisioned instances", func(t *testing.T) { 685 containerCleanupFunc, cfg, err := storage.InitTestDBContainer(t.Logf, ctx, "test_DB_1") 686 require.NoError(t, err) 687 defer containerCleanupFunc() 688 689 tablesCleanupFunc, err := storage.InitTestDBTables(t, cfg.ConnectionURL()) 690 require.NoError(t, err) 691 defer tablesCleanupFunc() 692 693 cipher := storage.NewEncrypter(cfg.SecretKey) 694 brokerStorage, _, err := storage.NewFromConfig(cfg, events.Config{}, cipher, logrus.StandardLogger()) 695 require.NoError(t, err) 696 require.NotNil(t, brokerStorage) 697 698 // populate database with samples 699 inst1 := fixInstance(instanceData{val: "inst1", deletedAt: time.Now()}) 700 inst2 := fixInstance(instanceData{val: "inst2", trial: true, expired: true, deletedAt: time.Now()}) 701 inst3 := fixInstance(instanceData{val: "inst3", trial: true, deletedAt: time.Time{}}) 702 inst4 := fixInstance(instanceData{val: "inst4", deletedAt: time.Now()}) 703 fixInstances := []internal.Instance{*inst1, *inst2, *inst3, *inst4} 704 705 for _, i := range fixInstances { 706 err = brokerStorage.Instances().Insert(i) 707 require.NoError(t, err) 708 } 709 710 // inst1 is in succeeded state 711 provOp1 := fixProvisionOperation("inst1") 712 provOp1.State = domain.Succeeded 713 err = brokerStorage.Operations().InsertOperation(provOp1) 714 require.NoError(t, err) 715 716 // inst2 is in error state 717 provOp2 := fixProvisionOperation("inst2") 718 provOp2.State = domain.Succeeded 719 err = brokerStorage.Operations().InsertOperation(provOp2) 720 require.NoError(t, err) 721 upgrOp2 := fixUpgradeKymaOperation("inst2") 722 upgrOp2.CreatedAt = upgrOp2.CreatedAt.Add(time.Minute) 723 upgrOp2.State = domain.Failed 724 err = brokerStorage.Operations().InsertUpgradeKymaOperation(upgrOp2) 725 require.NoError(t, err) 726 727 // inst3 is in suspended state 728 provOp3 := fixProvisionOperation("inst3") 729 provOp3.State = domain.Succeeded 730 err = brokerStorage.Operations().InsertOperation(provOp3) 731 require.NoError(t, err) 732 upgrOp3 := fixUpgradeKymaOperation("inst3") 733 upgrOp3.CreatedAt = upgrOp2.CreatedAt.Add(time.Minute) 734 upgrOp3.State = domain.Failed 735 err = brokerStorage.Operations().InsertUpgradeKymaOperation(upgrOp3) 736 require.NoError(t, err) 737 deprovOp3 := fixDeprovisionOperation("inst3") 738 deprovOp3.Temporary = true 739 deprovOp3.State = domain.Succeeded 740 deprovOp3.CreatedAt = deprovOp3.CreatedAt.Add(2 * time.Minute) 741 err = brokerStorage.Operations().InsertDeprovisioningOperation(deprovOp3) 742 require.NoError(t, err) 743 744 // inst4 is in failed state 745 provOp4 := fixProvisionOperation("inst4") 746 provOp4.State = domain.Failed 747 err = brokerStorage.Operations().InsertOperation(provOp4) 748 require.NoError(t, err) 749 750 // when 751 emptyFilter := dbmodel.InstanceFilter{} 752 out, count, _, err := brokerStorage.Instances().List(emptyFilter) 753 var notCompletelyDeleted int 754 for _, instance := range out { 755 if !instance.DeletedAt.IsZero() { 756 notCompletelyDeleted += 1 757 } 758 } 759 760 // then 761 require.NoError(t, err) 762 require.Equal(t, 4, count) 763 require.Equal(t, 3, notCompletelyDeleted) 764 }) 765 766 t.Run("Should list not completely deprovisioned instances", func(t *testing.T) { 767 containerCleanupFunc, cfg, err := storage.InitTestDBContainer(t.Logf, ctx, "test_DB_1") 768 require.NoError(t, err) 769 defer containerCleanupFunc() 770 771 tablesCleanupFunc, err := storage.InitTestDBTables(t, cfg.ConnectionURL()) 772 require.NoError(t, err) 773 defer tablesCleanupFunc() 774 775 cipher := storage.NewEncrypter(cfg.SecretKey) 776 brokerStorage, _, err := storage.NewFromConfig(cfg, events.Config{}, cipher, logrus.StandardLogger()) 777 require.NoError(t, err) 778 require.NotNil(t, brokerStorage) 779 780 // populate database with samples 781 inst1 := fixInstance(instanceData{val: "inst1", deletedAt: time.Now()}) 782 inst2 := fixInstance(instanceData{val: "inst2", trial: true, expired: true, deletedAt: time.Now()}) 783 inst3 := fixInstance(instanceData{val: "inst3", trial: true, deletedAt: time.Time{}}) 784 inst4 := fixInstance(instanceData{val: "inst4", deletedAt: time.Now()}) 785 fixInstances := []internal.Instance{*inst1, *inst2, *inst3, *inst4} 786 787 for _, i := range fixInstances { 788 err = brokerStorage.Instances().Insert(i) 789 require.NoError(t, err) 790 } 791 792 // inst1 is in succeeded state 793 provOp1 := fixProvisionOperation("inst1") 794 provOp1.State = domain.Succeeded 795 err = brokerStorage.Operations().InsertOperation(provOp1) 796 require.NoError(t, err) 797 798 // inst2 is in error state 799 provOp2 := fixProvisionOperation("inst2") 800 provOp2.State = domain.Succeeded 801 err = brokerStorage.Operations().InsertOperation(provOp2) 802 require.NoError(t, err) 803 upgrOp2 := fixUpgradeKymaOperation("inst2") 804 upgrOp2.CreatedAt = upgrOp2.CreatedAt.Add(time.Minute) 805 upgrOp2.State = domain.Failed 806 err = brokerStorage.Operations().InsertUpgradeKymaOperation(upgrOp2) 807 require.NoError(t, err) 808 809 // inst3 is in suspended state 810 provOp3 := fixProvisionOperation("inst3") 811 provOp3.State = domain.Succeeded 812 err = brokerStorage.Operations().InsertOperation(provOp3) 813 require.NoError(t, err) 814 upgrOp3 := fixUpgradeKymaOperation("inst3") 815 upgrOp3.CreatedAt = upgrOp2.CreatedAt.Add(time.Minute) 816 upgrOp3.State = domain.Failed 817 err = brokerStorage.Operations().InsertUpgradeKymaOperation(upgrOp3) 818 require.NoError(t, err) 819 deprovOp3 := fixDeprovisionOperation("inst3") 820 deprovOp3.Temporary = true 821 deprovOp3.State = domain.Succeeded 822 deprovOp3.CreatedAt = deprovOp3.CreatedAt.Add(2 * time.Minute) 823 err = brokerStorage.Operations().InsertDeprovisioningOperation(deprovOp3) 824 require.NoError(t, err) 825 826 // inst4 is in failed state 827 provOp4 := fixProvisionOperation("inst4") 828 provOp4.State = domain.Failed 829 err = brokerStorage.Operations().InsertOperation(provOp4) 830 require.NoError(t, err) 831 832 // when 833 notCompletelyDeletedFilter := dbmodel.InstanceFilter{DeletionAttempted: &[]bool{true}[0]} 834 835 _, notCompletelyDeleted, _, err := brokerStorage.Instances().List(notCompletelyDeletedFilter) 836 837 // then 838 require.NoError(t, err) 839 require.Equal(t, 3, notCompletelyDeleted) 840 }) 841 } 842 843 func assertInstanceByIgnoreTime(t *testing.T, want, got internal.Instance) { 844 t.Helper() 845 want.CreatedAt, got.CreatedAt = time.Time{}, time.Time{} 846 want.UpdatedAt, got.UpdatedAt = time.Time{}, time.Time{} 847 want.DeletedAt, got.DeletedAt = time.Time{}, time.Time{} 848 want.ExpiredAt, got.ExpiredAt = nil, nil 849 850 assert.EqualValues(t, want, got) 851 } 852 853 func assertEqualOperation(t *testing.T, want interface{}, got internal.InstanceWithOperation) { 854 t.Helper() 855 switch want := want.(type) { 856 case internal.ProvisioningOperation: 857 assert.EqualValues(t, internal.OperationTypeProvision, got.Type.String) 858 assert.EqualValues(t, want.State, got.State.String) 859 assert.EqualValues(t, want.Description, got.Description.String) 860 case internal.DeprovisioningOperation: 861 assert.EqualValues(t, internal.OperationTypeDeprovision, got.Type.String) 862 assert.EqualValues(t, want.State, got.State.String) 863 assert.EqualValues(t, want.Description, got.Description.String) 864 } 865 } 866 867 type instanceData struct { 868 val string 869 globalAccountID string 870 subAccountID string 871 expired bool 872 trial bool 873 deletedAt time.Time 874 } 875 876 func fixInstance(testData instanceData) *internal.Instance { 877 var ( 878 gaid string 879 suid string 880 ) 881 882 if testData.globalAccountID != "" { 883 gaid = testData.globalAccountID 884 } else { 885 gaid = testData.val 886 } 887 888 if testData.subAccountID != "" { 889 suid = testData.subAccountID 890 } else { 891 suid = testData.val 892 } 893 894 instance := fixture.FixInstance(testData.val) 895 instance.GlobalAccountID = gaid 896 instance.SubscriptionGlobalAccountID = gaid 897 instance.SubAccountID = suid 898 if testData.trial { 899 instance.ServicePlanID = broker.TrialPlanID 900 instance.ServicePlanName = broker.TrialPlanName 901 } else { 902 instance.ServiceID = testData.val 903 instance.ServiceName = testData.val 904 } 905 instance.ServicePlanName = testData.val 906 instance.DashboardURL = fmt.Sprintf("https://console.%s.kyma.local", testData.val) 907 instance.ProviderRegion = testData.val 908 instance.Parameters.ErsContext.SubAccountID = suid 909 instance.Parameters.ErsContext.GlobalAccountID = gaid 910 instance.InstanceDetails = internal.InstanceDetails{} 911 if testData.expired { 912 instance.ExpiredAt = ptr.Time(time.Now().Add(-10 * time.Hour)) 913 } 914 if !testData.deletedAt.IsZero() { 915 instance.DeletedAt = testData.deletedAt 916 } 917 return &instance 918 } 919 920 func fixRuntimeOperation(operationId string) orchestration.RuntimeOperation { 921 runtime := fixture.FixRuntime("runtime-id") 922 runtimeOperation := fixture.FixRuntimeOperation(operationId) 923 runtimeOperation.Runtime = runtime 924 925 return runtimeOperation 926 } 927 928 func fixProvisionOperation(instanceId string) internal.Operation { 929 operationId := fmt.Sprintf("%s-%d", instanceId, rand.Int()) 930 return fixture.FixProvisioningOperation(operationId, instanceId) 931 932 } 933 func fixDeprovisionOperation(instanceId string) internal.DeprovisioningOperation { 934 operationId := fmt.Sprintf("%s-%d", instanceId, rand.Int()) 935 return fixture.FixDeprovisioningOperation(operationId, instanceId) 936 } 937 938 func fixUpgradeKymaOperation(testData string) internal.UpgradeKymaOperation { 939 operationId := fmt.Sprintf("%s-%d", testData, rand.Int()) 940 return fixture.FixUpgradeKymaOperation(operationId, testData) 941 }