fix Readdir behaviour for n > 0, fix RemoveAll

This commit is contained in:
Martin Bertschler 2015-11-04 20:33:40 +01:00
parent c64453ab4d
commit 10150bfa64
3 changed files with 143 additions and 37 deletions

View File

@ -16,6 +16,7 @@ package afero
import (
"bytes"
"fmt"
"io"
"io/ioutil"
"os"
@ -288,6 +289,20 @@ func setupTestDir(t *testing.T) {
}
f.WriteString("Testfile 2 content")
f.Close()
f, err = fs.Create(filepath.Join(testSubDir, "testfile3"))
if err != nil {
t.Fatal(err)
}
f.WriteString("Testfile 3 content")
f.Close()
f, err = fs.Create(filepath.Join(testSubDir, "testfile4"))
if err != nil {
t.Fatal(err)
}
f.WriteString("Testfile 4 content")
f.Close()
}
}
@ -315,7 +330,81 @@ func TestReaddirnames(t *testing.T) {
}
}
func TestReaddirSimple(t *testing.T) {
for _, fs := range Fss {
root, err := fs.Open(testDir)
if err != nil {
t.Fatal(err)
}
rootInfo, err := root.Readdir(1)
if err != nil {
t.Log(myFileInfo(rootInfo))
t.Error(err)
}
rootInfo, err = root.Readdir(5)
if err != io.EOF {
t.Log(myFileInfo(rootInfo))
t.Error(err)
}
sub, err := fs.Open(testSubDir)
if err != nil {
t.Fatal(err)
}
subInfo, err := sub.Readdir(5)
if err != nil {
t.Log(myFileInfo(subInfo))
t.Error(err)
}
}
}
func TestReaddir(t *testing.T) {
for num := 0; num < 6; num++ {
outputs := make([]string, len(Fss))
for i, fs := range Fss {
root, err := fs.Open(testSubDir)
if err != nil {
t.Fatal(err)
}
for j := 0; j < 6; j++ {
info, err := root.Readdir(num)
outputs[i] += fmt.Sprintf("%v Error: %v\n", myFileInfo(info), err)
}
}
fail := false
for i, o := range outputs {
if i == 0 {
continue
}
if o != outputs[i-1] {
fail = true
break
}
}
if fail {
t.Log("Readdir outputs not equal for Readdir(", num, ")")
for i, o := range outputs {
t.Log(Fss[i].Name())
t.Log(o)
}
t.Fail()
}
}
}
type myFileInfo []os.FileInfo
func (m myFileInfo) String() string {
out := "Fileinfos:\n"
for _, e := range m {
out += " " + e.Name() + "\n"
}
return out
}
func TestReaddirAll(t *testing.T) {
defer removeTestDir(t)
for _, fs := range Fss {
root, err := fs.Open(testDir)
@ -389,12 +478,12 @@ func findNames(t *testing.T, root, sub []string, fs Fs) {
}
func removeTestDir(t *testing.T) {
// for _, fs := range Fss {
// err := fs.RemoveAll(testDir)
// if err != nil {
// t.Fatal(err)
// }
// }
for _, fs := range Fss {
err := fs.RemoveAll(testDir)
if err != nil {
t.Fatal(err)
}
}
}
func newFile(testName string, fs Fs, t *testing.T) (f File) {

View File

@ -35,14 +35,15 @@ type MemDir interface {
type InMemoryFile struct {
sync.Mutex
at int64
name string
data []byte
memDir MemDir
dir bool
closed bool
mode os.FileMode
modtime time.Time
at int64
name string
data []byte
memDir MemDir
dir bool
closed bool
mode os.FileMode
modtime time.Time
readDirCount int64
}
func MemFileCreate(name string) *InMemoryFile {
@ -51,6 +52,7 @@ func MemFileCreate(name string) *InMemoryFile {
func (f *InMemoryFile) Open() error {
atomic.StoreInt64(&f.at, 0)
atomic.StoreInt64(&f.readDirCount, 0)
f.Lock()
f.closed = false
f.Unlock()
@ -58,7 +60,6 @@ func (f *InMemoryFile) Open() error {
}
func (f *InMemoryFile) Close() error {
atomic.StoreInt64(&f.at, 0)
f.Lock()
f.closed = true
f.Unlock()
@ -74,29 +75,31 @@ func (f *InMemoryFile) Stat() (os.FileInfo, error) {
}
func (f *InMemoryFile) Readdir(count int) (res []os.FileInfo, err error) {
files := f.memDir.Files()
limit := len(files)
if len(files) == 0 {
return
}
var outLength int64
f.Lock()
files := f.memDir.Files()[f.readDirCount:]
if count > 0 {
limit = count
if len(files) < count {
outLength = int64(len(files))
} else {
outLength = int64(count)
}
if len(files) == 0 {
err = io.EOF
}
} else {
outLength = int64(len(files))
}
f.readDirCount += outLength
f.Unlock()
res = make([]os.FileInfo, outLength)
for i := range res {
res[i], _ = files[i].Stat()
}
if len(files) < limit {
err = io.EOF
}
res = make([]os.FileInfo, f.memDir.Len())
i := 0
for _, file := range f.memDir.Files() {
res[i], _ = file.Stat()
i++
}
return res, nil
return res, err
}
func (f *InMemoryFile) Readdirnames(n int) (names []string, err error) {

View File

@ -20,6 +20,7 @@ import (
"os"
"path"
"path/filepath"
"sort"
"strings"
"sync"
"time"
@ -65,9 +66,17 @@ func (m MemDirMap) Files() (files []File) {
for _, f := range m {
files = append(files, f)
}
sort.Sort(filesSorter(files))
return files
}
type filesSorter []File
// implement sort.Interface for []File
func (s filesSorter) Len() int { return len(s) }
func (s filesSorter) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
func (s filesSorter) Less(i, j int) bool { return s[i].Name() < s[j].Name() }
func (m MemDirMap) Names() (names []string) {
for x := range m {
names = append(names, x)
@ -95,6 +104,9 @@ func (m *MemMapFs) unRegisterWithParent(fileName string) {
return
}
parent := m.findParent(f)
if parent == nil {
log.Fatal("parent of ", f.Name(), " is nil")
}
pmem := parent.(*InMemoryFile)
pmem.memDir.Remove(f)
}
@ -113,11 +125,10 @@ func (m *MemMapFs) registerWithParent(f File) {
if f == nil {
return
}
var err error
parent := m.findParent(f)
if parent == nil {
pdir := filepath.Dir(path.Clean(f.Name()))
err = m.lockfreeMkdir(pdir, 0777)
err := m.lockfreeMkdir(pdir, 0777)
if err != nil {
log.Println("Mkdir error:", err)
return
@ -211,6 +222,10 @@ func (m *MemMapFs) Remove(name string) error {
}
func (m *MemMapFs) RemoveAll(path string) error {
m.lock()
m.unRegisterWithParent(path)
m.unlock()
m.rlock()
defer m.runlock()
@ -218,7 +233,6 @@ func (m *MemMapFs) RemoveAll(path string) error {
if strings.HasPrefix(p, path) {
m.runlock()
m.lock()
m.unRegisterWithParent(p)
delete(m.getData(), p)
m.unlock()
m.rlock()