Skip to content

Commit ff82cc9

Browse files
committed
os: force consistent mtime before running fstest on directory on Windows
FindFileNext sometimes returns a different mtime than looking at the file directly, because the MFT on NTFS is written to lazily. In order to keep these in sync, we use GetFileInformationByHandle to get the actual mtime, and then write it back to the file explicitly. Fixes #42637. Change-Id: I774016d3ac55d0dc9b0f9c1b681516c33ba0d28a Reviewed-on: https://go-review.googlesource.com/c/go/+/285720 Run-TryBot: Jason A. Donenfeld <[email protected]> TryBot-Result: Go Bot <[email protected]> Reviewed-by: Bryan C. Mills <[email protected]> Trust: Jason A. Donenfeld <[email protected]>
1 parent 044f937 commit ff82cc9

File tree

1 file changed

+27
-0
lines changed

1 file changed

+27
-0
lines changed

src/os/os_test.go

+27
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import (
1111
"fmt"
1212
"internal/testenv"
1313
"io"
14+
"io/fs"
1415
"os"
1516
. "os"
1617
osexec "os/exec"
@@ -2689,6 +2690,32 @@ func TestOpenFileKeepsPermissions(t *testing.T) {
26892690
}
26902691

26912692
func TestDirFS(t *testing.T) {
2693+
// On Windows, we force the MFT to update by reading the actual metadata from GetFileInformationByHandle and then
2694+
// explicitly setting that. Otherwise it might get out of sync with FindFirstFile. See golang.org/issues/42637.
2695+
if runtime.GOOS == "windows" {
2696+
if err := filepath.WalkDir("./testdata/dirfs", func(path string, d fs.DirEntry, err error) error {
2697+
if err != nil {
2698+
t.Fatal(err)
2699+
}
2700+
info, err := d.Info()
2701+
if err != nil {
2702+
t.Fatal(err)
2703+
}
2704+
stat, err := Stat(path) // This uses GetFileInformationByHandle internally.
2705+
if err != nil {
2706+
t.Fatal(err)
2707+
}
2708+
if stat.ModTime() == info.ModTime() {
2709+
return nil
2710+
}
2711+
if err := Chtimes(path, stat.ModTime(), stat.ModTime()); err != nil {
2712+
t.Log(err) // We only log, not die, in case the test directory is not writable.
2713+
}
2714+
return nil
2715+
}); err != nil {
2716+
t.Fatal(err)
2717+
}
2718+
}
26922719
if err := fstest.TestFS(DirFS("./testdata/dirfs"), "a", "b", "dir/x"); err != nil {
26932720
t.Fatal(err)
26942721
}

0 commit comments

Comments
 (0)