profiler: auto detect service name and service version on App Engine

flexible environment

Change-Id: I5040de5d9f411dc5161e657e668d57126f526d12
Reviewed-on: https://code-review.googlesource.com/16790
Reviewed-by: Alexey Alexandrov <aalexand@google.com>
diff --git a/profiler/profiler.go b/profiler/profiler.go
index 9a90a14..5ea9723 100644
--- a/profiler/profiler.go
+++ b/profiler/profiler.go
@@ -37,6 +37,7 @@
 	"bytes"
 	"errors"
 	"log"
+	"os"
 	"runtime/pprof"
 	"sync"
 	"time"
@@ -406,14 +407,21 @@
 func initializeConfig(cfg Config) error {
 	config = cfg
 
-	if config.Service != "" {
+	switch {
+	case config.Service != "":
 		config.Target = config.Service
+	case config.Target == "":
+		config.Target = os.Getenv("GAE_SERVICE")
 	}
 
 	if config.Target == "" {
 		return errors.New("service name must be specified in the configuration")
 	}
 
+	if config.ServiceVersion == "" {
+		config.ServiceVersion = os.Getenv("GAE_VERSION")
+	}
+
 	if config.APIAddr == "" {
 		config.APIAddr = apiAddress
 	}
diff --git a/profiler/profiler_test.go b/profiler/profiler_test.go
index 1c1ee1f..780302d 100644
--- a/profiler/profiler_test.go
+++ b/profiler/profiler_test.go
@@ -22,6 +22,7 @@
 	"io"
 	"log"
 	"math/rand"
+	"os"
 	"strings"
 	"testing"
 	"time"
@@ -48,7 +49,7 @@
 	testZoneName        = "test-zone-name"
 	testTarget          = "test-target"
 	testService         = "test-service"
-	testServiceVersion  = "test-service-version"
+	testSvcVersion      = "test-service-version"
 	testProfileDuration = time.Second * 10
 	testServerTimeout   = time.Second * 15
 	wantFunctionName    = "profilee"
@@ -57,7 +58,7 @@
 func createTestDeployment() *pb.Deployment {
 	labels := map[string]string{
 		zoneNameLabel: testZoneName,
-		versionLabel:  testServiceVersion,
+		versionLabel:  testSvcVersion,
 	}
 	return &pb.Deployment{
 		ProjectId: testProjectID,
@@ -357,7 +358,7 @@
 		return testZoneName, nil
 	}
 
-	cfg := Config{Service: testService, ServiceVersion: testServiceVersion}
+	cfg := Config{Service: testService, ServiceVersion: testSvcVersion}
 	initializeConfig(cfg)
 	d, err := initializeDeployment()
 	if err != nil {
@@ -370,32 +371,93 @@
 }
 
 func TestInitializeConfig(t *testing.T) {
-	oldConfig := config
+	oldConfig, oldService, oldVersion := config, os.Getenv("GAE_SERVICE"), os.Getenv("GAE_VERSION")
 	defer func() {
 		config = oldConfig
+		if err := os.Setenv("GAE_SERVICE", oldService); err != nil {
+			t.Fatal(err)
+		}
+		if err := os.Setenv("GAE_VERSION", oldVersion); err != nil {
+			t.Fatal(err)
+		}
 	}()
-
+	testGAEService := "test-gae-service"
+	testGAEVersion := "test-gae-version"
 	for _, tt := range []struct {
 		config          Config
 		wantTarget      string
 		wantErrorString string
+		wantSvcVersion  string
+		onGAE           bool
 	}{
 		{
 			Config{Service: testService},
 			testService,
 			"",
+			"",
+			false,
 		},
 		{
 			Config{Target: testTarget},
 			testTarget,
 			"",
+			"",
+			false,
 		},
 		{
 			Config{},
 			"",
 			"service name must be specified in the configuration",
+			"",
+			false,
+		},
+		{
+			Config{Service: testService},
+			testService,
+			"",
+			testGAEVersion,
+			true,
+		},
+		{
+			Config{Target: testTarget},
+			testTarget,
+			"",
+			testGAEVersion,
+			true,
+		},
+		{
+			Config{},
+			testGAEService,
+			"",
+			testGAEVersion,
+			true,
+		},
+		{
+			Config{Service: testService, ServiceVersion: testSvcVersion},
+			testService,
+			"",
+			testSvcVersion,
+			false,
+		},
+		{
+			Config{Service: testService, ServiceVersion: testSvcVersion},
+			testService,
+			"",
+			testSvcVersion,
+			true,
 		},
 	} {
+		envService, envVersion := "", ""
+		if tt.onGAE {
+			envService, envVersion = testGAEService, testGAEVersion
+		}
+		if err := os.Setenv("GAE_SERVICE", envService); err != nil {
+			t.Fatal(err)
+		}
+		if err := os.Setenv("GAE_VERSION", envVersion); err != nil {
+			t.Fatal(err)
+		}
+
 		errorString := ""
 		if err := initializeConfig(tt.config); err != nil {
 			errorString = err.Error()
@@ -408,6 +470,9 @@
 		if config.Target != tt.wantTarget {
 			t.Errorf("initializeConfig(%v) got target: %v, want %v", tt.config, config.Target, tt.wantTarget)
 		}
+		if config.ServiceVersion != tt.wantSvcVersion {
+			t.Errorf("initializeConfig(%v) got service version: %v, want %v", tt.config, config.ServiceVersion, tt.wantSvcVersion)
+		}
 	}
 }