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  }