Repository: knative/pkg
Pull request #1560 (2020-07-27 08:08:17)

Remove our copy of the proxy watcher.
We've long bumped the K8s dependencies. Deleted code is good code.

/assign @mattmoor 

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

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

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

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:

- ~~[apis/duck/OWNERS](https://github.com/knative/pkg/blob/master/apis/duck/OWNERS)~~ [markusthoemmes]

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":[]} -->

Patch:
diff --git a/apis/duck/proxy.go b/apis/duck/proxy.go
deleted file mode 100644
index 85a795c36..000000000
--- a/apis/duck/proxy.go
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
-Copyright 2018 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 (
-	"sync"
-
-	"k8s.io/apimachinery/pkg/watch"
-)
-
-// NewProxyWatcher is based on the same concept from Kubernetes apimachinery in 1.12 here:
-//    https://github.com/kubernetes/apimachinery/blob/c6dd271be/pkg/watch/watch.go#L272
-// Replace this copy once we've update our client libraries.
-
-// proxyWatcher lets you wrap your channel in watch.Interface. Threadsafe.
-type proxyWatcher struct {
-	result chan watch.Event
-	stopCh chan struct{}
-
-	mutex   sync.Mutex
-	stopped bool
-}
-
-var _ watch.Interface = (*proxyWatcher)(nil)
-
-// NewProxyWatcher creates new proxyWatcher by wrapping a channel
-func NewProxyWatcher(ch chan watch.Event) watch.Interface {
-	return &proxyWatcher{
-		result:  ch,
-		stopCh:  make(chan struct{}),
-		stopped: false,
-	}
-}
-
-// Stop implements Interface
-func (pw *proxyWatcher) Stop() {
-	pw.mutex.Lock()
-	defer pw.mutex.Unlock()
-	if !pw.stopped {
-		pw.stopped = true
-		close(pw.stopCh)
-	}
-}
-
-// Stopping returns true if Stop() has been called
-func (pw *proxyWatcher) Stopping() bool {
-	pw.mutex.Lock()
-	defer pw.mutex.Unlock()
-	return pw.stopped
-}
-
-// ResultChan implements watch.Interface
-func (pw *proxyWatcher) ResultChan() <-chan watch.Event {
-	return pw.result
-}
-
-// StopChan returns stop channel
-func (pw *proxyWatcher) StopChan() <-chan struct{} {
-	return pw.stopCh
-}
diff --git a/apis/duck/typed.go b/apis/duck/typed.go
index 5e1644a93..d6fa03451 100644
--- a/apis/duck/typed.go
+++ b/apis/duck/typed.go
@@ -134,6 +134,6 @@ func AsStructuredWatcher(wf cache.WatchFunc, obj runtime.Object) cache.WatchFunc
 			}
 		}()
 
-		return NewProxyWatcher(structuredCh), nil
+		return watch.NewProxyWatcher(structuredCh), nil
 	}
 }
diff --git a/go.mod b/go.mod
index 2a6d10de7..e65450974 100644
--- a/go.mod
+++ b/go.mod
@@ -47,7 +47,7 @@ require (
 	golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208
 	gomodules.xyz/jsonpatch/v2 v2.1.0
 	google.golang.org/api v0.29.0
-	google.golang.org/genproto v0.0.0-20200722002428-88e341933a54
+	google.golang.org/genproto v0.0.0-20200724131911-43cab4749ae7
 	google.golang.org/grpc v1.30.0
 	gopkg.in/yaml.v2 v2.3.0
 	gopkg.in/yaml.v3 v3.0.0-20190709130402-674ba3eaed22
@@ -59,7 +59,7 @@ require (
 	k8s.io/gengo v0.0.0-20200205140755-e0e292d8aa12
 	k8s.io/klog v1.0.0
 	k8s.io/utils v0.0.0-20200124190032-861946025e34 // indirect
-	knative.dev/test-infra v0.0.0-20200724213858-d5ec9cdc6b33
+	knative.dev/test-infra v0.0.0-20200725213358-8557dab80d7a
 	sigs.k8s.io/boskos v0.0.0-20200717180850-7299d535c033
 )
 
diff --git a/go.sum b/go.sum
index 9ab80571c..14affe4a7 100644
--- a/go.sum
+++ b/go.sum
@@ -1295,8 +1295,8 @@ 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-20200722175500-76b94024e4b6 h1:X9xIZ1YU8bLZA3l6gqDUHSFiD0GFI9S548h6C8nDtOY=
-golang.org/x/sys v0.0.0-20200722175500-76b94024e4b6/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/text v0.0.0-20160726164857-2910a502d2bf/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
 golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
 golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
@@ -1401,8 +1401,8 @@ golang.org/x/tools v0.0.0-20200709181711-e327e1019dfe/go.mod h1:njjCfa9FT2d7l9Bc
 golang.org/x/tools v0.0.0-20200713011307-fd294ab11aed/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
 golang.org/x/tools v0.0.0-20200721223218-6123e77877b2 h1:kxDWg8KNMtpGjI/XVKGgOtSljTnVg/PrjhS8+0pxjLE=
 golang.org/x/tools v0.0.0-20200721223218-6123e77877b2/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
-golang.org/x/tools v0.0.0-20200723000907-a7c6fd066f6d h1:7k9BKfwmdbykG6l5ztniTrH0TP25yel8O7l26/yovMU=
-golang.org/x/tools v0.0.0-20200723000907-a7c6fd066f6d/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/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
@@ -1494,6 +1494,8 @@ google.golang.org/genproto v0.0.0-20200709005830-7a2ca40e9dc3/go.mod h1:FWY/as6D
 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/grpc v0.0.0-20160317175043-d3ddb4469d5a/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw=
 google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs=
 google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
@@ -1633,16 +1635,16 @@ k8s.io/metrics v0.17.2/go.mod h1:3TkNHET4ROd+NfzNxkjoVfQ0Ob4iZnaHmSEA4vYpwLw=
 k8s.io/test-infra v0.0.0-20200514184223-ba32c8aae783 h1:dLB5TiQVoLcFkj1TPQSahZiJFP8NL+63tawMlX5aV8w=
 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-20200723132140-b02d194a2d64 h1:a/h/t14oAVzh2wvZgNgvC8z3A+HtbJnerlgHgcsXhUs=
-k8s.io/test-infra v0.0.0-20200723132140-b02d194a2d64/go.mod h1:4cRZlOy5Ka3Ym/orCmNWL2dsE39pN0xHFT0WFrZe2HQ=
+k8s.io/test-infra v0.0.0-20200724210216-b2cdf8399d01 h1:zIhDEzTWfMTFcp9pwe+Ga4qgIpzaljC9sFc9hjvE4EE=
+k8s.io/test-infra v0.0.0-20200724210216-b2cdf8399d01/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/eventing-contrib v0.11.2/go.mod h1:SnXZgSGgMSMLNFTwTnpaOH7hXDzTFtw0J8OmHflNx3g=
 knative.dev/pkg v0.0.0-20200207155214-fef852970f43/go.mod h1:pgODObA1dTyhNoFxPZTTjNWfx6F0aKsKzn+vaT9XO/Q=
-knative.dev/test-infra v0.0.0-20200724213858-d5ec9cdc6b33 h1:IhDg9AfaH9xgPv2KS0Lso5zLBXf9NSD9G+NdEznaYDI=
-knative.dev/test-infra v0.0.0-20200724213858-d5ec9cdc6b33/go.mod h1:Y3sNbLSTA11kRcLvTzRsZCxO+GQuw7KV7+PL+iD+9CA=
+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=
 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/ptr/ptr.go b/ptr/ptr.go
index a3bfef85c..6d5eeaab6 100644
--- a/ptr/ptr.go
+++ b/ptr/ptr.go
@@ -30,6 +30,18 @@ func Int64(i int64) *int64 {
 	return &i
 }
 
+// Float32 is a helper for turning floats into pointers for use in
+// API types that want *float32.
+func Float32(f float32) *float32 {
+	return &f
+}
+
+// Float64 is a helper for turning floats into pointers for use in
+// API types that want *float64.
+func Float64(f float64) *float64 {
+	return &f
+}
+
 // Bool is a helper for turning bools into pointers for use in
 // API types that want *bool.
 func Bool(b bool) *bool {
diff --git a/vendor/golang.org/x/sys/unix/zerrors_freebsd_386.go b/vendor/golang.org/x/sys/unix/zerrors_freebsd_386.go
index 848245873..3689c8084 100644
--- a/vendor/golang.org/x/sys/unix/zerrors_freebsd_386.go
+++ b/vendor/golang.org/x/sys/unix/zerrors_freebsd_386.go
@@ -339,6 +339,12 @@ const (
 	CLOCK_UPTIME_FAST              = 0x8
 	CLOCK_UPTIME_PRECISE           = 0x7
 	CLOCK_VIRTUAL                  = 0x1
+	CPUSTATES                      = 0x5
+	CP_IDLE                        = 0x4
+	CP_INTR                        = 0x3
+	CP_NICE                        = 0x1
+	CP_SYS                         = 0x2
+	CP_USER                        = 0x0
 	CREAD                          = 0x800
 	CRTSCTS                        = 0x30000
 	CS5                            = 0x0
diff --git a/vendor/golang.org/x/sys/unix/zerrors_freebsd_amd64.go b/vendor/golang.org/x/sys/unix/zerrors_freebsd_amd64.go
index 4acd101c3..b8f7c3c93 100644
--- a/vendor/golang.org/x/sys/unix/zerrors_freebsd_amd64.go
+++ b/vendor/golang.org/x/sys/unix/zerrors_freebsd_amd64.go
@@ -339,6 +339,12 @@ const (
 	CLOCK_UPTIME_FAST              = 0x8
 	CLOCK_UPTIME_PRECISE           = 0x7
 	CLOCK_VIRTUAL                  = 0x1
+	CPUSTATES                      = 0x5
+	CP_IDLE                        = 0x4
+	CP_INTR                        = 0x3
+	CP_NICE                        = 0x1
+	CP_SYS                         = 0x2
+	CP_USER                        = 0x0
 	CREAD                          = 0x800
 	CRTSCTS                        = 0x30000
 	CS5                            = 0x0
diff --git a/vendor/golang.org/x/sys/unix/zerrors_freebsd_arm.go b/vendor/golang.org/x/sys/unix/zerrors_freebsd_arm.go
index e4719873b..be14bb1a4 100644
--- a/vendor/golang.org/x/sys/unix/zerrors_freebsd_arm.go
+++ b/vendor/golang.org/x/sys/unix/zerrors_freebsd_arm.go
@@ -339,6 +339,12 @@ const (
 	CLOCK_UPTIME_FAST              = 0x8
 	CLOCK_UPTIME_PRECISE           = 0x7
 	CLOCK_VIRTUAL                  = 0x1
+	CPUSTATES                      = 0x5
+	CP_IDLE                        = 0x4
+	CP_INTR                        = 0x3
+	CP_NICE                        = 0x1
+	CP_SYS                         = 0x2
+	CP_USER                        = 0x0
 	CREAD                          = 0x800
 	CRTSCTS                        = 0x30000
 	CS5                            = 0x0
diff --git a/vendor/golang.org/x/sys/unix/zerrors_freebsd_arm64.go b/vendor/golang.org/x/sys/unix/zerrors_freebsd_arm64.go
index 5e49769d9..7ce9c0081 100644
--- a/vendor/golang.org/x/sys/unix/zerrors_freebsd_arm64.go
+++ b/vendor/golang.org/x/sys/unix/zerrors_freebsd_arm64.go
@@ -339,6 +339,12 @@ const (
 	CLOCK_UPTIME_FAST              = 0x8
 	CLOCK_UPTIME_PRECISE           = 0x7
 	CLOCK_VIRTUAL                  = 0x1
+	CPUSTATES                      = 0x5
+	CP_IDLE                        = 0x4
+	CP_INTR                        = 0x3
+	CP_NICE                        = 0x1
+	CP_SYS                         = 0x2
+	CP_USER                        = 0x0
 	CREAD                          = 0x800
 	CRTSCTS                        = 0x30000
 	CS5                            = 0x0
diff --git a/vendor/modules.txt b/vendor/modules.txt
index 5116d557d..4179a590f 100644
--- a/vendor/modules.txt
+++ b/vendor/modules.txt
@@ -348,7 +348,7 @@ golang.org/x/oauth2/jwt
 ## explicit
 golang.org/x/sync/errgroup
 golang.org/x/sync/semaphore
-# golang.org/x/sys v0.0.0-20200722175500-76b94024e4b6
+# golang.org/x/sys v0.0.0-20200724161237-0e2f3a69832c
 golang.org/x/sys/internal/unsafeheader
 golang.org/x/sys/unix
 golang.org/x/sys/windows
@@ -362,7 +362,7 @@ golang.org/x/text/unicode/norm
 golang.org/x/text/width
 # golang.org/x/time v0.0.0-20200630173020-3af7569d3a1e
 golang.org/x/time/rate
-# golang.org/x/tools v0.0.0-20200723000907-a7c6fd066f6d
+# golang.org/x/tools v0.0.0-20200724172932-b5fc9d354d99
 golang.org/x/tools/cmd/goimports
 golang.org/x/tools/go/ast/astutil
 golang.org/x/tools/go/gcexportdata
@@ -437,7 +437,7 @@ google.golang.org/appengine/internal/socket
 google.golang.org/appengine/internal/urlfetch
 google.golang.org/appengine/socket
 google.golang.org/appengine/urlfetch
-# google.golang.org/genproto v0.0.0-20200722002428-88e341933a54
+# google.golang.org/genproto v0.0.0-20200724131911-43cab4749ae7
 ## explicit
 google.golang.org/genproto/googleapis/api
 google.golang.org/genproto/googleapis/api/annotations
@@ -944,7 +944,7 @@ k8s.io/kube-openapi/pkg/generators
 k8s.io/kube-openapi/pkg/generators/rules
 k8s.io/kube-openapi/pkg/util/proto
 k8s.io/kube-openapi/pkg/util/sets
-# k8s.io/test-infra v0.0.0-20200723132140-b02d194a2d64
+# k8s.io/test-infra v0.0.0-20200724210216-b2cdf8399d01
 k8s.io/test-infra/prow/config/secret
 k8s.io/test-infra/prow/logrusutil
 k8s.io/test-infra/prow/version
@@ -954,7 +954,7 @@ k8s.io/utils/buffer
 k8s.io/utils/integer
 k8s.io/utils/pointer
 k8s.io/utils/trace
-# knative.dev/test-infra v0.0.0-20200724213858-d5ec9cdc6b33
+# knative.dev/test-infra v0.0.0-20200725213358-8557dab80d7a
 ## explicit
 knative.dev/test-infra/scripts
 # sigs.k8s.io/boskos v0.0.0-20200717180850-7299d535c033


Test patch:
diff --git a/apis/duck/typed_test.go b/apis/duck/typed_test.go
index 4ef97e170..a595a01fd 100644
--- a/apis/duck/typed_test.go
+++ b/apis/duck/typed_test.go
@@ -151,7 +151,7 @@ func TestAsStructuredWatcherClosedChannel(t *testing.T) {
 func TestAsStructuredWatcherPassThru(t *testing.T) {
 	unstructuredCh := make(chan watch.Event)
 	nwf := func(lo metav1.ListOptions) (watch.Interface, error) {
-		return duck.NewProxyWatcher(unstructuredCh), nil
+		return watch.NewProxyWatcher(unstructuredCh), nil
 	}
 
 	wf := duck.AsStructuredWatcher(nwf, &duckv1alpha1.AddressableType{})
@@ -197,7 +197,7 @@ func TestAsStructuredWatcherPassThru(t *testing.T) {
 func TestAsStructuredWatcherPassThruErrors(t *testing.T) {
 	unstructuredCh := make(chan watch.Event)
 	nwf := func(lo metav1.ListOptions) (watch.Interface, error) {
-		return duck.NewProxyWatcher(unstructuredCh), nil
+		return watch.NewProxyWatcher(unstructuredCh), nil
 	}
 
 	wf := duck.AsStructuredWatcher(nwf, &duckv1alpha1.AddressableType{})
@@ -234,7 +234,7 @@ func TestAsStructuredWatcherPassThruErrors(t *testing.T) {
 func TestAsStructuredWatcherErrorConverting(t *testing.T) {
 	unstructuredCh := make(chan watch.Event)
 	nwf := func(lo metav1.ListOptions) (watch.Interface, error) {
-		return duck.NewProxyWatcher(unstructuredCh), nil
+		return watch.NewProxyWatcher(unstructuredCh), nil
 	}
 
 	wf := duck.AsStructuredWatcher(nwf, &badObject{})
diff --git a/metrics/metricstest/resource_metrics.go b/metrics/metricstest/resource_metrics.go
index eeaeda6d7..f9cd6139f 100644
--- a/metrics/metricstest/resource_metrics.go
+++ b/metrics/metricstest/resource_metrics.go
@@ -30,6 +30,7 @@ import (
 	"go.opencensus.io/metric/metricdata"
 	"go.opencensus.io/metric/metricproducer"
 	"go.opencensus.io/resource"
+	"go.opencensus.io/stats/view"
 )
 
 // Value provides a simplified implementation of a metric Value suitable for
@@ -102,6 +103,18 @@ func NewMetric(metric *metricdata.Metric) Metric {
 	return value
 }
 
+// EnsureRecorded makes sure that all stats metrics are actually flushed and recorded.
+func EnsureRecorded() {
+	// stats.Record queues the actual record to a channel to be accounted for by
+	// a background goroutine (nonblocking). Call a method which does a
+	// round-trip to that goroutine to ensure that records have been flushed.
+	for _, producer := range metricproducer.GlobalManager().GetAll() {
+		if meter, ok := producer.(view.Meter); ok {
+			meter.Find("nonexistent")
+		}
+	}
+}
+
 // GetMetric returns all values for the named metric.
 func GetMetric(name string) []Metric {
 	producers := metricproducer.GlobalManager().GetAll()
@@ -152,31 +165,37 @@ func FloatMetric(name string, value float64, keyvalues ...string) Metric {
 	return genericMetricFactory(name, Value{Float64: &value}, keyvalues...)
 }
 
-// AssertMetric verifies that the metrics have the specified values.
+// AssertMetric verifies that the metrics have the specified values. Note that
+// this method will spuriously fail if there are multiple metrics with the same
+// name on different Meters. Calls EnsureRecorded internally before fetching the
+// batch of metrics.
 func AssertMetric(t *testing.T, values ...Metric) {
 	t.Helper()
+	EnsureRecorded()
 	for _, v := range values {
 		if diff := cmp.Diff(v, GetOneMetric(v.Name)); diff != "" {
-			t.Errorf("Wrong adds (-want +got): %s", diff)
+			t.Errorf("Wrong metric (-want +got): %s", diff)
 		}
 	}
 }
 
 // AssertMetricExists verifies that at least one metric values has been reported for
 // each of metric names.
+// Calls EnsureRecorded internally before fetching the batch of metrics.
 func AssertMetricExists(t *testing.T, names ...string) {
-	t.Helper()
-	for _, name := range names {
-		if len(GetMetric(name)) == 0 {
-			t.Errorf("No metrics found for %q", name)
-		}
+	metrics := make([]Metric, 0, len(names))
+	for _, n := range names {
+		metrics = append(metrics, Metric{Name: n})
 	}
+	AssertMetric(t, metrics...)
 }
 
 // AssertNoMetric verifies that no metrics have been reported for any of the
 // metric names.
+// Calls EnsureRecorded internally before fetching the batch of metrics.
 func AssertNoMetric(t *testing.T, names ...string) {
 	t.Helper()
+	EnsureRecorded()
 	for _, name := range names {
 		if m := GetMetric(name); len(m) != 0 {
 			t.Error("Found unexpected data for:", m)
diff --git a/metrics/metricstest/resource_metrics_test.go b/metrics/metricstest/resource_metrics_test.go
index d8c5a7c42..475a51ddb 100644
--- a/metrics/metricstest/resource_metrics_test.go
+++ b/metrics/metricstest/resource_metrics_test.go
@@ -21,12 +21,16 @@ limitations under the License.
 package metricstest
 
 import (
+	"context"
 	"testing"
 	"time"
 
 	"github.com/google/go-cmp/cmp"
 	"go.opencensus.io/metric/metricdata"
 	"go.opencensus.io/resource"
+	"go.opencensus.io/stats"
+	"go.opencensus.io/stats/view"
+	"go.opencensus.io/tag"
 )
 
 func TestMetricEqual(t *testing.T) {
@@ -315,3 +319,53 @@ func TestMetricShortcuts(t *testing.T) {
 		}
 	}
 }
+
+func TestMetricFetch(t *testing.T) {
+	count := stats.Int64("count", "Test count metric", stats.UnitBytes)
+	tagKey := tag.MustNewKey("tag")
+	countView := &view.View{
+		Measure:     count,
+		Aggregation: view.Sum(),
+		TagKeys:     []tag.Key{tagKey},
+	}
+
+	view.Register(countView)
+
+	ctx, err := tag.New(context.Background(), tag.Upsert(tagKey, "alpha"))
+	if err != nil {
+		t.Errorf("Unable to create context: %v", err)
+	}
+	stats.Record(ctx, count.M(5))
+	stats.Record(ctx, count.M(3))
+
+	AssertMetricExists(t, "count")
+	AssertNoMetric(t, "other")
+
+	ctx, err = tag.New(ctx, tag.Upsert(tagKey, "beta"))
+	if err != nil {
+		t.Errorf("Unable to create context: %v", err)
+	}
+	stats.Record(ctx, count.M(20))
+	EnsureRecorded()
+	m := GetMetric("count")
+
+	if len(m) != 1 {
+		t.Errorf("Unexpected number of found metrics (%d): %+v", len(m), m)
+	}
+
+	alphaValue, betaValue := int64(8), int64(20)
+
+	want := Metric{
+		Name: "count",
+		Type: metricdata.TypeCumulativeInt64,
+		Unit: metricdata.UnitBytes,
+		Values: []Value{
+			{Tags: map[string]string{"tag": "alpha"}, Int64: &alphaValue},
+			{Tags: map[string]string{"tag": "beta"}, Int64: &betaValue},
+		},
+	}
+	if diff := cmp.Diff(want, m[0]); diff != "" {
+		t.Errorf("Incorrect received metrics (-want +got): %s", diff)
+	}
+
+}
diff --git a/metrics/resource_view_test.go b/metrics/resource_view_test.go
index ee9bae531..23f73778d 100644
--- a/metrics/resource_view_test.go
+++ b/metrics/resource_view_test.go
@@ -47,6 +47,7 @@ import (
 	"google.golang.org/grpc"
 	logtesting "knative.dev/pkg/logging/testing"
 	"knative.dev/pkg/metrics/metricskey"
+	"knative.dev/pkg/metrics/metricstest"
 	//_ "knative.dev/pkg/metrics/testing"
 )
 
@@ -295,6 +296,7 @@ func TestMetricsExport(t *testing.T) {
 			return UpdateExporter(configForBackend(prometheus), logtesting.TestLogger(t))
 		},
 		validate: func(t *testing.T) {
+			metricstest.EnsureRecorded()
 			resp, err := http.Get(fmt.Sprintf("http://localhost:%d/metrics", prometheusPort))
 			if err != nil {
 				t.Fatalf("failed to fetch prometheus metrics: %+v", err)
diff --git a/metrics/workqueue_test.go b/metrics/workqueue_test.go
index aeed80e3d..4bca14f3e 100644
--- a/metrics/workqueue_test.go
+++ b/metrics/workqueue_test.go
@@ -49,13 +49,6 @@ func (f *fixedRateLimiter) NumRequeues(item interface{}) int {
 	return 0
 }
 
-func ensureRecorded() {
-	// stats.Record queues the actual record to a channel to be accounted for by
-	// a background goroutine (nonblocking). Call a method which does a
-	// round-trip to that goroutine to ensure that records have been flushed.
-	view.Find("nonexistent")
-}
-
 func TestWorkqueueMetrics(t *testing.T) {
 	wp := &WorkqueueProvider{
 		Adds:                           newInt64("adds"),
@@ -88,7 +81,6 @@ func TestWorkqueueMetrics(t *testing.T) {
 		"unfinished_work_seconds", "longest_running_processor_seconds")
 
 	wq.Add("foo")
-	ensureRecorded()
 
 	metricstest.AssertMetricExists(t, "adds", "depth")
 	metricstest.AssertNoMetric(t, "latency", "retries", "work_duration",
@@ -98,7 +90,6 @@ func TestWorkqueueMetrics(t *testing.T) {
 	metricstest.AssertMetric(t, wantAdd, wantDepth)
 
 	wq.Add("bar")
-	ensureRecorded()
 
 	metricstest.AssertNoMetric(t, "latency", "retries", "work_duration",
 		"unfinished_work_seconds", "longest_running_processor_seconds")
@@ -114,7 +105,6 @@ func TestWorkqueueMetrics(t *testing.T) {
 		wq.Forget(got)
 		wq.Done(got)
 	}
-	ensureRecorded()
 
 	metricstest.AssertMetricExists(t, "latency", "work_duration")
 	metricstest.AssertNoMetric(t, "retries",
@@ -129,7 +119,6 @@ func TestWorkqueueMetrics(t *testing.T) {
 		wq.AddRateLimited(got)
 		wq.Done(got)
 	}
-	ensureRecorded()
 
 	// It should show up as a retry now.
 	metricstest.AssertMetricExists(t, "retries")
diff --git a/ptr/ptr_test.go b/ptr/ptr_test.go
index 3555edf2e..f4be88bbc 100644
--- a/ptr/ptr_test.go
+++ b/ptr/ptr_test.go
@@ -21,9 +21,8 @@ import (
 	"time"
 )
 
-const want = 55
-
 func TestInt32(t *testing.T) {
+	const want = 55
 	gotPtr := Int32(want)
 	if want != *gotPtr {
 		t.Errorf("Int32() = &%v, wanted %v", *gotPtr, want)
@@ -31,12 +30,29 @@ func TestInt32(t *testing.T) {
 }
 
 func TestInt64(t *testing.T) {
+	const want = 55
 	gotPtr := Int64(want)
 	if want != *gotPtr {
 		t.Errorf("Int64() = &%v, wanted %v", *gotPtr, want)
 	}
 }
 
+func TestFloat32(t *testing.T) {
+	const want = 1.25
+	gotPtr := Float32(want)
+	if want != *gotPtr {
+		t.Errorf("Float32() = &%v, wanted %v", *gotPtr, want)
+	}
+}
+
+func TestFloat64(t *testing.T) {
+	const want = 1.25
+	gotPtr := Float64(want)
+	if want != *gotPtr {
+		t.Errorf("Float64() = &%v, wanted %v", *gotPtr, want)
+	}
+}
+
 func TestBool(t *testing.T) {
 	const want = true
 	gotPtr := Bool(want)