diff --git a/pkg/reconciler/revision/resources/deploy_test.go b/pkg/reconciler/revision/resources/deploy_test.go index 64f6f8f62bd5..9479708fa054 100644 --- a/pkg/reconciler/revision/resources/deploy_test.go +++ b/pkg/reconciler/revision/resources/deploy_test.go @@ -612,7 +612,7 @@ func TestMakePodSpec(t *testing.T) { withExecReadinessProbe([]string{"echo", "hello"})), queueContainer( withEnvVar("CONTAINER_CONCURRENCY", "0"), - withEnvVar("SERVING_READINESS_PROBE", "{}"), + withEnvVar("SERVING_READINESS_PROBE", `{"tcpSocket":{"port":8080,"host":"127.0.0.1"}}`), ), }), }, { diff --git a/pkg/reconciler/revision/resources/queue.go b/pkg/reconciler/revision/resources/queue.go index 028f781fe03b..8e1df78374cc 100644 --- a/pkg/reconciler/revision/resources/queue.go +++ b/pkg/reconciler/revision/resources/queue.go @@ -356,7 +356,12 @@ func applyReadinessProbeDefaults(p *corev1.Probe, port int32) { p.TCPSocket.Host = localAddress p.TCPSocket.Port = intstr.FromInt(int(port)) case p.Exec != nil: - //User-defined ExecProbe will still be run on user-container. + // User-defined ExecProbe will still be run on user-container. + // Use TCP probe in queue-proxy. + p.TCPSocket = &corev1.TCPSocketAction{ + Host: localAddress, + Port: intstr.FromInt(int(port)), + } p.Exec = nil } diff --git a/test/conformance/runtime/readiness_probe_test.go b/test/conformance/runtime/readiness_probe_test.go index 2daffb5ae309..a2bf1246f44a 100644 --- a/test/conformance/runtime/readiness_probe_test.go +++ b/test/conformance/runtime/readiness_probe_test.go @@ -31,37 +31,65 @@ import ( ) func TestProbeRuntime(t *testing.T) { - t.Parallel() cancel := logstream.Start(t) defer cancel() clients := test.Setup(t) - names := test.ResourceNames{ - Service: test.ObjectNameForTest(t), - Image: "runtime", - } + var testCases = []struct { + // name of the test case, which will be inserted in names of routes, configurations, etc. + // Use a short name here to avoid hitting the 63-character limit in names + // (e.g., "service-to-service-call-svc-cluster-local-uagkdshh-frkml-service" is too long.) + name string + // handler to be used for readiness probe in user container. + handler corev1.Handler + }{{ + "httpGet", + corev1.Handler{ + HTTPGet: &corev1.HTTPGetAction{ + Path: "/healthz", + }, + }, + }, { + "tcpSocket", + corev1.Handler{ + TCPSocket: &corev1.TCPSocketAction{}, + }, + }, { + "exec", + corev1.Handler{ + Exec: &corev1.ExecAction{ + Command: []string{"/ko-app/runtime", "probe"}, + }, + }, + }} - test.CleanupOnInterrupt(func() { test.TearDown(clients, names) }) - defer test.TearDown(clients, names) + for _, tc := range testCases { + tc := tc + t.Run(tc.name, func(t *testing.T) { + t.Parallel() + names := test.ResourceNames{ + Service: test.ObjectNameForTest(t), + Image: test.Runtime, + } - t.Log("Creating a new Service") - resources, _, err := v1a1test.CreateRunLatestServiceReady(t, clients, &names, - false, /* https TODO(taragu) turn this on after helloworld test running with https */ - v1a1opts.WithReadinessProbe( - &corev1.Probe{ - Handler: corev1.Handler{ - HTTPGet: &corev1.HTTPGetAction{ - Path: "/healthz", - }, - }, - })) - if err != nil { - t.Fatalf("Failed to create initial Service: %v: %v", names.Service, err) - } + test.CleanupOnInterrupt(func() { test.TearDown(clients, names) }) + defer test.TearDown(clients, names) - // Check if scaling down works even if access from liveness probe exists. - if err := e2e.WaitForScaleToZero(t, revisionresourcenames.Deployment(resources.Revision), clients); err != nil { - t.Fatalf("Could not scale to zero: %v", err) + t.Log("Creating a new Service") + resources, _, err := v1a1test.CreateRunLatestServiceReady(t, clients, &names, + false, /* https TODO(taragu) turn this on after helloworld test running with https */ + v1a1opts.WithReadinessProbe( + &corev1.Probe{ + Handler: tc.handler, + })) + if err != nil { + t.Fatalf("Failed to create initial Service: %v: %v", names.Service, err) + } + // Check if scaling down works even if access from liveness probe exists. + if err := e2e.WaitForScaleToZero(t, revisionresourcenames.Deployment(resources.Revision), clients); err != nil { + t.Fatalf("Could not scale to zero: %v", err) + } + }) } } diff --git a/test/test_images/runtime/main.go b/test/test_images/runtime/main.go index 36387fdbb1cd..d231e82a737d 100644 --- a/test/test_images/runtime/main.go +++ b/test/test_images/runtime/main.go @@ -14,6 +14,7 @@ limitations under the License. package main import ( + "flag" "log" "net/http" "os" @@ -23,7 +24,6 @@ import ( ) func main() { - // We expect PORT to be defined in a Knative environment // and don't want to mask this failure in a test image. port, isSet := os.LookupEnv("PORT") @@ -31,6 +31,17 @@ func main() { log.Fatal("Environment variable PORT is not set.") } + // This is an option for exec readiness probe test. + flag.Parse() + args := flag.Args() + if len(args) > 0 && args[0] == "probe" { + url := "http://localhost:" + port + if _, err := http.Get(url); err != nil { + log.Fatalf("Failed to probe %v", err) + } + return + } + mux := http.NewServeMux() handlers.InitHandlers(mux)