diff --git a/pkg/provider.go b/pkg/provider.go index bb41b54..305a475 100644 --- a/pkg/provider.go +++ b/pkg/provider.go @@ -48,6 +48,7 @@ type BucketeerSDK interface { featureID string, defaultValue interface{}, ) model.BKTEvaluationDetails[interface{}] + Close(ctx context.Context) error } type ProviderOptions []bucketeer.Option @@ -324,6 +325,11 @@ func toBucketeerUser(evalCtx openfeature.FlattenedContext) (user.User, *openfeat return bucketeerUser, nil } +// Shutdown closes the SDK +func (p *Provider) Shutdown() { + p.sdk.Close(context.Background()) +} + func ToPtr[T any](v T) *T { return &v } diff --git a/pkg/provider_test.go b/pkg/provider_test.go index 672188e..d9f23b6 100644 --- a/pkg/provider_test.go +++ b/pkg/provider_test.go @@ -846,3 +846,47 @@ func TestGetEvaluationError(t *testing.T) { }) } } + +func TestShutdown(t *testing.T) { + t.Parallel() + tests := []struct { + desc string + setupMock func(mockSDK *mockProvider.MockBucketeerSDK) + }{ + { + desc: "successful shutdown", + setupMock: func(mockSDK *mockProvider.MockBucketeerSDK) { + mockSDK.EXPECT(). + Close(context.Background()). + Return(nil). + Times(1) + }, + }, + { + desc: "shutdown with error from SDK", + setupMock: func(mockSDK *mockProvider.MockBucketeerSDK) { + mockSDK.EXPECT(). + Close(context.Background()). + Return(errors.New("close error")). + Times(1) + }, + }, + } + + for _, test := range tests { + t.Run(test.desc, func(t *testing.T) { + t.Parallel() + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + mockSDK := mockProvider.NewMockBucketeerSDK(ctrl) + + if test.setupMock != nil { + test.setupMock(mockSDK) + } + + provider := newTestProvider(mockSDK) + provider.Shutdown() + }) + } +} diff --git a/test/mock/provider/provider.go b/test/mock/provider/provider.go index 67d66be..b02484e 100644 --- a/test/mock/provider/provider.go +++ b/test/mock/provider/provider.go @@ -56,6 +56,20 @@ func (mr *MockBucketeerSDKMockRecorder) BoolVariationDetails(ctx, arg1, featureI return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "BoolVariationDetails", reflect.TypeOf((*MockBucketeerSDK)(nil).BoolVariationDetails), ctx, arg1, featureID, defaultValue) } +// Close mocks base method. +func (m *MockBucketeerSDK) Close(ctx context.Context) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Close", ctx) + ret0, _ := ret[0].(error) + return ret0 +} + +// Close indicates an expected call of Close. +func (mr *MockBucketeerSDKMockRecorder) Close(ctx any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Close", reflect.TypeOf((*MockBucketeerSDK)(nil).Close), ctx) +} + // Float64VariationDetails mocks base method. func (m *MockBucketeerSDK) Float64VariationDetails(ctx context.Context, arg1 *user.User, featureID string, defaultValue float64) model.BKTEvaluationDetails[float64] { m.ctrl.T.Helper()