veyron/tools/playground: Fix jenkins tests (with luck).

Issues included:
* veyron.js was not linked, js files could not require it.
* addresses were given in IPv6 format, which GCE can't handle.
* port collisions when starting processes.

Change-Id: I51b84135365e9f91709cb69b695b992b282feba8
diff --git a/tools/playground/builder/netrc b/tools/playground/builder/netrc
deleted file mode 100644
index 2cb442c..0000000
--- a/tools/playground/builder/netrc
+++ /dev/null
@@ -1,2 +0,0 @@
-machine veyron.googlesource.com login git-nlacasse.google.com password 1/jK0LNfz-nCtEoI2zixqeuGJww3CIlfN_vY31eVDRMck
-machine veyron-review.googlesource.com login git-nlacasse.google.com password 1/jK0LNfz-nCtEoI2zixqeuGJww3CIlfN_vY31eVDRMck
diff --git a/tools/playground/builder/services.go b/tools/playground/builder/services.go
index ded83f9..3bee6a8 100644
--- a/tools/playground/builder/services.go
+++ b/tools/playground/builder/services.go
@@ -6,19 +6,42 @@
 	"fmt"
 	"io"
 	"log"
+	"math/rand"
 	"os"
 	"path"
 	"regexp"
 	"strconv"
+	"syscall"
 	"time"
 )
 
 var (
-	proxyPort    = 1234
-	proxyName    = "proxy"
-	wsprBasePort = 1235
+	proxyName = "proxy"
 )
 
+// Note: This was copied from veyron/go/src/veyron/tools/findunusedport.
+// I would like to be able to import that package directly, but it defines a
+// main(), so can't be imported.  An alternative solution would be to call the
+// 'findunusedport' binary, but that would require starting another process and
+// parsing the output.  It seemed simpler to just copy the function here.
+func findUnusedPort() (int, error) {
+	rnd := rand.New(rand.NewSource(time.Now().UnixNano()))
+	for i := 0; i < 1000; i++ {
+		port := 1024 + rnd.Int31n(64512)
+		fd, err := syscall.Socket(syscall.AF_INET, syscall.SOCK_STREAM, syscall.IPPROTO_TCP)
+		if err != nil {
+			continue
+		}
+		sa := &syscall.SockaddrInet4{Port: int(port)}
+		if err := syscall.Bind(fd, sa); err != nil {
+			continue
+		}
+		syscall.Close(fd)
+		return int(port), nil
+	}
+	return 0, fmt.Errorf("Can't find unused port.")
+}
+
 // startMount starts a mounttabled process, and sets the NAMESPACE_ROOT env
 // variable to the mounttable's location.  We run one mounttabled process for
 // the entire environment.
@@ -60,7 +83,11 @@
 // startProxy starts a proxyd process.  We run one proxyd process for the
 // entire environment.
 func startProxy() (proc *os.Process, err error) {
-	cmd := makeCmdJsonEvent("", "proxyd", "-name="+proxyName, "-address=:"+strconv.Itoa(proxyPort))
+	port, err := findUnusedPort()
+	if err != nil {
+		return nil, err
+	}
+	cmd := makeCmdJsonEvent("", "proxyd", "-name="+proxyName, "-address=localhost:"+strconv.Itoa(port))
 	err = cmd.Start()
 	if err != nil {
 		return nil, err
@@ -69,10 +96,12 @@
 }
 
 // startWspr starts a wsprd process. We run one wsprd process for each
-// javascript file being run. The 'index' argument is used to pick a distinct
-// port for each wsprd process.
+// javascript file being run.
 func startWspr(f *codeFile) (proc *os.Process, port int, err error) {
-	port = wsprBasePort + f.index
+	port, err = findUnusedPort()
+	if err != nil {
+		return nil, port, err
+	}
 	cmd := makeCmdJsonEvent(f.Name,
 		"wsprd",
 		"-v=-1",
diff --git a/tools/playground/builder/vbuild.go b/tools/playground/builder/vbuild.go
index cc9188e..df63c38 100644
--- a/tools/playground/builder/vbuild.go
+++ b/tools/playground/builder/vbuild.go
@@ -25,7 +25,7 @@
 	"veyron/tools/playground/event"
 )
 
-const RUN_TIMEOUT = time.Second
+const runTimeout = 3 * time.Second
 
 var (
 	verbose = flag.Bool("v", false, "Verbose mode")
@@ -153,7 +153,7 @@
 		log.Fatal(err)
 	}
 
-	mt, err := startMount(RUN_TIMEOUT)
+	mt, err := startMount(runTimeout)
 	if err != nil {
 		log.Fatal(err)
 	}
@@ -222,12 +222,13 @@
 		}
 	}
 
-	timeout := time.After(RUN_TIMEOUT)
+	timeout := time.After(runTimeout)
 
 	for running > 0 {
 		select {
 		case <-timeout:
 			writeEvent("", "Playground exceeded deadline.", "stderr")
+			stopAll(files)
 		case status := <-exit:
 			if status.err == nil {
 				writeEvent(status.name, "Exited.", "stdout")
@@ -376,6 +377,17 @@
 	cmd := exec.Command(prog, args...)
 	cmd.Env = os.Environ()
 
+	// TODO(nlacasse): There is a bug in this code which results in
+	//   "read |0: bad file descriptor".
+	// The error seems to be caused by our use of cmd.StdoutPipe/StderrPipe
+	// and cmd.Wait.  In particular, we seem to be calling Wait after the
+	// pipes have been closed.
+	// See: http://stackoverflow.com/questions/20134095/why-do-i-get-bad-file-descriptor-in-this-go-program-using-stderr-and-ioutil-re
+	// and https://code.google.com/p/go/issues/detail?id=2266
+	//
+	// One solution is to wrap cmd.Start/Run, so that wait is never called
+	// before the pipes are closed.
+
 	stdout, err := cmd.StdoutPipe()
 	if err != nil {
 		log.Fatal(err)
diff --git a/tools/playground/test.sh b/tools/playground/test.sh
index 214570d..90d4e8f 100755
--- a/tools/playground/test.sh
+++ b/tools/playground/test.sh
@@ -4,6 +4,18 @@
 
 source "${VEYRON_ROOT}/environment/scripts/lib/shell_test.sh"
 
+install_veyron_js() {
+  # This installs the veyron.js library, and makes it accessable to javascript
+  # files in the veyron playground test folder under the module name 'veyron'.
+  #
+  # TODO(nlacasse): Once veyron.js is installed in a public npm registry, this
+  # should be replaced with just "npm install veyron".
+  pushd "${VEYRON_ROOT}/veyron.js"
+  "${VEYRON_ROOT}/environment/cout/node/bin/npm" link
+  popd
+  "${VEYRON_ROOT}/environment/cout/node/bin/npm" link veyron
+}
+
 build() {
   local -r GO="${VEYRON_ROOT}/veyron/scripts/build/go"
   "${GO}" build veyron/tools/identity || shell_test::fail "line ${LINENO}: failed to build 'identity'"
@@ -35,6 +47,7 @@
 main() {
   cd $(shell::tmp_dir)
   build
+  install_veyron_js
 
   local -r DIR="${VEYRON_ROOT}/veyron/go/src/veyron/tools/playground/testdata"