posix: Deprecate custom removeAll/mkdirAll implementations. (#4808)

Since go1.8 os.RemoveAll and os.MkdirAll both support long
path names i.e UNC path on windows. The code we are carrying
was directly borrowed from `pkg/os` package and doesn't need
to be in our repo anymore. As a side affect this also
addresses our codecoverage issue.

Refer #4658
This commit is contained in:
Harshavardhana 2017-08-12 19:25:43 -07:00 committed by Dee Koder
parent b69aa9c4d0
commit d864e00e24
67 changed files with 557 additions and 491 deletions

View File

@ -26,6 +26,7 @@ import (
"net/http"
"net/http/httptest"
"net/url"
"os"
"reflect"
"testing"
"time"
@ -182,7 +183,7 @@ func prepareAdminXLTestBed() (*adminXLTestBed, error) {
// TearDown - method that resets the test bed for subsequent unit
// tests to start afresh.
func (atb *adminXLTestBed) TearDown() {
removeAll(atb.configPath)
os.RemoveAll(atb.configPath)
removeRoots(atb.xlDirs)
resetTestGlobals()
}
@ -1363,7 +1364,7 @@ func TestWriteSetConfigResponse(t *testing.T) {
if err != nil {
t.Fatal(err)
}
defer removeAll(rootPath)
defer os.RemoveAll(rootPath)
testCases := []struct {
status bool
errs []error

View File

@ -18,6 +18,7 @@ package cmd
import (
"encoding/json"
"os"
"testing"
)
@ -30,7 +31,7 @@ func testAdminCmd(cmd cmdType, t *testing.T) {
if err != nil {
t.Fatalf("Failed to create test config - %v", err)
}
defer removeAll(rootPath)
defer os.RemoveAll(rootPath)
adminServer := adminCmd{}
creds := serverConfig.GetCredential()
@ -75,7 +76,7 @@ func TestReInitDisks(t *testing.T) {
if err != nil {
t.Fatalf("Unable to initialize server config. %s", err)
}
defer removeAll(rootPath)
defer os.RemoveAll(rootPath)
// Initializing objectLayer for HealFormatHandler.
_, xlDirs, xlErr := initTestXLObjLayer()
@ -149,7 +150,7 @@ func TestGetConfig(t *testing.T) {
if err != nil {
t.Fatalf("Unable to initialize server config. %s", err)
}
defer removeAll(rootPath)
defer os.RemoveAll(rootPath)
adminServer := adminCmd{}
creds := serverConfig.GetCredential()
@ -193,7 +194,7 @@ func TestWriteAndCommitConfig(t *testing.T) {
if err != nil {
t.Fatalf("Unable to initialize server config. %s", err)
}
defer removeAll(rootPath)
defer os.RemoveAll(rootPath)
adminServer := adminCmd{}
creds := serverConfig.GetCredential()

View File

@ -21,6 +21,7 @@ import (
"io"
"net/http"
"net/url"
"os"
"testing"
)
@ -324,7 +325,7 @@ func TestIsReqAuthenticated(t *testing.T) {
if err != nil {
t.Fatalf("unable initialize config file, %s", err)
}
defer removeAll(path)
defer os.RemoveAll(path)
creds, err := createCredential("myuser", "mypassword")
if err != nil {

View File

@ -17,6 +17,7 @@
package cmd
import (
"os"
"testing"
"time"
)
@ -26,7 +27,7 @@ func TestLogin(t *testing.T) {
if err != nil {
t.Fatalf("Failed to create test config - %v", err)
}
defer removeAll(rootPath)
defer os.RemoveAll(rootPath)
creds := serverConfig.GetCredential()
ls := AuthRPCServer{}
testCases := []struct {

View File

@ -21,6 +21,7 @@ import (
"io/ioutil"
"math"
"math/rand"
"os"
"strconv"
"testing"
@ -136,7 +137,7 @@ func benchmarkPutObjectPart(b *testing.B, instanceType string, objSize int) {
if err != nil {
b.Fatalf("Unable to initialize config. %s", err)
}
defer removeAll(rootPath)
defer os.RemoveAll(rootPath)
// create a temp XL/FS backend.
objLayer, disks, err := prepareBenchmarkBackend(instanceType)
@ -155,7 +156,7 @@ func benchmarkPutObject(b *testing.B, instanceType string, objSize int) {
if err != nil {
b.Fatalf("Unable to initialize config. %s", err)
}
defer removeAll(rootPath)
defer os.RemoveAll(rootPath)
// create a temp XL/FS backend.
objLayer, disks, err := prepareBenchmarkBackend(instanceType)
@ -174,7 +175,7 @@ func benchmarkPutObjectParallel(b *testing.B, instanceType string, objSize int)
if err != nil {
b.Fatalf("Unable to initialize config. %s", err)
}
defer removeAll(rootPath)
defer os.RemoveAll(rootPath)
// create a temp XL/FS backend.
objLayer, disks, err := prepareBenchmarkBackend(instanceType)
@ -194,7 +195,7 @@ func runGetObjectBenchmark(b *testing.B, obj ObjectLayer, objSize int) {
if err != nil {
b.Fatalf("Unable to initialize config. %s", err)
}
defer removeAll(rootPath)
defer os.RemoveAll(rootPath)
// obtains random bucket name.
bucket := getRandomBucketName()
@ -263,7 +264,7 @@ func benchmarkGetObject(b *testing.B, instanceType string, objSize int) {
if err != nil {
b.Fatalf("Unable to initialize config. %s", err)
}
defer removeAll(rootPath)
defer os.RemoveAll(rootPath)
// create a temp XL/FS backend.
objLayer, disks, err := prepareBenchmarkBackend(instanceType)
@ -282,7 +283,7 @@ func benchmarkGetObjectParallel(b *testing.B, instanceType string, objSize int)
if err != nil {
b.Fatalf("Unable to initialize config. %s", err)
}
defer removeAll(rootPath)
defer os.RemoveAll(rootPath)
// create a temp XL/FS backend.
objLayer, disks, err := prepareBenchmarkBackend(instanceType)
@ -302,7 +303,7 @@ func runPutObjectBenchmarkParallel(b *testing.B, obj ObjectLayer, objSize int) {
if err != nil {
b.Fatalf("Unable to initialize config. %s", err)
}
defer removeAll(rootPath)
defer os.RemoveAll(rootPath)
// obtains random bucket name.
bucket := getRandomBucketName()
@ -350,7 +351,7 @@ func runGetObjectBenchmarkParallel(b *testing.B, obj ObjectLayer, objSize int) {
if err != nil {
b.Fatalf("Unable to initialize config. %s", err)
}
defer removeAll(rootPath)
defer os.RemoveAll(rootPath)
// obtains random bucket name.
bucket := getRandomBucketName()

View File

@ -25,6 +25,7 @@ import (
"io/ioutil"
"net/http"
"net/http/httptest"
"os"
"reflect"
"testing"
)
@ -51,7 +52,7 @@ func TestWriteNotification(t *testing.T) {
if err != nil {
t.Fatalf("Unable to initialize test config %s", err)
}
defer removeAll(root)
defer os.RemoveAll(root)
var buffer bytes.Buffer
// Collection of test cases for each event writer.
@ -116,7 +117,7 @@ func TestSendBucketNotification(t *testing.T) {
if err != nil {
t.Fatalf("Unable to initialize test config %s", err)
}
defer removeAll(root)
defer os.RemoveAll(root)
eventCh := make(chan []NotificationEvent)

View File

@ -17,6 +17,7 @@
package cmd
import (
"os"
"strings"
"testing"
)
@ -222,7 +223,7 @@ func TestQueueARN(t *testing.T) {
if err != nil {
t.Fatalf("unable initialize config file, %s", err)
}
defer removeAll(rootPath)
defer os.RemoveAll(rootPath)
testCases := []struct {
queueARN string
@ -299,7 +300,7 @@ func TestQueueARN(t *testing.T) {
if err != nil {
t.Fatalf("unable initialize config file, %s", err)
}
defer removeAll(rootPath)
defer os.RemoveAll(rootPath)
testCases = []struct {
queueARN string
@ -332,7 +333,7 @@ func TestUnmarshalSQSARN(t *testing.T) {
if err != nil {
t.Fatalf("unable initialize config file, %s", err)
}
defer removeAll(rootPath)
defer os.RemoveAll(rootPath)
testCases := []struct {
queueARN string
@ -392,7 +393,7 @@ func TestUnmarshalSQSARN(t *testing.T) {
if err != nil {
t.Fatalf("unable initialize config file, %s", err)
}
defer removeAll(rootPath)
defer os.RemoveAll(rootPath)
testCases = []struct {
queueARN string

View File

@ -17,6 +17,7 @@
package cmd
import (
"os"
"path/filepath"
"sync"
@ -76,7 +77,7 @@ func (config *ConfigDir) GetCADir() string {
// Create - creates configuration directory tree.
func (config *ConfigDir) Create() error {
return mkdirAll(config.GetCADir(), 0700)
return os.MkdirAll(config.GetCADir(), 0700)
}
// GetMinioConfigFile - returns absolute path of config.json file.

View File

@ -169,7 +169,7 @@ func purgeV1() error {
return fmt.Errorf("unrecognized config version %s", cv1.Version)
}
removeAll(configFile)
os.RemoveAll(configFile)
log.Println("Removed unsupported config version 1.")
return nil
}

View File

@ -30,7 +30,7 @@ func TestServerConfigMigrateV1(t *testing.T) {
t.Fatalf("Init Test config failed")
}
// remove the root directory after the test ends.
defer removeAll(rootPath)
defer os.RemoveAll(rootPath)
setConfigDir(rootPath)
@ -64,7 +64,7 @@ func TestServerConfigMigrateInexistentConfig(t *testing.T) {
t.Fatalf("Init Test config failed")
}
// remove the root directory after the test ends.
defer removeAll(rootPath)
defer os.RemoveAll(rootPath)
setConfigDir(rootPath)
configPath := rootPath + "/" + minioConfigFile
@ -135,7 +135,7 @@ func TestServerConfigMigrateV2toV19(t *testing.T) {
t.Fatalf("Init Test config failed")
}
// remove the root directory after the test ends.
defer removeAll(rootPath)
defer os.RemoveAll(rootPath)
setConfigDir(rootPath)
configPath := rootPath + "/" + minioConfigFile
@ -190,7 +190,7 @@ func TestServerConfigMigrateFaultyConfig(t *testing.T) {
t.Fatalf("Init Test config failed")
}
// remove the root directory after the test ends.
defer removeAll(rootPath)
defer os.RemoveAll(rootPath)
setConfigDir(rootPath)
configPath := rootPath + "/" + minioConfigFile
@ -261,7 +261,7 @@ func TestServerConfigMigrateCorruptedConfig(t *testing.T) {
t.Fatalf("Init Test config failed")
}
// remove the root directory after the test ends.
defer removeAll(rootPath)
defer os.RemoveAll(rootPath)
setConfigDir(rootPath)
configPath := rootPath + "/" + minioConfigFile

View File

@ -32,7 +32,7 @@ func TestServerConfig(t *testing.T) {
t.Fatalf("Init Test config failed")
}
// remove the root directory after the test ends.
defer removeAll(rootPath)
defer os.RemoveAll(rootPath)
if serverConfig.GetRegion() != globalMinioDefaultRegion {
t.Errorf("Expecting region `us-east-1` found %s", serverConfig.GetRegion())
@ -166,7 +166,7 @@ func TestServerConfigWithEnvs(t *testing.T) {
initConfig()
// remove the root directory after the test ends.
defer removeAll(rootPath)
defer os.RemoveAll(rootPath)
// Check if serverConfig has
if serverConfig.GetBrowser() {
@ -227,7 +227,7 @@ func TestValidateConfig(t *testing.T) {
}
// remove the root directory after the test ends.
defer removeAll(rootPath)
defer os.RemoveAll(rootPath)
configPath := filepath.Join(rootPath, minioConfigFile)

View File

@ -20,6 +20,7 @@ import (
"bytes"
"errors"
"io"
"os"
"testing"
)
@ -74,7 +75,7 @@ func TestCopyBuffer(t *testing.T) {
if err != nil {
t.Fatalf("Unable to create posix test setup, %s", err)
}
defer removeAll(diskPath)
defer os.RemoveAll(diskPath)
volume := "success-vol"
// Setup test environment.

View File

@ -18,6 +18,7 @@ package cmd
import (
"bytes"
"os"
"testing"
)
@ -189,7 +190,7 @@ type erasureTestSetup struct {
// Removes the temporary disk directories.
func (e erasureTestSetup) Remove() {
for _, path := range e.diskPaths {
removeAll(path)
os.RemoveAll(path)
}
}

View File

@ -19,6 +19,7 @@ package cmd
import (
"bytes"
"fmt"
"os"
"reflect"
"testing"
"time"
@ -32,7 +33,7 @@ func TestInitEventNotifierFaultyDisks(t *testing.T) {
t.Fatalf("Init Test config failed")
}
// remove the root directory after the test ends.
defer removeAll(rootPath)
defer os.RemoveAll(rootPath)
disks, err := getRandomDisks(4)
if err != nil {
@ -85,10 +86,10 @@ func TestInitEventNotifierWithPostgreSQL(t *testing.T) {
t.Fatalf("Init Test config failed")
}
// remove the root directory after the test ends.
defer removeAll(rootPath)
defer os.RemoveAll(rootPath)
disks, err := getRandomDisks(1)
defer removeAll(disks[0])
defer os.RemoveAll(disks[0])
if err != nil {
t.Fatal("Unable to create directories for FS backend. ", err)
}
@ -112,10 +113,10 @@ func TestInitEventNotifierWithNATS(t *testing.T) {
t.Fatalf("Init Test config failed")
}
// remove the root directory after the test ends.
defer removeAll(rootPath)
defer os.RemoveAll(rootPath)
disks, err := getRandomDisks(1)
defer removeAll(disks[0])
defer os.RemoveAll(disks[0])
if err != nil {
t.Fatal("Unable to create directories for FS backend. ", err)
}
@ -139,10 +140,10 @@ func TestInitEventNotifierWithWebHook(t *testing.T) {
t.Fatalf("Init Test config failed")
}
// remove the root directory after the test ends.
defer removeAll(rootPath)
defer os.RemoveAll(rootPath)
disks, err := getRandomDisks(1)
defer removeAll(disks[0])
defer os.RemoveAll(disks[0])
if err != nil {
t.Fatal("Unable to create directories for FS backend. ", err)
}
@ -166,10 +167,10 @@ func TestInitEventNotifierWithAMQP(t *testing.T) {
t.Fatalf("Init Test config failed")
}
// remove the root directory after the test ends.
defer removeAll(rootPath)
defer os.RemoveAll(rootPath)
disks, err := getRandomDisks(1)
defer removeAll(disks[0])
defer os.RemoveAll(disks[0])
if err != nil {
t.Fatal("Unable to create directories for FS backend. ", err)
}
@ -193,10 +194,10 @@ func TestInitEventNotifierWithElasticSearch(t *testing.T) {
t.Fatalf("Init Test config failed")
}
// remove the root directory after the test ends.
defer removeAll(rootPath)
defer os.RemoveAll(rootPath)
disks, err := getRandomDisks(1)
defer removeAll(disks[0])
defer os.RemoveAll(disks[0])
if err != nil {
t.Fatal("Unable to create directories for FS backend. ", err)
}
@ -220,10 +221,10 @@ func TestInitEventNotifierWithRedis(t *testing.T) {
t.Fatalf("Init Test config failed")
}
// remove the root directory after the test ends.
defer removeAll(rootPath)
defer os.RemoveAll(rootPath)
disks, err := getRandomDisks(1)
defer removeAll(disks[0])
defer os.RemoveAll(disks[0])
if err != nil {
t.Fatal("Unable to create directories for FS backend. ", err)
}
@ -258,9 +259,9 @@ func (s *TestPeerRPCServerData) Setup(t *testing.T) {
func (s *TestPeerRPCServerData) TearDown() {
s.testServer.Stop()
_ = removeAll(s.testServer.Root)
_ = os.RemoveAll(s.testServer.Root)
for _, d := range s.testServer.Disks {
_ = removeAll(d.Path)
_ = os.RemoveAll(d.Path)
}
}

View File

@ -663,7 +663,7 @@ func TestGenericFormatCheckXL(t *testing.T) {
func TestFSCheckFormatFSErr(t *testing.T) {
// Prepare for testing
disk := filepath.Join(globalTestTmpDir, "minio-"+nextSuffix())
defer removeAll(disk)
defer os.RemoveAll(disk)
// Assign a new UUID.
uuid := mustGetUUID()
@ -725,7 +725,7 @@ func TestFSCheckFormatFSErr(t *testing.T) {
fsFormatPath := pathJoin(disk, minioMetaBucket, formatConfigFile)
for i, testCase := range testCases {
lk, err := lock.LockedOpenFile(preparePath(fsFormatPath), os.O_RDWR|os.O_CREATE, 0600)
lk, err := lock.LockedOpenFile((fsFormatPath), os.O_RDWR|os.O_CREATE, 0600)
if err != nil {
t.Fatal(err)
}
@ -735,7 +735,7 @@ func TestFSCheckFormatFSErr(t *testing.T) {
t.Fatalf("Test %d: Expected nil, got %s", i+1, err)
}
lk, err = lock.LockedOpenFile(preparePath(fsFormatPath), os.O_RDWR|os.O_CREATE, 0600)
lk, err = lock.LockedOpenFile((fsFormatPath), os.O_RDWR|os.O_CREATE, 0600)
if err != nil {
t.Fatal(err)
}
@ -765,7 +765,7 @@ func TestFSCheckFormatFSErr(t *testing.T) {
func TestFSCheckFormatFS(t *testing.T) {
// Prepare for testing
disk := filepath.Join(globalTestTmpDir, "minio-"+nextSuffix())
defer removeAll(disk)
defer os.RemoveAll(disk)
// Assign a new UUID.
uuid := mustGetUUID()
@ -776,7 +776,7 @@ func TestFSCheckFormatFS(t *testing.T) {
}
fsFormatPath := pathJoin(disk, minioMetaBucket, formatConfigFile)
lk, err := lock.LockedOpenFile(preparePath(fsFormatPath), os.O_RDWR|os.O_CREATE, 0600)
lk, err := lock.LockedOpenFile((fsFormatPath), os.O_RDWR|os.O_CREATE, 0600)
if err != nil {
t.Fatal(err)
}
@ -789,14 +789,14 @@ func TestFSCheckFormatFS(t *testing.T) {
}
// Loading corrupted format file
file, err := os.OpenFile(preparePath(fsFormatPath), os.O_APPEND|os.O_WRONLY|os.O_CREATE, 0666)
file, err := os.OpenFile((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)
lk, err = lock.LockedOpenFile((fsFormatPath), os.O_RDWR|os.O_CREATE, 0600)
if err != nil {
t.Fatal(err)
}
@ -809,8 +809,8 @@ func TestFSCheckFormatFS(t *testing.T) {
}
// Loading format file from disk not found.
removeAll(disk)
_, err = lock.LockedOpenFile(preparePath(fsFormatPath), os.O_RDONLY, 0600)
os.RemoveAll(disk)
_, err = lock.LockedOpenFile((fsFormatPath), os.O_RDONLY, 0600)
if err != nil && !os.IsNotExist(err) {
t.Fatal("Should return 'format.json' does not exist, but got", err)
}
@ -918,7 +918,7 @@ func TestHealFormatXLCorruptedDisksErrs(t *testing.T) {
if err != nil {
t.Fatal(err)
}
defer removeAll(root)
defer os.RemoveAll(root)
nDisks := 16
fsDirs, err := getRandomDisks(nDisks)
@ -991,7 +991,7 @@ func TestHealFormatXLFreshDisksErrs(t *testing.T) {
if err != nil {
t.Fatal(err)
}
defer removeAll(root)
defer os.RemoveAll(root)
nDisks := 16
fsDirs, err := getRandomDisks(nDisks)

View File

@ -224,7 +224,7 @@ func (fs fsObjects) appendPart(bucket, object, uploadID string, part objectPartI
tmpObjPath := pathJoin(fs.fsPath, minioMetaTmpBucket, fs.fsUUID, uploadID)
// No need to hold a lock, this is a unique file and will be only written
// to one one process per uploadID per minio process.
wfile, err := os.OpenFile(preparePath(tmpObjPath), os.O_CREATE|os.O_APPEND|os.O_WRONLY, 0666)
wfile, err := os.OpenFile((tmpObjPath), os.O_CREATE|os.O_APPEND|os.O_WRONLY, 0666)
if err != nil {
return err
}

View File

@ -35,7 +35,7 @@ func fsRemoveFile(filePath string) (err error) {
return traceError(err)
}
if err = os.Remove(preparePath(filePath)); err != nil {
if err = os.Remove((filePath)); err != nil {
if os.IsNotExist(err) {
return traceError(errFileNotFound)
} else if os.IsPermission(err) {
@ -58,7 +58,7 @@ func fsRemoveAll(dirPath string) (err error) {
return traceError(err)
}
if err = removeAll(dirPath); err != nil {
if err = os.RemoveAll(dirPath); err != nil {
if os.IsPermission(err) {
return traceError(errVolumeAccessDenied)
} else if isSysErrNotEmpty(err) {
@ -81,7 +81,7 @@ func fsRemoveDir(dirPath string) (err error) {
return traceError(err)
}
if err = os.Remove(preparePath(dirPath)); err != nil {
if err = os.Remove((dirPath)); err != nil {
if os.IsNotExist(err) {
return traceError(errVolumeNotFound)
} else if isSysErrNotEmpty(err) {
@ -106,7 +106,7 @@ func fsMkdir(dirPath string) (err error) {
return traceError(err)
}
if err = os.Mkdir(preparePath(dirPath), 0777); err != nil {
if err = os.Mkdir((dirPath), 0777); err != nil {
if os.IsExist(err) {
return traceError(errVolumeExists)
} else if os.IsPermission(err) {
@ -132,7 +132,7 @@ func fsStat(statLoc string) (os.FileInfo, error) {
if err := checkPathLength(statLoc); err != nil {
return nil, traceError(err)
}
fi, err := osStat(preparePath(statLoc))
fi, err := osStat((statLoc))
if err != nil {
return nil, traceError(err)
}
@ -193,7 +193,7 @@ func fsOpenFile(readPath string, offset int64) (io.ReadCloser, int64, error) {
return nil, 0, traceError(err)
}
fr, err := os.Open(preparePath(readPath))
fr, err := os.Open((readPath))
if err != nil {
if os.IsNotExist(err) {
return nil, 0, traceError(errFileNotFound)
@ -210,7 +210,7 @@ func fsOpenFile(readPath string, offset int64) (io.ReadCloser, int64, error) {
}
// Stat to get the size of the file at path.
st, err := osStat(preparePath(readPath))
st, err := osStat((readPath))
if err != nil {
return nil, 0, traceError(err)
}
@ -242,7 +242,7 @@ func fsCreateFile(filePath string, reader io.Reader, buf []byte, fallocSize int6
return 0, traceError(err)
}
if err := mkdirAll(pathutil.Dir(filePath), 0777); err != nil {
if err := os.MkdirAll(pathutil.Dir(filePath), 0777); err != nil {
return 0, traceError(err)
}
@ -250,7 +250,7 @@ func fsCreateFile(filePath string, reader io.Reader, buf []byte, fallocSize int6
return 0, traceError(err)
}
writer, err := os.OpenFile(preparePath(filePath), os.O_CREATE|os.O_WRONLY, 0666)
writer, err := os.OpenFile((filePath), os.O_CREATE|os.O_WRONLY, 0666)
if err != nil {
// File path cannot be verified since one of the parents is a file.
if isSysErrNotDir(err) {
@ -343,7 +343,7 @@ func fsRenameFile(sourcePath, destPath string) error {
return traceError(err)
}
// Verify if source path exists.
if _, err := os.Stat(preparePath(sourcePath)); err != nil {
if _, err := os.Stat((sourcePath)); err != nil {
if os.IsNotExist(err) {
return traceError(errFileNotFound)
} else if os.IsPermission(err) {
@ -356,10 +356,10 @@ func fsRenameFile(sourcePath, destPath string) error {
}
return traceError(err)
}
if err := mkdirAll(pathutil.Dir(destPath), 0777); err != nil {
if err := os.MkdirAll(pathutil.Dir(destPath), 0777); err != nil {
return traceError(err)
}
if err := os.Rename(preparePath(sourcePath), preparePath(destPath)); err != nil {
if err := os.Rename((sourcePath), (destPath)); err != nil {
return traceError(err)
}
return nil

View File

@ -33,7 +33,7 @@ func TestFSRenameFile(t *testing.T) {
if err != nil {
t.Fatalf("Unable to create posix test setup, %s", err)
}
defer removeAll(path)
defer os.RemoveAll(path)
if err = fsMkdir(pathJoin(path, "testvolume1")); err != nil {
t.Fatal(err)
@ -58,7 +58,7 @@ func TestFSStats(t *testing.T) {
if err != nil {
t.Fatalf("Unable to create posix test setup, %s", err)
}
defer removeAll(path)
defer os.RemoveAll(path)
// Setup test environment.
@ -186,7 +186,7 @@ func TestFSCreateAndOpen(t *testing.T) {
if err != nil {
t.Fatalf("Unable to create posix test setup, %s", err)
}
defer removeAll(path)
defer os.RemoveAll(path)
if err = fsMkdir(pathJoin(path, "success-vol")); err != nil {
t.Fatalf("Unable to create directory, %s", err)
@ -251,7 +251,7 @@ func TestFSDeletes(t *testing.T) {
if err != nil {
t.Fatalf("Unable to create posix test setup, %s", err)
}
defer removeAll(path)
defer os.RemoveAll(path)
// Setup test environment.
if err = fsMkdir(pathJoin(path, "success-vol")); err != nil {
@ -354,7 +354,7 @@ func BenchmarkFSDeleteFile(b *testing.B) {
if err != nil {
b.Fatalf("Unable to create posix test setup, %s", err)
}
defer removeAll(path)
defer os.RemoveAll(path)
// Setup test environment.
if err = fsMkdir(pathJoin(path, "benchmark")); err != nil {
@ -388,7 +388,7 @@ func TestFSRemoves(t *testing.T) {
if err != nil {
t.Fatalf("Unable to create posix test setup, %s", err)
}
defer removeAll(path)
defer os.RemoveAll(path)
// Setup test environment.
if err = fsMkdir(pathJoin(path, "success-vol")); err != nil {
@ -505,7 +505,7 @@ func TestFSRemoveMeta(t *testing.T) {
if err != nil {
t.Fatalf("Unable to create posix test setup, %s", err)
}
defer removeAll(fsPath)
defer os.RemoveAll(fsPath)
// Setup test environment.
if err = fsMkdir(pathJoin(fsPath, "success-vol")); err != nil {
@ -538,11 +538,11 @@ func TestFSRemoveMeta(t *testing.T) {
t.Fatalf("Unable to remove file, %s", err)
}
if _, err := osStat(preparePath(filePath)); !os.IsNotExist(err) {
if _, err := osStat((filePath)); !os.IsNotExist(err) {
t.Fatalf("`%s` file found though it should have been deleted.", filePath)
}
if _, err := osStat(preparePath(path.Dir(filePath))); !os.IsNotExist(err) {
if _, err := osStat((path.Dir(filePath))); !os.IsNotExist(err) {
t.Fatalf("`%s` parent directory found though it should have been deleted.", filePath)
}
}

View File

@ -264,7 +264,7 @@ func newFSMetaV1() (fsMeta fsMetaV1) {
func checkLockedValidFormatFS(fsPath string) (*lock.RLockedFile, error) {
fsFormatPath := pathJoin(fsPath, minioMetaBucket, formatConfigFile)
rlk, err := lock.RLockedOpenFile(preparePath(fsFormatPath))
rlk, err := lock.RLockedOpenFile((fsFormatPath))
if err != nil {
if os.IsNotExist(err) {
// If format.json not found then
@ -296,7 +296,7 @@ func createFormatFS(fsPath string) error {
// Attempt a write lock on formatConfigFile `format.json`
// file stored in minioMetaBucket(.minio.sys) directory.
lk, err := lock.TryLockedOpenFile(preparePath(fsFormatPath), os.O_RDWR|os.O_CREATE, 0600)
lk, err := lock.TryLockedOpenFile((fsFormatPath), os.O_RDWR|os.O_CREATE, 0600)
if err != nil {
return traceError(err)
}

View File

@ -18,6 +18,7 @@ package cmd
import (
"bytes"
"os"
"path/filepath"
"testing"
)
@ -40,7 +41,7 @@ func TestFSV1MetadataObjInfo(t *testing.T) {
// TestReadFSMetadata - readFSMetadata testing with a healthy and faulty disk
func TestReadFSMetadata(t *testing.T) {
disk := filepath.Join(globalTestTmpDir, "minio-"+nextSuffix())
defer removeAll(disk)
defer os.RemoveAll(disk)
obj := initFSObjects(disk, t)
fs := obj.(*fsObjects)
@ -77,7 +78,7 @@ func TestReadFSMetadata(t *testing.T) {
// TestWriteFSMetadata - tests of writeFSMetadata with healthy disk.
func TestWriteFSMetadata(t *testing.T) {
disk := filepath.Join(globalTestTmpDir, "minio-"+nextSuffix())
defer removeAll(disk)
defer os.RemoveAll(disk)
obj := initFSObjects(disk, t)
fs := obj.(*fsObjects)

View File

@ -801,7 +801,7 @@ func (fs fsObjects) CompleteMultipartUpload(bucket string, object string, upload
// No need to hold a lock, this is a unique file and will be only written
// to one one process per uploadID per minio process.
var wfile *os.File
wfile, err = os.OpenFile(preparePath(fsTmpObjPath), os.O_CREATE|os.O_APPEND|os.O_WRONLY, 0666)
wfile, err = os.OpenFile((fsTmpObjPath), os.O_CREATE|os.O_APPEND|os.O_WRONLY, 0666)
if err != nil {
reader.Close()
fs.rwPool.Close(fsMetaPathMultipart)

View File

@ -18,6 +18,7 @@ package cmd
import (
"bytes"
"os"
"path/filepath"
"testing"
"time"
@ -26,7 +27,7 @@ import (
func TestFSCleanupMultipartUploadsInRoutine(t *testing.T) {
// Prepare for tests
disk := filepath.Join(globalTestTmpDir, "minio-"+nextSuffix())
defer removeAll(disk)
defer os.RemoveAll(disk)
obj := initFSObjects(disk, t)
fs := obj.(*fsObjects)
@ -66,7 +67,7 @@ func TestFSCleanupMultipartUploadsInRoutine(t *testing.T) {
func TestFSCleanupMultipartUpload(t *testing.T) {
// Prepare for tests
disk := filepath.Join(globalTestTmpDir, "minio-"+nextSuffix())
defer removeAll(disk)
defer os.RemoveAll(disk)
obj := initFSObjects(disk, t)
fs := obj.(*fsObjects)
@ -103,7 +104,7 @@ func TestFSCleanupMultipartUpload(t *testing.T) {
func TestFSWriteUploadJSON(t *testing.T) {
// Prepare for tests
disk := filepath.Join(globalTestTmpDir, "minio-"+nextSuffix())
defer removeAll(disk)
defer os.RemoveAll(disk)
obj := initFSObjects(disk, t)
fs := obj.(*fsObjects)
@ -131,7 +132,7 @@ func TestFSWriteUploadJSON(t *testing.T) {
func TestNewMultipartUploadFaultyDisk(t *testing.T) {
// Prepare for tests
disk := filepath.Join(globalTestTmpDir, "minio-"+nextSuffix())
defer removeAll(disk)
defer os.RemoveAll(disk)
obj := initFSObjects(disk, t)
fs := obj.(*fsObjects)
@ -157,11 +158,11 @@ func TestPutObjectPartFaultyDisk(t *testing.T) {
if err != nil {
t.Fatal(err)
}
defer removeAll(root)
defer os.RemoveAll(root)
// Prepare for tests
disk := filepath.Join(globalTestTmpDir, "minio-"+nextSuffix())
defer removeAll(disk)
defer os.RemoveAll(disk)
obj := initFSObjects(disk, t)
fs := obj.(*fsObjects)
bucketName := "bucket"
@ -192,7 +193,7 @@ func TestPutObjectPartFaultyDisk(t *testing.T) {
func TestCompleteMultipartUploadFaultyDisk(t *testing.T) {
// Prepare for tests
disk := filepath.Join(globalTestTmpDir, "minio-"+nextSuffix())
defer removeAll(disk)
defer os.RemoveAll(disk)
obj := initFSObjects(disk, t)
fs := obj.(*fsObjects)
@ -230,7 +231,7 @@ func TestCompleteMultipartUploadFaultyDisk(t *testing.T) {
func TestListMultipartUploadsFaultyDisk(t *testing.T) {
// Prepare for tests
disk := filepath.Join(globalTestTmpDir, "minio-"+nextSuffix())
defer removeAll(disk)
defer os.RemoveAll(disk)
obj := initFSObjects(disk, t)

View File

@ -77,7 +77,7 @@ func (fsi *fsIOPool) Open(path string) (*lock.RLockedFile, error) {
var err error
var newRlkFile *lock.RLockedFile
// Open file for reading.
newRlkFile, err = lock.RLockedOpenFile(preparePath(path))
newRlkFile, err = lock.RLockedOpenFile(path)
if err != nil {
if os.IsNotExist(err) {
return nil, errFileNotFound
@ -137,7 +137,7 @@ func (fsi *fsIOPool) Write(path string) (wlk *lock.LockedFile, err error) {
return nil, err
}
wlk, err = lock.LockedOpenFile(preparePath(path), os.O_RDWR, 0666)
wlk, err = lock.LockedOpenFile(path, os.O_RDWR, 0666)
if err != nil {
if os.IsNotExist(err) {
return nil, errFileNotFound
@ -159,7 +159,7 @@ func (fsi *fsIOPool) Create(path string) (wlk *lock.LockedFile, err error) {
}
// Creates parent if missing.
if err = mkdirAll(pathutil.Dir(path), 0777); err != nil {
if err = os.MkdirAll(pathutil.Dir(path), 0777); err != nil {
if os.IsPermission(err) {
return nil, errFileAccessDenied
} else if isSysErrNotDir(err) {
@ -169,7 +169,7 @@ func (fsi *fsIOPool) Create(path string) (wlk *lock.LockedFile, err error) {
}
// Attempt to create the file.
wlk, err = lock.LockedOpenFile(preparePath(path), os.O_RDWR|os.O_CREATE, 0666)
wlk, err = lock.LockedOpenFile(path, os.O_RDWR|os.O_CREATE, 0666)
if err != nil {
if os.IsPermission(err) {
return nil, errFileAccessDenied

View File

@ -17,6 +17,7 @@
package cmd
import (
"os"
"runtime"
"testing"
@ -50,7 +51,7 @@ func TestRWPool(t *testing.T) {
if err != nil {
t.Fatalf("Unable to create posix test setup, %s", err)
}
defer removeAll(path)
defer os.RemoveAll(path)
rwPool := &fsIOPool{
readersMap: make(map[string]*lock.RLockedFile),

View File

@ -62,17 +62,17 @@ func initMetaVolumeFS(fsPath, fsUUID string) error {
// optimizing all other calls. Create minio meta volume,
// if it doesn't exist yet.
metaBucketPath := pathJoin(fsPath, minioMetaBucket)
if err := mkdirAll(metaBucketPath, 0777); err != nil {
if err := os.MkdirAll(metaBucketPath, 0777); err != nil {
return err
}
metaTmpPath := pathJoin(fsPath, minioMetaTmpBucket, fsUUID)
if err := mkdirAll(metaTmpPath, 0777); err != nil {
if err := os.MkdirAll(metaTmpPath, 0777); err != nil {
return err
}
metaMultipartPath := pathJoin(fsPath, minioMetaMultipartBucket)
return mkdirAll(metaMultipartPath, 0777)
return os.MkdirAll(metaMultipartPath, 0777)
}
@ -89,7 +89,7 @@ func newFSObjectLayer(fsPath string) (ObjectLayer, error) {
return nil, err
}
fi, err := osStat(preparePath(fsPath))
fi, err := osStat((fsPath))
if err == nil {
if !fi.IsDir() {
return nil, syscall.ENOTDIR
@ -97,13 +97,13 @@ func newFSObjectLayer(fsPath string) (ObjectLayer, error) {
}
if os.IsNotExist(err) {
// Disk not found create it.
err = mkdirAll(fsPath, 0777)
err = os.MkdirAll(fsPath, 0777)
if err != nil {
return nil, err
}
}
di, err := getDiskInfo(preparePath(fsPath))
di, err := getDiskInfo((fsPath))
if err != nil {
return nil, err
}
@ -174,7 +174,7 @@ func (fs fsObjects) Shutdown() error {
// StorageInfo - returns underlying storage statistics.
func (fs fsObjects) StorageInfo() StorageInfo {
info, err := getDiskInfo(preparePath(fs.fsPath))
info, err := getDiskInfo((fs.fsPath))
errorIf(err, "Unable to get disk info %#v", fs.fsPath)
storageInfo := StorageInfo{
Total: info.Total,
@ -247,7 +247,7 @@ func (fs fsObjects) ListBuckets() ([]BucketInfo, error) {
return nil, traceError(err)
}
var bucketInfos []BucketInfo
entries, err := readDir(preparePath(fs.fsPath))
entries, err := readDir((fs.fsPath))
if err != nil {
return nil, toObjectErr(traceError(errDiskNotFound))
}

View File

@ -31,7 +31,7 @@ func TestNewFS(t *testing.T) {
// so that newFSObjectLayer initializes non existing paths
// and successfully returns initialized object layer.
disk := filepath.Join(globalTestTmpDir, "minio-"+nextSuffix())
defer removeAll(disk)
defer os.RemoveAll(disk)
_, err := newFSObjectLayer("")
if err != errInvalidArgument {
@ -53,7 +53,7 @@ func TestFSShutdown(t *testing.T) {
if err != nil {
t.Fatal(err)
}
defer removeAll(rootPath)
defer os.RemoveAll(rootPath)
bucketName := "testbucket"
objectName := "object"
@ -74,12 +74,12 @@ func TestFSShutdown(t *testing.T) {
if err := fs.Shutdown(); err != nil {
t.Fatal("Cannot shutdown the FS object: ", err)
}
removeAll(disk)
os.RemoveAll(disk)
// Test Shutdown with faulty disk
fs, disk = prepareTest()
fs.DeleteObject(bucketName, objectName)
removeAll(disk)
os.RemoveAll(disk)
if err := fs.Shutdown(); err != nil {
t.Fatal("Got unexpected fs shutdown error: ", err)
}
@ -89,7 +89,7 @@ func TestFSShutdown(t *testing.T) {
func TestFSGetBucketInfo(t *testing.T) {
// Prepare for testing
disk := filepath.Join(globalTestTmpDir, "minio-"+nextSuffix())
defer removeAll(disk)
defer os.RemoveAll(disk)
obj := initFSObjects(disk, t)
fs := obj.(*fsObjects)
@ -124,7 +124,7 @@ func TestFSGetBucketInfo(t *testing.T) {
func TestFSPutObject(t *testing.T) {
// Prepare for tests
disk := filepath.Join(globalTestTmpDir, "minio-"+nextSuffix())
defer removeAll(disk)
defer os.RemoveAll(disk)
obj := initFSObjects(disk, t)
bucketName := "bucket"
@ -193,7 +193,7 @@ func TestFSPutObject(t *testing.T) {
func TestFSDeleteObject(t *testing.T) {
// Prepare for tests
disk := filepath.Join(globalTestTmpDir, "minio-"+nextSuffix())
defer removeAll(disk)
defer os.RemoveAll(disk)
obj := initFSObjects(disk, t)
fs := obj.(*fsObjects)
@ -239,7 +239,7 @@ func TestFSDeleteObject(t *testing.T) {
func TestFSDeleteBucket(t *testing.T) {
// Prepare for testing
disk := filepath.Join(globalTestTmpDir, "minio-"+nextSuffix())
defer removeAll(disk)
defer os.RemoveAll(disk)
obj := initFSObjects(disk, t)
fs := obj.(*fsObjects)
@ -278,7 +278,7 @@ func TestFSDeleteBucket(t *testing.T) {
func TestFSListBuckets(t *testing.T) {
// Prepare for tests
disk := filepath.Join(globalTestTmpDir, "minio-"+nextSuffix())
defer removeAll(disk)
defer os.RemoveAll(disk)
obj := initFSObjects(disk, t)
fs := obj.(*fsObjects)
@ -289,7 +289,7 @@ func TestFSListBuckets(t *testing.T) {
}
// Create a bucket with invalid name
if err := mkdirAll(pathJoin(fs.fsPath, "vo^"), 0777); err != nil {
if err := os.MkdirAll(pathJoin(fs.fsPath, "vo^"), 0777); err != nil {
t.Fatal("Unexpected error: ", err)
}
f, err := os.Create(pathJoin(fs.fsPath, "test"))
@ -328,7 +328,7 @@ func TestFSListBuckets(t *testing.T) {
// TestFSHealObject - tests for fs HealObject
func TestFSHealObject(t *testing.T) {
disk := filepath.Join(globalTestTmpDir, "minio-"+nextSuffix())
defer removeAll(disk)
defer os.RemoveAll(disk)
obj := initFSObjects(disk, t)
_, _, err := obj.HealObject("bucket", "object")
@ -340,7 +340,7 @@ func TestFSHealObject(t *testing.T) {
// TestFSListObjectHeal - tests for fs ListObjectHeals
func TestFSListObjectsHeal(t *testing.T) {
disk := filepath.Join(globalTestTmpDir, "minio-"+nextSuffix())
defer removeAll(disk)
defer os.RemoveAll(disk)
obj := initFSObjects(disk, t)
_, err := obj.ListObjectsHeal("bucket", "prefix", "marker", "delimiter", 1000)

View File

@ -16,7 +16,10 @@
package cmd
import "testing"
import (
"os"
"testing"
)
// Test printing Gateway common message.
func TestPrintGatewayCommonMessage(t *testing.T) {
@ -24,7 +27,7 @@ func TestPrintGatewayCommonMessage(t *testing.T) {
if err != nil {
t.Fatal(err)
}
defer removeAll(root)
defer os.RemoveAll(root)
apiEndpoints := []string{"http://127.0.0.1:9000"}
printGatewayCommonMsg(apiEndpoints)
@ -36,7 +39,7 @@ func TestPrintGatewayStartupMessage(t *testing.T) {
if err != nil {
t.Fatal(err)
}
defer removeAll(root)
defer os.RemoveAll(root)
apiEndpoints := []string{"http://127.0.0.1:9000"}
printGatewayStartupMessage(apiEndpoints, "azure")

View File

@ -21,6 +21,7 @@ import (
"encoding/xml"
"io/ioutil"
"net/http"
"os"
"reflect"
"strings"
"testing"
@ -32,7 +33,7 @@ func TestIsValidLocationContraint(t *testing.T) {
if err != nil {
t.Fatalf("unable initialize config file, %s", err)
}
defer removeAll(path)
defer os.RemoveAll(path)
// Test with corrupted XML
malformedReq := &http.Request{

View File

@ -16,14 +16,17 @@
package cmd
import "testing"
import (
"os"
"testing"
)
func testAuthenticate(authType string, t *testing.T) {
testPath, err := newTestConfig(globalMinioDefaultRegion)
if err != nil {
t.Fatalf("unable initialize config file, %s", err)
}
defer removeAll(testPath)
defer os.RemoveAll(testPath)
// Create access and secret keys in length, 300 and 600
cred, err := getNewCredential(300, 600)
if err != nil {
@ -90,7 +93,7 @@ func BenchmarkAuthenticateNode(b *testing.B) {
if err != nil {
b.Fatalf("unable initialize config file, %s", err)
}
defer removeAll(testPath)
defer os.RemoveAll(testPath)
creds := serverConfig.GetCredential()
b.ResetTimer()
@ -105,7 +108,7 @@ func BenchmarkAuthenticateWeb(b *testing.B) {
if err != nil {
b.Fatalf("unable initialize config file, %s", err)
}
defer removeAll(testPath)
defer os.RemoveAll(testPath)
creds := serverConfig.GetCredential()
b.ResetTimer()

View File

@ -17,6 +17,7 @@
package cmd
import (
"os"
"reflect"
"testing"
"time"
@ -25,7 +26,7 @@ import (
// Test function to remove lock entries from map only in case they still exist based on name & uid combination
func TestLockRpcServerRemoveEntryIfExists(t *testing.T) {
testPath, locker, _ := createLockTestServer(t)
defer removeAll(testPath)
defer os.RemoveAll(testPath)
lri := lockRequesterInfo{
writer: false,
@ -62,7 +63,7 @@ func TestLockRpcServerRemoveEntryIfExists(t *testing.T) {
// Test function to remove lock entries from map based on name & uid combination
func TestLockRpcServerRemoveEntry(t *testing.T) {
testPath, locker, _ := createLockTestServer(t)
defer removeAll(testPath)
defer os.RemoveAll(testPath)
lockRequesterInfo1 := lockRequesterInfo{
writer: true,

View File

@ -17,6 +17,7 @@
package cmd
import (
"os"
"runtime"
"sync"
"testing"
@ -76,7 +77,7 @@ func createLockTestServer(t *testing.T) (string, *lockServer, string) {
// Test Lock functionality
func TestLockRpcServerLock(t *testing.T) {
testPath, locker, token := createLockTestServer(t)
defer removeAll(testPath)
defer os.RemoveAll(testPath)
la := newLockArgs(dsync.LockArgs{
UID: "0123-4567",
@ -132,7 +133,7 @@ func TestLockRpcServerLock(t *testing.T) {
// Test Unlock functionality
func TestLockRpcServerUnlock(t *testing.T) {
testPath, locker, token := createLockTestServer(t)
defer removeAll(testPath)
defer os.RemoveAll(testPath)
la := newLockArgs(dsync.LockArgs{
UID: "0123-4567",
@ -177,7 +178,7 @@ func TestLockRpcServerUnlock(t *testing.T) {
// Test RLock functionality
func TestLockRpcServerRLock(t *testing.T) {
testPath, locker, token := createLockTestServer(t)
defer removeAll(testPath)
defer os.RemoveAll(testPath)
la := newLockArgs(dsync.LockArgs{
UID: "0123-4567",
@ -233,7 +234,7 @@ func TestLockRpcServerRLock(t *testing.T) {
// Test RUnlock functionality
func TestLockRpcServerRUnlock(t *testing.T) {
testPath, locker, token := createLockTestServer(t)
defer removeAll(testPath)
defer os.RemoveAll(testPath)
la := newLockArgs(dsync.LockArgs{
UID: "0123-4567",
@ -319,7 +320,7 @@ func TestLockRpcServerRUnlock(t *testing.T) {
// Test ForceUnlock functionality
func TestLockRpcServerForceUnlock(t *testing.T) {
testPath, locker, token := createLockTestServer(t)
defer removeAll(testPath)
defer os.RemoveAll(testPath)
laForce := newLockArgs(dsync.LockArgs{
UID: "1234-5678",
@ -383,7 +384,7 @@ func TestLockRpcServerForceUnlock(t *testing.T) {
// Test Expired functionality
func TestLockRpcServerExpired(t *testing.T) {
testPath, locker, token := createLockTestServer(t)
defer removeAll(testPath)
defer os.RemoveAll(testPath)
la := newLockArgs(dsync.LockArgs{
UID: "0123-4567",
@ -433,7 +434,7 @@ func TestLockServers(t *testing.T) {
if err != nil {
t.Fatalf("Init Test config failed")
}
defer removeAll(rootPath)
defer os.RemoveAll(rootPath)
currentIsDistXL := globalIsDistXL
defer func() {

View File

@ -22,6 +22,7 @@ import (
"io"
"net/http"
"net/http/httptest"
"os"
"path"
"testing"
@ -51,7 +52,7 @@ func TestNewWebHookNotify(t *testing.T) {
if err != nil {
t.Fatal(err)
}
defer removeAll(root)
defer os.RemoveAll(root)
_, err = newWebhookNotify("1")
if err == nil {

View File

@ -342,7 +342,7 @@ func testGetObjectDiskNotFound(obj ObjectLayer, instanceType string, disks []str
// Take 8 disks down before GetObject is called, one more we loose quorum on 16 disk node.
for _, disk := range disks[:8] {
removeAll(disk)
os.RemoveAll(disk)
}
// set of empty buffers used to fill GetObject data.

View File

@ -20,6 +20,7 @@ import (
"bytes"
"fmt"
"io/ioutil"
"os"
"strconv"
"strings"
"testing"
@ -586,14 +587,14 @@ func BenchmarkListObjects(b *testing.B) {
if err != nil {
b.Fatal(err)
}
defer removeAll(directory)
defer os.RemoveAll(directory)
// initialize the root directory.
rootPath, err := newTestConfig(globalMinioDefaultRegion)
if err != nil {
b.Fatalf("Unable to initialize config. %s", err)
}
defer removeAll(rootPath)
defer os.RemoveAll(rootPath)
// Create the obj.
obj := initFSObjectsB(directory, b)

View File

@ -19,6 +19,7 @@ package cmd
import (
"bytes"
"fmt"
"os"
"strings"
"testing"
@ -188,7 +189,7 @@ func testPutObjectPartDiskNotFound(obj ObjectLayer, instanceType string, disks [
// Remove some random disk.
for _, disk := range disks[:6] {
removeAll(disk)
os.RemoveAll(disk)
}
uploadIDs = append(uploadIDs, uploadID)
@ -226,7 +227,7 @@ func testPutObjectPartDiskNotFound(obj ObjectLayer, instanceType string, disks [
// This causes quorum failure verify.
disks = disks[len(disks)-3:]
for _, disk := range disks {
removeAll(disk)
os.RemoveAll(disk)
}
// Object part upload should fail with quorum not available.

View File

@ -204,7 +204,7 @@ func testObjectAPIPutObjectDiskNotFound(obj ObjectLayer, instanceType string, di
// Take 8 disks down, one more we loose quorum on 16 disk node.
for _, disk := range disks[:7] {
removeAll(disk)
os.RemoveAll(disk)
}
testCases := []struct {
@ -253,7 +253,7 @@ func testObjectAPIPutObjectDiskNotFound(obj ObjectLayer, instanceType string, di
}
// This causes quorum failure verify.
removeAll(disks[len(disks)-1])
os.RemoveAll(disks[len(disks)-1])
// Validate the last test.
testCase := struct {

View File

@ -27,7 +27,7 @@ import (
// Return all the entries at the directory dirPath.
func readDir(dirPath string) (entries []string, err error) {
d, err := os.Open(preparePath(dirPath))
d, err := os.Open((dirPath))
if err != nil {
// File is really not found.
if os.IsNotExist(err) {
@ -55,7 +55,7 @@ func readDir(dirPath string) (entries []string, err error) {
// Stat symbolic link and follow to get the final value.
if fi.Mode()&os.ModeSymlink == os.ModeSymlink {
var st os.FileInfo
st, err = osStat(preparePath(path.Join(dirPath, fi.Name())))
st, err = osStat((path.Join(dirPath, fi.Name())))
if err != nil {
errorIf(err, "Unable to stat path %s", path.Join(dirPath, fi.Name()))
continue

View File

@ -1,56 +0,0 @@
/*
* Minio Cloud Storage, (C) 2016, 2017 Minio, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package cmd
import (
"path/filepath"
"runtime"
"strings"
)
// preparePath rewrites path to handle any OS specific details.
func preparePath(path string) string {
if runtime.GOOS == globalWindowsOSName {
// Microsoft Windows supports long path names using
// uniform naming convention (UNC).
return UNCPath(path)
}
return path
}
// UNCPath converts a absolute windows path to a UNC long path.
func UNCPath(path string) string {
// Clean the path for any trailing "/".
path = filepath.Clean(path)
// UNC can NOT use "/", so convert all to "\".
path = filepath.FromSlash(path)
// If prefix is "\\", we already have a UNC path or server.
if strings.HasPrefix(path, `\\`) {
// If already long path, just keep it
if strings.HasPrefix(path, `\\?\`) {
return path
}
// Trim "\\" from path and add UNC prefix.
return `\\?\UNC\` + strings.TrimPrefix(path, `\\`)
}
path = `\\?\` + path
return path
}

View File

@ -31,20 +31,3 @@ func osStat(name string) (os.FileInfo, error) {
func isValidVolname(volname string) bool {
return !(len(volname) < 3 || len(volname) > 63)
}
// mkdirAll creates a directory named path,
// along with any necessary parents, and returns nil,
// or else returns an error. The permission bits perm are used
// for all directories that mkdirAll creates. If path is already
// a directory, mkdirAll does nothing and returns nil.
func mkdirAll(path string, perm os.FileMode) error {
return os.MkdirAll(path, perm)
}
// removeAll removes path and any children it contains.
// It removes everything it can but returns the first error
// it encounters. If the path does not exist, RemoveAll
// returns nil (no error).
func removeAll(path string) error {
return os.RemoveAll(path)
}

View File

@ -20,6 +20,7 @@ package cmd
import (
"io/ioutil"
"os"
"path"
"syscall"
"testing"
@ -58,7 +59,7 @@ func TestIsValidUmaskVol(t *testing.T) {
if err = disk.MakeVol(testCase.volName); err != nil {
t.Fatalf("Creating a volume failed with %s expected to pass.", err)
}
defer removeAll(tmpPath)
defer os.RemoveAll(tmpPath)
// Stat to get permissions bits.
st, err := osStat(path.Join(tmpPath, testCase.volName))
@ -101,7 +102,7 @@ func TestIsValidUmaskFile(t *testing.T) {
t.Fatalf("Creating a volume failed with %s expected to pass.", err)
}
defer removeAll(tmpPath)
defer os.RemoveAll(tmpPath)
// Attempt to create a file to verify the permissions later.
// AppendFile creates file with 0666 perms.

View File

@ -19,11 +19,8 @@
package cmd
import (
"io"
"os"
"path/filepath"
"strings"
"syscall"
os2 "github.com/minio/minio/pkg/x/os"
)
@ -42,131 +39,3 @@ func isValidVolname(volname string) bool {
// Volname shouldn't have reserved characters on windows in it.
return !strings.ContainsAny(volname, `\:*?\"<>|`)
}
// mkdirAll creates a directory named path,
// along with any necessary parents, and returns nil,
// or else returns an error. The permission bits perm are used
// for all directories that mkdirAll creates. If path is already
// a directory, mkdirAll does nothing and returns nil.
func mkdirAll(path string, perm os.FileMode) error {
path = preparePath(path)
// Fast path: if we can tell whether path is a directory or file, stop with success or error.
dir, err := osStat(path)
if err == nil {
if dir.IsDir() {
return nil
}
return &os.PathError{
Op: "mkdir",
Path: path,
Err: syscall.ENOTDIR,
}
}
// Slow path: make sure parent exists and then call Mkdir for path.
i := len(path)
for i > 0 && os.IsPathSeparator(path[i-1]) { // Skip trailing path separator.
i--
}
j := i
for j > 0 && !os.IsPathSeparator(path[j-1]) { // Scan backward over element.
j--
}
if j > 1 {
// Create parent
parent := path[0 : j-1]
if parent != filepath.VolumeName(parent) {
err = mkdirAll(parent, perm)
if err != nil {
return err
}
}
}
// Parent now exists; invoke Mkdir and use its result.
err = os.Mkdir(path, perm)
if err != nil {
// Handle arguments like "foo/." by
// double-checking that directory doesn't exist.
dir, err1 := os.Lstat(path)
if err1 == nil && dir.IsDir() {
return nil
}
return err
}
return nil
}
// removeAll removes path and any children it contains.
// It removes everything it can but returns the first error
// it encounters. If the path does not exist, RemoveAll
// returns nil (no error).
func removeAll(path string) error {
path = preparePath(path)
// Simple case: if Remove works, we're done.
err := os.Remove(path)
if err == nil || os.IsNotExist(err) {
return nil
}
// Otherwise, is this a directory we need to recurse into?
dir, serr := os.Lstat(path)
if serr != nil {
if serr, ok := serr.(*os.PathError); ok && (os.IsNotExist(serr.Err) || serr.Err == syscall.ENOTDIR) {
return nil
}
return serr
}
if !dir.IsDir() {
// Not a directory; return the error from Remove.
return err
}
// Directory.
fd, err := os.Open(path)
if err != nil {
if os.IsNotExist(err) {
// Race. It was deleted between the Lstat and Open.
// Return nil per RemoveAll's docs.
return nil
}
return err
}
// Remove contents & return first error.
err = nil
for {
names, err1 := fd.Readdirnames(4096) // Get 4k entries.
for _, name := range names {
err1 = removeAll(path + string(os.PathSeparator) + name)
if err == nil {
err = err1
}
}
if err1 == io.EOF {
break
}
// If Readdirnames returned an error, use it.
if err == nil {
err = err1
}
if len(names) == 0 {
break
}
}
// Close directory, because windows won't remove opened directory.
fd.Close()
// Remove directory.
err1 := os.Remove(path)
if err1 == nil || os.IsNotExist(err1) {
return nil
}
if err == nil {
err = err1
}
return err
}

View File

@ -21,7 +21,6 @@ package cmd
import (
"bytes"
"os"
"strings"
"testing"
)
@ -105,32 +104,3 @@ func TestUNCPathENOTDIR(t *testing.T) {
t.Errorf("expected: %s, got: %s", errFileAccessDenied, err)
}
}
// Test to validate 32k path works on windows platform
func Test32kUNCPath(t *testing.T) {
var err error
// The following calculation was derived empirically. It is not exactly MAX_PATH - len(longDiskName)
// possibly due to expansion rules as mentioned here -
// https://msdn.microsoft.com/en-us/library/windows/desktop/aa365247(v=vs.85).aspx#maxpath
var longPathName string
for {
compt := strings.Repeat("a", 255)
if len(compt)+len(longPathName)+1 > 32767 {
break
}
longPathName = longPathName + `\` + compt
}
longPathName = "C:" + longPathName
err = mkdirAll(longPathName, 0777)
if err != nil {
t.Fatal(err)
}
// Cleanup on exit of test
defer removeAll(longPathName)
_, err = newPosix(longPathName)
if err != nil {
t.Fatal(err)
}
}

View File

@ -72,7 +72,7 @@ func checkPathLength(pathName string) error {
// isDirEmpty - returns whether given directory is empty or not.
func isDirEmpty(dirname string) bool {
f, err := os.Open(preparePath(dirname))
f, err := os.Open((dirname))
if err != nil {
if !os.IsNotExist(err) {
errorIf(err, "Unable to access directory")
@ -114,7 +114,7 @@ func newPosix(path string) (StorageAPI, error) {
},
},
}
fi, err := osStat(preparePath(diskPath))
fi, err := osStat((diskPath))
if err == nil {
if !fi.IsDir() {
return nil, syscall.ENOTDIR
@ -122,13 +122,13 @@ func newPosix(path string) (StorageAPI, error) {
}
if os.IsNotExist(err) {
// Disk not found create it.
err = mkdirAll(diskPath, 0777)
err = os.MkdirAll(diskPath, 0777)
if err != nil {
return nil, err
}
}
di, err := getDiskInfo(preparePath(diskPath))
di, err := getDiskInfo((diskPath))
if err != nil {
return nil, err
}
@ -197,7 +197,7 @@ func checkDiskFree(diskPath string, neededSpace int64) (err error) {
}
var di disk.Info
di, err = getDiskInfo(preparePath(diskPath))
di, err = getDiskInfo((diskPath))
if err != nil {
return err
}
@ -232,7 +232,7 @@ func (s *posix) Close() error {
// DiskInfo provides current information about disk space usage,
// total free inodes and underlying filesystem.
func (s *posix) DiskInfo() (info disk.Info, err error) {
return getDiskInfo(preparePath(s.diskPath))
return getDiskInfo((s.diskPath))
}
// getVolDir - will convert incoming volume names to
@ -250,7 +250,7 @@ func (s *posix) getVolDir(volume string) (string, error) {
// checkDiskFound - validates if disk is available,
// returns errDiskNotFound if not found.
func (s *posix) checkDiskFound() (err error) {
_, err = osStat(preparePath(s.diskPath))
_, err = osStat((s.diskPath))
if err != nil {
if os.IsNotExist(err) {
return errDiskNotFound
@ -282,7 +282,7 @@ func (s *posix) MakeVol(volume string) (err error) {
return err
}
// Make a volume entry, with mode 0777 mkdir honors system umask.
err = os.Mkdir(preparePath(volumeDir), 0777)
err = os.Mkdir((volumeDir), 0777)
if err != nil {
if os.IsExist(err) {
return errVolumeExists
@ -311,7 +311,7 @@ func (s *posix) ListVols() (volsInfo []VolInfo, err error) {
return nil, err
}
volsInfo, err = listVols(preparePath(s.diskPath))
volsInfo, err = listVols((s.diskPath))
if err != nil {
return nil, err
}
@ -341,7 +341,7 @@ func listVols(dirPath string) ([]VolInfo, error) {
continue
}
var fi os.FileInfo
fi, err = osStat(preparePath(pathJoin(dirPath, entry)))
fi, err = osStat((pathJoin(dirPath, entry)))
if err != nil {
// If the file does not exist, skip the entry.
if os.IsNotExist(err) {
@ -382,7 +382,7 @@ func (s *posix) StatVol(volume string) (volInfo VolInfo, err error) {
}
// Stat a volume entry.
var st os.FileInfo
st, err = osStat(preparePath(volumeDir))
st, err = osStat((volumeDir))
if err != nil {
if os.IsNotExist(err) {
return VolInfo{}, errVolumeNotFound
@ -419,7 +419,7 @@ func (s *posix) DeleteVol(volume string) (err error) {
if err != nil {
return err
}
err = os.Remove(preparePath(volumeDir))
err = os.Remove((volumeDir))
if err != nil {
if os.IsNotExist(err) {
return errVolumeNotFound
@ -454,7 +454,7 @@ func (s *posix) ListDir(volume, dirPath string) (entries []string, err error) {
return nil, err
}
// Stat a volume entry.
_, err = osStat(preparePath(volumeDir))
_, err = osStat((volumeDir))
if err != nil {
if os.IsNotExist(err) {
return nil, errVolumeNotFound
@ -490,7 +490,7 @@ func (s *posix) ReadAll(volume, path string) (buf []byte, err error) {
return nil, err
}
// Stat a volume entry.
_, err = osStat(preparePath(volumeDir))
_, err = osStat((volumeDir))
if err != nil {
if os.IsNotExist(err) {
return nil, errVolumeNotFound
@ -500,12 +500,12 @@ func (s *posix) ReadAll(volume, path string) (buf []byte, err error) {
// Validate file path length, before reading.
filePath := pathJoin(volumeDir, path)
if err = checkPathLength(preparePath(filePath)); err != nil {
if err = checkPathLength((filePath)); err != nil {
return nil, err
}
// Open the file for reading.
buf, err = ioutil.ReadFile(preparePath(filePath))
buf, err = ioutil.ReadFile((filePath))
if err != nil {
if os.IsNotExist(err) {
return nil, errFileNotFound
@ -575,7 +575,7 @@ func (s *posix) ReadFileWithVerify(volume, path string, offset int64, buf []byte
return 0, err
}
// Stat a volume entry.
_, err = osStat(preparePath(volumeDir))
_, err = osStat((volumeDir))
if err != nil {
if os.IsNotExist(err) {
return 0, errVolumeNotFound
@ -585,12 +585,12 @@ func (s *posix) ReadFileWithVerify(volume, path string, offset int64, buf []byte
// Validate effective path length before reading.
filePath := pathJoin(volumeDir, path)
if err = checkPathLength(preparePath(filePath)); err != nil {
if err = checkPathLength((filePath)); err != nil {
return 0, err
}
// Open the file for reading.
file, err := os.Open(preparePath(filePath))
file, err := os.Open((filePath))
if err != nil {
if os.IsNotExist(err) {
return 0, errFileNotFound
@ -695,7 +695,7 @@ func (s *posix) createFile(volume, path string) (f *os.File, err error) {
return nil, err
}
// Stat a volume entry.
_, err = osStat(preparePath(volumeDir))
_, err = osStat((volumeDir))
if err != nil {
if os.IsNotExist(err) {
return nil, errVolumeNotFound
@ -704,20 +704,20 @@ func (s *posix) createFile(volume, path string) (f *os.File, err error) {
}
filePath := pathJoin(volumeDir, path)
if err = checkPathLength(preparePath(filePath)); err != nil {
if err = checkPathLength((filePath)); err != nil {
return nil, err
}
// Verify if the file already exists and is not of regular type.
var st os.FileInfo
if st, err = osStat(preparePath(filePath)); err == nil {
if st, err = osStat((filePath)); err == nil {
if !st.Mode().IsRegular() {
return nil, errIsNotRegular
}
} else {
// Create top level directories if they don't exist.
// with mode 0777 mkdir honors system umask.
if err = mkdirAll(slashpath.Dir(filePath), 0777); err != nil {
if err = os.MkdirAll(slashpath.Dir(filePath), 0777); err != nil {
// File path cannot be verified since one of the parents is a file.
if isSysErrNotDir(err) {
return nil, errFileAccessDenied
@ -729,7 +729,7 @@ func (s *posix) createFile(volume, path string) (f *os.File, err error) {
}
}
w, err := os.OpenFile(preparePath(filePath), os.O_CREATE|os.O_APPEND|os.O_WRONLY, 0666)
w, err := os.OpenFile((filePath), os.O_CREATE|os.O_APPEND|os.O_WRONLY, 0666)
if err != nil {
// File path cannot be verified since one of the parents is a file.
if isSysErrNotDir(err) {
@ -846,7 +846,7 @@ func (s *posix) StatFile(volume, path string) (file FileInfo, err error) {
return FileInfo{}, err
}
// Stat a volume entry.
_, err = osStat(preparePath(volumeDir))
_, err = osStat((volumeDir))
if err != nil {
if os.IsNotExist(err) {
return FileInfo{}, errVolumeNotFound
@ -855,10 +855,10 @@ func (s *posix) StatFile(volume, path string) (file FileInfo, err error) {
}
filePath := slashpath.Join(volumeDir, path)
if err = checkPathLength(preparePath(filePath)); err != nil {
if err = checkPathLength((filePath)); err != nil {
return FileInfo{}, err
}
st, err := osStat(preparePath(filePath))
st, err := osStat((filePath))
if err != nil {
// File is really not found.
if os.IsNotExist(err) {
@ -895,7 +895,7 @@ func deleteFile(basePath, deletePath string) error {
}
// Attempt to remove path.
if err := os.Remove(preparePath(deletePath)); err != nil {
if err := os.Remove((deletePath)); err != nil {
// Ignore errors if the directory is not empty. The server relies on
// this functionality, and sometimes uses recursion that should not
// error on parent directories.
@ -939,7 +939,7 @@ func (s *posix) DeleteFile(volume, path string) (err error) {
return err
}
// Stat a volume entry.
_, err = osStat(preparePath(volumeDir))
_, err = osStat((volumeDir))
if err != nil {
if os.IsNotExist(err) {
return errVolumeNotFound
@ -950,7 +950,7 @@ func (s *posix) DeleteFile(volume, path string) (err error) {
// Following code is needed so that we retain "/" suffix if any in
// path argument.
filePath := pathJoin(volumeDir, path)
if err = checkPathLength(preparePath(filePath)); err != nil {
if err = checkPathLength((filePath)); err != nil {
return err
}
@ -983,14 +983,14 @@ func (s *posix) RenameFile(srcVolume, srcPath, dstVolume, dstPath string) (err e
return err
}
// Stat a volume entry.
_, err = osStat(preparePath(srcVolumeDir))
_, err = osStat((srcVolumeDir))
if err != nil {
if os.IsNotExist(err) {
return errVolumeNotFound
}
return err
}
_, err = osStat(preparePath(dstVolumeDir))
_, err = osStat((dstVolumeDir))
if err != nil {
if os.IsNotExist(err) {
return errVolumeNotFound
@ -1004,16 +1004,16 @@ func (s *posix) RenameFile(srcVolume, srcPath, dstVolume, dstPath string) (err e
return errFileAccessDenied
}
srcFilePath := slashpath.Join(srcVolumeDir, srcPath)
if err = checkPathLength(preparePath(srcFilePath)); err != nil {
if err = checkPathLength((srcFilePath)); err != nil {
return err
}
dstFilePath := slashpath.Join(dstVolumeDir, dstPath)
if err = checkPathLength(preparePath(dstFilePath)); err != nil {
if err = checkPathLength((dstFilePath)); err != nil {
return err
}
if srcIsDir {
// If source is a directory we expect the destination to be non-existent always.
_, err = osStat(preparePath(dstFilePath))
_, err = osStat((dstFilePath))
if err == nil {
return errFileAccessDenied
}
@ -1023,7 +1023,7 @@ func (s *posix) RenameFile(srcVolume, srcPath, dstVolume, dstPath string) (err e
// Destination does not exist, hence proceed with the rename.
}
// Creates all the parent directories, with mode 0777 mkdir honors system umask.
if err = mkdirAll(slashpath.Dir(dstFilePath), 0777); err != nil {
if err = os.MkdirAll(slashpath.Dir(dstFilePath), 0777); err != nil {
// File path cannot be verified since one of the parents is a file.
if isSysErrNotDir(err) {
return errFileAccessDenied
@ -1036,7 +1036,7 @@ func (s *posix) RenameFile(srcVolume, srcPath, dstVolume, dstPath string) (err e
return err
}
// Finally attempt a rename.
err = os.Rename(preparePath(srcFilePath), preparePath(dstFilePath))
err = os.Rename((srcFilePath), (dstFilePath))
if err != nil {
if os.IsNotExist(err) {
return errFileNotFound

View File

@ -55,7 +55,7 @@ func TestPosixGetDiskInfo(t *testing.T) {
if err != nil {
t.Fatalf("Unable to create a temporary directory, %s", err)
}
defer removeAll(path)
defer os.RemoveAll(path)
testCases := []struct {
diskPath string
@ -78,7 +78,7 @@ func TestPosixIsDirEmpty(t *testing.T) {
if err != nil {
t.Fatal(err)
}
defer removeAll(tmp)
defer os.RemoveAll(tmp)
// Should give false on non-existent directory.
dir1 := slashpath.Join(tmp, "non-existent-directory")
@ -117,7 +117,7 @@ func TestPosixReadAll(t *testing.T) {
t.Fatalf("Unable to create posix test setup, %s", err)
}
defer removeAll(path)
defer os.RemoveAll(path)
// Create files for the test cases.
if err = posixStorage.MakeVol("exists"); err != nil {
@ -262,7 +262,7 @@ func TestPosixMakeVol(t *testing.T) {
if err != nil {
t.Fatalf("Unable to create posix test setup, %s", err)
}
defer removeAll(path)
defer os.RemoveAll(path)
// Setup test environment.
// Create a file.
@ -348,7 +348,7 @@ func TestPosixDeleteVol(t *testing.T) {
if err != nil {
t.Fatalf("Unable to create posix test setup, %s", err)
}
defer removeAll(path)
defer os.RemoveAll(path)
// Setup test environment.
if err = posixStorage.MakeVol("success-vol"); err != nil {
@ -436,7 +436,7 @@ func TestPosixDeleteVol(t *testing.T) {
t.Fatalf("Unable to create posix test setup, %s", err)
}
// removing the disk, used to recreate disk not found error.
removeAll(diskPath)
os.RemoveAll(diskPath)
// TestPosix for delete on an removed disk.
// should fail with disk not found.
@ -453,7 +453,7 @@ func TestPosixStatVol(t *testing.T) {
if err != nil {
t.Fatalf("Unable to create posix test setup, %s", err)
}
defer removeAll(path)
defer os.RemoveAll(path)
// Setup test environment.
if err = posixStorage.MakeVol("success-vol"); err != nil {
@ -517,7 +517,7 @@ func TestPosixStatVol(t *testing.T) {
t.Fatalf("Unable to create posix test setup, %s", err)
}
// removing the disk, used to recreate disk not found error.
removeAll(diskPath)
os.RemoveAll(diskPath)
// TestPosix for delete on an removed disk.
// should fail with disk not found.
@ -566,7 +566,7 @@ func TestPosixListVols(t *testing.T) {
t.Errorf("Expected to fail with \"%s\", but instead failed with \"%s\"", errFaultyDisk, err)
}
// removing the path and simulating disk failure
removeAll(path)
os.RemoveAll(path)
// Resetting the IO error.
// should fail with errDiskNotFound.
if posixType, ok := posixStorage.(*posix); ok {
@ -587,7 +587,7 @@ func TestPosixPosixListDir(t *testing.T) {
if err != nil {
t.Fatalf("Unable to create posix test setup, %s", err)
}
defer removeAll(path)
defer os.RemoveAll(path)
// create posix test setup.
posixDeletedStorage, diskPath, err := newPosixTestSetup()
@ -595,7 +595,7 @@ func TestPosixPosixListDir(t *testing.T) {
t.Fatalf("Unable to create posix test setup, %s", err)
}
// removing the disk, used to recreate disk not found error.
removeAll(diskPath)
os.RemoveAll(diskPath)
// Setup test environment.
if err = posixStorage.MakeVol("success-vol"); err != nil {
t.Fatalf("Unable to create volume, %s", err)
@ -725,7 +725,7 @@ func TestPosixDeleteFile(t *testing.T) {
if err != nil {
t.Fatalf("Unable to create posix test setup, %s", err)
}
defer removeAll(path)
defer os.RemoveAll(path)
// create posix test setup
posixDeletedStorage, diskPath, err := newPosixTestSetup()
@ -733,7 +733,7 @@ func TestPosixDeleteFile(t *testing.T) {
t.Fatalf("Unable to create posix test setup, %s", err)
}
// removing the disk, used to recreate disk not found error.
removeAll(diskPath)
os.RemoveAll(diskPath)
// Setup test environment.
if err = posixStorage.MakeVol("success-vol"); err != nil {
t.Fatalf("Unable to create volume, %s", err)
@ -859,7 +859,7 @@ func TestPosixReadFile(t *testing.T) {
if err != nil {
t.Fatalf("Unable to create posix test setup, %s", err)
}
defer removeAll(path)
defer os.RemoveAll(path)
volume := "success-vol"
// Setup test environment.
@ -946,13 +946,13 @@ func TestPosixReadFile(t *testing.T) {
if runtime.GOOS == globalWindowsOSName {
return &os.PathError{
Op: "seek",
Path: preparePath(slashpath.Join(path, "success-vol", "myobject")),
Path: (slashpath.Join(path, "success-vol", "myobject")),
Err: syscall.Errno(0x83), // ERROR_NEGATIVE_SEEK
}
}
return &os.PathError{
Op: "seek",
Path: preparePath(slashpath.Join(path, "success-vol", "myobject")),
Path: (slashpath.Join(path, "success-vol", "myobject")),
Err: os.ErrInvalid,
}
}(),
@ -1089,7 +1089,7 @@ func TestPosixReadFileWithVerify(t *testing.T) {
if err != nil {
t.Fatalf("Unable to create posix test setup, %s", err)
}
defer removeAll(path)
defer os.RemoveAll(path)
volume := "success-vol"
// Setup test environment.
@ -1195,7 +1195,7 @@ func TestPosixAppendFile(t *testing.T) {
if err != nil {
t.Fatalf("Unable to create posix test setup, %s", err)
}
defer removeAll(path)
defer os.RemoveAll(path)
// Setup test environment.
if err = posixStorage.MakeVol("success-vol"); err != nil {
@ -1287,7 +1287,7 @@ func TestPosixPrepareFile(t *testing.T) {
if err != nil {
t.Fatalf("Unable to create posix test setup, %s", err)
}
defer removeAll(path)
defer os.RemoveAll(path)
// Setup test environment.
if err = posixStorage.MakeVol("success-vol"); err != nil {
@ -1381,7 +1381,7 @@ func TestPosixRenameFile(t *testing.T) {
if err != nil {
t.Fatalf("Unable to create posix test setup, %s", err)
}
defer removeAll(path)
defer os.RemoveAll(path)
// Setup test environment.
if err := posixStorage.MakeVol("src-vol"); err != nil {
@ -1635,7 +1635,7 @@ func TestPosixStatFile(t *testing.T) {
if err != nil {
t.Fatalf("Unable to create posix test setup, %s", err)
}
defer removeAll(path)
defer os.RemoveAll(path)
// Setup test environment.
if err := posixStorage.MakeVol("success-vol"); err != nil {

View File

@ -25,6 +25,7 @@ import (
"net/http"
"net/http/httptest"
"net/url"
"os"
"testing"
"time"
@ -120,7 +121,7 @@ func testPostPolicyBucketHandler(obj ObjectLayer, instanceType string, t TestErr
if err != nil {
t.Fatalf("Initializing config.json failed")
}
defer removeAll(root)
defer os.RemoveAll(root)
// Register event notifier.
err = initEventNotifier(obj)
@ -428,7 +429,7 @@ func testPostPolicyBucketHandlerRedirect(obj ObjectLayer, instanceType string, t
if err != nil {
t.Fatalf("Initializing config.json failed")
}
defer removeAll(root)
defer os.RemoveAll(root)
// Register event notifier.
err = initEventNotifier(obj)

View File

@ -18,6 +18,7 @@ package cmd
import (
"fmt"
"os"
"testing"
)
@ -27,7 +28,7 @@ func TestHealMsg(t *testing.T) {
if err != nil {
t.Fatal("Unable to initialize test config", err)
}
defer removeAll(rootPath)
defer os.RemoveAll(rootPath)
storageDisks, fsDirs := prepareXLStorageDisks(t)
errs := make([]error, len(storageDisks))
defer removeRoots(fsDirs)

View File

@ -21,6 +21,7 @@ import (
"crypto/sha256"
"encoding/hex"
"errors"
"os"
"reflect"
"testing"
"time"
@ -32,7 +33,7 @@ func TestRetryStorage(t *testing.T) {
if err != nil {
t.Fatal(err)
}
defer removeAll(root)
defer os.RemoveAll(root)
originalStorageDisks, disks := prepareXLStorageDisks(t)
defer removeRoots(disks)

View File

@ -17,6 +17,7 @@
package cmd
import (
"os"
"reflect"
"testing"
)
@ -29,7 +30,7 @@ func TestMakeS3Peers(t *testing.T) {
if err != nil {
t.Fatalf("%s", err)
}
defer removeAll(root)
defer os.RemoveAll(root)
// test cases
testCases := []struct {

View File

@ -18,6 +18,7 @@ package cmd
import (
"encoding/json"
"os"
"path"
"testing"
)
@ -43,7 +44,7 @@ func (s *TestRPCS3PeerSuite) SetUpSuite(t *testing.T) {
func (s *TestRPCS3PeerSuite) TearDownSuite(t *testing.T) {
s.testServer.Stop()
removeRoots(s.disks)
removeAll(s.testServer.Root)
os.RemoveAll(s.testServer.Root)
}
func TestS3PeerRPC(t *testing.T) {

View File

@ -20,6 +20,7 @@ import (
"crypto/x509"
"crypto/x509/pkix"
"fmt"
"os"
"reflect"
"strings"
"testing"
@ -125,7 +126,7 @@ func TestPrintServerCommonMessage(t *testing.T) {
if err != nil {
t.Fatal(err)
}
defer removeAll(root)
defer os.RemoveAll(root)
apiEndpoints := []string{"http://127.0.0.1:9000"}
printServerCommonMsg(apiEndpoints)
@ -137,7 +138,7 @@ func TestPrintCLIAccessMsg(t *testing.T) {
if err != nil {
t.Fatal(err)
}
defer removeAll(root)
defer os.RemoveAll(root)
apiEndpoints := []string{"http://127.0.0.1:9000"}
printCLIAccessMsg(apiEndpoints[0], "myminio")
@ -149,7 +150,7 @@ func TestPrintStartupMessage(t *testing.T) {
if err != nil {
t.Fatal(err)
}
defer removeAll(root)
defer os.RemoveAll(root)
apiEndpoints := []string{"http://127.0.0.1:9000"}
printStartupMessage(apiEndpoints)

View File

@ -20,6 +20,7 @@ import (
"fmt"
"net/http"
"net/url"
"os"
"sort"
"testing"
)
@ -43,7 +44,7 @@ func TestDoesPresignedV2SignatureMatch(t *testing.T) {
if err != nil {
t.Fatal("Unable to initialize test config.")
}
defer removeAll(root)
defer os.RemoveAll(root)
now := UTCNow()
@ -138,7 +139,7 @@ func TestValidateV2AuthHeader(t *testing.T) {
if err != nil {
t.Fatal("Unable to initialize test config.")
}
defer removeAll(root)
defer os.RemoveAll(root)
accessID := serverConfig.GetCredential().AccessKey
testCases := []struct {
@ -209,7 +210,7 @@ func TestDoesPolicySignatureV2Match(t *testing.T) {
if err != nil {
t.Fatal("Unable to initialize test config.")
}
defer removeAll(root)
defer os.RemoveAll(root)
creds := serverConfig.GetCredential()
policy := "policy"
testCases := []struct {

View File

@ -20,6 +20,7 @@ import (
"fmt"
"net/http"
"net/url"
"os"
"testing"
"time"
)
@ -95,7 +96,7 @@ func TestDoesPresignedSignatureMatch(t *testing.T) {
if err != nil {
t.Fatal(err)
}
defer removeAll(rootPath)
defer os.RemoveAll(rootPath)
// sha256 hash of "payload"
payloadSHA256 := "239f59ed55e737c77147cf55ad0c1b030b6d7ee748a7426952f9b852d5a935e5"

View File

@ -17,6 +17,7 @@
package cmd
import (
"os"
"testing"
"github.com/minio/minio/pkg/disk"
@ -78,7 +79,7 @@ func errorIfInvalidToken(t *testing.T, err error) {
func TestStorageRPCInvalidToken(t *testing.T) {
st := createTestStorageServer(t)
defer removeRoots(st.diskDirs)
defer removeAll(st.configDir)
defer os.RemoveAll(st.configDir)
storageRPC := st.stServer

View File

@ -510,9 +510,9 @@ func newTestConfig(bucketLocation string) (rootPath string, err error) {
// Deleting the temporary backend and stopping the server.
func (testServer TestServer) Stop() {
removeAll(testServer.Root)
os.RemoveAll(testServer.Root)
for _, disk := range testServer.Disks {
removeAll(disk.Path)
os.RemoveAll(disk.Path)
}
testServer.Server.Close()
}
@ -1646,7 +1646,7 @@ func initObjectLayer(endpoints EndpointList) (ObjectLayer, []StorageAPI, error)
// removeRoots - Cleans up initialized directories during tests.
func removeRoots(roots []string) {
for _, root := range roots {
removeAll(root)
os.RemoveAll(root)
}
}
@ -1656,7 +1656,7 @@ func removeDiskN(disks []string, n int) {
n = len(disks)
}
for _, disk := range disks[:n] {
removeAll(disk)
os.RemoveAll(disk)
}
}
@ -1977,7 +1977,7 @@ func ExecObjectLayerTest(t TestErrHandler, objTest objTestType) {
if err != nil {
t.Fatal("Unexpected error", err)
}
defer removeAll(rootPath)
defer os.RemoveAll(rootPath)
objLayer, fsDir, err := prepareFS()
if err != nil {
@ -2002,7 +2002,7 @@ func ExecObjectLayerDiskAlteredTest(t *testing.T, objTest objTestDiskNotFoundTyp
if err != nil {
t.Fatal("Failed to create config directory", err)
}
defer removeAll(configPath)
defer os.RemoveAll(configPath)
objLayer, fsDirs, err := prepareXL()
if err != nil {
@ -2024,7 +2024,7 @@ func ExecObjectLayerStaleFilesTest(t *testing.T, objTest objTestStaleFilesType)
if err != nil {
t.Fatal("Failed to create config directory", err)
}
defer removeAll(configPath)
defer os.RemoveAll(configPath)
nDisks := 16
erasureDisks, err := getRandomDisks(nDisks)

View File

@ -19,6 +19,7 @@ package cmd
import (
"fmt"
"io/ioutil"
"os"
"reflect"
"sort"
"testing"
@ -190,7 +191,7 @@ func TestTreeWalk(t *testing.T) {
testTreeWalkPrefix(t, listDir, isLeaf)
// Simple test when marker is set.
testTreeWalkMarker(t, listDir, isLeaf)
err = removeAll(fsDir)
err = os.RemoveAll(fsDir)
if err != nil {
t.Fatal(err)
}
@ -258,7 +259,7 @@ func TestTreeWalkTimeout(t *testing.T) {
if ok {
t.Error("Tree-walk go routine has not exited after timeout.")
}
err = removeAll(fsDir)
err = os.RemoveAll(fsDir)
if err != nil {
t.Error(err)
}
@ -319,7 +320,7 @@ func TestListDir(t *testing.T) {
}
// Remove fsDir1 to test failover.
err = removeAll(fsDir1)
err = os.RemoveAll(fsDir1)
if err != nil {
t.Error(err)
}
@ -335,7 +336,7 @@ func TestListDir(t *testing.T) {
if entries[0] != file2 {
t.Fatal("Expected the entry to be file2")
}
err = removeAll(fsDir2)
err = os.RemoveAll(fsDir2)
if err != nil {
t.Error(err)
}
@ -451,7 +452,7 @@ func TestRecursiveTreeWalk(t *testing.T) {
}
}
}
err = removeAll(fsDir1)
err = os.RemoveAll(fsDir1)
if err != nil {
t.Error(err)
}
@ -526,7 +527,7 @@ func TestSortedness(t *testing.T) {
}
// Remove directory created for testing
err = removeAll(fsDir1)
err = os.RemoveAll(fsDir1)
if err != nil {
t.Error(err)
}
@ -601,7 +602,7 @@ func TestTreeWalkIsEnd(t *testing.T) {
}
// Remove directory created for testing
err = removeAll(fsDir1)
err = os.RemoveAll(fsDir1)
if err != nil {
t.Error(err)
}

View File

@ -28,6 +28,7 @@ import (
"io/ioutil"
"net/http"
"net/http/httptest"
"os"
"reflect"
"strconv"
"strings"
@ -1346,7 +1347,7 @@ func TestWebCheckAuthorization(t *testing.T) {
t.Fatal("Init Test config failed", err)
}
// remove the root directory after the test ends.
defer removeAll(rootPath)
defer os.RemoveAll(rootPath)
rec := httptest.NewRecorder()
@ -1428,7 +1429,7 @@ func TestWebObjectLayerNotReady(t *testing.T) {
t.Fatal("Init Test config failed", err)
}
// remove the root directory after the test ends.
defer removeAll(rootPath)
defer os.RemoveAll(rootPath)
rec := httptest.NewRecorder()
@ -1506,7 +1507,7 @@ func TestWebObjectLayerFaultyDisks(t *testing.T) {
if err != nil {
t.Fatal(err)
}
defer removeAll(root)
defer os.RemoveAll(root)
// Prepare XL backend
obj, fsDirs, err := prepareXL()
@ -1538,7 +1539,7 @@ func TestWebObjectLayerFaultyDisks(t *testing.T) {
t.Fatal("Init Test config failed", err)
}
// remove the root directory after the test ends.
defer removeAll(rootPath)
defer os.RemoveAll(rootPath)
rec := httptest.NewRecorder()

View File

@ -18,6 +18,7 @@ package cmd
import (
"bytes"
"os"
"path/filepath"
"testing"
"time"
@ -127,7 +128,7 @@ func TestListOnlineDisks(t *testing.T) {
if err != nil {
t.Fatalf("Failed to initialize config - %v", err)
}
defer removeAll(rootPath)
defer os.RemoveAll(rootPath)
obj, disks, err := prepareXL()
if err != nil {
@ -336,7 +337,7 @@ func TestDisksWithAllParts(t *testing.T) {
if err != nil {
t.Fatalf("Failed to initialize config - %v", err)
}
defer removeAll(rootPath)
defer os.RemoveAll(rootPath)
obj, disks, err := prepareXL()
if err != nil {

View File

@ -19,6 +19,7 @@ package cmd
import (
"bytes"
"fmt"
"os"
"path/filepath"
"testing"
)
@ -29,7 +30,7 @@ func TestHealFormatXL(t *testing.T) {
if err != nil {
t.Fatal(err)
}
defer removeAll(root)
defer os.RemoveAll(root)
nDisks := 16
fsDirs, err := getRandomDisks(nDisks)
@ -263,7 +264,7 @@ func TestUndoMakeBucket(t *testing.T) {
if err != nil {
t.Fatal(err)
}
defer removeAll(root)
defer os.RemoveAll(root)
nDisks := 16
fsDirs, err := getRandomDisks(nDisks)
@ -303,7 +304,7 @@ func TestQuickHeal(t *testing.T) {
if err != nil {
t.Fatal(err)
}
defer removeAll(root)
defer os.RemoveAll(root)
nDisks := 16
fsDirs, err := getRandomDisks(nDisks)
@ -398,7 +399,7 @@ func TestListBucketsHeal(t *testing.T) {
if err != nil {
t.Fatal(err)
}
defer removeAll(root)
defer os.RemoveAll(root)
nDisks := 16
fsDirs, err := getRandomDisks(nDisks)
@ -456,7 +457,7 @@ func TestHealObjectXL(t *testing.T) {
if err != nil {
t.Fatal(err)
}
defer removeAll(root)
defer os.RemoveAll(root)
nDisks := 16
fsDirs, err := getRandomDisks(nDisks)

View File

@ -18,6 +18,7 @@ package cmd
import (
"bytes"
"os"
"path"
"path/filepath"
"strconv"
@ -34,7 +35,7 @@ func TestListObjectsHeal(t *testing.T) {
t.Fatalf("Init Test config failed")
}
// remove the root directory after the test ends.
defer removeAll(rootPath)
defer os.RemoveAll(rootPath)
// Create an instance of xl backend
xl, fsDirs, err := prepareXL()
@ -151,7 +152,7 @@ func TestListUploadsHeal(t *testing.T) {
t.Fatalf("Init Test config failed")
}
// Remove config directory after the test ends.
defer removeAll(rootPath)
defer os.RemoveAll(rootPath)
// Create an instance of XL backend.
xl, fsDirs, err := prepareXL()

View File

@ -19,6 +19,7 @@ package cmd
import (
"bytes"
"errors"
"os"
"path"
"strconv"
"testing"
@ -89,7 +90,7 @@ func testXLReadStat(obj ObjectLayer, instanceType string, disks []string, t *tes
}
for _, disk := range disks {
removeAll(path.Join(disk, bucketName))
os.RemoveAll(path.Join(disk, bucketName))
}
_, _, err = obj.(*xlObjects).readXLMetaStat(bucketName, objectName)
@ -173,8 +174,8 @@ func testXLReadMetaParts(obj ObjectLayer, instanceType string, disks []string, t
}
for _, disk := range disks {
removeAll(path.Join(disk, bucketNames[0]))
removeAll(path.Join(disk, minioMetaMultipartBucket, bucketNames[0]))
os.RemoveAll(path.Join(disk, bucketNames[0]))
os.RemoveAll(path.Join(disk, minioMetaMultipartBucket, bucketNames[0]))
}
_, err = obj.(*xlObjects).readXLMetaParts(minioMetaMultipartBucket, uploadIDPath)

View File

@ -17,6 +17,7 @@
package cmd
import (
"os"
"testing"
"time"
)
@ -27,7 +28,7 @@ func TestUpdateUploadJSON(t *testing.T) {
if err != nil {
t.Fatalf("%s", err)
}
defer removeAll(root)
defer os.RemoveAll(root)
// Create an instance of xl backend
obj, fsDirs, err := prepareXL()

View File

@ -269,7 +269,7 @@ func TestHealing(t *testing.T) {
if err != nil {
t.Fatalf("Failed to initialize test config %v", err)
}
defer removeAll(rootPath)
defer os.RemoveAll(rootPath)
obj, fsDirs, err := prepareXL()
if err != nil {

View File

@ -17,6 +17,7 @@
package cmd
import (
"os"
"path/filepath"
"reflect"
"testing"
@ -33,7 +34,7 @@ func TestStorageInfo(t *testing.T) {
// Remove all dirs.
for _, dir := range fsDirs {
defer removeAll(dir)
defer os.RemoveAll(dir)
}
// Get storage info first attempt.
@ -131,7 +132,7 @@ func TestNewXL(t *testing.T) {
// and successfully returns initialized object layer.
disk := filepath.Join(globalTestTmpDir, "minio-"+nextSuffix())
erasureDisks = append(erasureDisks, disk)
defer removeAll(disk)
defer os.RemoveAll(disk)
}
// No disks input.

View File

@ -21,6 +21,7 @@ package lock
import (
"fmt"
"os"
"path/filepath"
"syscall"
"unsafe"
@ -86,6 +87,86 @@ func LockedOpenFile(path string, flag int, perm os.FileMode) (*LockedFile, error
return lockedOpenFile(path, flag, perm, 0)
}
// fixLongPath returns the extended-length (\\?\-prefixed) form of
// path when needed, in order to avoid the default 260 character file
// path limit imposed by Windows. If path is not easily converted to
// the extended-length form (for example, if path is a relative path
// or contains .. elements), or is short enough, fixLongPath returns
// path unmodified.
//
// See https://msdn.microsoft.com/en-us/library/windows/desktop/aa365247(v=vs.85).aspx#maxpath
func fixLongPath(path string) string {
// Do nothing (and don't allocate) if the path is "short".
// Empirically (at least on the Windows Server 2013 builder),
// the kernel is arbitrarily okay with < 248 bytes. That
// matches what the docs above say:
// "When using an API to create a directory, the specified
// path cannot be so long that you cannot append an 8.3 file
// name (that is, the directory name cannot exceed MAX_PATH
// minus 12)." Since MAX_PATH is 260, 260 - 12 = 248.
//
// The MSDN docs appear to say that a normal path that is 248 bytes long
// will work; empirically the path must be less then 248 bytes long.
if len(path) < 248 {
// Don't fix. (This is how Go 1.7 and earlier worked,
// not automatically generating the \\?\ form)
return path
}
// The extended form begins with \\?\, as in
// \\?\c:\windows\foo.txt or \\?\UNC\server\share\foo.txt.
// The extended form disables evaluation of . and .. path
// elements and disables the interpretation of / as equivalent
// to \. The conversion here rewrites / to \ and elides
// . elements as well as trailing or duplicate separators. For
// simplicity it avoids the conversion entirely for relative
// paths or paths containing .. elements. For now,
// \\server\share paths are not converted to
// \\?\UNC\server\share paths because the rules for doing so
// are less well-specified.
if len(path) >= 2 && path[:2] == `\\` {
// Don't canonicalize UNC paths.
return path
}
if !filepath.IsAbs(path) {
// Relative path
return path
}
const prefix = `\\?`
pathbuf := make([]byte, len(prefix)+len(path)+len(`\`))
copy(pathbuf, prefix)
n := len(path)
r, w := 0, len(prefix)
for r < n {
switch {
case os.IsPathSeparator(path[r]):
// empty block
r++
case path[r] == '.' && (r+1 == n || os.IsPathSeparator(path[r+1])):
// /./
r++
case r+1 < n && path[r] == '.' && path[r+1] == '.' && (r+2 == n || os.IsPathSeparator(path[r+2])):
// /../ is currently unhandled
return path
default:
pathbuf[w] = '\\'
w++
for ; r < n && !os.IsPathSeparator(path[r]); r++ {
pathbuf[w] = path[r]
w++
}
}
}
// A drive's root directory needs a trailing \
if w == len(`\\?\c:`) {
pathbuf[w] = '\\'
w++
}
return string(pathbuf[:w])
}
// perm param is ignored, on windows file perms/NT acls
// are not octet combinations. Providing access to NT
// acls is out of scope here.
@ -94,7 +175,7 @@ func open(path string, flag int, perm os.FileMode) (*os.File, error) {
return nil, syscall.ERROR_FILE_NOT_FOUND
}
pathp, err := syscall.UTF16PtrFromString(path)
pathp, err := syscall.UTF16PtrFromString(fixLongPath(path))
if err != nil {
return nil, err
}

View File

@ -0,0 +1,59 @@
// +build windows
/*
* Minio Cloud Storage, (C) 2017 Minio, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package lock
import (
"strings"
"testing"
)
func TestFixLongPath(t *testing.T) {
// 248 is long enough to trigger the longer-than-248 checks in
// fixLongPath, but short enough not to make a path component
// longer than 255, which is illegal on Windows. (which
// doesn't really matter anyway, since this is purely a string
// function we're testing, and it's not actually being used to
// do a system call)
veryLong := "l" + strings.Repeat("o", 248) + "ng"
for _, test := range []struct{ in, want string }{
// Short; unchanged:
{`C:\short.txt`, `C:\short.txt`},
{`C:\`, `C:\`},
{`C:`, `C:`},
// The "long" substring is replaced by a looooooong
// string which triggers the rewriting. Except in the
// cases below where it doesn't.
{`C:\long\foo.txt`, `\\?\C:\long\foo.txt`},
{`C:/long/foo.txt`, `\\?\C:\long\foo.txt`},
{`C:\long\foo\\bar\.\baz\\`, `\\?\C:\long\foo\bar\baz`},
{`\\unc\path`, `\\unc\path`},
{`long.txt`, `long.txt`},
{`C:long.txt`, `C:long.txt`},
{`c:\long\..\bar\baz`, `c:\long\..\bar\baz`},
{`\\?\c:\long\foo.txt`, `\\?\c:\long\foo.txt`},
{`\\?\c:\long/foo.txt`, `\\?\c:\long/foo.txt`},
} {
in := strings.Replace(test.in, "long", veryLong, -1)
want := strings.Replace(test.want, "long", veryLong, -1)
if got := fixLongPath(in); got != want {
got = strings.Replace(got, veryLong, "long", -1)
t.Errorf("fixLongPath(%q) = %q; want %q", test.in, got, test.want)
}
}
}

View File

@ -37,6 +37,86 @@ import (
const errSharingViolation syscall.Errno = 32
// fixLongPath returns the extended-length (\\?\-prefixed) form of
// path when needed, in order to avoid the default 260 character file
// path limit imposed by Windows. If path is not easily converted to
// the extended-length form (for example, if path is a relative path
// or contains .. elements), or is short enough, fixLongPath returns
// path unmodified.
//
// See https://msdn.microsoft.com/en-us/library/windows/desktop/aa365247(v=vs.85).aspx#maxpath
func fixLongPath(path string) string {
// Do nothing (and don't allocate) if the path is "short".
// Empirically (at least on the Windows Server 2013 builder),
// the kernel is arbitrarily okay with < 248 bytes. That
// matches what the docs above say:
// "When using an API to create a directory, the specified
// path cannot be so long that you cannot append an 8.3 file
// name (that is, the directory name cannot exceed MAX_PATH
// minus 12)." Since MAX_PATH is 260, 260 - 12 = 248.
//
// The MSDN docs appear to say that a normal path that is 248 bytes long
// will work; empirically the path must be less then 248 bytes long.
if len(path) < 248 {
// Don't fix. (This is how Go 1.7 and earlier worked,
// not automatically generating the \\?\ form)
return path
}
// The extended form begins with \\?\, as in
// \\?\c:\windows\foo.txt or \\?\UNC\server\share\foo.txt.
// The extended form disables evaluation of . and .. path
// elements and disables the interpretation of / as equivalent
// to \. The conversion here rewrites / to \ and elides
// . elements as well as trailing or duplicate separators. For
// simplicity it avoids the conversion entirely for relative
// paths or paths containing .. elements. For now,
// \\server\share paths are not converted to
// \\?\UNC\server\share paths because the rules for doing so
// are less well-specified.
if len(path) >= 2 && path[:2] == `\\` {
// Don't canonicalize UNC paths.
return path
}
if !filepath.IsAbs(path) {
// Relative path
return path
}
const prefix = `\\?`
pathbuf := make([]byte, len(prefix)+len(path)+len(`\`))
copy(pathbuf, prefix)
n := len(path)
r, w := 0, len(prefix)
for r < n {
switch {
case os1.IsPathSeparator(path[r]):
// empty block
r++
case path[r] == '.' && (r+1 == n || os1.IsPathSeparator(path[r+1])):
// /./
r++
case r+1 < n && path[r] == '.' && path[r+1] == '.' && (r+2 == n || os1.IsPathSeparator(path[r+2])):
// /../ is currently unhandled
return path
default:
pathbuf[w] = '\\'
w++
for ; r < n && !os1.IsPathSeparator(path[r]); r++ {
pathbuf[w] = path[r]
w++
}
}
}
// A drive's root directory needs a trailing \
if w == len(`\\?\c:`) {
pathbuf[w] = '\\'
w++
}
return string(pathbuf[:w])
}
// Stat returns a FileInfo structure describing the
// named file. If there is an error, it will be of type
// *PathError.
@ -51,7 +131,7 @@ func Stat(name string) (os1.FileInfo, error) {
if name == os1.DevNull {
return &devNullStat, nil
}
namep, err := syscall.UTF16PtrFromString(name)
namep, err := syscall.UTF16PtrFromString(fixLongPath(name))
if err != nil {
return nil, &os1.PathError{Op: "Stat", Path: name, Err: err}
}

View File

@ -22,6 +22,7 @@ import (
"io/ioutil"
os1 "os"
"path/filepath"
"strings"
"syscall"
"testing"
"unsafe"
@ -207,3 +208,38 @@ func TestStatSymlinkLoop(t *testing.T) {
}
}
}
func TestFixLongPath(t *testing.T) {
// 248 is long enough to trigger the longer-than-248 checks in
// fixLongPath, but short enough not to make a path component
// longer than 255, which is illegal on Windows. (which
// doesn't really matter anyway, since this is purely a string
// function we're testing, and it's not actually being used to
// do a system call)
veryLong := "l" + strings.Repeat("o", 248) + "ng"
for _, test := range []struct{ in, want string }{
// Short; unchanged:
{`C:\short.txt`, `C:\short.txt`},
{`C:\`, `C:\`},
{`C:`, `C:`},
// The "long" substring is replaced by a looooooong
// string which triggers the rewriting. Except in the
// cases below where it doesn't.
{`C:\long\foo.txt`, `\\?\C:\long\foo.txt`},
{`C:/long/foo.txt`, `\\?\C:\long\foo.txt`},
{`C:\long\foo\\bar\.\baz\\`, `\\?\C:\long\foo\bar\baz`},
{`\\unc\path`, `\\unc\path`},
{`long.txt`, `long.txt`},
{`C:long.txt`, `C:long.txt`},
{`c:\long\..\bar\baz`, `c:\long\..\bar\baz`},
{`\\?\c:\long\foo.txt`, `\\?\c:\long\foo.txt`},
{`\\?\c:\long/foo.txt`, `\\?\c:\long/foo.txt`},
} {
in := strings.Replace(test.in, "long", veryLong, -1)
want := strings.Replace(test.want, "long", veryLong, -1)
if got := fixLongPath(in); got != want {
got = strings.Replace(got, veryLong, "long", -1)
t.Errorf("fixLongPath(%q) = %q; want %q", test.in, got, test.want)
}
}
}