fix(pkger): fix flaky test in pkger service tests

tests failign from a data race caused in the tests setup. an incrementing
const needs something to serialzie it (atmoic in this case) to remove that
data race. This touches that up.
pull/16164/head
Johnny Steenbergen 2019-12-06 23:26:25 -08:00 committed by Johnny Steenbergen
parent 0225160814
commit 521ce543eb
8 changed files with 241 additions and 135 deletions

View File

@ -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)
}

View File

@ -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)
}

View File

@ -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)
}

View File

@ -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)
}

36
mock/safe_count.go Normal file
View File

@ -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()
}

View File

@ -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)
}

View File

@ -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)
}

View File

@ -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
})
})
})