services/device/mgmt_v23_test.go: multi-user integration tests

Modify the multi-user device manager integration tests to run with and
without root when invoked by the builder.

Change-Id: I1c6700d607f966d412beb01493fa768c1398be73
diff --git a/services/device/internal/impl/device_service.go b/services/device/internal/impl/device_service.go
index 4b612d1..58bc028 100644
--- a/services/device/internal/impl/device_service.go
+++ b/services/device/internal/impl/device_service.go
@@ -447,7 +447,7 @@
 		return verror.New(ErrOperationFailed, nil, fmt.Sprintf("EvalSymlinks(%v) failed: %v", os.Args[0], err))
 	}
 
-	if err := os.MkdirAll(logs, 0700); err != nil {
+	if err := os.MkdirAll(logs, 0711); err != nil {
 		return verror.New(ErrOperationFailed, nil, fmt.Sprintf("MkdirAll(%v) failed: %v", logs, err))
 	}
 	stderrLog, stdoutLog := filepath.Join(logs, "STDERR"), filepath.Join(logs, "STDOUT")
diff --git a/services/device/mgmt_v23_test.go b/services/device/mgmt_v23_test.go
index 585c57f..31fce30 100644
--- a/services/device/mgmt_v23_test.go
+++ b/services/device/mgmt_v23_test.go
@@ -70,13 +70,41 @@
 }
 
 func V23TestDeviceManager(i *v23tests.T) {
+	u, err := user.Current()
+	if err != nil {
+		i.Fatalf("couldn't get the current user: %v", err)
+	}
+	testCore(i, u.Username, "", false)
+}
+
+func V23TestDeviceManagerMultiUser(i *v23tests.T) {
+	u, err := user.Current()
+	if err != nil {
+		i.Fatalf("couldn't get the current user: %v", err)
+	}
+
+	if u.Username == "veyron" && runTestOnThisPlatform {
+		// We are running on the builder so run the multiuser
+		// test with default user names. These will be created as
+		// required.
+		makeTestAccounts(i)
+		testCore(i, "vana", "devicemanager", true)
+		return
+	}
+
+	if len(deviceUserFlag) > 0 && len(appUserFlag) > 0 {
+		testCore(i, appUserFlag, deviceUserFlag, true)
+	} else {
+		i.Logf("Test skipped because running in multiuser mode requires --appuser and --deviceuser flags")
+	}
+}
+
+func testCore(i *v23tests.T, appUser, deviceUser string, withSuid bool) {
 	defer fmt.Fprintf(os.Stderr, "--------------- SHUTDOWN ---------------\n")
 	userFlag := "--single_user"
-	withSuid := false
 	tempDir := ""
-	if len(deviceUserFlag) > 0 && len(appUserFlag) > 0 {
-		withSuid = true
-		i.Logf("device user %s, app user %s", deviceUserFlag, appUserFlag)
+
+	if withSuid {
 		// When running --with_suid, TMPDIR must grant the
 		// invoking user rwx permissions and world x permissions for
 		// all parent directories back to /. Otherwise, the
@@ -85,14 +113,6 @@
 		// in /var that is 0700. This is unworkable so force
 		// TMPDIR to /tmp in this case.
 		tempDir = "/tmp"
-	} else if len(deviceUserFlag) > 0 || len(appUserFlag) > 0 {
-		i.Fatalf("Running in multiuser mode requires --appuser and --deviceuser")
-	} else {
-		u, err := user.Current()
-		if err != nil {
-			i.Fatalf("couldn't get the current user: %v", err)
-		}
-		appUserFlag = u.Username
 	}
 
 	var (
@@ -156,7 +176,7 @@
 	}
 
 	if withSuid {
-		deviceScriptArguments = append(deviceScriptArguments, "--devuser="+deviceUserFlag)
+		deviceScriptArguments = append(deviceScriptArguments, "--devuser="+deviceUser)
 	} else {
 		deviceScriptArguments = append(deviceScriptArguments, userFlag)
 	}
@@ -221,10 +241,10 @@
 	mtEP := resolve(mtName)
 
 	if withSuid {
-		deviceBin.Start("associate", "add", mtName+"/devmgr/device", appUserFlag, "root/alice")
+		deviceBin.Start("associate", "add", mtName+"/devmgr/device", appUser, "root/alice")
 
 		aai := deviceBin.Start("associate", "list", mtName+"/devmgr/device")
-		if got, expected := strings.Trim(aai.Output(), "\n "), "root/alice "+appUserFlag; got != expected {
+		if got, expected := strings.Trim(aai.Output(), "\n "), "root/alice "+appUser; got != expected {
 			i.Fatalf("association test, got %v, expected %v", got, expected)
 		}
 	}
@@ -329,8 +349,8 @@
 	if err != nil {
 		i.Errorf("getUserForPid could not determine the user running pid %v", pid)
 	}
-	if uname != appUserFlag {
-		i.Errorf("app expected to be running as %v but is running as %v", appUserFlag, uname)
+	if uname != appUser {
+		i.Errorf("app expected to be running as %v but is running as %v", appUser, uname)
 	}
 
 	// Verify the app's default blessing.
diff --git a/services/device/util_darwin_test.go b/services/device/util_darwin_test.go
index 2a91405..f3ec7f4 100644
--- a/services/device/util_darwin_test.go
+++ b/services/device/util_darwin_test.go
@@ -4,4 +4,13 @@
 
 package device_test
 
+import (
+	"v.io/x/ref/test/v23tests"
+)
+
+const runTestOnThisPlatform = false
 const psFlags = "-ej"
+
+// TODO(rjkroege): Complete test implementation on Darwin.
+func makeTestAccounts(*v23tests.T) {
+}
diff --git a/services/device/util_linux_test.go b/services/device/util_linux_test.go
index bb96666..00f2343 100644
--- a/services/device/util_linux_test.go
+++ b/services/device/util_linux_test.go
@@ -4,4 +4,25 @@
 
 package device_test
 
+import (
+	"os"
+	"os/user"
+
+	"v.io/x/ref/test/v23tests"
+)
+
 const psFlags = "-ef"
+
+func makeTestAccounts(i *v23tests.T) {
+	userAddCmd := i.BinaryFromPath("/usr/bin/sudo")
+
+	if _, err := user.Lookup("vana"); err != nil {
+		userAddCmd.Start("/usr/sbin/adduser", "--no-create-home", "vana").WaitOrDie(os.Stdout, os.Stderr)
+	}
+
+	if _, err := user.Lookup("devicemanager"); err != nil {
+		userAddCmd.Start("/usr/sbin/adduser", "--no-create-home", "devicemanager").Wait(os.Stdout, os.Stderr)
+	}
+}
+
+const runTestOnThisPlatform = true
diff --git a/services/device/v23_test.go b/services/device/v23_test.go
index 597fed2..3eeab2f 100644
--- a/services/device/v23_test.go
+++ b/services/device/v23_test.go
@@ -23,3 +23,7 @@
 func TestV23DeviceManager(t *testing.T) {
 	v23tests.RunTest(t, V23TestDeviceManager)
 }
+
+func TestV23DeviceManagerMultiUser(t *testing.T) {
+	v23tests.RunTest(t, V23TestDeviceManagerMultiUser)
+}