I'm writing a unit test of a component that creates a file, specifically the case where it doesn't set the file's modification time (mtime). I.e., I'm verifying that mtime is within the time range from before the file was created until after creation completed.
However, I'm finding that I cannot assume the file system to be in sync with my process as shown in this minimal Go test:
package main
import (
"os"
"testing"
"time"
)
func Test(t *testing.T) {
before := time.Now()
f, err := os.CreateTemp("", "")
if err != nil {
t.Fatal(err)
}
t.Cleanup(func() {
if err := os.Remove(f.Name()); err != nil {
t.Fatal(err)
}
})
err = f.Close()
if err != nil {
t.Fatal(err)
}
info, err := os.Lstat(f.Name())
if err != nil {
t.Fatal(err)
}
mtime := info.ModTime()
if mtime.Before(before) {
t.Fatalf("file modification time %s is before %s where we started crating it!\n", mtime.Format("15:04:05.000"), before.Format("15:04:05.000"))
}
}
https://www.go-sandbox.org/snippets/pQ97nKDTUpTLuKMx/
The test is failing consistently with mtime being a few ms before before (on both my PopOS! 20.04/ext4 box and the linked sandbox). It does not fail on macOS.
Questions:
- Why is
mtimeconsistently earlier than the program'sbeforetime? - Is there another way
beforecan be read or a way to sync/flush against the OS/FS such that we know the earliest possible (reasonable) time thatmtimewill be?
My current workaround is to check mtime with 1s accuracy. That's quite unsatisfactory and I have no way of knowing whether that'll be enough forever.