diff --git a/internal/checker/checker_test.go b/internal/checker/checker_test.go index 58dc7c744..bdc2f9f77 100644 --- a/internal/checker/checker_test.go +++ b/internal/checker/checker_test.go @@ -72,6 +72,7 @@ func assertOnlyMixedPackHints(t *testing.T, hints []error) { } func TestCheckRepo(t *testing.T) { + repository.TestInjectKey(t, restic.TestParseID("7bb3065bfb17da7430dc4dde4741d6db3dd83fdb0829500cf105755e067f879a"), `{"mac":{"k":"W1Y8bmQNJg6TAmuDt7lbpQ==","r":"r43DBmAdmwtQneoBTGAABQ=="},"encrypt":"JuZGBs6joRiLzqkyMWhmbZMLHe8+5oH6MDE5I6M8R/I="}`) repo, _ := repository.TestFromFixture(t, checkerTestData) chkr := checker.New(repo, false) @@ -89,6 +90,7 @@ func TestCheckRepo(t *testing.T) { } func TestMissingPack(t *testing.T) { + repository.TestInjectKey(t, restic.TestParseID("7bb3065bfb17da7430dc4dde4741d6db3dd83fdb0829500cf105755e067f879a"), `{"mac":{"k":"W1Y8bmQNJg6TAmuDt7lbpQ==","r":"r43DBmAdmwtQneoBTGAABQ=="},"encrypt":"JuZGBs6joRiLzqkyMWhmbZMLHe8+5oH6MDE5I6M8R/I="}`) repo, be := repository.TestFromFixture(t, checkerTestData) packID := restic.TestParseID("657f7fb64f6a854fff6fe9279998ee09034901eded4e6db9bcee0e59745bbce6") @@ -114,6 +116,7 @@ func TestMissingPack(t *testing.T) { } func TestUnreferencedPack(t *testing.T) { + repository.TestInjectKey(t, restic.TestParseID("7bb3065bfb17da7430dc4dde4741d6db3dd83fdb0829500cf105755e067f879a"), `{"mac":{"k":"W1Y8bmQNJg6TAmuDt7lbpQ==","r":"r43DBmAdmwtQneoBTGAABQ=="},"encrypt":"JuZGBs6joRiLzqkyMWhmbZMLHe8+5oH6MDE5I6M8R/I="}`) repo, be := repository.TestFromFixture(t, checkerTestData) // index 3f1a only references pack 60e0 @@ -141,6 +144,7 @@ func TestUnreferencedPack(t *testing.T) { } func TestUnreferencedBlobs(t *testing.T) { + repository.TestInjectKey(t, restic.TestParseID("7bb3065bfb17da7430dc4dde4741d6db3dd83fdb0829500cf105755e067f879a"), `{"mac":{"k":"W1Y8bmQNJg6TAmuDt7lbpQ==","r":"r43DBmAdmwtQneoBTGAABQ=="},"encrypt":"JuZGBs6joRiLzqkyMWhmbZMLHe8+5oH6MDE5I6M8R/I="}`) repo, be := repository.TestFromFixture(t, checkerTestData) snapshotID := restic.TestParseID("51d249d28815200d59e4be7b3f21a157b864dc343353df9d8e498220c2499b02") @@ -175,6 +179,7 @@ func TestUnreferencedBlobs(t *testing.T) { } func TestModifiedIndex(t *testing.T) { + repository.TestInjectKey(t, restic.TestParseID("7bb3065bfb17da7430dc4dde4741d6db3dd83fdb0829500cf105755e067f879a"), `{"mac":{"k":"W1Y8bmQNJg6TAmuDt7lbpQ==","r":"r43DBmAdmwtQneoBTGAABQ=="},"encrypt":"JuZGBs6joRiLzqkyMWhmbZMLHe8+5oH6MDE5I6M8R/I="}`) repo, be := repository.TestFromFixture(t, checkerTestData) done := make(chan struct{}) @@ -214,6 +219,7 @@ func TestModifiedIndex(t *testing.T) { var checkerDuplicateIndexTestData = filepath.Join("testdata", "duplicate-packs-in-index-test-repo.tar.gz") func TestDuplicatePacksInIndex(t *testing.T) { + repository.TestInjectKey(t, restic.TestParseID("b9883c60bed42db51be171ca52f055104b6ea7cfa2bc381c05b2b1f78231280c"), `{"mac":{"k":"maQ4ILA872XnDxHVEno94A==","r":"OptMBABwkgIsMQcHME8cBw=="},"encrypt":"janrR1efN7HyQ8kOZ9zhHixooZ/e+WelH0mT4v9WskQ="}`) repo, _ := repository.TestFromFixture(t, checkerDuplicateIndexTestData) chkr := checker.New(repo, false) @@ -413,6 +419,7 @@ func (r *loadTreesOnceRepository) LoadBlob(ctx context.Context, bh restic.BlobHa } func TestCheckerNoDuplicateTreeDecodes(t *testing.T) { + repository.TestInjectKey(t, restic.TestParseID("7bb3065bfb17da7430dc4dde4741d6db3dd83fdb0829500cf105755e067f879a"), `{"mac":{"k":"W1Y8bmQNJg6TAmuDt7lbpQ==","r":"r43DBmAdmwtQneoBTGAABQ=="},"encrypt":"JuZGBs6joRiLzqkyMWhmbZMLHe8+5oH6MDE5I6M8R/I="}`) repo, _ := repository.TestFromFixture(t, checkerTestData) checkRepo := &loadTreesOnceRepository{ Repository: repo, @@ -562,6 +569,7 @@ func TestCheckerBlobTypeConfusion(t *testing.T) { } func loadBenchRepository(t *testing.B) (*checker.Checker, restic.Repository) { + repository.TestInjectKey(t, restic.TestParseID("7bb3065bfb17da7430dc4dde4741d6db3dd83fdb0829500cf105755e067f879a"), `{"mac":{"k":"W1Y8bmQNJg6TAmuDt7lbpQ==","r":"r43DBmAdmwtQneoBTGAABQ=="},"encrypt":"JuZGBs6joRiLzqkyMWhmbZMLHe8+5oH6MDE5I6M8R/I="}`) repo, _ := repository.TestFromFixture(t, checkerTestData) chkr := checker.New(repo, false) diff --git a/internal/repository/checker_test.go b/internal/repository/checker_test.go index 10fe94970..f344443ed 100644 --- a/internal/repository/checker_test.go +++ b/internal/repository/checker_test.go @@ -34,6 +34,7 @@ func testWrapCheckPack(ctx context.Context, t *testing.T, repo *Repository, // TestGapInBlobs creates a gap in the blob list by omitting the first entry before passing it to checkPack func TestGapInBlobs(t *testing.T) { + TestInjectKey(t, restic.TestParseID("7bb3065bfb17da7430dc4dde4741d6db3dd83fdb0829500cf105755e067f879a"), `{"mac":{"k":"W1Y8bmQNJg6TAmuDt7lbpQ==","r":"r43DBmAdmwtQneoBTGAABQ=="},"encrypt":"JuZGBs6joRiLzqkyMWhmbZMLHe8+5oH6MDE5I6M8R/I="}`) repo, _ := TestFromFixture(t, checkerTestData) err := repo.LoadIndex(context.TODO(), restic.NoopTerminalCounterFactory) diff --git a/internal/repository/key.go b/internal/repository/key.go index e5d1b0724..94a4184e6 100644 --- a/internal/repository/key.go +++ b/internal/repository/key.go @@ -6,6 +6,7 @@ import ( "fmt" "os" "os/user" + "sync" "time" "github.com/restic/restic/internal/errors" @@ -47,6 +48,9 @@ type Key struct { // calibrated on the first run of AddKey(). var params *crypto.Params +// testKeyInjection is used to speed up tests by skipping the key decryption step. +var testKeyInjection = sync.Map{} + const ( // KDFTimeout specifies the maximum runtime for the KDF. KDFTimeout = 500 * time.Millisecond @@ -63,6 +67,14 @@ func createMasterKey(ctx context.Context, s *Repository, password string) (*Key, // openKey tries do decrypt the key specified by name with the given password. func openKey(ctx context.Context, s *Repository, id restic.ID, password string) (*Key, error) { + if key, ok := testKeyInjection.Load(id); ok { + return &Key{ + master: key.(*crypto.Key), + user: key.(*crypto.Key), // not correct but good enough for testing + id: id, + }, nil + } + k, err := LoadKey(ctx, s, id) if err != nil { debug.Log("LoadKey(%v) returned error %v", id.String(), err) diff --git a/internal/repository/repository_test.go b/internal/repository/repository_test.go index b830458e7..331cea1c8 100644 --- a/internal/repository/repository_test.go +++ b/internal/repository/repository_test.go @@ -319,6 +319,7 @@ func benchmarkLoadUnpacked(b *testing.B, version uint) { var repoFixture = filepath.Join("testdata", "test-repo.tar.gz") func TestRepositoryLoadIndex(t *testing.T) { + repository.TestInjectKey(t, restic.TestParseID("7bb3065bfb17da7430dc4dde4741d6db3dd83fdb0829500cf105755e067f879a"), `{"mac":{"k":"W1Y8bmQNJg6TAmuDt7lbpQ==","r":"r43DBmAdmwtQneoBTGAABQ=="},"encrypt":"JuZGBs6joRiLzqkyMWhmbZMLHe8+5oH6MDE5I6M8R/I="}`) repo, _ := repository.TestFromFixture(t, repoFixture) rtest.OK(t, repo.LoadIndex(context.TODO(), restic.NoopTerminalCounterFactory)) @@ -372,6 +373,7 @@ func (be *damageOnceBackend) Load(ctx context.Context, h backend.Handle, length } func TestRepositoryLoadUnpackedRetryBroken(t *testing.T) { + repository.TestInjectKey(t, restic.TestParseID("7bb3065bfb17da7430dc4dde4741d6db3dd83fdb0829500cf105755e067f879a"), `{"mac":{"k":"W1Y8bmQNJg6TAmuDt7lbpQ==","r":"r43DBmAdmwtQneoBTGAABQ=="},"encrypt":"JuZGBs6joRiLzqkyMWhmbZMLHe8+5oH6MDE5I6M8R/I="}`) repodir := rtest.Env(t, repoFixture) be, err := local.Open(context.TODO(), local.Config{Path: repodir, Connections: 2}, t.Logf) diff --git a/internal/repository/testing.go b/internal/repository/testing.go index 27dd98f2f..976ae3b8a 100644 --- a/internal/repository/testing.go +++ b/internal/repository/testing.go @@ -2,6 +2,7 @@ package repository import ( "context" + "encoding/json" "fmt" "os" "sync" @@ -193,3 +194,12 @@ func TestCheckRepo(t testing.TB, repo *Repository) { t.Error(err) } } + +func TestInjectKey(t testing.TB, keyID restic.ID, key string) { + var k crypto.Key + err := json.Unmarshal([]byte(key), &k) + if err != nil { + t.Fatal(err) + } + testKeyInjection.Store(keyID, &k) +}