diff --git a/cmd/influxd/launcher/pkger_test.go b/cmd/influxd/launcher/pkger_test.go index 2efe4eac48..9d60a66a67 100644 --- a/cmd/influxd/launcher/pkger_test.go +++ b/cmd/influxd/launcher/pkger_test.go @@ -9,6 +9,7 @@ import ( "github.com/influxdata/influxdb" "github.com/influxdata/influxdb/cmd/influxd/launcher" + "github.com/influxdata/influxdb/mock" "github.com/influxdata/influxdb/pkger" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" @@ -462,19 +463,15 @@ spec: type fakeBucketSVC struct { influxdb.BucketService - countMu sync.Mutex - callCount int - killCount int + updateCallCount mock.SafeCount + killCount int } func (f *fakeBucketSVC) UpdateBucket(ctx context.Context, id influxdb.ID, upd influxdb.BucketUpdate) (*influxdb.Bucket, error) { - f.countMu.Lock() - if f.callCount == f.killCount { - f.countMu.Unlock() + if f.updateCallCount.Count() == f.killCount { return nil, errors.New("reached kill count") } - f.callCount++ - f.countMu.Unlock() + defer f.updateCallCount.IncrFn()() return f.BucketService.UpdateBucket(ctx, id, upd) } diff --git a/mock/bucket_service.go b/mock/bucket_service.go index fd71afd6d3..7d9dcd24e4 100644 --- a/mock/bucket_service.go +++ b/mock/bucket_service.go @@ -15,13 +15,20 @@ type BucketService struct { CloseFn func() error // Methods for an platform.BucketService - FindBucketByIDFn func(context.Context, platform.ID) (*platform.Bucket, error) - FindBucketByNameFn func(context.Context, platform.ID, string) (*platform.Bucket, error) - FindBucketFn func(context.Context, platform.BucketFilter) (*platform.Bucket, error) - FindBucketsFn func(context.Context, platform.BucketFilter, ...platform.FindOptions) ([]*platform.Bucket, int, error) - CreateBucketFn func(context.Context, *platform.Bucket) error - UpdateBucketFn func(context.Context, platform.ID, platform.BucketUpdate) (*platform.Bucket, error) - DeleteBucketFn func(context.Context, platform.ID) error + FindBucketByIDFn func(context.Context, platform.ID) (*platform.Bucket, error) + FindBucketByIDCalls SafeCount + FindBucketByNameFn func(context.Context, platform.ID, string) (*platform.Bucket, error) + FindBucketByNameCalls SafeCount + FindBucketFn func(context.Context, platform.BucketFilter) (*platform.Bucket, error) + FindBucketCalls SafeCount + FindBucketsFn func(context.Context, platform.BucketFilter, ...platform.FindOptions) ([]*platform.Bucket, int, error) + FindBucketsCalls SafeCount + CreateBucketFn func(context.Context, *platform.Bucket) error + CreateBucketCalls SafeCount + UpdateBucketFn func(context.Context, platform.ID, platform.BucketUpdate) (*platform.Bucket, error) + UpdateBucketCalls SafeCount + DeleteBucketFn func(context.Context, platform.ID) error + DeleteBucketCalls SafeCount } // NewBucketService returns a mock BucketService where its methods will return @@ -58,35 +65,42 @@ func (s *BucketService) Close() error { return s.CloseFn() } // FindBucketByID returns a single bucket by ID. func (s *BucketService) FindBucketByID(ctx context.Context, id platform.ID) (*platform.Bucket, error) { + defer s.FindBucketByIDCalls.IncrFn()() return s.FindBucketByIDFn(ctx, id) } // FindBucketByName returns a single bucket by name. func (s *BucketService) FindBucketByName(ctx context.Context, orgID platform.ID, name string) (*platform.Bucket, error) { + defer s.FindBucketByNameCalls.IncrFn()() return s.FindBucketByNameFn(ctx, orgID, name) } // FindBucket returns the first bucket that matches filter. func (s *BucketService) FindBucket(ctx context.Context, filter platform.BucketFilter) (*platform.Bucket, error) { + defer s.FindBucketCalls.IncrFn()() return s.FindBucketFn(ctx, filter) } // FindBuckets returns a list of buckets that match filter and the total count of matching buckets. func (s *BucketService) FindBuckets(ctx context.Context, filter platform.BucketFilter, opts ...platform.FindOptions) ([]*platform.Bucket, int, error) { + defer s.FindBucketsCalls.IncrFn()() return s.FindBucketsFn(ctx, filter, opts...) } // CreateBucket creates a new bucket and sets b.ID with the new identifier. func (s *BucketService) CreateBucket(ctx context.Context, bucket *platform.Bucket) error { + defer s.CreateBucketCalls.IncrFn()() return s.CreateBucketFn(ctx, bucket) } // UpdateBucket updates a single bucket with changeset. func (s *BucketService) UpdateBucket(ctx context.Context, id platform.ID, upd platform.BucketUpdate) (*platform.Bucket, error) { + defer s.UpdateBucketCalls.IncrFn()() return s.UpdateBucketFn(ctx, id, upd) } // DeleteBucket removes a bucket by ID. func (s *BucketService) DeleteBucket(ctx context.Context, id platform.ID) error { + defer s.DeleteBucketCalls.IncrFn()() return s.DeleteBucketFn(ctx, id) } diff --git a/mock/dashboard_service.go b/mock/dashboard_service.go index f80b0ac32c..7c4755e714 100644 --- a/mock/dashboard_service.go +++ b/mock/dashboard_service.go @@ -9,19 +9,31 @@ import ( var _ platform.DashboardService = &DashboardService{} type DashboardService struct { - CreateDashboardF func(context.Context, *platform.Dashboard) error - FindDashboardByIDF func(context.Context, platform.ID) (*platform.Dashboard, error) - FindDashboardsF func(context.Context, platform.DashboardFilter, platform.FindOptions) ([]*platform.Dashboard, int, error) - UpdateDashboardF func(context.Context, platform.ID, platform.DashboardUpdate) (*platform.Dashboard, error) - DeleteDashboardF func(context.Context, platform.ID) error + CreateDashboardF func(context.Context, *platform.Dashboard) error + CreateDashboardCalls SafeCount + FindDashboardByIDF func(context.Context, platform.ID) (*platform.Dashboard, error) + FindDashboardByIDCalls SafeCount + FindDashboardsF func(context.Context, platform.DashboardFilter, platform.FindOptions) ([]*platform.Dashboard, int, error) + FindDashboardsCalls SafeCount + UpdateDashboardF func(context.Context, platform.ID, platform.DashboardUpdate) (*platform.Dashboard, error) + UpdateDashboardCalls SafeCount + DeleteDashboardF func(context.Context, platform.ID) error + DeleteDashboardCalls SafeCount - AddDashboardCellF func(ctx context.Context, id platform.ID, c *platform.Cell, opts platform.AddDashboardCellOptions) error - RemoveDashboardCellF func(ctx context.Context, dashboardID platform.ID, cellID platform.ID) error - GetDashboardCellViewF func(ctx context.Context, dashboardID platform.ID, cellID platform.ID) (*platform.View, error) - UpdateDashboardCellViewF func(ctx context.Context, dashboardID platform.ID, cellID platform.ID, upd platform.ViewUpdate) (*platform.View, error) - UpdateDashboardCellF func(ctx context.Context, dashbaordID platform.ID, cellID platform.ID, upd platform.CellUpdate) (*platform.Cell, error) - CopyDashboardCellF func(ctx context.Context, dashbaordID platform.ID, cellID platform.ID) (*platform.Cell, error) - ReplaceDashboardCellsF func(ctx context.Context, id platform.ID, cs []*platform.Cell) error + AddDashboardCellF func(ctx context.Context, id platform.ID, c *platform.Cell, opts platform.AddDashboardCellOptions) error + AddDashboardCellCalls SafeCount + RemoveDashboardCellF func(ctx context.Context, dashboardID platform.ID, cellID platform.ID) error + RemoveDashboardCellCalls SafeCount + GetDashboardCellViewF func(ctx context.Context, dashboardID platform.ID, cellID platform.ID) (*platform.View, error) + GetDashboardCellViewCalls SafeCount + UpdateDashboardCellViewF func(ctx context.Context, dashboardID platform.ID, cellID platform.ID, upd platform.ViewUpdate) (*platform.View, error) + UpdateDashboardCellViewCalls SafeCount + UpdateDashboardCellF func(ctx context.Context, dashbaordID platform.ID, cellID platform.ID, upd platform.CellUpdate) (*platform.Cell, error) + UpdateDashboardCellCalls SafeCount + CopyDashboardCellF func(ctx context.Context, dashbaordID platform.ID, cellID platform.ID) (*platform.Cell, error) + CopyDashboardCellCalls SafeCount + ReplaceDashboardCellsF func(ctx context.Context, id platform.ID, cs []*platform.Cell) error + ReplaceDashboardCellsCalls SafeCount } // NewDashboardService returns a mock of DashboardService where its methods will return zero values. @@ -58,49 +70,61 @@ func NewDashboardService() *DashboardService { } func (s *DashboardService) FindDashboardByID(ctx context.Context, id platform.ID) (*platform.Dashboard, error) { + defer s.FindDashboardByIDCalls.IncrFn()() return s.FindDashboardByIDF(ctx, id) } func (s *DashboardService) FindDashboards(ctx context.Context, filter platform.DashboardFilter, opts platform.FindOptions) ([]*platform.Dashboard, int, error) { + defer s.FindDashboardsCalls.IncrFn()() return s.FindDashboardsF(ctx, filter, opts) } func (s *DashboardService) CreateDashboard(ctx context.Context, b *platform.Dashboard) error { + defer s.CreateDashboardCalls.IncrFn()() return s.CreateDashboardF(ctx, b) } func (s *DashboardService) UpdateDashboard(ctx context.Context, id platform.ID, upd platform.DashboardUpdate) (*platform.Dashboard, error) { + defer s.UpdateDashboardCalls.IncrFn()() return s.UpdateDashboardF(ctx, id, upd) } func (s *DashboardService) DeleteDashboard(ctx context.Context, id platform.ID) error { + defer s.DeleteDashboardCalls.IncrFn()() return s.DeleteDashboardF(ctx, id) } func (s *DashboardService) GetDashboardCellView(ctx context.Context, dashboardID, cellID platform.ID) (*platform.View, error) { + defer s.GetDashboardCellViewCalls.IncrFn()() return s.GetDashboardCellViewF(ctx, dashboardID, cellID) } func (s *DashboardService) UpdateDashboardCellView(ctx context.Context, dashboardID, cellID platform.ID, upd platform.ViewUpdate) (*platform.View, error) { + defer s.UpdateDashboardCellViewCalls.IncrFn()() return s.UpdateDashboardCellViewF(ctx, dashboardID, cellID, upd) } func (s *DashboardService) AddDashboardCell(ctx context.Context, id platform.ID, c *platform.Cell, opts platform.AddDashboardCellOptions) error { + defer s.AddDashboardCellCalls.IncrFn()() return s.AddDashboardCellF(ctx, id, c, opts) } func (s *DashboardService) ReplaceDashboardCells(ctx context.Context, id platform.ID, cs []*platform.Cell) error { + defer s.ReplaceDashboardCellsCalls.IncrFn()() return s.ReplaceDashboardCellsF(ctx, id, cs) } func (s *DashboardService) RemoveDashboardCell(ctx context.Context, dashboardID platform.ID, cellID platform.ID) error { + defer s.RemoveDashboardCellCalls.IncrFn()() return s.RemoveDashboardCellF(ctx, dashboardID, cellID) } func (s *DashboardService) UpdateDashboardCell(ctx context.Context, dashboardID platform.ID, cellID platform.ID, upd platform.CellUpdate) (*platform.Cell, error) { + defer s.UpdateDashboardCellCalls.IncrFn()() return s.UpdateDashboardCellF(ctx, dashboardID, cellID, upd) } func (s *DashboardService) CopyDashboardCell(ctx context.Context, dashboardID platform.ID, cellID platform.ID) (*platform.Cell, error) { + defer s.CopyDashboardCellCalls.IncrFn()() return s.CopyDashboardCellF(ctx, dashboardID, cellID) } diff --git a/mock/label_service.go b/mock/label_service.go index db4562c3a1..62b0038664 100644 --- a/mock/label_service.go +++ b/mock/label_service.go @@ -10,14 +10,22 @@ var _ platform.LabelService = &LabelService{} // LabelService is a mock implementation of platform.LabelService type LabelService struct { - FindLabelByIDFn func(ctx context.Context, id platform.ID) (*platform.Label, error) - FindLabelsFn func(context.Context, platform.LabelFilter) ([]*platform.Label, error) - FindResourceLabelsFn func(context.Context, platform.LabelMappingFilter) ([]*platform.Label, error) - CreateLabelFn func(context.Context, *platform.Label) error - CreateLabelMappingFn func(context.Context, *platform.LabelMapping) error - UpdateLabelFn func(context.Context, platform.ID, platform.LabelUpdate) (*platform.Label, error) - DeleteLabelFn func(context.Context, platform.ID) error - DeleteLabelMappingFn func(context.Context, *platform.LabelMapping) error + CreateLabelFn func(context.Context, *platform.Label) error + CreateLabelCalls SafeCount + DeleteLabelFn func(context.Context, platform.ID) error + DeleteLabelCalls SafeCount + FindLabelByIDFn func(ctx context.Context, id platform.ID) (*platform.Label, error) + FindLabelByIDCalls SafeCount + FindLabelsFn func(context.Context, platform.LabelFilter) ([]*platform.Label, error) + FindLabelsCalls SafeCount + FindResourceLabelsFn func(context.Context, platform.LabelMappingFilter) ([]*platform.Label, error) + FindResourceLabelsCalls SafeCount + UpdateLabelFn func(context.Context, platform.ID, platform.LabelUpdate) (*platform.Label, error) + UpdateLabelCalls SafeCount + CreateLabelMappingFn func(context.Context, *platform.LabelMapping) error + CreateLabelMappingCalls SafeCount + DeleteLabelMappingFn func(context.Context, *platform.LabelMapping) error + DeleteLabelMappingCalls SafeCount } // NewLabelService returns a mock of LabelService @@ -43,40 +51,48 @@ func NewLabelService() *LabelService { // FindLabelByID finds mappings by their ID func (s *LabelService) FindLabelByID(ctx context.Context, id platform.ID) (*platform.Label, error) { + defer s.FindLabelByIDCalls.IncrFn()() return s.FindLabelByIDFn(ctx, id) } // FindLabels finds mappings that match a given filter. func (s *LabelService) FindLabels(ctx context.Context, filter platform.LabelFilter, opt ...platform.FindOptions) ([]*platform.Label, error) { + defer s.FindLabelsCalls.IncrFn()() return s.FindLabelsFn(ctx, filter) } // FindResourceLabels finds mappings that match a given filter. func (s *LabelService) FindResourceLabels(ctx context.Context, filter platform.LabelMappingFilter) ([]*platform.Label, error) { + defer s.FindResourceLabelsCalls.IncrFn()() return s.FindResourceLabelsFn(ctx, filter) } // CreateLabel creates a new Label. func (s *LabelService) CreateLabel(ctx context.Context, l *platform.Label) error { + defer s.CreateLabelCalls.IncrFn()() return s.CreateLabelFn(ctx, l) } // CreateLabelMapping creates a new Label mapping. func (s *LabelService) CreateLabelMapping(ctx context.Context, m *platform.LabelMapping) error { + defer s.CreateLabelMappingCalls.IncrFn()() return s.CreateLabelMappingFn(ctx, m) } // UpdateLabel updates a label. func (s *LabelService) UpdateLabel(ctx context.Context, id platform.ID, upd platform.LabelUpdate) (*platform.Label, error) { + defer s.UpdateLabelCalls.IncrFn()() return s.UpdateLabelFn(ctx, id, upd) } // DeleteLabel removes a Label. func (s *LabelService) DeleteLabel(ctx context.Context, id platform.ID) error { + defer s.DeleteLabelCalls.IncrFn()() return s.DeleteLabelFn(ctx, id) } // DeleteLabelMapping removes a Label mapping. func (s *LabelService) DeleteLabelMapping(ctx context.Context, m *platform.LabelMapping) error { + defer s.DeleteLabelMappingCalls.IncrFn()() return s.DeleteLabelMappingFn(ctx, m) } diff --git a/mock/safe_count.go b/mock/safe_count.go new file mode 100644 index 0000000000..571fd7dad9 --- /dev/null +++ b/mock/safe_count.go @@ -0,0 +1,36 @@ +package mock + +import ( + "sync" +) + +// SafeCount provides a safe counter, useful for call counts to maintain +// thread safety. Removes burden of having to introduce serialization when +// concurrency is brought in. +type SafeCount struct { + mu sync.Mutex + i int +} + +// IncrFn increments the safe counter by 1. +func (s *SafeCount) IncrFn() func() { + s.mu.Lock() + return func() { + s.i++ + s.mu.Unlock() + } +} + +// Count returns the current count. +func (s *SafeCount) Count() int { + return s.i +} + +// Reset will reset the count to 0. +func (s *SafeCount) Reset() { + s.mu.Lock() + { + s.i = 0 + } + s.mu.Unlock() +} diff --git a/mock/telegraf_service.go b/mock/telegraf_service.go index 8ab4ac1ded..14eb0d7438 100644 --- a/mock/telegraf_service.go +++ b/mock/telegraf_service.go @@ -6,17 +6,21 @@ import ( platform "github.com/influxdata/influxdb" ) -var _ platform.TelegrafConfigStore = &TelegrafConfigStore{} +var _ platform.TelegrafConfigStore = (*TelegrafConfigStore)(nil) // TelegrafConfigStore represents a service for managing telegraf config data. type TelegrafConfigStore struct { *UserResourceMappingService - FindTelegrafConfigByIDF func(ctx context.Context, id platform.ID) (*platform.TelegrafConfig, error) - FindTelegrafConfigF func(ctx context.Context, filter platform.TelegrafConfigFilter) (*platform.TelegrafConfig, error) - FindTelegrafConfigsF func(ctx context.Context, filter platform.TelegrafConfigFilter, opt ...platform.FindOptions) ([]*platform.TelegrafConfig, int, error) - CreateTelegrafConfigF func(ctx context.Context, tc *platform.TelegrafConfig, userID platform.ID) error - UpdateTelegrafConfigF func(ctx context.Context, id platform.ID, tc *platform.TelegrafConfig, userID platform.ID) (*platform.TelegrafConfig, error) - DeleteTelegrafConfigF func(ctx context.Context, id platform.ID) error + FindTelegrafConfigByIDF func(ctx context.Context, id platform.ID) (*platform.TelegrafConfig, error) + FindTelegrafConfigByIDCalls SafeCount + FindTelegrafConfigsF func(ctx context.Context, filter platform.TelegrafConfigFilter, opt ...platform.FindOptions) ([]*platform.TelegrafConfig, int, error) + FindTelegrafConfigsCalls SafeCount + CreateTelegrafConfigF func(ctx context.Context, tc *platform.TelegrafConfig, userID platform.ID) error + CreateTelegrafConfigCalls SafeCount + UpdateTelegrafConfigF func(ctx context.Context, id platform.ID, tc *platform.TelegrafConfig, userID platform.ID) (*platform.TelegrafConfig, error) + UpdateTelegrafConfigCalls SafeCount + DeleteTelegrafConfigF func(ctx context.Context, id platform.ID) error + DeleteTelegrafConfigCalls SafeCount } // NewTelegrafConfigStore constructs a new fake TelegrafConfigStore. @@ -26,9 +30,6 @@ func NewTelegrafConfigStore() *TelegrafConfigStore { FindTelegrafConfigByIDF: func(ctx context.Context, id platform.ID) (*platform.TelegrafConfig, error) { return nil, nil }, - FindTelegrafConfigF: func(_ context.Context, f platform.TelegrafConfigFilter) (*platform.TelegrafConfig, error) { - return nil, nil - }, FindTelegrafConfigsF: func(_ context.Context, f platform.TelegrafConfigFilter, opt ...platform.FindOptions) ([]*platform.TelegrafConfig, int, error) { return nil, 0, nil }, @@ -46,27 +47,32 @@ func NewTelegrafConfigStore() *TelegrafConfigStore { // FindTelegrafConfigByID returns a single telegraf config by ID. func (s *TelegrafConfigStore) FindTelegrafConfigByID(ctx context.Context, id platform.ID) (*platform.TelegrafConfig, error) { + defer s.FindTelegrafConfigByIDCalls.IncrFn()() return s.FindTelegrafConfigByIDF(ctx, id) } // FindTelegrafConfigs returns a list of telegraf configs that match filter and the total count of matching telegraf configs. // Additional options provide pagination & sorting. func (s *TelegrafConfigStore) FindTelegrafConfigs(ctx context.Context, filter platform.TelegrafConfigFilter, opt ...platform.FindOptions) ([]*platform.TelegrafConfig, int, error) { + defer s.FindTelegrafConfigsCalls.IncrFn()() return s.FindTelegrafConfigsF(ctx, filter, opt...) } // CreateTelegrafConfig creates a new telegraf config and sets b.ID with the new identifier. func (s *TelegrafConfigStore) CreateTelegrafConfig(ctx context.Context, tc *platform.TelegrafConfig, userID platform.ID) error { + defer s.CreateTelegrafConfigCalls.IncrFn()() return s.CreateTelegrafConfigF(ctx, tc, userID) } // UpdateTelegrafConfig updates a single telegraf config. // Returns the new telegraf config after update. func (s *TelegrafConfigStore) UpdateTelegrafConfig(ctx context.Context, id platform.ID, tc *platform.TelegrafConfig, userID platform.ID) (*platform.TelegrafConfig, error) { + defer s.UpdateTelegrafConfigCalls.IncrFn()() return s.UpdateTelegrafConfigF(ctx, id, tc, userID) } // DeleteTelegrafConfig removes a telegraf config by ID. func (s *TelegrafConfigStore) DeleteTelegrafConfig(ctx context.Context, id platform.ID) error { + defer s.DeleteTelegrafConfigCalls.IncrFn()() return s.DeleteTelegrafConfigF(ctx, id) } diff --git a/mock/variable_service.go b/mock/variable_service.go index 92e5092db0..d0d9c2d9b6 100644 --- a/mock/variable_service.go +++ b/mock/variable_service.go @@ -9,50 +9,62 @@ import ( var _ platform.VariableService = &VariableService{} type VariableService struct { - FindVariablesF func(context.Context, platform.VariableFilter, ...platform.FindOptions) ([]*platform.Variable, error) - FindVariableByIDF func(context.Context, platform.ID) (*platform.Variable, error) - CreateVariableF func(context.Context, *platform.Variable) error - UpdateVariableF func(ctx context.Context, id platform.ID, update *platform.VariableUpdate) (*platform.Variable, error) - ReplaceVariableF func(context.Context, *platform.Variable) error - DeleteVariableF func(context.Context, platform.ID) error + CreateVariableF func(context.Context, *platform.Variable) error + CreateVariableCalls SafeCount + DeleteVariableF func(context.Context, platform.ID) error + DeleteVariableCalls SafeCount + FindVariableByIDF func(context.Context, platform.ID) (*platform.Variable, error) + FindVariableByIDCalls SafeCount + FindVariablesF func(context.Context, platform.VariableFilter, ...platform.FindOptions) ([]*platform.Variable, error) + FindVariablesCalls SafeCount + ReplaceVariableF func(context.Context, *platform.Variable) error + ReplaceVariableCalls SafeCount + UpdateVariableF func(ctx context.Context, id platform.ID, update *platform.VariableUpdate) (*platform.Variable, error) + UpdateVariableCalls SafeCount } // NewVariableService returns a mock of VariableService where its methods will return zero values. func NewVariableService() *VariableService { return &VariableService{ + CreateVariableF: func(context.Context, *platform.Variable) error { return nil }, + DeleteVariableF: func(context.Context, platform.ID) error { return nil }, + FindVariableByIDF: func(context.Context, platform.ID) (*platform.Variable, error) { return nil, nil }, FindVariablesF: func(context.Context, platform.VariableFilter, ...platform.FindOptions) ([]*platform.Variable, error) { return nil, nil }, - FindVariableByIDF: func(context.Context, platform.ID) (*platform.Variable, error) { return nil, nil }, - CreateVariableF: func(context.Context, *platform.Variable) error { return nil }, + ReplaceVariableF: func(context.Context, *platform.Variable) error { return nil }, UpdateVariableF: func(ctx context.Context, id platform.ID, update *platform.VariableUpdate) (*platform.Variable, error) { return nil, nil }, - ReplaceVariableF: func(context.Context, *platform.Variable) error { return nil }, - DeleteVariableF: func(context.Context, platform.ID) error { return nil }, } } func (s *VariableService) CreateVariable(ctx context.Context, variable *platform.Variable) error { + defer s.CreateVariableCalls.IncrFn()() return s.CreateVariableF(ctx, variable) } func (s *VariableService) ReplaceVariable(ctx context.Context, variable *platform.Variable) error { + defer s.ReplaceVariableCalls.IncrFn()() return s.ReplaceVariableF(ctx, variable) } func (s *VariableService) FindVariables(ctx context.Context, filter platform.VariableFilter, opts ...platform.FindOptions) ([]*platform.Variable, error) { + defer s.FindVariablesCalls.IncrFn()() return s.FindVariablesF(ctx, filter, opts...) } func (s *VariableService) FindVariableByID(ctx context.Context, id platform.ID) (*platform.Variable, error) { + defer s.FindVariableByIDCalls.IncrFn()() return s.FindVariableByIDF(ctx, id) } func (s *VariableService) DeleteVariable(ctx context.Context, id platform.ID) error { + defer s.DeleteVariableCalls.IncrFn()() return s.DeleteVariableF(ctx, id) } func (s *VariableService) UpdateVariable(ctx context.Context, id platform.ID, update *platform.VariableUpdate) (*platform.Variable, error) { + defer s.UpdateVariableCalls.IncrFn()() return s.UpdateVariableF(ctx, id, update) } diff --git a/pkger/service_test.go b/pkger/service_test.go index 41164029b9..a47eb83bd5 100644 --- a/pkger/service_test.go +++ b/pkger/service_test.go @@ -5,7 +5,6 @@ import ( "errors" "math/rand" "strconv" - "sync/atomic" "testing" "time" @@ -276,14 +275,7 @@ func TestService(t *testing.T) { } fakeBktSVC := mock.NewBucketService() - var createCallCount int - fakeBktSVC.CreateBucketFn = func(_ context.Context, b *influxdb.Bucket) error { - createCallCount++ - return nil - } - var updateCallCount int fakeBktSVC.UpdateBucketFn = func(_ context.Context, id influxdb.ID, upd influxdb.BucketUpdate) (*influxdb.Bucket, error) { - updateCallCount++ return &influxdb.Bucket{ID: id}, nil } @@ -299,8 +291,8 @@ func TestService(t *testing.T) { assert.Equal(t, "rucket_11", buck1.Name) assert.Equal(t, time.Hour, buck1.RetentionPeriod) assert.Equal(t, "bucket 1 description", buck1.Description) - assert.Zero(t, createCallCount) - assert.Zero(t, updateCallCount) + assert.Zero(t, fakeBktSVC.CreateBucketCalls.Count()) + assert.Zero(t, fakeBktSVC.UpdateBucketCalls.Count()) }) }) @@ -311,17 +303,10 @@ func TestService(t *testing.T) { // forces the bucket to be created a new return nil, errors.New("an error") } - var c int64 fakeBktSVC.CreateBucketFn = func(_ context.Context, b *influxdb.Bucket) error { - if atomic.LoadInt64(&c) == 2 { + if fakeBktSVC.CreateBucketCalls.Count() == 1 { return errors.New("blowed up ") } - atomic.AddInt64(&c, 1) - return nil - } - var count int - fakeBktSVC.DeleteBucketFn = func(_ context.Context, id influxdb.ID) error { - count++ return nil } @@ -335,7 +320,7 @@ func TestService(t *testing.T) { _, err := svc.Apply(context.TODO(), orgID, pkg) require.Error(t, err) - assert.Equal(t, 2, count) + assert.GreaterOrEqual(t, fakeBktSVC.DeleteBucketCalls.Count(), 1) }) }) }) @@ -380,18 +365,11 @@ func TestService(t *testing.T) { t.Run("rolls back all created labels on an error", func(t *testing.T) { testfileRunner(t, "testdata/label", func(t *testing.T, pkg *Pkg) { fakeLabelSVC := mock.NewLabelService() - var c int64 fakeLabelSVC.CreateLabelFn = func(_ context.Context, l *influxdb.Label) error { - // 4th label will return the error here, and 3 before should be rolled back - if atomic.LoadInt64(&c) == 3 { + // 3rd/4th label will return the error here, and 2 before should be rolled back + if fakeLabelSVC.CreateLabelCalls.Count() == 2 { return errors.New("blowed up ") } - atomic.AddInt64(&c, 1) - return nil - } - var count int - fakeLabelSVC.DeleteLabelFn = func(_ context.Context, id influxdb.ID) error { - count++ return nil } @@ -405,7 +383,7 @@ func TestService(t *testing.T) { _, err := svc.Apply(context.TODO(), orgID, pkg) require.Error(t, err) - assert.Equal(t, 3, count) + assert.GreaterOrEqual(t, fakeLabelSVC.DeleteLabelCalls.Count(), 1) }) }) @@ -427,9 +405,7 @@ func TestService(t *testing.T) { } fakeLabelSVC := mock.NewLabelService() - var createCallCount int fakeLabelSVC.CreateLabelFn = func(_ context.Context, l *influxdb.Label) error { - createCallCount++ if l.Name == "label_2" { l.ID = influxdb.ID(2) return nil @@ -463,7 +439,7 @@ func TestService(t *testing.T) { assert.Equal(t, "#000000", label2.Properties["color"]) assert.Equal(t, "label 2 description", label2.Properties["description"]) - assert.Equal(t, 1, createCallCount) // only called for second label + assert.Equal(t, 1, fakeLabelSVC.CreateLabelCalls.Count()) // only called for second label }) }) }) @@ -472,15 +448,11 @@ func TestService(t *testing.T) { t.Run("successfully creates a dashboard", func(t *testing.T) { testfileRunner(t, "testdata/dashboard.yml", func(t *testing.T, pkg *Pkg) { fakeDashSVC := mock.NewDashboardService() - id := 1 fakeDashSVC.CreateDashboardF = func(_ context.Context, d *influxdb.Dashboard) error { - d.ID = influxdb.ID(id) - id++ + d.ID = influxdb.ID(1) return nil } - viewCalls := 0 fakeDashSVC.UpdateDashboardCellViewF = func(ctx context.Context, dID influxdb.ID, cID influxdb.ID, upd influxdb.ViewUpdate) (*influxdb.View, error) { - viewCalls++ return &influxdb.View{}, nil } @@ -503,14 +475,12 @@ func TestService(t *testing.T) { t.Run("rolls back created dashboard on an error", func(t *testing.T) { testfileRunner(t, "testdata/dashboard.yml", func(t *testing.T, pkg *Pkg) { fakeDashSVC := mock.NewDashboardService() - var c int fakeDashSVC.CreateDashboardF = func(_ context.Context, d *influxdb.Dashboard) error { // error out on second dashboard attempted - if c == 1 { + if fakeDashSVC.CreateDashboardCalls.Count() == 1 { return errors.New("blowed up ") } - c++ - d.ID = influxdb.ID(c) + d.ID = influxdb.ID(1) return nil } deletedDashs := make(map[influxdb.ID]bool) @@ -528,22 +498,20 @@ func TestService(t *testing.T) { _, err := svc.Apply(context.TODO(), orgID, pkg) require.Error(t, err) - assert.True(t, deletedDashs[influxdb.ID(c)]) + assert.True(t, deletedDashs[1]) }) }) }) t.Run("label mapping", func(t *testing.T) { - testLabelMappingFn := func(filename string, numExpected int, settersFn func() []ServiceSetterFn) func(t *testing.T) { - return func(t *testing.T) { - t.Helper() + testLabelMappingFn := func(t *testing.T, filename string, numExpected int, settersFn func() []ServiceSetterFn) { + t.Run("applies successfully", func(t *testing.T) { testfileRunner(t, filename, func(t *testing.T, pkg *Pkg) { fakeLabelSVC := mock.NewLabelService() fakeLabelSVC.CreateLabelFn = func(_ context.Context, l *influxdb.Label) error { l.ID = influxdb.ID(rand.Int()) return nil } - var numLabelMappings int64 fakeLabelSVC.CreateLabelMappingFn = func(_ context.Context, mapping *influxdb.LabelMapping) error { if mapping.ResourceID == 0 { return errors.New("did not get a resource ID") @@ -551,7 +519,6 @@ func TestService(t *testing.T) { if mapping.ResourceType == "" { return errors.New("did not get a resource type") } - atomic.AddInt64(&numLabelMappings, 1) return nil } svc := newTestService(append(settersFn(), @@ -564,13 +531,56 @@ func TestService(t *testing.T) { _, err := svc.Apply(context.TODO(), orgID, pkg) require.NoError(t, err) - assert.Equal(t, numExpected, int(numLabelMappings)) + assert.Equal(t, numExpected, fakeLabelSVC.CreateLabelMappingCalls.Count()) }) - } + }) + + t.Run("deletes new label mappings on error", func(t *testing.T) { + testfileRunner(t, filename, func(t *testing.T, pkg *Pkg) { + for _, l := range pkg.mLabels { + for resource, vals := range l.mappings { + // create extra label mappings, enough for delete to ahve head room + l.mappings[resource] = append(l.mappings[resource], vals...) + l.mappings[resource] = append(l.mappings[resource], vals...) + l.mappings[resource] = append(l.mappings[resource], vals...) + } + } + + fakeLabelSVC := mock.NewLabelService() + fakeLabelSVC.CreateLabelFn = func(_ context.Context, l *influxdb.Label) error { + l.ID = influxdb.ID(fakeLabelSVC.CreateLabelCalls.Count()) + return nil + } + fakeLabelSVC.CreateLabelMappingFn = func(_ context.Context, mapping *influxdb.LabelMapping) error { + if mapping.ResourceID == 0 { + return errors.New("did not get a resource ID") + } + if mapping.ResourceType == "" { + return errors.New("did not get a resource type") + } + if fakeLabelSVC.CreateLabelMappingCalls.Count() > numExpected { + return errors.New("hit last label") + } + return nil + } + svc := newTestService(append(settersFn(), + WithLabelSVC(fakeLabelSVC), + WithLogger(zaptest.NewLogger(t)), + )...) + + orgID := influxdb.ID(9000) + + _, err := svc.Apply(context.TODO(), orgID, pkg) + require.Error(t, err) + + assert.GreaterOrEqual(t, fakeLabelSVC.DeleteLabelMappingCalls.Count(), numExpected) + }) + }) } - t.Run("successfully creates buckets with labels", + t.Run("maps buckets with labels", func(t *testing.T) { testLabelMappingFn( + t, "testdata/bucket_associates_label.yml", 4, func() []ServiceSetterFn { @@ -585,11 +595,12 @@ func TestService(t *testing.T) { } return []ServiceSetterFn{WithBucketSVC(fakeBktSVC)} }, - ), - ) + ) + }) - t.Run("successfully creates dashboards with labels", + t.Run("maps dashboards with labels", func(t *testing.T) { testLabelMappingFn( + t, "testdata/dashboard_associates_label.yml", 1, func() []ServiceSetterFn { @@ -600,11 +611,12 @@ func TestService(t *testing.T) { } return []ServiceSetterFn{WithDashboardSVC(fakeDashSVC)} }, - ), - ) + ) + }) - t.Run("successfully creates telegrafs with labels", + t.Run("maps telegrafs with labels", func(t *testing.T) { testLabelMappingFn( + t, "testdata/telegraf.yml", 1, func() []ServiceSetterFn { @@ -615,11 +627,12 @@ func TestService(t *testing.T) { } return []ServiceSetterFn{WithTelegrafSVC(fakeTeleSVC)} }, - ), - ) + ) + }) - t.Run("successfully creates variables with labels", + t.Run("maps variables with labels", func(t *testing.T) { testLabelMappingFn( + t, "testdata/variable_associates_label.yml", 1, func() []ServiceSetterFn { @@ -630,8 +643,9 @@ func TestService(t *testing.T) { } return []ServiceSetterFn{WithVariableSVC(fakeVarSVC)} }, - ), - ) + ) + }) + }) t.Run("telegrafs", func(t *testing.T) { @@ -659,18 +673,14 @@ func TestService(t *testing.T) { t.Run("rolls back all created telegrafs on an error", func(t *testing.T) { testfileRunner(t, "testdata/telegraf.yml", func(t *testing.T, pkg *Pkg) { fakeTeleSVC := mock.NewTelegrafConfigStore() - var c int fakeTeleSVC.CreateTelegrafConfigF = func(_ context.Context, tc *influxdb.TelegrafConfig, userID influxdb.ID) error { - if c == 1 { + if fakeTeleSVC.CreateTelegrafConfigCalls.Count() == 1 { return errors.New("limit hit") } - c++ - tc.ID = influxdb.ID(c) + tc.ID = influxdb.ID(1) return nil } - var deleteCalls int fakeTeleSVC.DeleteTelegrafConfigF = func(_ context.Context, id influxdb.ID) error { - deleteCalls++ if id != 1 { return errors.New("wrong id here") } @@ -686,7 +696,7 @@ func TestService(t *testing.T) { _, err := svc.Apply(context.TODO(), orgID, pkg) require.Error(t, err) - assert.Equal(t, 1, deleteCalls) + assert.Equal(t, 1, fakeTeleSVC.DeleteTelegrafConfigCalls.Count()) }) }) }) @@ -729,18 +739,11 @@ func TestService(t *testing.T) { t.Run("rolls back all created variables on an error", func(t *testing.T) { testfileRunner(t, "testdata/variables.yml", func(t *testing.T, pkg *Pkg) { fakeVarSVC := mock.NewVariableService() - var c int fakeVarSVC.CreateVariableF = func(_ context.Context, l *influxdb.Variable) error { // 4th variable will return the error here, and 3 before should be rolled back - if c == 3 { + if fakeVarSVC.CreateVariableCalls.Count() == 2 { return errors.New("blowed up ") } - c++ - return nil - } - var count int - fakeVarSVC.DeleteVariableF = func(_ context.Context, id influxdb.ID) error { - count++ return nil } @@ -751,7 +754,7 @@ func TestService(t *testing.T) { _, err := svc.Apply(context.TODO(), orgID, pkg) require.Error(t, err) - assert.Equal(t, 3, count) + assert.GreaterOrEqual(t, fakeVarSVC.DeleteVariableCalls.Count(), 1) }) }) @@ -773,9 +776,7 @@ func TestService(t *testing.T) { } fakeVarSVC := mock.NewVariableService() - var createCallCount int fakeVarSVC.CreateVariableF = func(_ context.Context, l *influxdb.Variable) error { - createCallCount++ if l.Name == "var_const" { return errors.New("shouldn't get here") } @@ -798,7 +799,7 @@ func TestService(t *testing.T) { assert.Equal(t, influxdb.ID(1), expected.ID) assert.Equal(t, "var_const_3", expected.Name) - assert.Equal(t, 3, createCallCount) // only called for last 3 labels + assert.Equal(t, 3, fakeVarSVC.CreateVariableCalls.Count()) // only called for last 3 labels }) }) })