veyron/lib/testutil/blackbox: Sanitize sub-process environment.
Some shells (e.g. P9P's rc) add environment strings that cannot be parsed
by bash when it attempts to run one of Veyron's generated shell scripts.
This change modifies blackbox's subprocess code to only include
explicitly white-listed environment variables in the environment of
Veyron processes: everything starting with VEYRON_, NAMESPACE_ROOT and
PAUSE_BEFORE_STOP.
Change-Id: Ie420b18dfbc48955b2b28255df128844b9ff4276
diff --git a/lib/testutil/blackbox/subprocess.go b/lib/testutil/blackbox/subprocess.go
index 0cb8092..984062b 100644
--- a/lib/testutil/blackbox/subprocess.go
+++ b/lib/testutil/blackbox/subprocess.go
@@ -53,6 +53,31 @@
return "--test.timeout=1m"
}
+// VeyronEnvironment returns only the environment variables needed for
+// Veyron execution from the provided list.
+func VeyronEnvironment(env []string) []string {
+ veyronEnvironmentPrefixes := []string{
+ "VEYRON_",
+ "NAMESPACE_ROOT",
+ "PAUSE_BEFORE_STOP",
+ "TMPDIR",
+ }
+
+ var ret []string
+ for _, e := range env {
+ if eqIdx := strings.Index(e, "="); eqIdx > 0 {
+ key := e[:eqIdx]
+ for _, prefix := range veyronEnvironmentPrefixes {
+ if strings.HasPrefix(key, prefix) {
+ ret = append(ret, fmt.Sprintf("%s=%s", key, e[eqIdx+1:]))
+ break
+ }
+ }
+ }
+ }
+ return ret
+}
+
// HelperCommand() takes an argument list and starts a helper subprocess.
// t maybe nil to allow use from outside of tests.
func HelperCommand(t *testing.T, command string, args ...string) *Child {
@@ -77,7 +102,8 @@
} else {
cmd.Stderr = stderr
}
- cmd.Env = append([]string{"VEYRON_BLACKBOX_TEST=1"}, os.Environ()...)
+
+ cmd.Env = append([]string{"VEYRON_BLACKBOX_TEST=1"}, VeyronEnvironment(os.Environ())...)
stdout, _ := cmd.StdoutPipe()
stdin, _ := cmd.StdinPipe()
return &Child{
diff --git a/lib/testutil/blackbox/subprocess_test.go b/lib/testutil/blackbox/subprocess_test.go
index 5105346..d3f8bf3 100644
--- a/lib/testutil/blackbox/subprocess_test.go
+++ b/lib/testutil/blackbox/subprocess_test.go
@@ -7,6 +7,7 @@
"fmt"
"io"
"os"
+ "reflect"
"strconv"
"strings"
"syscall"
@@ -251,3 +252,30 @@
waitForNonExistence(t, []int{child})
}
+
+func TestVeyronEnvironmentment(t *testing.T) {
+ in := [][]string{
+ []string{},
+ []string{"Hello", "NO=1"},
+ []string{"VEYRON_X=1", "Hello"},
+ []string{"NAMESPACE_ROOT=1", "VEYRON_IDENTITY=me"},
+ []string{"PAUSE_BEFORE_STOP=1", "NAMESPACE_ROOT2=2", "BOB=ALICE", "Hello"},
+ }
+
+ expected := [][]string{
+ []string{},
+ []string{},
+ []string{"VEYRON_X=1"},
+ []string{"NAMESPACE_ROOT=1", "VEYRON_IDENTITY=me"},
+ []string{"PAUSE_BEFORE_STOP=1", "NAMESPACE_ROOT2=2"},
+ }
+
+ for i, _ := range in {
+ s := blackbox.VeyronEnvironment(in[i])
+ if len(s) == 0 && len(expected[i]) == 0 {
+ continue
+ } else if !reflect.DeepEqual(expected[i], s) {
+ t.Fatalf("subtest %d: got %v, expected %v", i, s, expected[i])
+ }
+ }
+}
diff --git a/runtimes/google/rt/rt_test.go b/runtimes/google/rt/rt_test.go
index 0fc425f..06e5fa4 100644
--- a/runtimes/google/rt/rt_test.go
+++ b/runtimes/google/rt/rt_test.go
@@ -66,7 +66,7 @@
os.TempDir())
if str != expected {
- t.Fatalf("unexpected output from child: %s", str)
+ t.Fatalf("incorrect child output: got %s, expected %s", str, expected)
}
c.CloseStdin()
c.Expect("done")
diff --git a/services/mgmt/node/impl/util_test.go b/services/mgmt/node/impl/util_test.go
index caaad5b..d2fed3d 100644
--- a/services/mgmt/node/impl/util_test.go
+++ b/services/mgmt/node/impl/util_test.go
@@ -114,13 +114,13 @@
func updateExpectError(t *testing.T, name string, errID verror.ID) {
if err := invokeUpdate(t, name); !verror.Is(err, errID) {
- t.Fatalf("Unexpected update error %v, expected error ID %v", err, errID)
+ t.Fatalf("Unexpected update on %s error %v, expected error ID %v", name, err, errID)
}
}
func update(t *testing.T, name string) {
if err := invokeUpdate(t, name); err != nil {
- t.Fatalf("Update() failed: %v", err)
+ t.Fatalf("Update() on %s failed: %v", name, err)
}
}