Repository: knative/serving
Pull request #8611 (2020-07-13 14:14:26)

[master] Auto-update dependencies
<!--[master] Auto-update dependencies-->
<!---->
Produced via:
  `./hack/update-deps.sh --upgrade && ./hack/update-codegen.sh`
/assign dprotaso vagababov
/cc dprotaso vagababov


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

This pull-request has been approved by: *<a href="https://github.com/knative/serving/pull/8611#" title="Author self-approved">mattmoor</a>*

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

The pull request process is described [here](https://git.k8s.io/community/contributors/guide/owners.md#the-code-review-process)

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

- ~~[OWNERS](https://github.com/knative/serving/blob/master/OWNERS)~~ [mattmoor]

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":[]} -->
knative-prow-robot: @mattmoor: The following test **failed**, say `/retest` to rerun all failed tests:

Test name | Commit | Details | Rerun command
--- | --- | --- | ---
pull-knative-serving-unit-tests | abfcb8eaeb310a8672c250dcb7914b24e1b0e0de | [link](https://prow.knative.dev/view/gcs/knative-prow/pr-logs/pull/knative_serving/8611/pull-knative-serving-unit-tests/1282679945360838658) | `/test pull-knative-serving-unit-tests`

[Full PR test history](https://gubernator.knative.dev/pr/knative_serving/8611). [Your PR dashboard](https://gubernator.knative.dev/pr/mattmoor).

<details>

Instructions for interacting with me using PR comments are available [here](https://git.k8s.io/community/contributors/guide/pull-requests.md).  If you have questions or suggestions related to my behavior, please file an issue against the [kubernetes/test-infra](https://github.com/kubernetes/test-infra/issues/new?title=Prow%20issue:) repository. I understand the commands that are listed [here](https://go.k8s.io/bot-commands).
</details>
<!-- test report -->
knative-test-reporter-robot: <!--[AUTOMATED-FLAKY-RETRYER]abfcb8eaeb310a8672c250dcb7914b24e1b0e0de[AUTOMATED-FLAKY-RETRYER]-->
The following jobs failed:

Test name | Triggers | Retries
--- | --- | ---
pull-knative-serving-unit-tests |  | 0/3

Failed non-flaky tests preventing automatic retry of pull-knative-serving-unit-tests:

```
pkg/reconciler/gc/v2.TestCollect
```

Patch:
diff --git a/go.mod b/go.mod
index f4917bfba..84539a887 100644
--- a/go.mod
+++ b/go.mod
@@ -40,8 +40,8 @@ require (
 	k8s.io/kube-openapi v0.0.0-20200410145947-bcb3869e6f29
 	knative.dev/caching v0.0.0-20200707200344-95a2aaeace0f
 	knative.dev/networking v0.0.0-20200707203944-725ec013d8a2
-	knative.dev/pkg v0.0.0-20200710163519-a0cb3d689532
-	knative.dev/test-infra v0.0.0-20200710160019-5b9732bc24f7
+	knative.dev/pkg v0.0.0-20200713031612-b09a159e12c9
+	knative.dev/test-infra v0.0.0-20200713045417-850e4e37918d
 )
 
 replace (
diff --git a/go.sum b/go.sum
index 531a2c743..1656e86c4 100644
--- a/go.sum
+++ b/go.sum
@@ -1634,11 +1634,13 @@ knative.dev/networking v0.0.0-20200707203944-725ec013d8a2 h1:Co9j0Q4ZJxwkzVFKUc6
 knative.dev/networking v0.0.0-20200707203944-725ec013d8a2/go.mod h1:e1NL29AarTcgaR240oc4GUzqHtTfTu62JNrUHN3kIG0=
 knative.dev/pkg v0.0.0-20200207155214-fef852970f43/go.mod h1:pgODObA1dTyhNoFxPZTTjNWfx6F0aKsKzn+vaT9XO/Q=
 knative.dev/pkg v0.0.0-20200707190344-0a8314b44495/go.mod h1:AqAJV6rYi8IGikDjJ/9ZQd9qKdkXVlesVnVjwx62YB8=
-knative.dev/pkg v0.0.0-20200710163519-a0cb3d689532 h1:1dSRUstjueNPF06yxGlmeEzzMZpQJnlddA4VehDuTp8=
-knative.dev/pkg v0.0.0-20200710163519-a0cb3d689532/go.mod h1:AqAJV6rYi8IGikDjJ/9ZQd9qKdkXVlesVnVjwx62YB8=
+knative.dev/pkg v0.0.0-20200713031612-b09a159e12c9 h1:YSapebbZZbpH31YMSF0Egt7+IDi/og4S574eWqEXReo=
+knative.dev/pkg v0.0.0-20200713031612-b09a159e12c9/go.mod h1:aWPsPIHISvZetAm/2pnz+v6Ro5EYaX704Z/Zd9rTZ4M=
 knative.dev/test-infra v0.0.0-20200707183444-aed09e56ddc7/go.mod h1:RjYAhXnZqeHw9+B0zsbqSPlae0lCvjekO/nw5ZMpLCs=
 knative.dev/test-infra v0.0.0-20200710160019-5b9732bc24f7 h1:fAl3pG2I323tie8kuuNlB88B7RB8WJtCrsXIKuNh1U8=
 knative.dev/test-infra v0.0.0-20200710160019-5b9732bc24f7/go.mod h1:vtT6dLs/iNj8pKcfag8CSVqHKNMgyCFtU/g1pV7Bovs=
+knative.dev/test-infra v0.0.0-20200713045417-850e4e37918d h1:Q3LrAYSi+Ii2yZVUiA5Y3Jr4TCU6g/XN9ClVosejpJk=
+knative.dev/test-infra v0.0.0-20200713045417-850e4e37918d/go.mod h1:vtT6dLs/iNj8pKcfag8CSVqHKNMgyCFtU/g1pV7Bovs=
 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/vendor/knative.dev/pkg/apis/duck/ducktypes/ducktypes.go b/vendor/knative.dev/pkg/apis/duck/ducktypes/ducktypes.go
new file mode 100644
index 000000000..6f99e0882
--- /dev/null
+++ b/vendor/knative.dev/pkg/apis/duck/ducktypes/ducktypes.go
@@ -0,0 +1,43 @@
+/*
+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 ducktypes
+
+import (
+	"knative.dev/pkg/apis"
+)
+
+// Implementable is implemented by the Fooable duck type that consumers
+// are expected to embed as a `.status.fooable` field.
+type Implementable interface {
+	// GetFullType returns an instance of a full resource wrapping
+	// an instance of this Implementable that can populate its fields
+	// to verify json roundtripping.
+	GetFullType() Populatable
+}
+
+// Populatable is implemented by a skeleton resource wrapping an Implementable
+// duck type.  It will generally have TypeMeta, ObjectMeta, and a Status field
+// wrapping a Fooable field.
+type Populatable interface {
+	apis.Listable
+
+	// Populate fills in all possible fields, so that we can verify that
+	// they roundtrip properly through JSON.
+	Populate()
+}
+
+const GroupName = "duck.knative.dev"
diff --git a/vendor/knative.dev/pkg/apis/duck/register.go b/vendor/knative.dev/pkg/apis/duck/register.go
index d84cd49d1..93cf55d7f 100644
--- a/vendor/knative.dev/pkg/apis/duck/register.go
+++ b/vendor/knative.dev/pkg/apis/duck/register.go
@@ -16,8 +16,12 @@ limitations under the License.
 
 package duck
 
+import (
+	"knative.dev/pkg/apis/duck/ducktypes"
+)
+
 const (
-	GroupName = "duck.knative.dev"
+	GroupName = ducktypes.GroupName
 
 	// AddressableDuckVersionLabel is the label we use to declare
 	// that a type conforms to the Addressable duck type.
diff --git a/vendor/knative.dev/pkg/apis/duck/v1/addressable_types.go b/vendor/knative.dev/pkg/apis/duck/v1/addressable_types.go
index 579e6976e..3cfcac331 100644
--- a/vendor/knative.dev/pkg/apis/duck/v1/addressable_types.go
+++ b/vendor/knative.dev/pkg/apis/duck/v1/addressable_types.go
@@ -24,7 +24,7 @@ import (
 	"k8s.io/apimachinery/pkg/runtime"
 
 	"knative.dev/pkg/apis"
-	"knative.dev/pkg/apis/duck"
+	"knative.dev/pkg/apis/duck/ducktypes"
 )
 
 // +genduck
@@ -40,8 +40,6 @@ type Addressable struct {
 }
 
 var (
-	// Addressable is an Implementable "duck type".
-	_ duck.Implementable = (*Addressable)(nil)
 	// Addressable is a Convertible type.
 	_ apis.Convertible = (*Addressable)(nil)
 )
@@ -66,13 +64,11 @@ type AddressStatus struct {
 }
 
 var (
-	// Verify AddressableType resources meet duck contracts.
-	_ duck.Populatable = (*AddressableType)(nil)
-	_ apis.Listable    = (*AddressableType)(nil)
+	_ apis.Listable = (*AddressableType)(nil)
 )
 
 // GetFullType implements duck.Implementable
-func (*Addressable) GetFullType() duck.Populatable {
+func (*Addressable) GetFullType() ducktypes.Populatable {
 	return &AddressableType{}
 }
 
diff --git a/vendor/knative.dev/pkg/apis/duck/v1/podspec_types.go b/vendor/knative.dev/pkg/apis/duck/v1/podspec_types.go
index 0dd9ec338..92ed7f1c4 100644
--- a/vendor/knative.dev/pkg/apis/duck/v1/podspec_types.go
+++ b/vendor/knative.dev/pkg/apis/duck/v1/podspec_types.go
@@ -22,7 +22,7 @@ import (
 	"k8s.io/apimachinery/pkg/runtime"
 
 	"knative.dev/pkg/apis"
-	"knative.dev/pkg/apis/duck"
+	"knative.dev/pkg/apis/duck/ducktypes"
 )
 
 // +genduck
@@ -50,13 +50,11 @@ type WithPodSpec struct {
 // Assert that we implement the interfaces necessary to
 // use duck.VerifyType.
 var (
-	_ duck.Populatable   = (*WithPod)(nil)
-	_ duck.Implementable = (*PodSpecable)(nil)
-	_ apis.Listable      = (*WithPod)(nil)
+	_ apis.Listable = (*WithPod)(nil)
 )
 
 // GetFullType implements duck.Implementable
-func (*PodSpecable) GetFullType() duck.Populatable {
+func (*PodSpecable) GetFullType() ducktypes.Populatable {
 	return &WithPod{}
 }
 
diff --git a/vendor/knative.dev/pkg/apis/duck/v1/register.go b/vendor/knative.dev/pkg/apis/duck/v1/register.go
index e3af46d6f..69bb11578 100644
--- a/vendor/knative.dev/pkg/apis/duck/v1/register.go
+++ b/vendor/knative.dev/pkg/apis/duck/v1/register.go
@@ -20,11 +20,12 @@ import (
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 	"k8s.io/apimachinery/pkg/runtime"
 	"k8s.io/apimachinery/pkg/runtime/schema"
-	"knative.dev/pkg/apis/duck"
+
+	"knative.dev/pkg/apis/duck/ducktypes"
 )
 
 // SchemeGroupVersion is group version used to register these objects
-var SchemeGroupVersion = schema.GroupVersion{Group: duck.GroupName, Version: "v1"}
+var SchemeGroupVersion = schema.GroupVersion{Group: ducktypes.GroupName, Version: "v1"}
 
 // Kind takes an unqualified kind and returns back a Group qualified GroupKind
 func Kind(kind string) schema.GroupKind {
diff --git a/vendor/knative.dev/pkg/apis/duck/v1/source_types.go b/vendor/knative.dev/pkg/apis/duck/v1/source_types.go
index 3b378ca3d..03c4d40b9 100644
--- a/vendor/knative.dev/pkg/apis/duck/v1/source_types.go
+++ b/vendor/knative.dev/pkg/apis/duck/v1/source_types.go
@@ -24,12 +24,9 @@ import (
 	"k8s.io/apimachinery/pkg/runtime"
 
 	"knative.dev/pkg/apis"
-	"knative.dev/pkg/apis/duck"
+	"knative.dev/pkg/apis/duck/ducktypes"
 )
 
-// Source is an Implementable "duck type".
-var _ duck.Implementable = (*Source)(nil)
-
 // +genduck
 // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
 
@@ -113,9 +110,7 @@ func (ss *SourceStatus) IsReady() bool {
 }
 
 var (
-	// Verify Source resources meet duck contracts.
-	_ duck.Populatable = (*Source)(nil)
-	_ apis.Listable    = (*Source)(nil)
+	_ apis.Listable = (*Source)(nil)
 )
 
 const (
@@ -125,7 +120,7 @@ const (
 )
 
 // GetFullType implements duck.Implementable
-func (*Source) GetFullType() duck.Populatable {
+func (*Source) GetFullType() ducktypes.Populatable {
 	return &Source{}
 }
 
diff --git a/vendor/knative.dev/pkg/apis/duck/v1/status_types.go b/vendor/knative.dev/pkg/apis/duck/v1/status_types.go
index aab246b1f..f25212e57 100644
--- a/vendor/knative.dev/pkg/apis/duck/v1/status_types.go
+++ b/vendor/knative.dev/pkg/apis/duck/v1/status_types.go
@@ -20,7 +20,7 @@ import (
 	"context"
 
 	"knative.dev/pkg/apis"
-	"knative.dev/pkg/apis/duck"
+	"knative.dev/pkg/apis/duck/ducktypes"
 	"knative.dev/pkg/kmeta"
 )
 
@@ -29,9 +29,6 @@ import (
 // Conditions is a simple wrapper around apis.Conditions to implement duck.Implementable.
 type Conditions apis.Conditions
 
-// Conditions is an Implementable "duck type".
-var _ duck.Implementable = (*Conditions)(nil)
-
 // Status shows how we expect folks to embed Conditions in
 // their Status field.
 // WARNING: Adding fields to this struct will add them to all Knative resources.
@@ -66,14 +63,11 @@ func (s *Status) SetConditions(c apis.Conditions) {
 	s.Conditions = Conditions(c)
 }
 
-// In order for Conditions to be Implementable, KResource must be Populatable.
-var _ duck.Populatable = (*KResource)(nil)
-
 // Ensure KResource satisfies apis.Listable
 var _ apis.Listable = (*KResource)(nil)
 
 // GetFullType implements duck.Implementable
-func (*Conditions) GetFullType() duck.Populatable {
+func (*Conditions) GetFullType() ducktypes.Populatable {
 	return &KResource{}
 }
 
diff --git a/vendor/knative.dev/pkg/apis/duck/v1beta1/addressable_types.go b/vendor/knative.dev/pkg/apis/duck/v1beta1/addressable_types.go
index 3e3f82867..46cfed160 100644
--- a/vendor/knative.dev/pkg/apis/duck/v1beta1/addressable_types.go
+++ b/vendor/knative.dev/pkg/apis/duck/v1beta1/addressable_types.go
@@ -24,8 +24,8 @@ import (
 	"k8s.io/apimachinery/pkg/runtime"
 
 	"knative.dev/pkg/apis"
-	"knative.dev/pkg/apis/duck"
-	v1 "knative.dev/pkg/apis/duck/v1"
+	"knative.dev/pkg/apis/duck/ducktypes"
+	"knative.dev/pkg/apis/duck/v1"
 )
 
 // +genduck
@@ -41,8 +41,6 @@ type Addressable struct {
 }
 
 var (
-	// Addressable is an Implementable "duck type".
-	_ duck.Implementable = (*Addressable)(nil)
 	// Addressable is a Convertible type.
 	_ apis.Convertible = (*Addressable)(nil)
 )
@@ -67,13 +65,11 @@ type AddressStatus struct {
 }
 
 var (
-	// Verify AddressableType resources meet duck contracts.
-	_ duck.Populatable = (*AddressableType)(nil)
-	_ apis.Listable    = (*AddressableType)(nil)
+	_ apis.Listable = (*AddressableType)(nil)
 )
 
 // GetFullType implements duck.Implementable
-func (*Addressable) GetFullType() duck.Populatable {
+func (*Addressable) GetFullType() ducktypes.Populatable {
 	return &AddressableType{}
 }
 
diff --git a/vendor/knative.dev/pkg/apis/duck/v1beta1/register.go b/vendor/knative.dev/pkg/apis/duck/v1beta1/register.go
index ca8388ad4..324639c06 100644
--- a/vendor/knative.dev/pkg/apis/duck/v1beta1/register.go
+++ b/vendor/knative.dev/pkg/apis/duck/v1beta1/register.go
@@ -20,11 +20,12 @@ import (
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 	"k8s.io/apimachinery/pkg/runtime"
 	"k8s.io/apimachinery/pkg/runtime/schema"
-	"knative.dev/pkg/apis/duck"
+
+	"knative.dev/pkg/apis/duck/ducktypes"
 )
 
 // SchemeGroupVersion is group version used to register these objects
-var SchemeGroupVersion = schema.GroupVersion{Group: duck.GroupName, Version: "v1beta1"}
+var SchemeGroupVersion = schema.GroupVersion{Group: ducktypes.GroupName, Version: "v1beta1"}
 
 // Kind takes an unqualified kind and returns back a Group qualified GroupKind
 func Kind(kind string) schema.GroupKind {
diff --git a/vendor/knative.dev/pkg/apis/duck/v1beta1/source_types.go b/vendor/knative.dev/pkg/apis/duck/v1beta1/source_types.go
index 5853a1ae4..1a9be0d6c 100644
--- a/vendor/knative.dev/pkg/apis/duck/v1beta1/source_types.go
+++ b/vendor/knative.dev/pkg/apis/duck/v1beta1/source_types.go
@@ -24,12 +24,9 @@ import (
 	"k8s.io/apimachinery/pkg/runtime"
 
 	"knative.dev/pkg/apis"
-	"knative.dev/pkg/apis/duck"
+	"knative.dev/pkg/apis/duck/ducktypes"
 )
 
-// Source is an Implementable "duck type".
-var _ duck.Implementable = (*Source)(nil)
-
 // +genduck
 // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
 
@@ -98,9 +95,7 @@ func (ss *SourceStatus) IsReady() bool {
 }
 
 var (
-	// Verify Source resources meet duck contracts.
-	_ duck.Populatable = (*Source)(nil)
-	_ apis.Listable    = (*Source)(nil)
+	_ apis.Listable = (*Source)(nil)
 )
 
 const (
@@ -110,7 +105,7 @@ const (
 )
 
 // GetFullType implements duck.Implementable
-func (*Source) GetFullType() duck.Populatable {
+func (*Source) GetFullType() ducktypes.Populatable {
 	return &Source{}
 }
 
diff --git a/vendor/knative.dev/pkg/apis/duck/v1beta1/status_types.go b/vendor/knative.dev/pkg/apis/duck/v1beta1/status_types.go
index 107592e85..8054c53be 100644
--- a/vendor/knative.dev/pkg/apis/duck/v1beta1/status_types.go
+++ b/vendor/knative.dev/pkg/apis/duck/v1beta1/status_types.go
@@ -25,7 +25,7 @@ import (
 	"k8s.io/apimachinery/pkg/runtime"
 
 	"knative.dev/pkg/apis"
-	"knative.dev/pkg/apis/duck"
+	"knative.dev/pkg/apis/duck/ducktypes"
 	"knative.dev/pkg/kmeta"
 )
 
@@ -34,9 +34,6 @@ import (
 // Conditions is a simple wrapper around apis.Conditions to implement duck.Implementable.
 type Conditions apis.Conditions
 
-// Conditions is an Implementable "duck type".
-var _ duck.Implementable = (*Conditions)(nil)
-
 // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
 
 // KResource is a skeleton type wrapping Conditions in the manner we expect
@@ -84,14 +81,11 @@ func (s *Status) SetConditions(c apis.Conditions) {
 	s.Conditions = Conditions(c)
 }
 
-// In order for Conditions to be Implementable, KResource must be Populatable.
-var _ duck.Populatable = (*KResource)(nil)
-
 // Ensure KResource satisfies apis.Listable
 var _ apis.Listable = (*KResource)(nil)
 
 // GetFullType implements duck.Implementable
-func (*Conditions) GetFullType() duck.Populatable {
+func (*Conditions) GetFullType() ducktypes.Populatable {
 	return &KResource{}
 }
 
diff --git a/vendor/knative.dev/pkg/apis/duck/verify.go b/vendor/knative.dev/pkg/apis/duck/verify.go
index 3f42330ff..cbcc51117 100644
--- a/vendor/knative.dev/pkg/apis/duck/verify.go
+++ b/vendor/knative.dev/pkg/apis/duck/verify.go
@@ -20,29 +20,12 @@ import (
 	"encoding/json"
 	"fmt"
 
-	"knative.dev/pkg/apis"
+	"knative.dev/pkg/apis/duck/ducktypes"
 	"knative.dev/pkg/kmp"
 )
 
-// Implementable is implemented by the Fooable duck type that consumers
-// are expected to embed as a `.status.fooable` field.
-type Implementable interface {
-	// GetFullType returns an instance of a full resource wrapping
-	// an instance of this Implementable that can populate its fields
-	// to verify json roundtripping.
-	GetFullType() Populatable
-}
-
-// Populatable is implemented by a skeleton resource wrapping an Implementable
-// duck type.  It will generally have TypeMeta, ObjectMeta, and a Status field
-// wrapping a Fooable field.
-type Populatable interface {
-	apis.Listable
-
-	// Populate fills in all possible fields, so that we can verify that
-	// they roundtrip properly through JSON.
-	Populate()
-}
+type Implementable = ducktypes.Implementable
+type Populatable = ducktypes.Populatable
 
 // VerifyType verifies that a particular concrete resource properly implements
 // the provided Implementable duck type.  It is expected that under the resource
diff --git a/vendor/knative.dev/pkg/hash/bucketer.go b/vendor/knative.dev/pkg/hash/bucketer.go
new file mode 100644
index 000000000..45f1100ab
--- /dev/null
+++ b/vendor/knative.dev/pkg/hash/bucketer.go
@@ -0,0 +1,112 @@
+/*
+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
+
+    https://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.
+*/
+
+// This file contains the utilities to make bucketing decisions.
+
+package hash
+
+import (
+	"sync"
+
+	lru "github.com/hashicorp/golang-lru"
+	"k8s.io/apimachinery/pkg/types"
+	"k8s.io/apimachinery/pkg/util/sets"
+	"knative.dev/pkg/reconciler"
+)
+
+var _ reconciler.Bucket = (*Bucket)(nil)
+
+// BucketSet answers to what bucket does key X belong in a
+// consistent manner (consistent as in consistent hashing).
+type BucketSet struct {
+	// Stores the cached lookups. cache is internally thread safe.
+	cache *lru.Cache
+
+	// mu guards buckets.
+	mu sync.RWMutex
+	// All the bucket names. Needed for building hash universe.
+	// `name` must be in this set.
+	buckets sets.String
+}
+
+// Bucket implements reconciler.Bucket and wraps around BuketSet
+// for bucketing functions.
+type Bucket struct {
+	name    string
+	buckets *BucketSet
+}
+
+// Scientifically inferred preferred cache size.
+const cacheSize = 4096
+
+func newCache() *lru.Cache {
+	c, _ := lru.New(cacheSize)
+	return c
+}
+
+// NewBucketSet creates a new bucket set with the given universe
+// of bucket names.
+func NewBucketSet(bucketList sets.String) *BucketSet {
+	return &BucketSet{
+		cache:   newCache(),
+		buckets: bucketList,
+	}
+}
+
+// NewBucket creates a new bucket.
+func NewBucket(name string, bl *BucketSet) *Bucket {
+	return &Bucket{
+		name:    name,
+		buckets: bl,
+	}
+}
+
+// Name implements Bucket.
+func (b *Bucket) Name() string {
+	return b.name
+}
+
+// Has returns true if this bucket owns the key and
+// implements reconciler.Bucket interface.
+func (b *Bucket) Has(nn types.NamespacedName) bool {
+	return b.buckets.Owner(nn.String()) == b.name
+}
+
+// Owner returns the owner of the key.
+// Owner will cache the results for faster lookup.
+func (b *BucketSet) Owner(key string) string {
+	if v, ok := b.cache.Get(key); ok {
+		return v.(string)
+	}
+	b.mu.RLock()
+	defer b.mu.RUnlock()
+	l := ChooseSubset(b.buckets, 1 /*single query wanted*/, key)
+	ret := l.UnsortedList()[0]
+	b.cache.Add(key, ret)
+	return ret
+}
+
+// Update updates the universe of buckets.
+func (b *BucketSet) Update(newB sets.String) {
+	b.mu.Lock()
+	defer b.mu.Unlock()
+	// In theory we can iterate over the map and
+	// purge only the keys that moved to a new shard.
+	// But this might be more expensive than re-build
+	// the cache as reconciliations happen.
+	b.cache.Purge()
+	b.buckets = newB
+}
diff --git a/vendor/knative.dev/pkg/hash/doc.go b/vendor/knative.dev/pkg/hash/doc.go
index 36569b84a..5cb01faa6 100644
--- a/vendor/knative.dev/pkg/hash/doc.go
+++ b/vendor/knative.dev/pkg/hash/doc.go
@@ -17,6 +17,11 @@ limitations under the License.
 // Package hash contains various Knative specific hashing utilities.
 //
 // - ChooseSubset is a consistent hashing/mapping function providing
-//   a  consistent selection of N keys from M (N<=M) keys for a given
+//   a consistent selection of N keys from M (N<=M) keys for a given
 //   target.
+// - BucketSet is a bucketer library which uses ChooseSubset under the
+//   the hood in order to implement consistent mapping between keys and
+//   set of buckets, indentified by unique names. Compared to basic bucket
+//   implementtion which just does hash%num_buckets, when the number of
+//   buckets change only a small subset of keys are supposed to migrate.
 package hash
diff --git a/vendor/modules.txt b/vendor/modules.txt
index 39360dfb3..42758046f 100644
--- a/vendor/modules.txt
+++ b/vendor/modules.txt
@@ -1034,12 +1034,13 @@ 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-20200710163519-a0cb3d689532
+# knative.dev/pkg v0.0.0-20200713031612-b09a159e12c9
 ## explicit
 knative.dev/pkg/apiextensions/storageversion
 knative.dev/pkg/apiextensions/storageversion/cmd/migrate
 knative.dev/pkg/apis
 knative.dev/pkg/apis/duck
+knative.dev/pkg/apis/duck/ducktypes
 knative.dev/pkg/apis/duck/v1
 knative.dev/pkg/apis/duck/v1alpha1
 knative.dev/pkg/apis/duck/v1beta1
@@ -1154,7 +1155,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-20200710160019-5b9732bc24f7
+# knative.dev/test-infra v0.0.0-20200713045417-850e4e37918d
 ## explicit
 knative.dev/test-infra/scripts
 # sigs.k8s.io/yaml v1.2.0


Test patch:
diff --git a/pkg/reconciler/gc/v2/gc_test.go b/pkg/reconciler/gc/v2/gc_test.go
index d48a745a4..9a77c1677 100644
--- a/pkg/reconciler/gc/v2/gc_test.go
+++ b/pkg/reconciler/gc/v2/gc_test.go
@@ -54,6 +54,7 @@ var revisionSpec = v1.RevisionSpec{
 
 func TestCollect(t *testing.T) {
 	now := time.Now()
+	nineMinutesAgo := now.Add(-9 * time.Minute)
 	tenMinutesAgo := now.Add(-10 * time.Minute)
 
 	old := now.Add(-11 * time.Minute)
@@ -164,7 +165,7 @@ func TestCollect(t *testing.T) {
 			rev("keep-recent-last-pinned", "foo", 5555, MarkRevisionReady,
 				WithRevName("5555"),
 				WithCreationTimestamp(older),
-				WithLastPinned(tenMinutesAgo)),
+				WithLastPinned(nineMinutesAgo)),
 			rev("keep-recent-last-pinned", "foo", 5556, MarkRevisionReady,
 				WithRevName("5556"),
 				WithCreationTimestamp(old),
diff --git a/vendor/knative.dev/pkg/apis/duck/v1_tests.go b/vendor/knative.dev/pkg/apis/duck/v1_tests.go
new file mode 100644
index 000000000..ca68b4c89
--- /dev/null
+++ b/vendor/knative.dev/pkg/apis/duck/v1_tests.go
@@ -0,0 +1,78 @@
+/*
+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 duck
+
+import (
+	"testing"
+
+	appsv1 "k8s.io/api/apps/v1"
+	batchv1 "k8s.io/api/batch/v1"
+
+	"knative.dev/pkg/apis/duck/v1"
+)
+
+// Conditions is an Implementable "duck type".
+var _ Implementable = (*v1.Conditions)(nil)
+
+// In order for Conditions to be Implementable, KResource must be Populatable.
+var _ Populatable = (*v1.KResource)(nil)
+
+// Source is an Implementable "duck type".
+var _ Implementable = (*v1.Source)(nil)
+
+// Verify Source resources meet duck contracts.
+var _ Populatable = (*v1.Source)(nil)
+
+var _ Populatable = (*v1.WithPod)(nil)
+var _ Implementable = (*v1.PodSpecable)(nil)
+
+func TestV1TypesImplements(t *testing.T) {
+	testCases := []struct {
+		instance interface{}
+		iface    Implementable
+	}{
+		{instance: &v1.AddressableType{}, iface: &v1.Addressable{}},
+		{instance: &v1.KResource{}, iface: &v1.Conditions{}},
+	}
+	for _, tc := range testCases {
+		if err := VerifyType(tc.instance, tc.iface); err != nil {
+			t.Error(err)
+		}
+	}
+}
+
+func TestV1ImplementsPodSpecable(t *testing.T) {
+	instances := []interface{}{
+		&v1.WithPod{},
+		&appsv1.ReplicaSet{},
+		&appsv1.Deployment{},
+		&appsv1.StatefulSet{},
+		&appsv1.DaemonSet{},
+		&batchv1.Job{},
+	}
+	for _, instance := range instances {
+		if err := VerifyType(instance, &v1.PodSpecable{}); err != nil {
+			t.Error(err)
+		}
+	}
+}
+
+// Addressable is an Implementable "duck type".
+var _ Implementable = (*v1.Addressable)(nil)
+
+// Verify AddressableType resources meet duck contracts.
+var _ Populatable = (*v1.AddressableType)(nil)
diff --git a/vendor/knative.dev/pkg/apis/duck/v1beta1_tests.go b/vendor/knative.dev/pkg/apis/duck/v1beta1_tests.go
new file mode 100644
index 000000000..23731d8c7
--- /dev/null
+++ b/vendor/knative.dev/pkg/apis/duck/v1beta1_tests.go
@@ -0,0 +1,56 @@
+/*
+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 duck
+
+import (
+	"testing"
+
+	"knative.dev/pkg/apis/duck/v1beta1"
+)
+
+// v1beta1.Conditions is an Implementable "duck type".
+var _ Implementable = (*v1beta1.Conditions)(nil)
+
+// In order for v1beta1.Conditions to be Implementable, v1beta1.KResource must be Populatable.
+var _ Populatable = (*v1beta1.KResource)(nil)
+
+// v1beta1.Source is an Implementable "duck type".
+var _ Implementable = (*v1beta1.Source)(nil)
+
+// Verify v1beta1.Source resources meet duck contracts.
+var _ Populatable = (*v1beta1.Source)(nil)
+
+// Addressable is an Implementable "duck type".
+var _ Implementable = (*v1beta1.Addressable)(nil)
+
+// Verify AddressableType resources meet duck contracts.
+var _ Populatable = (*v1beta1.AddressableType)(nil)
+
+func TestV1Beta1TypesImplements(t *testing.T) {
+	testCases := []struct {
+		instance interface{}
+		iface    Implementable
+	}{
+		{instance: &v1beta1.AddressableType{}, iface: &v1beta1.Addressable{}},
+		{instance: &v1beta1.KResource{}, iface: &v1beta1.Conditions{}},
+	}
+	for _, tc := range testCases {
+		if err := VerifyType(tc.instance, tc.iface); err != nil {
+			t.Error(err)
+		}
+	}
+}
diff --git a/vendor/knative.dev/pkg/test/ha/ha.go b/vendor/knative.dev/pkg/test/ha/ha.go
index c1b5c045b..2859cc872 100644
--- a/vendor/knative.dev/pkg/test/ha/ha.go
+++ b/vendor/knative.dev/pkg/test/ha/ha.go
@@ -26,17 +26,36 @@ import (
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 	"k8s.io/apimachinery/pkg/util/sets"
 	"k8s.io/apimachinery/pkg/util/wait"
+
 	"knative.dev/pkg/test"
 	"knative.dev/pkg/test/logging"
 )
 
+func countingRFind(wr rune, wc int) func(rune) bool {
+	cnt := 0
+	return func(r rune) bool {
+		if r == wr {
+			cnt++
+		}
+		return cnt == wc
+	}
+}
+
+func extractDeployment(pod string) string {
+	if x := strings.LastIndexFunc(pod, countingRFind('-', 2)); x != -1 {
+		return pod[:x]
+	}
+	return ""
+}
+
 // GetLeaders collects all of the leader pods from the specified deployment.
+// GetLeaders will return duplicate pods by design.
 func GetLeaders(t *testing.T, client *test.KubeClient, deploymentName, namespace string) ([]string, error) {
 	leases, err := client.Kube.CoordinationV1().Leases(namespace).List(metav1.ListOptions{})
 	if err != nil {
 		return nil, fmt.Errorf("error getting leases for deployment %q: %w", deploymentName, err)
 	}
-	var pods []string
+	ret := make([]string, 0, len(leases.Items))
 	for _, lease := range leases.Items {
 		if lease.Spec.HolderIdentity == nil {
 			continue
@@ -44,16 +63,12 @@ func GetLeaders(t *testing.T, client *test.KubeClient, deploymentName, namespace
 		pod := strings.SplitN(*lease.Spec.HolderIdentity, "_", 2)[0]
 
 		// Deconstruct the pod name and look for the deployment.  This won't work for very long deployment names.
-		parts := strings.Split(pod, "-")
-		if len(parts) < 3 {
-			continue
-		}
-		if strings.Join(parts[:len(parts)-2], "-") != deploymentName {
+		if extractDeployment(pod) != deploymentName {
 			continue
 		}
-		pods = append(pods, pod)
+		ret = append(ret, pod)
 	}
-	return pods, nil
+	return ret, nil
 }
 
 // WaitForNewLeaders waits until the collection of current leaders consists of "n" leaders
@@ -64,19 +79,20 @@ func WaitForNewLeaders(t *testing.T, client *test.KubeClient, deploymentName, na
 
 	var leaders sets.String
 	err := wait.PollImmediate(time.Second, time.Minute, func() (bool, error) {
-		currentLeaders, err := GetLeaders(t, client, deploymentName, namespace)
+		currLeaders, err := GetLeaders(t, client, deploymentName, namespace)
 		if err != nil {
 			return false, err
 		}
-		if len(currentLeaders) < n {
-			t.Logf("WaitForNewLeaders[%s] not enough leaders, got: %d, want: %d", deploymentName, len(currentLeaders), n)
+		if len(currLeaders) < n {
+			t.Logf("WaitForNewLeaders[%s] not enough leaders, got: %d, want: %d", deploymentName, len(currLeaders), n)
 			return false, nil
 		}
-		if previousLeaders.HasAny(currentLeaders...) {
-			t.Logf("WaitForNewLeaders[%s] still see intersection: %v", deploymentName, previousLeaders.Intersection(sets.NewString(currentLeaders...)))
+		l := sets.NewString(currLeaders...)
+		if previousLeaders.HasAny(currLeaders...) {
+			t.Logf("WaitForNewLeaders[%s] still see intersection: %v", deploymentName, previousLeaders.Intersection(l))
 			return false, nil
 		}
-		leaders = sets.NewString(currentLeaders...)
+		leaders = l
 		return true, nil
 	})
 	return leaders, err