package storage_test import ( "context" "testing" "time" "github.com/dustin/go-humanize" "github.com/golang/mock/gomock" "github.com/influxdata/influxdb/v2" "github.com/influxdata/influxdb/v2/inmem" "github.com/influxdata/influxdb/v2/kit/platform" "github.com/influxdata/influxdb/v2/kv/migration/all" "github.com/influxdata/influxdb/v2/storage" "github.com/influxdata/influxdb/v2/storage/mocks" "github.com/influxdata/influxdb/v2/tenant" "github.com/stretchr/testify/require" "go.uber.org/zap" "go.uber.org/zap/zaptest" ) func TestBucketService_CreateBucket(t *testing.T) { testCases := []struct { name string rp time.Duration inSg time.Duration outSg time.Duration }{ { name: "infinite RP, derived SGD", rp: influxdb.InfiniteRetention, inSg: 0, outSg: humanize.Week, }, { name: "infinite RP, pinned SGD", rp: influxdb.InfiniteRetention, inSg: time.Hour, outSg: time.Hour, }, { name: "large RP, derived SGD", rp: humanize.Week, inSg: 0, outSg: humanize.Day, }, { name: "large RP, pinned SGD", rp: humanize.Week, inSg: 5 * time.Hour, outSg: 5 * time.Hour, }, { name: "small RP, derived SGD", rp: humanize.Day, inSg: 0, outSg: time.Hour, }, { name: "small RP, pinned SGD", rp: humanize.Day, inSg: 5 * time.Hour, outSg: 5 * time.Hour, }, } for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { ctrl := gomock.NewController(t) defer ctrl.Finish() engine := mocks.NewMockEngineSchema(ctrl) logger := zaptest.NewLogger(t) inmemService := newTenantService(t, logger) service := storage.NewBucketService(logger, inmemService, engine) ctx := context.Background() org := &influxdb.Organization{Name: "org1"} require.NoError(t, inmemService.CreateOrganization(ctx, org)) bucket := &influxdb.Bucket{OrgID: org.ID, RetentionPeriod: tc.rp, ShardGroupDuration: tc.inSg} // Test creating a bucket calls into the creator. engine.EXPECT().CreateBucket(gomock.Any(), bucket) require.NoError(t, service.CreateBucket(ctx, bucket)) // Test that a shard-group duration was created for the bucket require.Equal(t, tc.outSg, bucket.ShardGroupDuration) // Test that the shard-group duration was recorded in the KV store. kvBucket, err := inmemService.FindBucketByID(ctx, bucket.ID) require.NoError(t, err) require.Equal(t, tc.outSg, kvBucket.ShardGroupDuration) }) } } func TestBucketService_DeleteBucket(t *testing.T) { ctrl := gomock.NewController(t) defer ctrl.Finish() engine := mocks.NewMockEngineSchema(ctrl) logger := zaptest.NewLogger(t) inmemService := newTenantService(t, logger) service := storage.NewBucketService(logger, inmemService, engine) ctx := context.Background() org := &influxdb.Organization{Name: "org1"} require.NoError(t, inmemService.CreateOrganization(ctx, org)) bucket := &influxdb.Bucket{OrgID: org.ID} require.NoError(t, inmemService.CreateBucket(ctx, bucket)) // Test deleting a bucket calls into the deleter. engine.EXPECT().DeleteBucket(gomock.Any(), org.ID, bucket.ID) require.NoError(t, service.DeleteBucket(ctx, bucket.ID)) } func TestBucketService_DeleteNonexistentBucket(t *testing.T) { ctrl := gomock.NewController(t) defer ctrl.Finish() i, err := platform.IDFromString("2222222222222222") require.NoError(t, err) engine := mocks.NewMockEngineSchema(ctrl) logger := zaptest.NewLogger(t) inmemService := newTenantService(t, logger) service := storage.NewBucketService(logger, inmemService, engine) ctx := context.Background() require.Error(t, service.DeleteBucket(ctx, *i)) } func newTenantService(t *testing.T, logger *zap.Logger) *tenant.Service { t.Helper() store := inmem.NewKVStore() if err := all.Up(context.Background(), logger, store); err != nil { t.Fatal(err) } return tenant.NewService(tenant.NewStore(store)) }