Repository: knative/serving
Pull request #8867 (2020-07-31 11:33:42)

Move queue metrics handler in to its own file and add tests
<!--
Request Prow to automatically lint any go code in this PR:

/lint
-->

Spun out of https://github.com/knative/serving/pull/8864. Might end up redundant if we drop the prometheus stat serving, but no harm having it extracted and tested in the mean-time.

/assign @vagababov @yanweiguo 


knative-prow-robot: [APPROVALNOTIFIER] This PR is **NOT APPROVED**

This pull-request has been approved by: *<a href="https://github.com/knative/serving/pull/8867#" title="Author self-approved">julz</a>*
To complete the [pull request process](https://git.k8s.io/community/contributors/guide/owners.md#the-code-review-process), please assign **jrbancel**
You can assign the PR to them by writing `/assign @jrbancel` in a comment when ready.

The full list of commands accepted by this bot can be found [here](https://go.k8s.io/bot-commands?repo=knative%2Fserving).

<details open>
Needs approval from an approver in each of these files:

- **[cmd/queue/OWNERS](https://github.com/knative/serving/blob/master/cmd/queue/OWNERS)**
- **[pkg/queue/OWNERS](https://github.com/knative/serving/blob/master/pkg/queue/OWNERS)**

Approvers can indicate their approval by writing `/approve` in a comment
Approvers can cancel approval by writing `/approve cancel` in a comment
</details>
<!-- META={"approvers":["jrbancel"]} -->
knative-metrics-robot: The following is the coverage report on the affected files.
Say `/test pull-knative-serving-go-coverage` to re-run this coverage report

File | Old Coverage | New Coverage | Delta
---- |:------------:|:------------:|:-----:
[pkg/queue/stats_handler.go](https://storage.cloud.google.com/knative-prow/pr-logs/pull/knative_serving/8867/pull-knative-serving-go-coverage/1289162450704273412/artifacts/line-cov.html#file0) | Do not exist | 100.0% | 


Patch:
diff --git a/cmd/queue/main.go b/cmd/queue/main.go
index d1b3485d9..8a5f20c80 100644
--- a/cmd/queue/main.go
+++ b/cmd/queue/main.go
@@ -26,7 +26,6 @@ import (
 	"net/url"
 	"os"
 	"strconv"
-	"strings"
 	"time"
 
 	"github.com/kelseyhightower/envconfig"
@@ -425,23 +424,13 @@ func buildAdminServer(healthState *health.State, logger *zap.SugaredLogger) *htt
 
 func buildMetricsServer(promStatReporter *queue.PrometheusStatsReporter, protobufStatReporter *queue.ProtobufStatsReporter) *http.Server {
 	metricsMux := http.NewServeMux()
-	metricsMux.Handle("/metrics", metricsHTTPHandler(promStatReporter, protobufStatReporter))
+	metricsMux.Handle("/metrics", queue.NewStatsHandler(promStatReporter, protobufStatReporter))
 	return &http.Server{
 		Addr:    ":" + strconv.Itoa(networking.AutoscalingQueueMetricsPort),
 		Handler: metricsMux,
 	}
 }
 
-func metricsHTTPHandler(promStatReporter *queue.PrometheusStatsReporter, protobufStatReporter *queue.ProtobufStatsReporter) http.Handler {
-	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
-		if strings.Contains(r.Header.Get("Accept"), network.ProtoAcceptContent) {
-			protobufStatReporter.ServeHTTP(w, r)
-		} else {
-			promStatReporter.ServeHTTP(w, r)
-		}
-	})
-}
-
 func pushRequestLogHandler(currentHandler http.Handler, env config) http.Handler {
 	if env.ServingRequestLogTemplate == "" {
 		return currentHandler
diff --git a/go.mod b/go.mod
index 782ea8a85..9cc71ce6d 100644
--- a/go.mod
+++ b/go.mod
@@ -37,10 +37,10 @@ require (
 	k8s.io/client-go v11.0.1-0.20190805182717-6502b5e7b1b5+incompatible
 	k8s.io/code-generator v0.18.0
 	k8s.io/kube-openapi v0.0.0-20200410145947-bcb3869e6f29
-	knative.dev/caching v0.0.0-20200729172100-446be8987215
-	knative.dev/networking v0.0.0-20200729171959-0bfbd4f8dd0c
-	knative.dev/pkg v0.0.0-20200729214559-47e34f1f4ef1
-	knative.dev/test-infra v0.0.0-20200729161259-d21e6ed450cb
+	knative.dev/caching v0.0.0-20200730180101-d5ae48ced0e9
+	knative.dev/networking v0.0.0-20200730222100-e8df1ba775fa
+	knative.dev/pkg v0.0.0-20200731005101-694087017879
+	knative.dev/test-infra v0.0.0-20200730214800-52f8800d5692
 )
 
 replace (
diff --git a/go.sum b/go.sum
index 2ab7e1edb..3e641e3c9 100644
--- a/go.sum
+++ b/go.sum
@@ -36,7 +36,6 @@ cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2k
 cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw=
 cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA=
 cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU=
-cloud.google.com/go/pubsub v1.6.0/go.mod h1:I6DkrTv7tKIvDQTZt+6rAFo1446FEoVDJeLXTu4pCcE=
 cloud.google.com/go/pubsub v1.6.1/go.mod h1:kvW9rcn9OLEx6eTIzMBbWbpB8YsK3vu9jxgPolVz+p4=
 cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw=
 cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos=
@@ -1280,8 +1279,6 @@ golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7w
 golang.org/x/sys v0.0.0-20200610111108-226ff32320da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae h1:Ih9Yo4hSPImZOpfGuA4bR/ORKTAbhZo2AbWNRCnevdo=
 golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20200724161237-0e2f3a69832c h1:UIcGWL6/wpCfyGuJnRFJRurA+yj8RrW7Q6x2YMCXt6c=
-golang.org/x/sys v0.0.0-20200724161237-0e2f3a69832c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20200728102440-3e129f6d46b1 h1:sIky/MyNRSHTrdxfsiUSS4WIAMvInbeXljJz+jDjeYE=
 golang.org/x/sys v0.0.0-20200728102440-3e129f6d46b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/text v0.0.0-20160726164857-2910a502d2bf/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
@@ -1386,9 +1383,6 @@ golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roY
 golang.org/x/tools v0.0.0-20200626171337-aa94e735be7f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
 golang.org/x/tools v0.0.0-20200709181711-e327e1019dfe/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
 golang.org/x/tools v0.0.0-20200713011307-fd294ab11aed/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
-golang.org/x/tools v0.0.0-20200721223218-6123e77877b2/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
-golang.org/x/tools v0.0.0-20200724172932-b5fc9d354d99 h1:OHn441rq5CeM5r1xJ0OmY7lfdTvnedi6k+vQiI7G9b8=
-golang.org/x/tools v0.0.0-20200724172932-b5fc9d354d99/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
 golang.org/x/tools v0.0.0-20200725200936-102e7d357031/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
 golang.org/x/tools v0.0.0-20200727233628-55644ead90ce h1:HEwYEPqqa3/M0N2Q6IgtBaf2CaxvmRiVdAhX6LR7uE4=
 golang.org/x/tools v0.0.0-20200727233628-55644ead90ce/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
@@ -1478,10 +1472,6 @@ google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7Fc
 google.golang.org/genproto v0.0.0-20200626011028-ee7919e894b5/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
 google.golang.org/genproto v0.0.0-20200709005830-7a2ca40e9dc3/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
 google.golang.org/genproto v0.0.0-20200711021454-869866162049/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
-google.golang.org/genproto v0.0.0-20200722002428-88e341933a54 h1:ASrBgpl9XvkNTP0m39/j18mid7aoF21npu2ioIBxYnY=
-google.golang.org/genproto v0.0.0-20200722002428-88e341933a54/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
-google.golang.org/genproto v0.0.0-20200724131911-43cab4749ae7 h1:AWgNCmk2V5HZp9AiCDRBExX/b9I0Ey9F8STHDZlhCC4=
-google.golang.org/genproto v0.0.0-20200724131911-43cab4749ae7/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
 google.golang.org/genproto v0.0.0-20200726014623-da3ae01ef02d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
 google.golang.org/genproto v0.0.0-20200728010541-3dc8dca74b7b h1:FWkel6k8GbR7SbBY200Cz8tA58/KtMrfpVZwOOSjOvQ=
 google.golang.org/genproto v0.0.0-20200728010541-3dc8dca74b7b/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
@@ -1627,28 +1617,29 @@ k8s.io/legacy-cloud-providers v0.17.4/go.mod h1:FikRNoD64ECjkxO36gkDgJeiQWwyZTuB
 k8s.io/metrics v0.17.2/go.mod h1:3TkNHET4ROd+NfzNxkjoVfQ0Ob4iZnaHmSEA4vYpwLw=
 k8s.io/test-infra v0.0.0-20200514184223-ba32c8aae783/go.mod h1:bW6thaPZfL2hW7ecjx2WYwlP9KQLM47/xIJyttkVk5s=
 k8s.io/test-infra v0.0.0-20200617221206-ea73eaeab7ff/go.mod h1:L3+cRvwftUq8IW1TrHji5m3msnc4uck/7LsE/GR/aZk=
-k8s.io/test-infra v0.0.0-20200724210216-b2cdf8399d01/go.mod h1:4cRZlOy5Ka3Ym/orCmNWL2dsE39pN0xHFT0WFrZe2HQ=
 k8s.io/test-infra v0.0.0-20200728085909-4407d8aec1ee/go.mod h1:4cRZlOy5Ka3Ym/orCmNWL2dsE39pN0xHFT0WFrZe2HQ=
 k8s.io/utils v0.0.0-20191114184206-e782cd3c129f/go.mod h1:sZAwmy6armz5eXlNoLmJcl4F1QuKu7sr+mFQ0byX7Ew=
 k8s.io/utils v0.0.0-20200124190032-861946025e34 h1:HjlUD6M0K3P8nRXmr2B9o4F9dUy9TCj/aEpReeyi6+k=
 k8s.io/utils v0.0.0-20200124190032-861946025e34/go.mod h1:sZAwmy6armz5eXlNoLmJcl4F1QuKu7sr+mFQ0byX7Ew=
 knative.dev/caching v0.0.0-20200116200605-67bca2c83dfa/go.mod h1:dHXFU6CGlLlbzaWc32g80cR92iuBSpsslDNBWI8C7eg=
-knative.dev/caching v0.0.0-20200729172100-446be8987215 h1:nWSFAThxVAjhhYop7RR7P3JMBeSs4yKfuQs9NTdRoA8=
-knative.dev/caching v0.0.0-20200729172100-446be8987215/go.mod h1:O7VTyFBU64Y5IHznB9TDlf/Bhi6I+IL8DUT/nxbbm3w=
+knative.dev/caching v0.0.0-20200730180101-d5ae48ced0e9 h1:xqKWApOEmGRRQbKbhSlXhJ7iAhGhvqBMt0HWsuP4aL4=
+knative.dev/caching v0.0.0-20200730180101-d5ae48ced0e9/go.mod h1:j7MIQ8ZGYb97GNjA2DE16E00M1Zk6kXj0G87wkhzK3U=
 knative.dev/eventing-contrib v0.11.2/go.mod h1:SnXZgSGgMSMLNFTwTnpaOH7hXDzTFtw0J8OmHflNx3g=
-knative.dev/networking v0.0.0-20200729171959-0bfbd4f8dd0c h1:xl5NlgWmOwD2mtqaB9l/gcfUG/+Ztn55uHANtxUvun0=
-knative.dev/networking v0.0.0-20200729171959-0bfbd4f8dd0c/go.mod h1:P2v0oLSj3dfiq5jyPnfatF0Vd2VVYXuUxHonftdFCyw=
+knative.dev/networking v0.0.0-20200730222100-e8df1ba775fa h1:JwtuMr+3IFExyOdsdJeO0A/TfUaWELBChWLKCcs2K8Q=
+knative.dev/networking v0.0.0-20200730222100-e8df1ba775fa/go.mod h1:gdavzaLxZjjZOYg6NNe+ERqQONNQqw1DlYDM4CA6fJM=
 knative.dev/pkg v0.0.0-20200207155214-fef852970f43/go.mod h1:pgODObA1dTyhNoFxPZTTjNWfx6F0aKsKzn+vaT9XO/Q=
-knative.dev/pkg v0.0.0-20200729100859-68b3eeeaab46 h1:tRLgDNTfz90qg99llBjfN2EPbzwHkYfSPJvpBQxSKvA=
-knative.dev/pkg v0.0.0-20200729100859-68b3eeeaab46/go.mod h1:ur42MwFkZfPfqZPt987/rkdkaUhWfuuO7+jKbEUE+uk=
 knative.dev/pkg v0.0.0-20200729214559-47e34f1f4ef1 h1:RSIVAug90vyIfJzYqOJSyzYCb+mTSIyHD7Rn3UvLDmM=
 knative.dev/pkg v0.0.0-20200729214559-47e34f1f4ef1/go.mod h1:Anw0Jhhgt/6YoUxiIANo5a4MtsraFCdRY9UMeOKjsY0=
-knative.dev/test-infra v0.0.0-20200725213358-8557dab80d7a h1:Coxwj+5PN0WCrRh2Dxf33Nu2QteF4hcy55qw+AJKMSw=
-knative.dev/test-infra v0.0.0-20200725213358-8557dab80d7a/go.mod h1:Besm7oWHKZcLfn5lmBw/JCmQrOMCKUuM3tSKi6insQ4=
+knative.dev/pkg v0.0.0-20200730180200-bd4b7612364d/go.mod h1:XgwbBKFaZgeMYBf1LRc5WtHDbCnOv6j+36/W9XFxs7Y=
+knative.dev/pkg v0.0.0-20200731005101-694087017879 h1:54ACbR/yTJvP1mCZUgk/u2KodPpOCpMa1RMP3g+QDNI=
+knative.dev/pkg v0.0.0-20200731005101-694087017879/go.mod h1:XgwbBKFaZgeMYBf1LRc5WtHDbCnOv6j+36/W9XFxs7Y=
 knative.dev/test-infra v0.0.0-20200729023559-d33097928a54 h1:wuYWc/LMyEKE0grD7HMdMWcM1b1VqlEB2GtR7J4nVAQ=
 knative.dev/test-infra v0.0.0-20200729023559-d33097928a54/go.mod h1:AfEfWe/Z/DIA2vQSbSTxMVlF+ErBD7Oqc4/K/x1no90=
 knative.dev/test-infra v0.0.0-20200729161259-d21e6ed450cb h1:fwkMDaKklHbKrZpMvjIHrLfk8AXAhiiB1VNEpXrBFZI=
 knative.dev/test-infra v0.0.0-20200729161259-d21e6ed450cb/go.mod h1:AfEfWe/Z/DIA2vQSbSTxMVlF+ErBD7Oqc4/K/x1no90=
+knative.dev/test-infra v0.0.0-20200730141100-d0f7784f5bda/go.mod h1:AfEfWe/Z/DIA2vQSbSTxMVlF+ErBD7Oqc4/K/x1no90=
+knative.dev/test-infra v0.0.0-20200730214800-52f8800d5692 h1:ftbIX0MQwnUNFVsP/eM4ulpSX40Z4zj0VPWr+/jh51A=
+knative.dev/test-infra v0.0.0-20200730214800-52f8800d5692/go.mod h1:AfEfWe/Z/DIA2vQSbSTxMVlF+ErBD7Oqc4/K/x1no90=
 modernc.org/cc v1.0.0/go.mod h1:1Sk4//wdnYJiUIxnW8ddKpaOJCF37yAdqYnkxUpaYxw=
 modernc.org/golex v1.0.0/go.mod h1:b/QX9oBD/LhixY6NDh+IdGv17hgB+51fET1i2kPSmvk=
 modernc.org/mathutil v1.0.0/go.mod h1:wU0vUrJsVWBZ4P6e7xtFJEhFSNsfRLJ8H458uRjg03k=
diff --git a/pkg/queue/stats_handler.go b/pkg/queue/stats_handler.go
new file mode 100644
index 000000000..4794f5311
--- /dev/null
+++ b/pkg/queue/stats_handler.go
@@ -0,0 +1,47 @@
+/*
+Copyright 2020 The Knative Authors
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package queue
+
+import (
+	"net/http"
+	"strings"
+
+	"knative.dev/serving/pkg/network"
+)
+
+type statsHandler struct {
+	prom  http.Handler
+	proto http.Handler
+}
+
+// NewStatsHandler returns a new StatHandler.
+func NewStatsHandler(prom, proto http.Handler) http.Handler {
+	return &statsHandler{
+		prom:  prom,
+		proto: proto,
+	}
+}
+
+// ServeHTTP serves the stats over HTTP. Either protobuf or prometheus stats
+// are served, depending on the Accept header.
+func (reporter *statsHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
+	if strings.Contains(r.Header.Get("Accept"), network.ProtoAcceptContent) {
+		reporter.proto.ServeHTTP(w, r)
+	} else {
+		reporter.prom.ServeHTTP(w, r)
+	}
+}
diff --git a/pkg/reconciler/revision/controller.go b/pkg/reconciler/revision/controller.go
index d55405185..3e80bd94f 100644
--- a/pkg/reconciler/revision/controller.go
+++ b/pkg/reconciler/revision/controller.go
@@ -24,8 +24,6 @@ import (
 	imageinformer "knative.dev/caching/pkg/client/injection/informers/caching/v1alpha1/image"
 	kubeclient "knative.dev/pkg/client/injection/kube/client"
 	deploymentinformer "knative.dev/pkg/client/injection/kube/informers/apps/v1/deployment"
-	configmapinformer "knative.dev/pkg/client/injection/kube/informers/core/v1/configmap"
-	serviceinformer "knative.dev/pkg/client/injection/kube/informers/core/v1/service"
 	servingclient "knative.dev/serving/pkg/client/injection/client"
 	painformer "knative.dev/serving/pkg/client/injection/informers/autoscaling/v1alpha1/podautoscaler"
 	revisioninformer "knative.dev/serving/pkg/client/injection/informers/serving/v1/revision"
@@ -71,11 +69,9 @@ func newControllerWithOptions(
 
 	ctx = servingreconciler.AnnotateLoggerWithName(ctx, controllerAgentName)
 	logger := logging.FromContext(ctx)
+	revisionInformer := revisioninformer.Get(ctx)
 	deploymentInformer := deploymentinformer.Get(ctx)
-	serviceInformer := serviceinformer.Get(ctx)
-	configMapInformer := configmapinformer.Get(ctx)
 	imageInformer := imageinformer.Get(ctx)
-	revisionInformer := revisioninformer.Get(ctx)
 	paInformer := painformer.Get(ctx)
 
 	c := &Reconciler{
@@ -86,7 +82,6 @@ func newControllerWithOptions(
 		podAutoscalerLister: paInformer.Lister(),
 		imageLister:         imageInformer.Lister(),
 		deploymentLister:    deploymentInformer.Lister(),
-		serviceLister:       serviceInformer.Lister(),
 		resolver: &digestResolver{
 			client:    kubeclient.Get(ctx),
 			transport: transport,
@@ -121,7 +116,6 @@ func newControllerWithOptions(
 	}
 	deploymentInformer.Informer().AddEventHandler(handleMatchingControllers)
 	paInformer.Informer().AddEventHandler(handleMatchingControllers)
-	configMapInformer.Informer().AddEventHandler(handleMatchingControllers)
 
 	// We don't watch for changes to Image because we don't incorporate any of its
 	// properties into our own status and should work completely in the absence of
diff --git a/pkg/reconciler/revision/revision.go b/pkg/reconciler/revision/revision.go
index 5645d28a4..16f882395 100644
--- a/pkg/reconciler/revision/revision.go
+++ b/pkg/reconciler/revision/revision.go
@@ -30,7 +30,6 @@ import (
 	"k8s.io/apimachinery/pkg/util/sets"
 	"k8s.io/client-go/kubernetes"
 	appsv1listers "k8s.io/client-go/listers/apps/v1"
-	corev1listers "k8s.io/client-go/listers/core/v1"
 	cachingclientset "knative.dev/caching/pkg/client/clientset/versioned"
 	clientset "knative.dev/serving/pkg/client/clientset/versioned"
 	revisionreconciler "knative.dev/serving/pkg/client/injection/reconciler/serving/v1/revision"
@@ -60,7 +59,6 @@ type Reconciler struct {
 	podAutoscalerLister palisters.PodAutoscalerLister
 	imageLister         cachinglisters.ImageLister
 	deploymentLister    appsv1listers.DeploymentLister
-	serviceLister       corev1listers.ServiceLister
 
 	resolver resolver
 }
diff --git a/third_party/VENDOR-LICENSE/k8s.io/kube-openapi/pkg/util/proto/LICENSE b/third_party/VENDOR-LICENSE/k8s.io/kube-openapi/pkg/util/LICENSE
similarity index 100%
rename from third_party/VENDOR-LICENSE/k8s.io/kube-openapi/pkg/util/proto/LICENSE
rename to third_party/VENDOR-LICENSE/k8s.io/kube-openapi/pkg/util/LICENSE
diff --git a/vendor/knative.dev/networking/pkg/client/injection/reconciler/networking/v1alpha1/serverlessservice/reconciler.go b/vendor/knative.dev/networking/pkg/client/injection/reconciler/networking/v1alpha1/serverlessservice/reconciler.go
index e964dc02e..005f4a040 100644
--- a/vendor/knative.dev/networking/pkg/client/injection/reconciler/networking/v1alpha1/serverlessservice/reconciler.go
+++ b/vendor/knative.dev/networking/pkg/client/injection/reconciler/networking/v1alpha1/serverlessservice/reconciler.go
@@ -85,13 +85,6 @@ type ReadOnlyFinalizer interface {
 
 type doReconcile func(ctx context.Context, o *v1alpha1.ServerlessService) reconciler.Event
 
-const (
-	doReconcileKind       = "ReconcileKind"
-	doFinalizeKind        = "FinalizeKind"
-	doObserveKind         = "ObserveKind"
-	doObserveFinalizeKind = "ObserveFinalizeKind"
-)
-
 // reconcilerImpl implements controller.Reconciler for v1alpha1.ServerlessService resources.
 type reconcilerImpl struct {
 	// LeaderAwareFuncs is inlined to help us implement reconciler.LeaderAware
@@ -231,7 +224,7 @@ func (r *reconcilerImpl) Reconcile(ctx context.Context, key string) error {
 	// Append the target method to the logger.
 	logger = logger.With(zap.String("targetMethod", name))
 	switch name {
-	case doReconcileKind:
+	case reconciler.DoReconcileKind:
 		// Append the target method to the logger.
 		logger = logger.With(zap.String("targetMethod", "ReconcileKind"))
 
@@ -249,7 +242,7 @@ func (r *reconcilerImpl) Reconcile(ctx context.Context, key string) error {
 
 		reconciler.PostProcessReconcile(ctx, resource, original)
 
-	case "FinalizeKind":
+	case reconciler.DoFinalizeKind:
 		// For finalizing reconcilers, if this resource being marked for deletion
 		// and reconciled cleanly (nil or normal event), remove the finalizer.
 		reconcileEvent = do(ctx, resource)
@@ -258,7 +251,7 @@ func (r *reconcilerImpl) Reconcile(ctx context.Context, key string) error {
 			return fmt.Errorf("failed to clear finalizers: %w", err)
 		}
 
-	case "ObserveKind", "ObserveFinalizeKind":
+	case reconciler.DoObserveKind, reconciler.DoObserveFinalizeKind:
 		// Observe any changes to this resource, since we are not the leader.
 		reconcileEvent = do(ctx, resource)
 
diff --git a/vendor/knative.dev/networking/pkg/client/injection/reconciler/networking/v1alpha1/serverlessservice/state.go b/vendor/knative.dev/networking/pkg/client/injection/reconciler/networking/v1alpha1/serverlessservice/state.go
index 2675b8e07..ac5d13f5f 100644
--- a/vendor/knative.dev/networking/pkg/client/injection/reconciler/networking/v1alpha1/serverlessservice/state.go
+++ b/vendor/knative.dev/networking/pkg/client/injection/reconciler/networking/v1alpha1/serverlessservice/state.go
@@ -24,6 +24,7 @@ import (
 	types "k8s.io/apimachinery/pkg/types"
 	cache "k8s.io/client-go/tools/cache"
 	v1alpha1 "knative.dev/networking/pkg/apis/networking/v1alpha1"
+	reconciler "knative.dev/pkg/reconciler"
 )
 
 // state is used to track the state of a reconciler in a single run.
@@ -92,14 +93,14 @@ func (s *state) isNotLeaderNorObserver() bool {
 func (s *state) reconcileMethodFor(o *v1alpha1.ServerlessService) (string, doReconcile) {
 	if o.GetDeletionTimestamp().IsZero() {
 		if s.isLeader {
-			return doReconcileKind, s.reconciler.ReconcileKind
+			return reconciler.DoReconcileKind, s.reconciler.ReconcileKind
 		} else if s.isROI {
-			return doObserveKind, s.roi.ObserveKind
+			return reconciler.DoObserveKind, s.roi.ObserveKind
 		}
 	} else if fin, ok := s.reconciler.(Finalizer); s.isLeader && ok {
-		return doFinalizeKind, fin.FinalizeKind
+		return reconciler.DoFinalizeKind, fin.FinalizeKind
 	} else if !s.isLeader && s.isROF {
-		return doObserveFinalizeKind, s.rof.ObserveFinalizeKind
+		return reconciler.DoObserveFinalizeKind, s.rof.ObserveFinalizeKind
 	}
 	return "unknown", nil
 }
diff --git a/vendor/knative.dev/pkg/apis/volatile_time.go b/vendor/knative.dev/pkg/apis/volatile_time.go
index d735ada99..b114294bf 100644
--- a/vendor/knative.dev/pkg/apis/volatile_time.go
+++ b/vendor/knative.dev/pkg/apis/volatile_time.go
@@ -29,7 +29,7 @@ import (
 // Note, go-cmp will still return inequality, see unit test if you
 // need this behavior for go-cmp.
 type VolatileTime struct {
-	Inner metav1.Time
+	Inner metav1.Time `json:",inline"`
 }
 
 // MarshalJSON implements the json.Marshaler interface.
diff --git a/vendor/modules.txt b/vendor/modules.txt
index 5f7d6c593..499ffb045 100644
--- a/vendor/modules.txt
+++ b/vendor/modules.txt
@@ -1003,7 +1003,7 @@ k8s.io/utils/buffer
 k8s.io/utils/integer
 k8s.io/utils/pointer
 k8s.io/utils/trace
-# knative.dev/caching v0.0.0-20200729172100-446be8987215
+# knative.dev/caching v0.0.0-20200730180101-d5ae48ced0e9
 ## explicit
 knative.dev/caching/config
 knative.dev/caching/pkg/apis/caching
@@ -1024,7 +1024,7 @@ knative.dev/caching/pkg/client/injection/informers/caching/v1alpha1/image/fake
 knative.dev/caching/pkg/client/injection/informers/factory
 knative.dev/caching/pkg/client/injection/informers/factory/fake
 knative.dev/caching/pkg/client/listers/caching/v1alpha1
-# knative.dev/networking v0.0.0-20200729171959-0bfbd4f8dd0c
+# knative.dev/networking v0.0.0-20200730222100-e8df1ba775fa
 ## explicit
 knative.dev/networking/pkg/apis/config
 knative.dev/networking/pkg/apis/networking
@@ -1051,7 +1051,7 @@ knative.dev/networking/pkg/client/injection/informers/networking/v1alpha1/server
 knative.dev/networking/pkg/client/injection/reconciler/networking/v1alpha1/serverlessservice
 knative.dev/networking/pkg/client/istio/listers/networking/v1alpha3
 knative.dev/networking/pkg/client/listers/networking/v1alpha1
-# knative.dev/pkg v0.0.0-20200729214559-47e34f1f4ef1
+# knative.dev/pkg v0.0.0-20200731005101-694087017879
 ## explicit
 knative.dev/pkg/apiextensions/storageversion
 knative.dev/pkg/apiextensions/storageversion/cmd/migrate
@@ -1175,7 +1175,7 @@ knative.dev/pkg/webhook/resourcesemantics/conversion
 knative.dev/pkg/webhook/resourcesemantics/defaulting
 knative.dev/pkg/webhook/resourcesemantics/validation
 knative.dev/pkg/websocket
-# knative.dev/test-infra v0.0.0-20200729161259-d21e6ed450cb
+# knative.dev/test-infra v0.0.0-20200730214800-52f8800d5692
 ## explicit
 knative.dev/test-infra/scripts
 # sigs.k8s.io/yaml v1.2.0


Test patch:
diff --git a/pkg/queue/stats_handler_test.go b/pkg/queue/stats_handler_test.go
new file mode 100644
index 000000000..843b5e3c7
--- /dev/null
+++ b/pkg/queue/stats_handler_test.go
@@ -0,0 +1,84 @@
+/*
+Copyright 2020 The Knative Authors
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package queue
+
+import (
+	"net/http"
+	"net/http/httptest"
+	"testing"
+
+	"knative.dev/serving/pkg/network"
+)
+
+func TestStatsHandler(t *testing.T) {
+	prom := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+		w.Header().Set("served-by", "prometheus")
+	})
+
+	proto := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+		w.Header().Set("served-by", "protobuf")
+	})
+
+	reporter := NewStatsHandler(prom, proto)
+
+	tests := []struct {
+		name    string
+		headers http.Header
+		expect  string
+	}{{
+		name:   "no headers",
+		expect: "prometheus",
+	}, {
+		name: "some other accept header",
+		headers: http.Header{
+			"Accept": []string{"something-else"},
+		},
+		expect: "prometheus",
+	}, {
+		name: "protobuf in second Accept header still serves prometheus",
+		headers: http.Header{
+			"Accept": []string{"", network.ProtoAcceptContent},
+		},
+		expect: "prometheus",
+	}, {
+		name: "protobuf accept header",
+		headers: http.Header{
+			"Accept": []string{network.ProtoAcceptContent},
+		},
+		expect: "protobuf",
+	}, {
+		name: "protobuf accept header as part of CSV",
+		headers: http.Header{
+			"Accept": []string{"something/else, application/protobuf"},
+		},
+		expect: "protobuf",
+	}}
+
+	for _, test := range tests {
+		t.Run(test.name, func(t *testing.T) {
+			r := httptest.NewRequest(http.MethodGet, "/metrics", nil)
+			r.Header = test.headers
+
+			w := httptest.NewRecorder()
+			reporter.ServeHTTP(w, r)
+
+			if got, want := w.Header().Get("served-by"), test.expect; got != want {
+				t.Errorf("Expected to be served %s but was served %s", want, got)
+			}
+		})
+	}
+}
diff --git a/pkg/reconciler/revision/table_test.go b/pkg/reconciler/revision/table_test.go
index 98220a9a2..522f4a843 100644
--- a/pkg/reconciler/revision/table_test.go
+++ b/pkg/reconciler/revision/table_test.go
@@ -597,7 +597,6 @@ func TestReconcile(t *testing.T) {
 			podAutoscalerLister: listers.GetPodAutoscalerLister(),
 			imageLister:         listers.GetImageLister(),
 			deploymentLister:    listers.GetDeploymentLister(),
-			serviceLister:       listers.GetK8sServiceLister(),
 			resolver:            &nopResolver{},
 		}
 
diff --git a/vendor/knative.dev/pkg/reconciler/testing/table.go b/vendor/knative.dev/pkg/reconciler/testing/table.go
index 6059fefec..193861596 100644
--- a/vendor/knative.dev/pkg/reconciler/testing/table.go
+++ b/vendor/knative.dev/pkg/reconciler/testing/table.go
@@ -102,6 +102,15 @@ type TableRow struct {
 	CmpOpts []cmp.Option
 }
 
+var (
+	ignoreLastTransitionTime = cmp.FilterPath(func(p cmp.Path) bool {
+		return strings.HasSuffix(p.String(), "LastTransitionTime.Inner.Time")
+	}, cmp.Ignore())
+
+	ignoreQuantity = cmpopts.IgnoreUnexported(resource.Quantity{})
+	defaultCmpOpts = []cmp.Option{ignoreLastTransitionTime, ignoreQuantity, cmpopts.EquateEmpty()}
+)
+
 func objKey(o runtime.Object) string {
 	on := o.(kmeta.Accessor)
 
@@ -158,6 +167,7 @@ func (r *TableRow) Test(t *testing.T, factory Factory) {
 		t.Errorf("Error capturing actions by verb: %q", err)
 	}
 
+	effectiveOpts := append(r.CmpOpts, defaultCmpOpts...)
 	// Previous state is used to diff resource expected state for update requests that were missed.
 	objPrevState := make(map[string]runtime.Object, len(r.Objects))
 	for _, o := range r.Objects {
@@ -177,8 +187,9 @@ func (r *TableRow) Test(t *testing.T, factory Factory) {
 			t.Errorf("Unexpected action[%d]: %#v", i, got)
 		}
 
-		if diff := cmp.Diff(want, obj, append(r.CmpOpts, ignoreLastTransitionTime, safeDeployDiff, cmpopts.EquateEmpty())...); diff != "" {
-			t.Errorf("Unexpected create (-want, +got): %s", diff)
+		if !cmp.Equal(want, obj, effectiveOpts...) {
+			t.Errorf("Unexpected create (-want, +got):\n%s",
+				cmp.Diff(want, obj, effectiveOpts...))
 		}
 	}
 	if got, want := len(actions.Creates), len(r.WantCreates); got > want {
@@ -197,8 +208,8 @@ func (r *TableRow) Test(t *testing.T, factory Factory) {
 				t.Errorf("Object %s was never created: want: %#v", key, wo)
 				continue
 			}
-			t.Errorf("Missing update for %s (-want, +prevState): %s", key,
-				cmp.Diff(wo, oldObj, append(r.CmpOpts, ignoreLastTransitionTime, safeDeployDiff, cmpopts.EquateEmpty())...))
+			t.Errorf("Missing update for %s (-want, +prevState):\n%s", key,
+				cmp.Diff(wo, oldObj, effectiveOpts...))
 			continue
 		}
 
@@ -211,8 +222,9 @@ func (r *TableRow) Test(t *testing.T, factory Factory) {
 		// Update the object state.
 		objPrevState[objKey(got)] = got
 
-		if diff := cmp.Diff(want.GetObject(), got, append(r.CmpOpts, ignoreLastTransitionTime, safeDeployDiff, cmpopts.EquateEmpty())...); diff != "" {
-			t.Errorf("Unexpected update (-want, +got): %s", diff)
+		if !cmp.Equal(want.GetObject(), got, effectiveOpts...) {
+			t.Errorf("Unexpected update (-want, +got):\n%s",
+				cmp.Diff(want.GetObject(), got, effectiveOpts...))
 		}
 	}
 	if got, want := len(updates), len(r.WantUpdates); got > want {
@@ -232,8 +244,8 @@ func (r *TableRow) Test(t *testing.T, factory Factory) {
 				t.Errorf("Object %s was never created: want: %#v", key, wo)
 				continue
 			}
-			t.Errorf("Missing status update for %s (-want, +prevState): %s", key,
-				cmp.Diff(wo, oldObj, append(r.CmpOpts, ignoreLastTransitionTime, safeDeployDiff, cmpopts.EquateEmpty())...))
+			t.Errorf("Missing status update for %s (-want, +prevState):\n%s", key,
+				cmp.Diff(wo, oldObj, effectiveOpts...))
 			continue
 		}
 
@@ -242,8 +254,9 @@ func (r *TableRow) Test(t *testing.T, factory Factory) {
 		// Update the object state.
 		objPrevState[objKey(got)] = got
 
-		if diff := cmp.Diff(want.GetObject(), got, append(r.CmpOpts, ignoreLastTransitionTime, safeDeployDiff, cmpopts.EquateEmpty())...); diff != "" {
-			t.Errorf("Unexpected status update (-want, +got): %s\nFull: %v", diff, got)
+		if !cmp.Equal(want.GetObject(), got, effectiveOpts...) {
+			t.Errorf("Unexpected status update (-want, +got):\n%s\nFull: %v",
+				cmp.Diff(want.GetObject(), got, effectiveOpts...), got)
 		}
 	}
 	if got, want := len(statusUpdates), len(r.WantStatusUpdates); got > want {
@@ -255,8 +268,8 @@ func (r *TableRow) Test(t *testing.T, factory Factory) {
 				t.Errorf("Object %s was never created: want: %#v", key, wo)
 				continue
 			}
-			t.Errorf("Extra status update for %s (-extra, +prevState): %s", key,
-				cmp.Diff(wo, oldObj, append(r.CmpOpts, ignoreLastTransitionTime, safeDeployDiff, cmpopts.EquateEmpty())...))
+			t.Errorf("Extra status update for %s (-extra, +prevState):\n%s", key,
+				cmp.Diff(wo, oldObj, effectiveOpts...))
 		}
 	}
 
@@ -328,8 +341,8 @@ func (r *TableRow) Test(t *testing.T, factory Factory) {
 				got.GetName() != expectedNamespace) {
 			t.Errorf("Unexpected patch[%d]: %#v", i, got)
 		}
-		if diff := cmp.Diff(string(want.GetPatch()), string(got.GetPatch())); diff != "" {
-			t.Errorf("Unexpected patch(-want, +got): %s", diff)
+		if got, want := string(got.GetPatch()), string(want.GetPatch()); got != want {
+			t.Errorf("Unexpected patch(-want, +got):\n%s", cmp.Diff(want, got))
 		}
 	}
 	if got, want := len(actions.Patches), len(r.WantPatches); got > want {
@@ -341,17 +354,17 @@ func (r *TableRow) Test(t *testing.T, factory Factory) {
 	gotEvents := eventList.Events()
 	for i, want := range r.WantEvents {
 		if i >= len(gotEvents) {
-			t.Errorf("Missing event: %s", want)
+			t.Error("Missing event:", want)
 			continue
 		}
 
-		if diff := cmp.Diff(want, gotEvents[i]); diff != "" {
-			t.Errorf("unexpected event(-want, +got): %s", diff)
+		if !cmp.Equal(want, gotEvents[i]) {
+			t.Errorf("Unexpected event(-want, +got):\n%s", cmp.Diff(want, gotEvents[i]))
 		}
 	}
 	if got, want := len(gotEvents), len(r.WantEvents); got > want {
 		for _, extra := range gotEvents[want:] {
-			t.Errorf("Extra event: %s", extra)
+			t.Error("Extra event:", extra)
 		}
 	}
 
@@ -379,25 +392,18 @@ func (tt TableTest) Test(t *testing.T, factory Factory) {
 	t.Helper()
 	for _, test := range tt {
 		// Record the original objects in table.
-		originObjects := make([]runtime.Object, 0, len(test.Objects))
-		for _, obj := range test.Objects {
-			originObjects = append(originObjects, obj.DeepCopyObject())
+		originObjects := make([]runtime.Object, len(test.Objects))
+		for i, obj := range test.Objects {
+			originObjects[i] = obj.DeepCopyObject()
 		}
 		t.Run(test.Name, func(t *testing.T) {
 			t.Helper()
 			test.Test(t, factory)
+			// Validate cached objects do not get soiled after controller loops.
+			if !cmp.Equal(originObjects, test.Objects, defaultCmpOpts...) {
+				t.Errorf("Unexpected objects (-want, +got):\n%s",
+					cmp.Diff(originObjects, test.Objects, defaultCmpOpts...))
+			}
 		})
-		// Validate cached objects do not get soiled after controller loops
-		if diff := cmp.Diff(originObjects, test.Objects, safeDeployDiff, cmpopts.EquateEmpty()); diff != "" {
-			t.Errorf("Unexpected objects in test %s (-want, +got): %v", test.Name, diff)
-		}
 	}
 }
-
-var (
-	ignoreLastTransitionTime = cmp.FilterPath(func(p cmp.Path) bool {
-		return strings.HasSuffix(p.String(), "LastTransitionTime.Inner.Time")
-	}, cmp.Ignore())
-
-	safeDeployDiff = cmpopts.IgnoreUnexported(resource.Quantity{})
-)