Compare commits
1
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7a40125c80 |
@@ -1,6 +1,7 @@
|
|||||||
package vaultik //nolint:testpackage // sets ctx/cancel and inspects scratch files
|
package vaultik //nolint:testpackage // sets ctx/cancel and inspects scratch files
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
"context"
|
"context"
|
||||||
"io"
|
"io"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
@@ -11,6 +12,7 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/spf13/afero"
|
"github.com/spf13/afero"
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
"sneak.berlin/go/vaultik/internal/log"
|
"sneak.berlin/go/vaultik/internal/log"
|
||||||
"sneak.berlin/go/vaultik/internal/storage"
|
"sneak.berlin/go/vaultik/internal/storage"
|
||||||
@@ -157,3 +159,51 @@ func scratchEntries(t *testing.T, dir string) []string {
|
|||||||
|
|
||||||
return matches
|
return matches
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TestRestoreSkipErrorsCancelDuringBlobDownload cancels a SkipErrors
|
||||||
|
// restore while a blob download is in progress. The download fails only
|
||||||
|
// because of the cancel, so Restore must return context.Canceled without
|
||||||
|
// reporting the file that needs the blob as failed.
|
||||||
|
//
|
||||||
|
//nolint:paralleltest // installs the global logger via log.Initialize
|
||||||
|
func TestRestoreSkipErrorsCancelDuringBlobDownload(t *testing.T) {
|
||||||
|
log.Initialize(log.Config{})
|
||||||
|
|
||||||
|
fs := afero.NewOsFs()
|
||||||
|
tempDir := t.TempDir()
|
||||||
|
|
||||||
|
cfg, storer, snapshotID, srcPath := backupOneFile(context.Background(),
|
||||||
|
t, fs, tempDir, "a.txt", []byte("hello vaultik"), 0o644)
|
||||||
|
|
||||||
|
gate := newBlockingBlobStorer(storer)
|
||||||
|
|
||||||
|
ctx, cancel := context.WithCancel(context.Background())
|
||||||
|
defer cancel()
|
||||||
|
|
||||||
|
var out bytes.Buffer
|
||||||
|
|
||||||
|
v := newRestoreVaultik(ctx, cfg, gate, fs)
|
||||||
|
v.UI = ui.NewWithColor(&out, false)
|
||||||
|
|
||||||
|
restoreErr := make(chan error, 1)
|
||||||
|
|
||||||
|
go func() {
|
||||||
|
restoreErr <- v.Restore(&RestoreOptions{
|
||||||
|
SnapshotID: snapshotID,
|
||||||
|
TargetDir: filepath.Join(tempDir, "restored"),
|
||||||
|
SkipErrors: true,
|
||||||
|
})
|
||||||
|
}()
|
||||||
|
|
||||||
|
select {
|
||||||
|
case <-gate.entered:
|
||||||
|
case <-time.After(30 * time.Second):
|
||||||
|
t.Fatal("restore never reached the blob-download phase")
|
||||||
|
}
|
||||||
|
|
||||||
|
cancel()
|
||||||
|
|
||||||
|
require.ErrorIs(t, <-restoreErr, context.Canceled)
|
||||||
|
assert.NotContains(t, out.String(), srcPath,
|
||||||
|
"the cancel was reported as a failed file")
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user