veyron/lib/modules: create a fake ID for use in tests.
Change-Id: I3d5ecb5e8117982e1d1f8a2d229cef3602ddc5cf
diff --git a/lib/modules/core/core_test.go b/lib/modules/core/core_test.go
index 25d7df2..89df492 100644
--- a/lib/modules/core/core_test.go
+++ b/lib/modules/core/core_test.go
@@ -15,8 +15,8 @@
"veyron.io/veyron/veyron/lib/expect"
"veyron.io/veyron/veyron/lib/modules"
"veyron.io/veyron/veyron/lib/modules/core"
+
_ "veyron.io/veyron/veyron/lib/testutil"
- "veyron.io/veyron/veyron/lib/testutil/security"
)
func TestCommands(t *testing.T) {
@@ -34,15 +34,12 @@
}
func newShell() (*modules.Shell, func()) {
- shell := core.NewShell()
- idpath := security.SaveIdentityToFile(security.NewBlessedIdentity(rt.R().Identity(), "test"))
- shell.SetVar("VEYRON_IDENTITY", idpath)
- return shell, func() {
- os.Remove(idpath)
+ sh := core.NewShell()
+ return sh, func() {
if testing.Verbose() {
- shell.Cleanup(os.Stderr)
+ sh.Cleanup(os.Stderr)
} else {
- shell.Cleanup(nil)
+ sh.Cleanup(nil)
}
}
}
diff --git a/lib/modules/shell.go b/lib/modules/shell.go
index 7ceaf24..2e35c97 100644
--- a/lib/modules/shell.go
+++ b/lib/modules/shell.go
@@ -34,15 +34,26 @@
// same for both types of command and is defined by the Main function type.
// In particular stdin, stdout and stderr are provided as parameters, as is
// a map representation of the shell's environment.
+//
+// If a Shell is created within a unit test then it will automatically
+// generate a security ID, write it to a file and set the appropriate
+// environment variable to refer to it.
package modules
import (
+ "flag"
"fmt"
"io"
+ "io/ioutil"
+ "os"
+ "path/filepath"
"strings"
"sync"
"veyron.io/veyron/veyron2/vlog"
+
+ isecurity "veyron.io/veyron/veyron/runtimes/google/security"
+ seclib "veyron.io/veyron/veyron/security"
)
// Shell represents the context within which commands are run.
@@ -51,6 +62,7 @@
env map[string]string
cmds map[string]*commandDesc
handles map[Handle]struct{}
+ idfile string
}
type commandDesc struct {
@@ -65,15 +77,46 @@
var child = &childRegistrar{mains: make(map[string]Main)}
-// NewShell creates a new instance of Shell.
+// NewShell creates a new instance of Shell. If this new instance is
+// is a test and no identity has been configured in the environment
+// via VEYRON_IDENTITY then CreateAndUseNewID will be used to configure a new
+// ID for the shell and its children.
func NewShell() *Shell {
// TODO(cnicolaou): should create a new identity if one doesn't
// already exist
- return &Shell{
+ sh := &Shell{
env: make(map[string]string),
cmds: make(map[string]*commandDesc),
handles: make(map[Handle]struct{}),
}
+ if flag.Lookup("test.run") != nil && os.Getenv("VEYRON_IDENTITY") == "" {
+ if err := sh.CreateAndUseNewID(); err != nil {
+ panic(err)
+ }
+ }
+ return sh
+}
+
+// CreateAndUseNewID setups a new ID and then configures the shell and all of its
+// children to use to it.
+func (sh *Shell) CreateAndUseNewID() error {
+ id, err := isecurity.NewPrivateID("test", nil)
+ if err != nil {
+ return err
+ }
+ f, err := ioutil.TempFile("", filepath.Base(os.Args[0]))
+ if err != nil {
+ return err
+ }
+ defer f.Close()
+ filePath := f.Name()
+ if err := seclib.SaveIdentity(f, id); err != nil {
+ os.Remove(filePath)
+ return err
+ }
+ sh.idfile = filePath
+ sh.SetVar("VEYRON_IDENTITY", sh.idfile)
+ return nil
}
type Main func(stdin io.Reader, stdout, stderr io.Writer, env map[string]string, args ...string) error
@@ -209,6 +252,9 @@
for k, _ := range handles {
k.Shutdown(output)
}
+ if len(sh.idfile) > 0 {
+ os.Remove(sh.idfile)
+ }
}
// Handle represents a running command.