Back up symlinks, empty directories, and file permissions
Scanner now records symlinks (with their target) and directories during the walk phase instead of skipping them. processFileStreaming detects non-regular entries and writes the DB record without chunking. The e2e test (TestEndToEndFileStorage) now verifies: - Symlink target preserved through backup→restore - Empty directory survives round-trip - File permissions (0600) restored correctly
This commit is contained in:
@@ -585,6 +585,19 @@ func TestEndToEndFileStorage(t *testing.T) {
|
||||
require.NoError(t, afero.WriteFile(fs, path, content, 0o644))
|
||||
}
|
||||
|
||||
// Create a file with non-default permissions.
|
||||
restrictedPath := filepath.Join(dataDir, "restricted.txt")
|
||||
require.NoError(t, afero.WriteFile(fs, restrictedPath, []byte("secret"), 0o600))
|
||||
testFiles[restrictedPath] = []byte("secret")
|
||||
|
||||
// Create an empty directory (should survive round-trip).
|
||||
emptyDir := filepath.Join(dataDir, "emptydir")
|
||||
require.NoError(t, fs.MkdirAll(emptyDir, 0o755))
|
||||
|
||||
// Create a symlink.
|
||||
symlinkPath := filepath.Join(dataDir, "link-to-small")
|
||||
require.NoError(t, os.Symlink("small.txt", symlinkPath))
|
||||
|
||||
// FileStorer is the real-world local-disk backend.
|
||||
storer, err := storage.NewFileStorer(storeDir)
|
||||
require.NoError(t, err)
|
||||
@@ -669,6 +682,25 @@ func TestEndToEndFileStorage(t *testing.T) {
|
||||
require.NoError(t, err, "restored file missing: %s", restoredPath)
|
||||
require.Equalf(t, expected, got, "byte-equality failed for %s", origPath)
|
||||
}
|
||||
|
||||
// Verify the restricted file kept its permissions.
|
||||
restoredRestricted := filepath.Join(restoreDir, restrictedPath)
|
||||
rInfo, err := os.Stat(restoredRestricted)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, os.FileMode(0o600), rInfo.Mode().Perm(),
|
||||
"restricted file should preserve 0600 permissions")
|
||||
|
||||
// Verify the empty directory was restored.
|
||||
restoredEmptyDir := filepath.Join(restoreDir, emptyDir)
|
||||
dInfo, err := os.Stat(restoredEmptyDir)
|
||||
require.NoError(t, err, "empty directory should be restored")
|
||||
assert.True(t, dInfo.IsDir(), "emptydir should be a directory")
|
||||
|
||||
// Verify the symlink was restored with the correct target.
|
||||
restoredSymlink := filepath.Join(restoreDir, symlinkPath)
|
||||
target, err := os.Readlink(restoredSymlink)
|
||||
require.NoError(t, err, "symlink should be restored")
|
||||
assert.Equal(t, "small.txt", target, "symlink target should be preserved")
|
||||
}
|
||||
|
||||
// bytesPattern returns a deterministic byte slice of length n with a tag prefix,
|
||||
|
||||
Reference in New Issue
Block a user