@ -21,10 +21,7 @@ import (
"fmt"
"fmt"
"os"
"os"
"path/filepath"
"path/filepath"
"strings"
"testing"
"testing"
"github.com/minio/minio/pkg/lock"
)
)
// TestNewFS - tests initialization of all input disks
// TestNewFS - tests initialization of all input disks
@ -88,516 +85,6 @@ func TestFSShutdown(t *testing.T) {
}
}
}
}
// Tests migrating FS format without .minio.sys/buckets.
func TestFSMigrateObjectWithoutObjects ( t * testing . T ) {
// Prepare for testing
disk := filepath . Join ( globalTestTmpDir , "minio-" + nextSuffix ( ) )
defer removeAll ( disk )
// Assign a new UUID.
uuid := mustGetUUID ( )
// Initialize meta volume, if volume already exists ignores it.
if err := initMetaVolumeFS ( disk , uuid ) ; err != nil {
t . Fatal ( err )
}
fsFormatPath := pathJoin ( disk , minioMetaBucket , fsFormatJSONFile )
formatCfg := & formatConfigV1 {
Version : "1" ,
Format : "fs" ,
FS : & fsFormat {
Version : "1" ,
} ,
}
lk , err := lock . LockedOpenFile ( preparePath ( fsFormatPath ) , os . O_RDWR | os . O_CREATE , 0600 )
if err != nil {
t . Fatal ( err )
}
_ , err = formatCfg . WriteTo ( lk )
lk . Close ( )
if err != nil {
t . Fatal ( "Should not fail here" , err )
}
if err = initFormatFS ( disk , uuid ) ; err != nil {
t . Fatal ( "Should not fail with unexpected" , err )
}
formatCfg = & formatConfigV1 { }
lk , err = lock . LockedOpenFile ( preparePath ( fsFormatPath ) , os . O_RDONLY , 0600 )
if err != nil {
t . Fatal ( err )
}
_ , err = formatCfg . ReadFrom ( lk )
lk . Close ( )
if err != nil {
t . Fatal ( "Should not fail here" , err )
}
if formatCfg . FS . Version != fsFormatV2 {
t . Fatalf ( "Unexpected version detected expected \"%s\", got %s" , fsFormatV2 , formatCfg . FS . Version )
}
}
// Tests migrating FS format without .minio.sys/buckets.
func TestFSMigrateObjectWithErr ( t * testing . T ) {
// Prepare for testing
disk := filepath . Join ( globalTestTmpDir , "minio-" + nextSuffix ( ) )
defer removeAll ( disk )
// Assign a new UUID.
uuid := mustGetUUID ( )
// Initialize meta volume, if volume already exists ignores it.
if err := initMetaVolumeFS ( disk , uuid ) ; err != nil {
t . Fatal ( err )
}
fsFormatPath := pathJoin ( disk , minioMetaBucket , fsFormatJSONFile )
formatCfg := & formatConfigV1 {
Version : "1" ,
Format : "fs" ,
FS : & fsFormat {
Version : "10" ,
} ,
}
lk , err := lock . LockedOpenFile ( preparePath ( fsFormatPath ) , os . O_RDWR | os . O_CREATE , 0600 )
if err != nil {
t . Fatal ( err )
}
_ , err = formatCfg . WriteTo ( lk )
lk . Close ( )
if err != nil {
t . Fatal ( "Should not fail here" , err )
}
if err = initFormatFS ( disk , uuid ) ; err != nil {
if ! strings . Contains ( errorCause ( err ) . Error ( ) , "Unable to validate 'format.json', corrupted backend format" ) {
t . Fatal ( "Should not fail with unexpected" , err )
}
}
fsFormatPath = pathJoin ( disk , minioMetaBucket , fsFormatJSONFile )
formatCfg = & formatConfigV1 {
Version : "1" ,
Format : "garbage" ,
FS : & fsFormat {
Version : "1" ,
} ,
}
lk , err = lock . LockedOpenFile ( preparePath ( fsFormatPath ) , os . O_RDWR | os . O_CREATE , 0600 )
if err != nil {
t . Fatal ( err )
}
_ , err = formatCfg . WriteTo ( lk )
lk . Close ( )
if err != nil {
t . Fatal ( "Should not fail here" , err )
}
if err = initFormatFS ( disk , uuid ) ; err != nil {
if errorCause ( err ) . Error ( ) !=
"Unable to validate 'format.json', Unable to recognize backend format, Disk is not in FS format. garbage" {
t . Fatal ( "Should not fail with unexpected" , err )
}
}
}
// Tests migrating FS format with .minio.sys/buckets filled with
// objects such as policy.json/fs.json, notification.xml/fs.json
// listener.json/fs.json.
func TestFSMigrateObjectWithBucketConfigObjects ( t * testing . T ) {
// Prepare for testing
disk := filepath . Join ( globalTestTmpDir , "minio-" + nextSuffix ( ) )
defer removeAll ( disk )
// Assign a new UUID.
uuid := mustGetUUID ( )
// Initialize meta volume, if volume already exists ignores it.
if err := initMetaVolumeFS ( disk , uuid ) ; err != nil {
t . Fatal ( err )
}
fsFormatPath := pathJoin ( disk , minioMetaBucket , fsFormatJSONFile )
formatCfg := & formatConfigV1 {
Version : "1" ,
Format : "fs" ,
FS : & fsFormat {
Version : "1" ,
} ,
}
lk , err := lock . LockedOpenFile ( preparePath ( fsFormatPath ) , os . O_RDWR | os . O_CREATE , 0600 )
if err != nil {
t . Fatal ( err )
}
_ , err = formatCfg . WriteTo ( lk )
lk . Close ( )
if err != nil {
t . Fatal ( "Should not fail here" , err )
}
// Construct the full path of fs.json
fsPath1 := pathJoin ( bucketMetaPrefix , "testvolume1" , bucketPolicyConfig , fsMetaJSONFile )
fsPath1 = pathJoin ( disk , minioMetaBucket , fsPath1 )
fsMetaJSON := ` { "version":"1.0.0","format":"fs","minio": { "release":"DEVELOPMENT.2017-03-27T02-26-33Z"},"meta": { "etag":"467886be95c8ecfd71a2900e3f461b4f"} `
if _ , err = fsCreateFile ( fsPath1 , bytes . NewReader ( [ ] byte ( fsMetaJSON ) ) , nil , 0 ) ; err != nil {
t . Fatal ( err )
}
// Construct the full path of fs.json
fsPath2 := pathJoin ( bucketMetaPrefix , "testvolume2" , bucketNotificationConfig , fsMetaJSONFile )
fsPath2 = pathJoin ( disk , minioMetaBucket , fsPath2 )
fsMetaJSON = ` { "version":"1.0.0","format":"fs","minio": { "release":"DEVELOPMENT.2017-03-27T02-26-33Z"},"meta": { "etag":"467886be95c8ecfd71a2900eff461b4d"} `
if _ , err = fsCreateFile ( fsPath2 , bytes . NewReader ( [ ] byte ( fsMetaJSON ) ) , nil , 0 ) ; err != nil {
t . Fatal ( err )
}
// Construct the full path of fs.json
fsPath3 := pathJoin ( bucketMetaPrefix , "testvolume3" , bucketListenerConfig , fsMetaJSONFile )
fsPath3 = pathJoin ( disk , minioMetaBucket , fsPath3 )
fsMetaJSON = ` { "version":"1.0.0","format":"fs","minio": { "release":"DEVELOPMENT.2017-03-27T02-26-33Z"},"meta": { "etag":"467886be95c8ecfd71a2900eff461b4d"} `
if _ , err = fsCreateFile ( fsPath3 , bytes . NewReader ( [ ] byte ( fsMetaJSON ) ) , nil , 0 ) ; err != nil {
t . Fatal ( err )
}
if err = initFormatFS ( disk , mustGetUUID ( ) ) ; err != nil {
t . Fatal ( "Should not fail here" , err )
}
fsPath1 = pathJoin ( bucketMetaPrefix , "testvolume1" , objectMetaPrefix , bucketPolicyConfig , fsMetaJSONFile )
fsPath1 = pathJoin ( disk , minioMetaBucket , fsPath1 )
fi , err := fsStatFile ( fsPath1 )
if err != nil {
t . Fatal ( "Path should exist and accessible after migration" , err )
}
if fi . IsDir ( ) {
t . Fatalf ( "Unexpected path %s should be a file" , fsPath1 )
}
fsPath2 = pathJoin ( bucketMetaPrefix , "testvolume2" , objectMetaPrefix , bucketNotificationConfig , fsMetaJSONFile )
fsPath2 = pathJoin ( disk , minioMetaBucket , fsPath2 )
fi , err = fsStatFile ( fsPath2 )
if err != nil {
t . Fatal ( "Path should exist and accessible after migration" , err )
}
if fi . IsDir ( ) {
t . Fatalf ( "Unexpected path %s should be a file" , fsPath2 )
}
fsPath3 = pathJoin ( bucketMetaPrefix , "testvolume3" , objectMetaPrefix , bucketListenerConfig , fsMetaJSONFile )
fsPath3 = pathJoin ( disk , minioMetaBucket , fsPath3 )
fi , err = fsStatFile ( fsPath3 )
if err != nil {
t . Fatal ( "Path should exist and accessible after migration" , err )
}
if fi . IsDir ( ) {
t . Fatalf ( "Unexpected path %s should be a file" , fsPath3 )
}
formatCfg = & formatConfigV1 { }
lk , err = lock . LockedOpenFile ( preparePath ( fsFormatPath ) , os . O_RDONLY , 0600 )
if err != nil {
t . Fatal ( err )
}
_ , err = formatCfg . ReadFrom ( lk )
lk . Close ( )
if err != nil {
t . Fatal ( "Should not fail here" , err )
}
if formatCfg . FS . Version != fsFormatV2 {
t . Fatalf ( "Unexpected version detected expected \"%s\", got %s" , fsFormatV2 , formatCfg . FS . Version )
}
}
// Tests migrating FS format with .minio.sys/buckets filled with
// object metadata.
func TestFSMigrateObjectWithObjects ( t * testing . T ) {
// Prepare for testing
disk := filepath . Join ( globalTestTmpDir , "minio-" + nextSuffix ( ) )
defer removeAll ( disk )
// Assign a new UUID.
uuid := mustGetUUID ( )
// Initialize meta volume, if volume already exists ignores it.
if err := initMetaVolumeFS ( disk , uuid ) ; err != nil {
t . Fatal ( err )
}
fsFormatPath := pathJoin ( disk , minioMetaBucket , fsFormatJSONFile )
formatCfg := & formatConfigV1 {
Version : "1" ,
Format : "fs" ,
FS : & fsFormat {
Version : "1" ,
} ,
}
lk , err := lock . LockedOpenFile ( preparePath ( fsFormatPath ) , os . O_RDWR | os . O_CREATE , 0600 )
if err != nil {
t . Fatal ( err )
}
_ , err = formatCfg . WriteTo ( lk )
lk . Close ( )
if err != nil {
t . Fatal ( "Should not fail here" , err )
}
// Construct the full path of fs.json
fsPath1 := pathJoin ( bucketMetaPrefix , "testvolume1" , "my-object1" , fsMetaJSONFile )
fsPath1 = pathJoin ( disk , minioMetaBucket , fsPath1 )
fsMetaJSON := ` { "version":"1.0.0","format":"fs","minio": { "release":"DEVELOPMENT.2017-03-27T02-26-33Z"},"meta": { "etag":"467886be95c8ecfd71a2900e3f461b4f"} `
if _ , err = fsCreateFile ( fsPath1 , bytes . NewReader ( [ ] byte ( fsMetaJSON ) ) , nil , 0 ) ; err != nil {
t . Fatal ( err )
}
// Construct the full path of fs.json
fsPath2 := pathJoin ( bucketMetaPrefix , "testvolume2" , "my-object2" , fsMetaJSONFile )
fsPath2 = pathJoin ( disk , minioMetaBucket , fsPath2 )
fsMetaJSON = ` { "version":"1.0.0","format":"fs","minio": { "release":"DEVELOPMENT.2017-03-27T02-26-33Z"},"meta": { "etag":"467886be95c8ecfd71a2900eff461b4d"} `
if _ , err = fsCreateFile ( fsPath2 , bytes . NewReader ( [ ] byte ( fsMetaJSON ) ) , nil , 0 ) ; err != nil {
t . Fatal ( err )
}
// Construct the full path of policy.json
ppath := pathJoin ( bucketMetaPrefix , "testvolume2" , bucketPolicyConfig )
ppath = pathJoin ( disk , minioMetaBucket , ppath )
policyJSON := ` { "Version":"2012-10-17","Statement":[ { "Action":["s3:GetBucketLocation","s3:ListBucket"],"Effect":"Allow","Principal": { "AWS":["*"]},"Resource":["arn:aws:s3:::testbucket"],"Sid":""}, { "Action":["s3:GetObject"],"Effect":"Allow","Principal": { "AWS":["*"]},"Resource":["arn:aws:s3:::testbucket/*"],"Sid":""}]} `
if _ , err = fsCreateFile ( ppath , bytes . NewReader ( [ ] byte ( policyJSON ) ) , nil , 0 ) ; err != nil {
t . Fatal ( err )
}
if err = initFormatFS ( disk , mustGetUUID ( ) ) ; err != nil {
t . Fatal ( "Should not fail here" , err )
}
fsPath2 = pathJoin ( bucketMetaPrefix , "testvolume2" , objectMetaPrefix , "my-object2" , fsMetaJSONFile )
fsPath2 = pathJoin ( disk , minioMetaBucket , fsPath2 )
fi , err := fsStatFile ( fsPath2 )
if err != nil {
t . Fatal ( "Path should exist and accessible after migration" , err )
}
if fi . IsDir ( ) {
t . Fatalf ( "Unexpected path %s should be a file" , fsPath2 )
}
formatCfg = & formatConfigV1 { }
lk , err = lock . LockedOpenFile ( preparePath ( fsFormatPath ) , os . O_RDONLY , 0600 )
if err != nil {
t . Fatal ( err )
}
_ , err = formatCfg . ReadFrom ( lk )
lk . Close ( )
if err != nil {
t . Fatal ( "Should not fail here" , err )
}
if formatCfg . FS . Version != fsFormatV2 {
t . Fatalf ( "Unexpected version detected expected \"%s\", got %s" , fsFormatV2 , formatCfg . FS . Version )
}
ppath = pathJoin ( bucketMetaPrefix , "testvolume2" , "acl.json" )
ppath = pathJoin ( disk , minioMetaBucket , ppath )
if _ , err = fsCreateFile ( ppath , bytes . NewReader ( [ ] byte ( "" ) ) , nil , 0 ) ; err != nil {
t . Fatal ( err )
}
if err = initFormatFS ( disk , mustGetUUID ( ) ) ; errorCause ( err ) != errCorruptedFormat {
t . Fatal ( "Should not fail here" , err )
}
}
// TestFSCheckFormatFSErr - test loadFormatFS loading older format.
func TestFSCheckFormatFSErr ( t * testing . T ) {
// Prepare for testing
disk := filepath . Join ( globalTestTmpDir , "minio-" + nextSuffix ( ) )
defer removeAll ( disk )
// Assign a new UUID.
uuid := mustGetUUID ( )
// Initialize meta volume, if volume already exists ignores it.
if err := initMetaVolumeFS ( disk , uuid ) ; err != nil {
t . Fatal ( err )
}
fsFormatPath := pathJoin ( disk , minioMetaBucket , fsFormatJSONFile )
formatCfg := & formatConfigV1 {
Version : "1" ,
Format : "fs" ,
FS : & fsFormat {
Version : "1" ,
} ,
}
lk , err := lock . LockedOpenFile ( preparePath ( fsFormatPath ) , os . O_RDWR | os . O_CREATE , 0600 )
if err != nil {
t . Fatal ( err )
}
_ , err = formatCfg . WriteTo ( lk )
lk . Close ( )
if err != nil {
t . Fatal ( err )
}
formatCfg = & formatConfigV1 { }
lk , err = lock . LockedOpenFile ( preparePath ( fsFormatPath ) , os . O_RDWR | os . O_CREATE , 0600 )
if err != nil {
t . Fatal ( err )
}
_ , err = formatCfg . ReadFrom ( lk )
lk . Close ( )
if err != nil {
t . Fatal ( err )
}
if err = checkFormatFS ( formatCfg , fsFormatVersion ) ; errorCause ( err ) != errFSFormatOld {
t . Fatal ( "Should not fail with unexpected" , err )
}
formatCfg = & formatConfigV1 {
Version : "1" ,
Format : "fs" ,
FS : & fsFormat {
Version : "10" ,
} ,
}
lk , err = lock . LockedOpenFile ( preparePath ( fsFormatPath ) , os . O_RDWR | os . O_CREATE , 0600 )
if err != nil {
t . Fatal ( err )
}
_ , err = formatCfg . WriteTo ( lk )
lk . Close ( )
if err != nil {
t . Fatal ( err )
}
if err = checkFormatFS ( formatCfg , fsFormatVersion ) ; errorCause ( err ) != errCorruptedFormat {
t . Fatal ( "Should not fail with unexpected" , err )
}
formatCfg = & formatConfigV1 {
Version : "1" ,
Format : "garbage" ,
FS : & fsFormat {
Version : "1" ,
} ,
}
lk , err = lock . LockedOpenFile ( preparePath ( fsFormatPath ) , os . O_RDWR | os . O_CREATE , 0600 )
if err != nil {
t . Fatal ( err )
}
_ , err = formatCfg . WriteTo ( lk )
lk . Close ( )
if err != nil {
t . Fatal ( err )
}
if err = checkFormatFS ( formatCfg , fsFormatVersion ) ; err != nil {
if errorCause ( err ) . Error ( ) != "Unable to recognize backend format, Disk is not in FS format. garbage" {
t . Fatal ( "Should not fail with unexpected" , err )
}
}
if err = checkFormatFS ( nil , fsFormatVersion ) ; errorCause ( err ) != errUnexpected {
t . Fatal ( "Should fail with errUnexpected, but found" , err )
}
formatCfg = & formatConfigV1 {
Version : "1" ,
Format : "fs" ,
FS : & fsFormat {
Version : "2" ,
} ,
}
lk , err = lock . LockedOpenFile ( preparePath ( fsFormatPath ) , os . O_RDWR | os . O_CREATE , 0600 )
if err != nil {
t . Fatal ( err )
}
_ , err = formatCfg . WriteTo ( lk )
lk . Close ( )
if err != nil {
t . Fatal ( err )
}
// Should not fail.
if err = checkFormatFS ( formatCfg , fsFormatVersion ) ; err != nil {
t . Fatal ( err )
}
}
// TestFSCheckFormatFS - test loadFormatFS with healty and faulty disks
func TestFSCheckFormatFS ( t * testing . T ) {
// Prepare for testing
disk := filepath . Join ( globalTestTmpDir , "minio-" + nextSuffix ( ) )
defer removeAll ( disk )
// Assign a new UUID.
uuid := mustGetUUID ( )
// Initialize meta volume, if volume already exists ignores it.
if err := initMetaVolumeFS ( disk , uuid ) ; err != nil {
t . Fatal ( err )
}
fsFormatPath := pathJoin ( disk , minioMetaBucket , fsFormatJSONFile )
lk , err := lock . LockedOpenFile ( preparePath ( fsFormatPath ) , os . O_RDWR | os . O_CREATE , 0600 )
if err != nil {
t . Fatal ( err )
}
format := newFSFormatV2 ( )
_ , err = format . WriteTo ( lk )
lk . Close ( )
if err != nil {
t . Fatal ( err )
}
// Loading corrupted format file
file , err := os . OpenFile ( preparePath ( fsFormatPath ) , os . O_APPEND | os . O_WRONLY | os . O_CREATE , 0666 )
if err != nil {
t . Fatal ( "Should not fail here" , err )
}
file . Write ( [ ] byte { 'b' } )
file . Close ( )
lk , err = lock . LockedOpenFile ( preparePath ( fsFormatPath ) , os . O_RDWR | os . O_CREATE , 0600 )
if err != nil {
t . Fatal ( err )
}
format = & formatConfigV1 { }
_ , err = format . ReadFrom ( lk )
lk . Close ( )
if err == nil {
t . Fatal ( "Should return an error here" )
}
// Loading format file from disk not found.
removeAll ( disk )
_ , err = lock . LockedOpenFile ( preparePath ( fsFormatPath ) , os . O_RDONLY , 0600 )
if err != nil && ! os . IsNotExist ( err ) {
t . Fatal ( "Should return 'format.json' does not exist, but got" , err )
}
}
// TestFSGetBucketInfo - test GetBucketInfo with healty and faulty disks
// TestFSGetBucketInfo - test GetBucketInfo with healty and faulty disks
func TestFSGetBucketInfo ( t * testing . T ) {
func TestFSGetBucketInfo ( t * testing . T ) {
// Prepare for testing
// Prepare for testing
@ -633,7 +120,6 @@ func TestFSGetBucketInfo(t *testing.T) {
}
}
}
}
// Tests FS backend put object behavior.
func TestFSPutObject ( t * testing . T ) {
func TestFSPutObject ( t * testing . T ) {
// Prepare for tests
// Prepare for tests
disk := filepath . Join ( globalTestTmpDir , "minio-" + nextSuffix ( ) )
disk := filepath . Join ( globalTestTmpDir , "minio-" + nextSuffix ( ) )