diff options
| author | Marin Ivanov <[email protected]> | 2022-08-15 04:24:23 +0300 |
|---|---|---|
| committer | Marin Ivanov <[email protected]> | 2022-08-15 04:24:23 +0300 |
| commit | 43069c737dde59bd86e5b09c496d9df90f29d136 (patch) | |
| tree | 8d6e81c36c0f16c9a5da2f90af31df6f08dd6bab | |
| parent | 04200620823cf9b11e0185234429af6180110adc (diff) | |
Fid ReadDir and improve tests
| -rw-r--r-- | file.go | 48 | ||||
| -rw-r--r-- | fileinfo.go | 9 | ||||
| -rw-r--r-- | fs.go | 29 | ||||
| -rw-r--r-- | fs_test.go | 149 |
4 files changed, 148 insertions, 87 deletions
@@ -5,8 +5,6 @@ import ( "io" "os" "path" - - "github.com/minio/minio-go/v7" ) type File struct { @@ -20,7 +18,9 @@ type File struct { // implements io.Closer func (f *File) Close() error { - defer f.cancel() + if f.cancel != nil { + defer f.cancel() + } if f.r != nil { return f.r.Close() } @@ -70,50 +70,12 @@ func (f *File) Name() string { return path.Base(f.key) } -func (f *File) readdir(count int, onlyDir bool) ([]os.FileInfo, error) { - if !isDirPath(f.key) { - return nil, ErrNotDirectory - } - if count == 0 { - return []os.FileInfo{}, nil - } - ctx, cancel := f.fs.contextWithTimeout() - defer cancel() - objectsCh := f.fs.client.ListObjects(ctx, f.fs.bucket, minio.ListObjectsOptions{Prefix: f.key}) - n := 0 - lastDir := f.key - results := make([]os.FileInfo, 0) - for objectInfo := range objectsCh { - base := path.Base(objectInfo.Key) - dir := path.Dir(objectInfo.Key) + "/" - if lastDir != dir { - lastDir = dir - results = append(results, &FileInfo{ - name: base, - isDir: true, - }) - if onlyDir { - n += 1 - } - } - if !onlyDir { - results = append(results, transformObjectInfo(objectInfo)) - n += 1 - } - if n > count { - break - } - } - - return results, nil -} - func (f *File) Readdir(count int) ([]os.FileInfo, error) { - return f.readdir(count, false) + return f.fs.readdir(f.key, count, false) } func (f *File) Readdirnames(n int) ([]string, error) { - results, err := f.readdir(n, true) + results, err := f.fs.readdir(f.key, n, true) if err != nil { return nil, err } diff --git a/fileinfo.go b/fileinfo.go index c5a7f1d..4724919 100644 --- a/fileinfo.go +++ b/fileinfo.go @@ -48,10 +48,17 @@ func (fi *FileInfo) Sys() interface{} { } func transformObjectInfo(info minio.ObjectInfo) fs.FileInfo { + base := path.Base(info.Key) + isDir := isDirPath(info.Key) + if isDir { + base += "/" + } + return &FileInfo{ objectInfo: &info, - name: path.Base(info.Key), + isDir: isDir, + name: base, size: info.Size, mtime: info.LastModified, } @@ -154,7 +154,7 @@ func (fs *Fs) RemoveAll(path string) error { if !isDirPath(path) { return ErrNotDirectory } - objectsCh := fs.client.ListObjects(ctx, fs.bucket, minio.ListObjectsOptions{Prefix: path}) + objectsCh := fs.client.ListObjects(ctx, fs.bucket, minio.ListObjectsOptions{Prefix: path, Recursive: true}) errc := fs.client.RemoveObjects(ctx, fs.bucket, objectsCh, minio.RemoveObjectsOptions{}) for err := range errc { if err.Err != nil { @@ -242,6 +242,33 @@ func (fs *Fs) newObjectWriter(key string) (io.WriteCloser, context.CancelFunc, < return w, cancel, errc } +func (fs *Fs) readdir(directory string, count int, onlyDir bool) ([]os.FileInfo, error) { + if !isDirPath(directory) { + return nil, ErrNotDirectory + } + if count == 0 { + return []os.FileInfo{}, nil + } + ctx, cancel := fs.contextWithTimeout() + defer cancel() + objectsCh := fs.client.ListObjects(ctx, fs.bucket, minio.ListObjectsOptions{Prefix: directory}) + n := uint(0) + maxcount := uint(count) + results := make([]os.FileInfo, 0) + for objectInfo := range objectsCh { + if onlyDir && !isDirPath(objectInfo.Key) { + continue + } + results = append(results, transformObjectInfo(objectInfo)) + n += 1 + if n > maxcount { + break + } + } + + return results, nil +} + func transformError(err error) error { resp, ok := err.(minio.ErrorResponse) if !ok { @@ -9,10 +9,16 @@ import ( "github.com/spf13/afero" ) +var ( + testdata = []byte("testdata") +) + func TestFsListBuckets(t *testing.T) { is := is.New(t) - afs, err := newTestAfs() - is.NoErr(err) + afs, cleanup := newTestAfs() + defer cleanup() + + var err error buckets, err := testListBuckets(afs.Fs.(*Fs)) is.NoErr(err) is.Equal(len(buckets), 1) @@ -20,40 +26,46 @@ func TestFsListBuckets(t *testing.T) { func TestFsMkdir(t *testing.T) { is := is.New(t) - afs, err := newTestAfs() - is.NoErr(err) - err = afs.Mkdir("test", 0o644) + afs, cleanup := newTestAfs() + defer cleanup() + + err := afs.Mkdir("test", 0o644) is.Equal(err, ErrUnsupported) } func TestFsMkdirAll(t *testing.T) { is := is.New(t) - afs, err := newTestAfs() - is.NoErr(err) - err = afs.MkdirAll("test1/test2", 0o644) + afs, cleanup := newTestAfs() + defer cleanup() + + err := afs.MkdirAll("test1/test2", 0o644) is.Equal(err, ErrUnsupported) } func TestFsChmod(t *testing.T) { is := is.New(t) - afs, err := newTestAfs() - is.NoErr(err) - err = afs.Chmod("test", 0o644) + afs, cleanup := newTestAfs() + defer cleanup() + + err := afs.Chmod("test", 0o644) is.Equal(err, ErrUnsupported) } func TestFsChown(t *testing.T) { is := is.New(t) - afs, err := newTestAfs() - is.NoErr(err) - err = afs.Chown("test", 1000, 1000) + afs, cleanup := newTestAfs() + defer cleanup() + + err := afs.Chown("test", 1000, 1000) is.Equal(err, ErrUnsupported) } func TestFsChtimes(t *testing.T) { is := is.New(t) - afs, err := newTestAfs() - is.NoErr(err) + afs, cleanup := newTestAfs() + defer cleanup() + + var err error now := time.Now() err = afs.Chtimes("test", now, now) is.Equal(err, ErrUnsupported) @@ -61,15 +73,20 @@ func TestFsChtimes(t *testing.T) { func TestFsWriteFile(t *testing.T) { is := is.New(t) - afs, err := newTestAfs() - is.NoErr(err) - err = afs.WriteFile("dir/file", []byte("testdata"), 0) + afs, cleanup := newTestAfs() + defer cleanup() + + err := afs.WriteFile("dir/file", testdata, 0) is.NoErr(err) } func TestFsStat(t *testing.T) { is := is.New(t) - afs, err := newTestAfs() + afs, cleanup := newTestAfs() + defer cleanup() + + var err error + err = afs.WriteFile("dir/file", testdata, 0) is.NoErr(err) info, err := afs.Stat("dir/file") is.NoErr(err) @@ -79,54 +96,66 @@ func TestFsStat(t *testing.T) { func TestFsStatNoExist(t *testing.T) { is := is.New(t) - afs, err := newTestAfs() - is.NoErr(err) + afs, cleanup := newTestAfs() + defer cleanup() + + var err error _, err = afs.Stat("dir/non-existent") is.Equal(err, afero.ErrFileNotFound) } func TestFsReadFile(t *testing.T) { is := is.New(t) - afs, err := newTestAfs() + afs, cleanup := newTestAfs() + defer cleanup() + + var err error + err = afs.WriteFile("dir/file", testdata, 0) is.NoErr(err) b, err := afs.ReadFile("dir/file") is.NoErr(err) - is.Equal(b, []byte("testdata")) + is.Equal(b, testdata) } func TestFsReadNoExist(t *testing.T) { is := is.New(t) - afs, err := newTestAfs() - is.NoErr(err) + afs, cleanup := newTestAfs() + defer cleanup() + + var err error _, err = afs.ReadFile("non-existent") is.Equal(err, afero.ErrFileNotFound) } func TestFsRemove(t *testing.T) { is := is.New(t) - afs, err := newTestAfs() - is.NoErr(err) - err = afs.Remove("dir/file") + afs, cleanup := newTestAfs() + defer cleanup() + + err := afs.Remove("dir/file") is.NoErr(err) } func TestFsRemoveNoExist(t *testing.T) { is := is.New(t) - afs, err := newTestAfs() - is.NoErr(err) - err = afs.Remove("non-existent") + afs, cleanup := newTestAfs() + defer cleanup() + + err := afs.Remove("non-existent") is.NoErr(err) } func TestFsRemoveAll(t *testing.T) { is := is.New(t) - afs, err := newTestAfs() - is.NoErr(err) - err = afs.WriteFile("dir/file1", []byte("testdata"), 0) + afs, cleanup := newTestAfs() + defer cleanup() + + var err error + err = afs.WriteFile("dir/file1", testdata, 0) is.NoErr(err) - err = afs.WriteFile("dir/file2", []byte("testdata"), 0) + err = afs.WriteFile("dir/file2", testdata, 0) is.NoErr(err) - err = afs.WriteFile("persist/file0", []byte("testdata"), 0) + err = afs.WriteFile("persist/file0", testdata, 0) is.NoErr(err) err = afs.RemoveAll("dir/") is.NoErr(err) @@ -138,9 +167,11 @@ func TestFsRemoveAll(t *testing.T) { func TestFsRename(t *testing.T) { is := is.New(t) - afs, err := newTestAfs() - is.NoErr(err) - err = afs.WriteFile("dir/file", []byte("testdata"), 0) + afs, cleanup := newTestAfs() + defer cleanup() + + var err error + err = afs.WriteFile("dir/file", testdata, 0) is.NoErr(err) err = afs.Rename("dir/file", "dir/file2") is.NoErr(err) @@ -152,10 +183,44 @@ func TestFsRename(t *testing.T) { is.NoErr(err) } -func newTestAfs() (*afero.Afero, error) { +func TestFsReadDir(t *testing.T) { + is := is.New(t) + afs, cleanup := newTestAfs() + defer cleanup() + + var err error + err = afs.WriteFile("dir/file1", []byte(""), 0) + is.NoErr(err) + err = afs.WriteFile("dir/file2", []byte(""), 0) + is.NoErr(err) + err = afs.WriteFile("dir/subdir/file3", []byte(""), 0) + is.NoErr(err) + defer afs.RemoveAll("/") + + infos, err := afs.ReadDir("dir/") + is.NoErr(err) + is.Equal(len(infos), 3) + is.Equal(infos[0].Name(), "file1") + is.Equal(infos[1].Name(), "file2") + is.Equal(infos[2].IsDir(), true) + is.Equal(infos[2].Name(), "subdir/") + + f, err := afs.Open("dir/") + is.NoErr(err) + names, err := f.Readdirnames(-1) + is.NoErr(err) + is.Equal(names, []string{"subdir/"}) +} + +func newTestAfs() (*afero.Afero, func()) { fs, err := NewFsFromURL("http://testuser:[email protected]:9000/test-bucket") + if err != nil { + panic("unexpected error") + } afs := &afero.Afero{Fs: fs} - return afs, err + return afs, func() { + afs.RemoveAll("/") + } } func testListBuckets(fs *Fs) ([]string, error) { |
