profiler: add support for Knative environment variables

Change-Id: Ief6fad9a5829dbf41f9c41828c6463046083ffd1
Reviewed-on: https://code-review.googlesource.com/c/gocloud/+/39031
Reviewed-by: kokoro <noreply+kokoro@google.com>
Reviewed-by: Kalyana Chadalavada <kchadalavada@google.com>
diff --git a/profiler/profiler.go b/profiler/profiler.go
index 546d8d6..71f5191 100644
--- a/profiler/profiler.go
+++ b/profiler/profiler.go
@@ -474,7 +474,12 @@
 	config = cfg
 
 	if config.Service == "" {
-		config.Service = os.Getenv("GAE_SERVICE")
+		for _, ev := range []string{"GAE_SERVICE", "K_SERVICE"} {
+			if val := os.Getenv(ev); val != "" {
+				config.Service = val
+				break
+			}
+		}
 	}
 	if config.Service == "" {
 		return errors.New("service name must be configured")
@@ -484,7 +489,12 @@
 	}
 
 	if config.ServiceVersion == "" {
-		config.ServiceVersion = os.Getenv("GAE_VERSION")
+		for _, ev := range []string{"GAE_VERSION", "K_REVISION"} {
+			if val := os.Getenv(ev); val != "" {
+				config.ServiceVersion = val
+				break
+			}
+		}
 	}
 
 	if projectID := os.Getenv("GOOGLE_CLOUD_PROJECT"); config.ProjectID == "" && projectID != "" {
diff --git a/profiler/profiler_test.go b/profiler/profiler_test.go
index 82d803e..16effde 100644
--- a/profiler/profiler_test.go
+++ b/profiler/profiler_test.go
@@ -443,13 +443,19 @@
 }
 
 func TestInitializeConfig(t *testing.T) {
-	oldConfig, oldService, oldVersion, oldEnvProjectID, oldGetProjectID, oldGetInstanceName, oldGetZone, oldOnGCE := config, os.Getenv("GAE_SERVICE"), os.Getenv("GAE_VERSION"), os.Getenv("GOOGLE_CLOUD_PROJECT"), getProjectID, getInstanceName, getZone, onGCE
+	oldConfig, oldGAEService, oldGAEVersion, oldKnativeService, oldKnativeVersion, oldEnvProjectID, oldGetProjectID, oldGetInstanceName, oldGetZone, oldOnGCE := config, os.Getenv("GAE_SERVICE"), os.Getenv("GAE_VERSION"), os.Getenv("K_SERVICE"), os.Getenv("K_REVISION"), os.Getenv("GOOGLE_CLOUD_PROJECT"), getProjectID, getInstanceName, getZone, onGCE
 	defer func() {
 		config, getProjectID, getInstanceName, getZone, onGCE = oldConfig, oldGetProjectID, oldGetInstanceName, oldGetZone, oldOnGCE
-		if err := os.Setenv("GAE_SERVICE", oldService); err != nil {
+		if err := os.Setenv("GAE_SERVICE", oldGAEService); err != nil {
 			t.Fatal(err)
 		}
-		if err := os.Setenv("GAE_VERSION", oldVersion); err != nil {
+		if err := os.Setenv("GAE_VERSION", oldGAEVersion); err != nil {
+			t.Fatal(err)
+		}
+		if err := os.Setenv("K_SERVICE", oldKnativeService); err != nil {
+			t.Fatal(err)
+		}
+		if err := os.Setenv("K_REVISION", oldKnativeVersion); err != nil {
 			t.Fatal(err)
 		}
 		if err := os.Setenv("GOOGLE_CLOUD_PROJECT", oldEnvProjectID); err != nil {
@@ -457,10 +463,12 @@
 		}
 	}()
 	const (
-		testGAEService   = "test-gae-service"
-		testGAEVersion   = "test-gae-version"
-		testGCEProjectID = "test-gce-project-id"
-		testEnvProjectID = "test-env-project-id"
+		testGAEService     = "test-gae-service"
+		testGAEVersion     = "test-gae-version"
+		testKnativeService = "test-knative-service"
+		testKnativeVersion = "test-knative-version"
+		testGCEProjectID   = "test-gce-project-id"
+		testEnvProjectID   = "test-env-project-id"
 	)
 	for _, tt := range []struct {
 		desc            string
@@ -468,6 +476,7 @@
 		wantConfig      Config
 		wantErrorString string
 		onGAE           bool
+		onKnative       bool
 		onGCE           bool
 		envProjectID    bool
 	}{
@@ -477,6 +486,7 @@
 			Config{Service: testService, ProjectID: testGCEProjectID, Zone: testZone, Instance: testInstance},
 			"",
 			false,
+			false,
 			true,
 			false,
 		},
@@ -486,6 +496,7 @@
 			Config{Service: testService, ProjectID: testEnvProjectID, Zone: testZone, Instance: testInstance},
 			"",
 			false,
+			false,
 			true,
 			true,
 		},
@@ -495,6 +506,7 @@
 			Config{},
 			"service name must be configured",
 			false,
+			false,
 			true,
 			false,
 		},
@@ -504,6 +516,7 @@
 			Config{Service: "Service"},
 			"service name \"Service\" does not match regular expression ^[a-z]([-a-z0-9_.]{0,253}[a-z0-9])?$",
 			false,
+			false,
 			true,
 			false,
 		},
@@ -513,6 +526,7 @@
 			Config{Service: testService, ServiceVersion: testGAEVersion, ProjectID: testGCEProjectID, Zone: testZone, Instance: testInstance},
 			"",
 			true,
+			false,
 			true,
 			false,
 		},
@@ -522,6 +536,17 @@
 			Config{Service: testGAEService, ServiceVersion: testGAEVersion, ProjectID: testGCEProjectID, Zone: testZone, Instance: testInstance},
 			"",
 			true,
+			false,
+			true,
+			false,
+		},
+		{
+			"reads both service name and version from Knative env vars",
+			Config{},
+			Config{Service: testKnativeService, ServiceVersion: testKnativeVersion, ProjectID: testGCEProjectID, Zone: testZone, Instance: testInstance},
+			"",
+			false,
+			true,
 			true,
 			false,
 		},
@@ -531,6 +556,7 @@
 			Config{Service: testService, ServiceVersion: testSvcVersion, ProjectID: testGCEProjectID, Zone: testZone, Instance: testInstance},
 			"",
 			false,
+			false,
 			true,
 			false,
 		},
@@ -540,6 +566,27 @@
 			Config{Service: testService, ServiceVersion: testSvcVersion, ProjectID: testGCEProjectID, Zone: testZone, Instance: testInstance},
 			"",
 			true,
+			false,
+			true,
+			false,
+		},
+		{
+			"configured version has priority over Knative-provided version",
+			Config{Service: testService, ServiceVersion: testSvcVersion},
+			Config{Service: testService, ServiceVersion: testSvcVersion, ProjectID: testGCEProjectID, Zone: testZone, Instance: testInstance},
+			"",
+			false,
+			true,
+			true,
+			false,
+		},
+		{
+			"GAE version has priority over Knative-provided version",
+			Config{},
+			Config{Service: testGAEService, ServiceVersion: testGAEVersion, ProjectID: testGCEProjectID, Zone: testZone, Instance: testInstance},
+			"",
+			true,
+			true,
 			true,
 			false,
 		},
@@ -549,6 +596,7 @@
 			Config{Service: testService, ProjectID: testProjectID, Zone: testZone, Instance: testInstance},
 			"",
 			false,
+			false,
 			true,
 			false,
 		},
@@ -559,6 +607,7 @@
 			"",
 			false,
 			false,
+			false,
 			true,
 		},
 		{
@@ -569,6 +618,7 @@
 			false,
 			false,
 			false,
+			false,
 		},
 		{
 			"configured zone has priority over metadata-provided zone",
@@ -576,6 +626,7 @@
 			Config{Service: testService, ProjectID: testProjectID, Zone: testZone + "-override", Instance: testInstance},
 			"",
 			false,
+			false,
 			true,
 			false,
 		},
@@ -585,19 +636,30 @@
 			Config{Service: testService, ProjectID: testProjectID, Zone: testZone, Instance: testInstance + "-override"},
 			"",
 			false,
+			false,
 			true,
 			false,
 		},
 	} {
 		t.Logf("Running test: %s", tt.desc)
-		envService, envVersion := "", ""
+		gaeEnvService, gaeEnvVersion := "", ""
 		if tt.onGAE {
-			envService, envVersion = testGAEService, testGAEVersion
+			gaeEnvService, gaeEnvVersion = testGAEService, testGAEVersion
 		}
-		if err := os.Setenv("GAE_SERVICE", envService); err != nil {
+		if err := os.Setenv("GAE_SERVICE", gaeEnvService); err != nil {
 			t.Fatal(err)
 		}
-		if err := os.Setenv("GAE_VERSION", envVersion); err != nil {
+		if err := os.Setenv("GAE_VERSION", gaeEnvVersion); err != nil {
+			t.Fatal(err)
+		}
+		knEnvService, knEnvVersion := "", ""
+		if tt.onKnative {
+			knEnvService, knEnvVersion = testKnativeService, testKnativeVersion
+		}
+		if err := os.Setenv("K_SERVICE", knEnvService); err != nil {
+			t.Fatal(err)
+		}
+		if err := os.Setenv("K_REVISION", knEnvVersion); err != nil {
 			t.Fatal(err)
 		}
 		if tt.onGCE {