lib/fs, lib/model: Rewrite RecvOnly tests (#6318)

During some other work I discovered these tests weren't great, so I've
rewritten them to be a little better. The real changes here are:

- Don't play games with not starting the folder and such, and don't
  construct a fake folder instance -- just use the one the model has. The
  folder starts and scans but the folder contents are empty at this point
  so that's fine.

- Use a fakefs instead of a temp dir.

- To support the above, implement a fakefs option `?content=true` to
  make the fakefs actually retain written content. Use sparingly,
  obviously, but it means the fakefs can usually be used instead of an
  on disk real directory.
This commit is contained in:
Jakob Borg
2020-02-12 07:47:05 +01:00
committed by GitHub
parent b84aa114be
commit 0df39ddc72
4 changed files with 123 additions and 60 deletions
+37 -6
View File
@@ -52,9 +52,10 @@ const randomBlockShift = 14 // 128k
// - Two fakefs:s pointing at the same root path see the same files.
//
type fakefs struct {
mut sync.Mutex
root *fakeEntry
insens bool
mut sync.Mutex
root *fakeEntry
insens bool
withContent bool
}
var (
@@ -93,9 +94,9 @@ func newFakeFilesystem(root string) *fakefs {
sizeavg, _ := strconv.Atoi(params.Get("sizeavg"))
seed, _ := strconv.Atoi(params.Get("seed"))
if params.Get("insens") == "true" {
fs.insens = true
}
fs.insens = params.Get("insens") == "true"
fs.withContent = params.Get("content") == "true"
if sizeavg == 0 {
sizeavg = 1 << 20
}
@@ -151,6 +152,7 @@ type fakeEntry struct {
gid int
mtime time.Time
children map[string]*fakeEntry
content []byte
}
func (fs *fakefs) entryForName(name string) *fakeEntry {
@@ -227,6 +229,10 @@ func (fs *fakefs) create(name string) (*fakeEntry, error) {
entry.size = 0
entry.mtime = time.Now()
entry.mode = 0666
entry.content = nil
if fs.withContent {
entry.content = make([]byte, 0)
}
return entry, nil
}
@@ -246,6 +252,10 @@ func (fs *fakefs) create(name string) (*fakeEntry, error) {
base = UnicodeLowercase(base)
}
if fs.withContent {
new.content = make([]byte, 0)
}
entry.children[base] = new
return new, nil
}
@@ -417,6 +427,9 @@ func (fs *fakefs) OpenFile(name string, flags int, mode FileMode) (File, error)
mode: mode,
mtime: time.Now(),
}
if fs.withContent {
newEntry.content = make([]byte, 0)
}
entry.children[key] = newEntry
return &fakeFile{fakeEntry: newEntry}, nil
@@ -660,6 +673,12 @@ func (f *fakeFile) readShortAt(p []byte, offs int64) (int, error) {
return 0, io.EOF
}
if f.content != nil {
n := copy(p, f.content[int(offs):])
f.offset = offs + int64(n)
return n, nil
}
// Lazily calculate our main seed, a simple 64 bit FNV hash our file
// name.
if f.seed == 0 {
@@ -746,6 +765,15 @@ func (f *fakeFile) WriteAt(p []byte, off int64) (int, error) {
return 0, errors.New("is a directory")
}
if f.content != nil {
if len(f.content) < int(off)+len(p) {
newc := make([]byte, int(off)+len(p))
copy(newc, f.content)
f.content = newc
}
copy(f.content[int(off):], p)
}
f.rng = nil
f.offset = off + int64(len(p))
if f.offset > f.size {
@@ -765,6 +793,9 @@ func (f *fakeFile) Truncate(size int64) error {
f.mut.Lock()
defer f.mut.Unlock()
if f.content != nil {
f.content = f.content[:int(size)]
}
f.rng = nil
f.size = size
if f.offset > size {
+29
View File
@@ -896,6 +896,35 @@ func testFakeFSCreateInsens(t *testing.T, fs Filesystem) {
assertDir(t, fs, "/", []string{"FOO"})
}
func TestReadWriteContent(t *testing.T) {
fs := newFakeFilesystem("foo?content=true")
fd, err := fs.Create("file")
if err != nil {
t.Fatal(err)
}
if _, err := fd.Write([]byte("foo")); err != nil {
t.Fatal(err)
}
if _, err := fd.WriteAt([]byte("bar"), 5); err != nil {
t.Fatal(err)
}
expected := []byte("foo\x00\x00bar")
buf := make([]byte, len(expected)-1)
n, err := fd.ReadAt(buf, 1) // note offset one byte
if err != nil {
t.Fatal(err)
}
if n != len(expected)-1 {
t.Fatal("wrong number of bytes read")
}
if !bytes.Equal(buf[:n], expected[1:]) {
fmt.Printf("%d %q\n", n, buf[:n])
t.Error("wrong data in file")
}
}
func cleanup(fs Filesystem) error {
filenames, _ := fs.DirNames("/")
for _, filename := range filenames {