cmd/principal: addtoroots reorg and test.

(1) addtoroots shouldn't be a subcommand of the store, it has nothing to
do with the store. So move it out to the top level, similar to the
method on security.Principal

(2) add a test for it.

Change-Id: I3ba87226112fbc01f6da08e63584428452fd446a
diff --git a/cmd/principal/doc.go b/cmd/principal/doc.go
index 209bd34..42f6d6a 100644
--- a/cmd/principal/doc.go
+++ b/cmd/principal/doc.go
@@ -22,6 +22,7 @@
    blessself     Generate a self-signed blessing
    bless         Bless another principal
    store         Manipulate and inspect the principal's blessing store
+   addtoroots    Add provided blessings to root set
    help          Display help for commands or topics
 Run "principal help [command]" for command usage.
 
@@ -301,7 +302,6 @@
    setdefault  Set provided blessings as default
    forpeer     Return blessings marked for the provided peer
    set         Set provided blessings for peer
-   addtoroots  Add provided blessings to root set
 
 Principal Store Default
 
@@ -372,7 +372,7 @@
    If true, the root certificate of the blessing will be added to the
    principal's set of recognized root certificates
 
-Principal Store Addtoroots
+Principal Addtoroots
 
 Adds the provided blessings to the set of trusted roots for this principal.
 
@@ -381,12 +381,12 @@
 For example, to make the principal in credentials directory A trust the root of
 the default blessing in credentials directory B:
   principal -veyron.credentials=B bless A some_extension |
-  principal -veyron.credentials=A store addtoroots -
+  principal -veyron.credentials=A addtoroots -
 
 The extension 'some_extension' has no effect in the command above.
 
 Usage:
-   principal store addtoroots <file>
+   principal addtoroots <file>
 
 <file> is the path to a file containing a blessing typically obtained from this
 tool. - is used for STDIN.
diff --git a/cmd/principal/main.go b/cmd/principal/main.go
index 550c270..03f4d24 100644
--- a/cmd/principal/main.go
+++ b/cmd/principal/main.go
@@ -358,7 +358,7 @@
 		},
 	}
 
-	cmdStoreAddToRoots = &cmdline.Command{
+	cmdAddToRoots = &cmdline.Command{
 		Name:  "addtoroots",
 		Short: "Add provided blessings to root set",
 		Long: `
@@ -369,7 +369,7 @@
 For example, to make the principal in credentials directory A trust the
 root of the default blessing in credentials directory B:
   principal -veyron.credentials=B bless A some_extension |
-  principal -veyron.credentials=A store addtoroots -
+  principal -veyron.credentials=A addtoroots -
 
 The extension 'some_extension' has no effect in the command above.
 `,
@@ -729,7 +729,7 @@
 
 All blessings are printed to stdout using base64-VOM-encoding
 `,
-		Children: []*cmdline.Command{cmdStoreDefault, cmdStoreSetDefault, cmdStoreForPeer, cmdStoreSet, cmdStoreAddToRoots},
+		Children: []*cmdline.Command{cmdStoreDefault, cmdStoreSetDefault, cmdStoreForPeer, cmdStoreSet},
 	}
 
 	root := &cmdline.Command{
@@ -741,7 +741,7 @@
 
 All objects are printed using base64-VOM-encoding.
 `,
-		Children: []*cmdline.Command{cmdCreate, cmdFork, cmdSeekBlessings, cmdRecvBlessings, cmdDump, cmdDumpBlessings, cmdBlessSelf, cmdBless, cmdStore},
+		Children: []*cmdline.Command{cmdCreate, cmdFork, cmdSeekBlessings, cmdRecvBlessings, cmdDump, cmdDumpBlessings, cmdBlessSelf, cmdBless, cmdStore, cmdAddToRoots},
 	}
 	os.Exit(root.Main())
 }
diff --git a/cmd/principal/principal_v23_test.go b/cmd/principal/principal_v23_test.go
index 41b6433..fdc1718 100644
--- a/cmd/principal/principal_v23_test.go
+++ b/cmd/principal/principal_v23_test.go
@@ -2,6 +2,7 @@
 
 import (
 	"bytes"
+	"fmt"
 	"io/ioutil"
 	"os"
 	"path/filepath"
@@ -468,3 +469,47 @@
 		}
 	}
 }
+
+func V23TestAddToRoots(t *v23tests.T) {
+	var (
+		bin          = t.BuildGoPkg("v.io/x/ref/cmd/principal")
+		aliceDir     = t.NewTempDir()
+		bobDir       = t.NewTempDir()
+		blessingFile = filepath.Join(t.NewTempDir(), "bobfile")
+
+		// Extract the public key from the first line of output from
+		// "principal dump", which is formatted as:
+		// Public key : <the public key>
+		publicKey = func(dir string) string {
+			output := bin.Start("--veyron.credentials="+dir, "dump").Output()
+			line := strings.SplitN(output, "\n", 2)[0]
+			fields := strings.Split(line, " ")
+			return fields[len(fields)-1]
+		}
+	)
+	// Create two principals, "alice" and "bob"
+	bin.Start("create", aliceDir, "alice").WaitOrDie(os.Stdout, os.Stderr)
+	bin.Start("create", bobDir, "bob").WaitOrDie(os.Stdout, os.Stderr)
+	// Have bob create a "bob/friend" blessing and have alice recognize that.
+	redirect(t, bin.Start("--veyron.credentials="+bobDir, "bless", "--require_caveats=false", aliceDir, "friend"), blessingFile)
+	bin.Start("--veyron.credentials="+aliceDir, "addtoroots", blessingFile).WaitOrDie(os.Stdout, os.Stderr)
+	var (
+		// blessing roots lines that should match the keys
+		aliceLine = fmt.Sprintf("%v : [alice]", publicKey(aliceDir))
+		bobLine   = fmt.Sprintf("%v : [bob]", publicKey(bobDir))
+
+		foundAlice, foundBob bool
+	)
+	// Finally dump alice's principal, it should have lines corresponding to aliceLine and bobLine.
+	output := bin.Start("--veyron.credentials="+aliceDir, "dump").Output()
+	for _, line := range strings.Split(output, "\n") {
+		if line == aliceLine {
+			foundAlice = true
+		} else if line == bobLine {
+			foundBob = true
+		}
+	}
+	if !foundAlice || !foundBob {
+		t.Fatalf("Got:\n%v\n\nExpected Blessing Roots to include:\n%s\n%s", output, aliceLine, bobLine)
+	}
+}
diff --git a/cmd/principal/v23_test.go b/cmd/principal/v23_test.go
index 3fb0350..ec323f3 100644
--- a/cmd/principal/v23_test.go
+++ b/cmd/principal/v23_test.go
@@ -59,3 +59,7 @@
 func TestV23Bless(t *testing.T) {
 	v23tests.RunTest(t, V23TestBless)
 }
+
+func TestV23AddToRoots(t *testing.T) {
+	v23tests.RunTest(t, V23TestAddToRoots)
+}