forked from rook/rook
2194 lines
61 KiB
Go
2194 lines
61 KiB
Go
package object
|
|
|
|
import (
|
|
"encoding/json"
|
|
"reflect"
|
|
"testing"
|
|
"time"
|
|
|
|
cephv1 "github.com/rook/rook/pkg/apis/ceph.rook.io/v1"
|
|
"github.com/rook/rook/pkg/clusterd"
|
|
cephclient "github.com/rook/rook/pkg/daemon/ceph/client"
|
|
exectest "github.com/rook/rook/pkg/util/exec/test"
|
|
"github.com/stretchr/testify/assert"
|
|
)
|
|
|
|
func Test_validatePoolPlacements(t *testing.T) {
|
|
type args struct {
|
|
placements []cephv1.PoolPlacementSpec
|
|
}
|
|
tests := []struct {
|
|
name string
|
|
args args
|
|
wantErr bool
|
|
}{
|
|
{
|
|
name: "valid: names unique",
|
|
args: args{
|
|
placements: []cephv1.PoolPlacementSpec{
|
|
{
|
|
Name: "name1",
|
|
Default: true,
|
|
MetadataPoolName: "", // handled by CRD validation
|
|
DataPoolName: "", // handled by CRD validation
|
|
DataNonECPoolName: "", // handled by CRD validation
|
|
StorageClasses: []cephv1.PlacementStorageClassSpec{},
|
|
},
|
|
{
|
|
Name: "name2",
|
|
Default: false,
|
|
MetadataPoolName: "", // handled by CRD validation
|
|
DataPoolName: "", // handled by CRD validation
|
|
DataNonECPoolName: "", // handled by CRD validation
|
|
StorageClasses: []cephv1.PlacementStorageClassSpec{},
|
|
},
|
|
},
|
|
},
|
|
wantErr: false,
|
|
},
|
|
{
|
|
name: "invalid: duplicate names",
|
|
args: args{
|
|
placements: []cephv1.PoolPlacementSpec{
|
|
{
|
|
Name: "name",
|
|
MetadataPoolName: "", // handled by CRD validation
|
|
DataPoolName: "", // handled by CRD validation
|
|
DataNonECPoolName: "", // handled by CRD validation
|
|
StorageClasses: []cephv1.PlacementStorageClassSpec{},
|
|
},
|
|
{
|
|
Name: "name",
|
|
MetadataPoolName: "", // handled by CRD validation
|
|
DataPoolName: "", // handled by CRD validation
|
|
DataNonECPoolName: "", // handled by CRD validation
|
|
StorageClasses: []cephv1.PlacementStorageClassSpec{},
|
|
},
|
|
},
|
|
},
|
|
wantErr: true,
|
|
},
|
|
{
|
|
name: "invalid: more than one default placement",
|
|
args: args{
|
|
placements: []cephv1.PoolPlacementSpec{
|
|
{
|
|
Name: "one",
|
|
Default: true,
|
|
MetadataPoolName: "", // handled by CRD validation
|
|
DataPoolName: "", // handled by CRD validation
|
|
DataNonECPoolName: "", // handled by CRD validation
|
|
StorageClasses: []cephv1.PlacementStorageClassSpec{},
|
|
},
|
|
{
|
|
Name: "two",
|
|
Default: true,
|
|
MetadataPoolName: "", // handled by CRD validation
|
|
DataPoolName: "", // handled by CRD validation
|
|
DataNonECPoolName: "", // handled by CRD validation
|
|
StorageClasses: []cephv1.PlacementStorageClassSpec{},
|
|
},
|
|
},
|
|
},
|
|
wantErr: true,
|
|
},
|
|
{
|
|
name: "invalid: non-default placement with reserved name",
|
|
args: args{
|
|
placements: []cephv1.PoolPlacementSpec{
|
|
{
|
|
Name: defaultPlacementCephConfigName,
|
|
Default: false,
|
|
MetadataPoolName: "", // handled by CRD validation
|
|
DataPoolName: "", // handled by CRD validation
|
|
DataNonECPoolName: "", // handled by CRD validation
|
|
StorageClasses: []cephv1.PlacementStorageClassSpec{},
|
|
},
|
|
{
|
|
Name: "two",
|
|
Default: true,
|
|
MetadataPoolName: "", // handled by CRD validation
|
|
DataPoolName: "", // handled by CRD validation
|
|
DataNonECPoolName: "", // handled by CRD validation
|
|
StorageClasses: []cephv1.PlacementStorageClassSpec{},
|
|
},
|
|
},
|
|
},
|
|
wantErr: true,
|
|
},
|
|
{
|
|
name: "valid: default placement with reserved name",
|
|
args: args{
|
|
placements: []cephv1.PoolPlacementSpec{
|
|
{
|
|
Name: defaultPlacementCephConfigName,
|
|
Default: true,
|
|
MetadataPoolName: "", // handled by CRD validation
|
|
DataPoolName: "", // handled by CRD validation
|
|
DataNonECPoolName: "", // handled by CRD validation
|
|
StorageClasses: []cephv1.PlacementStorageClassSpec{},
|
|
},
|
|
{
|
|
Name: "two",
|
|
Default: false,
|
|
MetadataPoolName: "", // handled by CRD validation
|
|
DataPoolName: "", // handled by CRD validation
|
|
DataNonECPoolName: "", // handled by CRD validation
|
|
StorageClasses: []cephv1.PlacementStorageClassSpec{},
|
|
},
|
|
},
|
|
},
|
|
wantErr: false,
|
|
},
|
|
}
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
if err := validatePoolPlacements(tt.args.placements); (err != nil) != tt.wantErr {
|
|
t.Errorf("validatePoolPlacements() error = %v, wantErr %v", err, tt.wantErr)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func Test_validatePoolPlacementStorageClasses(t *testing.T) {
|
|
type args struct {
|
|
scList []cephv1.PlacementStorageClassSpec
|
|
}
|
|
tests := []struct {
|
|
name string
|
|
args args
|
|
wantErr bool
|
|
}{
|
|
{
|
|
name: "valid: unique names",
|
|
args: args{
|
|
scList: []cephv1.PlacementStorageClassSpec{
|
|
{
|
|
Name: "STANDARD_IA",
|
|
DataPoolName: "", // handled by CRD validation
|
|
},
|
|
{
|
|
Name: "REDUCED_REDUNDANCY",
|
|
DataPoolName: "", // handled by CRD validation
|
|
},
|
|
},
|
|
},
|
|
wantErr: false,
|
|
},
|
|
{
|
|
name: "invalid: cannot override STANDARD",
|
|
args: args{
|
|
scList: []cephv1.PlacementStorageClassSpec{
|
|
{
|
|
Name: "STANDARD",
|
|
DataPoolName: "", // handled by CRD validation
|
|
},
|
|
},
|
|
},
|
|
wantErr: true,
|
|
},
|
|
{
|
|
name: "invalid: duplicate names",
|
|
args: args{
|
|
scList: []cephv1.PlacementStorageClassSpec{
|
|
{
|
|
Name: "STANDARD_IA",
|
|
DataPoolName: "", // handled by CRD validation
|
|
},
|
|
{
|
|
Name: "STANDARD_IA",
|
|
DataPoolName: "", // handled by CRD validation
|
|
},
|
|
},
|
|
},
|
|
wantErr: true,
|
|
},
|
|
}
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
if err := validatePoolPlacementStorageClasses(tt.args.scList); (err != nil) != tt.wantErr {
|
|
t.Errorf("validatePoolPlacementStorageClasses() error = %v, wantErr %v", err, tt.wantErr)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestIsNeedToCreateObjectStorePools(t *testing.T) {
|
|
type args struct {
|
|
sharedPools cephv1.ObjectSharedPoolsSpec
|
|
}
|
|
tests := []struct {
|
|
name string
|
|
args args
|
|
want bool
|
|
}{
|
|
{
|
|
name: "no need: both shared pools set",
|
|
args: args{
|
|
sharedPools: cephv1.ObjectSharedPoolsSpec{
|
|
MetadataPoolName: "meta",
|
|
DataPoolName: "data",
|
|
PreserveRadosNamespaceDataOnDelete: false,
|
|
PoolPlacements: []cephv1.PoolPlacementSpec{},
|
|
},
|
|
},
|
|
want: false,
|
|
},
|
|
{
|
|
name: "no need: default placement is set",
|
|
args: args{
|
|
sharedPools: cephv1.ObjectSharedPoolsSpec{
|
|
MetadataPoolName: "",
|
|
DataPoolName: "",
|
|
PreserveRadosNamespaceDataOnDelete: false,
|
|
PoolPlacements: []cephv1.PoolPlacementSpec{
|
|
{
|
|
Name: "name",
|
|
Default: true,
|
|
MetadataPoolName: "", // handled by CRD validation
|
|
DataPoolName: "", // handled by CRD validation
|
|
DataNonECPoolName: "", // handled by CRD validation
|
|
StorageClasses: []cephv1.PlacementStorageClassSpec{},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
want: false,
|
|
},
|
|
{
|
|
name: "need: only meta shared pool set",
|
|
args: args{
|
|
sharedPools: cephv1.ObjectSharedPoolsSpec{
|
|
MetadataPoolName: "meta",
|
|
DataPoolName: "",
|
|
PreserveRadosNamespaceDataOnDelete: false,
|
|
PoolPlacements: []cephv1.PoolPlacementSpec{},
|
|
},
|
|
},
|
|
want: true,
|
|
},
|
|
{
|
|
name: "need: only data shared pool set",
|
|
args: args{
|
|
sharedPools: cephv1.ObjectSharedPoolsSpec{
|
|
MetadataPoolName: "",
|
|
DataPoolName: "data",
|
|
PreserveRadosNamespaceDataOnDelete: false,
|
|
PoolPlacements: []cephv1.PoolPlacementSpec{},
|
|
},
|
|
},
|
|
want: true,
|
|
},
|
|
{
|
|
name: "need: nothing is set",
|
|
args: args{
|
|
sharedPools: cephv1.ObjectSharedPoolsSpec{
|
|
MetadataPoolName: "",
|
|
DataPoolName: "",
|
|
PreserveRadosNamespaceDataOnDelete: false,
|
|
PoolPlacements: []cephv1.PoolPlacementSpec{},
|
|
},
|
|
},
|
|
want: true,
|
|
},
|
|
{
|
|
name: "need: no default placement is set",
|
|
args: args{
|
|
sharedPools: cephv1.ObjectSharedPoolsSpec{
|
|
MetadataPoolName: "",
|
|
DataPoolName: "",
|
|
PreserveRadosNamespaceDataOnDelete: false,
|
|
PoolPlacements: []cephv1.PoolPlacementSpec{
|
|
{
|
|
Name: "default",
|
|
Default: false,
|
|
MetadataPoolName: "", // handled by CRD validation
|
|
DataPoolName: "", // handled by CRD validation
|
|
DataNonECPoolName: "", // handled by CRD validation
|
|
StorageClasses: []cephv1.PlacementStorageClassSpec{},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
want: true,
|
|
},
|
|
}
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
if got := IsNeedToCreateObjectStorePools(tt.args.sharedPools); got != tt.want {
|
|
t.Errorf("IsNeedToCreateObjectStorePools() = %v, want %v", got, tt.want)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func Test_getDefaultMetadataPool(t *testing.T) {
|
|
type args struct {
|
|
spec cephv1.ObjectSharedPoolsSpec
|
|
}
|
|
tests := []struct {
|
|
name string
|
|
args args
|
|
want string
|
|
}{
|
|
{
|
|
name: "default placement is returned",
|
|
args: args{
|
|
spec: cephv1.ObjectSharedPoolsSpec{
|
|
MetadataPoolName: "",
|
|
DataPoolName: "",
|
|
PreserveRadosNamespaceDataOnDelete: false,
|
|
PoolPlacements: []cephv1.PoolPlacementSpec{
|
|
{
|
|
Name: "some_name",
|
|
MetadataPoolName: "meta1",
|
|
DataPoolName: "data1",
|
|
DataNonECPoolName: "data-non-ec1",
|
|
StorageClasses: []cephv1.PlacementStorageClassSpec{},
|
|
},
|
|
{
|
|
Name: "some_name_2",
|
|
Default: true,
|
|
MetadataPoolName: "meta2",
|
|
DataPoolName: "data2",
|
|
DataNonECPoolName: "data-non-ec2",
|
|
StorageClasses: []cephv1.PlacementStorageClassSpec{},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
want: "meta2",
|
|
},
|
|
{
|
|
name: "default placement override shared pool",
|
|
args: args{
|
|
spec: cephv1.ObjectSharedPoolsSpec{
|
|
MetadataPoolName: "meta-shared",
|
|
DataPoolName: "data-shared",
|
|
PreserveRadosNamespaceDataOnDelete: false,
|
|
PoolPlacements: []cephv1.PoolPlacementSpec{
|
|
{
|
|
Name: "some_name",
|
|
MetadataPoolName: "meta1",
|
|
DataPoolName: "data1",
|
|
DataNonECPoolName: "data-non-ec1",
|
|
StorageClasses: []cephv1.PlacementStorageClassSpec{},
|
|
},
|
|
{
|
|
Name: "some_name_2",
|
|
Default: true,
|
|
MetadataPoolName: "meta2",
|
|
DataPoolName: "data2",
|
|
DataNonECPoolName: "data-non-ec2",
|
|
StorageClasses: []cephv1.PlacementStorageClassSpec{},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
want: "meta2",
|
|
},
|
|
{
|
|
name: "shared pool returned if default placement not set",
|
|
args: args{
|
|
spec: cephv1.ObjectSharedPoolsSpec{
|
|
MetadataPoolName: "meta-shared",
|
|
DataPoolName: "data-shared",
|
|
PreserveRadosNamespaceDataOnDelete: false,
|
|
PoolPlacements: []cephv1.PoolPlacementSpec{
|
|
{
|
|
Name: "default",
|
|
Default: false,
|
|
MetadataPoolName: "meta1",
|
|
DataPoolName: "data1",
|
|
DataNonECPoolName: "data-non-ec1",
|
|
StorageClasses: []cephv1.PlacementStorageClassSpec{},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
want: "meta-shared",
|
|
},
|
|
{
|
|
name: "no pool returned",
|
|
args: args{
|
|
spec: cephv1.ObjectSharedPoolsSpec{
|
|
MetadataPoolName: "",
|
|
DataPoolName: "data-shared",
|
|
PreserveRadosNamespaceDataOnDelete: false,
|
|
PoolPlacements: []cephv1.PoolPlacementSpec{
|
|
{
|
|
Name: "default",
|
|
Default: false,
|
|
MetadataPoolName: "meta1",
|
|
DataPoolName: "data1",
|
|
DataNonECPoolName: "data-non-ec1",
|
|
StorageClasses: []cephv1.PlacementStorageClassSpec{},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
want: "",
|
|
},
|
|
}
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
if got := getDefaultMetadataPool(tt.args.spec); got != tt.want {
|
|
t.Errorf("getDefaultMetadataPool() = %v, want %v", got, tt.want)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func Test_toZonePlacementPool(t *testing.T) {
|
|
type args struct {
|
|
spec cephv1.PoolPlacementSpec
|
|
ns string
|
|
}
|
|
tests := []struct {
|
|
name string
|
|
args args
|
|
want ZonePlacementPool
|
|
}{
|
|
{
|
|
name: "map default placement without non-ec to config",
|
|
args: args{
|
|
spec: cephv1.PoolPlacementSpec{
|
|
Name: defaultPlacementCephConfigName,
|
|
Default: true,
|
|
MetadataPoolName: "meta",
|
|
DataPoolName: "data",
|
|
DataNonECPoolName: "",
|
|
StorageClasses: []cephv1.PlacementStorageClassSpec{
|
|
{
|
|
Name: "REDUCED_REDUNDANCY",
|
|
DataPoolName: "reduced",
|
|
},
|
|
},
|
|
},
|
|
ns: "ns",
|
|
},
|
|
want: ZonePlacementPool{
|
|
Key: defaultPlacementCephConfigName,
|
|
Val: ZonePlacementPoolVal{
|
|
DataExtraPool: "meta:ns.default-placement.data.non-ec",
|
|
IndexPool: "meta:ns.default-placement.index",
|
|
StorageClasses: map[string]ZonePlacementStorageClass{
|
|
defaultPlacementStorageClass: {
|
|
DataPool: "data:ns.default-placement.data",
|
|
},
|
|
"REDUCED_REDUNDANCY": {
|
|
DataPool: "reduced:ns.REDUCED_REDUNDANCY",
|
|
},
|
|
},
|
|
InlineData: true,
|
|
},
|
|
},
|
|
},
|
|
{
|
|
name: "map default placement to config",
|
|
args: args{
|
|
spec: cephv1.PoolPlacementSpec{
|
|
Name: "fast",
|
|
Default: true,
|
|
MetadataPoolName: "meta",
|
|
DataPoolName: "data",
|
|
DataNonECPoolName: "repl",
|
|
StorageClasses: []cephv1.PlacementStorageClassSpec{
|
|
{
|
|
Name: "REDUCED_REDUNDANCY",
|
|
DataPoolName: "reduced",
|
|
},
|
|
},
|
|
},
|
|
ns: "ns",
|
|
},
|
|
want: ZonePlacementPool{
|
|
Key: "fast",
|
|
Val: ZonePlacementPoolVal{
|
|
DataExtraPool: "repl:ns.fast.data.non-ec",
|
|
IndexPool: "meta:ns.fast.index",
|
|
StorageClasses: map[string]ZonePlacementStorageClass{
|
|
defaultPlacementStorageClass: {
|
|
DataPool: "data:ns.fast.data",
|
|
},
|
|
"REDUCED_REDUNDANCY": {
|
|
DataPool: "reduced:ns.REDUCED_REDUNDANCY",
|
|
},
|
|
},
|
|
InlineData: true,
|
|
},
|
|
},
|
|
},
|
|
{
|
|
name: "map non-default placement without non-ec to config",
|
|
args: args{
|
|
spec: cephv1.PoolPlacementSpec{
|
|
Name: "placement",
|
|
Default: false,
|
|
MetadataPoolName: "meta",
|
|
DataPoolName: "data",
|
|
DataNonECPoolName: "",
|
|
StorageClasses: []cephv1.PlacementStorageClassSpec{
|
|
{
|
|
Name: "REDUCED_REDUNDANCY",
|
|
DataPoolName: "reduced",
|
|
},
|
|
},
|
|
},
|
|
ns: "ns",
|
|
},
|
|
want: ZonePlacementPool{
|
|
Key: "placement",
|
|
Val: ZonePlacementPoolVal{
|
|
DataExtraPool: "meta:ns.placement.data.non-ec",
|
|
IndexPool: "meta:ns.placement.index",
|
|
StorageClasses: map[string]ZonePlacementStorageClass{
|
|
defaultPlacementStorageClass: {
|
|
DataPool: "data:ns.placement.data",
|
|
},
|
|
"REDUCED_REDUNDANCY": {
|
|
DataPool: "reduced:ns.REDUCED_REDUNDANCY",
|
|
},
|
|
},
|
|
InlineData: true,
|
|
},
|
|
},
|
|
},
|
|
{
|
|
name: "map non-default placement to config",
|
|
args: args{
|
|
spec: cephv1.PoolPlacementSpec{
|
|
Name: "placement",
|
|
Default: false,
|
|
MetadataPoolName: "meta",
|
|
DataPoolName: "data",
|
|
DataNonECPoolName: "repl",
|
|
StorageClasses: []cephv1.PlacementStorageClassSpec{
|
|
{
|
|
Name: "REDUCED_REDUNDANCY",
|
|
DataPoolName: "reduced",
|
|
},
|
|
},
|
|
},
|
|
ns: "ns",
|
|
},
|
|
want: ZonePlacementPool{
|
|
Key: "placement",
|
|
Val: ZonePlacementPoolVal{
|
|
DataExtraPool: "repl:ns.placement.data.non-ec",
|
|
IndexPool: "meta:ns.placement.index",
|
|
StorageClasses: map[string]ZonePlacementStorageClass{
|
|
defaultPlacementStorageClass: {
|
|
DataPool: "data:ns.placement.data",
|
|
},
|
|
"REDUCED_REDUNDANCY": {
|
|
DataPool: "reduced:ns.REDUCED_REDUNDANCY",
|
|
},
|
|
},
|
|
InlineData: true,
|
|
},
|
|
},
|
|
},
|
|
}
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
assert.Equal(t, tt.want, toZonePlacementPool(tt.args.spec, tt.args.ns))
|
|
})
|
|
}
|
|
}
|
|
|
|
func Test_toZonePlacementPools(t *testing.T) {
|
|
type args struct {
|
|
spec cephv1.ObjectSharedPoolsSpec
|
|
ns string
|
|
}
|
|
tests := []struct {
|
|
name string
|
|
args args
|
|
want map[string]ZonePlacementPool
|
|
}{
|
|
{
|
|
name: "backward compatible with prev shared pools",
|
|
args: args{
|
|
spec: cephv1.ObjectSharedPoolsSpec{
|
|
MetadataPoolName: "meta",
|
|
DataPoolName: "data",
|
|
PreserveRadosNamespaceDataOnDelete: false,
|
|
},
|
|
ns: "rgw-instance",
|
|
},
|
|
want: map[string]ZonePlacementPool{
|
|
defaultPlacementCephConfigName: {
|
|
Key: defaultPlacementCephConfigName,
|
|
Val: ZonePlacementPoolVal{
|
|
DataExtraPool: "meta:rgw-instance.buckets.non-ec",
|
|
IndexPool: "meta:rgw-instance.buckets.index",
|
|
StorageClasses: map[string]ZonePlacementStorageClass{
|
|
"STANDARD": {
|
|
DataPool: "data:rgw-instance.buckets.data",
|
|
},
|
|
},
|
|
InlineData: true,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
name: "shared pools not removed if default placement set",
|
|
args: args{
|
|
spec: cephv1.ObjectSharedPoolsSpec{
|
|
MetadataPoolName: "meta",
|
|
DataPoolName: "data",
|
|
PreserveRadosNamespaceDataOnDelete: false,
|
|
PoolPlacements: []cephv1.PoolPlacementSpec{
|
|
{
|
|
Name: "some_name",
|
|
Default: true,
|
|
MetadataPoolName: "meta1",
|
|
DataPoolName: "data1",
|
|
DataNonECPoolName: "data-non-ec",
|
|
StorageClasses: []cephv1.PlacementStorageClassSpec{
|
|
{
|
|
Name: "REDUCED_REDUNDANCY",
|
|
DataPoolName: "reduced",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
ns: "rgw-instance",
|
|
},
|
|
want: map[string]ZonePlacementPool{
|
|
defaultPlacementCephConfigName: {
|
|
Key: defaultPlacementCephConfigName,
|
|
Val: ZonePlacementPoolVal{
|
|
DataExtraPool: "meta:rgw-instance.buckets.non-ec",
|
|
IndexPool: "meta:rgw-instance.buckets.index",
|
|
StorageClasses: map[string]ZonePlacementStorageClass{
|
|
"STANDARD": {
|
|
DataPool: "data:rgw-instance.buckets.data",
|
|
},
|
|
},
|
|
InlineData: true,
|
|
},
|
|
},
|
|
"some_name": {
|
|
Key: "some_name",
|
|
Val: ZonePlacementPoolVal{
|
|
DataExtraPool: "data-non-ec:rgw-instance.some_name.data.non-ec",
|
|
IndexPool: "meta1:rgw-instance.some_name.index",
|
|
StorageClasses: map[string]ZonePlacementStorageClass{
|
|
defaultPlacementStorageClass: {
|
|
DataPool: "data1:rgw-instance.some_name.data",
|
|
},
|
|
"REDUCED_REDUNDANCY": {
|
|
DataPool: "reduced:rgw-instance.REDUCED_REDUNDANCY",
|
|
},
|
|
},
|
|
InlineData: true,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
name: "no default set",
|
|
args: args{
|
|
spec: cephv1.ObjectSharedPoolsSpec{
|
|
MetadataPoolName: "",
|
|
DataPoolName: "",
|
|
PreserveRadosNamespaceDataOnDelete: false,
|
|
PoolPlacements: []cephv1.PoolPlacementSpec{
|
|
{
|
|
Name: "placement",
|
|
MetadataPoolName: "meta1",
|
|
DataPoolName: "data1",
|
|
DataNonECPoolName: "data-non-ec",
|
|
StorageClasses: []cephv1.PlacementStorageClassSpec{
|
|
{
|
|
Name: "REDUCED_REDUNDANCY",
|
|
DataPoolName: "reduced",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
ns: "rgw-instance",
|
|
},
|
|
want: map[string]ZonePlacementPool{
|
|
"placement": {
|
|
Key: "placement",
|
|
Val: ZonePlacementPoolVal{
|
|
DataExtraPool: "data-non-ec:rgw-instance.placement.data.non-ec",
|
|
IndexPool: "meta1:rgw-instance.placement.index",
|
|
StorageClasses: map[string]ZonePlacementStorageClass{
|
|
defaultPlacementStorageClass: {
|
|
DataPool: "data1:rgw-instance.placement.data",
|
|
},
|
|
"REDUCED_REDUNDANCY": {
|
|
DataPool: "reduced:rgw-instance.REDUCED_REDUNDANCY",
|
|
},
|
|
},
|
|
InlineData: true,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
name: "default shared and placement",
|
|
args: args{
|
|
spec: cephv1.ObjectSharedPoolsSpec{
|
|
MetadataPoolName: "meta",
|
|
DataPoolName: "data",
|
|
PreserveRadosNamespaceDataOnDelete: false,
|
|
PoolPlacements: []cephv1.PoolPlacementSpec{
|
|
{
|
|
Name: "placement",
|
|
MetadataPoolName: "meta1",
|
|
DataPoolName: "data1",
|
|
DataNonECPoolName: "data-non-ec",
|
|
StorageClasses: []cephv1.PlacementStorageClassSpec{
|
|
{
|
|
Name: "REDUCED_REDUNDANCY",
|
|
DataPoolName: "reduced",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
ns: "rgw-instance",
|
|
},
|
|
want: map[string]ZonePlacementPool{
|
|
defaultPlacementCephConfigName: {
|
|
Key: defaultPlacementCephConfigName,
|
|
Val: ZonePlacementPoolVal{
|
|
DataExtraPool: "meta:rgw-instance.buckets.non-ec",
|
|
IndexPool: "meta:rgw-instance.buckets.index",
|
|
StorageClasses: map[string]ZonePlacementStorageClass{
|
|
"STANDARD": {
|
|
DataPool: "data:rgw-instance.buckets.data",
|
|
},
|
|
},
|
|
InlineData: true,
|
|
},
|
|
},
|
|
"placement": {
|
|
Key: "placement",
|
|
Val: ZonePlacementPoolVal{
|
|
DataExtraPool: "data-non-ec:rgw-instance.placement.data.non-ec",
|
|
IndexPool: "meta1:rgw-instance.placement.index",
|
|
StorageClasses: map[string]ZonePlacementStorageClass{
|
|
defaultPlacementStorageClass: {
|
|
DataPool: "data1:rgw-instance.placement.data",
|
|
},
|
|
"REDUCED_REDUNDANCY": {
|
|
DataPool: "reduced:rgw-instance.REDUCED_REDUNDANCY",
|
|
},
|
|
},
|
|
InlineData: true,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
}
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
assert.Equal(t, tt.want, toZonePlacementPools(tt.args.spec, tt.args.ns))
|
|
})
|
|
}
|
|
}
|
|
|
|
func Test_adjustZoneDefaultPools(t *testing.T) {
|
|
type args struct {
|
|
beforeJSON string
|
|
spec cephv1.ObjectSharedPoolsSpec
|
|
}
|
|
tests := []struct {
|
|
name string
|
|
args args
|
|
wantJSON string
|
|
wantChanged bool
|
|
wantErr bool
|
|
}{
|
|
{
|
|
name: "nothing changed if default shared pool not set",
|
|
args: args{
|
|
beforeJSON: `{
|
|
"id": "f539c2c0-e1ed-4c42-9294-41742352eeae",
|
|
"name": "test",
|
|
"domain_root": "DomainRoot",
|
|
"control_pool": "ControlPool",
|
|
"gc_pool": "GcPool",
|
|
"lc_pool": "LcPool",
|
|
"log_pool": "LogPool",
|
|
"intent_log_pool": "IntentLogPool",
|
|
"usage_log_pool": "UsageLogPool",
|
|
"roles_pool": "RolesPool",
|
|
"reshard_pool": "ReshardPool",
|
|
"user_keys_pool": "UserKeysPool",
|
|
"user_email_pool": "UserEmailPool",
|
|
"user_swift_pool": "UserSwiftPool",
|
|
"user_uid_pool": "UserUIDPool",
|
|
"otp_pool": "OtpPool",
|
|
"notif_pool": "NotifPool",
|
|
"system_key": {
|
|
"access_key": "AccessKey",
|
|
"secret_key": "SecretKey"
|
|
},
|
|
"placement_pools": [],
|
|
"realm_id": "29e28253-be54-4581-90dd-206020d2fcdd"
|
|
}`,
|
|
spec: cephv1.ObjectSharedPoolsSpec{
|
|
MetadataPoolName: "",
|
|
DataPoolName: "",
|
|
PreserveRadosNamespaceDataOnDelete: false,
|
|
PoolPlacements: []cephv1.PoolPlacementSpec{
|
|
{
|
|
Name: "non-default",
|
|
MetadataPoolName: "meta",
|
|
DataPoolName: "data",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
wantJSON: `{
|
|
"id": "f539c2c0-e1ed-4c42-9294-41742352eeae",
|
|
"name": "test",
|
|
"domain_root": "DomainRoot",
|
|
"control_pool": "ControlPool",
|
|
"gc_pool": "GcPool",
|
|
"lc_pool": "LcPool",
|
|
"log_pool": "LogPool",
|
|
"intent_log_pool": "IntentLogPool",
|
|
"usage_log_pool": "UsageLogPool",
|
|
"roles_pool": "RolesPool",
|
|
"reshard_pool": "ReshardPool",
|
|
"user_keys_pool": "UserKeysPool",
|
|
"user_email_pool": "UserEmailPool",
|
|
"user_swift_pool": "UserSwiftPool",
|
|
"user_uid_pool": "UserUIDPool",
|
|
"otp_pool": "OtpPool",
|
|
"notif_pool": "NotifPool",
|
|
"system_key": {
|
|
"access_key": "AccessKey",
|
|
"secret_key": "SecretKey"
|
|
},
|
|
"placement_pools": [],
|
|
"realm_id": "29e28253-be54-4581-90dd-206020d2fcdd"
|
|
}`,
|
|
wantChanged: false,
|
|
wantErr: false,
|
|
},
|
|
{
|
|
name: "shared pool set",
|
|
args: args{
|
|
beforeJSON: `{
|
|
"id": "f539c2c0-e1ed-4c42-9294-41742352eeae",
|
|
"name": "test",
|
|
"domain_root": "DomainRoot",
|
|
"control_pool": "ControlPool",
|
|
"gc_pool": "GcPool",
|
|
"lc_pool": "LcPool",
|
|
"log_pool": "LogPool",
|
|
"intent_log_pool": "IntentLogPool",
|
|
"usage_log_pool": "UsageLogPool",
|
|
"roles_pool": "RolesPool",
|
|
"reshard_pool": "ReshardPool",
|
|
"user_keys_pool": "UserKeysPool",
|
|
"user_email_pool": "UserEmailPool",
|
|
"user_swift_pool": "UserSwiftPool",
|
|
"user_uid_pool": "UserUIDPool",
|
|
"otp_pool": "OtpPool",
|
|
"notif_pool": "NotifPool",
|
|
"system_key": {
|
|
"access_key": "AccessKey",
|
|
"secret_key": "SecretKey"
|
|
},
|
|
"placement_pools": [],
|
|
"realm_id": "29e28253-be54-4581-90dd-206020d2fcdd"
|
|
}`,
|
|
spec: cephv1.ObjectSharedPoolsSpec{
|
|
MetadataPoolName: "meta-pool",
|
|
DataPoolName: "data-pool",
|
|
PreserveRadosNamespaceDataOnDelete: false,
|
|
},
|
|
},
|
|
wantJSON: `{
|
|
"id": "f539c2c0-e1ed-4c42-9294-41742352eeae",
|
|
"name": "test",
|
|
"domain_root": "meta-pool:test.meta.root",
|
|
"control_pool": "meta-pool:test.control",
|
|
"gc_pool": "meta-pool:test.log.gc",
|
|
"lc_pool": "meta-pool:test.log.lc",
|
|
"log_pool": "meta-pool:test.log",
|
|
"intent_log_pool": "meta-pool:test.log.intent",
|
|
"usage_log_pool": "meta-pool:test.log.usage",
|
|
"roles_pool": "meta-pool:test.meta.roles",
|
|
"reshard_pool": "meta-pool:test.log.reshard",
|
|
"user_keys_pool": "meta-pool:test.meta.users.keys",
|
|
"user_email_pool": "meta-pool:test.meta.users.email",
|
|
"user_swift_pool": "meta-pool:test.meta.users.swift",
|
|
"user_uid_pool": "meta-pool:test.meta.users.uid",
|
|
"otp_pool": "meta-pool:test.otp",
|
|
"notif_pool": "meta-pool:test.log.notif",
|
|
"system_key": {
|
|
"access_key": "AccessKey",
|
|
"secret_key": "SecretKey"
|
|
},
|
|
"placement_pools": [],
|
|
"realm_id": "29e28253-be54-4581-90dd-206020d2fcdd"
|
|
}`,
|
|
wantChanged: true,
|
|
wantErr: false,
|
|
},
|
|
{
|
|
name: "config equals to spec: no changes needed",
|
|
args: args{
|
|
beforeJSON: `{
|
|
"id": "f539c2c0-e1ed-4c42-9294-41742352eeae",
|
|
"name": "test",
|
|
"domain_root": "meta-pool:test.meta.root",
|
|
"control_pool": "meta-pool:test.control",
|
|
"gc_pool": "meta-pool:test.log.gc",
|
|
"lc_pool": "meta-pool:test.log.lc",
|
|
"log_pool": "meta-pool:test.log",
|
|
"intent_log_pool": "meta-pool:test.log.intent",
|
|
"usage_log_pool": "meta-pool:test.log.usage",
|
|
"roles_pool": "meta-pool:test.meta.roles",
|
|
"reshard_pool": "meta-pool:test.log.reshard",
|
|
"user_keys_pool": "meta-pool:test.meta.users.keys",
|
|
"user_email_pool": "meta-pool:test.meta.users.email",
|
|
"user_swift_pool": "meta-pool:test.meta.users.swift",
|
|
"user_uid_pool": "meta-pool:test.meta.users.uid",
|
|
"otp_pool": "meta-pool:test.otp",
|
|
"notif_pool": "meta-pool:test.log.notif",
|
|
"system_key": {
|
|
"access_key": "AccessKey",
|
|
"secret_key": "SecretKey"
|
|
},
|
|
"placement_pools": [],
|
|
"realm_id": "29e28253-be54-4581-90dd-206020d2fcdd"
|
|
}`,
|
|
spec: cephv1.ObjectSharedPoolsSpec{
|
|
MetadataPoolName: "meta-pool",
|
|
DataPoolName: "data-pool",
|
|
PreserveRadosNamespaceDataOnDelete: false,
|
|
PoolPlacements: []cephv1.PoolPlacementSpec{},
|
|
},
|
|
},
|
|
wantJSON: `{
|
|
"id": "f539c2c0-e1ed-4c42-9294-41742352eeae",
|
|
"name": "test",
|
|
"domain_root": "meta-pool:test.meta.root",
|
|
"control_pool": "meta-pool:test.control",
|
|
"gc_pool": "meta-pool:test.log.gc",
|
|
"lc_pool": "meta-pool:test.log.lc",
|
|
"log_pool": "meta-pool:test.log",
|
|
"intent_log_pool": "meta-pool:test.log.intent",
|
|
"usage_log_pool": "meta-pool:test.log.usage",
|
|
"roles_pool": "meta-pool:test.meta.roles",
|
|
"reshard_pool": "meta-pool:test.log.reshard",
|
|
"user_keys_pool": "meta-pool:test.meta.users.keys",
|
|
"user_email_pool": "meta-pool:test.meta.users.email",
|
|
"user_swift_pool": "meta-pool:test.meta.users.swift",
|
|
"user_uid_pool": "meta-pool:test.meta.users.uid",
|
|
"otp_pool": "meta-pool:test.otp",
|
|
"notif_pool": "meta-pool:test.log.notif",
|
|
"system_key": {
|
|
"access_key": "AccessKey",
|
|
"secret_key": "SecretKey"
|
|
},
|
|
"placement_pools": [],
|
|
"realm_id": "29e28253-be54-4581-90dd-206020d2fcdd"
|
|
}
|
|
`,
|
|
wantChanged: false,
|
|
wantErr: false,
|
|
},
|
|
{
|
|
name: "default placement pool overrides shared pool",
|
|
args: args{
|
|
beforeJSON: `{
|
|
"id": "f539c2c0-e1ed-4c42-9294-41742352eeae",
|
|
"name": "test",
|
|
"domain_root": "DomainRoot",
|
|
"control_pool": "ControlPool",
|
|
"gc_pool": "GcPool",
|
|
"lc_pool": "LcPool",
|
|
"log_pool": "LogPool",
|
|
"intent_log_pool": "IntentLogPool",
|
|
"usage_log_pool": "UsageLogPool",
|
|
"roles_pool": "RolesPool",
|
|
"reshard_pool": "ReshardPool",
|
|
"user_keys_pool": "UserKeysPool",
|
|
"user_email_pool": "UserEmailPool",
|
|
"user_swift_pool": "UserSwiftPool",
|
|
"user_uid_pool": "UserUIDPool",
|
|
"otp_pool": "OtpPool",
|
|
"notif_pool": "NotifPool",
|
|
"system_key": {
|
|
"access_key": "AccessKey",
|
|
"secret_key": "SecretKey"
|
|
},
|
|
"placement_pools": [],
|
|
"realm_id": "29e28253-be54-4581-90dd-206020d2fcdd"
|
|
}`,
|
|
spec: cephv1.ObjectSharedPoolsSpec{
|
|
MetadataPoolName: "shared-meta-pool",
|
|
DataPoolName: "shared-data-pool",
|
|
PreserveRadosNamespaceDataOnDelete: false,
|
|
PoolPlacements: []cephv1.PoolPlacementSpec{
|
|
{
|
|
Name: "some_name",
|
|
Default: true,
|
|
MetadataPoolName: "meta-pool",
|
|
DataPoolName: "data-pool",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
wantJSON: `{
|
|
"id": "f539c2c0-e1ed-4c42-9294-41742352eeae",
|
|
"name": "test",
|
|
"domain_root": "meta-pool:test.meta.root",
|
|
"control_pool": "meta-pool:test.control",
|
|
"gc_pool": "meta-pool:test.log.gc",
|
|
"lc_pool": "meta-pool:test.log.lc",
|
|
"log_pool": "meta-pool:test.log",
|
|
"intent_log_pool": "meta-pool:test.log.intent",
|
|
"usage_log_pool": "meta-pool:test.log.usage",
|
|
"roles_pool": "meta-pool:test.meta.roles",
|
|
"reshard_pool": "meta-pool:test.log.reshard",
|
|
"user_keys_pool": "meta-pool:test.meta.users.keys",
|
|
"user_email_pool": "meta-pool:test.meta.users.email",
|
|
"user_swift_pool": "meta-pool:test.meta.users.swift",
|
|
"user_uid_pool": "meta-pool:test.meta.users.uid",
|
|
"otp_pool": "meta-pool:test.otp",
|
|
"notif_pool": "meta-pool:test.log.notif",
|
|
"system_key": {
|
|
"access_key": "AccessKey",
|
|
"secret_key": "SecretKey"
|
|
},
|
|
"placement_pools": [],
|
|
"realm_id": "29e28253-be54-4581-90dd-206020d2fcdd"
|
|
}`,
|
|
wantChanged: true,
|
|
wantErr: false,
|
|
},
|
|
{
|
|
name: "v19 shared pool set",
|
|
args: args{
|
|
beforeJSON: `{
|
|
"id": "f539c2c0-e1ed-4c42-9294-41742352eeae",
|
|
"name": "test",
|
|
"topics_pool": "TopicsPool",
|
|
"account_pool": "AccountPool",
|
|
"group_pool": "GroupPool",
|
|
"domain_root": "DomainRoot",
|
|
"control_pool": "ControlPool",
|
|
"gc_pool": "GcPool",
|
|
"lc_pool": "LcPool",
|
|
"log_pool": "LogPool",
|
|
"intent_log_pool": "IntentLogPool",
|
|
"usage_log_pool": "UsageLogPool",
|
|
"roles_pool": "RolesPool",
|
|
"reshard_pool": "ReshardPool",
|
|
"user_keys_pool": "UserKeysPool",
|
|
"user_email_pool": "UserEmailPool",
|
|
"user_swift_pool": "UserSwiftPool",
|
|
"user_uid_pool": "UserUIDPool",
|
|
"otp_pool": "OtpPool",
|
|
"notif_pool": "NotifPool",
|
|
"system_key": {
|
|
"access_key": "AccessKey",
|
|
"secret_key": "SecretKey"
|
|
},
|
|
"placement_pools": [],
|
|
"realm_id": "29e28253-be54-4581-90dd-206020d2fcdd"
|
|
}`,
|
|
spec: cephv1.ObjectSharedPoolsSpec{
|
|
MetadataPoolName: "meta-pool",
|
|
DataPoolName: "data-pool",
|
|
PreserveRadosNamespaceDataOnDelete: false,
|
|
},
|
|
},
|
|
wantJSON: `{
|
|
"id": "f539c2c0-e1ed-4c42-9294-41742352eeae",
|
|
"name": "test",
|
|
"topics_pool": "meta-pool:test.meta.topics",
|
|
"account_pool": "meta-pool:test.meta.account",
|
|
"group_pool": "meta-pool:test.meta.group",
|
|
"domain_root": "meta-pool:test.meta.root",
|
|
"control_pool": "meta-pool:test.control",
|
|
"gc_pool": "meta-pool:test.log.gc",
|
|
"lc_pool": "meta-pool:test.log.lc",
|
|
"log_pool": "meta-pool:test.log",
|
|
"intent_log_pool": "meta-pool:test.log.intent",
|
|
"usage_log_pool": "meta-pool:test.log.usage",
|
|
"roles_pool": "meta-pool:test.meta.roles",
|
|
"reshard_pool": "meta-pool:test.log.reshard",
|
|
"user_keys_pool": "meta-pool:test.meta.users.keys",
|
|
"user_email_pool": "meta-pool:test.meta.users.email",
|
|
"user_swift_pool": "meta-pool:test.meta.users.swift",
|
|
"user_uid_pool": "meta-pool:test.meta.users.uid",
|
|
"otp_pool": "meta-pool:test.otp",
|
|
"notif_pool": "meta-pool:test.log.notif",
|
|
"system_key": {
|
|
"access_key": "AccessKey",
|
|
"secret_key": "SecretKey"
|
|
},
|
|
"placement_pools": [],
|
|
"realm_id": "29e28253-be54-4581-90dd-206020d2fcdd"
|
|
}`,
|
|
wantChanged: true,
|
|
wantErr: false,
|
|
},
|
|
}
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
srcZone := map[string]interface{}{}
|
|
err := json.Unmarshal([]byte(tt.args.beforeJSON), &srcZone)
|
|
assert.NoError(t, err)
|
|
// Provide a mock executor so checkPoolIsEmpty can run ceph/rados commands (best-effort).
|
|
executor := &exectest.MockExecutor{
|
|
MockExecuteCommandWithOutput: func(command string, args ...string) (string, error) {
|
|
if args[0] == "osd" && args[1] == "lspools" {
|
|
return `[]`, nil
|
|
}
|
|
return `{"pools":[]}`, nil
|
|
},
|
|
MockExecuteCommandWithTimeout: func(timeout time.Duration, command string, args ...string) (string, error) {
|
|
return "", nil
|
|
},
|
|
}
|
|
objContext := &Context{
|
|
Context: &clusterd.Context{Executor: executor},
|
|
clusterInfo: cephclient.AdminTestClusterInfo("test"),
|
|
}
|
|
changedZone, err := adjustZoneDefaultPools(objContext, srcZone, tt.args.spec)
|
|
|
|
// check that source was not modified
|
|
orig := map[string]interface{}{}
|
|
jErr := json.Unmarshal([]byte(tt.args.beforeJSON), &orig)
|
|
assert.NoError(t, jErr)
|
|
assert.EqualValues(t, orig, srcZone, "src was not modified")
|
|
|
|
if tt.wantErr {
|
|
assert.Error(t, err)
|
|
return
|
|
} else {
|
|
assert.NoError(t, err)
|
|
}
|
|
assert.Equal(t, tt.wantChanged, !reflect.DeepEqual(srcZone, changedZone))
|
|
bytes, err := json.Marshal(&changedZone)
|
|
assert.NoError(t, err)
|
|
assert.JSONEq(t, tt.wantJSON, string(bytes))
|
|
})
|
|
}
|
|
}
|
|
|
|
func Test_adjustZonePlacementPools(t *testing.T) {
|
|
type args struct {
|
|
beforeJSON string
|
|
spec cephv1.ObjectSharedPoolsSpec
|
|
}
|
|
tests := []struct {
|
|
name string
|
|
args args
|
|
wantJSON string
|
|
wantChanged bool
|
|
wantErr bool
|
|
}{
|
|
{
|
|
name: "no changes: shared spec not set",
|
|
args: args{
|
|
beforeJSON: `{
|
|
"id": "f539c2c0-e1ed-4c42-9294-41742352eeae",
|
|
"name": "test",
|
|
"placement_pools": [
|
|
{
|
|
"key": "default-placement",
|
|
"val": {
|
|
"index_pool": "test.rgw.buckets.index",
|
|
"storage_classes": {
|
|
"STANDARD": {
|
|
"data_pool": "test.rgw.buckets.data"
|
|
}
|
|
},
|
|
"data_extra_pool": "test.rgw.buckets.non-ec",
|
|
"index_type": 0,
|
|
"inline_data": true
|
|
}
|
|
}
|
|
]
|
|
}`,
|
|
spec: cephv1.ObjectSharedPoolsSpec{},
|
|
},
|
|
wantJSON: `{
|
|
"id": "f539c2c0-e1ed-4c42-9294-41742352eeae",
|
|
"name": "test",
|
|
"placement_pools": [
|
|
{
|
|
"key": "default-placement",
|
|
"val": {
|
|
"index_pool": "test.rgw.buckets.index",
|
|
"storage_classes": {
|
|
"STANDARD": {
|
|
"data_pool": "test.rgw.buckets.data"
|
|
}
|
|
},
|
|
"data_extra_pool": "test.rgw.buckets.non-ec",
|
|
"index_type": 0,
|
|
"inline_data": true
|
|
}
|
|
}
|
|
]
|
|
}`,
|
|
wantChanged: false,
|
|
wantErr: false,
|
|
},
|
|
{
|
|
name: "no changes: spec equal to config",
|
|
args: args{
|
|
beforeJSON: `{
|
|
"id": "f539c2c0-e1ed-4c42-9294-41742352eeae",
|
|
"name": "test",
|
|
"placement_pools": [
|
|
{
|
|
"key": "default-placement",
|
|
"val": {
|
|
"index_pool": "meta-pool:test.buckets.index",
|
|
"storage_classes": {
|
|
"STANDARD": {
|
|
"data_pool": "data-pool:test.buckets.data"
|
|
}
|
|
},
|
|
"data_extra_pool": "meta-pool:test.buckets.non-ec",
|
|
"index_type": 5,
|
|
"inline_data": true
|
|
}
|
|
}
|
|
]
|
|
}`,
|
|
spec: cephv1.ObjectSharedPoolsSpec{
|
|
MetadataPoolName: "meta-pool",
|
|
DataPoolName: "data-pool",
|
|
},
|
|
},
|
|
wantJSON: `{
|
|
"id": "f539c2c0-e1ed-4c42-9294-41742352eeae",
|
|
"name": "test",
|
|
"placement_pools": [
|
|
{
|
|
"key": "default-placement",
|
|
"val": {
|
|
"index_pool": "meta-pool:test.buckets.index",
|
|
"storage_classes": {
|
|
"STANDARD": {
|
|
"data_pool": "data-pool:test.buckets.data"
|
|
}
|
|
},
|
|
"data_extra_pool": "meta-pool:test.buckets.non-ec",
|
|
"index_type": 5,
|
|
"inline_data": true
|
|
}
|
|
}
|
|
]
|
|
}`,
|
|
wantChanged: false,
|
|
wantErr: false,
|
|
},
|
|
{
|
|
name: "default placement is preserved when non-default placement added",
|
|
args: args{
|
|
beforeJSON: `{
|
|
"id": "f539c2c0-e1ed-4c42-9294-41742352eeae",
|
|
"name": "test",
|
|
"placement_pools": [
|
|
{
|
|
"key": "default-placement",
|
|
"val": {
|
|
"index_pool": "test.rgw.buckets.index",
|
|
"storage_classes": {
|
|
"STANDARD": {
|
|
"data_pool": "test.rgw.buckets.data"
|
|
}
|
|
},
|
|
"data_extra_pool": "test.rgw.buckets.non-ec",
|
|
"index_type": 5,
|
|
"inline_data": true
|
|
}
|
|
}
|
|
]
|
|
}`,
|
|
spec: cephv1.ObjectSharedPoolsSpec{
|
|
MetadataPoolName: "",
|
|
DataPoolName: "",
|
|
PreserveRadosNamespaceDataOnDelete: false,
|
|
PoolPlacements: []cephv1.PoolPlacementSpec{{
|
|
Name: "fast",
|
|
MetadataPoolName: "fast-meta",
|
|
DataPoolName: "fast-data",
|
|
DataNonECPoolName: "fast-non-ec",
|
|
StorageClasses: []cephv1.PlacementStorageClassSpec{
|
|
{
|
|
Name: "REDUCED_REDUNDANCY",
|
|
DataPoolName: "reduced",
|
|
},
|
|
},
|
|
}},
|
|
},
|
|
},
|
|
wantJSON: `{
|
|
"id": "f539c2c0-e1ed-4c42-9294-41742352eeae",
|
|
"name": "test",
|
|
"placement_pools": [
|
|
{
|
|
"key": "default-placement",
|
|
"val": {
|
|
"index_pool": "test.rgw.buckets.index",
|
|
"storage_classes": {
|
|
"STANDARD": {
|
|
"data_pool": "test.rgw.buckets.data"
|
|
}
|
|
},
|
|
"data_extra_pool": "test.rgw.buckets.non-ec",
|
|
"index_type": 5,
|
|
"inline_data": true
|
|
}
|
|
},
|
|
{
|
|
"key": "fast",
|
|
"val": {
|
|
"index_pool": "fast-meta:test.fast.index",
|
|
"storage_classes": {
|
|
"STANDARD": {
|
|
"data_pool": "fast-data:test.fast.data"
|
|
},
|
|
"REDUCED_REDUNDANCY": {
|
|
"data_pool": "reduced:test.REDUCED_REDUNDANCY"
|
|
}
|
|
},
|
|
"data_extra_pool": "fast-non-ec:test.fast.data.non-ec",
|
|
"inline_data": true
|
|
}
|
|
}
|
|
|
|
]
|
|
}`,
|
|
wantChanged: true,
|
|
wantErr: false,
|
|
},
|
|
{
|
|
name: "delete placement",
|
|
args: args{
|
|
beforeJSON: `{
|
|
"id": "f539c2c0-e1ed-4c42-9294-41742352eeae",
|
|
"name": "test",
|
|
"placement_pools": [
|
|
{
|
|
"key": "default-placement",
|
|
"val": {
|
|
"index_pool": "test.rgw.buckets.index",
|
|
"storage_classes": {
|
|
"STANDARD": {
|
|
"data_pool": "test.rgw.buckets.data"
|
|
}
|
|
},
|
|
"data_extra_pool": "test.rgw.buckets.non-ec",
|
|
"index_type": 5,
|
|
"inline_data": true
|
|
}
|
|
},
|
|
{
|
|
"key": "fast",
|
|
"val": {
|
|
"index_pool": "fast-meta:test.fast.index",
|
|
"storage_classes": {
|
|
"STANDARD": {
|
|
"data_pool": "fast-data:test.fast.data"
|
|
}
|
|
},
|
|
"data_extra_pool": "fast-non-ec:test.fast.data.non-ec",
|
|
"index_type": 0,
|
|
"inline_data": true
|
|
}
|
|
},
|
|
{
|
|
"key": "slow",
|
|
"val": {
|
|
"index_pool": "slow-meta:test.slow.index",
|
|
"storage_classes": {
|
|
"STANDARD": {
|
|
"data_pool": "slow-data:test.slow.data"
|
|
}
|
|
},
|
|
"data_extra_pool": "slow-non-ec:test.slow.data.non-ec",
|
|
"index_type": 0,
|
|
"inline_data": false
|
|
}
|
|
}
|
|
]
|
|
}`,
|
|
spec: cephv1.ObjectSharedPoolsSpec{
|
|
MetadataPoolName: "",
|
|
DataPoolName: "",
|
|
PreserveRadosNamespaceDataOnDelete: false,
|
|
PoolPlacements: []cephv1.PoolPlacementSpec{
|
|
{
|
|
Name: "slow",
|
|
MetadataPoolName: "slow-meta",
|
|
DataPoolName: "slow-data",
|
|
DataNonECPoolName: "slow-non-ec",
|
|
StorageClasses: []cephv1.PlacementStorageClassSpec{},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
wantJSON: `{
|
|
"id": "f539c2c0-e1ed-4c42-9294-41742352eeae",
|
|
"name": "test",
|
|
"placement_pools": [
|
|
{
|
|
"key": "default-placement",
|
|
"val": {
|
|
"index_pool": "test.rgw.buckets.index",
|
|
"storage_classes": {
|
|
"STANDARD": {
|
|
"data_pool": "test.rgw.buckets.data"
|
|
}
|
|
},
|
|
"data_extra_pool": "test.rgw.buckets.non-ec",
|
|
"index_type": 5,
|
|
"inline_data": true
|
|
}
|
|
},
|
|
{
|
|
"key": "slow",
|
|
"val": {
|
|
"index_pool": "slow-meta:test.slow.index",
|
|
"storage_classes": {
|
|
"STANDARD": {
|
|
"data_pool": "slow-data:test.slow.data"
|
|
}
|
|
},
|
|
"data_extra_pool": "slow-non-ec:test.slow.data.non-ec",
|
|
"index_type": 0,
|
|
"inline_data": false
|
|
}
|
|
}
|
|
]
|
|
}`,
|
|
wantChanged: true,
|
|
wantErr: false,
|
|
},
|
|
{
|
|
name: "sharedPools placement not removed if default set",
|
|
args: args{
|
|
beforeJSON: `{
|
|
"id": "f539c2c0-e1ed-4c42-9294-41742352eeae",
|
|
"name": "test",
|
|
"placement_pools": [
|
|
{
|
|
"key": "default-placement",
|
|
"val": {
|
|
"index_pool": "test.rgw.buckets.index",
|
|
"storage_classes": {
|
|
"STANDARD": {
|
|
"data_pool": "test.rgw.buckets.data"
|
|
}
|
|
},
|
|
"data_extra_pool": "test.rgw.buckets.non-ec",
|
|
"index_type": 5,
|
|
"inline_data": true
|
|
}
|
|
}
|
|
]
|
|
}`,
|
|
spec: cephv1.ObjectSharedPoolsSpec{
|
|
MetadataPoolName: "meta-pool",
|
|
DataPoolName: "data-pool",
|
|
PreserveRadosNamespaceDataOnDelete: false,
|
|
PoolPlacements: []cephv1.PoolPlacementSpec{
|
|
{
|
|
Name: "slow",
|
|
Default: true,
|
|
MetadataPoolName: "slow-meta",
|
|
DataPoolName: "slow-data",
|
|
DataNonECPoolName: "slow-non-ec",
|
|
StorageClasses: []cephv1.PlacementStorageClassSpec{},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
wantJSON: `{
|
|
"id": "f539c2c0-e1ed-4c42-9294-41742352eeae",
|
|
"name": "test",
|
|
"placement_pools": [
|
|
{
|
|
"key": "default-placement",
|
|
"val": {
|
|
"index_pool": "meta-pool:test.buckets.index",
|
|
"storage_classes": {
|
|
"STANDARD": {
|
|
"data_pool": "data-pool:test.buckets.data"
|
|
}
|
|
},
|
|
"data_extra_pool": "meta-pool:test.buckets.non-ec",
|
|
"index_type": 5,
|
|
"inline_data": true
|
|
}
|
|
},
|
|
{
|
|
"key": "slow",
|
|
"val": {
|
|
"index_pool": "slow-meta:test.slow.index",
|
|
"storage_classes": {
|
|
"STANDARD": {
|
|
"data_pool": "slow-data:test.slow.data"
|
|
}
|
|
},
|
|
"data_extra_pool": "slow-non-ec:test.slow.data.non-ec",
|
|
"inline_data": true
|
|
}
|
|
}
|
|
]
|
|
}`,
|
|
wantChanged: true,
|
|
wantErr: false,
|
|
},
|
|
{
|
|
name: "if sharedPools not set and default placement is set, then default placements values are copied to 'default-placement'",
|
|
args: args{
|
|
beforeJSON: `{
|
|
"id": "f539c2c0-e1ed-4c42-9294-41742352eeae",
|
|
"name": "test",
|
|
"placement_pools": [
|
|
{
|
|
"key": "default-placement",
|
|
"val": {
|
|
"index_pool": "test.rgw.buckets.index",
|
|
"storage_classes": {
|
|
"STANDARD": {
|
|
"data_pool": "test.rgw.buckets.data"
|
|
}
|
|
},
|
|
"data_extra_pool": "test.rgw.buckets.non-ec",
|
|
"index_type": 5,
|
|
"inline_data": true
|
|
}
|
|
}
|
|
]
|
|
}`,
|
|
spec: cephv1.ObjectSharedPoolsSpec{
|
|
MetadataPoolName: "",
|
|
DataPoolName: "",
|
|
PreserveRadosNamespaceDataOnDelete: false,
|
|
PoolPlacements: []cephv1.PoolPlacementSpec{
|
|
{
|
|
Name: "slow",
|
|
Default: true,
|
|
MetadataPoolName: "slow-meta",
|
|
DataPoolName: "slow-data",
|
|
DataNonECPoolName: "slow-non-ec",
|
|
StorageClasses: []cephv1.PlacementStorageClassSpec{},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
wantJSON: `{
|
|
"id": "f539c2c0-e1ed-4c42-9294-41742352eeae",
|
|
"name": "test",
|
|
"placement_pools": [
|
|
{
|
|
"key": "default-placement",
|
|
"val": {
|
|
"index_pool": "slow-meta:test.slow.index",
|
|
"storage_classes": {
|
|
"STANDARD": {
|
|
"data_pool": "slow-data:test.slow.data"
|
|
}
|
|
},
|
|
"data_extra_pool": "slow-non-ec:test.slow.data.non-ec",
|
|
"index_type": 5,
|
|
"inline_data": true
|
|
}
|
|
},
|
|
{
|
|
"key": "slow",
|
|
"val": {
|
|
"index_pool": "slow-meta:test.slow.index",
|
|
"storage_classes": {
|
|
"STANDARD": {
|
|
"data_pool": "slow-data:test.slow.data"
|
|
}
|
|
},
|
|
"data_extra_pool": "slow-non-ec:test.slow.data.non-ec",
|
|
"inline_data": true
|
|
}
|
|
}
|
|
]
|
|
}`,
|
|
wantChanged: true,
|
|
wantErr: false,
|
|
},
|
|
}
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
srcZone := map[string]interface{}{}
|
|
err := json.Unmarshal([]byte(tt.args.beforeJSON), &srcZone)
|
|
assert.NoError(t, err)
|
|
changedZone, err := adjustZonePlacementPools(srcZone, tt.args.spec)
|
|
// check that source zone was not modified:
|
|
orig := map[string]interface{}{}
|
|
jErr := json.Unmarshal([]byte(tt.args.beforeJSON), &orig)
|
|
assert.NoError(t, jErr)
|
|
assert.EqualValues(t, srcZone, orig, "source obj was not modified")
|
|
|
|
if tt.wantErr {
|
|
assert.Error(t, err)
|
|
return
|
|
} else {
|
|
assert.NoError(t, err)
|
|
}
|
|
bytes, err := json.Marshal(&changedZone)
|
|
assert.NoError(t, err)
|
|
assert.JSONEq(t, tt.wantJSON, string(bytes))
|
|
|
|
assert.EqualValues(t, tt.wantChanged, !reflect.DeepEqual(srcZone, changedZone))
|
|
})
|
|
}
|
|
}
|
|
|
|
func Test_adjustZoneGroupPlacementTargets(t *testing.T) {
|
|
type args struct {
|
|
zone string
|
|
groupBefore string
|
|
defaultPlacement string
|
|
}
|
|
tests := []struct {
|
|
name string
|
|
args args
|
|
wantGroup string
|
|
wantChanged bool
|
|
wantErr bool
|
|
}{
|
|
{
|
|
name: "nothing changed",
|
|
args: args{
|
|
defaultPlacement: defaultPlacementCephConfigName,
|
|
groupBefore: `{
|
|
"id": "610c9e3d-19e7-40b0-9f88-03319c4bc65a",
|
|
"name": "test",
|
|
"placement_targets": [
|
|
{
|
|
"name": "default-placement",
|
|
"tags": [],
|
|
"storage_classes": [
|
|
"STANDARD"
|
|
]
|
|
}
|
|
],
|
|
"default_placement": "default-placement",
|
|
"enabled_features": [
|
|
"resharding"
|
|
]
|
|
}`,
|
|
zone: `{
|
|
"id": "f539c2c0-e1ed-4c42-9294-41742352eeae",
|
|
"name": "test",
|
|
"placement_pools": [
|
|
{
|
|
"key": "default-placement",
|
|
"val": {
|
|
"index_pool": "test.rgw.buckets.index",
|
|
"storage_classes": {
|
|
"STANDARD": {
|
|
"data_pool": "test.rgw.buckets.data"
|
|
}
|
|
},
|
|
"data_extra_pool": "test.rgw.buckets.non-ec",
|
|
"index_type": 5,
|
|
"inline_data": true
|
|
}
|
|
}
|
|
]
|
|
}`,
|
|
},
|
|
wantGroup: `{
|
|
"id": "610c9e3d-19e7-40b0-9f88-03319c4bc65a",
|
|
"name": "test",
|
|
"placement_targets": [
|
|
{
|
|
"name": "default-placement",
|
|
"tags": [],
|
|
"storage_classes": [
|
|
"STANDARD"
|
|
]
|
|
}
|
|
],
|
|
"default_placement": "default-placement",
|
|
"enabled_features": [
|
|
"resharding"
|
|
]
|
|
}`,
|
|
wantChanged: false,
|
|
wantErr: false,
|
|
},
|
|
{
|
|
name: "default changed",
|
|
args: args{
|
|
defaultPlacement: defaultPlacementCephConfigName,
|
|
groupBefore: `{
|
|
"id": "610c9e3d-19e7-40b0-9f88-03319c4bc65a",
|
|
"name": "test",
|
|
"placement_targets": [
|
|
{
|
|
"name": "default-placement",
|
|
"tags": [],
|
|
"storage_classes": [
|
|
"STANDARD"
|
|
]
|
|
}
|
|
],
|
|
"default_placement": "some-placement",
|
|
"enabled_features": [
|
|
"resharding"
|
|
]
|
|
}`,
|
|
zone: `{
|
|
"id": "f539c2c0-e1ed-4c42-9294-41742352eeae",
|
|
"name": "test",
|
|
"placement_pools": [
|
|
{
|
|
"key": "default-placement",
|
|
"val": {
|
|
"index_pool": "test.rgw.buckets.index",
|
|
"storage_classes": {
|
|
"STANDARD": {
|
|
"data_pool": "test.rgw.buckets.data"
|
|
}
|
|
},
|
|
"data_extra_pool": "test.rgw.buckets.non-ec",
|
|
"index_type": 5,
|
|
"inline_data": true
|
|
}
|
|
}
|
|
]
|
|
}`,
|
|
},
|
|
wantGroup: `{
|
|
"id": "610c9e3d-19e7-40b0-9f88-03319c4bc65a",
|
|
"name": "test",
|
|
"placement_targets": [
|
|
{
|
|
"name": "default-placement",
|
|
"tags": [],
|
|
"storage_classes": [
|
|
"STANDARD"
|
|
]
|
|
}
|
|
],
|
|
"default_placement": "default-placement",
|
|
"enabled_features": [
|
|
"resharding"
|
|
]
|
|
}`,
|
|
wantChanged: true,
|
|
wantErr: false,
|
|
},
|
|
{
|
|
name: "storage class added",
|
|
args: args{
|
|
defaultPlacement: defaultPlacementCephConfigName,
|
|
groupBefore: `{
|
|
"id": "610c9e3d-19e7-40b0-9f88-03319c4bc65a",
|
|
"name": "test",
|
|
"placement_targets": [
|
|
{
|
|
"name": "default-placement",
|
|
"tags": [],
|
|
"storage_classes": [
|
|
"STANDARD"
|
|
]
|
|
}
|
|
],
|
|
"default_placement": "default-placement",
|
|
"enabled_features": [
|
|
"resharding"
|
|
]
|
|
}`,
|
|
zone: `{
|
|
"id": "f539c2c0-e1ed-4c42-9294-41742352eeae",
|
|
"name": "test",
|
|
"placement_pools": [
|
|
{
|
|
"key": "default-placement",
|
|
"val": {
|
|
"index_pool": "test.rgw.buckets.index",
|
|
"storage_classes": {
|
|
"STANDARD": {
|
|
"data_pool": "test.rgw.buckets.data"
|
|
},
|
|
"REDUCED_REDUNDANCY": {
|
|
"data_pool": "test.rgw.buckets.data"
|
|
}
|
|
},
|
|
"data_extra_pool": "test.rgw.buckets.non-ec",
|
|
"index_type": 5,
|
|
"inline_data": true
|
|
}
|
|
}
|
|
]
|
|
}`,
|
|
},
|
|
wantGroup: `{
|
|
"id": "610c9e3d-19e7-40b0-9f88-03319c4bc65a",
|
|
"name": "test",
|
|
"placement_targets": [
|
|
{
|
|
"name": "default-placement",
|
|
"tags": [],
|
|
"storage_classes": [
|
|
"REDUCED_REDUNDANCY","STANDARD"
|
|
]
|
|
}
|
|
],
|
|
"default_placement": "default-placement",
|
|
"enabled_features": [
|
|
"resharding"
|
|
]
|
|
}`,
|
|
wantChanged: true,
|
|
wantErr: false,
|
|
},
|
|
{
|
|
name: "placement added",
|
|
args: args{
|
|
defaultPlacement: defaultPlacementCephConfigName,
|
|
groupBefore: `{
|
|
"id": "610c9e3d-19e7-40b0-9f88-03319c4bc65a",
|
|
"name": "test",
|
|
"placement_targets": [
|
|
{
|
|
"name": "default-placement",
|
|
"tags": [],
|
|
"storage_classes": [
|
|
"STANDARD"
|
|
]
|
|
}
|
|
],
|
|
"default_placement": "default-placement",
|
|
"enabled_features": [
|
|
"resharding"
|
|
]
|
|
}`,
|
|
zone: `{
|
|
"id": "f539c2c0-e1ed-4c42-9294-41742352eeae",
|
|
"name": "test",
|
|
"placement_pools": [
|
|
{
|
|
"key": "default-placement",
|
|
"val": {
|
|
"index_pool": "test.rgw.buckets.index",
|
|
"storage_classes": {
|
|
"STANDARD": {
|
|
"data_pool": "test.rgw.buckets.data"
|
|
},
|
|
"REDUCED_REDUNDANCY": {
|
|
"data_pool": "test.rgw.buckets.data"
|
|
}
|
|
},
|
|
"data_extra_pool": "test.rgw.buckets.non-ec"
|
|
}
|
|
},
|
|
{
|
|
"key": "slow",
|
|
"val": {
|
|
"index_pool": "test.rgw.buckets.index",
|
|
"storage_classes": {
|
|
"STANDARD": {
|
|
"data_pool": "test.rgw.buckets.data"
|
|
}
|
|
},
|
|
"data_extra_pool": "test.rgw.buckets.non-ec"
|
|
}
|
|
}
|
|
]
|
|
}`,
|
|
},
|
|
wantGroup: `{
|
|
"id": "610c9e3d-19e7-40b0-9f88-03319c4bc65a",
|
|
"name": "test",
|
|
"placement_targets": [
|
|
{
|
|
"name": "default-placement",
|
|
"tags": [],
|
|
"storage_classes": [
|
|
"REDUCED_REDUNDANCY","STANDARD"
|
|
]
|
|
},
|
|
{
|
|
"name": "slow",
|
|
"storage_classes": [
|
|
"STANDARD"
|
|
]
|
|
}
|
|
],
|
|
"default_placement": "default-placement",
|
|
"enabled_features": [
|
|
"resharding"
|
|
]
|
|
}`,
|
|
wantChanged: true,
|
|
wantErr: false,
|
|
},
|
|
{
|
|
name: "placement and sc removed",
|
|
args: args{
|
|
defaultPlacement: defaultPlacementCephConfigName,
|
|
groupBefore: `{
|
|
"id": "610c9e3d-19e7-40b0-9f88-03319c4bc65a",
|
|
"name": "test",
|
|
"placement_targets": [
|
|
{
|
|
"name": "default-placement",
|
|
"tags": [],
|
|
"storage_classes": [
|
|
"REDUCED_REDUNDANCY","STANDARD"
|
|
]
|
|
},
|
|
{
|
|
"name": "slow",
|
|
"tags": [],
|
|
"storage_classes": [
|
|
"STANDARD"
|
|
]
|
|
}
|
|
],
|
|
"default_placement": "default-placement",
|
|
"enabled_features": [
|
|
"resharding"
|
|
]
|
|
}`,
|
|
zone: `{
|
|
"id": "f539c2c0-e1ed-4c42-9294-41742352eeae",
|
|
"name": "test",
|
|
"placement_pools": [
|
|
{
|
|
"key": "default-placement",
|
|
"val": {
|
|
"index_pool": "test.rgw.buckets.index",
|
|
"storage_classes": {
|
|
"STANDARD": {
|
|
"data_pool": "test.rgw.buckets.data"
|
|
}
|
|
},
|
|
"data_extra_pool": "test.rgw.buckets.non-ec"
|
|
}
|
|
}
|
|
]
|
|
}`,
|
|
},
|
|
wantGroup: `{
|
|
"id": "610c9e3d-19e7-40b0-9f88-03319c4bc65a",
|
|
"name": "test",
|
|
"placement_targets": [
|
|
{
|
|
"name": "default-placement",
|
|
"tags": [],
|
|
"storage_classes": [
|
|
"STANDARD"
|
|
]
|
|
}
|
|
],
|
|
"default_placement": "default-placement",
|
|
"enabled_features": [
|
|
"resharding"
|
|
]
|
|
}`,
|
|
wantChanged: true,
|
|
wantErr: false,
|
|
},
|
|
}
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
zj := map[string]interface{}{}
|
|
err := json.Unmarshal([]byte(tt.args.zone), &zj)
|
|
assert.NoError(t, err)
|
|
srcGroup := map[string]interface{}{}
|
|
err = json.Unmarshal([]byte(tt.args.groupBefore), &srcGroup)
|
|
assert.NoError(t, err)
|
|
changedGroup, err := adjustZoneGroupPlacementTargets(srcGroup, zj, tt.args.defaultPlacement)
|
|
|
|
orig := map[string]interface{}{}
|
|
jErr := json.Unmarshal([]byte(tt.args.groupBefore), &orig)
|
|
assert.NoError(t, jErr)
|
|
assert.EqualValues(t, orig, srcGroup, "src was not modified")
|
|
|
|
if tt.wantErr {
|
|
assert.Error(t, err)
|
|
return
|
|
} else {
|
|
assert.NoError(t, err)
|
|
}
|
|
assert.Equal(t, tt.wantChanged, !reflect.DeepEqual(srcGroup, changedGroup))
|
|
bytes, err := json.Marshal(changedGroup)
|
|
assert.NoError(t, err)
|
|
assert.JSONEq(t, tt.wantGroup, string(bytes))
|
|
})
|
|
}
|
|
}
|
|
|
|
func Test_createPlacementTargetsFromZonePoolPlacements(t *testing.T) {
|
|
type args struct {
|
|
zone string
|
|
}
|
|
tests := []struct {
|
|
name string
|
|
args args
|
|
want map[string]ZonegroupPlacementTarget
|
|
wantErr bool
|
|
}{
|
|
{
|
|
name: "",
|
|
args: args{
|
|
zone: `{
|
|
"id": "f539c2c0-e1ed-4c42-9294-41742352eeae",
|
|
"name": "test",
|
|
"placement_pools": [
|
|
{
|
|
"key": "default-placement",
|
|
"val": {
|
|
"index_pool": "test.rgw.buckets.index",
|
|
"storage_classes": {
|
|
"STANDARD": {
|
|
"data_pool": "test.rgw.buckets.data"
|
|
},
|
|
"REDUCED_REDUNDANCY": {
|
|
"data_pool": "test.rgw.buckets.data"
|
|
}
|
|
},
|
|
"data_extra_pool": "test.rgw.buckets.non-ec",
|
|
"index_type": 5,
|
|
"inline_data": true
|
|
}
|
|
},
|
|
{
|
|
"key": "slow",
|
|
"val": {
|
|
"index_pool": "slow-meta:test.slow.index",
|
|
"storage_classes": {
|
|
"STANDARD": {
|
|
"data_pool": "slow-data:test.slow.data"
|
|
}
|
|
},
|
|
"data_extra_pool": "slow-non-ec:test.slow.data.non-ec",
|
|
"index_type": 0,
|
|
"inline_data": true
|
|
}
|
|
}
|
|
]
|
|
}`,
|
|
},
|
|
want: map[string]ZonegroupPlacementTarget{
|
|
"default-placement": {
|
|
Name: "default-placement",
|
|
StorageClasses: []string{"REDUCED_REDUNDANCY", "STANDARD"},
|
|
},
|
|
"slow": {
|
|
Name: "slow",
|
|
StorageClasses: []string{"STANDARD"},
|
|
},
|
|
},
|
|
wantErr: false,
|
|
},
|
|
}
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
zo := map[string]interface{}{}
|
|
_ = json.Unmarshal([]byte(tt.args.zone), &zo)
|
|
got, err := createPlacementTargetsFromZonePoolPlacements(zo)
|
|
if (err != nil) != tt.wantErr {
|
|
t.Errorf("createPlacementTargetsFromZonePoolPlacements() error = %v, wantErr %v", err, tt.wantErr)
|
|
return
|
|
}
|
|
if !reflect.DeepEqual(got, tt.want) {
|
|
t.Errorf("createPlacementTargetsFromZonePoolPlacements() = %v, want %v", got, tt.want)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func Test_getDefaultPlacementName(t *testing.T) {
|
|
type args struct {
|
|
spec cephv1.ObjectSharedPoolsSpec
|
|
}
|
|
tests := []struct {
|
|
name string
|
|
args args
|
|
want string
|
|
}{
|
|
{
|
|
name: "no default placement set in spec",
|
|
args: args{
|
|
spec: cephv1.ObjectSharedPoolsSpec{
|
|
PoolPlacements: []cephv1.PoolPlacementSpec{
|
|
{
|
|
Name: "one",
|
|
Default: false,
|
|
},
|
|
{
|
|
Name: "two",
|
|
Default: false,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
want: defaultPlacementCephConfigName,
|
|
},
|
|
{
|
|
name: "first placement set as defaultu in spec",
|
|
args: args{
|
|
spec: cephv1.ObjectSharedPoolsSpec{
|
|
PoolPlacements: []cephv1.PoolPlacementSpec{
|
|
{
|
|
Name: "one",
|
|
Default: true,
|
|
},
|
|
{
|
|
Name: "two",
|
|
Default: false,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
want: "one",
|
|
},
|
|
{
|
|
name: "second placement set as default in spec",
|
|
args: args{
|
|
spec: cephv1.ObjectSharedPoolsSpec{
|
|
PoolPlacements: []cephv1.PoolPlacementSpec{
|
|
{
|
|
Name: "one",
|
|
Default: false,
|
|
},
|
|
{
|
|
Name: "two",
|
|
Default: true,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
want: "two",
|
|
},
|
|
}
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
if got := getDefaultPlacementName(tt.args.spec); got != tt.want {
|
|
t.Errorf("getDefaultPlacementName() = %v, want %v", got, tt.want)
|
|
}
|
|
})
|
|
}
|
|
}
|