feat(kv): random ids without comma, space, backslash for org a… (#15049)
feat(kv): random ids without comma, space, backslash for org and bucketpull/15062/head
commit
80e3efa37a
|
@ -36,5 +36,6 @@ func initOrganizationService(f platformtesting.OrganizationFields, t *testing.T)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestOrganizationService(t *testing.T) {
|
func TestOrganizationService(t *testing.T) {
|
||||||
|
t.Skip("organization service no longer used. Remove all of this bolt stuff")
|
||||||
platformtesting.OrganizationService(initOrganizationService, t)
|
platformtesting.OrganizationService(initOrganizationService, t)
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,6 +13,7 @@ import (
|
||||||
|
|
||||||
platform "github.com/influxdata/influxdb"
|
platform "github.com/influxdata/influxdb"
|
||||||
"github.com/influxdata/influxdb/inmem"
|
"github.com/influxdata/influxdb/inmem"
|
||||||
|
"github.com/influxdata/influxdb/kv"
|
||||||
"github.com/influxdata/influxdb/mock"
|
"github.com/influxdata/influxdb/mock"
|
||||||
platformtesting "github.com/influxdata/influxdb/testing"
|
platformtesting "github.com/influxdata/influxdb/testing"
|
||||||
"github.com/julienschmidt/httprouter"
|
"github.com/julienschmidt/httprouter"
|
||||||
|
@ -1075,14 +1076,19 @@ func TestService_handlePostBucketOwner(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func initBucketService(f platformtesting.BucketFields, t *testing.T) (platform.BucketService, string, func()) {
|
func initBucketService(f platformtesting.BucketFields, t *testing.T) (platform.BucketService, string, func()) {
|
||||||
svc := inmem.NewService()
|
svc := kv.NewService(inmem.NewKVStore())
|
||||||
svc.IDGenerator = f.IDGenerator
|
svc.IDGenerator = f.IDGenerator
|
||||||
|
svc.OrgBucketIDs = f.OrgBucketIDs
|
||||||
svc.TimeGenerator = f.TimeGenerator
|
svc.TimeGenerator = f.TimeGenerator
|
||||||
if f.TimeGenerator == nil {
|
if f.TimeGenerator == nil {
|
||||||
svc.TimeGenerator = platform.RealTimeGenerator{}
|
svc.TimeGenerator = platform.RealTimeGenerator{}
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
|
if err := svc.Initialize(ctx); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
for _, o := range f.Organizations {
|
for _, o := range f.Organizations {
|
||||||
if err := svc.PutOrganization(ctx, o); err != nil {
|
if err := svc.PutOrganization(ctx, o); err != nil {
|
||||||
t.Fatalf("failed to populate organizations")
|
t.Fatalf("failed to populate organizations")
|
||||||
|
|
|
@ -14,6 +14,7 @@ import (
|
||||||
|
|
||||||
platform "github.com/influxdata/influxdb"
|
platform "github.com/influxdata/influxdb"
|
||||||
"github.com/influxdata/influxdb/inmem"
|
"github.com/influxdata/influxdb/inmem"
|
||||||
|
"github.com/influxdata/influxdb/kv"
|
||||||
"github.com/influxdata/influxdb/mock"
|
"github.com/influxdata/influxdb/mock"
|
||||||
platformtesting "github.com/influxdata/influxdb/testing"
|
platformtesting "github.com/influxdata/influxdb/testing"
|
||||||
)
|
)
|
||||||
|
@ -34,14 +35,19 @@ func NewMockOrgBackend() *OrgBackend {
|
||||||
|
|
||||||
func initOrganizationService(f platformtesting.OrganizationFields, t *testing.T) (platform.OrganizationService, string, func()) {
|
func initOrganizationService(f platformtesting.OrganizationFields, t *testing.T) (platform.OrganizationService, string, func()) {
|
||||||
t.Helper()
|
t.Helper()
|
||||||
svc := inmem.NewService()
|
svc := kv.NewService(inmem.NewKVStore())
|
||||||
svc.IDGenerator = f.IDGenerator
|
svc.IDGenerator = f.IDGenerator
|
||||||
|
svc.OrgBucketIDs = f.OrgBucketIDs
|
||||||
svc.TimeGenerator = f.TimeGenerator
|
svc.TimeGenerator = f.TimeGenerator
|
||||||
if f.TimeGenerator == nil {
|
if f.TimeGenerator == nil {
|
||||||
svc.TimeGenerator = platform.RealTimeGenerator{}
|
svc.TimeGenerator = platform.RealTimeGenerator{}
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
|
if err := svc.Initialize(ctx); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
for _, o := range f.Organizations {
|
for _, o := range f.Organizations {
|
||||||
if err := svc.PutOrganization(ctx, o); err != nil {
|
if err := svc.PutOrganization(ctx, o); err != nil {
|
||||||
t.Fatalf("failed to populate organizations")
|
t.Fatalf("failed to populate organizations")
|
||||||
|
@ -62,6 +68,7 @@ func initOrganizationService(f platformtesting.OrganizationFields, t *testing.T)
|
||||||
return &client, inmem.OpPrefix, done
|
return &client, inmem.OpPrefix, done
|
||||||
}
|
}
|
||||||
func TestOrganizationService(t *testing.T) {
|
func TestOrganizationService(t *testing.T) {
|
||||||
|
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
platformtesting.OrganizationService(initOrganizationService, t)
|
platformtesting.OrganizationService(initOrganizationService, t)
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,5 +30,6 @@ func initBucketService(f platformtesting.BucketFields, t *testing.T) (platform.B
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestBucketService(t *testing.T) {
|
func TestBucketService(t *testing.T) {
|
||||||
|
t.Skip("bucket service no longer used. Remove all of this inmem stuff")
|
||||||
platformtesting.BucketService(initBucketService, t)
|
platformtesting.BucketService(initBucketService, t)
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,5 +25,6 @@ func initOrganizationService(f platformtesting.OrganizationFields, t *testing.T)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestOrganizationService(t *testing.T) {
|
func TestOrganizationService(t *testing.T) {
|
||||||
|
t.Skip("organization service no longer used. Remove all of this inmem stuff")
|
||||||
platformtesting.OrganizationService(initOrganizationService, t)
|
platformtesting.OrganizationService(initOrganizationService, t)
|
||||||
}
|
}
|
||||||
|
|
13
kv/bucket.go
13
kv/bucket.go
|
@ -3,7 +3,6 @@ package kv
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"errors"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
@ -425,7 +424,7 @@ func (s *Service) createBucket(ctx context.Context, tx Tx, b *influxdb.Bucket) (
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if b.ID, err = s.generateBucketID(); err != nil {
|
if b.ID, err = s.generateBucketID(ctx, tx); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -448,14 +447,8 @@ func (s *Service) createBucket(ctx context.Context, tx Tx, b *influxdb.Bucket) (
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Service) generateBucketID() (influxdb.ID, error) {
|
func (s *Service) generateBucketID(ctx context.Context, tx Tx) (influxdb.ID, error) {
|
||||||
for i := 0; i < MaxIDGenerationN; i++ {
|
return s.generateSafeID(ctx, tx, bucketBucket)
|
||||||
id := s.IDGenerator.ID()
|
|
||||||
if s.IsValidOrgBucketID == nil || s.IsValidOrgBucketID(id) {
|
|
||||||
return id, nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return 0, errors.New("unable to generate valid bucket id")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// PutBucket will put a bucket without setting an ID.
|
// PutBucket will put a bucket without setting an ID.
|
||||||
|
|
|
@ -5,7 +5,6 @@ import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/influxdata/influxdb"
|
"github.com/influxdata/influxdb"
|
||||||
"github.com/influxdata/influxdb/inmem"
|
|
||||||
"github.com/influxdata/influxdb/kv"
|
"github.com/influxdata/influxdb/kv"
|
||||||
influxdbtesting "github.com/influxdata/influxdb/testing"
|
influxdbtesting "github.com/influxdata/influxdb/testing"
|
||||||
)
|
)
|
||||||
|
@ -46,6 +45,7 @@ func initInmemBucketService(f influxdbtesting.BucketFields, t *testing.T) (influ
|
||||||
|
|
||||||
func initBucketService(s kv.Store, f influxdbtesting.BucketFields, t *testing.T) (influxdb.BucketService, string, func()) {
|
func initBucketService(s kv.Store, f influxdbtesting.BucketFields, t *testing.T) (influxdb.BucketService, string, func()) {
|
||||||
svc := kv.NewService(s)
|
svc := kv.NewService(s)
|
||||||
|
svc.OrgBucketIDs = f.OrgBucketIDs
|
||||||
svc.IDGenerator = f.IDGenerator
|
svc.IDGenerator = f.IDGenerator
|
||||||
svc.TimeGenerator = f.TimeGenerator
|
svc.TimeGenerator = f.TimeGenerator
|
||||||
if f.TimeGenerator == nil {
|
if f.TimeGenerator == nil {
|
||||||
|
@ -79,16 +79,3 @@ func initBucketService(s kv.Store, f influxdbtesting.BucketFields, t *testing.T)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestService_CreateBucket(t *testing.T) {
|
|
||||||
t.Run("InvalidBucketID", func(t *testing.T) {
|
|
||||||
svc := kv.NewService(inmem.NewKVStore())
|
|
||||||
if err := svc.PutOrganization(context.Background(), &influxdb.Organization{ID: 123, Name: "ORG"}); err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
svc.IsValidOrgBucketID = func(id influxdb.ID) bool { return false }
|
|
||||||
if err := svc.CreateBucket(context.Background(), &influxdb.Bucket{OrgID: 123, Name: "BUCKET"}); err == nil || err.Error() != `unable to generate valid bucket id` {
|
|
||||||
t.Fatalf("unexpected error: %s", err)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
|
@ -11,7 +11,7 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
testID = influxdb.ID(1)
|
testID = influxdb.ID(10000)
|
||||||
testIDStr = testID.String()
|
testIDStr = testID.String()
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -84,9 +84,11 @@ func testLookupName(newStore StoreFn, t *testing.T) {
|
||||||
ID: influxdbtesting.IDPtr(testID),
|
ID: influxdbtesting.IDPtr(testID),
|
||||||
},
|
},
|
||||||
init: func(ctx context.Context, s *kv.Service) error {
|
init: func(ctx context.Context, s *kv.Service) error {
|
||||||
_ = s.CreateOrganization(ctx, &influxdb.Organization{
|
o1 := &influxdb.Organization{
|
||||||
Name: "o1",
|
Name: "o1",
|
||||||
})
|
}
|
||||||
|
_ = s.CreateOrganization(ctx, o1)
|
||||||
|
t.Log(o1)
|
||||||
return s.CreateBucket(ctx, &influxdb.Bucket{
|
return s.CreateBucket(ctx, &influxdb.Bucket{
|
||||||
Name: "b1",
|
Name: "b1",
|
||||||
OrgID: testID,
|
OrgID: testID,
|
||||||
|
@ -243,6 +245,7 @@ func testLookupName(newStore StoreFn, t *testing.T) {
|
||||||
defer done()
|
defer done()
|
||||||
|
|
||||||
svc.IDGenerator = mock.NewIDGenerator(testIDStr, t)
|
svc.IDGenerator = mock.NewIDGenerator(testIDStr, t)
|
||||||
|
svc.WithSpecialOrgBucketIDs(svc.IDGenerator)
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
if tt.args.init != nil {
|
if tt.args.init != nil {
|
||||||
if err := tt.args.init(ctx, svc); err != nil {
|
if err := tt.args.init(ctx, svc); err != nil {
|
||||||
|
|
|
@ -46,6 +46,7 @@ func initInmemOnboardingService(f influxdbtesting.OnboardingFields, t *testing.T
|
||||||
func initOnboardingService(s kv.Store, f influxdbtesting.OnboardingFields, t *testing.T) (influxdb.OnboardingService, func()) {
|
func initOnboardingService(s kv.Store, f influxdbtesting.OnboardingFields, t *testing.T) (influxdb.OnboardingService, func()) {
|
||||||
svc := kv.NewService(s)
|
svc := kv.NewService(s)
|
||||||
svc.IDGenerator = f.IDGenerator
|
svc.IDGenerator = f.IDGenerator
|
||||||
|
svc.OrgBucketIDs = f.IDGenerator
|
||||||
svc.TokenGenerator = f.TokenGenerator
|
svc.TokenGenerator = f.TokenGenerator
|
||||||
svc.TimeGenerator = f.TimeGenerator
|
svc.TimeGenerator = f.TimeGenerator
|
||||||
if f.TimeGenerator == nil {
|
if f.TimeGenerator == nil {
|
||||||
|
|
27
kv/org.go
27
kv/org.go
|
@ -3,7 +3,6 @@ package kv
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"errors"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
@ -15,14 +14,26 @@ import (
|
||||||
"github.com/influxdata/influxdb/kit/tracing"
|
"github.com/influxdata/influxdb/kit/tracing"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
// MaxIDGenerationN is the maximum number of times an ID generation is done before failing.
|
// MaxIDGenerationN is the maximum number of times an ID generation is done before failing.
|
||||||
const MaxIDGenerationN = 100
|
MaxIDGenerationN = 100
|
||||||
|
// ReservedIDs are the number of IDs reserved from 1 - ReservedIDs we use
|
||||||
|
// for our system org/buckets
|
||||||
|
ReservedIDs = 1000
|
||||||
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
organizationBucket = []byte("organizationsv1")
|
organizationBucket = []byte("organizationsv1")
|
||||||
organizationIndex = []byte("organizationindexv1")
|
organizationIndex = []byte("organizationindexv1")
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// ErrFailureGeneratingID occurs ony when the random number generator
|
||||||
|
// cannot generate an ID in MaxIDGenerationN times.
|
||||||
|
var ErrFailureGeneratingID = &influxdb.Error{
|
||||||
|
Code: influxdb.EInternal,
|
||||||
|
Msg: "unable to generate valid id",
|
||||||
|
}
|
||||||
|
|
||||||
var _ influxdb.OrganizationService = (*Service)(nil)
|
var _ influxdb.OrganizationService = (*Service)(nil)
|
||||||
var _ influxdb.OrganizationOperationLogService = (*Service)(nil)
|
var _ influxdb.OrganizationOperationLogService = (*Service)(nil)
|
||||||
|
|
||||||
|
@ -271,7 +282,7 @@ func (s *Service) createOrganization(ctx context.Context, tx Tx, o *influxdb.Org
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if o.ID, err = s.generateOrgID(); err != nil {
|
if o.ID, err = s.generateOrgID(ctx, tx); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
o.CreatedAt = s.Now()
|
o.CreatedAt = s.Now()
|
||||||
|
@ -290,14 +301,8 @@ func (s *Service) createOrganization(ctx context.Context, tx Tx, o *influxdb.Org
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Service) generateOrgID() (influxdb.ID, error) {
|
func (s *Service) generateOrgID(ctx context.Context, tx Tx) (influxdb.ID, error) {
|
||||||
for i := 0; i < MaxIDGenerationN; i++ {
|
return s.generateSafeID(ctx, tx, organizationBucket)
|
||||||
id := s.IDGenerator.ID()
|
|
||||||
if s.IsValidOrgBucketID == nil || s.IsValidOrgBucketID(id) {
|
|
||||||
return id, nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return 0, errors.New("unable to generate valid org id")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// PutOrganization will put a organization without setting an ID.
|
// PutOrganization will put a organization without setting an ID.
|
||||||
|
|
|
@ -5,7 +5,6 @@ import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/influxdata/influxdb"
|
"github.com/influxdata/influxdb"
|
||||||
"github.com/influxdata/influxdb/inmem"
|
|
||||||
"github.com/influxdata/influxdb/kv"
|
"github.com/influxdata/influxdb/kv"
|
||||||
influxdbtesting "github.com/influxdata/influxdb/testing"
|
influxdbtesting "github.com/influxdata/influxdb/testing"
|
||||||
)
|
)
|
||||||
|
@ -46,6 +45,7 @@ func initInmemOrganizationService(f influxdbtesting.OrganizationFields, t *testi
|
||||||
|
|
||||||
func initOrganizationService(s kv.Store, f influxdbtesting.OrganizationFields, t *testing.T) (influxdb.OrganizationService, string, func()) {
|
func initOrganizationService(s kv.Store, f influxdbtesting.OrganizationFields, t *testing.T) (influxdb.OrganizationService, string, func()) {
|
||||||
svc := kv.NewService(s)
|
svc := kv.NewService(s)
|
||||||
|
svc.OrgBucketIDs = f.OrgBucketIDs
|
||||||
svc.IDGenerator = f.IDGenerator
|
svc.IDGenerator = f.IDGenerator
|
||||||
svc.TimeGenerator = f.TimeGenerator
|
svc.TimeGenerator = f.TimeGenerator
|
||||||
if f.TimeGenerator == nil {
|
if f.TimeGenerator == nil {
|
||||||
|
@ -71,13 +71,3 @@ func initOrganizationService(s kv.Store, f influxdbtesting.OrganizationFields, t
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestService_CreateOrganization(t *testing.T) {
|
|
||||||
t.Run("InvalidOrgID", func(t *testing.T) {
|
|
||||||
svc := kv.NewService(inmem.NewKVStore())
|
|
||||||
svc.IsValidOrgBucketID = func(id influxdb.ID) bool { return false }
|
|
||||||
if err := svc.CreateOrganization(context.Background(), &influxdb.Organization{Name: "ORG"}); err == nil || err.Error() != `unable to generate valid org id` {
|
|
||||||
t.Fatalf("unexpected error: %#v", err)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
|
@ -25,12 +25,15 @@ type Service struct {
|
||||||
Config ServiceConfig
|
Config ServiceConfig
|
||||||
|
|
||||||
IDGenerator influxdb.IDGenerator
|
IDGenerator influxdb.IDGenerator
|
||||||
|
|
||||||
|
// special ID generator that never returns bytes with backslash,
|
||||||
|
// comma, or space. Used to support very specific encoding of org &
|
||||||
|
// bucket into the old measurement in storage.
|
||||||
|
OrgBucketIDs influxdb.IDGenerator
|
||||||
|
|
||||||
TokenGenerator influxdb.TokenGenerator
|
TokenGenerator influxdb.TokenGenerator
|
||||||
influxdb.TimeGenerator
|
influxdb.TimeGenerator
|
||||||
Hash Crypt
|
Hash Crypt
|
||||||
|
|
||||||
// Organization & bucket specific validation.
|
|
||||||
IsValidOrgBucketID func(influxdb.ID) bool
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewService returns an instance of a Service.
|
// NewService returns an instance of a Service.
|
||||||
|
@ -38,6 +41,8 @@ func NewService(kv Store, configs ...ServiceConfig) *Service {
|
||||||
s := &Service{
|
s := &Service{
|
||||||
Logger: zap.NewNop(),
|
Logger: zap.NewNop(),
|
||||||
IDGenerator: snowflake.NewIDGenerator(),
|
IDGenerator: snowflake.NewIDGenerator(),
|
||||||
|
// Seed the random number generator with the current time
|
||||||
|
OrgBucketIDs: rand.NewOrgBucketID(time.Now().UnixNano()),
|
||||||
TokenGenerator: rand.NewTokenGenerator(64),
|
TokenGenerator: rand.NewTokenGenerator(64),
|
||||||
Hash: &Bcrypt{},
|
Hash: &Bcrypt{},
|
||||||
kv: kv,
|
kv: kv,
|
||||||
|
@ -150,3 +155,11 @@ func (s *Service) Initialize(ctx context.Context) error {
|
||||||
func (s *Service) WithStore(store Store) {
|
func (s *Service) WithStore(store Store) {
|
||||||
s.kv = store
|
s.kv = store
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// WithSpecialOrgBucketIDs sets the generator for the org
|
||||||
|
// and bucket ids.
|
||||||
|
//
|
||||||
|
// Should only be used in tests for mocking.
|
||||||
|
func (s *Service) WithSpecialOrgBucketIDs(gen influxdb.IDGenerator) {
|
||||||
|
s.OrgBucketIDs = gen
|
||||||
|
}
|
||||||
|
|
59
kv/unique.go
59
kv/unique.go
|
@ -5,6 +5,7 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
influxdb "github.com/influxdata/influxdb"
|
influxdb "github.com/influxdata/influxdb"
|
||||||
|
"github.com/influxdata/influxdb/kit/tracing"
|
||||||
)
|
)
|
||||||
|
|
||||||
// UnexpectedIndexError is used when the error comes from an internal system.
|
// UnexpectedIndexError is used when the error comes from an internal system.
|
||||||
|
@ -20,7 +21,14 @@ func UnexpectedIndexError(err error) *influxdb.Error {
|
||||||
// exists.
|
// exists.
|
||||||
var NotUniqueError = &influxdb.Error{
|
var NotUniqueError = &influxdb.Error{
|
||||||
Code: influxdb.EConflict,
|
Code: influxdb.EConflict,
|
||||||
Msg: fmt.Sprintf("name already exists"),
|
Msg: "name already exists",
|
||||||
|
}
|
||||||
|
|
||||||
|
// NotUniqueIDError is used when attempting to create an org or bucket that already
|
||||||
|
// exists.
|
||||||
|
var NotUniqueIDError = &influxdb.Error{
|
||||||
|
Code: influxdb.EConflict,
|
||||||
|
Msg: "ID already exists",
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Service) unique(ctx context.Context, tx Tx, indexBucket, indexKey []byte) error {
|
func (s *Service) unique(ctx context.Context, tx Tx, indexBucket, indexKey []byte) error {
|
||||||
|
@ -43,3 +51,52 @@ func (s *Service) unique(ctx context.Context, tx Tx, indexBucket, indexKey []byt
|
||||||
// any other error is some sort of internal server error
|
// any other error is some sort of internal server error
|
||||||
return UnexpectedIndexError(err)
|
return UnexpectedIndexError(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *Service) uniqueID(ctx context.Context, tx Tx, bucket []byte, id influxdb.ID) error {
|
||||||
|
span, _ := tracing.StartSpanFromContext(ctx)
|
||||||
|
defer span.Finish()
|
||||||
|
|
||||||
|
encodedID, err := id.Encode()
|
||||||
|
if err != nil {
|
||||||
|
return &influxdb.Error{
|
||||||
|
Code: influxdb.EInvalid,
|
||||||
|
Err: err,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
b, err := tx.Bucket(bucket)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = b.Get(encodedID)
|
||||||
|
if IsNotFound(err) {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return NotUniqueIDError
|
||||||
|
}
|
||||||
|
|
||||||
|
// generateSafeID attempts to create ids for buckets
|
||||||
|
// and orgs that are without backslash, commas, and spaces, BUT ALSO do not already exist.
|
||||||
|
func (s *Service) generateSafeID(ctx context.Context, tx Tx, bucket []byte) (influxdb.ID, error) {
|
||||||
|
for i := 0; i < MaxIDGenerationN; i++ {
|
||||||
|
id := s.OrgBucketIDs.ID()
|
||||||
|
// we have reserved a certain number of IDs
|
||||||
|
// for orgs and buckets.
|
||||||
|
if id < ReservedIDs {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
err := s.uniqueID(ctx, tx, bucket, id)
|
||||||
|
if err == nil {
|
||||||
|
return id, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if err == NotUniqueIDError {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
return influxdb.InvalidID(), err
|
||||||
|
}
|
||||||
|
return influxdb.InvalidID(), ErrFailureGeneratingID
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,72 @@
|
||||||
|
package rand
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/binary"
|
||||||
|
"math/rand"
|
||||||
|
"sync"
|
||||||
|
|
||||||
|
"github.com/influxdata/influxdb"
|
||||||
|
)
|
||||||
|
|
||||||
|
var _ influxdb.IDGenerator = (*OrgBucketID)(nil)
|
||||||
|
|
||||||
|
// OrgBucketID creates an id that does not have ascii
|
||||||
|
// backslash, commas, or spaces. Used to create IDs for organizations
|
||||||
|
// and buckets.
|
||||||
|
//
|
||||||
|
// It is implemented without those characters because orgbucket
|
||||||
|
// pairs are placed in the old measurement field. Measurement
|
||||||
|
// was interpreted as a string delimited with commas. Therefore,
|
||||||
|
// to continue to use the underlying storage engine we need to
|
||||||
|
// sanitize ids.
|
||||||
|
//
|
||||||
|
// Safe for concurrent use by multiple goroutines.
|
||||||
|
type OrgBucketID struct {
|
||||||
|
m sync.Mutex
|
||||||
|
src *rand.Rand
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewOrgBucketID creates an influxdb.IDGenerator that creates
|
||||||
|
// random numbers seeded with seed. Ascii backslash, comma,
|
||||||
|
// and space are manipulated by incrementing.
|
||||||
|
//
|
||||||
|
// Typically, seed with `time.Now().UnixNano()`
|
||||||
|
func NewOrgBucketID(seed int64) *OrgBucketID {
|
||||||
|
return &OrgBucketID{
|
||||||
|
src: rand.New(rand.NewSource(seed)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Seed allows one to override the current seed.
|
||||||
|
// Typically, this override is done for tests.
|
||||||
|
func (r *OrgBucketID) Seed(seed int64) {
|
||||||
|
r.m.Lock()
|
||||||
|
r.src = rand.New(rand.NewSource(seed))
|
||||||
|
r.m.Unlock()
|
||||||
|
}
|
||||||
|
|
||||||
|
// ID generates an ID that does not have backslashes, commas, or spaces.
|
||||||
|
func (r *OrgBucketID) ID() influxdb.ID {
|
||||||
|
r.m.Lock()
|
||||||
|
n := r.src.Uint64()
|
||||||
|
r.m.Unlock()
|
||||||
|
|
||||||
|
n = sanitize(n)
|
||||||
|
return influxdb.ID(n)
|
||||||
|
}
|
||||||
|
|
||||||
|
func sanitize(n uint64) uint64 {
|
||||||
|
b := make([]byte, 8)
|
||||||
|
binary.BigEndian.PutUint64(b, n)
|
||||||
|
for i := range b {
|
||||||
|
switch b[i] {
|
||||||
|
// these bytes must be remove here to prevent the need
|
||||||
|
// to escape/unescape. See the models package for
|
||||||
|
// additional detail.
|
||||||
|
// \ , " "
|
||||||
|
case 0x5C, 0x2C, 0x20:
|
||||||
|
b[i] = b[i] + 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return binary.BigEndian.Uint64(b)
|
||||||
|
}
|
|
@ -0,0 +1,51 @@
|
||||||
|
package rand
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/binary"
|
||||||
|
"reflect"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/influxdata/influxdb"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestOrgBucketID_ID(t *testing.T) {
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
seed int64
|
||||||
|
want influxdb.ID
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "when seeded with 6 the first random number contains characters",
|
||||||
|
seed: 6,
|
||||||
|
want: influxdb.ID(0xaddff35d7fe88f15),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "when seeded with 1234567890 we get a random number without any bad chars",
|
||||||
|
seed: 1234567890,
|
||||||
|
want: influxdb.ID(0x8a95c1bf40518fee),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
r := NewOrgBucketID(tt.seed)
|
||||||
|
if got := r.ID(); !reflect.DeepEqual(got, tt.want) {
|
||||||
|
t.Errorf("OrgBucketID.ID() = %v, want %v", got, tt.want)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestOrgBucketID_ID_sanitized(t *testing.T) {
|
||||||
|
r := NewOrgBucketID(42)
|
||||||
|
b := make([]byte, 8)
|
||||||
|
for i := 0; i < 1000; i++ {
|
||||||
|
id := r.ID()
|
||||||
|
binary.LittleEndian.PutUint64(b, uint64(id))
|
||||||
|
for j := range b {
|
||||||
|
switch b[j] {
|
||||||
|
case 0x5C, 0x2C, 0x20:
|
||||||
|
t.Fatalf("unexpected bytes found in IDs")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
File diff suppressed because it is too large
Load Diff
|
@ -3,13 +3,15 @@ package testing
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"context"
|
"context"
|
||||||
|
"fmt"
|
||||||
"sort"
|
"sort"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/google/go-cmp/cmp"
|
"github.com/google/go-cmp/cmp"
|
||||||
platform "github.com/influxdata/influxdb"
|
"github.com/influxdata/influxdb"
|
||||||
"github.com/influxdata/influxdb/mock"
|
"github.com/influxdata/influxdb/mock"
|
||||||
|
"github.com/influxdata/influxdb/rand"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
@ -21,8 +23,8 @@ var organizationCmpOptions = cmp.Options{
|
||||||
cmp.Comparer(func(x, y []byte) bool {
|
cmp.Comparer(func(x, y []byte) bool {
|
||||||
return bytes.Equal(x, y)
|
return bytes.Equal(x, y)
|
||||||
}),
|
}),
|
||||||
cmp.Transformer("Sort", func(in []*platform.Organization) []*platform.Organization {
|
cmp.Transformer("Sort", func(in []*influxdb.Organization) []*influxdb.Organization {
|
||||||
out := append([]*platform.Organization(nil), in...) // Copy input to avoid mutating it
|
out := append([]*influxdb.Organization(nil), in...) // Copy input to avoid mutating it
|
||||||
sort.Slice(out, func(i, j int) bool {
|
sort.Slice(out, func(i, j int) bool {
|
||||||
return out[i].ID.String() > out[j].ID.String()
|
return out[i].ID.String() > out[j].ID.String()
|
||||||
})
|
})
|
||||||
|
@ -32,18 +34,19 @@ var organizationCmpOptions = cmp.Options{
|
||||||
|
|
||||||
// OrganizationFields will include the IDGenerator, and organizations
|
// OrganizationFields will include the IDGenerator, and organizations
|
||||||
type OrganizationFields struct {
|
type OrganizationFields struct {
|
||||||
IDGenerator platform.IDGenerator
|
IDGenerator influxdb.IDGenerator
|
||||||
Organizations []*platform.Organization
|
Organizations []*influxdb.Organization
|
||||||
TimeGenerator platform.TimeGenerator
|
TimeGenerator influxdb.TimeGenerator
|
||||||
|
OrgBucketIDs influxdb.IDGenerator
|
||||||
}
|
}
|
||||||
|
|
||||||
// OrganizationService tests all the service functions.
|
// OrganizationService tests all the service functions.
|
||||||
func OrganizationService(
|
func OrganizationService(
|
||||||
init func(OrganizationFields, *testing.T) (platform.OrganizationService, string, func()), t *testing.T,
|
init func(OrganizationFields, *testing.T) (influxdb.OrganizationService, string, func()), t *testing.T,
|
||||||
) {
|
) {
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
name string
|
name string
|
||||||
fn func(init func(OrganizationFields, *testing.T) (platform.OrganizationService, string, func()),
|
fn func(init func(OrganizationFields, *testing.T) (influxdb.OrganizationService, string, func()),
|
||||||
t *testing.T)
|
t *testing.T)
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
|
@ -80,15 +83,15 @@ func OrganizationService(
|
||||||
|
|
||||||
// CreateOrganization testing
|
// CreateOrganization testing
|
||||||
func CreateOrganization(
|
func CreateOrganization(
|
||||||
init func(OrganizationFields, *testing.T) (platform.OrganizationService, string, func()),
|
init func(OrganizationFields, *testing.T) (influxdb.OrganizationService, string, func()),
|
||||||
t *testing.T,
|
t *testing.T,
|
||||||
) {
|
) {
|
||||||
type args struct {
|
type args struct {
|
||||||
organization *platform.Organization
|
organization *influxdb.Organization
|
||||||
}
|
}
|
||||||
type wants struct {
|
type wants struct {
|
||||||
err error
|
err error
|
||||||
organizations []*platform.Organization
|
organizations []*influxdb.Organization
|
||||||
}
|
}
|
||||||
|
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
|
@ -101,23 +104,24 @@ func CreateOrganization(
|
||||||
name: "create organizations with empty set",
|
name: "create organizations with empty set",
|
||||||
fields: OrganizationFields{
|
fields: OrganizationFields{
|
||||||
IDGenerator: mock.NewIDGenerator(orgOneID, t),
|
IDGenerator: mock.NewIDGenerator(orgOneID, t),
|
||||||
|
OrgBucketIDs: mock.NewIDGenerator(orgOneID, t),
|
||||||
TimeGenerator: mock.TimeGenerator{FakeValue: time.Date(2006, 5, 4, 1, 2, 3, 0, time.UTC)},
|
TimeGenerator: mock.TimeGenerator{FakeValue: time.Date(2006, 5, 4, 1, 2, 3, 0, time.UTC)},
|
||||||
Organizations: []*platform.Organization{},
|
Organizations: []*influxdb.Organization{},
|
||||||
},
|
},
|
||||||
args: args{
|
args: args{
|
||||||
organization: &platform.Organization{
|
organization: &influxdb.Organization{
|
||||||
Name: "name1",
|
Name: "name1",
|
||||||
ID: MustIDBase16(orgOneID),
|
ID: MustIDBase16(orgOneID),
|
||||||
Description: "desc1",
|
Description: "desc1",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
wants: wants{
|
wants: wants{
|
||||||
organizations: []*platform.Organization{
|
organizations: []*influxdb.Organization{
|
||||||
{
|
{
|
||||||
Name: "name1",
|
Name: "name1",
|
||||||
ID: MustIDBase16(orgOneID),
|
ID: MustIDBase16(orgOneID),
|
||||||
Description: "desc1",
|
Description: "desc1",
|
||||||
CRUDLog: platform.CRUDLog{
|
CRUDLog: influxdb.CRUDLog{
|
||||||
CreatedAt: time.Date(2006, 5, 4, 1, 2, 3, 0, time.UTC),
|
CreatedAt: time.Date(2006, 5, 4, 1, 2, 3, 0, time.UTC),
|
||||||
UpdatedAt: time.Date(2006, 5, 4, 1, 2, 3, 0, time.UTC),
|
UpdatedAt: time.Date(2006, 5, 4, 1, 2, 3, 0, time.UTC),
|
||||||
},
|
},
|
||||||
|
@ -129,8 +133,9 @@ func CreateOrganization(
|
||||||
name: "basic create organization",
|
name: "basic create organization",
|
||||||
fields: OrganizationFields{
|
fields: OrganizationFields{
|
||||||
IDGenerator: mock.NewIDGenerator(orgTwoID, t),
|
IDGenerator: mock.NewIDGenerator(orgTwoID, t),
|
||||||
|
OrgBucketIDs: mock.NewIDGenerator(orgTwoID, t),
|
||||||
TimeGenerator: mock.TimeGenerator{FakeValue: time.Date(2006, 5, 4, 1, 2, 3, 0, time.UTC)},
|
TimeGenerator: mock.TimeGenerator{FakeValue: time.Date(2006, 5, 4, 1, 2, 3, 0, time.UTC)},
|
||||||
Organizations: []*platform.Organization{
|
Organizations: []*influxdb.Organization{
|
||||||
{
|
{
|
||||||
ID: MustIDBase16(orgOneID),
|
ID: MustIDBase16(orgOneID),
|
||||||
Name: "organization1",
|
Name: "organization1",
|
||||||
|
@ -138,13 +143,13 @@ func CreateOrganization(
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
args: args{
|
args: args{
|
||||||
organization: &platform.Organization{
|
organization: &influxdb.Organization{
|
||||||
ID: MustIDBase16(orgTwoID),
|
ID: MustIDBase16(orgTwoID),
|
||||||
Name: "organization2",
|
Name: "organization2",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
wants: wants{
|
wants: wants{
|
||||||
organizations: []*platform.Organization{
|
organizations: []*influxdb.Organization{
|
||||||
{
|
{
|
||||||
ID: MustIDBase16(orgOneID),
|
ID: MustIDBase16(orgOneID),
|
||||||
Name: "organization1",
|
Name: "organization1",
|
||||||
|
@ -152,7 +157,7 @@ func CreateOrganization(
|
||||||
{
|
{
|
||||||
ID: MustIDBase16(orgTwoID),
|
ID: MustIDBase16(orgTwoID),
|
||||||
Name: "organization2",
|
Name: "organization2",
|
||||||
CRUDLog: platform.CRUDLog{
|
CRUDLog: influxdb.CRUDLog{
|
||||||
CreatedAt: time.Date(2006, 5, 4, 1, 2, 3, 0, time.UTC),
|
CreatedAt: time.Date(2006, 5, 4, 1, 2, 3, 0, time.UTC),
|
||||||
UpdatedAt: time.Date(2006, 5, 4, 1, 2, 3, 0, time.UTC),
|
UpdatedAt: time.Date(2006, 5, 4, 1, 2, 3, 0, time.UTC),
|
||||||
},
|
},
|
||||||
|
@ -164,8 +169,9 @@ func CreateOrganization(
|
||||||
name: "empty name",
|
name: "empty name",
|
||||||
fields: OrganizationFields{
|
fields: OrganizationFields{
|
||||||
IDGenerator: mock.NewIDGenerator(orgTwoID, t),
|
IDGenerator: mock.NewIDGenerator(orgTwoID, t),
|
||||||
|
OrgBucketIDs: mock.NewIDGenerator(orgTwoID, t),
|
||||||
TimeGenerator: mock.TimeGenerator{FakeValue: time.Date(2006, 5, 4, 1, 2, 3, 0, time.UTC)},
|
TimeGenerator: mock.TimeGenerator{FakeValue: time.Date(2006, 5, 4, 1, 2, 3, 0, time.UTC)},
|
||||||
Organizations: []*platform.Organization{
|
Organizations: []*influxdb.Organization{
|
||||||
{
|
{
|
||||||
ID: MustIDBase16(orgOneID),
|
ID: MustIDBase16(orgOneID),
|
||||||
Name: "organization1",
|
Name: "organization1",
|
||||||
|
@ -173,26 +179,27 @@ func CreateOrganization(
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
args: args{
|
args: args{
|
||||||
organization: &platform.Organization{
|
organization: &influxdb.Organization{
|
||||||
ID: MustIDBase16(orgOneID),
|
ID: MustIDBase16(orgOneID),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
wants: wants{
|
wants: wants{
|
||||||
organizations: []*platform.Organization{
|
organizations: []*influxdb.Organization{
|
||||||
{
|
{
|
||||||
ID: MustIDBase16(orgOneID),
|
ID: MustIDBase16(orgOneID),
|
||||||
Name: "organization1",
|
Name: "organization1",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
err: platform.ErrOrgNameisEmpty,
|
err: influxdb.ErrOrgNameisEmpty,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "name only have spaces",
|
name: "name only have spaces",
|
||||||
fields: OrganizationFields{
|
fields: OrganizationFields{
|
||||||
IDGenerator: mock.NewIDGenerator(orgTwoID, t),
|
IDGenerator: mock.NewIDGenerator(orgTwoID, t),
|
||||||
|
OrgBucketIDs: mock.NewIDGenerator(orgTwoID, t),
|
||||||
TimeGenerator: mock.TimeGenerator{FakeValue: time.Date(2006, 5, 4, 1, 2, 3, 0, time.UTC)},
|
TimeGenerator: mock.TimeGenerator{FakeValue: time.Date(2006, 5, 4, 1, 2, 3, 0, time.UTC)},
|
||||||
Organizations: []*platform.Organization{
|
Organizations: []*influxdb.Organization{
|
||||||
{
|
{
|
||||||
ID: MustIDBase16(orgOneID),
|
ID: MustIDBase16(orgOneID),
|
||||||
Name: "organization1",
|
Name: "organization1",
|
||||||
|
@ -200,27 +207,28 @@ func CreateOrganization(
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
args: args{
|
args: args{
|
||||||
organization: &platform.Organization{
|
organization: &influxdb.Organization{
|
||||||
ID: MustIDBase16(orgOneID),
|
ID: MustIDBase16(orgOneID),
|
||||||
Name: " ",
|
Name: " ",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
wants: wants{
|
wants: wants{
|
||||||
organizations: []*platform.Organization{
|
organizations: []*influxdb.Organization{
|
||||||
{
|
{
|
||||||
ID: MustIDBase16(orgOneID),
|
ID: MustIDBase16(orgOneID),
|
||||||
Name: "organization1",
|
Name: "organization1",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
err: platform.ErrOrgNameisEmpty,
|
err: influxdb.ErrOrgNameisEmpty,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "names should be unique",
|
name: "names should be unique",
|
||||||
fields: OrganizationFields{
|
fields: OrganizationFields{
|
||||||
IDGenerator: mock.NewIDGenerator(orgTwoID, t),
|
IDGenerator: mock.NewIDGenerator(orgTwoID, t),
|
||||||
|
OrgBucketIDs: mock.NewIDGenerator(orgTwoID, t),
|
||||||
TimeGenerator: mock.TimeGenerator{FakeValue: time.Date(2006, 5, 4, 1, 2, 3, 0, time.UTC)},
|
TimeGenerator: mock.TimeGenerator{FakeValue: time.Date(2006, 5, 4, 1, 2, 3, 0, time.UTC)},
|
||||||
Organizations: []*platform.Organization{
|
Organizations: []*influxdb.Organization{
|
||||||
{
|
{
|
||||||
ID: MustIDBase16(orgOneID),
|
ID: MustIDBase16(orgOneID),
|
||||||
Name: "organization1",
|
Name: "organization1",
|
||||||
|
@ -228,21 +236,21 @@ func CreateOrganization(
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
args: args{
|
args: args{
|
||||||
organization: &platform.Organization{
|
organization: &influxdb.Organization{
|
||||||
ID: MustIDBase16(orgOneID),
|
ID: MustIDBase16(orgOneID),
|
||||||
Name: "organization1",
|
Name: "organization1",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
wants: wants{
|
wants: wants{
|
||||||
organizations: []*platform.Organization{
|
organizations: []*influxdb.Organization{
|
||||||
{
|
{
|
||||||
ID: MustIDBase16(orgOneID),
|
ID: MustIDBase16(orgOneID),
|
||||||
Name: "organization1",
|
Name: "organization1",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
err: &platform.Error{
|
err: &influxdb.Error{
|
||||||
Code: platform.EConflict,
|
Code: influxdb.EConflict,
|
||||||
Op: platform.OpCreateOrganization,
|
Op: influxdb.OpCreateOrganization,
|
||||||
Msg: "organization with name organization1 already exists",
|
Msg: "organization with name organization1 already exists",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -251,8 +259,9 @@ func CreateOrganization(
|
||||||
name: "create organization with no id",
|
name: "create organization with no id",
|
||||||
fields: OrganizationFields{
|
fields: OrganizationFields{
|
||||||
IDGenerator: mock.NewIDGenerator(orgTwoID, t),
|
IDGenerator: mock.NewIDGenerator(orgTwoID, t),
|
||||||
|
OrgBucketIDs: mock.NewIDGenerator(orgTwoID, t),
|
||||||
TimeGenerator: mock.TimeGenerator{FakeValue: time.Date(2006, 5, 4, 1, 2, 3, 0, time.UTC)},
|
TimeGenerator: mock.TimeGenerator{FakeValue: time.Date(2006, 5, 4, 1, 2, 3, 0, time.UTC)},
|
||||||
Organizations: []*platform.Organization{
|
Organizations: []*influxdb.Organization{
|
||||||
{
|
{
|
||||||
ID: MustIDBase16(orgOneID),
|
ID: MustIDBase16(orgOneID),
|
||||||
Name: "organization1",
|
Name: "organization1",
|
||||||
|
@ -260,12 +269,12 @@ func CreateOrganization(
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
args: args{
|
args: args{
|
||||||
organization: &platform.Organization{
|
organization: &influxdb.Organization{
|
||||||
Name: "organization2",
|
Name: "organization2",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
wants: wants{
|
wants: wants{
|
||||||
organizations: []*platform.Organization{
|
organizations: []*influxdb.Organization{
|
||||||
{
|
{
|
||||||
ID: MustIDBase16(orgOneID),
|
ID: MustIDBase16(orgOneID),
|
||||||
Name: "organization1",
|
Name: "organization1",
|
||||||
|
@ -273,7 +282,130 @@ func CreateOrganization(
|
||||||
{
|
{
|
||||||
ID: MustIDBase16(orgTwoID),
|
ID: MustIDBase16(orgTwoID),
|
||||||
Name: "organization2",
|
Name: "organization2",
|
||||||
CRUDLog: platform.CRUDLog{
|
CRUDLog: influxdb.CRUDLog{
|
||||||
|
CreatedAt: time.Date(2006, 5, 4, 1, 2, 3, 0, time.UTC),
|
||||||
|
UpdatedAt: time.Date(2006, 5, 4, 1, 2, 3, 0, time.UTC),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "names should be unique",
|
||||||
|
fields: OrganizationFields{
|
||||||
|
IDGenerator: mock.NewIDGenerator(orgTwoID, t),
|
||||||
|
OrgBucketIDs: mock.NewIDGenerator(orgTwoID, t),
|
||||||
|
TimeGenerator: mock.TimeGenerator{FakeValue: time.Date(2006, 5, 4, 1, 2, 3, 0, time.UTC)},
|
||||||
|
Organizations: []*influxdb.Organization{
|
||||||
|
{
|
||||||
|
ID: MustIDBase16(orgOneID),
|
||||||
|
Name: "organization1",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
args: args{
|
||||||
|
organization: &influxdb.Organization{
|
||||||
|
ID: MustIDBase16(orgOneID),
|
||||||
|
Name: "organization1",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
wants: wants{
|
||||||
|
organizations: []*influxdb.Organization{
|
||||||
|
{
|
||||||
|
ID: MustIDBase16(orgOneID),
|
||||||
|
Name: "organization1",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
err: &influxdb.Error{
|
||||||
|
Code: influxdb.EConflict,
|
||||||
|
Op: influxdb.OpCreateOrganization,
|
||||||
|
Msg: "organization with name organization1 already exists",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "ids should be unique",
|
||||||
|
fields: OrganizationFields{
|
||||||
|
IDGenerator: mock.NewIDGenerator(orgOneID, t),
|
||||||
|
OrgBucketIDs: mock.NewIDGenerator(orgOneID, t),
|
||||||
|
TimeGenerator: mock.TimeGenerator{FakeValue: time.Date(2006, 5, 4, 1, 2, 3, 0, time.UTC)},
|
||||||
|
Organizations: []*influxdb.Organization{
|
||||||
|
{
|
||||||
|
ID: MustIDBase16(orgOneID),
|
||||||
|
Name: "organization1",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
args: args{
|
||||||
|
organization: &influxdb.Organization{
|
||||||
|
ID: MustIDBase16(orgOneID),
|
||||||
|
Name: "organization2",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
wants: wants{
|
||||||
|
organizations: []*influxdb.Organization{
|
||||||
|
{
|
||||||
|
ID: MustIDBase16(orgOneID),
|
||||||
|
Name: "organization1",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
err: &influxdb.Error{
|
||||||
|
Code: influxdb.EInternal,
|
||||||
|
Msg: fmt.Sprintf("unable to generate valid id"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "reserved ids should not be created",
|
||||||
|
fields: OrganizationFields{
|
||||||
|
IDGenerator: mock.NewIDGenerator("000000000000000a", t),
|
||||||
|
OrgBucketIDs: mock.NewIDGenerator("000000000000000a", t),
|
||||||
|
TimeGenerator: mock.TimeGenerator{FakeValue: time.Date(2006, 5, 4, 1, 2, 3, 0, time.UTC)},
|
||||||
|
Organizations: []*influxdb.Organization{
|
||||||
|
{
|
||||||
|
ID: MustIDBase16(orgOneID),
|
||||||
|
Name: "organization1",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
args: args{
|
||||||
|
organization: &influxdb.Organization{
|
||||||
|
ID: MustIDBase16(orgOneID),
|
||||||
|
Name: "organization2",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
wants: wants{
|
||||||
|
organizations: []*influxdb.Organization{
|
||||||
|
{
|
||||||
|
ID: MustIDBase16(orgOneID),
|
||||||
|
Name: "organization1",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
err: &influxdb.Error{
|
||||||
|
Code: influxdb.EInternal,
|
||||||
|
Msg: fmt.Sprintf("unable to generate valid id"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "randomly generted org ids should not have commas, spaces, or backslashes",
|
||||||
|
fields: OrganizationFields{
|
||||||
|
OrgBucketIDs: rand.NewOrgBucketID(42),
|
||||||
|
TimeGenerator: mock.TimeGenerator{FakeValue: time.Date(2006, 5, 4, 1, 2, 3, 0, time.UTC)},
|
||||||
|
Organizations: []*influxdb.Organization{},
|
||||||
|
},
|
||||||
|
args: args{
|
||||||
|
organization: &influxdb.Organization{
|
||||||
|
Name: "o1",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
wants: wants{
|
||||||
|
organizations: []*influxdb.Organization{
|
||||||
|
{
|
||||||
|
ID: MustIDBase16("afbf64b1967f8c53"),
|
||||||
|
Name: "o1",
|
||||||
|
|
||||||
|
CRUDLog: influxdb.CRUDLog{
|
||||||
CreatedAt: time.Date(2006, 5, 4, 1, 2, 3, 0, time.UTC),
|
CreatedAt: time.Date(2006, 5, 4, 1, 2, 3, 0, time.UTC),
|
||||||
UpdatedAt: time.Date(2006, 5, 4, 1, 2, 3, 0, time.UTC),
|
UpdatedAt: time.Date(2006, 5, 4, 1, 2, 3, 0, time.UTC),
|
||||||
},
|
},
|
||||||
|
@ -296,7 +428,7 @@ func CreateOrganization(
|
||||||
defer s.DeleteOrganization(ctx, tt.args.organization.ID)
|
defer s.DeleteOrganization(ctx, tt.args.organization.ID)
|
||||||
// }
|
// }
|
||||||
|
|
||||||
organizations, _, err := s.FindOrganizations(ctx, platform.OrganizationFilter{})
|
organizations, _, err := s.FindOrganizations(ctx, influxdb.OrganizationFilter{})
|
||||||
diffPlatformErrors(tt.name, err, nil, opPrefix, t)
|
diffPlatformErrors(tt.name, err, nil, opPrefix, t)
|
||||||
if diff := cmp.Diff(organizations, tt.wants.organizations, organizationCmpOptions...); diff != "" {
|
if diff := cmp.Diff(organizations, tt.wants.organizations, organizationCmpOptions...); diff != "" {
|
||||||
t.Errorf("organizations are different -got/+want\ndiff %s", diff)
|
t.Errorf("organizations are different -got/+want\ndiff %s", diff)
|
||||||
|
@ -307,15 +439,15 @@ func CreateOrganization(
|
||||||
|
|
||||||
// FindOrganizationByID testing
|
// FindOrganizationByID testing
|
||||||
func FindOrganizationByID(
|
func FindOrganizationByID(
|
||||||
init func(OrganizationFields, *testing.T) (platform.OrganizationService, string, func()),
|
init func(OrganizationFields, *testing.T) (influxdb.OrganizationService, string, func()),
|
||||||
t *testing.T,
|
t *testing.T,
|
||||||
) {
|
) {
|
||||||
type args struct {
|
type args struct {
|
||||||
id platform.ID
|
id influxdb.ID
|
||||||
}
|
}
|
||||||
type wants struct {
|
type wants struct {
|
||||||
err error
|
err error
|
||||||
organization *platform.Organization
|
organization *influxdb.Organization
|
||||||
}
|
}
|
||||||
|
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
|
@ -327,7 +459,7 @@ func FindOrganizationByID(
|
||||||
{
|
{
|
||||||
name: "basic find organization by id",
|
name: "basic find organization by id",
|
||||||
fields: OrganizationFields{
|
fields: OrganizationFields{
|
||||||
Organizations: []*platform.Organization{
|
Organizations: []*influxdb.Organization{
|
||||||
{
|
{
|
||||||
ID: MustIDBase16(orgOneID),
|
ID: MustIDBase16(orgOneID),
|
||||||
Name: "organization1",
|
Name: "organization1",
|
||||||
|
@ -342,7 +474,7 @@ func FindOrganizationByID(
|
||||||
id: MustIDBase16(orgTwoID),
|
id: MustIDBase16(orgTwoID),
|
||||||
},
|
},
|
||||||
wants: wants{
|
wants: wants{
|
||||||
organization: &platform.Organization{
|
organization: &influxdb.Organization{
|
||||||
ID: MustIDBase16(orgTwoID),
|
ID: MustIDBase16(orgTwoID),
|
||||||
Name: "organization2",
|
Name: "organization2",
|
||||||
},
|
},
|
||||||
|
@ -351,7 +483,7 @@ func FindOrganizationByID(
|
||||||
{
|
{
|
||||||
name: "didn't find organization by id",
|
name: "didn't find organization by id",
|
||||||
fields: OrganizationFields{
|
fields: OrganizationFields{
|
||||||
Organizations: []*platform.Organization{
|
Organizations: []*influxdb.Organization{
|
||||||
{
|
{
|
||||||
ID: MustIDBase16(orgOneID),
|
ID: MustIDBase16(orgOneID),
|
||||||
Name: "organization1",
|
Name: "organization1",
|
||||||
|
@ -367,9 +499,9 @@ func FindOrganizationByID(
|
||||||
},
|
},
|
||||||
wants: wants{
|
wants: wants{
|
||||||
organization: nil,
|
organization: nil,
|
||||||
err: &platform.Error{
|
err: &influxdb.Error{
|
||||||
Code: platform.ENotFound,
|
Code: influxdb.ENotFound,
|
||||||
Op: platform.OpFindOrganizationByID,
|
Op: influxdb.OpFindOrganizationByID,
|
||||||
Msg: "organization not found",
|
Msg: "organization not found",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -394,16 +526,16 @@ func FindOrganizationByID(
|
||||||
|
|
||||||
// FindOrganizations testing
|
// FindOrganizations testing
|
||||||
func FindOrganizations(
|
func FindOrganizations(
|
||||||
init func(OrganizationFields, *testing.T) (platform.OrganizationService, string, func()),
|
init func(OrganizationFields, *testing.T) (influxdb.OrganizationService, string, func()),
|
||||||
t *testing.T,
|
t *testing.T,
|
||||||
) {
|
) {
|
||||||
type args struct {
|
type args struct {
|
||||||
ID platform.ID
|
ID influxdb.ID
|
||||||
name string
|
name string
|
||||||
}
|
}
|
||||||
|
|
||||||
type wants struct {
|
type wants struct {
|
||||||
organizations []*platform.Organization
|
organizations []*influxdb.Organization
|
||||||
err error
|
err error
|
||||||
}
|
}
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
|
@ -415,7 +547,7 @@ func FindOrganizations(
|
||||||
{
|
{
|
||||||
name: "find all organizations",
|
name: "find all organizations",
|
||||||
fields: OrganizationFields{
|
fields: OrganizationFields{
|
||||||
Organizations: []*platform.Organization{
|
Organizations: []*influxdb.Organization{
|
||||||
{
|
{
|
||||||
ID: MustIDBase16(orgOneID),
|
ID: MustIDBase16(orgOneID),
|
||||||
Name: "abc",
|
Name: "abc",
|
||||||
|
@ -429,7 +561,7 @@ func FindOrganizations(
|
||||||
},
|
},
|
||||||
args: args{},
|
args: args{},
|
||||||
wants: wants{
|
wants: wants{
|
||||||
organizations: []*platform.Organization{
|
organizations: []*influxdb.Organization{
|
||||||
{
|
{
|
||||||
ID: MustIDBase16(orgOneID),
|
ID: MustIDBase16(orgOneID),
|
||||||
Name: "abc",
|
Name: "abc",
|
||||||
|
@ -445,7 +577,7 @@ func FindOrganizations(
|
||||||
{
|
{
|
||||||
name: "find organization by id",
|
name: "find organization by id",
|
||||||
fields: OrganizationFields{
|
fields: OrganizationFields{
|
||||||
Organizations: []*platform.Organization{
|
Organizations: []*influxdb.Organization{
|
||||||
{
|
{
|
||||||
ID: MustIDBase16(orgOneID),
|
ID: MustIDBase16(orgOneID),
|
||||||
Name: "abc",
|
Name: "abc",
|
||||||
|
@ -460,7 +592,7 @@ func FindOrganizations(
|
||||||
ID: MustIDBase16(orgTwoID),
|
ID: MustIDBase16(orgTwoID),
|
||||||
},
|
},
|
||||||
wants: wants{
|
wants: wants{
|
||||||
organizations: []*platform.Organization{
|
organizations: []*influxdb.Organization{
|
||||||
{
|
{
|
||||||
ID: MustIDBase16(orgTwoID),
|
ID: MustIDBase16(orgTwoID),
|
||||||
Name: "xyz",
|
Name: "xyz",
|
||||||
|
@ -471,7 +603,7 @@ func FindOrganizations(
|
||||||
{
|
{
|
||||||
name: "find organization by name",
|
name: "find organization by name",
|
||||||
fields: OrganizationFields{
|
fields: OrganizationFields{
|
||||||
Organizations: []*platform.Organization{
|
Organizations: []*influxdb.Organization{
|
||||||
{
|
{
|
||||||
ID: MustIDBase16(orgOneID),
|
ID: MustIDBase16(orgOneID),
|
||||||
Name: "abc",
|
Name: "abc",
|
||||||
|
@ -486,7 +618,7 @@ func FindOrganizations(
|
||||||
name: "xyz",
|
name: "xyz",
|
||||||
},
|
},
|
||||||
wants: wants{
|
wants: wants{
|
||||||
organizations: []*platform.Organization{
|
organizations: []*influxdb.Organization{
|
||||||
{
|
{
|
||||||
ID: MustIDBase16(orgTwoID),
|
ID: MustIDBase16(orgTwoID),
|
||||||
Name: "xyz",
|
Name: "xyz",
|
||||||
|
@ -497,7 +629,7 @@ func FindOrganizations(
|
||||||
{
|
{
|
||||||
name: "find organization by id not exists",
|
name: "find organization by id not exists",
|
||||||
fields: OrganizationFields{
|
fields: OrganizationFields{
|
||||||
Organizations: []*platform.Organization{
|
Organizations: []*influxdb.Organization{
|
||||||
{
|
{
|
||||||
ID: MustIDBase16(orgOneID),
|
ID: MustIDBase16(orgOneID),
|
||||||
Name: "abc",
|
Name: "abc",
|
||||||
|
@ -512,10 +644,10 @@ func FindOrganizations(
|
||||||
ID: MustIDBase16(threeID),
|
ID: MustIDBase16(threeID),
|
||||||
},
|
},
|
||||||
wants: wants{
|
wants: wants{
|
||||||
organizations: []*platform.Organization{},
|
organizations: []*influxdb.Organization{},
|
||||||
err: &platform.Error{
|
err: &influxdb.Error{
|
||||||
Code: platform.ENotFound,
|
Code: influxdb.ENotFound,
|
||||||
Op: platform.OpFindOrganizations,
|
Op: influxdb.OpFindOrganizations,
|
||||||
Msg: "organization not found",
|
Msg: "organization not found",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -523,7 +655,7 @@ func FindOrganizations(
|
||||||
{
|
{
|
||||||
name: "find organization by name not exists",
|
name: "find organization by name not exists",
|
||||||
fields: OrganizationFields{
|
fields: OrganizationFields{
|
||||||
Organizations: []*platform.Organization{
|
Organizations: []*influxdb.Organization{
|
||||||
{
|
{
|
||||||
ID: MustIDBase16(orgOneID),
|
ID: MustIDBase16(orgOneID),
|
||||||
Name: "abc",
|
Name: "abc",
|
||||||
|
@ -538,10 +670,10 @@ func FindOrganizations(
|
||||||
name: "na",
|
name: "na",
|
||||||
},
|
},
|
||||||
wants: wants{
|
wants: wants{
|
||||||
organizations: []*platform.Organization{},
|
organizations: []*influxdb.Organization{},
|
||||||
err: &platform.Error{
|
err: &influxdb.Error{
|
||||||
Code: platform.ENotFound,
|
Code: influxdb.ENotFound,
|
||||||
Op: platform.OpFindOrganizations,
|
Op: influxdb.OpFindOrganizations,
|
||||||
Msg: "organization name \"na\" not found",
|
Msg: "organization name \"na\" not found",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -554,7 +686,7 @@ func FindOrganizations(
|
||||||
defer done()
|
defer done()
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
|
|
||||||
filter := platform.OrganizationFilter{}
|
filter := influxdb.OrganizationFilter{}
|
||||||
if tt.args.ID.Valid() {
|
if tt.args.ID.Valid() {
|
||||||
filter.ID = &tt.args.ID
|
filter.ID = &tt.args.ID
|
||||||
}
|
}
|
||||||
|
@ -574,7 +706,7 @@ func FindOrganizations(
|
||||||
|
|
||||||
// DeleteOrganization testing
|
// DeleteOrganization testing
|
||||||
func DeleteOrganization(
|
func DeleteOrganization(
|
||||||
init func(OrganizationFields, *testing.T) (platform.OrganizationService, string, func()),
|
init func(OrganizationFields, *testing.T) (influxdb.OrganizationService, string, func()),
|
||||||
t *testing.T,
|
t *testing.T,
|
||||||
) {
|
) {
|
||||||
type args struct {
|
type args struct {
|
||||||
|
@ -582,7 +714,7 @@ func DeleteOrganization(
|
||||||
}
|
}
|
||||||
type wants struct {
|
type wants struct {
|
||||||
err error
|
err error
|
||||||
organizations []*platform.Organization
|
organizations []*influxdb.Organization
|
||||||
}
|
}
|
||||||
|
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
|
@ -594,7 +726,7 @@ func DeleteOrganization(
|
||||||
{
|
{
|
||||||
name: "delete organizations using exist id",
|
name: "delete organizations using exist id",
|
||||||
fields: OrganizationFields{
|
fields: OrganizationFields{
|
||||||
Organizations: []*platform.Organization{
|
Organizations: []*influxdb.Organization{
|
||||||
{
|
{
|
||||||
Name: "orgA",
|
Name: "orgA",
|
||||||
ID: MustIDBase16(orgOneID),
|
ID: MustIDBase16(orgOneID),
|
||||||
|
@ -609,7 +741,7 @@ func DeleteOrganization(
|
||||||
ID: orgOneID,
|
ID: orgOneID,
|
||||||
},
|
},
|
||||||
wants: wants{
|
wants: wants{
|
||||||
organizations: []*platform.Organization{
|
organizations: []*influxdb.Organization{
|
||||||
{
|
{
|
||||||
Name: "orgB",
|
Name: "orgB",
|
||||||
ID: MustIDBase16(orgTwoID),
|
ID: MustIDBase16(orgTwoID),
|
||||||
|
@ -620,7 +752,7 @@ func DeleteOrganization(
|
||||||
{
|
{
|
||||||
name: "delete organizations using id that does not exist",
|
name: "delete organizations using id that does not exist",
|
||||||
fields: OrganizationFields{
|
fields: OrganizationFields{
|
||||||
Organizations: []*platform.Organization{
|
Organizations: []*influxdb.Organization{
|
||||||
{
|
{
|
||||||
Name: "orgA",
|
Name: "orgA",
|
||||||
ID: MustIDBase16(orgOneID),
|
ID: MustIDBase16(orgOneID),
|
||||||
|
@ -635,12 +767,12 @@ func DeleteOrganization(
|
||||||
ID: "1234567890654321",
|
ID: "1234567890654321",
|
||||||
},
|
},
|
||||||
wants: wants{
|
wants: wants{
|
||||||
err: &platform.Error{
|
err: &influxdb.Error{
|
||||||
Code: platform.ENotFound,
|
Code: influxdb.ENotFound,
|
||||||
Op: platform.OpDeleteOrganization,
|
Op: influxdb.OpDeleteOrganization,
|
||||||
Msg: "organization not found",
|
Msg: "organization not found",
|
||||||
},
|
},
|
||||||
organizations: []*platform.Organization{
|
organizations: []*influxdb.Organization{
|
||||||
{
|
{
|
||||||
Name: "orgA",
|
Name: "orgA",
|
||||||
ID: MustIDBase16(orgOneID),
|
ID: MustIDBase16(orgOneID),
|
||||||
|
@ -662,7 +794,7 @@ func DeleteOrganization(
|
||||||
err := s.DeleteOrganization(ctx, MustIDBase16(tt.args.ID))
|
err := s.DeleteOrganization(ctx, MustIDBase16(tt.args.ID))
|
||||||
diffPlatformErrors(tt.name, err, tt.wants.err, opPrefix, t)
|
diffPlatformErrors(tt.name, err, tt.wants.err, opPrefix, t)
|
||||||
|
|
||||||
filter := platform.OrganizationFilter{}
|
filter := influxdb.OrganizationFilter{}
|
||||||
organizations, _, err := s.FindOrganizations(ctx, filter)
|
organizations, _, err := s.FindOrganizations(ctx, filter)
|
||||||
diffPlatformErrors(tt.name, err, nil, opPrefix, t)
|
diffPlatformErrors(tt.name, err, nil, opPrefix, t)
|
||||||
|
|
||||||
|
@ -675,16 +807,16 @@ func DeleteOrganization(
|
||||||
|
|
||||||
// FindOrganization testing
|
// FindOrganization testing
|
||||||
func FindOrganization(
|
func FindOrganization(
|
||||||
init func(OrganizationFields, *testing.T) (platform.OrganizationService, string, func()),
|
init func(OrganizationFields, *testing.T) (influxdb.OrganizationService, string, func()),
|
||||||
t *testing.T,
|
t *testing.T,
|
||||||
) {
|
) {
|
||||||
type args struct {
|
type args struct {
|
||||||
name string
|
name string
|
||||||
id platform.ID
|
id influxdb.ID
|
||||||
}
|
}
|
||||||
|
|
||||||
type wants struct {
|
type wants struct {
|
||||||
organization *platform.Organization
|
organization *influxdb.Organization
|
||||||
err error
|
err error
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -697,7 +829,7 @@ func FindOrganization(
|
||||||
{
|
{
|
||||||
name: "find organization by name",
|
name: "find organization by name",
|
||||||
fields: OrganizationFields{
|
fields: OrganizationFields{
|
||||||
Organizations: []*platform.Organization{
|
Organizations: []*influxdb.Organization{
|
||||||
{
|
{
|
||||||
ID: MustIDBase16(orgOneID),
|
ID: MustIDBase16(orgOneID),
|
||||||
Name: "abc",
|
Name: "abc",
|
||||||
|
@ -712,7 +844,7 @@ func FindOrganization(
|
||||||
name: "abc",
|
name: "abc",
|
||||||
},
|
},
|
||||||
wants: wants{
|
wants: wants{
|
||||||
organization: &platform.Organization{
|
organization: &influxdb.Organization{
|
||||||
ID: MustIDBase16(orgOneID),
|
ID: MustIDBase16(orgOneID),
|
||||||
Name: "abc",
|
Name: "abc",
|
||||||
},
|
},
|
||||||
|
@ -724,9 +856,9 @@ func FindOrganization(
|
||||||
name: "unknown",
|
name: "unknown",
|
||||||
},
|
},
|
||||||
wants: wants{
|
wants: wants{
|
||||||
err: &platform.Error{
|
err: &influxdb.Error{
|
||||||
Code: platform.ENotFound,
|
Code: influxdb.ENotFound,
|
||||||
Op: platform.OpFindOrganization,
|
Op: influxdb.OpFindOrganization,
|
||||||
Msg: "organization name \"unknown\" not found",
|
Msg: "organization name \"unknown\" not found",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -734,11 +866,11 @@ func FindOrganization(
|
||||||
{
|
{
|
||||||
name: "find organization in which no id filter matches should return no org",
|
name: "find organization in which no id filter matches should return no org",
|
||||||
args: args{
|
args: args{
|
||||||
id: platform.ID(3),
|
id: influxdb.ID(3),
|
||||||
},
|
},
|
||||||
wants: wants{
|
wants: wants{
|
||||||
err: &platform.Error{
|
err: &influxdb.Error{
|
||||||
Code: platform.ENotFound,
|
Code: influxdb.ENotFound,
|
||||||
Msg: "organization not found",
|
Msg: "organization not found",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -746,7 +878,7 @@ func FindOrganization(
|
||||||
{
|
{
|
||||||
name: "find organization no filter is set returns an error about filters not provided",
|
name: "find organization no filter is set returns an error about filters not provided",
|
||||||
fields: OrganizationFields{
|
fields: OrganizationFields{
|
||||||
Organizations: []*platform.Organization{
|
Organizations: []*influxdb.Organization{
|
||||||
{
|
{
|
||||||
ID: MustIDBase16(orgOneID),
|
ID: MustIDBase16(orgOneID),
|
||||||
Name: "o1",
|
Name: "o1",
|
||||||
|
@ -754,21 +886,21 @@ func FindOrganization(
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
wants: wants{
|
wants: wants{
|
||||||
err: platform.ErrInvalidOrgFilter,
|
err: influxdb.ErrInvalidOrgFilter,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "missing organization returns error",
|
name: "missing organization returns error",
|
||||||
fields: OrganizationFields{
|
fields: OrganizationFields{
|
||||||
Organizations: []*platform.Organization{},
|
Organizations: []*influxdb.Organization{},
|
||||||
},
|
},
|
||||||
args: args{
|
args: args{
|
||||||
name: "abc",
|
name: "abc",
|
||||||
},
|
},
|
||||||
wants: wants{
|
wants: wants{
|
||||||
err: &platform.Error{
|
err: &influxdb.Error{
|
||||||
Code: platform.ENotFound,
|
Code: influxdb.ENotFound,
|
||||||
Op: platform.OpFindOrganization,
|
Op: influxdb.OpFindOrganization,
|
||||||
Msg: "organization name \"abc\" not found",
|
Msg: "organization name \"abc\" not found",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -780,11 +912,11 @@ func FindOrganization(
|
||||||
s, opPrefix, done := init(tt.fields, t)
|
s, opPrefix, done := init(tt.fields, t)
|
||||||
defer done()
|
defer done()
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
filter := platform.OrganizationFilter{}
|
filter := influxdb.OrganizationFilter{}
|
||||||
if tt.args.name != "" {
|
if tt.args.name != "" {
|
||||||
filter.Name = &tt.args.name
|
filter.Name = &tt.args.name
|
||||||
}
|
}
|
||||||
if tt.args.id != platform.InvalidID() {
|
if tt.args.id != influxdb.InvalidID() {
|
||||||
filter.ID = &tt.args.id
|
filter.ID = &tt.args.id
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -800,17 +932,17 @@ func FindOrganization(
|
||||||
|
|
||||||
// UpdateOrganization testing
|
// UpdateOrganization testing
|
||||||
func UpdateOrganization(
|
func UpdateOrganization(
|
||||||
init func(OrganizationFields, *testing.T) (platform.OrganizationService, string, func()),
|
init func(OrganizationFields, *testing.T) (influxdb.OrganizationService, string, func()),
|
||||||
t *testing.T,
|
t *testing.T,
|
||||||
) {
|
) {
|
||||||
type args struct {
|
type args struct {
|
||||||
id platform.ID
|
id influxdb.ID
|
||||||
name *string
|
name *string
|
||||||
description *string
|
description *string
|
||||||
}
|
}
|
||||||
type wants struct {
|
type wants struct {
|
||||||
err error
|
err error
|
||||||
organization *platform.Organization
|
organization *influxdb.Organization
|
||||||
}
|
}
|
||||||
|
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
|
@ -823,7 +955,7 @@ func UpdateOrganization(
|
||||||
name: "update id not exists",
|
name: "update id not exists",
|
||||||
fields: OrganizationFields{
|
fields: OrganizationFields{
|
||||||
TimeGenerator: mock.TimeGenerator{FakeValue: time.Date(2006, 5, 4, 1, 2, 3, 0, time.UTC)},
|
TimeGenerator: mock.TimeGenerator{FakeValue: time.Date(2006, 5, 4, 1, 2, 3, 0, time.UTC)},
|
||||||
Organizations: []*platform.Organization{
|
Organizations: []*influxdb.Organization{
|
||||||
{
|
{
|
||||||
ID: MustIDBase16(orgOneID),
|
ID: MustIDBase16(orgOneID),
|
||||||
Name: "organization1",
|
Name: "organization1",
|
||||||
|
@ -839,9 +971,9 @@ func UpdateOrganization(
|
||||||
name: strPtr("changed"),
|
name: strPtr("changed"),
|
||||||
},
|
},
|
||||||
wants: wants{
|
wants: wants{
|
||||||
err: &platform.Error{
|
err: &influxdb.Error{
|
||||||
Code: platform.ENotFound,
|
Code: influxdb.ENotFound,
|
||||||
Op: platform.OpUpdateOrganization,
|
Op: influxdb.OpUpdateOrganization,
|
||||||
Msg: "organization not found",
|
Msg: "organization not found",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -850,7 +982,7 @@ func UpdateOrganization(
|
||||||
name: "update name",
|
name: "update name",
|
||||||
fields: OrganizationFields{
|
fields: OrganizationFields{
|
||||||
TimeGenerator: mock.TimeGenerator{FakeValue: time.Date(2006, 5, 4, 1, 2, 3, 0, time.UTC)},
|
TimeGenerator: mock.TimeGenerator{FakeValue: time.Date(2006, 5, 4, 1, 2, 3, 0, time.UTC)},
|
||||||
Organizations: []*platform.Organization{
|
Organizations: []*influxdb.Organization{
|
||||||
{
|
{
|
||||||
ID: MustIDBase16(orgOneID),
|
ID: MustIDBase16(orgOneID),
|
||||||
Name: "organization1",
|
Name: "organization1",
|
||||||
|
@ -866,10 +998,10 @@ func UpdateOrganization(
|
||||||
name: strPtr("changed"),
|
name: strPtr("changed"),
|
||||||
},
|
},
|
||||||
wants: wants{
|
wants: wants{
|
||||||
organization: &platform.Organization{
|
organization: &influxdb.Organization{
|
||||||
ID: MustIDBase16(orgOneID),
|
ID: MustIDBase16(orgOneID),
|
||||||
Name: "changed",
|
Name: "changed",
|
||||||
CRUDLog: platform.CRUDLog{
|
CRUDLog: influxdb.CRUDLog{
|
||||||
UpdatedAt: time.Date(2006, 5, 4, 1, 2, 3, 0, time.UTC),
|
UpdatedAt: time.Date(2006, 5, 4, 1, 2, 3, 0, time.UTC),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -879,7 +1011,7 @@ func UpdateOrganization(
|
||||||
name: "update name not unique",
|
name: "update name not unique",
|
||||||
fields: OrganizationFields{
|
fields: OrganizationFields{
|
||||||
TimeGenerator: mock.TimeGenerator{FakeValue: time.Date(2006, 5, 4, 1, 2, 3, 0, time.UTC)},
|
TimeGenerator: mock.TimeGenerator{FakeValue: time.Date(2006, 5, 4, 1, 2, 3, 0, time.UTC)},
|
||||||
Organizations: []*platform.Organization{
|
Organizations: []*influxdb.Organization{
|
||||||
{
|
{
|
||||||
ID: MustIDBase16(orgOneID),
|
ID: MustIDBase16(orgOneID),
|
||||||
Name: "organization1",
|
Name: "organization1",
|
||||||
|
@ -895,9 +1027,9 @@ func UpdateOrganization(
|
||||||
name: strPtr("organization2"),
|
name: strPtr("organization2"),
|
||||||
},
|
},
|
||||||
wants: wants{
|
wants: wants{
|
||||||
err: &platform.Error{
|
err: &influxdb.Error{
|
||||||
Code: platform.EConflict,
|
Code: influxdb.EConflict,
|
||||||
Op: platform.OpUpdateOrganization,
|
Op: influxdb.OpUpdateOrganization,
|
||||||
Msg: "organization with name organization2 already exists",
|
Msg: "organization with name organization2 already exists",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -906,7 +1038,7 @@ func UpdateOrganization(
|
||||||
name: "update name is empty",
|
name: "update name is empty",
|
||||||
fields: OrganizationFields{
|
fields: OrganizationFields{
|
||||||
TimeGenerator: mock.TimeGenerator{FakeValue: time.Date(2006, 5, 4, 1, 2, 3, 0, time.UTC)},
|
TimeGenerator: mock.TimeGenerator{FakeValue: time.Date(2006, 5, 4, 1, 2, 3, 0, time.UTC)},
|
||||||
Organizations: []*platform.Organization{
|
Organizations: []*influxdb.Organization{
|
||||||
{
|
{
|
||||||
ID: MustIDBase16(orgOneID),
|
ID: MustIDBase16(orgOneID),
|
||||||
Name: "organization1",
|
Name: "organization1",
|
||||||
|
@ -922,14 +1054,14 @@ func UpdateOrganization(
|
||||||
name: strPtr(""),
|
name: strPtr(""),
|
||||||
},
|
},
|
||||||
wants: wants{
|
wants: wants{
|
||||||
err: platform.ErrOrgNameisEmpty,
|
err: influxdb.ErrOrgNameisEmpty,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "update name only has space",
|
name: "update name only has space",
|
||||||
fields: OrganizationFields{
|
fields: OrganizationFields{
|
||||||
TimeGenerator: mock.TimeGenerator{FakeValue: time.Date(2006, 5, 4, 1, 2, 3, 0, time.UTC)},
|
TimeGenerator: mock.TimeGenerator{FakeValue: time.Date(2006, 5, 4, 1, 2, 3, 0, time.UTC)},
|
||||||
Organizations: []*platform.Organization{
|
Organizations: []*influxdb.Organization{
|
||||||
{
|
{
|
||||||
ID: MustIDBase16(orgOneID),
|
ID: MustIDBase16(orgOneID),
|
||||||
Name: "organization1",
|
Name: "organization1",
|
||||||
|
@ -945,14 +1077,14 @@ func UpdateOrganization(
|
||||||
name: strPtr(" "),
|
name: strPtr(" "),
|
||||||
},
|
},
|
||||||
wants: wants{
|
wants: wants{
|
||||||
err: platform.ErrOrgNameisEmpty,
|
err: influxdb.ErrOrgNameisEmpty,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "update description",
|
name: "update description",
|
||||||
fields: OrganizationFields{
|
fields: OrganizationFields{
|
||||||
TimeGenerator: mock.TimeGenerator{FakeValue: time.Date(2006, 5, 4, 1, 2, 3, 0, time.UTC)},
|
TimeGenerator: mock.TimeGenerator{FakeValue: time.Date(2006, 5, 4, 1, 2, 3, 0, time.UTC)},
|
||||||
Organizations: []*platform.Organization{
|
Organizations: []*influxdb.Organization{
|
||||||
{
|
{
|
||||||
ID: MustIDBase16(orgOneID),
|
ID: MustIDBase16(orgOneID),
|
||||||
Name: "organization1",
|
Name: "organization1",
|
||||||
|
@ -970,11 +1102,11 @@ func UpdateOrganization(
|
||||||
description: strPtr("changed"),
|
description: strPtr("changed"),
|
||||||
},
|
},
|
||||||
wants: wants{
|
wants: wants{
|
||||||
organization: &platform.Organization{
|
organization: &influxdb.Organization{
|
||||||
ID: MustIDBase16(orgOneID),
|
ID: MustIDBase16(orgOneID),
|
||||||
Name: "organization1",
|
Name: "organization1",
|
||||||
Description: "changed",
|
Description: "changed",
|
||||||
CRUDLog: platform.CRUDLog{
|
CRUDLog: influxdb.CRUDLog{
|
||||||
UpdatedAt: time.Date(2006, 5, 4, 1, 2, 3, 0, time.UTC),
|
UpdatedAt: time.Date(2006, 5, 4, 1, 2, 3, 0, time.UTC),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -988,7 +1120,7 @@ func UpdateOrganization(
|
||||||
defer done()
|
defer done()
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
|
|
||||||
upd := platform.OrganizationUpdate{}
|
upd := influxdb.OrganizationUpdate{}
|
||||||
upd.Name = tt.args.name
|
upd.Name = tt.args.name
|
||||||
upd.Description = tt.args.description
|
upd.Description = tt.args.description
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue