check / check (push) Waiting to run
snapshot create --prune purged the older snapshots holding a volume's files when the volume, mounted below a configured path, was not mounted: its empty mount point read as deleted files. The scan now records in the local index each directory at or below a configured path that holds an entry and is on a different device from its parent directory, looked up once the walk has listed it, as listing mounts an automounted volume. Under --prune, when an earlier snapshot of that name recorded such a directory and this run does not, the run skips the prune, keeps every older snapshot and exits non-zero, naming the directory. For a volume retired on purpose, snapshot purge removes the older snapshots. Model: opus-5-5
41 lines
1.0 KiB
Go
41 lines
1.0 KiB
Go
//nolint:testpackage // exercises the unexported deviceNumberFromStat
|
|
package snapshot
|
|
|
|
import (
|
|
"os"
|
|
"path/filepath"
|
|
"testing"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
// The device number a real backup reads is the same for a directory and
|
|
// a file in it, and differs between the temp directory and /dev.
|
|
// Without it no mount point is ever found. See
|
|
// https://git.eeqj.de/sneak/vaultik/issues/395.
|
|
func TestDeviceNumberFromStat(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
dir := t.TempDir()
|
|
file := filepath.Join(dir, "file.txt")
|
|
require.NoError(t, os.WriteFile(file, nil, 0o600))
|
|
|
|
deviceOf := func(path string) uint64 {
|
|
t.Helper()
|
|
|
|
info, err := os.Stat(path)
|
|
require.NoError(t, err)
|
|
|
|
device, ok := deviceNumberFromStat(info)
|
|
require.True(t, ok, "no device number read for %s", path)
|
|
|
|
return device
|
|
}
|
|
|
|
assert.Equal(t, deviceOf(dir), deviceOf(file))
|
|
|
|
// /dev is a different filesystem from the temp dir on Linux, macOS and in Docker.
|
|
assert.NotEqual(t, deviceOf(dir), deviceOf("/dev"))
|
|
}
|