Beispiel #1
0
// Create and mount filesystem.
func NewTestCase(t *testing.T) *testCase {
	tc := &testCase{}
	tc.tester = t

	// Make sure system setting does not affect test.
	syscall.Umask(0)

	const name string = "hello.txt"
	const subdir string = "subdir"

	var err error
	tc.tmpDir, err = ioutil.TempDir("", "go-fuse")
	if err != nil {
		t.Fatalf("TempDir failed: %v", err)
	}
	tc.orig = tc.tmpDir + "/orig"
	tc.mnt = tc.tmpDir + "/mnt"

	tc.Mkdir(tc.orig, 0700)
	tc.Mkdir(tc.mnt, 0700)

	tc.mountFile = filepath.Join(tc.mnt, name)
	tc.mountSubdir = filepath.Join(tc.mnt, subdir)
	tc.origFile = filepath.Join(tc.orig, name)
	tc.origSubdir = filepath.Join(tc.orig, subdir)

	var pfs pathfs.FileSystem
	pfs = pathfs.NewLoopbackFileSystem(tc.orig)
	pfs = pathfs.NewLockingFileSystem(pfs)

	tc.pathFs = pathfs.NewPathNodeFs(pfs, &pathfs.PathNodeFsOptions{
		ClientInodes: true})
	tc.connector = nodefs.NewFileSystemConnector(tc.pathFs.Root(),
		&nodefs.Options{
			EntryTimeout:    testTtl,
			AttrTimeout:     testTtl,
			NegativeTimeout: 0.0,
			Debug:           VerboseTest(),
		})
	tc.state, err = fuse.NewServer(
		fuse.NewRawFileSystem(tc.connector.RawFS()), tc.mnt, &fuse.MountOptions{
			SingleThreaded: true,
			Debug:          VerboseTest(),
		})
	if err != nil {
		t.Fatal("NewServer:", err)
	}

	go tc.state.Serve()
	if err := tc.state.WaitMount(); err != nil {
		t.Fatal("WaitMount", err)
	}
	return tc
}
Beispiel #2
0
// Create and mount filesystem.
func NewTestCase(t *testing.T) *testCase {
	me := &testCase{}
	me.tester = t

	// Make sure system setting does not affect test.
	syscall.Umask(0)

	const name string = "hello.txt"
	const subdir string = "subdir"

	var err error
	me.tmpDir, err = ioutil.TempDir("", "go-fuse")
	if err != nil {
		t.Fatalf("TempDir failed: %v", err)
	}
	me.orig = me.tmpDir + "/orig"
	me.mnt = me.tmpDir + "/mnt"

	os.Mkdir(me.orig, 0700)
	os.Mkdir(me.mnt, 0700)

	me.mountFile = filepath.Join(me.mnt, name)
	me.mountSubdir = filepath.Join(me.mnt, subdir)
	me.origFile = filepath.Join(me.orig, name)
	me.origSubdir = filepath.Join(me.orig, subdir)

	var pfs pathfs.FileSystem
	pfs = pathfs.NewLoopbackFileSystem(me.orig)
	pfs = pathfs.NewLockingFileSystem(pfs)

	me.pathFs = pathfs.NewPathNodeFs(pfs, &pathfs.PathNodeFsOptions{
		ClientInodes: true})
	me.connector = nodefs.NewFileSystemConnector(me.pathFs.Root(),
		&nodefs.Options{
			EntryTimeout:    testTtl,
			AttrTimeout:     testTtl,
			NegativeTimeout: 0.0,
		})
	me.connector.SetDebug(VerboseTest())
	me.state, err = fuse.NewServer(
		fuse.NewRawFileSystem(me.connector.RawFS()), me.mnt, &fuse.MountOptions{SingleThreaded: true})
	if err != nil {
		t.Fatal("NewServer:", err)
	}

	me.state.SetDebug(VerboseTest())

	// Unthreaded, but in background.
	go me.state.Serve()

	me.state.WaitMount()
	return me
}
Beispiel #3
0
func TestFSetAttr(t *testing.T) {
	fSetAttrFs := &FSetAttrFs{
		FileSystem: pathfs.NewDefaultFileSystem(),
	}
	fs := pathfs.NewLockingFileSystem(fSetAttrFs)
	dir, clean := setupFAttrTest(t, fs)
	defer func() {
		if clean != nil {
			clean()
		}
	}()

	fn := dir + "/file"
	f, err := os.OpenFile(fn, os.O_CREATE|os.O_WRONLY, 0755)

	if err != nil {
		t.Fatalf("OpenFile failed: %v", err)
	}
	defer f.Close()
	fi, err := f.Stat()
	if err != nil {
		t.Fatalf("Stat failed: %v", err)
	}

	_, err = f.WriteString("hello")
	if err != nil {
		t.Fatalf("WriteString failed: %v", err)
	}

	code := syscall.Ftruncate(int(f.Fd()), 3)
	if code != nil {
		t.Error("truncate retval", os.NewSyscallError("Ftruncate", code))
	}

	if a, status := fs.GetAttr("file", nil); !status.Ok() {
		t.Fatalf("GetAttr: status %v", status)
	} else if a.Size != 3 {
		t.Errorf("truncate: size %d, status %v", a.Size, status)
	}

	if err := f.Chmod(024); err != nil {
		t.Fatalf("Chmod failed: %v", err)
	}

	if a, status := fs.GetAttr("file", nil); !status.Ok() {
		t.Errorf("chmod: %v", status)
	} else if a.Mode&07777 != 024 {
		t.Errorf("getattr after chmod: %o", a.Mode&0777)
	}

	if err := os.Chtimes(fn, time.Unix(0, 100e3), time.Unix(0, 101e3)); err != nil {
		t.Fatalf("Chtimes failed: %v", err)
	}

	if a, status := fs.GetAttr("file", nil); !status.Ok() {
		t.Errorf("GetAttr: %v", status)
	} else if a.Atimensec != 100e3 || a.Mtimensec != 101e3 {
		t.Errorf("Utimens: atime %d != 100e3 mtime %d != 101e3",
			a.Atimensec, a.Mtimensec)
	}

	newFi, err := f.Stat()
	if err != nil {
		t.Fatalf("Stat failed: %v", err)
	}
	i1 := fuse.ToStatT(fi).Ino
	i2 := fuse.ToStatT(newFi).Ino
	if i1 != i2 {
		t.Errorf("f.Lstat().Ino = %d. Returned %d before.", i2, i1)
	}

	if code := syscall.Fsync(int(f.Fd())); code != nil {
		t.Error("Fsync failed:", os.NewSyscallError("Fsync", code))
	}

	// Close the file, otherwise we can't unmount.
	f.Close()

	// Shutdown the FUSE FS so we can safely look at fSetAttrFs
	clean()
	clean = nil
	if !fSetAttrFs.file.FsyncCalled {
		t.Error("Fsync was not called")
	}
}
Beispiel #4
0
func TestUnionFsDisappearing(t *testing.T) {
	// This init is like setupUfs, but we want access to the
	// writable Fs.
	wd, _ := ioutil.TempDir("", "")
	defer os.RemoveAll(wd)
	err := os.Mkdir(wd+"/mnt", 0700)
	if err != nil {
		t.Fatalf("Mkdir failed: %v", err)
	}

	err = os.Mkdir(wd+"/rw", 0700)
	if err != nil {
		t.Fatalf("Mkdir failed: %v", err)
	}

	os.Mkdir(wd+"/ro", 0700)
	if err != nil {
		t.Fatalf("Mkdir failed: %v", err)
	}

	wrFs := newDisappearingFS(pathfs.NewLoopbackFileSystem(wd+"/rw"),
		pathfs.NewLoopbackFileSystem("/dev/null"))
	var fses []pathfs.FileSystem
	fses = append(fses, pathfs.NewLockingFileSystem(wrFs))
	fses = append(fses, pathfs.NewLoopbackFileSystem(wd+"/ro"))
	ufs, err := NewUnionFs(fses, testOpts)
	if err != nil {
		t.Fatalf("NewUnionFs: %v", err)
	}

	opts := &nodefs.Options{
		EntryTimeout:    entryTtl,
		AttrTimeout:     entryTtl,
		NegativeTimeout: entryTtl,
	}

	nfs := pathfs.NewPathNodeFs(ufs, nil)
	state, _, err := nodefs.MountRoot(wd+"/mnt", nfs.Root(), opts)
	if err != nil {
		t.Fatalf("MountNodeFileSystem failed: %v", err)
	}
	defer state.Unmount()
	state.SetDebug(VerboseTest())
	go state.Serve()

	err = ioutil.WriteFile(wd+"/ro/file", []byte("blabla"), 0644)
	if err != nil {
		t.Fatalf("WriteFile failed: %v", err)
	}
	setRecursiveWritable(t, wd+"/ro", false)

	err = os.Remove(wd + "/mnt/file")
	if err != nil {
		t.Fatalf("Remove failed: %v", err)
	}

	wrFs.visibleChan <- false
	time.Sleep((3 * entryTtl) / 2)

	_, err = ioutil.ReadDir(wd + "/mnt")
	if err == nil {
		t.Fatal("Readdir should have failed")
	}

	err = ioutil.WriteFile(wd+"/mnt/file2", []byte("blabla"), 0644)
	if err == nil {
		t.Fatal("write should have failed")
	}

	// Restore, and wait for caches to catch up.
	wrFs.visibleChan <- true
	time.Sleep((3 * entryTtl) / 2)

	_, err = ioutil.ReadDir(wd + "/mnt")
	if err != nil {
		t.Fatal("Readdir should succeed", err)
	}
	err = ioutil.WriteFile(wd+"/mnt/file2", []byte("blabla"), 0644)
	if err != nil {
		t.Fatal("write should succeed", err)
	}
}
Beispiel #5
0
func TestFSetAttr(t *testing.T) {
	fs := pathfs.NewLockingFileSystem(&FSetAttrFs{
		FileSystem: pathfs.NewDefaultFileSystem(),
	})
	dir, clean := setupFAttrTest(t, fs)
	defer clean()

	fn := dir + "/file"
	f, err := os.OpenFile(fn, os.O_CREATE|os.O_WRONLY, 0755)

	if err != nil {
		t.Fatalf("OpenFile failed: %v", err)
	}
	defer f.Close()
	fi, err := f.Stat()
	if err != nil {
		t.Fatalf("Stat failed: %v", err)
	}

	_, err = f.WriteString("hello")
	if err != nil {
		t.Fatalf("WriteString failed: %v", err)
	}

	code := syscall.Ftruncate(int(f.Fd()), 3)
	if code != nil {
		t.Error("truncate retval", os.NewSyscallError("Ftruncate", code))
	}

	if a, status := fs.GetAttr("file", nil); !status.Ok() {
		t.Fatalf("GetAttr: status %v", status)
	} else if a.Size != 3 {
		t.Errorf("truncate: size %d, status %v", a.Size, status)
	}

	if err := f.Chmod(024); err != nil {
		t.Fatalf("Chmod failed: %v", err)
	}

	if a, status := fs.GetAttr("file", nil); !status.Ok() {
		t.Errorf("chmod: %v", status)
	} else if a.Mode&07777 != 024 {
		t.Errorf("getattr after chmod: %o", a.Mode&0777)
	}

	if err := os.Chtimes(fn, time.Unix(0, 100e3), time.Unix(0, 101e3)); err != nil {
		t.Fatalf("Chtimes failed: %v", err)
	}

	if a, status := fs.GetAttr("file", nil); !status.Ok() {
		t.Errorf("GetAttr: %v", status)
	} else if a.Atimensec != 100e3 || a.Mtimensec != 101e3 {
		t.Errorf("Utimens: atime %d != 100e3 mtime %d != 101e3",
			a.Atimensec, a.Mtimensec)
	}

	newFi, err := f.Stat()
	if err != nil {
		t.Fatalf("Stat failed: %v", err)
	}
	i1 := fuse.ToStatT(fi).Ino
	i2 := fuse.ToStatT(newFi).Ino
	if i1 != i2 {
		t.Errorf("f.Lstat().Ino = %d. Returned %d before.", i2, i1)
	}
	// TODO - test chown if run as root.
}