From cfaf8ab8a66c765555626081db8880778b6f66d5 Mon Sep 17 00:00:00 2001 From: Alexander Neumann Date: Sun, 21 Jun 2015 15:01:52 +0200 Subject: [PATCH] Add integration test for key handling --- cmd/restic/cmd_key.go | 32 +++------- cmd/restic/global.go | 4 ++ cmd/restic/integration_test.go | 103 +++++++++++++++++++++++-------- testsuite/test-key-add-remove.sh | 42 ------------- 4 files changed, 90 insertions(+), 91 deletions(-) delete mode 100755 testsuite/test-key-add-remove.sh diff --git a/cmd/restic/cmd_key.go b/cmd/restic/cmd_key.go index 201e23c0f..ad1a358fd 100644 --- a/cmd/restic/cmd_key.go +++ b/cmd/restic/cmd_key.go @@ -3,14 +3,14 @@ package main import ( "errors" "fmt" - "os" "github.com/restic/restic/backend" "github.com/restic/restic/repository" ) type CmdKey struct { - global *GlobalOptions + global *GlobalOptions + newPassword string } func init() { @@ -56,25 +56,18 @@ func (cmd CmdKey) listKeys(s *repository.Repository) error { return tab.Write(cmd.global.stdout) } -func (cmd CmdKey) getNewPassword() (string, error) { - newPassword := os.Getenv("RESTIC_NEWPASSWORD") - - if newPassword == "" { - newPassword = cmd.global.ReadPasswordTwice( - "enter password for new key: ", - "enter password again: ") +func (cmd CmdKey) getNewPassword() string { + if cmd.newPassword != "" { + return cmd.newPassword } - return newPassword, nil + return cmd.global.ReadPasswordTwice( + "enter password for new key: ", + "enter password again: ") } func (cmd CmdKey) addKey(repo *repository.Repository) error { - newPassword, err := cmd.getNewPassword() - if err != nil { - return err - } - - id, err := repository.AddKey(repo, newPassword, repo.Key()) + id, err := repository.AddKey(repo, cmd.getNewPassword(), repo.Key()) if err != nil { return fmt.Errorf("creating new key failed: %v\n", err) } @@ -99,12 +92,7 @@ func (cmd CmdKey) deleteKey(repo *repository.Repository, name string) error { } func (cmd CmdKey) changePassword(repo *repository.Repository) error { - newPassword, err := cmd.getNewPassword() - if err != nil { - return err - } - - id, err := repository.AddKey(repo, newPassword, repo.Key()) + id, err := repository.AddKey(repo, cmd.getNewPassword(), repo.Key()) if err != nil { return fmt.Errorf("creating new key failed: %v\n", err) } diff --git a/cmd/restic/global.go b/cmd/restic/global.go index 7c411a85c..79c9eaf98 100644 --- a/cmd/restic/global.go +++ b/cmd/restic/global.go @@ -82,6 +82,10 @@ func (o GlobalOptions) ReadPassword(prompt string) string { } fmt.Fprintln(os.Stderr) + if len(pw) == 0 { + o.Exitf(1, "an empty password is not a password") + } + return string(pw) } diff --git a/cmd/restic/integration_test.go b/cmd/restic/integration_test.go index 9d905790c..22e00ded5 100644 --- a/cmd/restic/integration_test.go +++ b/cmd/restic/integration_test.go @@ -2,12 +2,14 @@ package main import ( "bufio" + "bytes" "crypto/rand" "fmt" "io" "os" "os/exec" "path/filepath" + "regexp" "testing" "github.com/restic/restic/backend" @@ -62,16 +64,12 @@ func cmdBackup(t testing.TB, global GlobalOptions, target []string, parentID bac } func cmdList(t testing.TB, global GlobalOptions, tpe string) []backend.ID { - rd, wr := io.Pipe() - global.stdout = wr + var buf bytes.Buffer + global.stdout = &buf cmd := &CmdList{global: &global} - go func() { - OK(t, cmd.Execute([]string{tpe})) - OK(t, wr.Close()) - }() - - IDs := parseIDsFromReader(t, rd) + OK(t, cmd.Execute([]string{tpe})) + IDs := parseIDsFromReader(t, &buf) return IDs } @@ -86,11 +84,6 @@ func cmdFsck(t testing.TB, global GlobalOptions) { OK(t, cmd.Execute(nil)) } -func cmdKey(t testing.TB, global GlobalOptions, args ...string) { - cmd := &CmdKey{global: &global} - OK(t, cmd.Execute(args)) -} - func TestBackup(t *testing.T) { withTestEnvironment(t, func(env *testEnvironment, global GlobalOptions) { datafile := filepath.Join("testdata", "backup-data.tar.gz") @@ -181,10 +174,6 @@ func appendRandomData(filename string, bytes uint) error { return f.Close() } -func TestInit(t *testing.T) { - -} - func TestIncrementalBackup(t *testing.T) { withTestEnvironment(t, func(env *testEnvironment, global GlobalOptions) { datafile := filepath.Join("testdata", "backup-data.tar.gz") @@ -229,18 +218,78 @@ func TestIncrementalBackup(t *testing.T) { }) } -func TestKeyAddRemove(t *testing.T) { - withTestEnvironment(t, func(env *testEnvironment, global GlobalOptions) { - datafile := filepath.Join("testdata", "backup-data.tar.gz") - fd, err := os.Open(datafile) - if os.IsNotExist(err) { - t.Skipf("unable to find data file %q, skipping", datafile) - return - } - OK(t, err) - OK(t, fd.Close()) +func cmdKey(t testing.TB, global GlobalOptions, args ...string) string { + var buf bytes.Buffer + global.stdout = &buf + cmd := &CmdKey{global: &global} + OK(t, cmd.Execute(args)) + + return buf.String() +} + +func cmdKeyListOtherIDs(t testing.TB, global GlobalOptions) []string { + var buf bytes.Buffer + + global.stdout = &buf + cmd := &CmdKey{global: &global} + OK(t, cmd.Execute([]string{"list"})) + + scanner := bufio.NewScanner(&buf) + exp := regexp.MustCompile(`^ ([a-f0-9]+) `) + + IDs := []string{} + for scanner.Scan() { + if id := exp.FindStringSubmatch(scanner.Text()); id != nil { + IDs = append(IDs, id[1]) + } + } + + return IDs +} + +func cmdKeyAddNewKey(t testing.TB, global GlobalOptions, newPassword string) { + cmd := &CmdKey{global: &global, newPassword: newPassword} + OK(t, cmd.Execute([]string{"add"})) +} + +func cmdKeyPasswd(t testing.TB, global GlobalOptions, newPassword string) { + cmd := &CmdKey{global: &global, newPassword: newPassword} + OK(t, cmd.Execute([]string{"passwd"})) +} + +func cmdKeyRemove(t testing.TB, global GlobalOptions, IDs []string) { + cmd := &CmdKey{global: &global} + t.Logf("remove %d keys: %q\n", len(IDs), IDs) + for _, id := range IDs { + OK(t, cmd.Execute([]string{"rm", id})) + } +} + +func TestKeyAddRemove(t *testing.T) { + passwordList := []string{ + "OnnyiasyatvodsEvVodyawit", + "raicneirvOjEfEigonOmLasOd", + } + + withTestEnvironment(t, func(env *testEnvironment, global GlobalOptions) { cmdInit(t, global) + + cmdKeyPasswd(t, global, "geheim2") + global.password = "geheim2" + t.Logf("changed password to %q", global.password) + + for _, newPassword := range passwordList { + cmdKeyAddNewKey(t, global, newPassword) + t.Logf("added new password %q", newPassword) + global.password = newPassword + cmdKeyRemove(t, global, cmdKeyListOtherIDs(t, global)) + } + + global.password = passwordList[len(passwordList)-1] + t.Logf("testing access with last password %q\n", global.password) cmdKey(t, global, "list") + + cmdFsck(t, global) }) } diff --git a/testsuite/test-key-add-remove.sh b/testsuite/test-key-add-remove.sh deleted file mode 100755 index b012ea552..000000000 --- a/testsuite/test-key-add-remove.sh +++ /dev/null @@ -1,42 +0,0 @@ -set -e - -dump_repo() { - if [ "$FAILED" == "1" ]; then - tar cvz "$RESTIC_REPOSITORY" | base64 >&2 - fi -} - -FAILED=1 - -trap dump_repo 0 - -prepare -unset RESTIC_PASSWORD -RESTIC_PASSWORD=foo run restic init -RESTIC_PASSWORD=foo run restic key list - -RESTIC_PASSWORD=foo RESTIC_NEWPASSWORD=foobar run restic key passwd -RESTIC_PASSWORD=foobar run restic key list -RESTIC_PASSWORD=foobar RESTIC_NEWPASSWORD=foo run restic key passwd - -OLD_PWD=foo -for i in {1..3}; do - NEW_PWD=bar$i - RESTIC_PASSWORD=$OLD_PWD RESTIC_NEWPASSWORD=$NEW_PWD run restic key add - RESTIC_PASSWORD=$OLD_PWD run restic key list - RESTIC_PASSWORD=$NEW_PWD run restic key list - - export RESTIC_PASSWORD=$OLD_PWD - ID=$(restic key list | grep '^\*'|cut -d ' ' -f 1| sed 's/^.//') - unset RESTIC_PASSWORD - RESTIC_PASSWORD=$NEW_PWD run restic key rm $ID - RESTIC_PASSWORD=$NEW_PWD run restic key list - - OLD_PWD=bar$i -done - -RESTIC_PASSWORD=$OLD_PWD run restic fsck -o --check-data - -cleanup - -FAILED=0