influxdb/testing/bucket_service.go

1750 lines
37 KiB
Go

package testing
import (
"bytes"
"context"
"sort"
"testing"
"time"
"github.com/influxdata/influxdb/v2/kit/platform"
"github.com/influxdata/influxdb/v2/kit/platform/errors"
"github.com/dustin/go-humanize"
"github.com/google/go-cmp/cmp"
"github.com/influxdata/influxdb/v2"
"github.com/influxdata/influxdb/v2/mock"
)
const (
idOne = platform.ID(iota + 1)
idTwo
idThree
idFour
idFive
)
var bucketCmpOptions = cmp.Options{
cmp.Comparer(func(x, y []byte) bool {
return bytes.Equal(x, y)
}),
cmp.Comparer(func(x, y *influxdb.Bucket) bool {
if x == nil && y == nil {
return true
}
if x != nil && y == nil || y != nil && x == nil {
return false
}
return x.OrgID == y.OrgID &&
x.Type == y.Type &&
x.Description == y.Description &&
x.RetentionPolicyName == y.RetentionPolicyName &&
x.RetentionPeriod == y.RetentionPeriod &&
x.Name == y.Name
}),
cmp.Transformer("Sort", func(in []*influxdb.Bucket) []*influxdb.Bucket {
out := append([]*influxdb.Bucket(nil), in...) // Copy input to avoid mutating it
sort.Slice(out, func(i, j int) bool {
return out[i].Name > out[j].Name
})
return out
}),
}
// BucketFields will include the IDGenerator, and buckets
type BucketFields struct {
IDGenerator platform.IDGenerator
OrgIDs platform.IDGenerator
BucketIDs platform.IDGenerator
TimeGenerator influxdb.TimeGenerator
Buckets []*influxdb.Bucket
Organizations []*influxdb.Organization
}
type bucketServiceF func(
init func(BucketFields, *testing.T) (influxdb.BucketService, string, func()),
t *testing.T,
)
// BucketService tests all the service functions.
func BucketService(
init func(BucketFields, *testing.T) (influxdb.BucketService, string, func()),
t *testing.T) {
tests := []struct {
name string
fn bucketServiceF
}{
{
name: "CreateBucket",
fn: CreateBucket,
},
{
name: "FindBucketByID",
fn: FindBucketByID,
},
{
name: "FindBuckets",
fn: FindBuckets,
},
{
name: "FindBucket",
fn: FindBucket,
},
{
name: "UpdateBucket",
fn: UpdateBucket,
},
{
name: "DeleteBucket",
fn: DeleteBucket,
},
}
for _, tt := range tests {
tt := tt
t.Run(tt.name, func(t *testing.T) {
t.Parallel()
tt.fn(init, t)
})
}
}
// CreateBucket testing
func CreateBucket(
init func(BucketFields, *testing.T) (influxdb.BucketService, string, func()),
t *testing.T,
) {
type args struct {
bucket *influxdb.Bucket
}
type wants struct {
err error
buckets []*influxdb.Bucket
}
tests := []struct {
name string
fields BucketFields
args args
wants wants
}{
{
name: "create buckets with empty set",
fields: BucketFields{
IDGenerator: mock.NewStaticIDGenerator(idOne),
OrgIDs: mock.NewIncrementingIDGenerator(idOne),
BucketIDs: mock.NewIncrementingIDGenerator(idOne),
TimeGenerator: mock.TimeGenerator{FakeValue: time.Date(2006, 5, 4, 1, 2, 3, 0, time.UTC)},
Buckets: []*influxdb.Bucket{},
Organizations: []*influxdb.Organization{
{
// ID(1)
Name: "theorg",
},
},
},
args: args{
bucket: &influxdb.Bucket{
Name: "name1",
OrgID: idOne,
Description: "desc1",
},
},
wants: wants{
buckets: []*influxdb.Bucket{
{
Name: "name1",
ID: idOne,
OrgID: idOne,
Description: "desc1",
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: "basic create bucket",
fields: BucketFields{
IDGenerator: mock.NewStaticIDGenerator(idTwo),
OrgIDs: mock.NewIncrementingIDGenerator(idOne),
BucketIDs: mock.NewIncrementingIDGenerator(idOne),
TimeGenerator: mock.TimeGenerator{FakeValue: time.Date(2006, 5, 4, 1, 2, 3, 0, time.UTC)},
Organizations: []*influxdb.Organization{
{
// ID(1)
Name: "theorg",
},
{
// ID(2)
Name: "otherorg",
},
},
Buckets: []*influxdb.Bucket{
{
// ID(1)
Name: "bucket1",
OrgID: idOne,
},
},
},
args: args{
bucket: &influxdb.Bucket{
Name: "bucket2",
OrgID: idTwo,
RetentionPeriod: humanize.Week,
ShardGroupDuration: humanize.Day,
},
},
wants: wants{
buckets: []*influxdb.Bucket{
{
ID: idOne,
Name: "bucket1",
OrgID: idOne,
},
{
ID: idTwo,
Name: "bucket2",
OrgID: idTwo,
RetentionPeriod: humanize.Week,
ShardGroupDuration: humanize.Day,
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 within an organization",
fields: BucketFields{
IDGenerator: mock.NewStaticIDGenerator(idTwo),
OrgIDs: mock.NewIncrementingIDGenerator(idOne),
BucketIDs: mock.NewIncrementingIDGenerator(idOne),
TimeGenerator: mock.TimeGenerator{FakeValue: time.Date(2006, 5, 4, 1, 2, 3, 0, time.UTC)},
Organizations: []*influxdb.Organization{
{
// ID(1)
Name: "theorg",
},
{
// ID(2)
Name: "otherorg",
},
},
Buckets: []*influxdb.Bucket{
{
// ID(1)
Name: "bucket1",
OrgID: idOne,
},
},
},
args: args{
bucket: &influxdb.Bucket{
Name: "bucket1",
OrgID: idOne,
},
},
wants: wants{
buckets: []*influxdb.Bucket{
{
ID: idOne,
Name: "bucket1",
OrgID: idOne,
},
},
err: &errors.Error{
Code: errors.EConflict,
Op: influxdb.OpCreateBucket,
Msg: "bucket with name bucket1 already exists",
},
},
},
{
name: "names should not be unique across organizations",
fields: BucketFields{
IDGenerator: mock.NewStaticIDGenerator(idTwo),
OrgIDs: mock.NewIncrementingIDGenerator(idOne),
BucketIDs: mock.NewIncrementingIDGenerator(idOne),
TimeGenerator: mock.TimeGenerator{FakeValue: time.Date(2006, 5, 4, 1, 2, 3, 0, time.UTC)},
Organizations: []*influxdb.Organization{
{
// ID(1)
Name: "theorg",
},
{
// ID(2)
Name: "otherorg",
},
},
Buckets: []*influxdb.Bucket{
{
// ID(1)
Name: "bucket1",
OrgID: idOne,
},
},
},
args: args{
bucket: &influxdb.Bucket{
Name: "bucket1",
OrgID: idTwo,
},
},
wants: wants{
buckets: []*influxdb.Bucket{
{
ID: idOne,
Name: "bucket1",
OrgID: idOne,
// CRUDLog is missing because seed data is created through
// storage layer and not service layer (where CRUDLog is populated)
},
{
ID: idTwo,
Name: "bucket1",
OrgID: idTwo,
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: "create bucket with orgID not exist",
fields: BucketFields{
IDGenerator: mock.NewStaticIDGenerator(idOne),
OrgIDs: mock.NewStaticIDGenerator(idOne),
BucketIDs: mock.NewStaticIDGenerator(idOne),
TimeGenerator: mock.TimeGenerator{FakeValue: time.Date(2006, 5, 4, 1, 2, 3, 0, time.UTC)},
Buckets: []*influxdb.Bucket{},
Organizations: []*influxdb.Organization{},
},
args: args{
bucket: &influxdb.Bucket{
Name: "name1",
OrgID: idOne,
},
},
wants: wants{
buckets: []*influxdb.Bucket{},
err: &errors.Error{
Code: errors.ENotFound,
Msg: "organization not found",
Op: influxdb.OpCreateBucket,
},
},
},
{
name: "create bucket with illegal quotation mark",
fields: BucketFields{
IDGenerator: mock.NewStaticIDGenerator(idOne),
BucketIDs: mock.NewStaticIDGenerator(idOne),
OrgIDs: mock.NewStaticIDGenerator(idOne),
TimeGenerator: mock.TimeGenerator{FakeValue: time.Date(2006, 5, 4, 1, 2, 3, 0, time.UTC)},
Buckets: []*influxdb.Bucket{},
Organizations: []*influxdb.Organization{
{
Name: "org",
},
},
},
args: args{
bucket: &influxdb.Bucket{
Name: "namewith\"quote",
OrgID: idOne,
},
},
wants: wants{
buckets: []*influxdb.Bucket{},
err: &errors.Error{
Code: errors.EInvalid,
Op: influxdb.OpCreateBucket,
Msg: "bucket name namewith\"quote is invalid. Bucket names may not include quotation marks",
},
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
s, opPrefix, done := init(tt.fields, t)
defer done()
ctx := context.Background()
err := s.CreateBucket(ctx, tt.args.bucket)
diffPlatformErrors(tt.name, err, tt.wants.err, opPrefix, t)
// Delete only newly created buckets - ie., with a not nil ID
// if tt.args.bucket.ID.Valid() {
defer s.DeleteBucket(ctx, tt.args.bucket.ID)
// }
buckets, _, err := s.FindBuckets(ctx, influxdb.BucketFilter{})
if err != nil {
t.Fatalf("failed to retrieve buckets: %v", err)
}
// remove system buckets
filteredBuckets := []*influxdb.Bucket{}
for _, b := range buckets {
if b.Type != influxdb.BucketTypeSystem {
filteredBuckets = append(filteredBuckets, b)
}
}
if diff := cmp.Diff(filteredBuckets, tt.wants.buckets, bucketCmpOptions...); diff != "" {
t.Errorf("buckets are different -got/+want\ndiff %s", diff)
}
})
}
}
// FindBucketByID testing
func FindBucketByID(
init func(BucketFields, *testing.T) (influxdb.BucketService, string, func()),
t *testing.T,
) {
type args struct {
id platform.ID
}
type wants struct {
err error
bucket *influxdb.Bucket
}
tests := []struct {
name string
fields BucketFields
args args
wants wants
}{
{
name: "basic find bucket by id",
fields: BucketFields{
OrgIDs: mock.NewIncrementingIDGenerator(idOne),
BucketIDs: mock.NewIncrementingIDGenerator(idOne),
Organizations: []*influxdb.Organization{
{
// ID(1)
Name: "theorg",
ID: idOne,
},
},
Buckets: []*influxdb.Bucket{
{
// ID(1)
OrgID: idOne,
Name: "bucket1",
},
{
// ID(2)
OrgID: idOne,
Name: "bucket2",
},
},
},
args: args{
id: idOne,
},
wants: wants{
bucket: &influxdb.Bucket{
ID: idOne,
OrgID: idOne,
Name: "bucket1",
},
},
},
{
name: "find bucket by id not exist",
fields: BucketFields{
OrgIDs: mock.NewIncrementingIDGenerator(idOne),
BucketIDs: mock.NewIncrementingIDGenerator(idOne),
Organizations: []*influxdb.Organization{
{
// ID(1)
Name: "theorg",
},
},
Buckets: []*influxdb.Bucket{
{
// ID(1)
OrgID: idOne,
Name: "bucket1",
},
{
// ID(2)
OrgID: idOne,
Name: "bucket2",
},
},
},
args: args{
id: idThree,
},
wants: wants{
err: &errors.Error{
Code: errors.ENotFound,
Op: influxdb.OpFindBucketByID,
Msg: "bucket not found",
},
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
s, opPrefix, done := init(tt.fields, t)
defer done()
ctx := context.Background()
bucket, err := s.FindBucketByID(ctx, tt.args.id)
diffPlatformErrors(tt.name, err, tt.wants.err, opPrefix, t)
if diff := cmp.Diff(bucket, tt.wants.bucket, bucketCmpOptions...); diff != "" {
t.Errorf("bucket is different -got/+want\ndiff %s", diff)
}
})
}
}
// FindBuckets testing
func FindBuckets(
init func(BucketFields, *testing.T) (influxdb.BucketService, string, func()),
t *testing.T,
) {
type args struct {
ID platform.ID
name string
organization string
organizationID platform.ID
findOptions influxdb.FindOptions
}
type wants struct {
buckets []*influxdb.Bucket
err error
}
tests := []struct {
name string
fields BucketFields
args args
wants wants
}{
{
name: "find all buckets",
fields: BucketFields{
OrgIDs: mock.NewIncrementingIDGenerator(idOne),
BucketIDs: mock.NewIncrementingIDGenerator(idOne),
Organizations: []*influxdb.Organization{
{
// ID(1)
Name: "theorg",
},
{
// ID(2)
Name: "otherorg",
},
},
Buckets: []*influxdb.Bucket{
{
OrgID: idOne,
Name: "abc",
RetentionPeriod: humanize.Week,
},
{
OrgID: idTwo,
Name: "xyz",
ShardGroupDuration: humanize.Day,
},
},
},
args: args{},
wants: wants{
buckets: []*influxdb.Bucket{
{
ID: idOne,
OrgID: idOne,
Name: "abc",
RetentionPeriod: humanize.Week,
},
{
ID: idTwo,
OrgID: idTwo,
Name: "xyz",
ShardGroupDuration: humanize.Day,
},
},
},
},
{
name: "find all buckets by offset and limit",
fields: BucketFields{
OrgIDs: mock.NewIncrementingIDGenerator(idOne),
BucketIDs: mock.NewIncrementingIDGenerator(idOne),
Organizations: []*influxdb.Organization{
{
// ID(1)
Name: "theorg",
},
},
Buckets: []*influxdb.Bucket{
{
// ID(1)
OrgID: idOne,
Name: "abc",
},
{
// ID(2)
OrgID: idOne,
Name: "def",
},
{
// ID(3)
OrgID: idOne,
Name: "xyz",
},
},
},
args: args{
findOptions: influxdb.FindOptions{
Offset: 1,
Limit: 1,
},
},
wants: wants{
buckets: []*influxdb.Bucket{
{
ID: idTwo,
OrgID: idOne,
Name: "def",
},
},
},
},
{
name: "find all buckets by after and limit",
fields: BucketFields{
OrgIDs: mock.NewIncrementingIDGenerator(idOne),
BucketIDs: mock.NewIncrementingIDGenerator(idOne),
Organizations: []*influxdb.Organization{
{
Name: "theorg",
},
},
Buckets: []*influxdb.Bucket{
{
// ID(1)
OrgID: idOne,
Name: "abc",
},
{
// ID(2)
OrgID: idOne,
Name: "def",
},
{
// ID(3)
OrgID: idOne,
Name: "xyz",
},
},
},
args: args{
findOptions: influxdb.FindOptions{
After: idPtr(idOne),
Limit: 2,
},
},
wants: wants{
buckets: []*influxdb.Bucket{
{
ID: idTwo,
OrgID: idOne,
Name: "def",
},
{
ID: idThree,
OrgID: idOne,
Name: "xyz",
},
},
},
},
{
name: "find all buckets by descending",
fields: BucketFields{
OrgIDs: mock.NewIncrementingIDGenerator(idOne),
BucketIDs: mock.NewIncrementingIDGenerator(idOne),
Organizations: []*influxdb.Organization{
{
// ID(1)
Name: "theorg",
},
},
Buckets: []*influxdb.Bucket{
{
// ID(1)
OrgID: idOne,
Name: "abc",
},
{
// ID(2)
OrgID: idOne,
Name: "def",
},
{
// ID(3)
OrgID: idOne,
Name: "xyz",
},
},
},
args: args{
findOptions: influxdb.FindOptions{
Offset: 1,
Descending: true,
},
},
wants: wants{
buckets: []*influxdb.Bucket{
{
ID: idTwo,
OrgID: idOne,
Name: "def",
},
{
ID: idOne,
OrgID: idOne,
Name: "abc",
},
},
},
},
{
name: "find buckets by organization name",
fields: BucketFields{
OrgIDs: mock.NewIncrementingIDGenerator(idOne),
BucketIDs: mock.NewIncrementingIDGenerator(idOne),
Organizations: []*influxdb.Organization{
{
// ID(1)
Name: "theorg",
},
{
// ID(2)
Name: "otherorg",
},
},
Buckets: []*influxdb.Bucket{
{
// ID(1)
OrgID: idOne,
Name: "abc",
},
{
// ID(2)
OrgID: idTwo,
Name: "xyz",
},
{
// ID(3)
OrgID: idOne,
Name: "123",
},
},
},
args: args{
organization: "theorg",
},
wants: wants{
buckets: []*influxdb.Bucket{
{
ID: idOne,
OrgID: idOne,
Name: "abc",
},
{
ID: idThree,
OrgID: idOne,
Name: "123",
},
},
},
},
{
name: "find buckets by organization id",
fields: BucketFields{
OrgIDs: mock.NewIncrementingIDGenerator(idOne),
BucketIDs: mock.NewIncrementingIDGenerator(idOne),
Organizations: []*influxdb.Organization{
{
// ID(1)
Name: "theorg",
},
{
// ID(2)
Name: "otherorg",
},
},
Buckets: []*influxdb.Bucket{
{
// ID(1)
OrgID: idOne,
Name: "abc",
},
{
// ID(2)
OrgID: idTwo,
Name: "xyz",
},
{
// ID(3)
OrgID: idOne,
Name: "123",
},
},
},
args: args{
organizationID: idOne,
},
wants: wants{
buckets: []*influxdb.Bucket{
{
ID: idOne,
OrgID: idOne,
Name: "abc",
},
{
ID: idThree,
OrgID: idOne,
Name: "123",
},
},
},
},
{
name: "find bucket by name",
fields: BucketFields{
OrgIDs: mock.NewIncrementingIDGenerator(idOne),
BucketIDs: mock.NewIncrementingIDGenerator(idOne),
Organizations: []*influxdb.Organization{
{
// ID(1)
Name: "theorg",
},
},
Buckets: []*influxdb.Bucket{
{
// ID(1)
OrgID: idOne,
Name: "abc",
},
{
// ID(2)
OrgID: idOne,
Name: "xyz",
},
},
},
args: args{
name: "xyz",
},
wants: wants{
buckets: []*influxdb.Bucket{
{
ID: idTwo,
OrgID: idOne,
Name: "xyz",
},
},
},
},
{
name: "missing bucket returns no buckets",
fields: BucketFields{
OrgIDs: mock.NewIncrementingIDGenerator(idOne),
BucketIDs: mock.NewIncrementingIDGenerator(idOne),
Organizations: []*influxdb.Organization{
{
// ID(1)
Name: "theorg",
},
},
Buckets: []*influxdb.Bucket{},
},
args: args{
name: "xyz",
},
wants: wants{},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
s, opPrefix, done := init(tt.fields, t)
defer done()
ctx := context.Background()
filter := influxdb.BucketFilter{}
if tt.args.ID.Valid() {
filter.ID = &tt.args.ID
}
if tt.args.organizationID.Valid() {
filter.OrganizationID = &tt.args.organizationID
}
if tt.args.organization != "" {
filter.Org = &tt.args.organization
}
if tt.args.name != "" {
filter.Name = &tt.args.name
}
buckets, _, err := s.FindBuckets(ctx, filter, tt.args.findOptions)
diffPlatformErrors(tt.name, err, tt.wants.err, opPrefix, t)
// remove system buckets
filteredBuckets := []*influxdb.Bucket{}
for _, b := range buckets {
if b.Type != influxdb.BucketTypeSystem {
filteredBuckets = append(filteredBuckets, b)
}
}
if diff := cmp.Diff(filteredBuckets, tt.wants.buckets, bucketCmpOptions...); diff != "" {
t.Errorf("buckets are different -got/+want\ndiff %s", diff)
}
})
}
}
// DeleteBucket testing
func DeleteBucket(
init func(BucketFields, *testing.T) (influxdb.BucketService, string, func()),
t *testing.T,
) {
type args struct {
ID platform.ID
}
type wants struct {
err error
buckets []*influxdb.Bucket
}
tests := []struct {
name string
fields BucketFields
args args
wants wants
}{
{
name: "delete buckets using exist id",
fields: BucketFields{
OrgIDs: mock.NewIncrementingIDGenerator(idOne),
BucketIDs: mock.NewIncrementingIDGenerator(idOne),
Organizations: []*influxdb.Organization{
{
// ID(1)
Name: "theorg",
},
},
Buckets: []*influxdb.Bucket{
{
// ID(1)
Name: "A",
OrgID: idOne,
},
{
// ID(2)
Name: "B",
OrgID: idOne,
},
},
},
args: args{
ID: idOne,
},
wants: wants{
buckets: []*influxdb.Bucket{
{
Name: "B",
ID: idTwo,
OrgID: idOne,
},
},
},
},
{
name: "delete buckets using id that does not exist",
fields: BucketFields{
OrgIDs: mock.NewIncrementingIDGenerator(idOne),
BucketIDs: mock.NewIncrementingIDGenerator(idOne),
Organizations: []*influxdb.Organization{
{
// ID(1)
Name: "theorg",
},
},
Buckets: []*influxdb.Bucket{
{
// ID(1)
Name: "A",
OrgID: idOne,
},
{
// ID(2)
Name: "B",
OrgID: idOne,
},
},
},
args: args{
ID: MustIDBase16("1234567890654321"),
},
wants: wants{
err: &errors.Error{
Op: influxdb.OpDeleteBucket,
Msg: "bucket not found",
Code: errors.ENotFound,
},
buckets: []*influxdb.Bucket{
{
Name: "A",
ID: idOne,
OrgID: idOne,
},
{
Name: "B",
ID: idTwo,
OrgID: idOne,
},
},
},
},
{
name: "delete system buckets",
fields: BucketFields{
OrgIDs: mock.NewIncrementingIDGenerator(idOne),
BucketIDs: mock.NewIncrementingIDGenerator(idOne),
Organizations: []*influxdb.Organization{
{
// ID(1)
Name: "theorg",
},
},
Buckets: []*influxdb.Bucket{
{
// ID(1)
Name: "A",
OrgID: idOne,
Type: influxdb.BucketTypeSystem,
},
},
},
args: args{
ID: idOne,
},
wants: wants{
err: &errors.Error{
Op: influxdb.OpDeleteBucket,
Msg: "system buckets cannot be deleted",
Code: errors.EInvalid,
},
buckets: []*influxdb.Bucket{
{
Name: "A",
ID: idOne,
OrgID: idOne,
Type: influxdb.BucketTypeSystem,
},
},
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
s, opPrefix, done := init(tt.fields, t)
defer done()
ctx := context.Background()
err := s.DeleteBucket(ctx, tt.args.ID)
diffPlatformErrors(tt.name, err, tt.wants.err, opPrefix, t)
filter := influxdb.BucketFilter{}
buckets, _, err := s.FindBuckets(ctx, filter)
if err != nil {
t.Fatalf("failed to retrieve buckets: %v", err)
}
// remove built in system buckets
filteredBuckets := []*influxdb.Bucket{}
for _, b := range buckets {
if b.Name != influxdb.TasksSystemBucketName && b.Name != influxdb.MonitoringSystemBucketName {
filteredBuckets = append(filteredBuckets, b)
}
}
if diff := cmp.Diff(filteredBuckets, tt.wants.buckets, bucketCmpOptions...); diff != "" {
t.Errorf("buckets are different -got/+want\ndiff %s", diff)
}
})
}
}
// FindBucket testing
func FindBucket(
init func(BucketFields, *testing.T) (influxdb.BucketService, string, func()),
t *testing.T,
) {
type args struct {
name string
organizationID platform.ID
id platform.ID
}
type wants struct {
bucket *influxdb.Bucket
err error
}
tests := []struct {
name string
fields BucketFields
args args
wants wants
}{
{
name: "find bucket by name",
fields: BucketFields{
OrgIDs: mock.NewIncrementingIDGenerator(idOne),
BucketIDs: mock.NewIncrementingIDGenerator(idOne),
Organizations: []*influxdb.Organization{
{
// ID(1)
Name: "theorg",
},
},
Buckets: []*influxdb.Bucket{
{
// ID(1)
OrgID: idOne,
Name: "abc",
RetentionPeriod: humanize.Week,
ShardGroupDuration: humanize.Day,
},
{
// ID(2)
OrgID: idOne,
Name: "xyz",
},
},
},
args: args{
name: "abc",
organizationID: idOne,
},
wants: wants{
bucket: &influxdb.Bucket{
ID: idOne,
OrgID: idOne,
Name: "abc",
RetentionPeriod: humanize.Week,
ShardGroupDuration: humanize.Day,
},
},
},
{
name: "find bucket by id",
fields: BucketFields{
OrgIDs: mock.NewIncrementingIDGenerator(idOne),
BucketIDs: mock.NewIncrementingIDGenerator(idOne),
Organizations: []*influxdb.Organization{
{
// ID(1)
Name: "theorg",
},
},
Buckets: []*influxdb.Bucket{
{
// ID(1)
OrgID: idOne,
Name: "abc",
},
{
// ID(2)
OrgID: idOne,
Name: "xyz",
RetentionPeriod: humanize.Week,
ShardGroupDuration: humanize.Day,
},
},
},
args: args{
id: idTwo,
organizationID: idOne,
},
wants: wants{
bucket: &influxdb.Bucket{
ID: idTwo,
OrgID: idOne,
Name: "xyz",
RetentionPeriod: humanize.Week,
ShardGroupDuration: humanize.Day,
},
},
},
{
name: "missing bucket returns error",
fields: BucketFields{
OrgIDs: mock.NewIncrementingIDGenerator(idOne),
BucketIDs: mock.NewIncrementingIDGenerator(idOne),
Organizations: []*influxdb.Organization{
{
// ID(1)
Name: "theorg",
},
},
Buckets: []*influxdb.Bucket{},
},
args: args{
name: "xyz",
organizationID: idOne,
},
wants: wants{
err: &errors.Error{
Code: errors.ENotFound,
Op: influxdb.OpFindBucket,
Msg: "bucket \"xyz\" not found",
},
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
s, opPrefix, done := init(tt.fields, t)
defer done()
ctx := context.Background()
filter := influxdb.BucketFilter{}
if tt.args.name != "" {
filter.Name = &tt.args.name
}
if tt.args.id.Valid() {
filter.ID = &tt.args.id
}
if tt.args.organizationID.Valid() {
filter.OrganizationID = &tt.args.organizationID
}
bucket, err := s.FindBucket(ctx, filter)
diffPlatformErrors(tt.name, err, tt.wants.err, opPrefix, t)
if diff := cmp.Diff(bucket, tt.wants.bucket, bucketCmpOptions...); diff != "" {
t.Errorf("buckets are different -got/+want\ndiff %s", diff)
}
})
}
}
// UpdateBucket testing
func UpdateBucket(
init func(BucketFields, *testing.T) (influxdb.BucketService, string, func()),
t *testing.T,
) {
type args struct {
name string
id platform.ID
retention int
shardDuration int
description *string
}
type wants struct {
err error
bucket *influxdb.Bucket
}
tests := []struct {
name string
fields BucketFields
args args
wants wants
}{
{
name: "update name",
fields: BucketFields{
OrgIDs: mock.NewIncrementingIDGenerator(idOne),
BucketIDs: mock.NewIncrementingIDGenerator(idOne),
TimeGenerator: mock.TimeGenerator{FakeValue: time.Date(2006, 5, 4, 1, 2, 3, 0, time.UTC)},
Organizations: []*influxdb.Organization{
{
// ID(1)
Name: "theorg",
},
},
Buckets: []*influxdb.Bucket{
{
// ID(1)
OrgID: idOne,
Name: "bucket1",
},
{
// ID(2)
OrgID: idOne,
Name: "bucket2",
},
},
},
args: args{
id: idTwo,
name: "changed",
},
wants: wants{
bucket: &influxdb.Bucket{
ID: idTwo,
OrgID: idOne,
Name: "changed",
CRUDLog: influxdb.CRUDLog{
UpdatedAt: time.Date(2006, 5, 4, 1, 2, 3, 0, time.UTC),
},
},
},
},
{
name: "update name unique",
fields: BucketFields{
OrgIDs: mock.NewIncrementingIDGenerator(idOne),
BucketIDs: mock.NewIncrementingIDGenerator(idOne),
TimeGenerator: mock.TimeGenerator{FakeValue: time.Date(2006, 5, 4, 1, 2, 3, 0, time.UTC)},
Organizations: []*influxdb.Organization{
{
// ID(1)
Name: "theorg",
},
},
Buckets: []*influxdb.Bucket{
{
// ID(1)
OrgID: idOne,
Name: "bucket1",
},
{
// ID(2)
OrgID: idOne,
Name: "bucket2",
},
},
},
args: args{
id: idOne,
name: "bucket2",
},
wants: wants{
err: &errors.Error{
Code: errors.EConflict,
Msg: "bucket name is not unique",
},
},
},
{
name: "update system bucket name",
fields: BucketFields{
OrgIDs: mock.NewIncrementingIDGenerator(idOne),
BucketIDs: mock.NewIncrementingIDGenerator(idOne),
TimeGenerator: mock.TimeGenerator{FakeValue: time.Date(2006, 5, 4, 1, 2, 3, 0, time.UTC)},
Organizations: []*influxdb.Organization{
{
// ID(1)
Name: "theorg",
},
},
Buckets: []*influxdb.Bucket{
{
// ID(1)
OrgID: idOne,
Type: influxdb.BucketTypeSystem,
Name: "bucket1",
},
},
},
args: args{
id: idOne,
name: "bucket2",
},
wants: wants{
err: &errors.Error{
Code: errors.EInvalid,
Msg: "system buckets cannot be renamed",
},
},
},
{
name: "update retention",
fields: BucketFields{
OrgIDs: mock.NewIncrementingIDGenerator(idOne),
BucketIDs: mock.NewIncrementingIDGenerator(idOne),
TimeGenerator: mock.TimeGenerator{FakeValue: time.Date(2006, 5, 4, 1, 2, 3, 0, time.UTC)},
Organizations: []*influxdb.Organization{
{
// ID(1)
Name: "theorg",
},
},
Buckets: []*influxdb.Bucket{
{
// ID(1)
OrgID: idOne,
Name: "bucket1",
ShardGroupDuration: time.Hour,
},
{
// ID(2)
OrgID: idOne,
Name: "bucket2",
},
},
},
args: args{
id: idOne,
retention: 100,
},
wants: wants{
bucket: &influxdb.Bucket{
ID: idOne,
OrgID: idOne,
Name: "bucket1",
RetentionPeriod: 100 * time.Minute,
ShardGroupDuration: time.Hour,
CRUDLog: influxdb.CRUDLog{
UpdatedAt: time.Date(2006, 5, 4, 1, 2, 3, 0, time.UTC),
},
},
},
},
{
name: "update shard-group duration",
fields: BucketFields{
OrgIDs: mock.NewIncrementingIDGenerator(idOne),
BucketIDs: mock.NewIncrementingIDGenerator(idOne),
TimeGenerator: mock.TimeGenerator{FakeValue: time.Date(2006, 5, 4, 1, 2, 3, 0, time.UTC)},
Organizations: []*influxdb.Organization{
{
// ID(1)
Name: "theorg",
},
},
Buckets: []*influxdb.Bucket{
{
// ID(1)
OrgID: idOne,
Name: "bucket1",
RetentionPeriod: humanize.Day,
ShardGroupDuration: time.Hour,
},
{
// ID(2)
OrgID: idOne,
Name: "bucket2",
},
},
},
args: args{
id: idOne,
shardDuration: 100,
},
wants: wants{
bucket: &influxdb.Bucket{
ID: idOne,
OrgID: idOne,
Name: "bucket1",
RetentionPeriod: humanize.Day,
ShardGroupDuration: 100 * time.Minute,
CRUDLog: influxdb.CRUDLog{
UpdatedAt: time.Date(2006, 5, 4, 1, 2, 3, 0, time.UTC),
},
},
},
},
{
name: "update retention and shard-group duration",
fields: BucketFields{
OrgIDs: mock.NewIncrementingIDGenerator(idOne),
BucketIDs: mock.NewIncrementingIDGenerator(idOne),
TimeGenerator: mock.TimeGenerator{FakeValue: time.Date(2006, 5, 4, 1, 2, 3, 0, time.UTC)},
Organizations: []*influxdb.Organization{
{
// ID(1)
Name: "theorg",
},
},
Buckets: []*influxdb.Bucket{
{
// ID(1)
OrgID: idOne,
Name: "bucket1",
RetentionPeriod: humanize.Day,
ShardGroupDuration: time.Hour,
},
{
// ID(2)
OrgID: idOne,
Name: "bucket2",
},
},
},
args: args{
id: idOne,
retention: 100,
shardDuration: 100,
},
wants: wants{
bucket: &influxdb.Bucket{
ID: idOne,
OrgID: idOne,
Name: "bucket1",
RetentionPeriod: 100 * time.Minute,
ShardGroupDuration: 100 * time.Minute,
CRUDLog: influxdb.CRUDLog{
UpdatedAt: time.Date(2006, 5, 4, 1, 2, 3, 0, time.UTC),
},
},
},
},
{
name: "update description",
fields: BucketFields{
OrgIDs: mock.NewIncrementingIDGenerator(idOne),
BucketIDs: mock.NewIncrementingIDGenerator(idOne),
TimeGenerator: mock.TimeGenerator{FakeValue: time.Date(2006, 5, 4, 1, 2, 3, 0, time.UTC)},
Organizations: []*influxdb.Organization{
{
// ID(1)
Name: "theorg",
},
},
Buckets: []*influxdb.Bucket{
{
// ID(1)
OrgID: idOne,
Name: "bucket1",
},
{
// ID(2)
OrgID: idOne,
Name: "bucket2",
},
},
},
args: args{
id: idOne,
description: stringPtr("desc1"),
},
wants: wants{
bucket: &influxdb.Bucket{
ID: idOne,
OrgID: idOne,
Name: "bucket1",
Description: "desc1",
CRUDLog: influxdb.CRUDLog{
UpdatedAt: time.Date(2006, 5, 4, 1, 2, 3, 0, time.UTC),
},
},
},
},
{
name: "update retention and name",
fields: BucketFields{
OrgIDs: mock.NewIncrementingIDGenerator(idOne),
BucketIDs: mock.NewIncrementingIDGenerator(idOne),
TimeGenerator: mock.TimeGenerator{FakeValue: time.Date(2006, 5, 4, 1, 2, 3, 0, time.UTC)},
Organizations: []*influxdb.Organization{
{
// ID(1)
Name: "theorg",
},
},
Buckets: []*influxdb.Bucket{
{
// ID(1)
OrgID: idOne,
Name: "bucket1",
},
{
// ID(2)
OrgID: idOne,
Name: "bucket2",
},
},
},
args: args{
id: idOne,
retention: 101,
name: "changed",
},
wants: wants{
bucket: &influxdb.Bucket{
ID: idOne,
OrgID: idOne,
Name: "changed",
RetentionPeriod: 101 * time.Minute,
CRUDLog: influxdb.CRUDLog{
UpdatedAt: time.Date(2006, 5, 4, 1, 2, 3, 0, time.UTC),
},
},
},
},
{
name: "update retention and same name",
fields: BucketFields{
OrgIDs: mock.NewIncrementingIDGenerator(idOne),
BucketIDs: mock.NewIncrementingIDGenerator(idOne),
TimeGenerator: mock.TimeGenerator{FakeValue: time.Date(2006, 5, 4, 1, 2, 3, 0, time.UTC)},
Organizations: []*influxdb.Organization{
{
// ID(1)
Name: "theorg",
},
},
Buckets: []*influxdb.Bucket{
{
// ID(1)
OrgID: idOne,
Name: "bucket1",
},
{
// ID(2)
OrgID: idOne,
Name: "bucket2",
},
},
},
args: args{
id: idTwo,
retention: 101,
name: "bucket2",
},
wants: wants{
bucket: &influxdb.Bucket{
ID: idTwo,
OrgID: idOne,
Name: "bucket2",
RetentionPeriod: 101 * time.Minute,
CRUDLog: influxdb.CRUDLog{
UpdatedAt: time.Date(2006, 5, 4, 1, 2, 3, 0, time.UTC),
},
},
},
},
{
name: "update retention and same name",
fields: BucketFields{
OrgIDs: mock.NewIncrementingIDGenerator(idOne),
BucketIDs: mock.NewIncrementingIDGenerator(idOne),
TimeGenerator: mock.TimeGenerator{FakeValue: time.Date(2006, 5, 4, 1, 2, 3, 0, time.UTC)},
Organizations: []*influxdb.Organization{
{
// ID(1)
Name: "theorg",
},
},
Buckets: []*influxdb.Bucket{
{
// ID(1)
OrgID: idOne,
Name: "bucket1",
},
{
// ID(2)
OrgID: idOne,
Name: "bucket2",
},
},
},
args: args{
id: idTwo,
retention: 101,
name: "bucket2",
},
wants: wants{
bucket: &influxdb.Bucket{
ID: idTwo,
OrgID: idOne,
Name: "bucket2",
RetentionPeriod: 101 * time.Minute,
CRUDLog: influxdb.CRUDLog{
UpdatedAt: time.Date(2006, 5, 4, 1, 2, 3, 0, time.UTC),
},
},
},
},
{
name: "update bucket with illegal quotation mark",
fields: BucketFields{
OrgIDs: mock.NewStaticIDGenerator(idOne),
BucketIDs: mock.NewStaticIDGenerator(idOne),
TimeGenerator: mock.TimeGenerator{FakeValue: time.Date(2006, 5, 4, 1, 2, 3, 0, time.UTC)},
Organizations: []*influxdb.Organization{
{
// ID(1)
Name: "org",
},
},
Buckets: []*influxdb.Bucket{
{
// ID(1)
Name: "valid name",
OrgID: idOne,
},
},
},
args: args{
id: idOne,
name: "namewith\"quote",
},
wants: wants{
err: &errors.Error{
Code: errors.EInvalid,
Op: influxdb.OpCreateBucket,
Msg: "bucket name namewith\"quote is invalid. Bucket names may not include quotation marks",
},
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
s, opPrefix, done := init(tt.fields, t)
defer done()
ctx := context.Background()
upd := influxdb.BucketUpdate{}
if tt.args.name != "" {
upd.Name = &tt.args.name
}
if tt.args.retention != 0 {
d := time.Duration(tt.args.retention) * time.Minute
upd.RetentionPeriod = &d
}
if tt.args.shardDuration != 0 {
d := time.Duration(tt.args.shardDuration) * time.Minute
upd.ShardGroupDuration = &d
}
upd.Description = tt.args.description
bucket, err := s.UpdateBucket(ctx, tt.args.id, upd)
diffPlatformErrors(tt.name, err, tt.wants.err, opPrefix, t)
if diff := cmp.Diff(bucket, tt.wants.bucket, bucketCmpOptions...); diff != "" {
t.Errorf("bucket is different -got/+want\ndiff %s", diff)
}
})
}
}