Keep command output to the README's stdout and stderr rules (closes #224)
check / check (push) Successful in 16m49s
check / check (push) Successful in 16m49s
The startup banner moves from stdout to stderr, so a `completion` script, a `config get` value and the hidden `__complete` command print only their own output. `--quiet`, `--cron` and `--json` still suppress it. A failing `remote info`, `prune` or `snapshot remove` under `--json` now reports its error on stderr. Their reporters returned early under `--json`, so the failure reached neither stream. `snapshot verify --quiet` writes no report. A failure is still returned and printed on stderr, with the same exit status. Judgement call: the banner's stream, posted on the issue for the owner. Model: opus-5-5
This commit was merged in pull request #252.
This commit is contained in:
@@ -0,0 +1,102 @@
|
||||
package vaultik_test
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"io"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
|
||||
"github.com/spf13/afero"
|
||||
"github.com/stretchr/testify/require"
|
||||
"sneak.berlin/go/vaultik/internal/log"
|
||||
"sneak.berlin/go/vaultik/internal/snapshot"
|
||||
"sneak.berlin/go/vaultik/internal/ui"
|
||||
"sneak.berlin/go/vaultik/internal/vaultik"
|
||||
)
|
||||
|
||||
// TestVerify_QuietSuppressesReport is the --quiet contract for
|
||||
// `snapshot verify`: neither shallow nor deep verify writes its report,
|
||||
// a failed verify still returns its error (which the cli layer prints
|
||||
// on stderr), and the --json document still emits.
|
||||
func TestVerify_QuietSuppressesReport(t *testing.T) {
|
||||
log.Initialize(log.Config{})
|
||||
t.Parallel()
|
||||
|
||||
fs := afero.NewOsFs()
|
||||
tempDir := t.TempDir()
|
||||
|
||||
dataDir := filepath.Join(tempDir, "source")
|
||||
storeDir := filepath.Join(tempDir, "remote")
|
||||
dbPath := filepath.Join(tempDir, "index.sqlite")
|
||||
|
||||
chunkSize := int64(32 * 1024)
|
||||
maxBlobSize := int64(128 * 1024)
|
||||
|
||||
require.NoError(t, fs.MkdirAll(dataDir, 0o755))
|
||||
require.NoError(t, afero.WriteFile(fs,
|
||||
filepath.Join(dataDir, "data.bin"),
|
||||
bytesPattern("quiet-", int(maxBlobSize*2)), 0o644))
|
||||
|
||||
ctx := context.Background()
|
||||
|
||||
cfg, storer, snapshotID := runFileStorageBackup(
|
||||
ctx, t, fs, dataDir, storeDir, dbPath, chunkSize, maxBlobSize)
|
||||
|
||||
// The UI writes to the same buffer as Stdout, as both write to the
|
||||
// process's stdout in production.
|
||||
var stdout bytes.Buffer
|
||||
|
||||
newQuietVerifier := func() *vaultik.Vaultik {
|
||||
v := &vaultik.Vaultik{
|
||||
Config: cfg,
|
||||
Storage: storer,
|
||||
Fs: fs,
|
||||
Stdout: &stdout,
|
||||
Stderr: io.Discard,
|
||||
UI: ui.NewWithColor(&stdout, false),
|
||||
}
|
||||
v.SetContext(ctx)
|
||||
v.UI.SetQuiet(true)
|
||||
|
||||
return v
|
||||
}
|
||||
|
||||
require.NoError(t, newQuietVerifier().VerifySnapshotWithOptions(
|
||||
snapshotID, &vaultik.VerifyOptions{}))
|
||||
require.Empty(t, stdout.String(),
|
||||
"shallow verify must write no report under --quiet")
|
||||
|
||||
require.NoError(t, newQuietVerifier().VerifySnapshotWithOptions(
|
||||
snapshotID, &vaultik.VerifyOptions{Deep: true}))
|
||||
require.Empty(t, stdout.String(),
|
||||
"deep verify must write no report under --quiet")
|
||||
|
||||
require.NoError(t, newQuietVerifier().VerifySnapshotWithOptions(
|
||||
snapshotID, &vaultik.VerifyOptions{JSON: true}))
|
||||
require.Equal(t, "ok", decodeVerifyResult(t, stdout.Bytes()).Status,
|
||||
"the --json document must still emit under --quiet")
|
||||
|
||||
// A snapshot without its encrypted database fails shallow verify. A
|
||||
// failed report also lists each missing blob and each blob of the
|
||||
// wrong size, so remove one blob and grow another.
|
||||
require.NoError(t, os.Remove(filepath.Join(storeDir, "metadata",
|
||||
snapshot.RemoteSnapshotKey(snapshotID), "db.zst.age")))
|
||||
|
||||
blobFiles, err := filepath.Glob(
|
||||
filepath.Join(storeDir, "blobs", "*", "*", "*"))
|
||||
require.NoError(t, err)
|
||||
require.GreaterOrEqual(t, len(blobFiles), 2,
|
||||
"the snapshot must span two blobs, one to remove and one to grow")
|
||||
require.NoError(t, os.Remove(blobFiles[0]))
|
||||
growOneBlob(t, fs, filepath.Join(storeDir, "blobs"))
|
||||
|
||||
stdout.Reset()
|
||||
|
||||
require.Error(t, newQuietVerifier().VerifySnapshotWithOptions(
|
||||
snapshotID, &vaultik.VerifyOptions{}),
|
||||
"--quiet must not change the outcome of a failed verify")
|
||||
require.Empty(t, stdout.String(),
|
||||
"a failed verify must write no report under --quiet")
|
||||
}
|
||||
Reference in New Issue
Block a user