github.com/kyma-project/kyma-environment-broker@v0.0.1/internal/suspension/handler_test.go (about)

     1  package suspension
     2  
     3  import (
     4  	"testing"
     5  	"time"
     6  
     7  	"github.com/kyma-project/kyma-environment-broker/common/orchestration"
     8  
     9  	"github.com/kyma-project/kyma-environment-broker/internal/storage/dberr"
    10  
    11  	"github.com/kyma-project/kyma-environment-broker/internal"
    12  	"github.com/kyma-project/kyma-environment-broker/internal/broker"
    13  	"github.com/kyma-project/kyma-environment-broker/internal/fixture"
    14  	"github.com/kyma-project/kyma-environment-broker/internal/ptr"
    15  	"github.com/kyma-project/kyma-environment-broker/internal/storage"
    16  	"github.com/pivotal-cf/brokerapi/v8/domain"
    17  	"github.com/sirupsen/logrus"
    18  	"github.com/stretchr/testify/assert"
    19  	"github.com/stretchr/testify/require"
    20  )
    21  
    22  func TestSuspension(t *testing.T) {
    23  	// given
    24  	provisioning := NewDummyQueue()
    25  	deprovisioning := NewDummyQueue()
    26  	st := storage.NewMemoryStorage()
    27  
    28  	svc := NewContextUpdateHandler(st.Operations(), provisioning, deprovisioning, logrus.New())
    29  	instance := fixInstance(fixActiveErsContext())
    30  	st.Instances().Insert(*instance)
    31  
    32  	// when
    33  	changed, err := svc.Handle(instance, fixInactiveErsContext())
    34  	require.NoError(t, err)
    35  	assert.True(t, changed, "handler to change active flag")
    36  
    37  	// then
    38  	op, _ := st.Operations().GetDeprovisioningOperationByInstanceID("instance-id")
    39  	assertQueue(t, deprovisioning, op.ID)
    40  	assertQueue(t, provisioning)
    41  
    42  	assert.Equal(t, domain.LastOperationState("pending"), op.State)
    43  	assert.Equal(t, instance.InstanceID, op.InstanceID)
    44  }
    45  
    46  func TestSuspension_Retrigger(t *testing.T) {
    47  	t.Run("should skip suspension when temporary deprovisioning operation already succeeded", func(t *testing.T) {
    48  		// given
    49  		provisioning := NewDummyQueue()
    50  		deprovisioning := NewDummyQueue()
    51  		st := storage.NewMemoryStorage()
    52  
    53  		svc := NewContextUpdateHandler(st.Operations(), provisioning, deprovisioning, logrus.New())
    54  		instance := fixInstance(fixInactiveErsContext())
    55  		st.Instances().Insert(*instance)
    56  		st.Operations().InsertDeprovisioningOperation(internal.DeprovisioningOperation{
    57  			Operation: internal.Operation{
    58  				ID:         "suspended-op-id",
    59  				Version:    0,
    60  				CreatedAt:  time.Now(),
    61  				UpdatedAt:  time.Now(),
    62  				InstanceID: instance.InstanceID,
    63  				State:      domain.Succeeded,
    64  				Temporary:  true,
    65  				Type:       internal.OperationTypeDeprovision,
    66  			},
    67  		})
    68  
    69  		// when
    70  		changed, err := svc.Handle(instance, fixInactiveErsContext())
    71  		require.NoError(t, err)
    72  		assert.False(t, changed, "handler to not change active flag")
    73  
    74  		// then
    75  		op, _ := st.Operations().GetDeprovisioningOperationByInstanceID("instance-id")
    76  		assertQueue(t, deprovisioning)
    77  		assertQueue(t, provisioning)
    78  
    79  		assert.Equal(t, domain.Succeeded, op.State)
    80  		assert.Equal(t, instance.InstanceID, op.InstanceID)
    81  	})
    82  
    83  	t.Run("should retrigger deprovisioning when existing temporary deprovisioning operation failed", func(t *testing.T) {
    84  		// given
    85  		provisioning := NewDummyQueue()
    86  		deprovisioning := NewDummyQueue()
    87  		st := storage.NewMemoryStorage()
    88  
    89  		svc := NewContextUpdateHandler(st.Operations(), provisioning, deprovisioning, logrus.New())
    90  		instance := fixInstance(fixInactiveErsContext())
    91  		st.Instances().Insert(*instance)
    92  		st.Operations().InsertDeprovisioningOperation(internal.DeprovisioningOperation{
    93  			Operation: internal.Operation{
    94  				ID:         "suspended-op-id",
    95  				Version:    0,
    96  				CreatedAt:  time.Now(),
    97  				UpdatedAt:  time.Now(),
    98  				InstanceID: instance.InstanceID,
    99  				State:      domain.Failed,
   100  				Temporary:  true,
   101  				Type:       internal.OperationTypeDeprovision,
   102  			},
   103  		})
   104  
   105  		// when
   106  		changed, err := svc.Handle(instance, fixInactiveErsContext())
   107  		require.NoError(t, err)
   108  		assert.True(t, changed, "handler to change active flag")
   109  
   110  		// then
   111  		op, _ := st.Operations().GetDeprovisioningOperationByInstanceID("instance-id")
   112  		assertQueue(t, deprovisioning, op.ID)
   113  		assertQueue(t, provisioning)
   114  
   115  		assert.Equal(t, domain.LastOperationState("pending"), op.State)
   116  		assert.Equal(t, instance.InstanceID, op.InstanceID)
   117  	})
   118  
   119  }
   120  
   121  func assertQueue(t *testing.T, q *dummyQueue, id ...string) {
   122  	t.Helper()
   123  	if len(id) == 0 {
   124  		assert.Empty(t, q.IDs)
   125  		return
   126  	}
   127  	assert.Equal(t, q.IDs, id)
   128  }
   129  
   130  func TestUnsuspension(t *testing.T) {
   131  	// given
   132  	provisioning := NewDummyQueue()
   133  	deprovisioning := NewDummyQueue()
   134  	st := storage.NewMemoryStorage()
   135  
   136  	svc := NewContextUpdateHandler(st.Operations(), provisioning, deprovisioning, logrus.New())
   137  	instance := fixInstance(fixInactiveErsContext())
   138  	instance.InstanceDetails.ShootName = "c-012345"
   139  	instance.InstanceDetails.ShootDomain = "c-012345.sap.com"
   140  
   141  	st.Instances().Insert(*instance)
   142  
   143  	deprovisioningOperation := fixture.FixDeprovisioningOperation("d-op", "instance-id")
   144  	deprovisioningOperation.Temporary = true
   145  	st.Operations().InsertDeprovisioningOperation(deprovisioningOperation)
   146  
   147  	// when
   148  	changed, err := svc.Handle(instance, fixActiveErsContext())
   149  	require.NoError(t, err)
   150  	assert.True(t, changed, "handler to change active flag")
   151  
   152  	// then
   153  	op, err := st.Operations().GetProvisioningOperationByInstanceID("instance-id")
   154  	require.NoError(t, err)
   155  	assertQueue(t, deprovisioning)
   156  	assertQueue(t, provisioning, op.ID)
   157  
   158  	assert.Equal(t, domain.LastOperationState(orchestration.Pending), op.State)
   159  	assert.Equal(t, instance.InstanceID, op.InstanceID)
   160  	assert.Equal(t, "c-012345", op.ShootName)
   161  	assert.Equal(t, "c-012345.sap.com", op.ShootDomain)
   162  }
   163  
   164  func TestUnsuspensionForDeprovisioningInstance(t *testing.T) {
   165  	// given
   166  	provisioning := NewDummyQueue()
   167  	deprovisioning := NewDummyQueue()
   168  	st := storage.NewMemoryStorage()
   169  
   170  	svc := NewContextUpdateHandler(st.Operations(), provisioning, deprovisioning, logrus.New())
   171  	instance := fixInstance(fixInactiveErsContext())
   172  	instance.InstanceDetails.ShootName = "c-012345"
   173  	instance.InstanceDetails.ShootDomain = "c-012345.sap.com"
   174  
   175  	st.Instances().Insert(*instance)
   176  	deprovisioningOperation := fixture.FixDeprovisioningOperation("d-op", "instance-id")
   177  	deprovisioningOperation.Temporary = false
   178  	st.Operations().InsertDeprovisioningOperation(deprovisioningOperation)
   179  
   180  	// when
   181  	changed, err := svc.Handle(instance, fixActiveErsContext())
   182  	require.NoError(t, err)
   183  	assert.False(t, changed, "handler to not change active flag")
   184  
   185  	// then
   186  	_, err = st.Operations().GetProvisioningOperationByInstanceID("instance-id")
   187  	assert.True(t, dberr.IsNotFound(err))
   188  	assertQueue(t, deprovisioning)
   189  	assertQueue(t, provisioning)
   190  }
   191  
   192  func TestUnsuspensionForExpiredInstance(t *testing.T) {
   193  	// given
   194  	provisioning := NewDummyQueue()
   195  	deprovisioning := NewDummyQueue()
   196  	st := storage.NewMemoryStorage()
   197  
   198  	svc := NewContextUpdateHandler(st.Operations(), provisioning, deprovisioning, logrus.New())
   199  	instance := fixInstance(fixInactiveErsContext())
   200  	instance.InstanceDetails.ShootName = "c-012345"
   201  	instance.InstanceDetails.ShootDomain = "c-012345.sap.com"
   202  	instance.ExpiredAt = ptr.Time(time.Now())
   203  
   204  	st.Instances().Insert(*instance)
   205  
   206  	// when
   207  	changed, err := svc.Handle(instance, fixActiveErsContext())
   208  	require.NoError(t, err)
   209  	assert.False(t, changed, "handler to not change active flag")
   210  
   211  	// then
   212  	_, err = st.Operations().GetProvisioningOperationByInstanceID("instance-id")
   213  	assert.True(t, dberr.IsNotFound(err))
   214  }
   215  
   216  func fixInstance(ersContext internal.ERSContext) *internal.Instance {
   217  	instance := fixture.FixInstance("instance-id")
   218  	instance.ServicePlanID = broker.TrialPlanID
   219  	instance.Parameters.ErsContext = ersContext
   220  
   221  	return &instance
   222  }
   223  
   224  func fixActiveErsContext() internal.ERSContext {
   225  	return internal.ERSContext{
   226  		Active: ptr.Bool(true),
   227  	}
   228  }
   229  
   230  func fixInactiveErsContext() internal.ERSContext {
   231  	return internal.ERSContext{
   232  		Active: ptr.Bool(false),
   233  	}
   234  }
   235  
   236  type dummyQueue struct {
   237  	IDs []string
   238  }
   239  
   240  func NewDummyQueue() *dummyQueue {
   241  	return &dummyQueue{
   242  		IDs: []string{},
   243  	}
   244  }
   245  
   246  func (q *dummyQueue) Add(id string) {
   247  	q.IDs = append(q.IDs, id)
   248  }