package snapshot_test import ( "context" "os" "path/filepath" "slices" "testing" "github.com/spf13/afero" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "sneak.berlin/go/vaultik/internal/database" "sneak.berlin/go/vaultik/internal/snapshot" ) // A scan records with the snapshot each directory on a different device // from its parent directory, as a mount point is, the scanned path // included. A filesystem that gives no device numbers, as the in-memory // one, records none. See https://git.eeqj.de/sneak/vaultik/issues/395. func TestScanRecordsMountPoints(t *testing.T) { t.Parallel() const ( scannedPath = "/data/source" snapshotID = "mount-points" ) tests := []struct { name string // onVolume names the directories on the volume's device; every // other directory is on another one. nil leaves the device // numbers to the in-memory filesystem, which has none. onVolume []string want []string }{ { name: "volume below the scanned path", onVolume: []string{"nas"}, want: []string{scannedPath + "/nas"}, }, { name: "volume at the scanned path", onVolume: []string{"source", "nas"}, want: []string{scannedPath}, }, {name: "no device numbers", want: nil}, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { t.Parallel() ctx := context.Background() fs := afero.NewMemMapFs() for _, path := range []string{ scannedPath + "/notes.txt", scannedPath + "/nas/a.txt", } { require.NoError(t, fs.MkdirAll(filepath.Dir(path), 0o755)) require.NoError(t, afero.WriteFile(fs, path, []byte(path), 0o644)) } db, err := database.NewTestDB() require.NoError(t, err) t.Cleanup(func() { _ = db.Close() }) repos := database.NewRepositories(db) createTestSnapshotRecord(ctx, t, repos, snapshotID) cfg := snapshot.ScannerConfig{ FS: fs, ChunkSize: int64(1024 * 16), Repositories: repos, MaxBlobSize: int64(1024 * 1024), CompressionLevel: 3, AgeRecipients: []string{testAgePublicKey}, } if tt.onVolume != nil { cfg.DeviceNumber = func(info os.FileInfo) (uint64, bool) { if slices.Contains(tt.onVolume, info.Name()) { return 2, true } return 1, true } } _, err = snapshot.NewScanner(cfg).Scan(ctx, scannedPath, snapshotID) require.NoError(t, err) got, err := repos.Snapshots.GetMountPoints(ctx, snapshotID) require.NoError(t, err) assert.Equal(t, tt.want, got) }) } }