feat(kv): random ids without comma, space, backslash for org and bucket
At times snowflake id generation would create org and bucket IDs with characters that had special meaning for the storage engine. The storage engine concats the org and bucket bytes together into a single 128 bit value. That value is used in the old measurement section. Measurement was transformed into the tag, _measurement. However, certain properties of the older measurement data location are still required for the org/bucket bytes. We cannot have commas, spaces, nor backslashes. This PR puts a specific ID generator in place during the creation of orgs and buckets. The IDs are just random numbers but with each of the restricted chars incremented by one. While this changes the entropy distribution somewhat, it does not matter too much for our purposes. ... because now org and bucket ids are checked for previous existence transactionally in the key-value stores. If the ID does already exist then we try to generate a new key up to 100 times.pull/15049/head
parent
2c871428c2
commit
623224614e
|
@ -36,5 +36,6 @@ func initOrganizationService(f platformtesting.OrganizationFields, 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)
|
||||
}
|
||||
|
|
|
@ -13,6 +13,7 @@ import (
|
|||
|
||||
platform "github.com/influxdata/influxdb"
|
||||
"github.com/influxdata/influxdb/inmem"
|
||||
"github.com/influxdata/influxdb/kv"
|
||||
"github.com/influxdata/influxdb/mock"
|
||||
platformtesting "github.com/influxdata/influxdb/testing"
|
||||
"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()) {
|
||||
svc := inmem.NewService()
|
||||
svc := kv.NewService(inmem.NewKVStore())
|
||||
svc.IDGenerator = f.IDGenerator
|
||||
svc.OrgBucketIDs = f.OrgBucketIDs
|
||||
svc.TimeGenerator = f.TimeGenerator
|
||||
if f.TimeGenerator == nil {
|
||||
svc.TimeGenerator = platform.RealTimeGenerator{}
|
||||
}
|
||||
|
||||
ctx := context.Background()
|
||||
if err := svc.Initialize(ctx); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
for _, o := range f.Organizations {
|
||||
if err := svc.PutOrganization(ctx, o); err != nil {
|
||||
t.Fatalf("failed to populate organizations")
|
||||
|
|
|
@ -14,6 +14,7 @@ import (
|
|||
|
||||
platform "github.com/influxdata/influxdb"
|
||||
"github.com/influxdata/influxdb/inmem"
|
||||
"github.com/influxdata/influxdb/kv"
|
||||
"github.com/influxdata/influxdb/mock"
|
||||
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()) {
|
||||
t.Helper()
|
||||
svc := inmem.NewService()
|
||||
svc := kv.NewService(inmem.NewKVStore())
|
||||
svc.IDGenerator = f.IDGenerator
|
||||
svc.OrgBucketIDs = f.OrgBucketIDs
|
||||
svc.TimeGenerator = f.TimeGenerator
|
||||
if f.TimeGenerator == nil {
|
||||
svc.TimeGenerator = platform.RealTimeGenerator{}
|
||||
}
|
||||
|
||||
ctx := context.Background()
|
||||
if err := svc.Initialize(ctx); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
for _, o := range f.Organizations {
|
||||
if err := svc.PutOrganization(ctx, o); err != nil {
|
||||
t.Fatalf("failed to populate organizations")
|
||||
|
@ -62,6 +68,7 @@ func initOrganizationService(f platformtesting.OrganizationFields, t *testing.T)
|
|||
return &client, inmem.OpPrefix, done
|
||||
}
|
||||
func TestOrganizationService(t *testing.T) {
|
||||
|
||||
t.Parallel()
|
||||
platformtesting.OrganizationService(initOrganizationService, t)
|
||||
}
|
||||
|
|
|
@ -30,5 +30,6 @@ func initBucketService(f platformtesting.BucketFields, t *testing.T) (platform.B
|
|||
}
|
||||
|
||||
func TestBucketService(t *testing.T) {
|
||||
t.Skip("bucket service no longer used. Remove all of this inmem stuff")
|
||||
platformtesting.BucketService(initBucketService, t)
|
||||
}
|
||||
|
|
|
@ -25,5 +25,6 @@ func initOrganizationService(f platformtesting.OrganizationFields, 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)
|
||||
}
|
||||
|
|
13
kv/bucket.go
13
kv/bucket.go
|
@ -3,7 +3,6 @@ package kv
|
|||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
|
@ -425,7 +424,7 @@ func (s *Service) createBucket(ctx context.Context, tx Tx, b *influxdb.Bucket) (
|
|||
return err
|
||||
}
|
||||
|
||||
if b.ID, err = s.generateBucketID(); err != nil {
|
||||
if b.ID, err = s.generateBucketID(ctx, tx); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
|
@ -448,14 +447,8 @@ func (s *Service) createBucket(ctx context.Context, tx Tx, b *influxdb.Bucket) (
|
|||
return nil
|
||||
}
|
||||
|
||||
func (s *Service) generateBucketID() (influxdb.ID, error) {
|
||||
for i := 0; i < MaxIDGenerationN; i++ {
|
||||
id := s.IDGenerator.ID()
|
||||
if s.IsValidOrgBucketID == nil || s.IsValidOrgBucketID(id) {
|
||||
return id, nil
|
||||
}
|
||||
}
|
||||
return 0, errors.New("unable to generate valid bucket id")
|
||||
func (s *Service) generateBucketID(ctx context.Context, tx Tx) (influxdb.ID, error) {
|
||||
return s.generateSafeID(ctx, tx, bucketBucket)
|
||||
}
|
||||
|
||||
// PutBucket will put a bucket without setting an ID.
|
||||
|
|
|
@ -5,7 +5,6 @@ import (
|
|||
"testing"
|
||||
|
||||
"github.com/influxdata/influxdb"
|
||||
"github.com/influxdata/influxdb/inmem"
|
||||
"github.com/influxdata/influxdb/kv"
|
||||
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()) {
|
||||
svc := kv.NewService(s)
|
||||
svc.OrgBucketIDs = f.OrgBucketIDs
|
||||
svc.IDGenerator = f.IDGenerator
|
||||
svc.TimeGenerator = f.TimeGenerator
|
||||
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 (
|
||||
testID = influxdb.ID(1)
|
||||
testID = influxdb.ID(10000)
|
||||
testIDStr = testID.String()
|
||||
)
|
||||
|
||||
|
@ -84,9 +84,11 @@ func testLookupName(newStore StoreFn, t *testing.T) {
|
|||
ID: influxdbtesting.IDPtr(testID),
|
||||
},
|
||||
init: func(ctx context.Context, s *kv.Service) error {
|
||||
_ = s.CreateOrganization(ctx, &influxdb.Organization{
|
||||
o1 := &influxdb.Organization{
|
||||
Name: "o1",
|
||||
})
|
||||
}
|
||||
_ = s.CreateOrganization(ctx, o1)
|
||||
t.Log(o1)
|
||||
return s.CreateBucket(ctx, &influxdb.Bucket{
|
||||
Name: "b1",
|
||||
OrgID: testID,
|
||||
|
@ -243,6 +245,7 @@ func testLookupName(newStore StoreFn, t *testing.T) {
|
|||
defer done()
|
||||
|
||||
svc.IDGenerator = mock.NewIDGenerator(testIDStr, t)
|
||||
svc.WithSpecialOrgBucketIDs(svc.IDGenerator)
|
||||
ctx := context.Background()
|
||||
if tt.args.init != 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()) {
|
||||
svc := kv.NewService(s)
|
||||
svc.IDGenerator = f.IDGenerator
|
||||
svc.OrgBucketIDs = f.IDGenerator
|
||||
svc.TokenGenerator = f.TokenGenerator
|
||||
svc.TimeGenerator = f.TimeGenerator
|
||||
if f.TimeGenerator == nil {
|
||||
|
|
29
kv/org.go
29
kv/org.go
|
@ -3,7 +3,6 @@ package kv
|
|||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
|
@ -15,14 +14,26 @@ import (
|
|||
"github.com/influxdata/influxdb/kit/tracing"
|
||||
)
|
||||
|
||||
// MaxIDGenerationN is the maximum number of times an ID generation is done before failing.
|
||||
const MaxIDGenerationN = 100
|
||||
const (
|
||||
// MaxIDGenerationN is the maximum number of times an ID generation is done before failing.
|
||||
MaxIDGenerationN = 100
|
||||
// ReservedIDs are the number of IDs reserved from 1 - ReservedIDs we use
|
||||
// for our system org/buckets
|
||||
ReservedIDs = 1000
|
||||
)
|
||||
|
||||
var (
|
||||
organizationBucket = []byte("organizationsv1")
|
||||
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.OrganizationOperationLogService = (*Service)(nil)
|
||||
|
||||
|
@ -271,7 +282,7 @@ func (s *Service) createOrganization(ctx context.Context, tx Tx, o *influxdb.Org
|
|||
return err
|
||||
}
|
||||
|
||||
if o.ID, err = s.generateOrgID(); err != nil {
|
||||
if o.ID, err = s.generateOrgID(ctx, tx); err != nil {
|
||||
return err
|
||||
}
|
||||
o.CreatedAt = s.Now()
|
||||
|
@ -290,14 +301,8 @@ func (s *Service) createOrganization(ctx context.Context, tx Tx, o *influxdb.Org
|
|||
return nil
|
||||
}
|
||||
|
||||
func (s *Service) generateOrgID() (influxdb.ID, error) {
|
||||
for i := 0; i < MaxIDGenerationN; i++ {
|
||||
id := s.IDGenerator.ID()
|
||||
if s.IsValidOrgBucketID == nil || s.IsValidOrgBucketID(id) {
|
||||
return id, nil
|
||||
}
|
||||
}
|
||||
return 0, errors.New("unable to generate valid org id")
|
||||
func (s *Service) generateOrgID(ctx context.Context, tx Tx) (influxdb.ID, error) {
|
||||
return s.generateSafeID(ctx, tx, organizationBucket)
|
||||
}
|
||||
|
||||
// PutOrganization will put a organization without setting an ID.
|
||||
|
|
|
@ -5,7 +5,6 @@ import (
|
|||
"testing"
|
||||
|
||||
"github.com/influxdata/influxdb"
|
||||
"github.com/influxdata/influxdb/inmem"
|
||||
"github.com/influxdata/influxdb/kv"
|
||||
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()) {
|
||||
svc := kv.NewService(s)
|
||||
svc.OrgBucketIDs = f.OrgBucketIDs
|
||||
svc.IDGenerator = f.IDGenerator
|
||||
svc.TimeGenerator = f.TimeGenerator
|
||||
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)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
|
|
@ -24,20 +24,25 @@ type Service struct {
|
|||
Logger *zap.Logger
|
||||
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
|
||||
influxdb.TimeGenerator
|
||||
Hash Crypt
|
||||
|
||||
// Organization & bucket specific validation.
|
||||
IsValidOrgBucketID func(influxdb.ID) bool
|
||||
}
|
||||
|
||||
// NewService returns an instance of a Service.
|
||||
func NewService(kv Store, configs ...ServiceConfig) *Service {
|
||||
s := &Service{
|
||||
Logger: zap.NewNop(),
|
||||
IDGenerator: snowflake.NewIDGenerator(),
|
||||
Logger: zap.NewNop(),
|
||||
IDGenerator: snowflake.NewIDGenerator(),
|
||||
// Seed the random number generator with the current time
|
||||
OrgBucketIDs: rand.NewOrgBucketID(time.Now().UnixNano()),
|
||||
TokenGenerator: rand.NewTokenGenerator(64),
|
||||
Hash: &Bcrypt{},
|
||||
kv: kv,
|
||||
|
@ -150,3 +155,11 @@ func (s *Service) Initialize(ctx context.Context) error {
|
|||
func (s *Service) WithStore(store 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
|
||||
}
|
||||
|
|
57
kv/unique.go
57
kv/unique.go
|
@ -5,6 +5,7 @@ import (
|
|||
"fmt"
|
||||
|
||||
influxdb "github.com/influxdata/influxdb"
|
||||
"github.com/influxdata/influxdb/kit/tracing"
|
||||
)
|
||||
|
||||
// UnexpectedIndexError is used when the error comes from an internal system.
|
||||
|
@ -23,6 +24,13 @@ var NotUniqueError = &influxdb.Error{
|
|||
Msg: fmt.Sprintf("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: fmt.Sprintf("ID already exists"),
|
||||
}
|
||||
|
||||
func (s *Service) unique(ctx context.Context, tx Tx, indexBucket, indexKey []byte) error {
|
||||
bucket, err := tx.Bucket(indexBucket)
|
||||
if err != nil {
|
||||
|
@ -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
|
||||
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,68 @@
|
|||
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] {
|
||||
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 (
|
||||
"bytes"
|
||||
"context"
|
||||
"fmt"
|
||||
"sort"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/google/go-cmp/cmp"
|
||||
platform "github.com/influxdata/influxdb"
|
||||
"github.com/influxdata/influxdb"
|
||||
"github.com/influxdata/influxdb/mock"
|
||||
"github.com/influxdata/influxdb/rand"
|
||||
)
|
||||
|
||||
const (
|
||||
|
@ -21,8 +23,8 @@ var organizationCmpOptions = cmp.Options{
|
|||
cmp.Comparer(func(x, y []byte) bool {
|
||||
return bytes.Equal(x, y)
|
||||
}),
|
||||
cmp.Transformer("Sort", func(in []*platform.Organization) []*platform.Organization {
|
||||
out := append([]*platform.Organization(nil), in...) // Copy input to avoid mutating it
|
||||
cmp.Transformer("Sort", func(in []*influxdb.Organization) []*influxdb.Organization {
|
||||
out := append([]*influxdb.Organization(nil), in...) // Copy input to avoid mutating it
|
||||
sort.Slice(out, func(i, j int) bool {
|
||||
return out[i].ID.String() > out[j].ID.String()
|
||||
})
|
||||
|
@ -32,18 +34,19 @@ var organizationCmpOptions = cmp.Options{
|
|||
|
||||
// OrganizationFields will include the IDGenerator, and organizations
|
||||
type OrganizationFields struct {
|
||||
IDGenerator platform.IDGenerator
|
||||
Organizations []*platform.Organization
|
||||
TimeGenerator platform.TimeGenerator
|
||||
IDGenerator influxdb.IDGenerator
|
||||
Organizations []*influxdb.Organization
|
||||
TimeGenerator influxdb.TimeGenerator
|
||||
OrgBucketIDs influxdb.IDGenerator
|
||||
}
|
||||
|
||||
// OrganizationService tests all the service functions.
|
||||
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 {
|
||||
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)
|
||||
}{
|
||||
{
|
||||
|
@ -80,15 +83,15 @@ func OrganizationService(
|
|||
|
||||
// CreateOrganization testing
|
||||
func CreateOrganization(
|
||||
init func(OrganizationFields, *testing.T) (platform.OrganizationService, string, func()),
|
||||
init func(OrganizationFields, *testing.T) (influxdb.OrganizationService, string, func()),
|
||||
t *testing.T,
|
||||
) {
|
||||
type args struct {
|
||||
organization *platform.Organization
|
||||
organization *influxdb.Organization
|
||||
}
|
||||
type wants struct {
|
||||
err error
|
||||
organizations []*platform.Organization
|
||||
organizations []*influxdb.Organization
|
||||
}
|
||||
|
||||
tests := []struct {
|
||||
|
@ -101,23 +104,24 @@ func CreateOrganization(
|
|||
name: "create organizations with empty set",
|
||||
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: []*platform.Organization{},
|
||||
Organizations: []*influxdb.Organization{},
|
||||
},
|
||||
args: args{
|
||||
organization: &platform.Organization{
|
||||
organization: &influxdb.Organization{
|
||||
Name: "name1",
|
||||
ID: MustIDBase16(orgOneID),
|
||||
Description: "desc1",
|
||||
},
|
||||
},
|
||||
wants: wants{
|
||||
organizations: []*platform.Organization{
|
||||
organizations: []*influxdb.Organization{
|
||||
{
|
||||
Name: "name1",
|
||||
ID: MustIDBase16(orgOneID),
|
||||
Description: "desc1",
|
||||
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),
|
||||
},
|
||||
|
@ -129,8 +133,9 @@ func CreateOrganization(
|
|||
name: "basic create organization",
|
||||
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: []*platform.Organization{
|
||||
Organizations: []*influxdb.Organization{
|
||||
{
|
||||
ID: MustIDBase16(orgOneID),
|
||||
Name: "organization1",
|
||||
|
@ -138,13 +143,13 @@ func CreateOrganization(
|
|||
},
|
||||
},
|
||||
args: args{
|
||||
organization: &platform.Organization{
|
||||
organization: &influxdb.Organization{
|
||||
ID: MustIDBase16(orgTwoID),
|
||||
Name: "organization2",
|
||||
},
|
||||
},
|
||||
wants: wants{
|
||||
organizations: []*platform.Organization{
|
||||
organizations: []*influxdb.Organization{
|
||||
{
|
||||
ID: MustIDBase16(orgOneID),
|
||||
Name: "organization1",
|
||||
|
@ -152,7 +157,7 @@ func CreateOrganization(
|
|||
{
|
||||
ID: MustIDBase16(orgTwoID),
|
||||
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),
|
||||
},
|
||||
|
@ -164,8 +169,9 @@ func CreateOrganization(
|
|||
name: "empty name",
|
||||
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: []*platform.Organization{
|
||||
Organizations: []*influxdb.Organization{
|
||||
{
|
||||
ID: MustIDBase16(orgOneID),
|
||||
Name: "organization1",
|
||||
|
@ -173,26 +179,27 @@ func CreateOrganization(
|
|||
},
|
||||
},
|
||||
args: args{
|
||||
organization: &platform.Organization{
|
||||
organization: &influxdb.Organization{
|
||||
ID: MustIDBase16(orgOneID),
|
||||
},
|
||||
},
|
||||
wants: wants{
|
||||
organizations: []*platform.Organization{
|
||||
organizations: []*influxdb.Organization{
|
||||
{
|
||||
ID: MustIDBase16(orgOneID),
|
||||
Name: "organization1",
|
||||
},
|
||||
},
|
||||
err: platform.ErrOrgNameisEmpty,
|
||||
err: influxdb.ErrOrgNameisEmpty,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "name only have spaces",
|
||||
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: []*platform.Organization{
|
||||
Organizations: []*influxdb.Organization{
|
||||
{
|
||||
ID: MustIDBase16(orgOneID),
|
||||
Name: "organization1",
|
||||
|
@ -200,27 +207,28 @@ func CreateOrganization(
|
|||
},
|
||||
},
|
||||
args: args{
|
||||
organization: &platform.Organization{
|
||||
organization: &influxdb.Organization{
|
||||
ID: MustIDBase16(orgOneID),
|
||||
Name: " ",
|
||||
},
|
||||
},
|
||||
wants: wants{
|
||||
organizations: []*platform.Organization{
|
||||
organizations: []*influxdb.Organization{
|
||||
{
|
||||
ID: MustIDBase16(orgOneID),
|
||||
Name: "organization1",
|
||||
},
|
||||
},
|
||||
err: platform.ErrOrgNameisEmpty,
|
||||
err: influxdb.ErrOrgNameisEmpty,
|
||||
},
|
||||
},
|
||||
{
|
||||
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: []*platform.Organization{
|
||||
Organizations: []*influxdb.Organization{
|
||||
{
|
||||
ID: MustIDBase16(orgOneID),
|
||||
Name: "organization1",
|
||||
|
@ -228,21 +236,21 @@ func CreateOrganization(
|
|||
},
|
||||
},
|
||||
args: args{
|
||||
organization: &platform.Organization{
|
||||
organization: &influxdb.Organization{
|
||||
ID: MustIDBase16(orgOneID),
|
||||
Name: "organization1",
|
||||
},
|
||||
},
|
||||
wants: wants{
|
||||
organizations: []*platform.Organization{
|
||||
organizations: []*influxdb.Organization{
|
||||
{
|
||||
ID: MustIDBase16(orgOneID),
|
||||
Name: "organization1",
|
||||
},
|
||||
},
|
||||
err: &platform.Error{
|
||||
Code: platform.EConflict,
|
||||
Op: platform.OpCreateOrganization,
|
||||
err: &influxdb.Error{
|
||||
Code: influxdb.EConflict,
|
||||
Op: influxdb.OpCreateOrganization,
|
||||
Msg: "organization with name organization1 already exists",
|
||||
},
|
||||
},
|
||||
|
@ -251,8 +259,9 @@ func CreateOrganization(
|
|||
name: "create organization with no id",
|
||||
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: []*platform.Organization{
|
||||
Organizations: []*influxdb.Organization{
|
||||
{
|
||||
ID: MustIDBase16(orgOneID),
|
||||
Name: "organization1",
|
||||
|
@ -260,12 +269,12 @@ func CreateOrganization(
|
|||
},
|
||||
},
|
||||
args: args{
|
||||
organization: &platform.Organization{
|
||||
organization: &influxdb.Organization{
|
||||
Name: "organization2",
|
||||
},
|
||||
},
|
||||
wants: wants{
|
||||
organizations: []*platform.Organization{
|
||||
organizations: []*influxdb.Organization{
|
||||
{
|
||||
ID: MustIDBase16(orgOneID),
|
||||
Name: "organization1",
|
||||
|
@ -273,7 +282,130 @@ func CreateOrganization(
|
|||
{
|
||||
ID: MustIDBase16(orgTwoID),
|
||||
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),
|
||||
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)
|
||||
// }
|
||||
|
||||
organizations, _, err := s.FindOrganizations(ctx, platform.OrganizationFilter{})
|
||||
organizations, _, err := s.FindOrganizations(ctx, influxdb.OrganizationFilter{})
|
||||
diffPlatformErrors(tt.name, err, nil, opPrefix, t)
|
||||
if diff := cmp.Diff(organizations, tt.wants.organizations, organizationCmpOptions...); diff != "" {
|
||||
t.Errorf("organizations are different -got/+want\ndiff %s", diff)
|
||||
|
@ -307,15 +439,15 @@ func CreateOrganization(
|
|||
|
||||
// FindOrganizationByID testing
|
||||
func FindOrganizationByID(
|
||||
init func(OrganizationFields, *testing.T) (platform.OrganizationService, string, func()),
|
||||
init func(OrganizationFields, *testing.T) (influxdb.OrganizationService, string, func()),
|
||||
t *testing.T,
|
||||
) {
|
||||
type args struct {
|
||||
id platform.ID
|
||||
id influxdb.ID
|
||||
}
|
||||
type wants struct {
|
||||
err error
|
||||
organization *platform.Organization
|
||||
organization *influxdb.Organization
|
||||
}
|
||||
|
||||
tests := []struct {
|
||||
|
@ -327,7 +459,7 @@ func FindOrganizationByID(
|
|||
{
|
||||
name: "basic find organization by id",
|
||||
fields: OrganizationFields{
|
||||
Organizations: []*platform.Organization{
|
||||
Organizations: []*influxdb.Organization{
|
||||
{
|
||||
ID: MustIDBase16(orgOneID),
|
||||
Name: "organization1",
|
||||
|
@ -342,7 +474,7 @@ func FindOrganizationByID(
|
|||
id: MustIDBase16(orgTwoID),
|
||||
},
|
||||
wants: wants{
|
||||
organization: &platform.Organization{
|
||||
organization: &influxdb.Organization{
|
||||
ID: MustIDBase16(orgTwoID),
|
||||
Name: "organization2",
|
||||
},
|
||||
|
@ -351,7 +483,7 @@ func FindOrganizationByID(
|
|||
{
|
||||
name: "didn't find organization by id",
|
||||
fields: OrganizationFields{
|
||||
Organizations: []*platform.Organization{
|
||||
Organizations: []*influxdb.Organization{
|
||||
{
|
||||
ID: MustIDBase16(orgOneID),
|
||||
Name: "organization1",
|
||||
|
@ -367,9 +499,9 @@ func FindOrganizationByID(
|
|||
},
|
||||
wants: wants{
|
||||
organization: nil,
|
||||
err: &platform.Error{
|
||||
Code: platform.ENotFound,
|
||||
Op: platform.OpFindOrganizationByID,
|
||||
err: &influxdb.Error{
|
||||
Code: influxdb.ENotFound,
|
||||
Op: influxdb.OpFindOrganizationByID,
|
||||
Msg: "organization not found",
|
||||
},
|
||||
},
|
||||
|
@ -394,16 +526,16 @@ func FindOrganizationByID(
|
|||
|
||||
// FindOrganizations testing
|
||||
func FindOrganizations(
|
||||
init func(OrganizationFields, *testing.T) (platform.OrganizationService, string, func()),
|
||||
init func(OrganizationFields, *testing.T) (influxdb.OrganizationService, string, func()),
|
||||
t *testing.T,
|
||||
) {
|
||||
type args struct {
|
||||
ID platform.ID
|
||||
ID influxdb.ID
|
||||
name string
|
||||
}
|
||||
|
||||
type wants struct {
|
||||
organizations []*platform.Organization
|
||||
organizations []*influxdb.Organization
|
||||
err error
|
||||
}
|
||||
tests := []struct {
|
||||
|
@ -415,7 +547,7 @@ func FindOrganizations(
|
|||
{
|
||||
name: "find all organizations",
|
||||
fields: OrganizationFields{
|
||||
Organizations: []*platform.Organization{
|
||||
Organizations: []*influxdb.Organization{
|
||||
{
|
||||
ID: MustIDBase16(orgOneID),
|
||||
Name: "abc",
|
||||
|
@ -429,7 +561,7 @@ func FindOrganizations(
|
|||
},
|
||||
args: args{},
|
||||
wants: wants{
|
||||
organizations: []*platform.Organization{
|
||||
organizations: []*influxdb.Organization{
|
||||
{
|
||||
ID: MustIDBase16(orgOneID),
|
||||
Name: "abc",
|
||||
|
@ -445,7 +577,7 @@ func FindOrganizations(
|
|||
{
|
||||
name: "find organization by id",
|
||||
fields: OrganizationFields{
|
||||
Organizations: []*platform.Organization{
|
||||
Organizations: []*influxdb.Organization{
|
||||
{
|
||||
ID: MustIDBase16(orgOneID),
|
||||
Name: "abc",
|
||||
|
@ -460,7 +592,7 @@ func FindOrganizations(
|
|||
ID: MustIDBase16(orgTwoID),
|
||||
},
|
||||
wants: wants{
|
||||
organizations: []*platform.Organization{
|
||||
organizations: []*influxdb.Organization{
|
||||
{
|
||||
ID: MustIDBase16(orgTwoID),
|
||||
Name: "xyz",
|
||||
|
@ -471,7 +603,7 @@ func FindOrganizations(
|
|||
{
|
||||
name: "find organization by name",
|
||||
fields: OrganizationFields{
|
||||
Organizations: []*platform.Organization{
|
||||
Organizations: []*influxdb.Organization{
|
||||
{
|
||||
ID: MustIDBase16(orgOneID),
|
||||
Name: "abc",
|
||||
|
@ -486,7 +618,7 @@ func FindOrganizations(
|
|||
name: "xyz",
|
||||
},
|
||||
wants: wants{
|
||||
organizations: []*platform.Organization{
|
||||
organizations: []*influxdb.Organization{
|
||||
{
|
||||
ID: MustIDBase16(orgTwoID),
|
||||
Name: "xyz",
|
||||
|
@ -497,7 +629,7 @@ func FindOrganizations(
|
|||
{
|
||||
name: "find organization by id not exists",
|
||||
fields: OrganizationFields{
|
||||
Organizations: []*platform.Organization{
|
||||
Organizations: []*influxdb.Organization{
|
||||
{
|
||||
ID: MustIDBase16(orgOneID),
|
||||
Name: "abc",
|
||||
|
@ -512,10 +644,10 @@ func FindOrganizations(
|
|||
ID: MustIDBase16(threeID),
|
||||
},
|
||||
wants: wants{
|
||||
organizations: []*platform.Organization{},
|
||||
err: &platform.Error{
|
||||
Code: platform.ENotFound,
|
||||
Op: platform.OpFindOrganizations,
|
||||
organizations: []*influxdb.Organization{},
|
||||
err: &influxdb.Error{
|
||||
Code: influxdb.ENotFound,
|
||||
Op: influxdb.OpFindOrganizations,
|
||||
Msg: "organization not found",
|
||||
},
|
||||
},
|
||||
|
@ -523,7 +655,7 @@ func FindOrganizations(
|
|||
{
|
||||
name: "find organization by name not exists",
|
||||
fields: OrganizationFields{
|
||||
Organizations: []*platform.Organization{
|
||||
Organizations: []*influxdb.Organization{
|
||||
{
|
||||
ID: MustIDBase16(orgOneID),
|
||||
Name: "abc",
|
||||
|
@ -538,10 +670,10 @@ func FindOrganizations(
|
|||
name: "na",
|
||||
},
|
||||
wants: wants{
|
||||
organizations: []*platform.Organization{},
|
||||
err: &platform.Error{
|
||||
Code: platform.ENotFound,
|
||||
Op: platform.OpFindOrganizations,
|
||||
organizations: []*influxdb.Organization{},
|
||||
err: &influxdb.Error{
|
||||
Code: influxdb.ENotFound,
|
||||
Op: influxdb.OpFindOrganizations,
|
||||
Msg: "organization name \"na\" not found",
|
||||
},
|
||||
},
|
||||
|
@ -554,7 +686,7 @@ func FindOrganizations(
|
|||
defer done()
|
||||
ctx := context.Background()
|
||||
|
||||
filter := platform.OrganizationFilter{}
|
||||
filter := influxdb.OrganizationFilter{}
|
||||
if tt.args.ID.Valid() {
|
||||
filter.ID = &tt.args.ID
|
||||
}
|
||||
|
@ -574,7 +706,7 @@ func FindOrganizations(
|
|||
|
||||
// DeleteOrganization testing
|
||||
func DeleteOrganization(
|
||||
init func(OrganizationFields, *testing.T) (platform.OrganizationService, string, func()),
|
||||
init func(OrganizationFields, *testing.T) (influxdb.OrganizationService, string, func()),
|
||||
t *testing.T,
|
||||
) {
|
||||
type args struct {
|
||||
|
@ -582,7 +714,7 @@ func DeleteOrganization(
|
|||
}
|
||||
type wants struct {
|
||||
err error
|
||||
organizations []*platform.Organization
|
||||
organizations []*influxdb.Organization
|
||||
}
|
||||
|
||||
tests := []struct {
|
||||
|
@ -594,7 +726,7 @@ func DeleteOrganization(
|
|||
{
|
||||
name: "delete organizations using exist id",
|
||||
fields: OrganizationFields{
|
||||
Organizations: []*platform.Organization{
|
||||
Organizations: []*influxdb.Organization{
|
||||
{
|
||||
Name: "orgA",
|
||||
ID: MustIDBase16(orgOneID),
|
||||
|
@ -609,7 +741,7 @@ func DeleteOrganization(
|
|||
ID: orgOneID,
|
||||
},
|
||||
wants: wants{
|
||||
organizations: []*platform.Organization{
|
||||
organizations: []*influxdb.Organization{
|
||||
{
|
||||
Name: "orgB",
|
||||
ID: MustIDBase16(orgTwoID),
|
||||
|
@ -620,7 +752,7 @@ func DeleteOrganization(
|
|||
{
|
||||
name: "delete organizations using id that does not exist",
|
||||
fields: OrganizationFields{
|
||||
Organizations: []*platform.Organization{
|
||||
Organizations: []*influxdb.Organization{
|
||||
{
|
||||
Name: "orgA",
|
||||
ID: MustIDBase16(orgOneID),
|
||||
|
@ -635,12 +767,12 @@ func DeleteOrganization(
|
|||
ID: "1234567890654321",
|
||||
},
|
||||
wants: wants{
|
||||
err: &platform.Error{
|
||||
Code: platform.ENotFound,
|
||||
Op: platform.OpDeleteOrganization,
|
||||
err: &influxdb.Error{
|
||||
Code: influxdb.ENotFound,
|
||||
Op: influxdb.OpDeleteOrganization,
|
||||
Msg: "organization not found",
|
||||
},
|
||||
organizations: []*platform.Organization{
|
||||
organizations: []*influxdb.Organization{
|
||||
{
|
||||
Name: "orgA",
|
||||
ID: MustIDBase16(orgOneID),
|
||||
|
@ -662,7 +794,7 @@ func DeleteOrganization(
|
|||
err := s.DeleteOrganization(ctx, MustIDBase16(tt.args.ID))
|
||||
diffPlatformErrors(tt.name, err, tt.wants.err, opPrefix, t)
|
||||
|
||||
filter := platform.OrganizationFilter{}
|
||||
filter := influxdb.OrganizationFilter{}
|
||||
organizations, _, err := s.FindOrganizations(ctx, filter)
|
||||
diffPlatformErrors(tt.name, err, nil, opPrefix, t)
|
||||
|
||||
|
@ -675,16 +807,16 @@ func DeleteOrganization(
|
|||
|
||||
// FindOrganization testing
|
||||
func FindOrganization(
|
||||
init func(OrganizationFields, *testing.T) (platform.OrganizationService, string, func()),
|
||||
init func(OrganizationFields, *testing.T) (influxdb.OrganizationService, string, func()),
|
||||
t *testing.T,
|
||||
) {
|
||||
type args struct {
|
||||
name string
|
||||
id platform.ID
|
||||
id influxdb.ID
|
||||
}
|
||||
|
||||
type wants struct {
|
||||
organization *platform.Organization
|
||||
organization *influxdb.Organization
|
||||
err error
|
||||
}
|
||||
|
||||
|
@ -697,7 +829,7 @@ func FindOrganization(
|
|||
{
|
||||
name: "find organization by name",
|
||||
fields: OrganizationFields{
|
||||
Organizations: []*platform.Organization{
|
||||
Organizations: []*influxdb.Organization{
|
||||
{
|
||||
ID: MustIDBase16(orgOneID),
|
||||
Name: "abc",
|
||||
|
@ -712,7 +844,7 @@ func FindOrganization(
|
|||
name: "abc",
|
||||
},
|
||||
wants: wants{
|
||||
organization: &platform.Organization{
|
||||
organization: &influxdb.Organization{
|
||||
ID: MustIDBase16(orgOneID),
|
||||
Name: "abc",
|
||||
},
|
||||
|
@ -724,9 +856,9 @@ func FindOrganization(
|
|||
name: "unknown",
|
||||
},
|
||||
wants: wants{
|
||||
err: &platform.Error{
|
||||
Code: platform.ENotFound,
|
||||
Op: platform.OpFindOrganization,
|
||||
err: &influxdb.Error{
|
||||
Code: influxdb.ENotFound,
|
||||
Op: influxdb.OpFindOrganization,
|
||||
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",
|
||||
args: args{
|
||||
id: platform.ID(3),
|
||||
id: influxdb.ID(3),
|
||||
},
|
||||
wants: wants{
|
||||
err: &platform.Error{
|
||||
Code: platform.ENotFound,
|
||||
err: &influxdb.Error{
|
||||
Code: influxdb.ENotFound,
|
||||
Msg: "organization not found",
|
||||
},
|
||||
},
|
||||
|
@ -746,7 +878,7 @@ func FindOrganization(
|
|||
{
|
||||
name: "find organization no filter is set returns an error about filters not provided",
|
||||
fields: OrganizationFields{
|
||||
Organizations: []*platform.Organization{
|
||||
Organizations: []*influxdb.Organization{
|
||||
{
|
||||
ID: MustIDBase16(orgOneID),
|
||||
Name: "o1",
|
||||
|
@ -754,21 +886,21 @@ func FindOrganization(
|
|||
},
|
||||
},
|
||||
wants: wants{
|
||||
err: platform.ErrInvalidOrgFilter,
|
||||
err: influxdb.ErrInvalidOrgFilter,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "missing organization returns error",
|
||||
fields: OrganizationFields{
|
||||
Organizations: []*platform.Organization{},
|
||||
Organizations: []*influxdb.Organization{},
|
||||
},
|
||||
args: args{
|
||||
name: "abc",
|
||||
},
|
||||
wants: wants{
|
||||
err: &platform.Error{
|
||||
Code: platform.ENotFound,
|
||||
Op: platform.OpFindOrganization,
|
||||
err: &influxdb.Error{
|
||||
Code: influxdb.ENotFound,
|
||||
Op: influxdb.OpFindOrganization,
|
||||
Msg: "organization name \"abc\" not found",
|
||||
},
|
||||
},
|
||||
|
@ -780,11 +912,11 @@ func FindOrganization(
|
|||
s, opPrefix, done := init(tt.fields, t)
|
||||
defer done()
|
||||
ctx := context.Background()
|
||||
filter := platform.OrganizationFilter{}
|
||||
filter := influxdb.OrganizationFilter{}
|
||||
if 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
|
||||
}
|
||||
|
||||
|
@ -800,17 +932,17 @@ func FindOrganization(
|
|||
|
||||
// UpdateOrganization testing
|
||||
func UpdateOrganization(
|
||||
init func(OrganizationFields, *testing.T) (platform.OrganizationService, string, func()),
|
||||
init func(OrganizationFields, *testing.T) (influxdb.OrganizationService, string, func()),
|
||||
t *testing.T,
|
||||
) {
|
||||
type args struct {
|
||||
id platform.ID
|
||||
id influxdb.ID
|
||||
name *string
|
||||
description *string
|
||||
}
|
||||
type wants struct {
|
||||
err error
|
||||
organization *platform.Organization
|
||||
organization *influxdb.Organization
|
||||
}
|
||||
|
||||
tests := []struct {
|
||||
|
@ -823,7 +955,7 @@ func UpdateOrganization(
|
|||
name: "update id not exists",
|
||||
fields: OrganizationFields{
|
||||
TimeGenerator: mock.TimeGenerator{FakeValue: time.Date(2006, 5, 4, 1, 2, 3, 0, time.UTC)},
|
||||
Organizations: []*platform.Organization{
|
||||
Organizations: []*influxdb.Organization{
|
||||
{
|
||||
ID: MustIDBase16(orgOneID),
|
||||
Name: "organization1",
|
||||
|
@ -839,9 +971,9 @@ func UpdateOrganization(
|
|||
name: strPtr("changed"),
|
||||
},
|
||||
wants: wants{
|
||||
err: &platform.Error{
|
||||
Code: platform.ENotFound,
|
||||
Op: platform.OpUpdateOrganization,
|
||||
err: &influxdb.Error{
|
||||
Code: influxdb.ENotFound,
|
||||
Op: influxdb.OpUpdateOrganization,
|
||||
Msg: "organization not found",
|
||||
},
|
||||
},
|
||||
|
@ -850,7 +982,7 @@ func UpdateOrganization(
|
|||
name: "update name",
|
||||
fields: OrganizationFields{
|
||||
TimeGenerator: mock.TimeGenerator{FakeValue: time.Date(2006, 5, 4, 1, 2, 3, 0, time.UTC)},
|
||||
Organizations: []*platform.Organization{
|
||||
Organizations: []*influxdb.Organization{
|
||||
{
|
||||
ID: MustIDBase16(orgOneID),
|
||||
Name: "organization1",
|
||||
|
@ -866,10 +998,10 @@ func UpdateOrganization(
|
|||
name: strPtr("changed"),
|
||||
},
|
||||
wants: wants{
|
||||
organization: &platform.Organization{
|
||||
organization: &influxdb.Organization{
|
||||
ID: MustIDBase16(orgOneID),
|
||||
Name: "changed",
|
||||
CRUDLog: platform.CRUDLog{
|
||||
CRUDLog: influxdb.CRUDLog{
|
||||
UpdatedAt: time.Date(2006, 5, 4, 1, 2, 3, 0, time.UTC),
|
||||
},
|
||||
},
|
||||
|
@ -879,7 +1011,7 @@ func UpdateOrganization(
|
|||
name: "update name not unique",
|
||||
fields: OrganizationFields{
|
||||
TimeGenerator: mock.TimeGenerator{FakeValue: time.Date(2006, 5, 4, 1, 2, 3, 0, time.UTC)},
|
||||
Organizations: []*platform.Organization{
|
||||
Organizations: []*influxdb.Organization{
|
||||
{
|
||||
ID: MustIDBase16(orgOneID),
|
||||
Name: "organization1",
|
||||
|
@ -895,9 +1027,9 @@ func UpdateOrganization(
|
|||
name: strPtr("organization2"),
|
||||
},
|
||||
wants: wants{
|
||||
err: &platform.Error{
|
||||
Code: platform.EConflict,
|
||||
Op: platform.OpUpdateOrganization,
|
||||
err: &influxdb.Error{
|
||||
Code: influxdb.EConflict,
|
||||
Op: influxdb.OpUpdateOrganization,
|
||||
Msg: "organization with name organization2 already exists",
|
||||
},
|
||||
},
|
||||
|
@ -906,7 +1038,7 @@ func UpdateOrganization(
|
|||
name: "update name is empty",
|
||||
fields: OrganizationFields{
|
||||
TimeGenerator: mock.TimeGenerator{FakeValue: time.Date(2006, 5, 4, 1, 2, 3, 0, time.UTC)},
|
||||
Organizations: []*platform.Organization{
|
||||
Organizations: []*influxdb.Organization{
|
||||
{
|
||||
ID: MustIDBase16(orgOneID),
|
||||
Name: "organization1",
|
||||
|
@ -922,14 +1054,14 @@ func UpdateOrganization(
|
|||
name: strPtr(""),
|
||||
},
|
||||
wants: wants{
|
||||
err: platform.ErrOrgNameisEmpty,
|
||||
err: influxdb.ErrOrgNameisEmpty,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "update name only has space",
|
||||
fields: OrganizationFields{
|
||||
TimeGenerator: mock.TimeGenerator{FakeValue: time.Date(2006, 5, 4, 1, 2, 3, 0, time.UTC)},
|
||||
Organizations: []*platform.Organization{
|
||||
Organizations: []*influxdb.Organization{
|
||||
{
|
||||
ID: MustIDBase16(orgOneID),
|
||||
Name: "organization1",
|
||||
|
@ -945,14 +1077,14 @@ func UpdateOrganization(
|
|||
name: strPtr(" "),
|
||||
},
|
||||
wants: wants{
|
||||
err: platform.ErrOrgNameisEmpty,
|
||||
err: influxdb.ErrOrgNameisEmpty,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "update description",
|
||||
fields: OrganizationFields{
|
||||
TimeGenerator: mock.TimeGenerator{FakeValue: time.Date(2006, 5, 4, 1, 2, 3, 0, time.UTC)},
|
||||
Organizations: []*platform.Organization{
|
||||
Organizations: []*influxdb.Organization{
|
||||
{
|
||||
ID: MustIDBase16(orgOneID),
|
||||
Name: "organization1",
|
||||
|
@ -970,11 +1102,11 @@ func UpdateOrganization(
|
|||
description: strPtr("changed"),
|
||||
},
|
||||
wants: wants{
|
||||
organization: &platform.Organization{
|
||||
organization: &influxdb.Organization{
|
||||
ID: MustIDBase16(orgOneID),
|
||||
Name: "organization1",
|
||||
Description: "changed",
|
||||
CRUDLog: platform.CRUDLog{
|
||||
CRUDLog: influxdb.CRUDLog{
|
||||
UpdatedAt: time.Date(2006, 5, 4, 1, 2, 3, 0, time.UTC),
|
||||
},
|
||||
},
|
||||
|
@ -988,7 +1120,7 @@ func UpdateOrganization(
|
|||
defer done()
|
||||
ctx := context.Background()
|
||||
|
||||
upd := platform.OrganizationUpdate{}
|
||||
upd := influxdb.OrganizationUpdate{}
|
||||
upd.Name = tt.args.name
|
||||
upd.Description = tt.args.description
|
||||
|
||||
|
|
Loading…
Reference in New Issue