Files
kopia/internal/server/api_restore_test.go

221 lines
6.7 KiB
Go

package server_test
import (
"context"
"math"
"path/filepath"
"testing"
"time"
"github.com/google/uuid"
"github.com/stretchr/testify/require"
"github.com/kopia/kopia/internal/apiclient"
"github.com/kopia/kopia/internal/mockfs"
"github.com/kopia/kopia/internal/repotesting"
"github.com/kopia/kopia/internal/serverapi"
"github.com/kopia/kopia/internal/servertesting"
"github.com/kopia/kopia/internal/testutil"
"github.com/kopia/kopia/internal/uitask"
"github.com/kopia/kopia/repo"
"github.com/kopia/kopia/repo/manifest"
"github.com/kopia/kopia/snapshot"
"github.com/kopia/kopia/snapshot/restore"
"github.com/kopia/kopia/snapshot/upload"
)
func TestRestoreSnapshots(t *testing.T) {
ctx, env := repotesting.NewEnvironment(t, repotesting.FormatNotImportant)
si1 := env.LocalPathSourceInfo("/dummy/path")
var id11 manifest.ID
require.NoError(t, repo.WriteSession(ctx, env.Repository, repo.WriteSessionOptions{Purpose: "Test"}, func(ctx context.Context, w repo.RepositoryWriter) error {
u := upload.NewUploader(w)
dir1 := mockfs.NewDirectory()
dir1.AddFile("file1", []byte{1, 2, 3}, 0o644)
dir1.AddDir("dir1", 0o644).AddFile("file2", []byte{1, 2, 4}, 0o644)
man11, err := u.Upload(ctx, dir1, nil, si1)
require.NoError(t, err)
id11, err = snapshot.SaveSnapshot(ctx, w, man11)
require.NoError(t, err)
return nil
}))
srvInfo := servertesting.StartServer(t, env, false)
cli, err := apiclient.NewKopiaAPIClient(apiclient.Options{
BaseURL: srvInfo.BaseURL,
TrustedServerCertificateFingerprint: srvInfo.TrustedServerCertificateFingerprint,
Username: servertesting.TestUIUsername,
Password: servertesting.TestUIPassword,
})
require.NoError(t, err)
require.NoError(t, cli.FetchCSRFTokenForTesting(ctx))
t.Run("Filesystem", func(t *testing.T) {
targetPath1 := testutil.TempDirectory(t)
restoreTask1, err := serverapi.Restore(ctx, cli, &serverapi.RestoreRequest{
Root: string(id11),
Options: restore.Options{
RestoreDirEntryAtDepth: math.MaxInt32,
},
Filesystem: &restore.FilesystemOutput{
TargetPath: targetPath1,
SkipOwners: true,
SkipPermissions: true,
},
})
require.NoError(t, err)
waitForTask(t, cli, restoreTask1.TaskID, 30*time.Second)
require.FileExists(t, filepath.Join(targetPath1, "file1"))
require.FileExists(t, filepath.Join(targetPath1, "dir1", "file2"))
})
t.Run("FilesystemSubdir", func(t *testing.T) {
targetPath1 := testutil.TempDirectory(t)
restoreTask1, err := serverapi.Restore(ctx, cli, &serverapi.RestoreRequest{
Root: string(id11) + "/dir1",
Options: restore.Options{
RestoreDirEntryAtDepth: math.MaxInt32,
},
Filesystem: &restore.FilesystemOutput{
TargetPath: targetPath1,
SkipOwners: true,
SkipPermissions: true,
},
})
require.NoError(t, err)
require.Equal(t, uitask.StatusSuccess, waitForTask(t, cli, restoreTask1.TaskID, 30*time.Second).Status)
require.FileExists(t, filepath.Join(targetPath1, "file2"))
})
t.Run("FilesystemFullShallowRestore", func(t *testing.T) {
targetPath1 := testutil.TempDirectory(t)
restoreTask1, err := serverapi.Restore(ctx, cli, &serverapi.RestoreRequest{
Root: string(id11),
Options: restore.Options{},
Filesystem: &restore.FilesystemOutput{
TargetPath: targetPath1,
SkipOwners: true,
SkipPermissions: true,
},
})
require.NoError(t, err)
require.Equal(t, uitask.StatusSuccess, waitForTask(t, cli, restoreTask1.TaskID, 30*time.Second).Status)
require.FileExists(t, filepath.Join(targetPath1, "file1.kopia-entry"))
require.DirExists(t, filepath.Join(targetPath1, "dir1.kopia-entry"))
require.FileExists(t, filepath.Join(targetPath1, "dir1.kopia-entry", ".kopia-entry"))
})
t.Run("FilesystemPartialShallowRestore", func(t *testing.T) {
targetPath1 := testutil.TempDirectory(t)
restoreTask1, err := serverapi.Restore(ctx, cli, &serverapi.RestoreRequest{
Root: string(id11),
Options: restore.Options{
RestoreDirEntryAtDepth: 1,
},
Filesystem: &restore.FilesystemOutput{
TargetPath: targetPath1,
SkipOwners: true,
SkipPermissions: true,
},
})
require.NoError(t, err)
require.Equal(t, uitask.StatusSuccess, waitForTask(t, cli, restoreTask1.TaskID, 30*time.Second).Status)
require.FileExists(t, filepath.Join(targetPath1, "file1"))
require.DirExists(t, filepath.Join(targetPath1, "dir1"))
require.FileExists(t, filepath.Join(targetPath1, "dir1", "file2.kopia-entry"))
})
t.Run("ZipFile", func(t *testing.T) {
outputZipFile := filepath.Join(testutil.TempDirectory(t), "test1.zip")
restoreTask1, err := serverapi.Restore(ctx, cli, &serverapi.RestoreRequest{
Root: string(id11),
Options: restore.Options{
RestoreDirEntryAtDepth: math.MaxInt32,
},
ZipFile: outputZipFile,
})
require.NoError(t, err)
require.Equal(t, uitask.StatusSuccess, waitForTask(t, cli, restoreTask1.TaskID, 30*time.Second).Status)
require.FileExists(t, outputZipFile)
})
t.Run("UncompressedZipFile", func(t *testing.T) {
outputZipFile := filepath.Join(testutil.TempDirectory(t), "test1.zip")
restoreTask1, err := serverapi.Restore(ctx, cli, &serverapi.RestoreRequest{
Root: string(id11),
Options: restore.Options{
RestoreDirEntryAtDepth: math.MaxInt32,
},
ZipFile: outputZipFile,
UncompressedZip: true,
})
require.NoError(t, err)
require.Equal(t, uitask.StatusSuccess, waitForTask(t, cli, restoreTask1.TaskID, 30*time.Second).Status)
require.FileExists(t, outputZipFile)
})
t.Run("TarFile", func(t *testing.T) {
outputTarFile := filepath.Join(testutil.TempDirectory(t), "test1.tar")
restoreTask1, err := serverapi.Restore(ctx, cli, &serverapi.RestoreRequest{
Root: string(id11),
Options: restore.Options{
RestoreDirEntryAtDepth: math.MaxInt32,
},
TarFile: outputTarFile,
})
require.NoError(t, err)
require.Equal(t, uitask.StatusSuccess, waitForTask(t, cli, restoreTask1.TaskID, 30*time.Second).Status)
require.FileExists(t, outputTarFile)
})
t.Run("InvalidRequest", func(t *testing.T) {
requests := []*serverapi.RestoreRequest{
{
Root: string(id11),
// no output
},
{
// no root
ZipFile: filepath.Join(testutil.TempDirectory(t), "test1.zip"),
},
{
Root: string(id11 + "bad"),
ZipFile: filepath.Join(testutil.TempDirectory(t), "test1.zip"),
},
{
Root: string(id11),
ZipFile: "/no/such/directory/" + uuid.NewString() + "/test1.zip",
},
{
Root: string(id11),
TarFile: "/no/such/directory/" + uuid.NewString() + "/test1.tar",
},
}
for _, req := range requests {
_, err := serverapi.Restore(ctx, cli, req)
var se apiclient.HTTPStatusError
require.ErrorAs(t, err, &se)
}
})
}