Fix profiler integration test.

The profiler integration test hasn't run for some time since it was
covered by a build tag that was not specified in the
internal/kokoro/continuous.sh script used to run the tests now. Fix that
by not using that build tag anymore and instead skip the integration
test when the cloud project environment is not specified.

Also remove versions of Go that are unsupported now.

Also start passing X-Goog-User-Project header to override the client
project ID to make it possible to run the test with authentication set
up with gcloud application default credentials, not just service
account.

Tested locally. Command used for the test:

GCLOUD_TESTS_GOLANG_PROJECT_ID=dulcet-port-762 GCLOUD_TESTS_GOLANG_PROFILER_ZONE=us-west1-b go test -timeout=60m -v ./... -commit=$(git rev-parse HEAD)

Change-Id: I4ffbb5153cf2284ef84d0963dd845dc4b40f2912
Reviewed-on: https://code-review.googlesource.com/c/37511
Reviewed-by: Jean de Klerk <deklerk@google.com>
diff --git a/internal/kokoro/continuous.sh b/internal/kokoro/continuous.sh
index 7fde176..dd60ecc 100755
--- a/internal/kokoro/continuous.sh
+++ b/internal/kokoro/continuous.sh
@@ -1,12 +1,16 @@
 #!/bin/bash
 
 export GOOGLE_APPLICATION_CREDENTIALS=$KOKORO_KEYSTORE_DIR/72523_go_integration_service_account
+# Removing the GCLOUD_TESTS_GOLANG_PROJECT_ID setting may make some integration
+# tests (like profiler's) silently skipped, so make sure you know what you are
+# doing when changing / removing the next line.
 export GCLOUD_TESTS_GOLANG_PROJECT_ID=dulcet-port-762
 export GCLOUD_TESTS_GOLANG_KEY=$GOOGLE_APPLICATION_CREDENTIALS
 export GCLOUD_TESTS_GOLANG_FIRESTORE_PROJECT_ID=gcloud-golang-firestore-tests
 export GCLOUD_TESTS_GOLANG_FIRESTORE_KEY=$KOKORO_KEYSTORE_DIR/72523_go_firestore_integration_service_account
 export GCLOUD_TESTS_API_KEY=`cat $KOKORO_KEYSTORE_DIR/72523_go_gcloud_tests_api_key`
 export GCLOUD_TESTS_GOLANG_KEYRING=projects/dulcet-port-762/locations/global/keyRings/go-integration-test
+export GCLOUD_TESTS_GOLANG_PROFILER_ZONE="us-west1-b"
 
 # Fail on any error
 set -eo pipefail
@@ -40,4 +44,4 @@
 ./internal/kokoro/vet.sh
 
 # Run tests and tee output to log file, to be pushed to GCS as artifact.
-go test -race -v -timeout 15m ./... 2>&1 | tee $KOKORO_ARTIFACTS_DIR/$KOKORO_GERRIT_CHANGE_NUMBER.txt
+go test -race -v -timeout 30m ./... 2>&1 | tee $KOKORO_ARTIFACTS_DIR/$KOKORO_GERRIT_CHANGE_NUMBER.txt
diff --git a/profiler/busybench/busybench.go b/profiler/busybench/busybench.go
index d99e6f5..ee7b321 100644
--- a/profiler/busybench/busybench.go
+++ b/profiler/busybench/busybench.go
@@ -30,7 +30,7 @@
 var (
 	service        = flag.String("service", "", "service name")
 	mutexProfiling = flag.Bool("mutex_profiling", false, "enable mutex profiling")
-	duration       = flag.Int("duration", 600, "duration of the benchmark in seconds")
+	duration       = flag.Int("duration", 150, "duration of the benchmark in seconds")
 	apiAddr        = flag.String("api_address", "", "API address of the profiler (e.g. 'cloudprofiler.googleapis.com:443')")
 	projectID      = flag.String("project_id", "", "cloud project ID")
 )
diff --git a/profiler/integration-test.sh b/profiler/integration-test.sh
deleted file mode 100644
index bb29f11..0000000
--- a/profiler/integration-test.sh
+++ /dev/null
@@ -1,43 +0,0 @@
-#!/bin/bash
-
-retry() {
-  for i in {1..3}; do
-    "${@}" && return 0
-  done
-  return 1
-}
-
-# Fail on any error.
-set -eo pipefail
-
-# Display commands being run.
-set -x
-
-cd git/gocloud
-COMMIT=$(git rev-parse HEAD)
-
-# Set $GOPATH
-export GOPATH="$HOME/go"
-GOCLOUD_HOME=$GOPATH/src/cloud.google.com/go
-mkdir -p $GOCLOUD_HOME
-
-# Move code into $GOPATH and get dependencies
-cp -R ./* $GOCLOUD_HOME
-cd $GOCLOUD_HOME/internal/kokoro
-# Don't print out encryption keys, etc
-set +x
-key=$(cat "$KOKORO_ARTIFACTS_DIR/keystore/72523_encrypted_ba2d6f7723ed_key")
-iv=$(cat "$KOKORO_ARTIFACTS_DIR/keystore/72523_encrypted_ba2d6f7723ed_iv")
-pass=$(cat "$KOKORO_ARTIFACTS_DIR/keystore/72523_encrypted_ba2d6f7723ed_pass")
-
-openssl aes-256-cbc -K $key -iv $iv -pass pass:$pass -in kokoro-key.json.enc -out key.json -d
-set -x
-
-export GOOGLE_APPLICATION_CREDENTIALS="$(pwd)/key.json"
-export GCLOUD_TESTS_GOLANG_PROJECT_ID="dulcet-port-762"
-export GCLOUD_TESTS_GOLANG_ZONE="us-west1-b"
-export GCLOUD_TESTS_GOLANG_BUCKET="dulcet-port-762-go-cloud-profiler-test"
-
-cd $GOCLOUD_HOME/profiler
-retry go get -t -tags=integration .
-go test -timeout=60m -tags=integration -run TestAgentIntegration -commit="$COMMIT"
diff --git a/profiler/integration_test.go b/profiler/integration_test.go
index 8f1ea35..353445f 100644
--- a/profiler/integration_test.go
+++ b/profiler/integration_test.go
@@ -12,16 +12,14 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-// +build integration,go1.7
-
 package profiler
 
 import (
 	"bytes"
 	"context"
-	"flag"
 	"fmt"
 	"os"
+	"os/exec"
 	"runtime"
 	"strings"
 	"testing"
@@ -33,11 +31,6 @@
 	compute "google.golang.org/api/compute/v1"
 )
 
-var (
-	commit = flag.String("commit", "", "git commit to test")
-	runID  = strings.Replace(time.Now().Format("2006-01-02-15-04-05.000000-0700"), ".", "-", -1)
-)
-
 const (
 	cloudScope        = "https://www.googleapis.com/auth/cloud-platform"
 	benchFinishString = "busybench finished profiling"
@@ -88,9 +81,11 @@
 
 # Install agent
 retry git clone https://code.googlesource.com/gocloud $GOCLOUD_HOME >/dev/null
+cd $GOCLOUD_HOME
+retry git fetch origin {{.Commit}}
+git reset --hard {{.Commit}}
 
 cd $GOCLOUD_HOME/profiler/busybench
-git reset --hard {{.Commit}}
 retry go get >/dev/null
 
 # Run benchmark with agent
@@ -100,13 +95,6 @@
 ) 2>&1 | while read line; do echo "$(date): ${line}"; done >/dev/ttyS1
 `
 
-const dockerfileFmt = `FROM golang
-RUN git clone https://code.googlesource.com/gocloud /go/src/cloud.google.com/go \
-    && cd /go/src/cloud.google.com/go/profiler/busybench && git reset --hard %s \
-    && go get && go install
-CMD ["busybench", "--service", "%s"]
- `
-
 type goGCETestCase struct {
 	proftest.InstanceConfig
 	name             string
@@ -115,7 +103,7 @@
 	wantProfileTypes []string
 }
 
-func (tc *goGCETestCase) initializeStartupScript(template *template.Template) error {
+func (tc *goGCETestCase) initializeStartupScript(template *template.Template, commit string) error {
 	var buf bytes.Buffer
 	err := template.Execute(&buf,
 		struct {
@@ -127,7 +115,7 @@
 		}{
 			Service:        tc.name,
 			GoVersion:      tc.goVersion,
-			Commit:         *commit,
+			Commit:         commit,
 			ErrorString:    errorString,
 			MutexProfiling: tc.mutexProfiling,
 		})
@@ -139,19 +127,37 @@
 }
 
 func TestAgentIntegration(t *testing.T) {
+	if testing.Short() {
+		t.Skip("skipping profiler integration test in short mode")
+	}
+
 	projectID := os.Getenv("GCLOUD_TESTS_GOLANG_PROJECT_ID")
 	if projectID == "" {
-		t.Fatalf("Getenv(GCLOUD_TESTS_GOLANG_PROJECT_ID) got empty string")
+		t.Skip("skipping profiler integration test when GCLOUD_TESTS_GOLANG_PROJECT_ID variable is not set")
 	}
 
-	zone := os.Getenv("GCLOUD_TESTS_GOLANG_ZONE")
+	zone := os.Getenv("GCLOUD_TESTS_GOLANG_PROFILER_ZONE")
 	if zone == "" {
-		t.Fatalf("Getenv(GCLOUD_TESTS_GOLANG_ZONE) got empty string")
+		t.Fatalf("GCLOUD_TESTS_GOLANG_PROFILER_ZONE environment variable must be set when integration test is requested")
 	}
 
-	if *commit == "" {
-		t.Fatal("commit flag is not set")
+	// Figure out the Git commit of the current directory. The source checkout in
+	// the test VM will run in the same commit. Note that any local changes to
+	// the profiler agent won't be tested in the integration test. This flow only
+	// works with code that has been committed and pushed to the public repo
+	// (either to master or to a branch).
+	output, err := exec.Command("git", "rev-parse", "HEAD").CombinedOutput()
+	if err != nil {
+		t.Fatalf("failed to gather the Git revision of the current source: %v", err)
 	}
+	commit := strings.Trim(string(output), "\n")
+	t.Logf("using Git commit %q for the profiler integration test", commit)
+
+	pst, err := time.LoadLocation("America/Los_Angeles")
+	if err != nil {
+		t.Fatalf("failed to initiate PST location: %v", err)
+	}
+	runID := strings.Replace(time.Now().In(pst).Format("2006-01-02-15-04-05.000000-0700"), ".", "-", -1)
 
 	ctx := context.Background()
 
@@ -216,40 +222,6 @@
 			goVersion:        "1.9",
 			mutexProfiling:   true,
 		},
-		{
-			InstanceConfig: proftest.InstanceConfig{
-				ProjectID:   projectID,
-				Zone:        zone,
-				Name:        fmt.Sprintf("profiler-test-go18-%s", runID),
-				MachineType: "n1-standard-1",
-			},
-			name:             fmt.Sprintf("profiler-test-go18-%s-gce", runID),
-			wantProfileTypes: []string{"CPU", "HEAP", "THREADS", "CONTENTION", "HEAP_ALLOC"},
-			goVersion:        "1.8",
-			mutexProfiling:   true,
-		},
-		{
-			InstanceConfig: proftest.InstanceConfig{
-				ProjectID:   projectID,
-				Zone:        zone,
-				Name:        fmt.Sprintf("profiler-test-go17-%s", runID),
-				MachineType: "n1-standard-1",
-			},
-			name:             fmt.Sprintf("profiler-test-go17-%s-gce", runID),
-			wantProfileTypes: []string{"CPU", "HEAP", "THREADS", "HEAP_ALLOC"},
-			goVersion:        "1.7",
-		},
-		{
-			InstanceConfig: proftest.InstanceConfig{
-				ProjectID:   projectID,
-				Zone:        zone,
-				Name:        fmt.Sprintf("profiler-test-go16-%s", runID),
-				MachineType: "n1-standard-1",
-			},
-			name:             fmt.Sprintf("profiler-test-go16-%s-gce", runID),
-			wantProfileTypes: []string{"CPU", "HEAP", "THREADS", "HEAP_ALLOC"},
-			goVersion:        "1.6",
-		},
 	}
 	// The number of tests run in parallel is the current value of GOMAXPROCS.
 	runtime.GOMAXPROCS(len(testcases))
@@ -257,7 +229,7 @@
 		tc := tc // capture range variable
 		t.Run(tc.name, func(t *testing.T) {
 			t.Parallel()
-			if err := tc.initializeStartupScript(template); err != nil {
+			if err := tc.initializeStartupScript(template, commit); err != nil {
 				t.Fatalf("failed to initialize startup script")
 			}
 
diff --git a/profiler/proftest/proftest.go b/profiler/proftest/proftest.go
index 7d8c1cb..4c1b7d4 100644
--- a/profiler/proftest/proftest.go
+++ b/profiler/proftest/proftest.go
@@ -306,7 +306,15 @@
 
 	queryRequest := fmt.Sprintf(queryJSONFmt, endTime, profileType, startTime, service)
 
-	resp, err := tr.Client.Post(queryURL, "application/json", strings.NewReader(queryRequest))
+	req, err := http.NewRequest("POST", queryURL, strings.NewReader(queryRequest))
+	if err != nil {
+		return ProfileResponse{}, fmt.Errorf("failed to create an API request: %v", err)
+	}
+	req.Header = map[string][]string{
+		"X-Goog-User-Project": {projectID},
+	}
+
+	resp, err := tr.Client.Do(req)
 	if err != nil {
 		return ProfileResponse{}, fmt.Errorf("failed to query API: %v", err)
 	}