Write only the document to stdout from snapshot remove --json (closes #251)
check / check (push) Waiting to run
check / check (push) Waiting to run
When the destination store cannot be reached, `snapshot remove` still removes the snapshot from the local index and warns. The warning went through the UI, which writes to stdout, so under `--json` it landed ahead of the document and `| jq` failed on a command that exited 0. Under `--json` the UI warning is now skipped, and the logger's warning on stderr carries the follow-up. That follow-up, in the warning, the README and the command's help, said `vaultik prune` would finish the cleanup, but `prune` never removes snapshot metadata. They now say to run `vaultik snapshot remove` for the snapshot again once the destination store is reachable. The new test removes a snapshot from the local index against a missing destination directory and checks both streams. Model: opus-5-5
This commit is contained in:
@@ -87,12 +87,33 @@ func TestEntryJSONFailureIsReportedOnStderr(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// writeUnusableDestinationConfig builds a config whose destination
|
||||
// directory does not exist, which fails `remote info`, and whose local
|
||||
// index is bound to another destination, which fails `prune` and
|
||||
// `snapshot remove` (a missing destination alone only makes `snapshot
|
||||
// remove` warn). Returns the config path.
|
||||
func writeUnusableDestinationConfig(t *testing.T) string {
|
||||
// TestEntrySnapshotRemoveJSONWarningIsOnStderr runs `snapshot remove
|
||||
// --json` on a snapshot in the local index, against a destination
|
||||
// directory that does not exist. The command removes the snapshot from
|
||||
// the local index and still exits 0. Its stdout must hold the document
|
||||
// alone, with the warning about the destination store, and the command
|
||||
// to run again once it is reachable, on stderr.
|
||||
//
|
||||
//nolint:paralleltest // replaces os.Args, os.Stdout, os.Stderr and the xdg globals
|
||||
func TestEntrySnapshotRemoveJSONWarningIsOnStderr(t *testing.T) {
|
||||
configPath, indexPath := writeMissingDestinationConfig(t)
|
||||
seedStaleSnapshotRecord(t, indexPath)
|
||||
|
||||
code, stdout, stderr := runEntry(t, flagConfig, configPath,
|
||||
cmdSnapshot, cmdRemove, stalePruneSnapshotID, flagJSON)
|
||||
|
||||
require.Equal(t, 0, code)
|
||||
requireExactlyOneJSONDocument(t, stdout)
|
||||
assert.Contains(t, stderr,
|
||||
"Could not remove snapshot metadata from remote storage")
|
||||
assert.Contains(t, stderr,
|
||||
"run 'vaultik snapshot remove "+stalePruneSnapshotID+"' again")
|
||||
}
|
||||
|
||||
// writeMissingDestinationConfig builds a config whose destination
|
||||
// directory does not exist. Returns the config path and the path of
|
||||
// its local index, which is not created here.
|
||||
func writeMissingDestinationConfig(t *testing.T) (string, string) {
|
||||
t.Helper()
|
||||
|
||||
dir := t.TempDir()
|
||||
@@ -114,6 +135,19 @@ func writeUnusableDestinationConfig(t *testing.T) string {
|
||||
xdg.Reload()
|
||||
t.Cleanup(xdg.Reload)
|
||||
|
||||
return configPath, indexPath
|
||||
}
|
||||
|
||||
// writeUnusableDestinationConfig builds a config whose destination
|
||||
// directory does not exist, which fails `remote info`, and whose local
|
||||
// index is bound to another destination, which fails `prune` and
|
||||
// `snapshot remove` (a missing destination alone only makes `snapshot
|
||||
// remove` warn). Returns the config path.
|
||||
func writeUnusableDestinationConfig(t *testing.T) string {
|
||||
t.Helper()
|
||||
|
||||
configPath, indexPath := writeMissingDestinationConfig(t)
|
||||
|
||||
ctx := context.Background()
|
||||
|
||||
db, err := database.New(ctx, indexPath)
|
||||
@@ -122,7 +156,7 @@ func writeUnusableDestinationConfig(t *testing.T) string {
|
||||
defer func() { require.NoError(t, db.Close()) }()
|
||||
|
||||
require.NoError(t, database.NewRepositories(db).LocalMeta.Set(ctx,
|
||||
database.LocalMetaKeyStorageURL, "file://"+filepath.Join(dir, "other")))
|
||||
database.LocalMetaKeyStorageURL, "file://"+t.TempDir()))
|
||||
|
||||
return configPath
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user