Add a script to enable running tests locally (#2979)

* build/all.bash: script to enable running tests locally and reliably

This script provides a command to build and run tests in a docker
container where all tools and source code used by tests are installed
and all environment variables tests depend on (e.g. GOPATH) are set
properly.

   Usage: build/all.bash testlocal

The container uses the latest official release of Go and node.
I hoped this could help setting up the environment to reproduce the
current CI test run failure but the test succeeded - that indicates the
problem may be in the environment used in the travis.

* .vsignore: exclude build/* files from vs extension packaging
diff --git a/.vscodeignore b/.vscodeignore
index b112084..8b678ce 100644
--- a/.vscodeignore
+++ b/.vscodeignore
@@ -7,3 +7,4 @@
 test/
 **/*.map
 **/tslint.json
+build/**/*
diff --git a/build/Dockerfile b/build/Dockerfile
new file mode 100644
index 0000000..6f55594
--- /dev/null
+++ b/build/Dockerfile
@@ -0,0 +1,39 @@
+FROM golang:latest AS gobuilder
+
+ENV GO111MODULE on
+ENV GOBIN /gobin
+ENV GOPROXY https://proxy.golang.org
+RUN cd $(mktemp -d) && go get golang.org/x/tools/gopls@latest
+
+FROM node:latest
+
+# GO111MODULE=auto
+RUN mkdir /go
+COPY --from=gobuilder /gobin /go/bin
+COPY --from=gobuilder /usr/local/go /usr/local/go
+
+# TODO(hyangah): some tests fail if GOPATH is not set. Fix them.
+ENV GOPATH=/go
+ENV PATH=${GOPATH}/bin:/usr/local/go/bin:${PATH}
+ENV DEBIAN_FRONTEND noninteractive
+
+RUN apt-get update && apt-get install -y libnss3 libgtk-3-dev libxss1 libasound2 xvfb libsecret-1-0
+
+# Install other Go tools tests depend on
+RUN go get -u -v \
+	github.com/acroca/go-symbols \
+	github.com/cweill/gotests/... \
+  	github.com/davidrjenni/reftools/cmd/fillstruct \
+  	github.com/haya14busa/goplay/cmd/goplay \
+  	github.com/mdempsky/gocode \
+  	github.com/ramya-rao-a/go-outline \
+  	github.com/rogpeppe/godef \
+  	github.com/sqs/goreturns \
+  	github.com/uudashr/gopkgs/cmd/gopkgs \
+  	github.com/zmb3/gogetdoc \
+  	golang.org/x/lint/golint \
+  	golang.org/x/tools/cmd/gorename
+
+
+WORKDIR /workspace
+ENTRYPOINT ["build/all.bash"]
diff --git a/build/all.bash b/build/all.bash
new file mode 100755
index 0000000..1a8e4a8
--- /dev/null
+++ b/build/all.bash
@@ -0,0 +1,78 @@
+#!/bin/bash -e
+usage() {
+  cat <<EOUSAGE
+Usage: $0 [subcommand]
+Available subcommands:
+  help      - display this help message.
+  test      - build and test locally. Some tests may fail if vscode is alreay in use.
+  testlocal - build and test in a locally built container.
+  ci        - build and test with headless vscode. Requires Xvfb.
+EOUSAGE
+}
+
+# TODO(hyangah): commands for building docker container and running tests locally with docker run.
+root_dir() {
+  local script_name=$(readlink -f "${0}")
+  local script_dir=$(dirname "${script_name}")
+  local parent_dir=$(dirname "${script_dir}")
+  echo "${parent_dir}"
+}
+
+setup_virtual_display() {
+  echo "**** Set up virtual display ****"
+  # Start xvfb (an in-memory display server for UNIX-like operating system)
+  # so we can launch a headless vscode for testing.
+  /usr/bin/Xvfb :99 -screen 0 1024x768x24 > /dev/null 2>&1 &
+  trap 'kill "$(jobs -p)"' EXIT
+  export DISPLAY=:99
+  sleep 3  # Wait for xvfb to be up.
+}
+
+go_binaries_info() {
+  echo "**** Go version ****"
+  which go
+  go version
+  echo "**** Gopls version ****"
+  go version -m "$(which gopls)"
+}
+
+run_test() {
+  echo "**** Run test ****"
+  npm ci
+  npm run compile
+  npm run lint
+  npm run unit-test
+  npm test --silent
+}
+
+run_test_in_docker() {
+  echo "**** Building the docker image ***"
+  docker build -t vscode-test-env ./build
+  docker run --workdir=/workspace -v "$(pwd):/workspace" vscode-test-env ci
+}
+
+main() {
+  cd "$(root_dir)"  # always run from the script root.
+  case "$1" in
+    "help"|"-h"|"--help")
+      usage
+      exit 0
+      ;;
+    "test")
+      go_binaries_info
+      run_test
+      ;;
+    "testlocal")
+      run_test_in_docker
+      ;;
+    "ci")
+      go_binaries_info
+      setup_virtual_display
+      run_test
+      ;;
+    *)
+      usage
+      exit 2
+  esac
+}
+main $@
\ No newline at end of file