package cli_test import ( "io" "testing" "git.eeqj.de/sneak/secret/internal/cli" "git.eeqj.de/sneak/secret/internal/secret" "git.eeqj.de/sneak/secret/internal/vault" "github.com/spf13/afero" "github.com/spf13/cobra" "github.com/stretchr/testify/require" ) // TestLeftoversRemovedByNextChangingCommand is a regression test for // https://git.eeqj.de/sneak/secret/issues/75. It plants what a command // killed part-way leaves in each directory where secret.TempDirFor and // secret.WriteFileAtomic make temporary entries: a temporary directory // holding a vault, secret, unlocker or version being added or removed, and // a temporary file beside a file being replaced. `secret list` must leave // them all, and the next command that takes the state directory lock, here // `secret vault select` of the vault already current, must delete exactly // them: a vault named like a temporary directory stays. The copy has no // lock file yet, so that command, as after a killed one, finds no mark that // the last holder of the lock finished. func TestLeftoversRemovedByNextChangingCommand(t *testing.T) { t.Parallel() fs := newTwoVaultFs(t) _, err := vault.CreateVault(fs, testStateDir, ".tmp-0", nil) require.NoError(t, err) require.NoError(t, vault.SelectVault(fs, testStateDir, "default")) before := snapshotStateDir(t, fs) vaultDir := testStateDir + "/vaults.d/default" secretDir := vaultDir + "/secrets.d/x" versions, err := secret.ListVersions(fs, secretDir) require.NoError(t, err) require.Len(t, versions, 1) for _, dir := range []string{ testStateDir + "/.tmp-1/default", vaultDir + "/.tmp-2/x", secretDir + "/.tmp-3/" + testVersion, } { require.NoError(t, fs.MkdirAll(dir, secret.DirPerms)) require.NoError(t, afero.WriteFile(fs, dir+"/value.age", []byte("encrypted"), secret.FilePerms)) } for _, file := range []string{ testStateDir + "/.currentvault.tmp-4", vaultDir + "/.current-unlocker.tmp-5", secretDir + "/.current.tmp-6", secretDir + "/versions/" + versions[0] + "/.metadata.age.tmp-7", } { require.NoError(t, afero.WriteFile(fs, file, []byte("partial"), secret.FilePerms)) } planted := snapshotStateDir(t, fs) c := cli.NewCLIInstanceWithStateDir(fs, testStateDir) cmd := &cobra.Command{} cmd.SetOut(io.Discard) require.NoError(t, c.ListSecrets(cmd, false, false, "")) require.Equal(t, planted, snapshotStateDir(t, fs)) require.NoError(t, c.SelectVault(cmd, "default")) require.Equal(t, before, snapshotStateDir(t, fs)) }