veyron/.../test.sh: update test.sh scripts to use a single dir to share binaries.

Also use different work dir for each test.

Change-Id: Id17c8c262ddd49dd8cbdcd807c3c1a0d404de0ce
diff --git a/runtimes/google/ipc/stream/crypto/test.sh b/runtimes/google/ipc/stream/crypto/test.sh
index 80b677e..5ce4020 100755
--- a/runtimes/google/ipc/stream/crypto/test.sh
+++ b/runtimes/google/ipc/stream/crypto/test.sh
@@ -4,9 +4,11 @@
 
 source "${VEYRON_ROOT}/scripts/lib/shell_test.sh"
 
+readonly WORKDIR="${shell_test_WORK_DIR}"
+
 main() {
   local -r DIR="$(dirname $0)"
-  local -r OUTFILE="${TMPDIR}/latest.go"
+  local -r OUTFILE="${WORKDIR}/latest.go"
   "${DIR}/tls_generate_old.sh" "${OUTFILE}" || shell_test::fail "failed to generate tls_old.go"
   if diff "${OUTFILE}" "${DIR}/tls_old.go"; then
     shell_test::pass
diff --git a/runtimes/google/rt/sectransition/test.sh b/runtimes/google/rt/sectransition/test.sh
index da91233..b1ddf61 100755
--- a/runtimes/google/rt/sectransition/test.sh
+++ b/runtimes/google/rt/sectransition/test.sh
@@ -5,20 +5,19 @@
 
 . "${VEYRON_ROOT}/scripts/lib/shell_test.sh"
 
-readonly WORKDIR=$(shell::tmp_dir)
+readonly WORKDIR="${shell_test_WORK_DIR}"
 
 build() {
-  veyron go build veyron.io/veyron/veyron/runtimes/google/rt/sectransition || shell_test::fail "line ${LINENO}: failed to build sectransition binary"
-  veyron go build veyron.io/veyron/veyron/tools/identity || shell_test::fail "line ${LINENO}: failed to build identity"
+  SECTRANSITION_BIN="$(shell_test::build_go_binary 'veyron.io/veyron/veyron/runtimes/google/rt/sectransition')"
+  IDENTITY_BIN="$(shell_test::build_go_binary 'veyron.io/veyron/veyron/tools/identity')"
 }
 
-
 startserver() {
   # The server has access to both the old and new security model.
   export VEYRON_IDENTITY="${WORKDIR}/old"
   export VEYRON_CREDENTIALS="${WORKDIR}/new"
   shell::run_server "${shell_test_DEFAULT_SERVER_TIMEOUT}" "${SERVERLOG}" /dev/null \
-    ./sectransition --server --logtostderr &> /dev/null \
+    "${SECTRANSITION_BIN}" --server --logtostderr &> /dev/null \
     || shell_test::fail "line ${LINENO}: failed to start sectransaction"
   shell::timed_wait_for "${shell_test_DEFAULT_MESSAGE_TIMEOUT}" "${SERVERLOG}" "SERVER" \
     || shell_test::fail "line ${LINENO}: failed to read expected output from log file"
@@ -28,7 +27,7 @@
 }
 
 runclient() {
-  ./sectransition "${EP}" &>"${CLIENTLOG}"
+  "${SECTRANSITION_BIN}" "${EP}" &>"${CLIENTLOG}"
 }
 
 oldmodel() {
@@ -45,7 +44,7 @@
 
   # Generate an identity (old security model) that may be used by the client.
   local -r OLD="${WORKDIR}/old"
-  ./identity generate "old" > "${OLD}"
+  "${IDENTITY_BIN}" generate "old" > "${OLD}"
 
   local -r SERVERLOG="${WORKDIR}/server.log"
   local -r CLIENTLOG="${WORKDIR}/client.log"
diff --git a/security/agent/test.sh b/security/agent/test.sh
index 9ed0277..037e5fe 100755
--- a/security/agent/test.sh
+++ b/security/agent/test.sh
@@ -4,17 +4,17 @@
 
 source "${VEYRON_ROOT}/scripts/lib/shell_test.sh"
 
-readonly WORKDIR="$(shell::tmp_dir)"
+readonly WORKDIR="${shell_test_WORK_DIR}"
 
 build() {
-  veyron go build veyron.io/veyron/veyron/security/agent/agentd || shell_test::fail "line ${LINENO}: failed to build agentd"
-  veyron go build -o pingpong veyron.io/veyron/veyron/security/agent/test || shell_test::fail "line ${LINENO}: failed to build pingpong"
-  veyron go build veyron.io/veyron/veyron/tools/identity || shell_test::fail "line ${LINENO}: failed to build identity"
+  AGENTD_BIN="$(shell_test::build_go_binary 'veyron.io/veyron/veyron/security/agent/agentd')"
+  PINGPONG_BIN="$(shell_test::build_go_binary 'veyron.io/veyron/veyron/security/agent/test' 'pingpong')"
+  IDENTITY_BIN="$(shell_test::build_go_binary 'veyron.io/veyron/veyron/tools/identity')"
 }
 
 echo_identity() {
   local -r OUTPUT="$1"
-  ./agentd bash -c 'echo ${VEYRON_IDENTITY}' > "${OUTPUT}"
+  "${AGENTD_BIN}" bash -c 'echo ${VEYRON_IDENTITY}' > "${OUTPUT}"
 }
 
 main() {
@@ -34,15 +34,15 @@
   # TODO(ashankar): Remove this block (and remove the compilation of the identity tool)
   # once the agent has been updated to comply with the new security model.
   local -r ID=$(shell::tmp_file)
-  ./identity generate agenttest >"${ID}" || shell_test::fail "line ${LINENO}: failed to run identity"
+  "${IDENTITY_BIN}" generate agenttest >"${ID}" || shell_test::fail "line ${LINENO}: failed to run identity"
   export VEYRON_IDENTITY="${ID}"
 
   shell_test::setup_server_test || shell_test::fail "line ${LINENO} failed to start server"
   unset VEYRON_CREDENTIALS
 
   # Test running a single app.
-  shell_test::start_server ./pingpong --server
-  ./agentd --v=4 ./pingpong || shell_test::fail "line ${LINENO}: failed to run pingpong"
+  shell_test::start_server "${PINGPONG_BIN}" --server
+  "${AGENTD_BIN}" --v=4 "${PINGPONG_BIN}" || shell_test::fail "line ${LINENO}: failed to run pingpong"
   local -r OUTPUT=$(shell::tmp_file)
   RESULT=$(shell::check_result echo_identity "${OUTPUT}")
   shell_test::assert_eq "${RESULT}" "0" "${LINENO}"
@@ -51,7 +51,9 @@
   fi
 
   # Test running multiple apps connecting to the same agent.
-  RESULT=$(shell::check_result ./agentd bash "${VEYRON_ROOT}/veyron/go/src/veyron.io/veyron/veyron/security/agent/testchild.sh")
+  # Make sure the testchild.sh script get the same shell_test_BIN_DIR as the main script.
+  export shell_test_BIN_DIR="${shell_test_BIN_DIR}"
+  RESULT=$(shell::check_result "${AGENTD_BIN}" bash "${VEYRON_ROOT}/veyron/go/src/veyron.io/veyron/veyron/security/agent/testchild.sh")
   shell_test::assert_eq "${RESULT}" "0" "${LINENO}"
 
   shell_test::pass
diff --git a/security/agent/testchild.sh b/security/agent/testchild.sh
index addf884..7a9fa58 100644
--- a/security/agent/testchild.sh
+++ b/security/agent/testchild.sh
@@ -8,8 +8,9 @@
   if [[ -n "${VEYRON_IDENTITY}" ]]; then
       shell_test::fail "line ${LINENO}: identity preserved"
   fi
-  shell_test::start_server ./pingpong --server
-  ./pingpong || shell_test::fail "line ${LINENO}: ping"
+  PINGPONG_BIN="$(shell_test::build_go_binary 'veyron.io/veyron/veyron/security/agent/test' 'pinpong')"
+  shell_test::start_server "${PINGPONG_BIN}" --server
+  "${PINGPONG_BIN}" || shell_test::fail "line ${LINENO}: ping"
 
   shell_test::pass
 }
diff --git a/services/mgmt/application/applicationd/test.sh b/services/mgmt/application/applicationd/test.sh
index 2ace5e4..7f40da2 100755
--- a/services/mgmt/application/applicationd/test.sh
+++ b/services/mgmt/application/applicationd/test.sh
@@ -8,13 +8,15 @@
 
 source "${VEYRON_ROOT}/scripts/lib/shell_test.sh"
 
+readonly WORKDIR="${shell_test_WORK_DIR}"
+
 build() {
-  veyron go build veyron.io/veyron/veyron/services/mgmt/application/applicationd || shell_test::fail "line ${LINENO}: failed to build 'applicationd'"
-  veyron go build veyron.io/veyron/veyron/tools/application || shell_test::fail "line ${LINENO}: failed to build 'application'"
+  APPLICATIOND_BIN="$(shell_test::build_go_binary 'veyron.io/veyron/veyron/services/mgmt/application/applicationd')"
+  APPLICATION_BIN="$(shell_test::build_go_binary 'veyron.io/veyron/veyron/tools/application')"
 }
 
 main() {
-  cd "${TMPDIR}"
+  cd "${WORKDIR}"
   build
 
   shell_test::setup_server_test
@@ -22,7 +24,7 @@
   # Start the application repository daemon.
   local -r REPO="applicationd-test-repo"
   local -r STORE=$(shell::tmp_dir)
-  shell_test::start_server ./applicationd --name="${REPO}" --store="${STORE}" --veyron.tcp.address=127.0.0.1:0 \
+  shell_test::start_server "${APPLICATIOND_BIN}" --name="${REPO}" --store="${STORE}" --veyron.tcp.address=127.0.0.1:0 \
     || shell_test::fail "line ${LINENO} failed to start applicationd"
 
   # Create an application envelope.
@@ -32,20 +34,20 @@
   cat > "${ENVELOPE_WANT}" <<EOF
 {"Title":"title", "Args":[], "Binary":"foo", "Env":[]}
 EOF
-  ./application put "${APPLICATION}" "${PROFILE}" "${ENVELOPE_WANT}" || shell_test::fail "line ${LINENO}: 'put' failed"
+  "${APPLICATION_BIN}" put "${APPLICATION}" "${PROFILE}" "${ENVELOPE_WANT}" || shell_test::fail "line ${LINENO}: 'put' failed"
 
   # Match the application envelope.
   local -r ENVELOPE_GOT=$(shell::tmp_file)
-  ./application match "${APPLICATION}" "${PROFILE}" | tee "${ENVELOPE_GOT}" || shell_test::fail "line ${LINENO}: 'match' failed"
+  "${APPLICATION_BIN}" match "${APPLICATION}" "${PROFILE}" | tee "${ENVELOPE_GOT}" || shell_test::fail "line ${LINENO}: 'match' failed"
   if [[ $(cmp "${ENVELOPE_WANT}" "${ENVELOPE_GOT}" &> /dev/null) ]]; then
     shell_test::fail "mismatching application envelopes"
   fi
 
   # Remove the application envelope.
-  ./application remove "${APPLICATION}" "${PROFILE}" || shell_test::fail "line ${LINENO}: 'remove' failed"
+  "${APPLICATION_BIN}" remove "${APPLICATION}" "${PROFILE}" || shell_test::fail "line ${LINENO}: 'remove' failed"
 
   # Check the application envelope no longer exists.
-  local -r RESULT=$(shell::check_result ./application match "${APPLICATION}" "${PROFILE}")
+  local -r RESULT=$(shell::check_result "${APPLICATION_BIN}" match "${APPLICATION}" "${PROFILE}")
   shell_test::assert_ne "${RESULT}" "0" "${LINENO}"
 
   shell_test::pass
diff --git a/services/mgmt/binary/binaryd/test.sh b/services/mgmt/binary/binaryd/test.sh
index 10cc858..dae104b 100755
--- a/services/mgmt/binary/binaryd/test.sh
+++ b/services/mgmt/binary/binaryd/test.sh
@@ -8,20 +8,22 @@
 
 source "${VEYRON_ROOT}/scripts/lib/shell_test.sh"
 
+readonly WORKDIR="${shell_test_WORK_DIR}"
+
 build() {
-  veyron go build veyron.io/veyron/veyron/services/mgmt/binary/binaryd || shell_test::fail "line ${LINENO}: failed to build 'binaryd'"
-  veyron go build veyron.io/veyron/veyron/tools/binary || shell_test::fail "line ${LINENO}: failed to build 'binary'"
+  BINARYD_BIN="$(shell_test::build_go_binary 'veyron.io/veyron/veyron/services/mgmt/binary/binaryd')"
+  BINARY_BIN="$(shell_test::build_go_binary 'veyron.io/veyron/veyron/tools/binary')"
 }
 
 main() {
-  cd "${TMPDIR}"
+  cd "${WORKDIR}"
   build
 
   shell_test::setup_server_test
 
   # Start the binary repository daemon.
   local -r REPO="binaryd-test-repo"
-  shell_test::start_server ./binaryd --name="${REPO}" --veyron.tcp.address=127.0.0.1:0 \
+  shell_test::start_server "${BINARYD_BIN}" --name="${REPO}" --veyron.tcp.address=127.0.0.1:0 \
     || shell_test::fail "line ${LINENO} failed to start binaryd"
 
   # Create a binary file.
@@ -29,20 +31,20 @@
   local -r BINARY_FILE=$(shell::tmp_file)
   dd if=/dev/urandom of="${BINARY_FILE}" bs=1000000 count=16 \
     || shell_test::fail "line ${LINENO}: faile to create a random binary file"
-  ./binary upload "${BINARY}" "${BINARY_FILE}" || shell_test::fail "line ${LINENO}: 'upload' failed"
+  "${BINARY_BIN}" upload "${BINARY}" "${BINARY_FILE}" || shell_test::fail "line ${LINENO}: 'upload' failed"
 
   # Download the binary file.
   local -r BINARY_FILE2=$(shell::tmp_file)
-  ./binary download "${BINARY}" "${BINARY_FILE2}" || shell_test::fail "line ${LINENO}: 'download' failed"
+  "${BINARY_BIN}" download "${BINARY}" "${BINARY_FILE2}" || shell_test::fail "line ${LINENO}: 'download' failed"
   if [[ $(cmp "${BINARY_FILE}" "${BINARY_FILE2}" &> /dev/null) ]]; then
     shell_test::fail "mismatching binary files"
   fi
 
   # Remove the binary file.
-  ./binary delete "${BINARY}" || shell_test::fail "line ${LINENO}: 'delete' failed"
+  "${BINARY_BIN}" delete "${BINARY}" || shell_test::fail "line ${LINENO}: 'delete' failed"
 
   # Check the binary no longer exists.
-  local -r RESULT=$(shell::check_result ./binary download "${BINARY}" "${BINARY_FILE2}")
+  local -r RESULT=$(shell::check_result "${BINARY_BIN}" download "${BINARY}" "${BINARY_FILE2}")
   shell_test::assert_ne "${RESULT}" "0" "${LINENO}"
 
   shell_test::pass
diff --git a/services/mgmt/build/buildd/test.sh b/services/mgmt/build/buildd/test.sh
index 611d462..4df2905 100755
--- a/services/mgmt/build/buildd/test.sh
+++ b/services/mgmt/build/buildd/test.sh
@@ -7,13 +7,15 @@
 
 source "${VEYRON_ROOT}/scripts/lib/shell_test.sh"
 
+readonly WORKDIR="${shell_test_WORK_DIR}"
+
 build() {
-  veyron go build veyron.io/veyron/veyron/services/mgmt/build/buildd || shell_test::fail "line ${LINENO}: failed to build 'buildd'"
-  veyron go build veyron.io/veyron/veyron/tools/build || shell_test::fail "line ${LINENO}: failed to build 'build'"
+  BUILDD_BIN="$(shell_test::build_go_binary 'veyron.io/veyron/veyron/services/mgmt/build/buildd')"
+  BUILD_BIN="$(shell_test::build_go_binary 'veyron.io/veyron/veyron/tools/build')"
 }
 
 main() {
-  cd "${TMPDIR}"
+  cd "${WORKDIR}"
   build
 
   shell_test::setup_server_test
@@ -22,7 +24,7 @@
   local -r SERVER="buildd-test-server"
   local GO_BIN=$(which go)
   local -r GO_ROOT=$("${GO_BIN}" env GOROOT)
-  shell_test::start_server ./buildd --name="${SERVER}" --gobin="${GO_BIN}" --goroot="${GO_ROOT}" --veyron.tcp.address=127.0.0.1:0 \
+  shell_test::start_server "${BUILDD_BIN}" --name="${SERVER}" --gobin="${GO_BIN}" --goroot="${GO_ROOT}" --veyron.tcp.address=127.0.0.1:0 \
     || shell_test::fail "line ${LINENO} failed to start server"
 
   # Create and build a test source file.
@@ -41,7 +43,7 @@
   fmt.Printf("Hello World!\n")
 }
 EOF
-  GOPATH="${GO_PATH}" GOROOT="${GO_ROOT}" TMPDIR="${BIN_DIR}" ./build build "${SERVER}" "test" || shell_test::fail "line ${LINENO}: 'build' failed"
+  GOPATH="${GO_PATH}" GOROOT="${GO_ROOT}" TMPDIR="${BIN_DIR}" "${BUILD_BIN}" build "${SERVER}" "test" || shell_test::fail "line ${LINENO}: 'build' failed"
   if [[ ! -e "${BIN_DIR}/test" ]]; then
     shell_test::fail "test binary not found"
   fi
diff --git a/services/mgmt/profile/profiled/test.sh b/services/mgmt/profile/profiled/test.sh
index 380daf1..7022e92 100755
--- a/services/mgmt/profile/profiled/test.sh
+++ b/services/mgmt/profile/profiled/test.sh
@@ -9,15 +9,17 @@
 
 source "${VEYRON_ROOT}/scripts/lib/shell_test.sh"
 
+readonly WORKDIR="${shell_test_WORK_DIR}"
+
 build() {
-  veyron go build veyron.io/veyron/veyron/services/mgmt/profile/profiled || shell_test::fail "line ${LINENO}: failed to build 'profiled'"
-  veyron go build veyron.io/veyron/veyron/tools/profile || shell_test::fail "line ${LINENO}: failed to build 'profile'"
+  PROFILED_BIN="$(shell_test::build_go_binary 'veyron.io/veyron/veyron/services/mgmt/profile/profiled')"
+  PROFILE_BIN="$(shell_test::build_go_binary 'veyron.io/veyron/veyron/tools/profile')"
 }
 
 main() {
   local GOT OUTPUT RESULT WANT
 
-  cd "${TMPDIR}"
+  cd "${WORKDIR}"
   build
 
   shell_test::setup_server_test
@@ -25,43 +27,43 @@
   # Start the profile repository daemon.
   local -r REPO="profiled-test-repo"
   local -r STORE=$(shell::tmp_dir)
-  shell_test::start_server ./profiled --name="${REPO}" --veyron.tcp.address=127.0.0.1:0 --store="${STORE}" \
+  shell_test::start_server "${PROFILED_BIN}" --name="${REPO}" --veyron.tcp.address=127.0.0.1:0 --store="${STORE}" \
     || shell_test::fail "line ${LINENO} failed to start server"
 
   # Create a profile.
   local -r PROFILE="${REPO}/test-profile"
-  ./profile put "${PROFILE}" || shell_test::fail "line ${LINENO}: 'put' failed"
+  "${PROFILE_BIN}" put "${PROFILE}" || shell_test::fail "line ${LINENO}: 'put' failed"
 
   # Retrieve the profile label.
   OUTPUT=$(shell::tmp_file)
-  ./profile label "${PROFILE}" | tee "${OUTPUT}" || shell_test::fail "line ${LINENO}: 'label' failed"
+  "${PROFILE_BIN}" label "${PROFILE}" | tee "${OUTPUT}" || shell_test::fail "line ${LINENO}: 'label' failed"
   GOT=$(cat "${OUTPUT}")
   WANT="example"
   shell_test::assert_eq "${GOT}" "${WANT}" "${LINENO}"
 
   # Retrieve the profile description.
   OUTPUT=$(shell::tmp_file)
-  ./profile description "${PROFILE}" | tee "${OUTPUT}" || shell_test::fail "line ${LINENO}: 'description' failed"
+  "${PROFILE_BIN}" description "${PROFILE}" | tee "${OUTPUT}" || shell_test::fail "line ${LINENO}: 'description' failed"
   GOT=$(cat "${OUTPUT}")
   WANT="Example profile to test the profile manager implementation."
   shell_test::assert_eq "${GOT}" "${WANT}" "${LINENO}"
 
   # Retrieve the profile specification.
   OUTPUT=$(shell::tmp_file)
-  ./profile spec "${PROFILE}" | tee "${OUTPUT}" || shell_test::fail "line ${LINENO}: 'spec' failed"
+  "${PROFILE_BIN}" spec "${PROFILE}" | tee "${OUTPUT}" || shell_test::fail "line ${LINENO}: 'spec' failed"
   GOT=$(cat "${OUTPUT}")
   WANT='profile.Specification{Arch:"amd64", Description:"Example profile to test the profile manager implementation.", Format:"ELF", Libraries:map[profile.Library]struct {}{profile.Library{Name:"foo", MajorVersion:"1", MinorVersion:"0"}:struct {}{}}, Label:"example", OS:"linux"}'
   shell_test::assert_eq "${GOT}" "${WANT}" "${LINENO}"
 
   # Remove the profile.
-  ./profile remove "${PROFILE}" || shell_test::fail "line ${LINENO}: 'remove' failed"
+  "${PROFILE_BIN}" remove "${PROFILE}" || shell_test::fail "line ${LINENO}: 'remove' failed"
 
   # Check the profile no longer exists.
-  RESULT=$(shell::check_result ./profile label "${PROFILE}")
+  RESULT=$(shell::check_result "${PROFILE_BIN}" label "${PROFILE}")
   shell_test::assert_ne "${RESULT}" "0" "${LINENO}"
-  RESULT=$(shell::check_result ./profile description "${PROFILE}")
+  RESULT=$(shell::check_result "${PROFILE_BIN}" description "${PROFILE}")
   shell_test::assert_ne "${RESULT}" "0" "${LINENO}"
-  RESULT=$(shell::check_result ./profile spec "${PROFILE}")
+  RESULT=$(shell::check_result "${PROFILE_BIN}" spec "${PROFILE}")
   shell_test::assert_ne "${RESULT}" "0" "${LINENO}"
 
   shell_test::pass
diff --git a/services/mounttable/mounttabled/test.sh b/services/mounttable/mounttabled/test.sh
index f0987fa..bb65687 100755
--- a/services/mounttable/mounttabled/test.sh
+++ b/services/mounttable/mounttabled/test.sh
@@ -11,23 +11,25 @@
 
 source "${VEYRON_ROOT}/scripts/lib/shell_test.sh"
 
+readonly WORKDIR="${shell_test_WORK_DIR}"
+
 build() {
-  veyron go build veyron.io/veyron/veyron/services/mounttable/mounttabled || shell_test::fail "line ${LINENO}: failed to build mounttabled"
-  veyron go build veyron.io/veyron/veyron/tools/mounttable || shell_test::fail "line ${LINENO}: failed to build mounttable"
+  MOUNTTABLED_BIN="$(shell_test::build_go_binary 'veyron.io/veyron/veyron/services/mounttable/mounttabled')"
+  MOUNTTABLE_BIN="$(shell_test::build_go_binary 'veyron.io/veyron/veyron/tools/mounttable')"
 }
 
 main() {
   local EP GOT NHEP WANT
 
-  cd "${TMPDIR}"
+  cd "${WORKDIR}"
   build
 
   # Start mounttabled and find its endpoint.
   local -r NHNAME=test-$(hostname)-$$
-  local -r MTLOG="${TMPDIR}/mt.log"
+  local -r MTLOG="${WORKDIR}/mt.log"
 
   shell::run_server "${shell_test_DEFAULT_SERVER_TIMEOUT}" "${MTLOG}" "${MTLOG}" \
-    ./mounttabled --veyron.tcp.address=127.0.0.1:0 -vmodule=publisher=2 --neighborhood_name="${NHNAME}" &> /dev/null \
+    ${MOUNTTABLED_BIN} --veyron.tcp.address=127.0.0.1:0 -vmodule=publisher=2 --neighborhood_name="${NHNAME}" &> /dev/null \
     || shell_test::fail "line ${LINENO}: failed to start mounttabled"
   shell::timed_wait_for "${shell_test_DEFAULT_MESSAGE_TIMEOUT}" "${MTLOG}" "ipc pub: mount" \
     || shell_test::fail "line ${LINENO}: failed to mount mounttabled"
@@ -35,17 +37,17 @@
     || (cat "${MTLOG}"; shell_test::fail "line ${LINENO}: failed to identify endpoint")
 
   # Get the neighborhood endpoint from the mounttable.
-  NHEP=$(./mounttable glob "${EP}" nh | grep ^nh | cut -d' ' -f2) \
+  NHEP=$(${MOUNTTABLE_BIN} glob "${EP}" nh | grep ^nh | cut -d' ' -f2) \
     || (cat "${MTLOG}"; shell_test::fail "line ${LINENO}: failed to identify neighborhood endpoint")
 
   # Mount objects and verify the result.
-  ./mounttable mount "${EP}/myself" "${EP}" 5m > /dev/null \
+  ${MOUNTTABLE_BIN} mount "${EP}/myself" "${EP}" 5m > /dev/null \
     || shell_test::fail "line ${LINENO}: failed to mount the mounttable on itself"
-  ./mounttable mount "${EP}/google" /www.google.com:80 5m > /dev/null \
+  ${MOUNTTABLE_BIN} mount "${EP}/google" /www.google.com:80 5m > /dev/null \
     || shell_test::fail "line ${LINENO}: failed to mount www.google.com"
 
   # <mounttable>.Glob('*')
-  GOT=$(./mounttable glob "${EP}" '*' | sed 's/TTL [^)]*/TTL XmXXs/' | sort) \
+  GOT=$(${MOUNTTABLE_BIN} glob "${EP}" '*' | sed 's/TTL [^)]*/TTL XmXXs/' | sort) \
     || shell_test::fail "line ${LINENO}: failed to run mounttable"
   WANT="[${EP}]
 google /www.google.com:80 (TTL XmXXs)
@@ -54,7 +56,7 @@
   shell_test::assert_eq "${GOT}" "${WANT}" "${LINENO}"
 
   # <neighborhood>.Glob('NHNAME')
-  GOT=$(./mounttable glob "${NHEP}" "${NHNAME}" | sed 's/TTL [^)]*/TTL XmXXs/' | sort) \
+  GOT=$("${MOUNTTABLE_BIN}" glob "${NHEP}" "${NHNAME}" | sed 's/TTL [^)]*/TTL XmXXs/' | sort) \
     || shell_test::fail "line ${LINENO}: failed to run mounttable"
   WANT="[${NHEP}]
 ${NHNAME} ${EP} (TTL XmXXs)"
diff --git a/tools/debug/test.sh b/tools/debug/test.sh
index 888e481..4c1471a 100755
--- a/tools/debug/test.sh
+++ b/tools/debug/test.sh
@@ -7,10 +7,10 @@
 
 source "${VEYRON_ROOT}/scripts/lib/shell_test.sh"
 
-readonly WORKDIR=$(shell::tmp_dir)
+readonly WORKDIR="${shell_test_WORK_DIR}"
 
 build() {
-  veyron go build veyron.io/veyron/veyron/tools/debug || shell_test::fail "line ${LINENO}: failed to build debug"
+  DEBUG_BIN="$(shell_test::build_go_binary 'veyron.io/veyron/veyron/tools/debug')"
 }
 
 dumplogs() {
@@ -24,9 +24,9 @@
   local GOT WANT
 
   cd "${WORKDIR}"
+  build
   mkdir "tmp"
   export TMPDIR="${WORKDIR}/tmp"
-  build
 
   export VEYRON_CREDENTIALS=$(shell::tmp_dir)
   shell_test::setup_server_test || shell_test::fail "setup_server_test failed"
@@ -35,7 +35,7 @@
 
   # Test top level glob.
   local -r DBGLOG="${WORKDIR}/debug.log"
-  GOT=$(./debug glob "${EP}/__debug/*" 2> "${DBGLOG}") \
+  GOT=$("${DEBUG_BIN}" glob "${EP}/__debug/*" 2> "${DBGLOG}") \
     || (dumplogs "${DBGLOG}"; shell_test::fail "line ${LINENO}: failed to run debug")
   WANT="${EP}/__debug/logs
 ${EP}/__debug/pprof
@@ -43,25 +43,25 @@
   shell_test::assert_eq "${GOT}" "${WANT}" "${LINENO}"
 
   # Test logs glob.
-  GOT=$(./debug glob "${EP}/__debug/logs/*" 2> "${DBGLOG}" | wc -l) \
+  GOT=$("${DEBUG_BIN}" glob "${EP}/__debug/logs/*" 2> "${DBGLOG}" | wc -l) \
     || (dumplogs "${DBGLOG}"; shell_test::fail "line ${LINENO}: failed to run debug")
   shell_test::assert_gt "${GOT}" "0" "${LINENO}"
 
   # Test logs size.
   echo "This is a log file" > "${TMPDIR}/my-test-log-file"
-  GOT=$(./debug logs size "${EP}/__debug/logs/my-test-log-file" 2> "${DBGLOG}") \
+  GOT=$("${DEBUG_BIN}" logs size "${EP}/__debug/logs/my-test-log-file" 2> "${DBGLOG}") \
     || (dumplogs "${DBGLOG}"; shell_test::fail "line ${LINENO}: failed to run debug")
   WANT=$(echo "This is a log file" | wc -c | tr -d ' ')
   shell_test::assert_eq "${GOT}" "${WANT}" "${LINENO}"
 
   # Test logs read.
-  GOT=$(./debug logs read "${EP}/__debug/logs/my-test-log-file" 2> "${DBGLOG}") \
+  GOT=$("${DEBUG_BIN}" logs read "${EP}/__debug/logs/my-test-log-file" 2> "${DBGLOG}") \
     || (dumplogs "${DBGLOG}"; shell_test::fail "line ${LINENO}: failed to run debug")
   WANT="This is a log file"
   shell_test::assert_eq "${GOT}" "${WANT}" "${LINENO}"
 
   # Test stats read.
-  GOT=$(./debug stats read "${EP}/__debug/stats/ipc/server/*/ReadLog/latency-ms" 2> "${DBGLOG}" | wc -l) \
+  GOT=$("${DEBUG_BIN}" stats read "${EP}/__debug/stats/ipc/server/*/ReadLog/latency-ms" 2> "${DBGLOG}" | wc -l) \
     || (dumplogs "${DBGLOG}"; shell_test::fail "line ${LINENO}: failed to run debug")
   shell_test::assert_gt "${GOT}" "0" "${LINENO}"
 
@@ -69,13 +69,13 @@
   local TMP=$(shell::tmp_file)
   touch "${TMP}"
   local -r DEBUG_PID=$(shell::run_server "${shell_test_DEFAULT_SERVER_TIMEOUT}" "${TMP}" "${DBGLOG}" \
-    ./debug stats watch -raw "${EP}/__debug/stats/ipc/server/*/ReadLog/latency-ms")
+    "${DEBUG_BIN}" stats watch -raw "${EP}/__debug/stats/ipc/server/*/ReadLog/latency-ms")
   shell::timed_wait_for "${shell_test_DEFAULT_MESSAGE_TIMEOUT}" "${TMP}" "ReadLog/latency-ms"
   kill "${DEBUG_PID}"
   grep -q "Count:1 " "${TMP}" || (dumplogs "${TMP}"; shell_test::fail "line ${LINENO}: failed to find expected output")
 
   # Test pprof.
-  if ! ./debug pprof run "${EP}/__debug/pprof" heap --text &> "${DBGLOG}"; then
+  if ! "${DEBUG_BIN}" pprof run "${EP}/__debug/pprof" heap --text &> "${DBGLOG}"; then
     dumplogs "${DBGLOG}"
     shell_test::fail "line ${LINENO}: unexpected failure."
   fi
diff --git a/tools/identity/test.sh b/tools/identity/test.sh
index a6e69b8..53a8263 100755
--- a/tools/identity/test.sh
+++ b/tools/identity/test.sh
@@ -8,29 +8,34 @@
 
 source "${VEYRON_ROOT}/scripts/lib/shell_test.sh"
 
+readonly WORKDIR="${shell_test_WORK_DIR}"
+
+build() {
+  IDENTITY_BIN="$(shell_test::build_go_binary 'veyron.io/veyron/veyron/tools/identity')"
+}
+
 main() {
   local GOT
   local WANT
 
-  # Build binaries.
-  cd "${TMPDIR}"
-  veyron go build veyron.io/veyron/veyron/tools/identity || shell_test::fail "line ${LINENO}: failed to build identity"
+  cd "${WORKDIR}"
+  build
 
-  ./identity print >/dev/null || shell_test::fail "line ${LINENO}: print failed"
-  ./identity generate >/dev/null || shell_test::fail "line ${LINENO}: generate failed"
-  ./identity generate root >root || shell_test::fail "line ${LINENO}: generate root failed"
+  "${IDENTITY_BIN}" print >/dev/null || shell_test::fail "line ${LINENO}: print failed"
+  "${IDENTITY_BIN}" generate >/dev/null || shell_test::fail "line ${LINENO}: generate failed"
+  "${IDENTITY_BIN}" generate root >root || shell_test::fail "line ${LINENO}: generate root failed"
 
   export VEYRON_IDENTITY="root"
 
   # Generate an identity and get it blessed by root using "identity bless"
-  GOT=$(./identity generate ignoreme | ./identity bless - child | ./identity print - | awk '/Name/ {print $3}') \
+  GOT=$("${IDENTITY_BIN}" generate ignoreme | "${IDENTITY_BIN}" bless - child | "${IDENTITY_BIN}" print - | awk '/Name/ {print $3}') \
     || shell_test::fail "line ${LINENO}: failed to run identity"
   WANT="root/child"
   shell_test::assert_eq "${GOT}" "${WANT}" "${LINENO}"
 
   # Generate an identity and get it blessed by root using "identity bless --with"
-  ./identity generate other >other || shell_test::fail
-  GOT=$(./identity generate ignoreme | ./identity bless --with=other - child | ./identity print - | awk '/Name/ {print $3}') \
+  "${IDENTITY_BIN}" generate other >other || shell_test::fail
+  GOT=$("${IDENTITY_BIN}" generate ignoreme | "${IDENTITY_BIN}" bless --with=other - child | "${IDENTITY_BIN}" print - | awk '/Name/ {print $3}') \
     || shell_test::fail "line ${LINENO}: failed to run identity"
   WANT="unknown/other/child"
   shell_test::assert_eq "${GOT}" "${WANT}" "${LINENO}"
@@ -41,12 +46,12 @@
   # identity generate "root" >testdata/root.id
   # identity generate "other" | VEYRON_IDENTITY=testdata/root.id identity bless - "blessed" >testdata/blessed.id
   local -r TESTDATA_DIR="${VEYRON_ROOT}/veyron/go/src/veyron.io/veyron/veyron/tools/identity/testdata"
-  GOT=$(VEYRON_IDENTITY="${TESTDATA_DIR}/root.id" ./identity print | awk '/Name/ {print $3}') \
+  GOT=$(VEYRON_IDENTITY="${TESTDATA_DIR}/root.id" "${IDENTITY_BIN}" print | awk '/Name/ {print $3}') \
     || shell_test::fail "line ${LINENO}: failed to run identity"
   WANT="root"
   shell_test::assert_eq "${GOT}" "${WANT}" "${LINENO}"
 
-  GOT=$(VEYRON_IDENTITY="${TESTDATA_DIR}/root.id" ./identity print "${TESTDATA_DIR}/blessed.id" | awk '/Name/ {print $3}') \
+  GOT=$(VEYRON_IDENTITY="${TESTDATA_DIR}/root.id" "${IDENTITY_BIN}" print "${TESTDATA_DIR}/blessed.id" | awk '/Name/ {print $3}') \
     || shell_test::fail "line ${LINENO}: failed to run identity"
   WANT="root/blessed"
   shell_test::assert_eq "${GOT}" "${WANT}" "${LINENO}"
diff --git a/tools/naming/simulator/test.sh b/tools/naming/simulator/test.sh
index 56dfa19..d8373c4 100755
--- a/tools/naming/simulator/test.sh
+++ b/tools/naming/simulator/test.sh
@@ -5,17 +5,19 @@
 
 source "${VEYRON_ROOT}/scripts/lib/shell_test.sh"
 
+readonly WORKDIR="${shell_test_WORK_DIR}"
+
 main() {
   # Build binaries.
-  cd "${TMPDIR}"
-  local -r PKG=veyron.io/veyron/veyron/tools/naming/simulator
-  veyron go build "${PKG}" || shell_test::fail "line ${LINENO}: failed to build simulator"
+  cd "${WORKDIR}"
+  PKG="veyron.io/veyron/veyron/tools/naming/simulator"
+  SIMULATOR_BIN="$(shell_test::build_go_binary ${PKG})"
 
   local -r DIR=$(shell::go_package_dir "${PKG}")
   local file
   for file in "${DIR}"/*.scr; do
     echo "${file}"
-    ./simulator < "${file}" &> /dev/null || shell_test::fail "line ${LINENO}: failed for ${file}"
+    "${SIMULATOR_BIN}" < "${file}" &> /dev/null || shell_test::fail "line ${LINENO}: failed for ${file}"
   done
   shell_test::pass
 }
diff --git a/tools/principal/test.sh b/tools/principal/test.sh
index c5afe4a..5fb525b 100755
--- a/tools/principal/test.sh
+++ b/tools/principal/test.sh
@@ -8,10 +8,10 @@
 
 source "${VEYRON_ROOT}/scripts/lib/shell_test.sh"
 
-readonly WORKDIR=$(shell::tmp_dir)
+readonly WORKDIR=${shell_test_WORK_DIR}
 
 build() {
-  veyron go build veyron.io/veyron/veyron/tools/principal || shell_test::fail "line ${LINENO}: failed to build principal"
+  PRINCIPAL_BIN="$(shell_test::build_go_binary 'veyron.io/veyron/veyron/tools/principal')"
 }
 
 # rmpublickey replaces public keys (16 hex bytes, :-separated) with XX:....
@@ -26,7 +26,7 @@
 }
 
 dumpblessings() {
-    ./principal dumpblessings "$1" | rmpublickey | rmcaveats
+    "${PRINCIPAL_BIN}" dumpblessings "$1" | rmpublickey | rmcaveats
 }
 
 main() {
@@ -36,20 +36,20 @@
   # Prevent any VEYRON_CREDENTIALS in the environment from interfering with this test.
   unset VEYRON_CREDENTIALS
   # Create two principals, one called "alice" one called "bob"
-  ./principal create --overwrite=true ./alice alice >/dev/null || shell_test::fail "line ${LINENO}: create failed"
-  ./principal create ./bob bob >/dev/null || shell_test::fail "line ${LINENO}: create failed"
-  ./principal create --overwrite=true ./bob bob >/dev/null || shell_test::fail "line ${LINENO}: create failed"
+  "${PRINCIPAL_BIN}" create --overwrite=true ./alice alice >/dev/null || shell_test::fail "line ${LINENO}: create failed"
+  "${PRINCIPAL_BIN}" create ./bob bob >/dev/null || shell_test::fail "line ${LINENO}: create failed"
+  "${PRINCIPAL_BIN}" create --overwrite=true ./bob bob >/dev/null || shell_test::fail "line ${LINENO}: create failed"
   # Run dump, bless, blessself on alice
   export VEYRON_CREDENTIALS=./alice
-  ./principal blessself alicereborn >alice.blessself || shell_test::fail "line ${LINENO}: blessself failed"
-  ./principal bless ./bob friend >alice.bless || shell_test::fail "line ${LINENO}: bless failed"
-  ./principal dump >alice.dump || shell_test::fail "line ${LINENO}: dump failed"
+  "${PRINCIPAL_BIN}" blessself alicereborn >alice.blessself || shell_test::fail "line ${LINENO}: blessself failed"
+  "${PRINCIPAL_BIN}" bless ./bob friend >alice.bless || shell_test::fail "line ${LINENO}: bless failed"
+  "${PRINCIPAL_BIN}" dump >alice.dump || shell_test::fail "line ${LINENO}: dump failed"
   # Run store setdefault, store default, store set, store forpeer on bob
   export VEYRON_CREDENTIALS=./bob
-  ./principal store setdefault alice.bless || shell_test::fail "line ${LINENO}: store setdefault failed"
-  ./principal store default >bob.store.default || shell_test::fail "line ${LINENO}: store default failed"
-  ./principal store set alice.bless alice/... || shell_test::fail "line ${LINENO}: store set failed"
-  ./principal store forpeer alice/server >bob.store.forpeer || shell_test::fail "line ${LINENO}: store forpeer failed" 
+  "${PRINCIPAL_BIN}" store setdefault alice.bless || shell_test::fail "line ${LINENO}: store setdefault failed"
+  "${PRINCIPAL_BIN}" store default >bob.store.default || shell_test::fail "line ${LINENO}: store default failed"
+  "${PRINCIPAL_BIN}" store set alice.bless alice/... || shell_test::fail "line ${LINENO}: store set failed"
+  "${PRINCIPAL_BIN}" store forpeer alice/server >bob.store.forpeer || shell_test::fail "line ${LINENO}: store forpeer failed" 
   # Any other commands to be run without VEYRON_CREDENTIALS set.
   unset VEYRON_CREDENTIALS