Stop using a clock for memfs mtimes.
We can't do this now that the kernel chooses mtimes and sends setattr requests due to our use of writeback caching.geesefs-0-30-9
commit
373004db87
|
@ -28,28 +28,32 @@ import (
|
|||
// also that it matches.
|
||||
func MtimeIs(expected time.Time) oglematchers.Matcher {
|
||||
return oglematchers.NewMatcher(
|
||||
func(c interface{}) error { return mtimeIs(c, expected) },
|
||||
func(c interface{}) error { return mtimeIsWithin(c, expected, 0) },
|
||||
fmt.Sprintf("mtime is %v", expected))
|
||||
}
|
||||
|
||||
func mtimeIs(c interface{}, expected time.Time) error {
|
||||
// Like MtimeIs, but allows for a tolerance.
|
||||
func MtimeIsWithin(expected time.Time, d time.Duration) oglematchers.Matcher {
|
||||
return oglematchers.NewMatcher(
|
||||
func(c interface{}) error { return mtimeIsWithin(c, expected, d) },
|
||||
fmt.Sprintf("mtime is within %v of %v", d, expected))
|
||||
}
|
||||
|
||||
func mtimeIsWithin(c interface{}, expected time.Time, d time.Duration) error {
|
||||
fi, ok := c.(os.FileInfo)
|
||||
if !ok {
|
||||
return fmt.Errorf("which is of type %v", reflect.TypeOf(c))
|
||||
}
|
||||
|
||||
// Check ModTime().
|
||||
if fi.ModTime() != expected {
|
||||
d := fi.ModTime().Sub(expected)
|
||||
return fmt.Errorf("which has mtime %v, off by %v", fi.ModTime(), d)
|
||||
diff := fi.ModTime().Sub(expected)
|
||||
absDiff := diff
|
||||
if absDiff < 0 {
|
||||
absDiff = -absDiff
|
||||
}
|
||||
|
||||
// Check Sys().
|
||||
if sysMtime, ok := extractMtime(fi.Sys()); ok {
|
||||
if sysMtime != expected {
|
||||
d := sysMtime.Sub(expected)
|
||||
return fmt.Errorf("which has Sys() mtime %v, off by %v", sysMtime, d)
|
||||
}
|
||||
if !(absDiff < d) {
|
||||
return fmt.Errorf("which has mtime %v, off by %v", fi.ModTime(), diff)
|
||||
}
|
||||
|
||||
return nil
|
||||
|
|
|
@ -22,19 +22,12 @@ import (
|
|||
|
||||
"github.com/jacobsa/fuse/fuseops"
|
||||
"github.com/jacobsa/fuse/fuseutil"
|
||||
"github.com/jacobsa/timeutil"
|
||||
)
|
||||
|
||||
// Common attributes for files and directories.
|
||||
//
|
||||
// External synchronization is required.
|
||||
type inode struct {
|
||||
/////////////////////////
|
||||
// Dependencies
|
||||
/////////////////////////
|
||||
|
||||
clock timeutil.Clock
|
||||
|
||||
/////////////////////////
|
||||
// Mutable state
|
||||
/////////////////////////
|
||||
|
@ -79,16 +72,14 @@ type inode struct {
|
|||
// Create a new inode with the supplied attributes, which need not contain
|
||||
// time-related information (the inode object will take care of that).
|
||||
func newInode(
|
||||
clock timeutil.Clock,
|
||||
attrs fuseops.InodeAttributes) (in *inode) {
|
||||
// Update time info.
|
||||
now := clock.Now()
|
||||
now := time.Now()
|
||||
attrs.Mtime = now
|
||||
attrs.Crtime = now
|
||||
|
||||
// Create the object.
|
||||
in = &inode{
|
||||
clock: clock,
|
||||
attrs: attrs,
|
||||
}
|
||||
|
||||
|
@ -226,7 +217,7 @@ func (in *inode) AddChild(
|
|||
var index int
|
||||
|
||||
// Update the modification time.
|
||||
in.attrs.Mtime = in.clock.Now()
|
||||
in.attrs.Mtime = time.Now()
|
||||
|
||||
// No matter where we place the entry, make sure it has the correct Offset
|
||||
// field.
|
||||
|
@ -260,7 +251,7 @@ func (in *inode) AddChild(
|
|||
// REQUIRES: An entry for the given name exists.
|
||||
func (in *inode) RemoveChild(name string) {
|
||||
// Update the modification time.
|
||||
in.attrs.Mtime = in.clock.Now()
|
||||
in.attrs.Mtime = time.Now()
|
||||
|
||||
// Find the entry.
|
||||
i, ok := in.findChild(name)
|
||||
|
@ -334,7 +325,7 @@ func (in *inode) WriteAt(p []byte, off int64) (n int, err error) {
|
|||
}
|
||||
|
||||
// Update the modification time.
|
||||
in.attrs.Mtime = in.clock.Now()
|
||||
in.attrs.Mtime = time.Now()
|
||||
|
||||
// Ensure that the contents slice is long enough.
|
||||
newLen := int(off) + len(p)
|
||||
|
@ -361,7 +352,7 @@ func (in *inode) SetAttributes(
|
|||
mode *os.FileMode,
|
||||
mtime *time.Time) {
|
||||
// Update the modification time.
|
||||
in.attrs.Mtime = in.clock.Now()
|
||||
in.attrs.Mtime = time.Now()
|
||||
|
||||
// Truncate?
|
||||
if size != nil {
|
||||
|
|
|
@ -26,7 +26,6 @@ import (
|
|||
"github.com/jacobsa/fuse/fuseops"
|
||||
"github.com/jacobsa/fuse/fuseutil"
|
||||
"github.com/jacobsa/syncutil"
|
||||
"github.com/jacobsa/timeutil"
|
||||
)
|
||||
|
||||
type memFS struct {
|
||||
|
@ -36,12 +35,6 @@ type memFS struct {
|
|||
uid uint32
|
||||
gid uint32
|
||||
|
||||
/////////////////////////
|
||||
// Dependencies
|
||||
/////////////////////////
|
||||
|
||||
clock timeutil.Clock
|
||||
|
||||
/////////////////////////
|
||||
// Mutable state
|
||||
/////////////////////////
|
||||
|
@ -74,11 +67,9 @@ type memFS struct {
|
|||
// default_permissions option.
|
||||
func NewMemFS(
|
||||
uid uint32,
|
||||
gid uint32,
|
||||
clock timeutil.Clock) fuse.Server {
|
||||
gid uint32) fuse.Server {
|
||||
// Set up the basic struct.
|
||||
fs := &memFS{
|
||||
clock: clock,
|
||||
inodes: make([]*inode, fuseops.RootInodeID+1),
|
||||
uid: uid,
|
||||
gid: gid,
|
||||
|
@ -91,7 +82,7 @@ func NewMemFS(
|
|||
Gid: gid,
|
||||
}
|
||||
|
||||
fs.inodes[fuseops.RootInodeID] = newInode(clock, rootAttrs)
|
||||
fs.inodes[fuseops.RootInodeID] = newInode(rootAttrs)
|
||||
|
||||
// Set up invariant checking.
|
||||
fs.mu = syncutil.NewInvariantMutex(fs.checkInvariants)
|
||||
|
@ -165,7 +156,7 @@ func (fs *memFS) getInodeOrDie(id fuseops.InodeID) (inode *inode) {
|
|||
func (fs *memFS) allocateInode(
|
||||
attrs fuseops.InodeAttributes) (id fuseops.InodeID, inode *inode) {
|
||||
// Create the inode.
|
||||
inode = newInode(fs.clock, attrs)
|
||||
inode = newInode(attrs)
|
||||
|
||||
// Re-use a free ID if possible. Otherwise mint a new one.
|
||||
numFree := len(fs.freeInodes)
|
||||
|
@ -216,7 +207,7 @@ func (fs *memFS) LookUpInode(
|
|||
|
||||
// We don't spontaneously mutate, so the kernel can cache as long as it wants
|
||||
// (since it also handles invalidation).
|
||||
op.Entry.AttributesExpiration = fs.clock.Now().Add(365 * 24 * time.Hour)
|
||||
op.Entry.AttributesExpiration = time.Now().Add(365 * 24 * time.Hour)
|
||||
op.Entry.EntryExpiration = op.Entry.EntryExpiration
|
||||
|
||||
return
|
||||
|
@ -236,7 +227,7 @@ func (fs *memFS) GetInodeAttributes(
|
|||
|
||||
// We don't spontaneously mutate, so the kernel can cache as long as it wants
|
||||
// (since it also handles invalidation).
|
||||
op.AttributesExpiration = fs.clock.Now().Add(365 * 24 * time.Hour)
|
||||
op.AttributesExpiration = time.Now().Add(365 * 24 * time.Hour)
|
||||
|
||||
return
|
||||
}
|
||||
|
@ -258,7 +249,7 @@ func (fs *memFS) SetInodeAttributes(
|
|||
|
||||
// We don't spontaneously mutate, so the kernel can cache as long as it wants
|
||||
// (since it also handles invalidation).
|
||||
op.AttributesExpiration = fs.clock.Now().Add(365 * 24 * time.Hour)
|
||||
op.AttributesExpiration = time.Now().Add(365 * 24 * time.Hour)
|
||||
|
||||
return
|
||||
}
|
||||
|
@ -300,7 +291,7 @@ func (fs *memFS) MkDir(
|
|||
|
||||
// We don't spontaneously mutate, so the kernel can cache as long as it wants
|
||||
// (since it also handles invalidation).
|
||||
op.Entry.AttributesExpiration = fs.clock.Now().Add(365 * 24 * time.Hour)
|
||||
op.Entry.AttributesExpiration = time.Now().Add(365 * 24 * time.Hour)
|
||||
op.Entry.EntryExpiration = op.Entry.EntryExpiration
|
||||
|
||||
return
|
||||
|
@ -324,7 +315,7 @@ func (fs *memFS) CreateFile(
|
|||
}
|
||||
|
||||
// Set up attributes from the child.
|
||||
now := fs.clock.Now()
|
||||
now := time.Now()
|
||||
childAttrs := fuseops.InodeAttributes{
|
||||
Nlink: 1,
|
||||
Mode: op.Mode,
|
||||
|
@ -348,7 +339,7 @@ func (fs *memFS) CreateFile(
|
|||
|
||||
// We don't spontaneously mutate, so the kernel can cache as long as it wants
|
||||
// (since it also handles invalidation).
|
||||
op.Entry.AttributesExpiration = fs.clock.Now().Add(365 * 24 * time.Hour)
|
||||
op.Entry.AttributesExpiration = time.Now().Add(365 * 24 * time.Hour)
|
||||
op.Entry.EntryExpiration = op.Entry.EntryExpiration
|
||||
|
||||
// We have nothing interesting to put in the Handle field.
|
||||
|
@ -374,7 +365,7 @@ func (fs *memFS) CreateSymlink(
|
|||
}
|
||||
|
||||
// Set up attributes from the child.
|
||||
now := fs.clock.Now()
|
||||
now := time.Now()
|
||||
childAttrs := fuseops.InodeAttributes{
|
||||
Nlink: 1,
|
||||
Mode: 0444 | os.ModeSymlink,
|
||||
|
@ -401,7 +392,7 @@ func (fs *memFS) CreateSymlink(
|
|||
|
||||
// We don't spontaneously mutate, so the kernel can cache as long as it wants
|
||||
// (since it also handles invalidation).
|
||||
op.Entry.AttributesExpiration = fs.clock.Now().Add(365 * 24 * time.Hour)
|
||||
op.Entry.AttributesExpiration = time.Now().Add(365 * 24 * time.Hour)
|
||||
op.Entry.EntryExpiration = op.Entry.EntryExpiration
|
||||
|
||||
return
|
||||
|
|
|
@ -35,6 +35,11 @@ import (
|
|||
|
||||
func TestMemFS(t *testing.T) { RunTests(t) }
|
||||
|
||||
// The radius we use for "expect mtime is within"-style assertions. We can't
|
||||
// share a synchronized clock with the ultimate source of mtimes because with
|
||||
// writeback caching enabled the kernel manufactures them based on wall time.
|
||||
const timeSlop = 5 * time.Millisecond
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// Helpers
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
@ -89,7 +94,7 @@ type MemFSTest struct {
|
|||
func init() { RegisterTestSuite(&MemFSTest{}) }
|
||||
|
||||
func (t *MemFSTest) SetUp(ti *TestInfo) {
|
||||
t.Server = memfs.NewMemFS(currentUid(), currentGid(), &t.Clock)
|
||||
t.Server = memfs.NewMemFS(currentUid(), currentGid())
|
||||
t.SampleTest.SetUp(ti)
|
||||
}
|
||||
|
||||
|
@ -112,17 +117,11 @@ func (t *MemFSTest) Mkdir_OneLevel() {
|
|||
|
||||
dirName := path.Join(t.Dir, "dir")
|
||||
|
||||
// Simulate time advancing.
|
||||
t.Clock.AdvanceTime(time.Second)
|
||||
|
||||
// Create a directory within the root.
|
||||
createTime := t.Clock.Now()
|
||||
createTime := time.Now()
|
||||
err = os.Mkdir(dirName, 0754)
|
||||
AssertEq(nil, err)
|
||||
|
||||
// Simulate time advancing.
|
||||
t.Clock.AdvanceTime(time.Second)
|
||||
|
||||
// Stat the directory.
|
||||
fi, err = os.Stat(dirName)
|
||||
stat = fi.Sys().(*syscall.Stat_t)
|
||||
|
@ -131,7 +130,7 @@ func (t *MemFSTest) Mkdir_OneLevel() {
|
|||
ExpectEq("dir", fi.Name())
|
||||
ExpectEq(0, fi.Size())
|
||||
ExpectEq(os.ModeDir|applyUmask(0754), fi.Mode())
|
||||
ExpectThat(fi, fusetesting.MtimeIs(createTime))
|
||||
ExpectThat(fi, fusetesting.MtimeIsWithin(createTime, timeSlop))
|
||||
ExpectThat(fi, fusetesting.BirthtimeIs(createTime))
|
||||
ExpectTrue(fi.IsDir())
|
||||
|
||||
|
@ -145,7 +144,7 @@ func (t *MemFSTest) Mkdir_OneLevel() {
|
|||
fi, err = os.Stat(t.Dir)
|
||||
|
||||
AssertEq(nil, err)
|
||||
ExpectEq(0, fi.ModTime().Sub(createTime))
|
||||
ExpectThat(fi, fusetesting.MtimeIsWithin(createTime, timeSlop))
|
||||
|
||||
// Read the directory.
|
||||
entries, err = fusetesting.ReadDirPicky(dirName)
|
||||
|
@ -174,17 +173,11 @@ func (t *MemFSTest) Mkdir_TwoLevels() {
|
|||
err = os.Mkdir(path.Join(t.Dir, "parent"), 0700)
|
||||
AssertEq(nil, err)
|
||||
|
||||
// Simulate time advancing.
|
||||
t.Clock.AdvanceTime(time.Second)
|
||||
|
||||
// Create a child of that directory.
|
||||
createTime := t.Clock.Now()
|
||||
createTime := time.Now()
|
||||
err = os.Mkdir(path.Join(t.Dir, "parent/dir"), 0754)
|
||||
AssertEq(nil, err)
|
||||
|
||||
// Simulate time advancing.
|
||||
t.Clock.AdvanceTime(time.Second)
|
||||
|
||||
// Stat the directory.
|
||||
fi, err = os.Stat(path.Join(t.Dir, "parent/dir"))
|
||||
stat = fi.Sys().(*syscall.Stat_t)
|
||||
|
@ -193,7 +186,7 @@ func (t *MemFSTest) Mkdir_TwoLevels() {
|
|||
ExpectEq("dir", fi.Name())
|
||||
ExpectEq(0, fi.Size())
|
||||
ExpectEq(os.ModeDir|applyUmask(0754), fi.Mode())
|
||||
ExpectThat(fi, fusetesting.MtimeIs(createTime))
|
||||
ExpectThat(fi, fusetesting.MtimeIsWithin(createTime, timeSlop))
|
||||
ExpectThat(fi, fusetesting.BirthtimeIs(createTime))
|
||||
ExpectTrue(fi.IsDir())
|
||||
|
||||
|
@ -206,7 +199,7 @@ func (t *MemFSTest) Mkdir_TwoLevels() {
|
|||
// Check the parent's mtime.
|
||||
fi, err = os.Stat(path.Join(t.Dir, "parent"))
|
||||
AssertEq(nil, err)
|
||||
ExpectEq(0, fi.ModTime().Sub(createTime))
|
||||
ExpectThat(fi, fusetesting.MtimeIsWithin(createTime, timeSlop))
|
||||
|
||||
// Read the directory.
|
||||
entries, err = fusetesting.ReadDirPicky(path.Join(t.Dir, "parent/dir"))
|
||||
|
@ -290,13 +283,10 @@ func (t *MemFSTest) CreateNewFile_InRoot() {
|
|||
fileName := path.Join(t.Dir, "foo")
|
||||
const contents = "Hello\x00world"
|
||||
|
||||
createTime := t.Clock.Now()
|
||||
createTime := time.Now()
|
||||
err = ioutil.WriteFile(fileName, []byte(contents), 0400)
|
||||
AssertEq(nil, err)
|
||||
|
||||
// Simulate time advancing.
|
||||
t.Clock.AdvanceTime(time.Second)
|
||||
|
||||
// Stat it.
|
||||
fi, err = os.Stat(fileName)
|
||||
stat = fi.Sys().(*syscall.Stat_t)
|
||||
|
@ -305,7 +295,7 @@ func (t *MemFSTest) CreateNewFile_InRoot() {
|
|||
ExpectEq("foo", fi.Name())
|
||||
ExpectEq(len(contents), fi.Size())
|
||||
ExpectEq(applyUmask(0400), fi.Mode())
|
||||
ExpectThat(fi, fusetesting.MtimeIs(createTime))
|
||||
ExpectThat(fi, fusetesting.MtimeIsWithin(createTime, timeSlop))
|
||||
ExpectThat(fi, fusetesting.BirthtimeIs(createTime))
|
||||
ExpectFalse(fi.IsDir())
|
||||
|
||||
|
@ -335,13 +325,10 @@ func (t *MemFSTest) CreateNewFile_InSubDir() {
|
|||
fileName := path.Join(dirName, "foo")
|
||||
const contents = "Hello\x00world"
|
||||
|
||||
createTime := t.Clock.Now()
|
||||
createTime := time.Now()
|
||||
err = ioutil.WriteFile(fileName, []byte(contents), 0400)
|
||||
AssertEq(nil, err)
|
||||
|
||||
// Simulate time advancing.
|
||||
t.Clock.AdvanceTime(time.Second)
|
||||
|
||||
// Stat it.
|
||||
fi, err = os.Stat(fileName)
|
||||
stat = fi.Sys().(*syscall.Stat_t)
|
||||
|
@ -350,7 +337,7 @@ func (t *MemFSTest) CreateNewFile_InSubDir() {
|
|||
ExpectEq("foo", fi.Name())
|
||||
ExpectEq(len(contents), fi.Size())
|
||||
ExpectEq(applyUmask(0400), fi.Mode())
|
||||
ExpectThat(fi, fusetesting.MtimeIs(createTime))
|
||||
ExpectThat(fi, fusetesting.MtimeIsWithin(createTime, timeSlop))
|
||||
ExpectThat(fi, fusetesting.BirthtimeIs(createTime))
|
||||
ExpectFalse(fi.IsDir())
|
||||
|
||||
|
@ -375,26 +362,20 @@ func (t *MemFSTest) ModifyExistingFile_InRoot() {
|
|||
// Write a file.
|
||||
fileName := path.Join(t.Dir, "foo")
|
||||
|
||||
createTime := t.Clock.Now()
|
||||
createTime := time.Now()
|
||||
err = ioutil.WriteFile(fileName, []byte("Hello, world!"), 0600)
|
||||
AssertEq(nil, err)
|
||||
|
||||
// Simulate time advancing.
|
||||
t.Clock.AdvanceTime(time.Second)
|
||||
|
||||
// Open the file and modify it.
|
||||
f, err := os.OpenFile(fileName, os.O_WRONLY, 0400)
|
||||
t.ToClose = append(t.ToClose, f)
|
||||
AssertEq(nil, err)
|
||||
|
||||
modifyTime := t.Clock.Now()
|
||||
modifyTime := time.Now()
|
||||
n, err = f.WriteAt([]byte("H"), 0)
|
||||
AssertEq(nil, err)
|
||||
AssertEq(1, n)
|
||||
|
||||
// Simulate time advancing.
|
||||
t.Clock.AdvanceTime(time.Second)
|
||||
|
||||
// Stat the file.
|
||||
fi, err = os.Stat(fileName)
|
||||
stat = fi.Sys().(*syscall.Stat_t)
|
||||
|
@ -403,7 +384,7 @@ func (t *MemFSTest) ModifyExistingFile_InRoot() {
|
|||
ExpectEq("foo", fi.Name())
|
||||
ExpectEq(len("Hello, world!"), fi.Size())
|
||||
ExpectEq(applyUmask(0600), fi.Mode())
|
||||
ExpectThat(fi, fusetesting.MtimeIs(modifyTime))
|
||||
ExpectThat(fi, fusetesting.MtimeIsWithin(modifyTime, timeSlop))
|
||||
ExpectThat(fi, fusetesting.BirthtimeIs(createTime))
|
||||
ExpectFalse(fi.IsDir())
|
||||
|
||||
|
@ -433,26 +414,20 @@ func (t *MemFSTest) ModifyExistingFile_InSubDir() {
|
|||
// Write a file.
|
||||
fileName := path.Join(dirName, "foo")
|
||||
|
||||
createTime := t.Clock.Now()
|
||||
createTime := time.Now()
|
||||
err = ioutil.WriteFile(fileName, []byte("Hello, world!"), 0600)
|
||||
AssertEq(nil, err)
|
||||
|
||||
// Simulate time advancing.
|
||||
t.Clock.AdvanceTime(time.Second)
|
||||
|
||||
// Open the file and modify it.
|
||||
f, err := os.OpenFile(fileName, os.O_WRONLY, 0400)
|
||||
t.ToClose = append(t.ToClose, f)
|
||||
AssertEq(nil, err)
|
||||
|
||||
modifyTime := t.Clock.Now()
|
||||
modifyTime := time.Now()
|
||||
n, err = f.WriteAt([]byte("H"), 0)
|
||||
AssertEq(nil, err)
|
||||
AssertEq(1, n)
|
||||
|
||||
// Simulate time advancing.
|
||||
t.Clock.AdvanceTime(time.Second)
|
||||
|
||||
// Stat the file.
|
||||
fi, err = os.Stat(fileName)
|
||||
stat = fi.Sys().(*syscall.Stat_t)
|
||||
|
@ -461,7 +436,7 @@ func (t *MemFSTest) ModifyExistingFile_InSubDir() {
|
|||
ExpectEq("foo", fi.Name())
|
||||
ExpectEq(len("Hello, world!"), fi.Size())
|
||||
ExpectEq(applyUmask(0600), fi.Mode())
|
||||
ExpectThat(fi, fusetesting.MtimeIs(modifyTime))
|
||||
ExpectThat(fi, fusetesting.MtimeIsWithin(modifyTime, timeSlop))
|
||||
ExpectThat(fi, fusetesting.BirthtimeIs(createTime))
|
||||
ExpectFalse(fi.IsDir())
|
||||
|
||||
|
@ -574,17 +549,11 @@ func (t *MemFSTest) Rmdir_Empty() {
|
|||
err = os.MkdirAll(path.Join(t.Dir, "foo/bar"), 0754)
|
||||
AssertEq(nil, err)
|
||||
|
||||
// Simulate time advancing.
|
||||
t.Clock.AdvanceTime(time.Second)
|
||||
|
||||
// Remove the leaf.
|
||||
rmTime := t.Clock.Now()
|
||||
rmTime := time.Now()
|
||||
err = os.Remove(path.Join(t.Dir, "foo/bar"))
|
||||
AssertEq(nil, err)
|
||||
|
||||
// Simulate time advancing.
|
||||
t.Clock.AdvanceTime(time.Second)
|
||||
|
||||
// There should be nothing left in the parent.
|
||||
entries, err = fusetesting.ReadDirPicky(path.Join(t.Dir, "foo"))
|
||||
|
||||
|
@ -594,7 +563,7 @@ func (t *MemFSTest) Rmdir_Empty() {
|
|||
// Check the parent's mtime.
|
||||
fi, err := os.Stat(path.Join(t.Dir, "foo"))
|
||||
AssertEq(nil, err)
|
||||
ExpectEq(0, fi.ModTime().Sub(rmTime))
|
||||
ExpectThat(fi, fusetesting.MtimeIsWithin(rmTime, timeSlop))
|
||||
|
||||
// Remove the parent.
|
||||
err = os.Remove(path.Join(t.Dir, "foo"))
|
||||
|
@ -618,13 +587,10 @@ func (t *MemFSTest) Rmdir_OpenedForReading() {
|
|||
var err error
|
||||
|
||||
// Create a directory.
|
||||
createTime := t.Clock.Now()
|
||||
createTime := time.Now()
|
||||
err = os.Mkdir(path.Join(t.Dir, "dir"), 0700)
|
||||
AssertEq(nil, err)
|
||||
|
||||
// Simulate time advancing.
|
||||
t.Clock.AdvanceTime(time.Second)
|
||||
|
||||
// Open the directory for reading.
|
||||
f, err := os.Open(path.Join(t.Dir, "dir"))
|
||||
defer func() {
|
||||
|
@ -655,7 +621,7 @@ func (t *MemFSTest) Rmdir_OpenedForReading() {
|
|||
fi, err := f.Stat()
|
||||
|
||||
ExpectEq("dir", fi.Name())
|
||||
ExpectEq(0, fi.ModTime().Sub(createTime))
|
||||
ExpectThat(fi, fusetesting.MtimeIsWithin(createTime, timeSlop))
|
||||
ExpectEq(0, fi.Sys().(*syscall.Stat_t).Nlink)
|
||||
|
||||
// Attempt to read from the directory. This shouldn't see any junk from the
|
||||
|
@ -1054,7 +1020,7 @@ func (t *MemFSTest) Chtimes() {
|
|||
// Stat it.
|
||||
fi, err := os.Stat(fileName)
|
||||
AssertEq(nil, err)
|
||||
ExpectEq(0, fi.ModTime().Sub(expectedMtime))
|
||||
ExpectThat(fi, fusetesting.MtimeIsWithin(expectedMtime, timeSlop))
|
||||
}
|
||||
|
||||
func (t *MemFSTest) ReadDirWhileModifying() {
|
||||
|
|
Loading…
Reference in New Issue