mirror of
https://github.com/kopia/kopia.git
synced 2026-03-24 17:11:10 -04:00
75
internal/server/api_sources_test.go
Normal file
75
internal/server/api_sources_test.go
Normal file
@@ -0,0 +1,75 @@
|
||||
package server_test
|
||||
|
||||
import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/kopia/kopia/internal/apiclient"
|
||||
"github.com/kopia/kopia/internal/repotesting"
|
||||
"github.com/kopia/kopia/internal/serverapi"
|
||||
"github.com/kopia/kopia/internal/testutil"
|
||||
"github.com/kopia/kopia/internal/uitask"
|
||||
"github.com/kopia/kopia/snapshot"
|
||||
"github.com/kopia/kopia/snapshot/policy"
|
||||
)
|
||||
|
||||
func TestSnapshotCounters(t *testing.T) {
|
||||
ctx, env := repotesting.NewEnvironment(t, repotesting.FormatNotImportant)
|
||||
srvInfo := startServer(t, env, false)
|
||||
|
||||
cli, err := apiclient.NewKopiaAPIClient(apiclient.Options{
|
||||
BaseURL: srvInfo.BaseURL,
|
||||
TrustedServerCertificateFingerprint: srvInfo.TrustedServerCertificateFingerprint,
|
||||
Username: testUIUsername,
|
||||
Password: testUIPassword,
|
||||
})
|
||||
|
||||
require.NoError(t, err)
|
||||
|
||||
dir := testutil.TempDirectory(t)
|
||||
si := localSource(env, dir)
|
||||
|
||||
mustCreateSource(t, cli, dir)
|
||||
require.Len(t, mustListSources(t, cli, &snapshot.SourceInfo{}), 1)
|
||||
|
||||
mustSetPolicy(t, cli, si, &policy.Policy{
|
||||
FilesPolicy: policy.FilesPolicy{
|
||||
IgnoreRules: []string{"*.i"},
|
||||
},
|
||||
})
|
||||
|
||||
require.NoError(t, os.WriteFile(filepath.Join(dir, "file-a"), []byte{1, 2}, 0o644))
|
||||
require.NoError(t, os.WriteFile(filepath.Join(dir, "file-b"), []byte{1, 2, 3}, 0o644))
|
||||
require.NoError(t, os.WriteFile(filepath.Join(dir, "file-c"), []byte{1, 2, 3, 4}, 0o644))
|
||||
require.NoError(t, os.WriteFile(filepath.Join(dir, "file2.i"), []byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, 0o644))
|
||||
require.NoError(t, os.MkdirAll(filepath.Join(dir, "dir.i"), 0o755))
|
||||
|
||||
eti, err := serverapi.Estimate(ctx, cli, &serverapi.EstimateRequest{
|
||||
Root: dir,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
et := waitForTask(t, cli, eti.TaskID, 15*time.Second)
|
||||
|
||||
require.Equal(t, et.Counters["Bytes"], uitask.BytesCounter(9))
|
||||
require.Equal(t, et.Counters["Directories"], uitask.SimpleCounter(1))
|
||||
require.Equal(t, et.Counters["Files"], uitask.SimpleCounter(3))
|
||||
require.Equal(t, et.Counters["Excluded Directories"], uitask.SimpleCounter(1))
|
||||
require.Equal(t, et.Counters["Excluded Files"], uitask.SimpleCounter(1))
|
||||
|
||||
uresp, err := serverapi.UploadSnapshots(ctx, cli, &si)
|
||||
|
||||
require.True(t, uresp.Sources[si.String()].Success)
|
||||
require.NoError(t, err)
|
||||
|
||||
ut := waitForTask(t, cli, mustGetLatestTask(t, cli).TaskID, 15*time.Second)
|
||||
|
||||
require.Equal(t, ut.Counters["Hashed Files"], uitask.SimpleCounter(3))
|
||||
require.Equal(t, ut.Counters["Hashed Bytes"], uitask.BytesCounter(9))
|
||||
require.Equal(t, ut.Counters["Excluded Directories"], uitask.SimpleCounter(1))
|
||||
require.Equal(t, ut.Counters["Excluded Files"], uitask.SimpleCounter(1))
|
||||
require.Equal(t, ut.Counters["Processed Files"], uitask.SimpleCounter(3))
|
||||
}
|
||||
@@ -41,8 +41,8 @@
|
||||
)
|
||||
|
||||
// nolint:thelper
|
||||
func startServer(ctx context.Context, t *testing.T) *repo.APIServerInfo {
|
||||
_, env := repotesting.NewEnvironment(t, repotesting.FormatNotImportant)
|
||||
func startServer(t *testing.T, env *repotesting.Environment, tls bool) *repo.APIServerInfo {
|
||||
ctx := testlogging.Context(t)
|
||||
|
||||
s, err := server.New(ctx, server.Options{
|
||||
ConfigFile: env.ConfigFile(),
|
||||
@@ -67,18 +67,23 @@ func startServer(ctx context.Context, t *testing.T) *repo.APIServerInfo {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
asi := &repo.APIServerInfo{}
|
||||
|
||||
hs := httptest.NewUnstartedServer(s.GRPCRouterHandler(s.APIHandlers(true)))
|
||||
hs.EnableHTTP2 = true
|
||||
hs.StartTLS()
|
||||
if tls {
|
||||
hs.EnableHTTP2 = true
|
||||
hs.StartTLS()
|
||||
serverHash := sha256.Sum256(hs.Certificate().Raw)
|
||||
asi.BaseURL = hs.URL
|
||||
asi.TrustedServerCertificateFingerprint = hex.EncodeToString(serverHash[:])
|
||||
} else {
|
||||
hs.Start()
|
||||
asi.BaseURL = hs.URL
|
||||
}
|
||||
|
||||
t.Cleanup(hs.Close)
|
||||
|
||||
serverHash := sha256.Sum256(hs.Certificate().Raw)
|
||||
|
||||
return &repo.APIServerInfo{
|
||||
BaseURL: hs.URL,
|
||||
TrustedServerCertificateFingerprint: hex.EncodeToString(serverHash[:]),
|
||||
}
|
||||
return asi
|
||||
}
|
||||
|
||||
func TestServer_REST(t *testing.T) {
|
||||
@@ -91,8 +96,8 @@ func TestServer_GRPC(t *testing.T) {
|
||||
|
||||
// nolint:thelper
|
||||
func testServer(t *testing.T, disableGRPC bool) {
|
||||
ctx := testlogging.ContextWithLevel(t, testlogging.LevelDebug)
|
||||
apiServerInfo := startServer(ctx, t)
|
||||
ctx, env := repotesting.NewEnvironment(t, repotesting.FormatNotImportant)
|
||||
apiServerInfo := startServer(t, env, true)
|
||||
|
||||
apiServerInfo.DisableGRPC = disableGRPC
|
||||
|
||||
@@ -113,8 +118,8 @@ func testServer(t *testing.T, disableGRPC bool) {
|
||||
}
|
||||
|
||||
func TestGPRServer_AuthenticationError(t *testing.T) {
|
||||
ctx := testlogging.ContextWithLevel(t, testlogging.LevelDebug)
|
||||
apiServerInfo := startServer(ctx, t)
|
||||
ctx, env := repotesting.NewEnvironment(t, repotesting.FormatNotImportant)
|
||||
apiServerInfo := startServer(t, env, true)
|
||||
|
||||
if _, err := repo.OpenGRPCAPIRepository(ctx, apiServerInfo, repo.ClientOptions{
|
||||
Username: "bad-username",
|
||||
@@ -125,8 +130,8 @@ func TestGPRServer_AuthenticationError(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestServerUIAccessDeniedToRemoteUser(t *testing.T) {
|
||||
ctx := testlogging.ContextWithLevel(t, testlogging.LevelDebug)
|
||||
si := startServer(ctx, t)
|
||||
ctx, env := repotesting.NewEnvironment(t, repotesting.FormatNotImportant)
|
||||
si := startServer(t, env, true)
|
||||
|
||||
remoteUserClient, err := apiclient.NewKopiaAPIClient(apiclient.Options{
|
||||
BaseURL: si.BaseURL,
|
||||
|
||||
95
internal/server/util_test.go
Normal file
95
internal/server/util_test.go
Normal file
@@ -0,0 +1,95 @@
|
||||
package server_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/kopia/kopia/internal/apiclient"
|
||||
"github.com/kopia/kopia/internal/clock"
|
||||
"github.com/kopia/kopia/internal/repotesting"
|
||||
"github.com/kopia/kopia/internal/serverapi"
|
||||
"github.com/kopia/kopia/internal/testlogging"
|
||||
"github.com/kopia/kopia/internal/uitask"
|
||||
"github.com/kopia/kopia/snapshot"
|
||||
"github.com/kopia/kopia/snapshot/policy"
|
||||
)
|
||||
|
||||
func mustCreateSource(t *testing.T, cli *apiclient.KopiaAPIClient, path string) {
|
||||
t.Helper()
|
||||
|
||||
_, err := serverapi.CreateSnapshotSource(testlogging.Context(t), cli, &serverapi.CreateSnapshotSourceRequest{
|
||||
Path: path,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
}
|
||||
|
||||
func mustSetPolicy(t *testing.T, cli *apiclient.KopiaAPIClient, si snapshot.SourceInfo, pol *policy.Policy) {
|
||||
t.Helper()
|
||||
|
||||
require.NoError(t, serverapi.SetPolicy(testlogging.Context(t), cli, si, pol))
|
||||
}
|
||||
|
||||
func mustListSources(t *testing.T, cli *apiclient.KopiaAPIClient, match *snapshot.SourceInfo) []*serverapi.SourceStatus {
|
||||
t.Helper()
|
||||
|
||||
resp, err := serverapi.ListSources(testlogging.Context(t), cli, match)
|
||||
require.NoError(t, err)
|
||||
|
||||
return resp.Sources
|
||||
}
|
||||
|
||||
func mustGetTask(t *testing.T, cli *apiclient.KopiaAPIClient, taskID string) uitask.Info {
|
||||
t.Helper()
|
||||
|
||||
resp, err := serverapi.GetTask(testlogging.Context(t), cli, taskID)
|
||||
require.NoError(t, err)
|
||||
|
||||
return *resp
|
||||
}
|
||||
|
||||
func mustListTasks(t *testing.T, cli *apiclient.KopiaAPIClient) []uitask.Info {
|
||||
t.Helper()
|
||||
|
||||
resp, err := serverapi.ListTasks(testlogging.Context(t), cli)
|
||||
require.NoError(t, err)
|
||||
|
||||
return resp.Tasks
|
||||
}
|
||||
|
||||
func mustGetLatestTask(t *testing.T, cli *apiclient.KopiaAPIClient) uitask.Info {
|
||||
t.Helper()
|
||||
|
||||
tl := mustListTasks(t, cli)
|
||||
require.NotEmpty(t, tl)
|
||||
|
||||
return tl[0]
|
||||
}
|
||||
|
||||
func waitForTask(t *testing.T, cli *apiclient.KopiaAPIClient, taskID string, timeout time.Duration) uitask.Info {
|
||||
t.Helper()
|
||||
|
||||
var lastInfo uitask.Info
|
||||
|
||||
deadline := clock.Now().Add(timeout)
|
||||
for clock.Now().Before(deadline) {
|
||||
lastInfo = mustGetTask(t, cli, taskID)
|
||||
|
||||
if lastInfo.Status.IsFinished() {
|
||||
return lastInfo
|
||||
}
|
||||
}
|
||||
|
||||
t.Fatalf("task %v did not complete in %v, last: %v", taskID, timeout, lastInfo)
|
||||
|
||||
return lastInfo
|
||||
}
|
||||
|
||||
func localSource(env *repotesting.Environment, path string) snapshot.SourceInfo {
|
||||
return snapshot.SourceInfo{
|
||||
UserName: env.Repository.ClientOptions().Username,
|
||||
Host: env.Repository.ClientOptions().Hostname,
|
||||
Path: path,
|
||||
}
|
||||
}
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
@@ -11,6 +12,7 @@
|
||||
"github.com/kopia/kopia/repo/blob/throttling"
|
||||
"github.com/kopia/kopia/repo/object"
|
||||
"github.com/kopia/kopia/snapshot"
|
||||
"github.com/kopia/kopia/snapshot/policy"
|
||||
)
|
||||
|
||||
// CreateSnapshotSource creates snapshot source with a given path.
|
||||
@@ -146,6 +148,30 @@ func ListPolicies(ctx context.Context, c *apiclient.KopiaAPIClient, match *snaps
|
||||
return resp, nil
|
||||
}
|
||||
|
||||
func policyTargetURLParamters(si snapshot.SourceInfo) string {
|
||||
return fmt.Sprintf("userName=%v&host=%v&path=%v", si.UserName, si.Host, si.Path)
|
||||
}
|
||||
|
||||
// SetPolicy sets the policy.
|
||||
func SetPolicy(ctx context.Context, c *apiclient.KopiaAPIClient, si snapshot.SourceInfo, pol *policy.Policy) error {
|
||||
resp := &Empty{}
|
||||
if err := c.Put(ctx, "policy?"+policyTargetURLParamters(si), pol, resp); err != nil {
|
||||
return errors.Wrap(err, "SetPolicy")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// ListTasks lists the tasks.
|
||||
func ListTasks(ctx context.Context, c *apiclient.KopiaAPIClient) (*TaskListResponse, error) {
|
||||
resp := &TaskListResponse{}
|
||||
if err := c.Get(ctx, "tasks", nil, resp); err != nil {
|
||||
return nil, errors.Wrap(err, "ListTasks")
|
||||
}
|
||||
|
||||
return resp, nil
|
||||
}
|
||||
|
||||
// GetObject returns the object payload.
|
||||
func GetObject(ctx context.Context, c *apiclient.KopiaAPIClient, objectID string) ([]byte, error) {
|
||||
var b []byte
|
||||
|
||||
Reference in New Issue
Block a user