commit 46e4a3d74846eac124148a35918ad2cd55221a86
parent f7a5e44b45f868ff3e44b8abdbd9896c1a50ade4
Author: Matsuda Kenji <info@mtkn.jp>
Date: Fri, 19 Jan 2024 14:54:12 +0900
update client/fs_test.go
I want to unify fs_test.go and client/fs_test.go
Diffstat:
2 files changed, 82 insertions(+), 5 deletions(-)
diff --git a/client/file.go b/client/file.go
@@ -88,6 +88,12 @@ func (cf *File) Read(b []byte) (int, error) {
}
}
+/*
+func (cf *File) Write([]byte) (int, error) {
+
+}
+*/
+
func (cf *File) ReadDir(n int) ([]fs.DirEntry, error) {
if cf.qid.Type&lib9p.QTDIR == 0 {
return nil, errors.New("not a directory")
diff --git a/client/fs_test.go b/client/fs_test.go
@@ -3,9 +3,11 @@ package client
import (
"bytes"
"fmt"
+ "io"
"io/fs"
"path"
"strings"
+ "time"
"git.mtkn.jp/lib9p"
"git.mtkn.jp/lib9p/testdata"
@@ -26,6 +28,7 @@ type testFile struct {
// when this testFile is read.
// It contains content.
r *bytes.Reader
+ offset int64
// stat is the Stat of this testFile.
stat lib9p.Stat
// closec is used by TestClose to check if *File.Close from the client
@@ -51,7 +54,12 @@ func (f *testFile) Read(b []byte) (int, error) {
f.fsys.waitc <- struct{}{}
<-f.fsys.waitc
}
- return f.r.Read(b)
+ if f.r == nil {
+ f.r = bytes.NewReader(f.content)
+ }
+ n, err := f.r.ReadAt(b, f.offset)
+ f.offset += int64(n)
+ return n, err
}
func (f *testFile) ReadAt(b []byte, off int64) (n int, err error) {
@@ -59,6 +67,7 @@ func (f *testFile) ReadAt(b []byte, off int64) (n int, err error) {
f.fsys.waitc <- struct{}{}
<-f.fsys.waitc
}
+ // ReadAt shoul not affect nor be affected by the underlying seek offset.
return f.r.ReadAt(b, off)
}
@@ -75,9 +84,6 @@ func (f *testFile) WriteAt(p []byte, off int64) (int, error) {
if f.fsys.slow {
f.fsys.waitc <- struct{}{}
}
- if f.r == nil {
- return 0, fmt.Errorf("not open")
- }
if off < 0 || off > int64(len(f.content)) {
return 0, fmt.Errorf("bad offset")
}
@@ -87,13 +93,21 @@ func (f *testFile) WriteAt(p []byte, off int64) (int, error) {
f.content = newcon
}
copy(f.content[off:], p)
- f.r.Reset(f.content)
+ if f.r != nil {
+ f.r.Reset(f.content)
+ f.r.Seek(f.offset, io.SeekStart)
+ }
if f.fsys.slow {
<-f.fsys.waitc
}
return len(p), nil
}
+func (f *testFile) WStat(stat *lib9p.Stat) error {
+ f.stat = *stat
+ return nil
+}
+
type testFS struct {
// root is the root testFile of this file system.
root *testFile
@@ -138,6 +152,63 @@ func (fs *testFS) IsGroupMember(gid, uid string) bool {
return g.members[uid]
}
+// Permission check is intentionally skipped.
+func (fs *testFS) Create(name string, uid string, mode lib9p.OpenMode, perm lib9p.FileMode) (lib9p.File, error) {
+ dirname, filename := path.Split(name)
+ if dirname == "" && (filename == "." || filename == "") {
+ return nil, fmt.Errorf("cant create root")
+ }
+ dir, err := fs.walkPath(path.Dir(dirname))
+ if err != nil {
+ return nil, fmt.Errorf("not found")
+ }
+ for _, c := range dir.children {
+ if c.stat.Name == filename {
+ return nil, fmt.Errorf("file already exists")
+ }
+ }
+ f := &testFile{
+ fsys: fs,
+ parent: dir,
+ stat: lib9p.Stat{
+ Qid: lib9p.Qid{
+ Type: lib9p.FSModeToQidType(perm),
+ Path: fs.nextQid,
+ },
+ Mode: perm,
+ Atime: uint32(time.Now().Unix()),
+ Mtime: uint32(time.Now().Unix()),
+ Name: filename,
+ Uid: uid,
+ Gid: dir.stat.Gid,
+ Muid: uid,
+ },
+ }
+ fs.nextQid++
+ dir.children = append(dir.children, f)
+ return f, nil
+}
+
+func (fs *testFS) Remove(name string) error {
+ ds, filename := path.Split(name)
+ dirname := path.Dir(ds)
+ dir, err := fs.walkPath(dirname)
+ if err != nil {
+ return fmt.Errorf("not found")
+ }
+ for i, c := range dir.children {
+ if c.stat.Name == filename {
+ if len(c.children) != 0 {
+ return fmt.Errorf("directory not empty")
+ }
+ dir.children = append(dir.children[:i], dir.children[i+1:]...)
+ // TODO: should close the file?
+ return nil
+ }
+ }
+ return fmt.Errorf("not found")
+}
+
func (fs *testFS) walk(wnames []string) (*testFile, error) {
if len(wnames) == 1 && (wnames[0] == "." || wnames[0] == "") {
return fs.root, nil