github.com/kyma-project/kyma-environment-broker@v0.0.1/internal/storage/driver/postsql/conflict_test.go (about)

     1  package postsql_test
     2  
     3  import (
     4  	"context"
     5  	"testing"
     6  	"time"
     7  
     8  	"github.com/kyma-project/kyma-environment-broker/internal"
     9  	"github.com/kyma-project/kyma-environment-broker/internal/events"
    10  	"github.com/kyma-project/kyma-environment-broker/internal/fixture"
    11  	"github.com/kyma-project/kyma-environment-broker/internal/storage"
    12  	"github.com/kyma-project/kyma-environment-broker/internal/storage/dberr"
    13  	"github.com/pivotal-cf/brokerapi/v8/domain"
    14  	"github.com/sirupsen/logrus"
    15  	"github.com/stretchr/testify/assert"
    16  	"github.com/stretchr/testify/require"
    17  )
    18  
    19  func TestConflict(t *testing.T) {
    20  
    21  	ctx := context.Background()
    22  
    23  	t.Run("Conflict Operations", func(t *testing.T) {
    24  
    25  		t.Run("Plain operations - provisioning", func(t *testing.T) {
    26  			containerCleanupFunc, cfg, err := storage.InitTestDBContainer(t.Logf, ctx, "test_DB_1")
    27  			require.NoError(t, err)
    28  
    29  			tablesCleanupFunc, err := storage.InitTestDBTables(t, cfg.ConnectionURL())
    30  			defer tablesCleanupFunc()
    31  			defer containerCleanupFunc()
    32  			require.NoError(t, err)
    33  
    34  			cipher := storage.NewEncrypter(cfg.SecretKey)
    35  			brokerStorage, _, err := storage.NewFromConfig(cfg, events.Config{}, cipher, logrus.StandardLogger())
    36  			require.NoError(t, err)
    37  			require.NotNil(t, brokerStorage)
    38  
    39  			givenOperation := fixture.FixOperation("operation-001", "inst-id", internal.OperationTypeProvision)
    40  			givenOperation.State = domain.InProgress
    41  			givenOperation.ProvisionerOperationID = "target-op-id"
    42  
    43  			svc := brokerStorage.Operations()
    44  
    45  			require.NoError(t, err)
    46  			require.NotNil(t, brokerStorage)
    47  			err = svc.InsertOperation(givenOperation)
    48  			require.NoError(t, err)
    49  
    50  			// when
    51  			gotOperation1, err := svc.GetOperationByID("operation-001")
    52  			require.NoError(t, err)
    53  
    54  			gotOperation2, err := svc.GetOperationByID("operation-001")
    55  			require.NoError(t, err)
    56  
    57  			// when
    58  			gotOperation1.Description = "new modified description 1"
    59  			gotOperation2.Description = "new modified description 2"
    60  			_, err = svc.UpdateOperation(*gotOperation1)
    61  			require.NoError(t, err)
    62  
    63  			_, err = svc.UpdateOperation(*gotOperation2)
    64  
    65  			// then
    66  			assertError(t, dberr.CodeConflict, err)
    67  
    68  			// when
    69  			err = svc.InsertOperation(*gotOperation1)
    70  
    71  			// then
    72  			assertError(t, dberr.CodeAlreadyExists, err)
    73  		})
    74  
    75  		t.Run("Plain operations - deprovisioning", func(t *testing.T) {
    76  			containerCleanupFunc, cfg, err := storage.InitTestDBContainer(t.Logf, ctx, "test_DB_1")
    77  			require.NoError(t, err)
    78  
    79  			tablesCleanupFunc, err := storage.InitTestDBTables(t, cfg.ConnectionURL())
    80  			defer tablesCleanupFunc()
    81  			defer containerCleanupFunc()
    82  			require.NoError(t, err)
    83  
    84  			cipher := storage.NewEncrypter(cfg.SecretKey)
    85  			brokerStorage, _, err := storage.NewFromConfig(cfg, events.Config{}, cipher, logrus.StandardLogger())
    86  			require.NoError(t, err)
    87  			require.NotNil(t, brokerStorage)
    88  
    89  			givenOperation := fixture.FixOperation("operation-001", "inst-id", internal.OperationTypeDeprovision)
    90  			givenOperation.State = domain.InProgress
    91  			givenOperation.ProvisionerOperationID = "target-op-id"
    92  
    93  			svc := brokerStorage.Operations()
    94  
    95  			require.NoError(t, err)
    96  			require.NotNil(t, brokerStorage)
    97  			err = svc.InsertOperation(givenOperation)
    98  			require.NoError(t, err)
    99  
   100  			// when
   101  			gotOperation1, err := svc.GetOperationByID("operation-001")
   102  			require.NoError(t, err)
   103  
   104  			gotOperation2, err := svc.GetOperationByID("operation-001")
   105  			require.NoError(t, err)
   106  
   107  			// when
   108  			gotOperation1.Description = "new modified description 1"
   109  			gotOperation2.Description = "new modified description 2"
   110  			_, err = svc.UpdateOperation(*gotOperation1)
   111  			require.NoError(t, err)
   112  
   113  			_, err = svc.UpdateOperation(*gotOperation2)
   114  
   115  			// then
   116  			assertError(t, dberr.CodeConflict, err)
   117  
   118  			// when
   119  			err = svc.InsertOperation(*gotOperation1)
   120  
   121  			// then
   122  			assertError(t, dberr.CodeAlreadyExists, err)
   123  		})
   124  
   125  		t.Run("Provisioning", func(t *testing.T) {
   126  			containerCleanupFunc, cfg, err := storage.InitTestDBContainer(t.Logf, ctx, "test_DB_1")
   127  			require.NoError(t, err)
   128  
   129  			tablesCleanupFunc, err := storage.InitTestDBTables(t, cfg.ConnectionURL())
   130  			defer tablesCleanupFunc()
   131  			defer containerCleanupFunc()
   132  			require.NoError(t, err)
   133  
   134  			cipher := storage.NewEncrypter(cfg.SecretKey)
   135  			brokerStorage, _, err := storage.NewFromConfig(cfg, events.Config{}, cipher, logrus.StandardLogger())
   136  			require.NoError(t, err)
   137  			require.NotNil(t, brokerStorage)
   138  
   139  			givenOperation := fixture.FixProvisioningOperation("operation-001", "inst-id")
   140  			givenOperation.State = domain.InProgress
   141  			givenOperation.ProvisionerOperationID = "target-op-id"
   142  
   143  			svc := brokerStorage.Operations()
   144  
   145  			require.NoError(t, err)
   146  			require.NotNil(t, brokerStorage)
   147  			err = svc.InsertOperation(givenOperation)
   148  			require.NoError(t, err)
   149  
   150  			// when
   151  			gotOperation1, err := svc.GetProvisioningOperationByID("operation-001")
   152  			require.NoError(t, err)
   153  
   154  			gotOperation2, err := svc.GetProvisioningOperationByID("operation-001")
   155  			require.NoError(t, err)
   156  
   157  			// when
   158  			gotOperation1.Description = "new modified description 1"
   159  			gotOperation2.Description = "new modified description 2"
   160  			_, err = svc.UpdateProvisioningOperation(*gotOperation1)
   161  			require.NoError(t, err)
   162  
   163  			_, err = svc.UpdateProvisioningOperation(*gotOperation2)
   164  
   165  			// then
   166  			assertError(t, dberr.CodeConflict, err)
   167  
   168  			// when
   169  			err = svc.InsertProvisioningOperation(*gotOperation1)
   170  
   171  			// then
   172  			assertError(t, dberr.CodeAlreadyExists, err)
   173  		})
   174  
   175  		t.Run("Deprovisioning", func(t *testing.T) {
   176  			containerCleanupFunc, cfg, err := storage.InitTestDBContainer(t.Logf, ctx, "test_DB_1")
   177  			require.NoError(t, err)
   178  			defer containerCleanupFunc()
   179  
   180  			tablesCleanupFunc, err := storage.InitTestDBTables(t, cfg.ConnectionURL())
   181  			require.NoError(t, err)
   182  			defer tablesCleanupFunc()
   183  
   184  			cipher := storage.NewEncrypter(cfg.SecretKey)
   185  			brokerStorage, _, err := storage.NewFromConfig(cfg, events.Config{}, cipher, logrus.StandardLogger())
   186  			require.NoError(t, err)
   187  			require.NotNil(t, brokerStorage)
   188  
   189  			givenOperation := fixture.FixDeprovisioningOperation("operation-001", "inst-id")
   190  			givenOperation.State = domain.InProgress
   191  			givenOperation.ProvisionerOperationID = "target-op-id"
   192  
   193  			svc := brokerStorage.Deprovisioning()
   194  
   195  			err = svc.InsertDeprovisioningOperation(givenOperation)
   196  			require.NoError(t, err)
   197  
   198  			// when
   199  			gotOperation1, err := svc.GetDeprovisioningOperationByID("operation-001")
   200  			require.NoError(t, err)
   201  
   202  			gotOperation2, err := svc.GetDeprovisioningOperationByID("operation-001")
   203  			require.NoError(t, err)
   204  
   205  			// when
   206  			gotOperation1.Description = "new modified description 1"
   207  			gotOperation2.Description = "new modified description 2"
   208  			_, err = svc.UpdateDeprovisioningOperation(*gotOperation1)
   209  			require.NoError(t, err)
   210  
   211  			_, err = svc.UpdateDeprovisioningOperation(*gotOperation2)
   212  
   213  			// then
   214  			assertError(t, dberr.CodeConflict, err)
   215  
   216  			// when
   217  			err = svc.InsertDeprovisioningOperation(*gotOperation1)
   218  
   219  			// then
   220  			assertError(t, dberr.CodeAlreadyExists, err)
   221  		})
   222  	})
   223  
   224  	t.Run("Conflict Instances", func(t *testing.T) {
   225  		containerCleanupFunc, cfg, err := storage.InitTestDBContainer(t.Logf, ctx, "test_DB_1")
   226  		require.NoError(t, err)
   227  		defer containerCleanupFunc()
   228  
   229  		tablesCleanupFunc, err := storage.InitTestDBTables(t, cfg.ConnectionURL())
   230  		require.NoError(t, err)
   231  		defer tablesCleanupFunc()
   232  
   233  		cipher := storage.NewEncrypter(cfg.SecretKey)
   234  		brokerStorage, _, err := storage.NewFromConfig(cfg, events.Config{}, cipher, logrus.StandardLogger())
   235  		require.NoError(t, err)
   236  		require.NotNil(t, brokerStorage)
   237  
   238  		svc := brokerStorage.Instances()
   239  
   240  		inst := internal.Instance{
   241  			InstanceID:      "abcd-01234",
   242  			RuntimeID:       "r-id-001",
   243  			GlobalAccountID: "ga-001",
   244  			SubAccountID:    "sa-001",
   245  			ServiceID:       "service-id-001",
   246  			ServiceName:     "awesome-service",
   247  			ServicePlanID:   "plan-id",
   248  			ServicePlanName: "awesome-plan",
   249  			DashboardURL:    "",
   250  			Parameters:      internal.ProvisioningParameters{},
   251  			ProviderRegion:  "",
   252  			CreatedAt:       time.Now(),
   253  			Version:         0,
   254  		}
   255  
   256  		err = svc.Insert(inst)
   257  		require.NoError(t, err)
   258  
   259  		// try an update
   260  		inst.DashboardURL = "http://kyma.org"
   261  		newInst, err := svc.Update(inst)
   262  		require.NoError(t, err)
   263  
   264  		// try another update with old version - expect conflict
   265  		inst.DashboardURL = "---"
   266  		_, err = svc.Update(inst)
   267  		require.Error(t, err)
   268  		assert.True(t, dberr.IsConflict(err))
   269  
   270  		// try second update with correct version
   271  		newInst.DashboardURL = "http://new.kyma.com"
   272  		_, err = svc.Update(*newInst)
   273  		require.NoError(t, err)
   274  	})
   275  }
   276  
   277  func assertError(t *testing.T, expectedCode int, err error) {
   278  	require.Error(t, err)
   279  
   280  	dbe, ok := err.(dberr.Error)
   281  	if !ok {
   282  		assert.Fail(t, "expected DB Error Conflict")
   283  	}
   284  	assert.Equal(t, expectedCode, dbe.Code())
   285  }