@ -29,125 +29,93 @@ func TestParseStorageClass(t *testing.T) {
func testParseStorageClass ( obj ObjectLayer , instanceType string , t TestErrHandler ) {
func testParseStorageClass ( obj ObjectLayer , instanceType string , t TestErrHandler ) {
tests := [ ] struct {
tests := [ ] struct {
name int
storageClassEnv string
storageClassEnv string
wantSc storageClass
wantSc storageClass
expectedError error
expectedError error
} {
} {
{ 1 , "EC:3" , storageClass {
{ "EC:3" , storageClass {
Scheme : "EC" ,
Scheme : "EC" ,
Parity : 3 } ,
Parity : 3 } ,
nil } ,
nil } ,
{ 2 , "EC:4" , storageClass {
{ "EC:4" , storageClass {
Scheme : "EC" ,
Scheme : "EC" ,
Parity : 4 } ,
Parity : 4 } ,
nil } ,
nil } ,
{ 3 , "AB:4" , storageClass {
{ "AB:4" , storageClass {
Scheme : "EC" ,
Scheme : "EC" ,
Parity : 4 } ,
Parity : 4 } ,
errors . New ( "Unsupported scheme AB. Supported scheme is EC" ) } ,
errors . New ( "Unsupported scheme AB. Supported scheme is EC" ) } ,
{ 4 , "EC:4:5" , storageClass {
{ "EC:4:5" , storageClass {
Scheme : "EC" ,
Scheme : "EC" ,
Parity : 4 } ,
Parity : 4 } ,
errors . New ( "Too many sections in EC:4:5" ) } ,
errors . New ( "Too many sections in EC:4:5" ) } ,
{ 5 , "AB" , storageClass {
{ "AB" , storageClass {
Scheme : "EC" ,
Scheme : "EC" ,
Parity : 4 } ,
Parity : 4 } ,
errors . New ( "Too few sections in AB" ) } ,
errors . New ( "Too few sections in AB" ) } ,
}
}
for _ , tt := range tests {
for i , tt := range tests {
gotSc , err := parseStorageClass ( tt . storageClassEnv )
gotSc , err := parseStorageClass ( tt . storageClassEnv )
if err != nil && tt . expectedError == nil {
if err != nil && tt . expectedError == nil {
t . Errorf ( "Test %d, Expected %s, got %s" , tt . name , tt . expectedError , err )
t . Errorf ( "Test %d, Expected %s, got %s" , i + 1 , tt . expectedError , err )
return
return
}
}
if err == nil && tt . expectedError != nil {
if err == nil && tt . expectedError != nil {
t . Errorf ( "Test %d, Expected %s, got %s" , tt . name , tt . expectedError , err )
t . Errorf ( "Test %d, Expected %s, got %s" , i + 1 , tt . expectedError , err )
return
return
}
}
if tt . expectedError == nil && ! reflect . DeepEqual ( gotSc , tt . wantSc ) {
if tt . expectedError == nil && ! reflect . DeepEqual ( gotSc , tt . wantSc ) {
t . Errorf ( "Test %d, Expected %v, got %v" , tt . name , tt . wantSc , gotSc )
t . Errorf ( "Test %d, Expected %v, got %v" , i + 1 , tt . wantSc , gotSc )
return
return
}
}
if tt . expectedError != nil && ! reflect . DeepEqual ( err , tt . expectedError ) {
if tt . expectedError != nil && ! reflect . DeepEqual ( err , tt . expectedError ) {
t . Errorf ( "Test %d, Expected %v, got %v" , tt . name , tt . expectedError , err )
t . Errorf ( "Test %d, Expected %v, got %v" , i + 1 , tt . expectedError , err )
}
}
}
}
}
}
func TestValidateRRS Parity ( t * testing . T ) {
func TestValidateParity ( t * testing . T ) {
ExecObjectLayerTestWithDirs ( t , testValidateRRS Parity )
ExecObjectLayerTestWithDirs ( t , testValidateParity )
}
}
func testValidateRRS Parity ( obj ObjectLayer , instanceType string , dirs [ ] string , t TestErrHandler ) {
func testValidateParity ( obj ObjectLayer , instanceType string , dirs [ ] string , t TestErrHandler ) {
// Reset global storage class flags
// Reset global storage class flags
resetGlobalStorageEnvs ( )
resetGlobalStorageEnvs ( )
// Set globalEndpoints for a single node XL setup.
globalEndpoints = mustGetNewEndpointList ( dirs ... )
tests := [ ] struct {
// Set globalEndpoints for a single node XL setup.
name int
endpoints := globalEndpoints
rrsParity int
defer func ( ) {
ssParity int
globalEndpoints = endpoints
expectedError error
} ( )
} {
{ 1 , 2 , 4 , nil } ,
{ 2 , 1 , 4 , errors . New ( "Reduced redundancy storage class parity should be greater than or equal to 2" ) } ,
{ 3 , 7 , 6 , errors . New ( "Reduced redundancy storage class parity disks should be less than 6" ) } ,
{ 4 , 9 , 0 , errors . New ( "Reduced redundancy storage class parity disks should be less than 8" ) } ,
{ 5 , 3 , 3 , errors . New ( "Reduced redundancy storage class parity disks should be less than 3" ) } ,
}
for _ , tt := range tests {
err := validateRRSParity ( tt . rrsParity , tt . ssParity )
if err != nil && tt . expectedError == nil {
t . Errorf ( "Test %d, Expected %s, got %s" , tt . name , tt . expectedError , err )
return
}
if err == nil && tt . expectedError != nil {
t . Errorf ( "Test %d, Expected %s, got %s" , tt . name , tt . expectedError , err )
return
}
if tt . expectedError != nil && ! reflect . DeepEqual ( err , tt . expectedError ) {
t . Errorf ( "Test %d, Expected %v, got %v" , tt . name , tt . expectedError , err )
}
}
}
func TestValidateSSParity ( t * testing . T ) {
isXL := globalIsXL
ExecObjectLayerTestWithDirs ( t , testValidateSSParity )
defer func ( ) {
}
globalIsXL = isXL
} ( )
func testValidateSSParity ( obj ObjectLayer , instanceType string , dirs [ ] string , t TestErrHandler ) {
globalIsXL = true
// Reset global storage class flags
resetGlobalStorageEnvs ( )
// Set globalEndpoints for a single node XL setup.
globalEndpoints = mustGetNewEndpointList ( dirs ... )
globalEndpoints = mustGetNewEndpointList ( dirs ... )
tests := [ ] struct {
tests := [ ] struct {
name int
rrsParity int
ssParity int
ssParity int
rrsParity int
success bool
expectedError error
} {
} {
{ 1 , 4 , 2 , nil } ,
{ 2 , 4 , true } ,
{ 2 , 6 , 5 , nil } ,
{ 3 , 3 , true } ,
{ 3 , 1 , 0 , errors . New ( "Standard storage class parity disks should be greater than or equal to 2" ) } ,
{ 1 , 4 , false } ,
{ 4 , 4 , 6 , errors . New ( "Standard storage class parity disks should be greater than 6" ) } ,
{ 7 , 6 , false } ,
{ 5 , 9 , 0 , errors . New ( "Standard storage class parity disks should be less than or equal to 8" ) } ,
{ 9 , 0 , false } ,
{ 6 , 3 , 3 , errors . New ( "Standard storage class parity disks should be greater than 3" ) } ,
{ 9 , 9 , false } ,
{ 2 , 9 , false } ,
}
}
for _ , tt := range tests {
for i , tt := range tests {
err := validateSSParity ( tt . ssParity , tt . rrsParity )
err := validateParity ( tt . ssParity , tt . rrsParity )
if err != nil && tt . expectedError == nil {
if err != nil && tt . success {
t . Errorf ( "Test %d, Expected %s, got %s" , tt . name , tt . expectedError , err )
t . Errorf ( "Test %d, Expected success, got %s" , i + 1 , err )
return
}
if err == nil && tt . expectedError != nil {
t . Errorf ( "Test %d, Expected %s, got %s" , tt . name , tt . expectedError , err )
return
}
}
if tt . expectedError ! = nil && ! reflect . DeepEqual ( err , tt . expectedError ) {
if err == nil && ! tt . success {
t . Errorf ( "Test %d, Expected %v, got %v" , tt . name , tt . expectedError , err )
t . Errorf ( "Test %d, Expected failure, got success" , i + 1 )
}
}
}
}
}
}
@ -162,39 +130,38 @@ func testGetRedundancyCount(obj ObjectLayer, instanceType string, dirs []string,
xl := obj . ( * xlObjects )
xl := obj . ( * xlObjects )
tests := [ ] struct {
tests := [ ] struct {
name int
sc string
sc string
disks [ ] StorageAPI
disks [ ] StorageAPI
expectedData int
expectedData int
expectedParity int
expectedParity int
} {
} {
{ 1 , reducedRedundancyStorageClass , xl . storageDisks , 14 , 2 } ,
{ reducedRedundancyStorageClass , xl . storageDisks , 14 , 2 } ,
{ 2 , standardStorageClass , xl . storageDisks , 8 , 8 } ,
{ standardStorageClass , xl . storageDisks , 8 , 8 } ,
{ 3 , "" , xl . storageDisks , 8 , 8 } ,
{ "" , xl . storageDisks , 8 , 8 } ,
{ 4 , reducedRedundancyStorageClass , xl . storageDisks , 9 , 7 } ,
{ reducedRedundancyStorageClass , xl . storageDisks , 9 , 7 } ,
{ 5 , standardStorageClass , xl . storageDisks , 10 , 6 } ,
{ standardStorageClass , xl . storageDisks , 10 , 6 } ,
{ 6 , "" , xl . storageDisks , 9 , 7 } ,
{ "" , xl . storageDisks , 9 , 7 } ,
}
}
for _ , tt := range tests {
for i , tt := range tests {
// Set env var for test case 4
// Set env var for test case 4
if tt . name == 4 {
if i + 1 == 4 {
globalRRStorageClass . Parity = 7
globalRRStorageClass . Parity = 7
}
}
// Set env var for test case 5
// Set env var for test case 5
if tt . name == 5 {
if i + 1 == 5 {
globalStandardStorageClass . Parity = 6
globalStandardStorageClass . Parity = 6
}
}
// Set env var for test case 6
// Set env var for test case 6
if tt . name == 6 {
if i + 1 == 6 {
globalStandardStorageClass . Parity = 7
globalStandardStorageClass . Parity = 7
}
}
data , parity := getRedundancyCount ( tt . sc , len ( tt . disks ) )
data , parity := getRedundancyCount ( tt . sc , len ( tt . disks ) )
if data != tt . expectedData {
if data != tt . expectedData {
t . Errorf ( "Test %d, Expected data disks %d, got %d" , tt . name , tt . expectedData , data )
t . Errorf ( "Test %d, Expected data disks %d, got %d" , i + 1 , tt . expectedData , data )
return
return
}
}
if parity != tt . expectedParity {
if parity != tt . expectedParity {
t . Errorf ( "Test %d, Expected parity disks %d, got %d" , tt . name , tt . expectedParity , parity )
t . Errorf ( "Test %d, Expected parity disks %d, got %d" , i + 1 , tt . expectedParity , parity )
return
return
}
}
}
}
@ -322,38 +289,36 @@ func testObjectQuorumFromMeta(obj ObjectLayer, instanceType string, dirs []strin
parts7 , errs7 := readAllXLMetadata ( xlDisks , bucket , object7 )
parts7 , errs7 := readAllXLMetadata ( xlDisks , bucket , object7 )
tests := [ ] struct {
tests := [ ] struct {
name int
xl xlObjects
parts [ ] xlMetaV1
parts [ ] xlMetaV1
errs [ ] error
errs [ ] error
expectedReadQuorum int
expectedReadQuorum int
expectedWriteQuorum int
expectedWriteQuorum int
expectedError error
expectedError error
} {
} {
{ 1 , * xl , parts1 , errs1 , 8 , 9 , nil } ,
{ parts1 , errs1 , 8 , 9 , nil } ,
{ 2 , * xl , parts2 , errs2 , 14 , 15 , nil } ,
{ parts2 , errs2 , 14 , 15 , nil } ,
{ 3 , * xl , parts3 , errs3 , 8 , 9 , nil } ,
{ parts3 , errs3 , 8 , 9 , nil } ,
{ 4 , * xl , parts4 , errs4 , 10 , 11 , nil } ,
{ parts4 , errs4 , 10 , 11 , nil } ,
{ 5 , * xl , parts5 , errs5 , 14 , 15 , nil } ,
{ parts5 , errs5 , 14 , 15 , nil } ,
{ 6 , * xl , parts6 , errs6 , 8 , 9 , nil } ,
{ parts6 , errs6 , 8 , 9 , nil } ,
{ 7 , * xl , parts7 , errs7 , 14 , 15 , nil } ,
{ parts7 , errs7 , 14 , 15 , nil } ,
}
}
for _ , tt := range tests {
for i , tt := range tests {
actualReadQuorum , actualWriteQuorum , err := objectQuorumFromMeta ( tt . xl , tt . parts , tt . errs )
actualReadQuorum , actualWriteQuorum , err := objectQuorumFromMeta ( * xl , tt . parts , tt . errs )
if tt . expectedError != nil && err == nil {
if tt . expectedError != nil && err == nil {
t . Errorf ( "Test %d, Expected %s, got %s" , tt . name , tt . expectedError , err )
t . Errorf ( "Test %d, Expected %s, got %s" , i + 1 , tt . expectedError , err )
return
return
}
}
if tt . expectedError == nil && err != nil {
if tt . expectedError == nil && err != nil {
t . Errorf ( "Test %d, Expected %s, got %s" , tt . name , tt . expectedError , err )
t . Errorf ( "Test %d, Expected %s, got %s" , i + 1 , tt . expectedError , err )
return
return
}
}
if tt . expectedReadQuorum != actualReadQuorum {
if tt . expectedReadQuorum != actualReadQuorum {
t . Errorf ( "Test %d, Expected Read Quorum %d, got %d" , tt . name , tt . expectedReadQuorum , actualReadQuorum )
t . Errorf ( "Test %d, Expected Read Quorum %d, got %d" , i + 1 , tt . expectedReadQuorum , actualReadQuorum )
return
return
}
}
if tt . expectedWriteQuorum != actualWriteQuorum {
if tt . expectedWriteQuorum != actualWriteQuorum {
t . Errorf ( "Test %d, Expected Write Quorum %d, got %d" , tt . name , tt . expectedWriteQuorum , actualWriteQuorum )
t . Errorf ( "Test %d, Expected Write Quorum %d, got %d" , i + 1 , tt . expectedWriteQuorum , actualWriteQuorum )
return
return
}
}
}
}
@ -362,21 +327,20 @@ func testObjectQuorumFromMeta(obj ObjectLayer, instanceType string, dirs []strin
// Test isValidStorageClassMeta method with valid and invalid inputs
// Test isValidStorageClassMeta method with valid and invalid inputs
func TestIsValidStorageClassMeta ( t * testing . T ) {
func TestIsValidStorageClassMeta ( t * testing . T ) {
tests := [ ] struct {
tests := [ ] struct {
name int
sc string
sc string
want bool
want bool
} {
} {
{ 1 , "STANDARD" , true } ,
{ "STANDARD" , true } ,
{ 2 , "REDUCED_REDUNDANCY" , true } ,
{ "REDUCED_REDUNDANCY" , true } ,
{ 3 , "" , false } ,
{ "" , false } ,
{ 4 , "INVALID" , false } ,
{ "INVALID" , false } ,
{ 5 , "123" , false } ,
{ "123" , false } ,
{ 6 , "MINIO_STORAGE_CLASS_RRS" , false } ,
{ "MINIO_STORAGE_CLASS_RRS" , false } ,
{ 7 , "MINIO_STORAGE_CLASS_STANDARD" , false } ,
{ "MINIO_STORAGE_CLASS_STANDARD" , false } ,
}
}
for _ , tt := range tests {
for i , tt := range tests {
if got := isValidStorageClassMeta ( tt . sc ) ; got != tt . want {
if got := isValidStorageClassMeta ( tt . sc ) ; got != tt . want {
t . Errorf ( "Test %d, Expected Storage Class to be %t, got %t" , tt . name , tt . want , got )
t . Errorf ( "Test %d, Expected Storage Class to be %t, got %t" , i + 1 , tt . want , got )
}
}
}
}
}
}