veyron/tools/playground: Add test.sh for the builder tool.
Change-Id: Idf7b99b3ce40f9e9bb7c6b28eb84b4c03ae49179
diff --git a/tools/playground/builder/vbuild.go b/tools/playground/builder/vbuild.go
index 3579760..b9decde 100644
--- a/tools/playground/builder/vbuild.go
+++ b/tools/playground/builder/vbuild.go
@@ -116,8 +116,15 @@
log.Fatal(err)
}
- CreateIdentities(r)
- if err = StartMount(); err != nil {
+ err = CreateIdentities(r)
+ if err != nil {
+ log.Fatal(err)
+ }
+ mt, err := StartMount()
+ if mt != nil {
+ defer mt.Kill()
+ }
+ if err != nil {
log.Fatal(err)
}
CompileAndRun(r)
@@ -217,10 +224,9 @@
func (f *CodeFile) Compile() error {
var cmd *exec.Cmd
if path.Ext(f.Name) == ".vdl" {
- cmd = MakeCmd("vdl", "generate", f.pkg)
+ cmd = MakeCmd("vdl", "generate", "--lang=go", f.pkg)
} else {
- cmd = MakeCmd("go", "install", f.pkg)
- cmd.Dir = "/usr/local/veyron/veyron"
+ cmd = MakeCmd(path.Join(os.Getenv("VEYRON_ROOT"), "veyron/scripts/build/go"), "install", f.pkg)
}
cmd.Stdout = cmd.Stderr
err := cmd.Run()
@@ -241,16 +247,46 @@
}
func (id Identity) Create() error {
- args := make([]string, 0, 10)
- args = append(args, "--name", id.Name)
- if id.Blesser != "" {
- args = append(args, "--blesser", path.Join("ids", id.Blesser))
+ if err := id.generate(); err != nil {
+ return err
}
+ if id.Blesser != "" || id.Duration != "" {
+ return id.bless()
+ }
+ return nil
+}
+
+func (id Identity) generate() error {
+ args := []string{"generate"}
+ if id.Blesser == "" && id.Duration == "" {
+ args = append(args, id.Name)
+ }
+ return runIdentity(args, path.Join("ids", id.Name))
+}
+
+func (id Identity) bless() error {
+ filename := path.Join("ids", id.Name)
+ var blesser string
+ if id.Blesser == "" {
+ blesser = filename
+ } else {
+ blesser = path.Join("ids", id.Blesser)
+ }
+ args := []string{"bless", "--with", blesser}
if id.Duration != "" {
- args = append(args, "--duration", id.Duration)
+ args = append(args, "--for", id.Duration)
}
+ args = append(args, filename, id.Name)
+ tempfile := filename + ".tmp"
+ if err := runIdentity(args, tempfile); err != nil {
+ return err
+ }
+ return os.Rename(tempfile, filename)
+}
+
+func runIdentity(args []string, filename string) error {
cmd := MakeCmd("identity", args...)
- out, err := os.Create(path.Join("ids", id.Name))
+ out, err := os.Create(filename)
if err != nil {
return err
}
@@ -259,14 +295,14 @@
return cmd.Run()
}
-func StartMount() (err error) {
+func StartMount() (proc *os.Process, err error) {
reader, writer := io.Pipe()
cmd := MakeCmd("mounttabled")
cmd.Stdout = writer
cmd.Stderr = cmd.Stdout
err = cmd.Start()
if err != nil {
- return err
+ return nil, err
}
buf := bufio.NewReader(reader)
pat := regexp.MustCompile("Mount table .+ endpoint: (.+)\n")
@@ -291,7 +327,7 @@
log.Fatal("mounttable died")
}
Log("mount at ", endpoint)
- return os.Setenv("NAMESPACE_ROOT", endpoint)
+ return cmd.Process, os.Setenv("NAMESPACE_ROOT", endpoint)
}
- return err
+ return cmd.Process, err
}
diff --git a/tools/playground/test.sh b/tools/playground/test.sh
new file mode 100755
index 0000000..fa69c8e
--- /dev/null
+++ b/tools/playground/test.sh
@@ -0,0 +1,58 @@
+#!/bin/bash
+
+# Test the playground builder tool.
+
+source "${VEYRON_ROOT}/environment/scripts/lib/shell_test.sh"
+
+build() {
+ local -r GO="${REPO_ROOT}/scripts/build/go"
+ "${GO}" build veyron/tools/identity || shell_test::fail "line ${LINENO}: failed to build 'identity'"
+ "${GO}" build veyron/services/mounttable/mounttabled || shell_test::fail "line ${LINENO}: failed to build 'mounttabled'"
+ "${GO}" build veyron2/vdl/vdl || shell_test::fail "line ${LINENO}: failed to build 'vdl'"
+ "${GO}" build veyron/tools/playground/builder || shell_test::fail "line ${LINENO}: failed to build 'builder'"
+ "${GO}" build veyron/tools/playground/testdata/escaper || shell_test::fail "line ${LINENO}: failed to build 'escaper'"
+}
+
+test_with_files() {
+ echo '{"Files":[' > request.json
+ while [[ $# > 0 ]]; do
+ echo '{"Name":"'"$(basename $1)"'","Body":' >>request.json
+ grep -v OMIT $1 | ./escaper >>request.json
+ shift
+ if [[ $# > 0 ]]; then
+ echo '},' >>request.json
+ else
+ echo '}' >>request.json
+ fi
+ done
+ echo ']}' >>request.json
+ rm -f builder.out
+ ./builder <request.json 2>&1 | tee builder.out
+}
+
+main() {
+ cd $(shell::tmp_dir)
+ build
+
+ local -r DIR="${REPO_ROOT}/go/src/veyron/tools/playground/testdata"
+
+ export GOPATH="$(pwd)"
+ export PATH="$(pwd):$PATH"
+ test_with_files $DIR/pingpong/wire.vdl $DIR/pong/pong.go $DIR/ping/ping.go || shell_test::fail "line ${LINENO}: basic ping"
+ grep -q ping builder.out || shell_test::fail "line ${LINENO}: no ping"
+ grep -q pong builder.out || shell_test::fail "line ${LINENO}: no pong"
+
+ test_with_files $DIR/pingpong/wire.vdl $DIR/pong/pong.go $DIR/ping/ping.go $DIR/ids/authorized.id || shell_test::fail "line ${LINENO}: authorized id"
+ grep -q ping builder.out || shell_test::fail "line ${LINENO}: no ping"
+ grep -q pong builder.out || shell_test::fail "line ${LINENO}: no pong"
+
+ test_with_files $DIR/pingpong/wire.vdl $DIR/pong/pong.go $DIR/ping/ping.go $DIR/ids/expired.id || shell_test::fail "line ${LINENO}: failed to build with expired id"
+ grep -q "ipc: not authorized" builder.out || shell_test::fail "line ${LINENO}: rpc with expired id succeeded"
+
+ test_with_files $DIR/pingpong/wire.vdl $DIR/pong/pong.go $DIR/ping/ping.go $DIR/ids/unauthorized.id || shell_test::fail "line ${LINENO}: failed to build with unauthorized id"
+ grep -q "ipc: not authorized" builder.out || shell_test::fail "line ${LINENO}: rpc with unauthorized id succeeded"
+
+ shell_test::pass
+}
+
+main "$@"
diff --git a/tools/playground/testdata/escaper/main.go b/tools/playground/testdata/escaper/main.go
new file mode 100644
index 0000000..9f867e1
--- /dev/null
+++ b/tools/playground/testdata/escaper/main.go
@@ -0,0 +1,19 @@
+package main
+
+import (
+ "encoding/json"
+ "io/ioutil"
+ "os"
+)
+
+func main() {
+ data, err := ioutil.ReadAll(os.Stdin)
+ if err != nil {
+ panic(err)
+ }
+ out, err := json.Marshal(string(data))
+ if err != nil {
+ panic(err)
+ }
+ os.Stdout.Write(out)
+}
diff --git a/tools/playground/testdata/ids/authorized.id b/tools/playground/testdata/ids/authorized.id
new file mode 100644
index 0000000..8a1f950
--- /dev/null
+++ b/tools/playground/testdata/ids/authorized.id
@@ -0,0 +1,15 @@
+[
+{
+ "Name": "myorg"
+},
+{
+ "Name": "myserver",
+ "Blesser": "myorg",
+ "Files": ["pong.go"]
+},
+{
+ "Name": "myclient",
+ "Blesser": "myserver",
+ "Files": ["ping.go"]
+}
+]
\ No newline at end of file
diff --git a/tools/playground/testdata/ids/expired.id b/tools/playground/testdata/ids/expired.id
new file mode 100644
index 0000000..6ff368d
--- /dev/null
+++ b/tools/playground/testdata/ids/expired.id
@@ -0,0 +1,7 @@
+[
+{
+ "Name": "expired",
+ "Duration": "0s",
+ "Files": ["ping.go", "pong.go"]
+}
+]
\ No newline at end of file
diff --git a/tools/playground/testdata/ids/unauthorized.id b/tools/playground/testdata/ids/unauthorized.id
new file mode 100644
index 0000000..544343b
--- /dev/null
+++ b/tools/playground/testdata/ids/unauthorized.id
@@ -0,0 +1,15 @@
+[
+{
+ "Name": "myorg"
+},
+{
+ "Name": "myserver",
+ "Blesser": "myorg",
+ "Files": ["pong.go"]
+},
+{
+ "Name": "myclient",
+ "Blesser": "myorg",
+ "Files": ["ping.go"]
+}
+]
\ No newline at end of file
diff --git a/tools/playground/testdata/ping/ping.go b/tools/playground/testdata/ping/ping.go
new file mode 100644
index 0000000..725c102
--- /dev/null
+++ b/tools/playground/testdata/ping/ping.go
@@ -0,0 +1,24 @@
+// +build OMIT
+package main
+
+import (
+ "fmt"
+ "pingpong"
+ "veyron2/rt"
+)
+
+func main() {
+ runtime := rt.Init()
+ log := runtime.Logger()
+
+ s, err := pingpong.BindPingPong("pingpong")
+ if err != nil {
+ log.Fatal("error binding to server: ", err)
+ }
+
+ pong, err := s.Ping(runtime.NewContext(), "ping")
+ if err != nil {
+ log.Fatal("error pinging: ", err)
+ }
+ fmt.Println(pong)
+}
diff --git a/tools/playground/testdata/pingpong/wire.vdl b/tools/playground/testdata/pingpong/wire.vdl
new file mode 100644
index 0000000..b4e8e0a
--- /dev/null
+++ b/tools/playground/testdata/pingpong/wire.vdl
@@ -0,0 +1,5 @@
+package pingpong
+
+type PingPong interface {
+ Ping(message string) (string, error)
+}
\ No newline at end of file
diff --git a/tools/playground/testdata/pong/pong.go b/tools/playground/testdata/pong/pong.go
new file mode 100644
index 0000000..fa961f8
--- /dev/null
+++ b/tools/playground/testdata/pong/pong.go
@@ -0,0 +1,43 @@
+// +build OMIT
+package main
+
+import (
+ "fmt"
+ "pingpong"
+ "veyron/lib/signals"
+ sflag "veyron/security/flag"
+ "veyron2/ipc"
+ "veyron2/rt"
+)
+
+type pongd struct{}
+
+func (f *pongd) Ping(_ ipc.ServerContext, message string) (result string, err error) {
+ fmt.Println(message)
+ return "pong", nil
+}
+
+func main() {
+ r := rt.Init()
+ log := r.Logger()
+ s, err := r.NewServer()
+ if err != nil {
+ log.Fatal("failure creating server: ", err)
+ }
+ log.Info("Waiting for ping")
+
+ serverPong := pingpong.NewServerPingPong(&pongd{})
+
+ if endpoint, err := s.Listen("tcp", "127.0.0.1:0"); err == nil {
+ fmt.Printf("Listening at: %v\n", endpoint)
+ } else {
+ log.Fatal("error listening to service: ", err)
+ }
+
+ if err := s.Serve("pingpong", ipc.LeafDispatcher(serverPong, sflag.NewAuthorizerOrDie())); err != nil {
+ log.Fatal("error serving service: ", err)
+ }
+
+ // Wait forever.
+ <-signals.ShutdownOnSignals()
+}