services/device/util_darwin_test.go: devmgr multiuser tests on darwin

Add the necessary account creation code to support running the
integration tests for the device manager on darwin on the builders in
multi-user mode.

Change-Id: Ia0d5a9e447f0aa915b039492896237dba1f123f4
diff --git a/services/device/util_darwin_test.go b/services/device/util_darwin_test.go
index f3ec7f4..1fc1891 100644
--- a/services/device/util_darwin_test.go
+++ b/services/device/util_darwin_test.go
@@ -5,12 +5,84 @@
 package device_test
 
 import (
+	"fmt"
+	"os/user"
+	"strconv"
+	"strings"
+
 	"v.io/x/ref/test/v23tests"
 )
 
-const runTestOnThisPlatform = false
+const runTestOnThisPlatform = true
 const psFlags = "-ej"
 
-// TODO(rjkroege): Complete test implementation on Darwin.
-func makeTestAccounts(*v23tests.T) {
+type uidMap map[int]struct{}
+
+func (uids uidMap) findAvailable() (int, error) {
+	// Accounts starting at 501 are available. Don't use the largest
+	// UID because on a corporate imaged Mac, this will overlap with
+	// another employee's UID. Instead, use the first available UID >= 501.
+	for newuid := 501; newuid < 1e6; newuid++ {
+		if _, ok := uids[newuid]; !ok {
+			uids[newuid] = struct{}{}
+			return newuid, nil
+		}
+	}
+	return 0, fmt.Errorf("Couldn't find an available UID")
+}
+
+func newUidMap(i *v23tests.T) uidMap {
+	dsclCmd := i.BinaryFromPath("dscl")
+
+	// `dscl . -list /Users UniqueID` into a datastructure.
+	userstring := dsclCmd.Run(".", "-list", "/Users", "UniqueID")
+	users := strings.Split(userstring, "\n")
+
+	uids := make(map[int]struct{}, len(users))
+	for _, line := range users {
+		fields := re.Split(line, -1)
+		if len(fields) > 1 {
+			if uid, err := strconv.Atoi(fields[1]); err == nil {
+				uids[uid] = struct{}{}
+			}
+		}
+	}
+	return uids
+}
+
+func makeAccount(i *v23tests.T, uid int, uname, fullname string) {
+	sudoCmd := i.BinaryFromPath("/usr/bin/sudo")
+	dsclCmd := sudoCmd.WithPrefixArgs("dscl", ".", "-create", "/Users/"+uname)
+
+	dsclCmd.Run()
+	dsclCmd.Run("UserShell", "/bin/bash")
+	dsclCmd.Run("RealName", fullname)
+	dsclCmd.Run("UniqueID", strconv.FormatInt(int64(uid), 10))
+	dsclCmd.Run("PrimaryGroupID", "20")
+
+}
+
+func makeTestAccounts(i *v23tests.T) {
+	_, needVanaErr := user.Lookup("vana")
+	_, needDevErr := user.Lookup("devicemanager")
+
+	if needVanaErr == nil && needDevErr == nil {
+		return
+	}
+
+	uids := newUidMap(i)
+	if needVanaErr != nil {
+		vanauid, err := uids.findAvailable()
+		if err != nil {
+			i.Fatalf("Can't make test accounts: %v", err)
+		}
+		makeAccount(i, vanauid, "vana", "Vanadium White")
+	}
+	if needDevErr != nil {
+		devmgruid, err := uids.findAvailable()
+		if err != nil {
+			i.Fatalf("Can't make test accounts: %v", err)
+		}
+		makeAccount(i, devmgruid, "devicemanager", "Devicemanager")
+	}
 }