// Copyright 2015 The Vanadium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// Test the device manager and related services and tools.
//
// By default, this script tests the device manager in a fashion amenable
// to automatic testing: the --single_user is passed to the device
// manager so that all device manager components run as the same user and
// no user input (such as an agent pass phrase) is needed.
//
// This script can exercise the device manager in two different modes. It
// can be executed like so:
//
//   jiri go test -v . --v23.tests
//
// This will exercise the device manager's single user mode where all
// processes run as the same invoking user.
//
// Alternatively, the device manager can be executed in multiple account
// mode by providing the --deviceuser <deviceuser> and --appuser
// <appuser> flags. In this case, the device manager will run as user
// <devicemgr> and the test will run applications as user <appuser>. If
// executed in this fashion, root permissions will be required to install
// and it may require configuring an agent passphrase. For example:
//
//   jiri go test -v . --v23.tests --deviceuser devicemanager --appuser  vana
//
// NB: the accounts provided as arguments to this test must already exist.
// Also, the --v23.tests.shell-on-fail flag is useful to enable debugging
// output. Note that this flag does not work for some shells. Set
// $SHELL in that case.

package device_test

import (
	"errors"
	"flag"
	"fmt"
	"io"
	"io/ioutil"
	"math/rand"
	"os"
	"os/user"
	"path/filepath"
	"regexp"
	"runtime"
	"strings"
	"sync"
	"testing"
	"time"

	"v.io/x/ref"
	"v.io/x/ref/lib/v23test"
	_ "v.io/x/ref/runtime/factories/generic"
	"v.io/x/ref/test/testutil"
)

var (
	appUserFlag    string
	deviceUserFlag string
	hostname       string
	errTimeout     = errors.New("timeout")
)

func init() {
	flag.StringVar(&appUserFlag, "appuser", "", "launch apps as the specified user")
	flag.StringVar(&deviceUserFlag, "deviceuser", "", "run the device manager as the specified user")
	name, err := os.Hostname()
	if err != nil {
		panic(fmt.Sprintf("Hostname() failed: %v", err))
	}
	hostname = name
}

func TestV23DeviceManagerSingleUser(t *testing.T) {
	v23test.SkipUnlessRunningIntegrationTests(t)
	sh := v23test.NewShell(t, v23test.Opts{})
	defer sh.Cleanup()

	u, err := user.Current()
	if err != nil {
		t.Fatalf("couldn't get the current user: %v", err)
	}
	testCore(t, sh, u.Username, "", false)
}

func TestV23DeviceManagerMultiUser(t *testing.T) {
	v23test.SkipUnlessRunningIntegrationTests(t)
	sh := v23test.NewShell(t, v23test.Opts{})
	defer sh.Cleanup()

	u, err := user.Current()
	if err != nil {
		t.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(t, sh)
		testCore(t, sh, "vana", "devicemanager", true)
		return
	}

	if len(deviceUserFlag) > 0 && len(appUserFlag) > 0 {
		testCore(t, sh, appUserFlag, deviceUserFlag, true)
	} else {
		t.Logf("Test skipped because running in multiuser mode requires --appuser and --deviceuser flags")
	}
}

func testCore(t *testing.T, sh *v23test.Shell, appUser, deviceUser string, withSuid bool) {
	defer fmt.Fprintf(os.Stderr, "--------------- SHUTDOWN ---------------\n")

	// Call sh.StartRootMountTable() first, since it updates sh.Vars, which is
	// copied by various Cmds at Cmd creation time.
	sh.StartRootMountTable()

	// When running with --with_suid, TMPDIR must grant the invoking user rwx
	// permissions and world x permissions for all parent directories back to /.
	// Otherwise, the with_suid user will not be able to use absolute paths. On
	// Darwin, TMPDIR defaults to a directory hierararchy in /var that is 0700.
	// This is unworkable, so force TMPDIR to /tmp in this case.
	//
	// In addition, even when running without --with_suid, on Darwin the default
	// TMPDIR results in "socket path (...) exceeds maximum allowed socket path
	// length" errors, so we always set TMPDIR to /tmp.
	oldTmpdir := os.Getenv("TMPDIR")
	os.Setenv("TMPDIR", "/tmp")
	defer os.Setenv("TMPDIR", oldTmpdir)

	var (
		workDir       = sh.MakeTempDir()
		binStagingDir = mkSubdir(t, workDir, "bin")
		dmInstallDir  = filepath.Join(workDir, "dm")

		// Most vanadium command-line utilities will be run by a
		// principal that has "root:u:alice" as its blessing.
		// (Where "root" comes from i.Principal().BlessingStore().Default()).
		// Create those credentials and options to use to setup the
		// binaries with them.
		aliceCreds = sh.ForkCredentials("u:alice")

		// Build all the command-line tools and set them up to run as alice.
		// applicationd/binaryd servers will be run by alice too.
		// TODO: applicationd/binaryd should run as a separate "service" role, as
		// alice is just a user.
		namespaceBin    = sh.Cmd(sh.BuildGoPkg("v.io/x/ref/cmd/namespace")).WithCredentials(aliceCreds)
		deviceBin       = sh.Cmd(sh.BuildGoPkg("v.io/x/ref/services/device/device")).WithCredentials(aliceCreds)
		binarydBin      = sh.Cmd(sh.BuildGoPkg("v.io/x/ref/services/binary/binaryd")).WithCredentials(aliceCreds)
		applicationdBin = sh.Cmd(sh.BuildGoPkg("v.io/x/ref/services/application/applicationd")).WithCredentials(aliceCreds)

		// The devicex script is not provided with any credentials, it
		// will generate its own.  This means that on "devicex start"
		// the device will have no useful credentials and until "device
		// claim" is invoked (as alice), it will just sit around
		// waiting to be claimed.
		//
		// Other binaries, like applicationd and binaryd will be run by alice.
		deviceScript = sh.Cmd("./devicex")

		mtName = "devices/" + hostname // Name under which the device manager will publish itself.
	)
	deviceScript.Vars["V23_DEVICE_DIR"] = dmInstallDir
	delete(deviceScript.Vars, ref.EnvCredentials)

	// We also need some tools running with different sets of credentials...

	// Administration tasks will be performed with a blessing that represents a corporate
	// adminstrator (which is usually a role account)
	adminCreds := sh.ForkCredentials("r:admin")
	adminDeviceBin := deviceBin.WithCredentials(adminCreds)
	debugBin := sh.Cmd(sh.BuildGoPkg("v.io/x/ref/services/debug/debug")).WithCredentials(adminCreds)

	// A special set of credentials will be used to give two blessings to the device manager
	// when claiming it -- one blessing will be from the corporate administrator role who owns
	// the machine, and the other will be a manufacturer blessing. (This is a hack until
	// there's a way to separately supply a manufacturer blessing. Eventually, the claim
	// would really be done by the administator, and the adminstrator's blessing would get
	// added to the manufacturer's blessing, which would already be present.)
	claimCreds := sh.ForkCredentials("r:admin", "m:orange:zphone5:ime-i007")
	claimDeviceBin := deviceBin.WithCredentials(claimCreds)

	// Another set of credentials be used to represent the application publisher, who
	// signs and pushes binaries
	pubCreds := sh.ForkCredentials("a:rovio")
	pubDeviceBin := deviceBin.WithCredentials(pubCreds)
	applicationBin := sh.Cmd(sh.BuildGoPkg("v.io/x/ref/services/application/application")).WithCredentials(pubCreds)
	binaryBin := sh.Cmd(sh.BuildGoPkg("v.io/x/ref/services/binary/binary")).WithCredentials(pubCreds)

	if withSuid {
		// In multiuser mode, deviceUserFlag needs execute access to
		// tempDir.
		if err := os.Chmod(workDir, 0711); err != nil {
			t.Fatalf("os.Chmod() failed: %v", err)
		}
	}

	buildAndCopyBinaries(
		t, sh, binStagingDir,
		"v.io/x/ref/services/device/deviced",
		"v.io/x/ref/services/agent/agentd",
		"v.io/x/ref/services/device/suidhelper",
		"v.io/x/ref/services/device/inithelper")

	appDName := "applications"
	devicedAppName := filepath.Join(appDName, "deviced", "test")

	deviceScriptArguments := []string{
		"install",
		binStagingDir,
	}

	if withSuid {
		deviceScriptArguments = append(deviceScriptArguments, "--devuser="+deviceUser)
	} else {
		deviceScriptArguments = append(deviceScriptArguments, "--single_user")
	}

	deviceScriptArguments = append(deviceScriptArguments, []string{
		"--origin=" + devicedAppName,
		"--",
		"--v23.tcp.address=127.0.0.1:0",
		"--neighborhood-name=" + fmt.Sprintf("%s-%d-%d", hostname, os.Getpid(), rand.Int()),
	}...)

	withArgs(deviceScript, deviceScriptArguments...).Run()
	withArgs(deviceScript, "start").Run()
	dmLog := filepath.Join(dmInstallDir, "dmroot/device-manager/logs/deviced.INFO")
	stopDevMgr := func() {
		withArgs(deviceScript, "stop").Run()
		if dmLogF, err := os.Open(dmLog); err != nil {
			t.Errorf("Failed to read dm log: %v", err)
		} else {
			fmt.Fprintf(os.Stderr, "--------------- START DM LOG ---------------\n")
			defer dmLogF.Close()
			if _, err := io.Copy(os.Stderr, dmLogF); err != nil {
				t.Errorf("Error dumping dm log: %v", err)
			}
			fmt.Fprintf(os.Stderr, "--------------- END DM LOG ---------------\n")
		}
	}
	var stopDevMgrOnce sync.Once
	defer stopDevMgrOnce.Do(stopDevMgr)
	// Grab the endpoint for the claimable service from the device manager's
	// log.
	var claimableEP string
	expiry := time.Now().Add(30 * time.Second)
	for {
		if time.Now().After(expiry) {
			t.Fatalf("Timed out looking for claimable endpoint in %v", dmLog)
		}
		startLog, err := ioutil.ReadFile(dmLog)
		if err != nil {
			t.Logf("Couldn't read log %v: %v", dmLog, err)
			time.Sleep(time.Second)
			continue
		}
		re := regexp.MustCompile(`Unclaimed device manager endpoint: (.*)`)
		matches := re.FindSubmatch(startLog)
		if len(matches) == 0 {
			t.Logf("Couldn't find match in %v [%s]", dmLog, startLog)
			time.Sleep(time.Second)
			continue
		}
		if len(matches) < 2 {
			t.Fatalf("Wrong match in %v (%d) %v", dmLog, len(matches), string(matches[0]))
		}
		claimableEP = string(matches[len(matches)-1])
		break
	}
	// Claim the device as "root:u:alice:myworkstation".
	withArgs(claimDeviceBin, "claim", claimableEP, "myworkstation").Run()

	resolve := func(name string) string {
		res := ""
		if err := testutil.RetryFor(10*time.Second, func() error {
			// Set ExitErrorIsOk to true since we expect "namespace resolve" to fail
			// if the name doesn't exist.
			c := withArgs(namespaceBin, "resolve", name)
			c.ExitErrorIsOk = true
			c.AddStderrWriter(os.Stderr)
			if res = tr(c.Stdout()); len(res) > 0 {
				return nil
			}
			return testutil.TryAgain(errors.New("resolve returned nothing"))
		}); err != nil {
			t.Fatal(err)
		}
		return res
	}

	// Wait for the device manager to publish its mount table entry.
	mtEP := resolve(mtName)
	withArgs(adminDeviceBin, "acl", "set", mtName+"/devmgr/device", "root:u:alice", "Read,Resolve,Write").Run()

	if withSuid {
		withArgs(adminDeviceBin, "associate", "add", mtName+"/devmgr/device", appUser, "root:u:alice").Run()
		associations := withArgs(adminDeviceBin, "associate", "list", mtName+"/devmgr/device").Stdout()
		if got, expected := strings.Trim(associations, "\n "), "root:u:alice "+appUser; got != expected {
			t.Fatalf("association test, got %v, expected %v", got, expected)
		}
	}

	// Verify the device's default blessing is as expected.
	mfrBlessing := "root:m:orange:zphone5:ime-i007:myworkstation"
	ownerBlessing := "root:r:admin:myworkstation"
	c := withArgs(debugBin, "stats", "read", mtName+"/devmgr/__debug/stats/security/principal/*/blessingstore/*")
	c.Run()
	c.S.ExpectSetEventuallyRE(".*Default Blessings[ ]+" + mfrBlessing + "," + ownerBlessing)

	// Get the device's profile, which should be set to non-empty string
	c = withArgs(adminDeviceBin, "describe", mtName+"/devmgr/device")
	c.Run()
	parts := c.S.ExpectRE(`{Profiles:map\[(.*):{}\]}`, 1)
	expectOneMatch := func(parts [][]string) string {
		if len(parts) != 1 || len(parts[0]) != 2 {
			t.Fatalf("%s: failed to match profile: %#v", caller(1), parts)
		}
		return parts[0][1]
	}
	deviceProfile := expectOneMatch(parts)
	if len(deviceProfile) == 0 {
		t.Fatalf("failed to get profile")
	}

	// Start a binaryd server that will serve the binary for the test
	// application to be installed on the device.
	binarydName := "binaries"
	withArgs(binarydBin,
		"--name="+binarydName,
		"--root-dir="+filepath.Join(workDir, "binstore"),
		"--v23.tcp.address=127.0.0.1:0",
		"--http=127.0.0.1:0").Start()
	// Allow publishers to update binaries
	withArgs(deviceBin, "acl", "set", binarydName, "root:a", "Write").Run()

	// We are also going to use the binaryd binary as our test app binary. Once our test app
	// binary is published to the binaryd server started above, this (augmented with a
	// timestamp) is the name the test app binary will have.
	sampleAppBinName := binarydName + "/binaryd"

	// Start an applicationd server that will serve the application
	// envelope for the test application to be installed on the device.
	withArgs(applicationdBin,
		"--name="+appDName,
		"--store="+mkSubdir(t, workDir, "appstore"),
		"--v23.tcp.address=127.0.0.1:0").Start()
	// Allow publishers to create and update envelopes
	withArgs(deviceBin, "acl", "set", appDName, "root:a", "Read,Write,Resolve").Run()

	sampleAppName := appDName + "/testapp"
	appPubName := "testbinaryd"
	appEnvelopeFilename := filepath.Join(workDir, "app.envelope")
	appEnvelope := fmt.Sprintf("{\"Title\":\"BINARYD\", \"Args\":[\"--name=%s\", \"--root-dir=./binstore\", \"--v23.tcp.address=127.0.0.1:0\", \"--http=127.0.0.1:0\"], \"Binary\":{\"File\":%q}, \"Env\":[]}", appPubName, sampleAppBinName)
	ioutil.WriteFile(appEnvelopeFilename, []byte(appEnvelope), 0666)
	defer os.Remove(appEnvelopeFilename)

	output := withArgs(applicationBin, "put", sampleAppName+"/0", deviceProfile, appEnvelopeFilename).Stdout()
	if got, want := tr(output), fmt.Sprintf("Application envelope added for profile %s.", deviceProfile); got != want {
		t.Fatalf("got %q, want %q", got, want)
	}

	// Verify that the envelope we uploaded shows up with glob.
	c = withArgs(applicationBin, "match", sampleAppName, deviceProfile)
	c.Run()
	parts = c.S.ExpectSetEventuallyRE(`"Title": "(.*)",`, `"File": "(.*)",`)
	if got, want := len(parts), 2; got != want {
		t.Fatalf("got %d, want %d", got, want)
	}
	for line, want := range []string{"BINARYD", sampleAppBinName} {
		if got := parts[line][1]; got != want {
			t.Fatalf("got %q, want %q", got, want)
		}
	}

	// Publish the app (This uses the binarydBin binary and the testapp envelope from above)
	withArgs(pubDeviceBin, "publish", "-from", filepath.Dir(binarydBin.Path), "-readers", "root:r:admin", filepath.Base(binarydBin.Path)+":testapp").Run()
	if got := withArgs(namespaceBin, "glob", sampleAppBinName).Stdout(); len(got) == 0 {
		t.Fatalf("glob failed for %q", sampleAppBinName)
	}

	// Install the app on the device.
	c = withArgs(deviceBin, "install", mtName+"/devmgr/apps", sampleAppName)
	c.Run()
	installationName := c.S.ReadLine()
	if installationName == "" {
		t.Fatalf("got empty installation name from install")
	}

	// Verify that the installation shows up when globbing the device manager.
	output = withArgs(namespaceBin, "glob", mtName+"/devmgr/apps/BINARYD/*").Stdout()
	if got, want := tr(output), installationName; got != want {
		t.Fatalf("got %q, want %q", got, want)
	}

	// Start an instance of the app, granting it blessing extension myapp.
	c = withArgs(deviceBin, "instantiate", installationName, "myapp")
	c.Run()
	instanceName := c.S.ReadLine()
	if instanceName == "" {
		t.Fatalf("got empty instance name from new")
	}
	withArgs(deviceBin, "run", instanceName).Run()

	resolve(mtName + "/" + appPubName)

	// Verify that the instance shows up when globbing the device manager.
	output = withArgs(namespaceBin, "glob", mtName+"/devmgr/apps/BINARYD/*/*").Stdout()
	if got, want := tr(output), instanceName; got != want {
		t.Fatalf("got %q, want %q", got, want)
	}

	c = withArgs(debugBin, "stats", "read", instanceName+"/stats/system/pid")
	c.Run()
	pid := c.S.ExpectRE("[0-9]+$", 1)[0][0]
	uname, err := getUserForPid(sh, pid)
	if err != nil {
		t.Errorf("getUserForPid could not determine the user running pid %v", pid)
	} else if uname != appUser {
		t.Errorf("app expected to be running as %v but is running as %v", appUser, uname)
	}

	// Verify the app's blessings. We check the default blessing, as well as the
	// "..." blessing, which should be the default blessing plus a publisher blessing.
	userBlessing := "root:u:alice:myapp"
	pubBlessing := "root:a:rovio:apps:published:binaryd"
	appBlessing := mfrBlessing + ":a:" + pubBlessing + "," + ownerBlessing + ":a:" + pubBlessing
	c = withArgs(debugBin, "stats", "read", instanceName+"/stats/security/principal/*/blessingstore/*")
	c.Run()
	c.S.ExpectSetEventuallyRE(".*Default Blessings[ ]+"+userBlessing+"$", "[.][.][.][ ]+"+userBlessing+","+appBlessing)

	// Kill and delete the instance.
	withArgs(deviceBin, "kill", instanceName).Run()
	withArgs(deviceBin, "delete", instanceName).Run()

	// Verify that logs, but not stats, show up when globbing the
	// not-running instance.
	if output = withArgs(namespaceBin, "glob", instanceName+"/stats/...").Stdout(); len(output) > 0 {
		t.Fatalf("no output expected for glob %s/stats/..., got %q", output, instanceName)
	}
	if output = withArgs(namespaceBin, "glob", instanceName+"/logs/...").Stdout(); len(output) == 0 {
		t.Fatalf("output expected for glob %s/logs/..., but got none", instanceName)
	}

	// TODO: The deviced binary should probably be published by someone other than rovio :-)
	// Maybe publishing the deviced binary should eventually use "device publish" too?
	// For now, it uses the "application" and "binary" tools directly to ensure that those work

	// Upload a deviced binary
	devicedAppBinName := binarydName + "/deviced"
	withArgs(binaryBin, "upload", devicedAppBinName, sh.BuildGoPkg("v.io/x/ref/services/device/deviced")).Run()
	// Allow root:r:admin and its devices to read the binary
	withArgs(deviceBin, "acl", "set", devicedAppBinName, "root:r:admin", "Read").Run()

	// Upload a device manager envelope.
	devicedEnvelopeFilename := filepath.Join(workDir, "deviced.envelope")
	devicedEnvelope := fmt.Sprintf("{\"Title\":\"device manager\", \"Binary\":{\"File\":%q}}", devicedAppBinName)
	ioutil.WriteFile(devicedEnvelopeFilename, []byte(devicedEnvelope), 0666)
	defer os.Remove(devicedEnvelopeFilename)
	withArgs(applicationBin, "put", devicedAppName, deviceProfile, devicedEnvelopeFilename).Run()
	// Allow root:r:admin and its devices to read the envelope
	withArgs(deviceBin, "acl", "set", devicedAppName, "root:r:admin", "Read").Run()

	// Update the device manager.
	withArgs(adminDeviceBin, "update", mtName+"/devmgr/device").Run()
	resolveChange := func(name, old string) string {
		res := ""
		if err := testutil.RetryFor(10*time.Second, func() error {
			// Set ExitErrorIsOk to true since we expect "namespace resolve" to fail
			// if the name doesn't exist.
			c := withArgs(namespaceBin, "resolve", name)
			c.ExitErrorIsOk = true
			c.AddStderrWriter(os.Stderr)
			switch res = tr(c.Stdout()); {
			case res == "":
				return testutil.TryAgain(errors.New("resolve returned nothing"))
			case res == old:
				return testutil.TryAgain(errors.New("no change"))
			}
			return nil
		}); err != nil {
			t.Fatal(err)
		}
		return res
	}
	mtEP = resolveChange(mtName, mtEP)

	// Verify that device manager's mounttable is still published under the
	// expected name (hostname).
	if withArgs(namespaceBin, "glob", mtName).Stdout() == "" {
		t.Fatalf("failed to glob %s", mtName)
	}

	// Revert the device manager
	// The argument to "device revert" is a glob pattern. So we need to
	// wait for devmgr to be mounted before running the command.
	resolve(mtEP + "/devmgr")
	withArgs(adminDeviceBin, "revert", mtName+"/devmgr/device").Run()
	mtEP = resolveChange(mtName, mtEP)

	// Verify that device manager's mounttable is still published under the
	// expected name (hostname).
	if withArgs(namespaceBin, "glob", mtName).Stdout() == "" {
		t.Fatalf("failed to glob %s", mtName)
	}

	// Verify that the local mounttable exists, and that the device manager,
	// the global namespace, and the neighborhood are mounted on it.
	resolve(mtEP + "/devmgr")
	resolve(mtEP + "/nh")
	resolve(mtEP + "/global")

	namespaceRoot := sh.Vars[ref.EnvNamespacePrefix]
	output = withArgs(namespaceBin, "resolve", mtEP+"/global").Stdout()
	if got, want := tr(output), namespaceRoot; got != want {
		t.Fatalf("got %q, want %q", got, want)
	}

	// Kill the device manager (which causes it to be restarted), wait for
	// the endpoint to change.
	withArgs(deviceBin, "kill", mtName+"/devmgr/device").Run()
	mtEP = resolveChange(mtName, mtEP)

	// Shut down the device manager.
	stopDevMgrOnce.Do(stopDevMgr)

	// Wait for the mounttable entry to go away.
	resolveGone := func(name string) string {
		res := ""
		if err := testutil.RetryFor(10*time.Second, func() error {
			// Set ExitErrorIsOk to true since we expect "namespace resolve" to fail
			// if the name doesn't exist.
			c := withArgs(namespaceBin, "resolve", name)
			c.ExitErrorIsOk = true
			c.AddStderrWriter(os.Stderr)
			if res = tr(c.Stdout()); len(res) == 0 {
				return nil
			}
			return testutil.TryAgain(errors.New("mount table entry still exists"))
		}); err != nil {
			t.Fatal(err)
		}
		return res
	}
	resolveGone(mtName)

	var fi []os.FileInfo

	// This doesn't work in multiuser mode because dmInstallDir is
	// owned by the device manager user and unreadable by the user
	// running this test.
	if !withSuid {
		fi, err = ioutil.ReadDir(dmInstallDir)
		if err != nil {
			t.Fatalf("failed to readdir for %q: %v", dmInstallDir, err)
		}
	}

	withArgs(deviceScript, "uninstall").Run()

	fi, err = ioutil.ReadDir(dmInstallDir)
	if err == nil || len(fi) > 0 {
		t.Fatalf("managed to read %d entries from %q", len(fi), dmInstallDir)
	}
	if err != nil && !strings.Contains(err.Error(), "no such file or directory") {
		t.Fatalf("wrong error: %v", err)
	}
}

func withArgs(cmd *v23test.Cmd, args ...string) *v23test.Cmd {
	res := cmd.Clone()
	res.Args = append(res.Args, args...)
	return res
}

func buildAndCopyBinaries(t *testing.T, sh *v23test.Shell, destinationDir string, packages ...string) {
	var args []string
	for _, pkg := range packages {
		args = append(args, sh.BuildGoPkg(pkg))
	}
	args = append(args, destinationDir)
	sh.Cmd("/bin/cp", args...).Run()
}

func mkSubdir(t *testing.T, parent, child string) string {
	dir := filepath.Join(parent, child)
	if err := os.Mkdir(dir, 0755); err != nil {
		t.Fatalf("failed to create %q: %v", dir, err)
	}
	return dir
}

var re = regexp.MustCompile("[ \t]+")

// getUserForPid determines the username running process pid.
func getUserForPid(sh *v23test.Shell, pid string) (string, error) {
	pidString := sh.Cmd("/bin/ps", psFlags).Stdout()
	for _, line := range strings.Split(pidString, "\n") {
		fields := re.Split(line, -1)
		if len(fields) > 1 && pid == fields[1] {
			return fields[0], nil
		}
	}
	return "", fmt.Errorf("Couldn't determine the user for pid %s", pid)
}

// tr trims off trailing newline characters.
func tr(s string) string {
	return strings.TrimRight(s, "\n")
}

// caller returns a string of the form <filename>:<lineno>.
func caller(skip int) string {
	_, file, line, _ := runtime.Caller(skip + 1)
	return fmt.Sprintf("%s:%d", filepath.Base(file), line)
}

func TestMain(m *testing.M) {
	os.Exit(v23test.Run(m.Run))
}
