mirror of https://github.com/restic/restic.git
71 lines
1.5 KiB
Go
71 lines
1.5 KiB
Go
package fs
|
|
|
|
import (
|
|
"io"
|
|
"os"
|
|
"testing"
|
|
"time"
|
|
|
|
rtest "github.com/restic/restic/internal/test"
|
|
|
|
"golang.org/x/sys/unix"
|
|
)
|
|
|
|
func TestNoatime(t *testing.T) {
|
|
f, err := os.CreateTemp("", "restic-test-noatime")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
defer func() {
|
|
_ = f.Close()
|
|
err = Remove(f.Name())
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
}()
|
|
|
|
// Only run this test on common filesystems that support O_NOATIME.
|
|
// On others, we may not get an error.
|
|
if !supportsNoatime(t, f) {
|
|
t.Skip("temp directory may not support O_NOATIME, skipping")
|
|
}
|
|
// From this point on, we own the file, so we should not get EPERM.
|
|
|
|
_, err = io.WriteString(f, "Hello!")
|
|
rtest.OK(t, err)
|
|
_, err = f.Seek(0, io.SeekStart)
|
|
rtest.OK(t, err)
|
|
|
|
getAtime := func() time.Time {
|
|
info, err := f.Stat()
|
|
rtest.OK(t, err)
|
|
return ExtendedStat(info).AccessTime
|
|
}
|
|
|
|
atime := getAtime()
|
|
|
|
err = setFlags(f)
|
|
rtest.OK(t, err)
|
|
|
|
_, err = f.Read(make([]byte, 1))
|
|
rtest.OK(t, err)
|
|
rtest.Equals(t, atime, getAtime())
|
|
}
|
|
|
|
func supportsNoatime(t *testing.T, f *os.File) bool {
|
|
var fsinfo unix.Statfs_t
|
|
err := unix.Fstatfs(int(f.Fd()), &fsinfo)
|
|
rtest.OK(t, err)
|
|
|
|
// The funky cast works around a compiler error on 32-bit archs:
|
|
// "unix.BTRFS_SUPER_MAGIC (untyped int constant 2435016766) overflows int32".
|
|
// https://github.com/golang/go/issues/52061
|
|
typ := int64(uint(fsinfo.Type))
|
|
return typ == unix.BTRFS_SUPER_MAGIC ||
|
|
typ == unix.EXT2_SUPER_MAGIC ||
|
|
typ == unix.EXT3_SUPER_MAGIC ||
|
|
typ == unix.EXT4_SUPER_MAGIC ||
|
|
typ == unix.TMPFS_MAGIC
|
|
}
|