Repository: knative/serving
Pull request #8965 (2020-08-07 21:59:53)

Use a super long KIngress timeout.
<!--
Request Prow to automatically lint any go code in this PR:

/lint
-->

Before https://github.com/knative/networking/pull/64 we used a default value in the KIngress timeout settings. However, that does not work well with gRPC streaming timeout, so we stop the defaulting going forward.

However, that is a breaking change for KIngress implementations. It broke Contour, and breaks Gloo.

In order to give the Ingress implementers to have time to implement this `no timeout` behavior we will specify a high timeout value in Route controller in the mean time.


<!-- Please include the 'why' behind your changes if no issue exists -->
## Proposed Changes
* Set a long timeout in the Route controller.

**Release Note**

<!-- Enter your extended release note in the below block. If the PR requires
additional action from users switching to the new release, include the string
"action required". If no release note is required, write "NONE". -->

```release-note
NONE
```


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

This pull-request has been approved by: *<a href="https://github.com/knative/serving/pull/8965#" title="Author self-approved">tcnghia</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:

- ~~[pkg/reconciler/route/OWNERS](https://github.com/knative/serving/blob/master/pkg/reconciler/route/OWNERS)~~ [tcnghia]

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-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/reconciler/route/resources/ingress.go](https://storage.cloud.google.com/knative-prow/pr-logs/pull/knative_serving/8965/pull-knative-serving-go-coverage/1291856728295477250/artifacts/line-cov.html#file0) | 100.0% | 98.6% | -1.4

knative-prow-robot: @tcnghia: The following test **failed**, say `/retest` to rerun all failed tests:

Test name | Commit | Details | Rerun command
--- | --- | --- | ---
pull-knative-serving-unit-tests | 63747b37c1c0f4062df720a1799cd1cf9abea8a5 | [link](https://prow.knative.dev/view/gs/knative-prow/pr-logs/pull/knative_serving/8965/pull-knative-serving-unit-tests/1291856728295477252) | `/test pull-knative-serving-unit-tests`

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

<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]63747b37c1c0f4062df720a1799cd1cf9abea8a5[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/route.TestNewRouteCallsSyncHandler
```
mattmoor: /test pull-knative-serving-contour-latest
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/reconciler/route/resources/ingress.go](https://storage.cloud.google.com/knative-prow/pr-logs/pull/knative_serving/8965/pull-knative-serving-go-coverage/1291862516061704195/artifacts/line-cov.html#file0) | 100.0% | 98.6% | -1.4

mattmoor: /test pull-knative-serving-contour-latest

knative-prow-robot: @tcnghia: The following test **failed**, say `/retest` to rerun all failed tests:

Test name | Commit | Details | Rerun command
--- | --- | --- | ---
pull-knative-serving-integration-tests | 9cbb8dcf9a31943301e2a797997a4daaf74b9fbe | [link](https://prow.knative.dev/view/gs/knative-prow/pr-logs/pull/knative_serving/8965/pull-knative-serving-integration-tests/1291862516061704192) | `/test pull-knative-serving-integration-tests`

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

<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]9cbb8dcf9a31943301e2a797997a4daaf74b9fbe[AUTOMATED-FLAKY-RETRYER]-->
The following jobs failed:

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

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

```
test/conformance/api/v1alpha1.TestContainerExitingMsg
test/conformance/api/v1beta1.TestContainerExitingMsg
test/e2e.TestRouteVisibilityChanges
```
tcnghia: /test pull-knative-serving-integration-tests
knative-prow-robot: @tcnghia: The following tests **failed**, say `/retest` to rerun all failed tests:

Test name | Commit | Details | Rerun command
--- | --- | --- | ---
pull-knative-serving-integration-tests | 9cbb8dcf9a31943301e2a797997a4daaf74b9fbe | [link](https://prow.knative.dev/view/gs/knative-prow/pr-logs/pull/knative_serving/8965/pull-knative-serving-integration-tests/1291862516061704192) | `/test pull-knative-serving-integration-tests`
pull-knative-serving-contour-latest | 9cbb8dcf9a31943301e2a797997a4daaf74b9fbe | [link](https://prow.knative.dev/view/gs/knative-prow/pr-logs/pull/knative_serving/8965/pull-knative-serving-contour-latest/1291868178363715585) | `/test pull-knative-serving-contour-latest`

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

<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 -->

Patch:
diff --git a/config/core/configmaps/features.yaml b/config/core/configmaps/features.yaml
index 3fd5c2cd5..68143dad1 100644
--- a/config/core/configmaps/features.yaml
+++ b/config/core/configmaps/features.yaml
@@ -20,7 +20,7 @@ metadata:
   labels:
     serving.knative.dev/release: devel
   annotations:
-    knative.dev/example-checksum: "ab930d35"
+    knative.dev/example-checksum: "66de029c"
 data:
   _example: |
     ################################
@@ -39,7 +39,7 @@ data:
     # to actually change the configuration.
 
     # Indicates whether multi container support is enabled
-    multi-container: "disabled"
+    multi-container: "enabled"
 
     # Indicates whether Kubernetes affinity support is enabled
     kubernetes.podspec-affinity: "disabled"
diff --git a/go.mod b/go.mod
index 4b3c9dcd5..602738c78 100644
--- a/go.mod
+++ b/go.mod
@@ -36,9 +36,9 @@ require (
 	k8s.io/code-generator v0.18.6
 	k8s.io/kube-openapi v0.0.0-20200410145947-bcb3869e6f29
 	knative.dev/caching v0.0.0-20200806150829-1f9e3d92b7bf
-	knative.dev/networking v0.0.0-20200805173129-ef35174c9ced
-	knative.dev/pkg v0.0.0-20200806022228-2aae6f373dda
-	knative.dev/test-infra v0.0.0-20200803175002-5efff0c4bd0a
+	knative.dev/networking v0.0.0-20200806231028-6309580426f4
+	knative.dev/pkg v0.0.0-20200806230728-62f2560aa795
+	knative.dev/test-infra v0.0.0-20200806191129-68b7defbd189
 )
 
 replace (
diff --git a/go.sum b/go.sum
index 574c7bece..4706f6f34 100644
--- a/go.sum
+++ b/go.sum
@@ -1800,8 +1800,8 @@ knative.dev/caching v0.0.0-20200806150829-1f9e3d92b7bf h1:s8CDt9lmXvcMugKZ5VlWmk
 knative.dev/caching v0.0.0-20200806150829-1f9e3d92b7bf/go.mod h1:m7OQVFAzw/z8KpZrgHJpzy8DxcMysjOLezEs59v4vpM=
 knative.dev/eventing-contrib v0.6.1-0.20190723221543-5ce18048c08b/go.mod h1:SnXZgSGgMSMLNFTwTnpaOH7hXDzTFtw0J8OmHflNx3g=
 knative.dev/eventing-contrib v0.11.2/go.mod h1:SnXZgSGgMSMLNFTwTnpaOH7hXDzTFtw0J8OmHflNx3g=
-knative.dev/networking v0.0.0-20200805173129-ef35174c9ced h1:+2JY9pZiYbpOe0fw2x44xU4zgBEjjWpq67FgvZzzNL4=
-knative.dev/networking v0.0.0-20200805173129-ef35174c9ced/go.mod h1:BhckoJZMxtO8VWsVazJng1YizTP2iLH2R6V9Yhf4OqE=
+knative.dev/networking v0.0.0-20200806231028-6309580426f4 h1:4caIwEqzCzD4E8SFkB4Mb2cZst3GjLz94yqApcXlagg=
+knative.dev/networking v0.0.0-20200806231028-6309580426f4/go.mod h1:HYtMYqF9RVAfg5HCt6jz0J63743g4AMj7Fa6lKrZtuE=
 knative.dev/pkg v0.0.0-20191101194912-56c2594e4f11/go.mod h1:pgODObA1dTyhNoFxPZTTjNWfx6F0aKsKzn+vaT9XO/Q=
 knative.dev/pkg v0.0.0-20191111150521-6d806b998379/go.mod h1:pgODObA1dTyhNoFxPZTTjNWfx6F0aKsKzn+vaT9XO/Q=
 knative.dev/pkg v0.0.0-20200207155214-fef852970f43/go.mod h1:pgODObA1dTyhNoFxPZTTjNWfx6F0aKsKzn+vaT9XO/Q=
@@ -1810,10 +1810,10 @@ knative.dev/pkg v0.0.0-20200505191044-3da93ebb24c2/go.mod h1:Q6sL35DdGs8hIQZKdaC
 knative.dev/pkg v0.0.0-20200515002500-16d7b963416f/go.mod h1:tMOHGbxtRz8zYFGEGpV/bpoTEM1o89MwYFC4YJXl3GY=
 knative.dev/pkg v0.0.0-20200528142800-1c6815d7e4c9/go.mod h1:QgNZTxnwpB/oSpNcfnLVlw+WpEwwyKAvJlvR3hgeltA=
 knative.dev/pkg v0.0.0-20200711004937-22502028e31a/go.mod h1:AqAJV6rYi8IGikDjJ/9ZQd9qKdkXVlesVnVjwx62YB8=
-knative.dev/pkg v0.0.0-20200805045628-bb91a15b1a18 h1:ywpZa098+kSsHZe8aGjJkgzjcZUOLWgao+rGE6OW6rY=
-knative.dev/pkg v0.0.0-20200805045628-bb91a15b1a18/go.mod h1:0y8OGCR6F0bIaIT+pK8NXE/KtqfeXKAzDW56t7T0ENk=
 knative.dev/pkg v0.0.0-20200806022228-2aae6f373dda h1:lQEtosYg5+6F37MVx3FQYVRwUaz3Ie2xpzhz2yOdvfo=
 knative.dev/pkg v0.0.0-20200806022228-2aae6f373dda/go.mod h1:0y8OGCR6F0bIaIT+pK8NXE/KtqfeXKAzDW56t7T0ENk=
+knative.dev/pkg v0.0.0-20200806230728-62f2560aa795 h1:7WSZvSc8SR2xLCjBUp5S0dg9e1AySM/xmOdpLGOMAtI=
+knative.dev/pkg v0.0.0-20200806230728-62f2560aa795/go.mod h1:0y8OGCR6F0bIaIT+pK8NXE/KtqfeXKAzDW56t7T0ENk=
 knative.dev/test-infra v0.0.0-20200407185800-1b88cb3b45a5/go.mod h1:xcdUkMJrLlBswIZqL5zCuBFOC22WIPMQoVX1L35i0vQ=
 knative.dev/test-infra v0.0.0-20200505052144-5ea2f705bb55/go.mod h1:WqF1Azka+FxPZ20keR2zCNtiQA1MP9ZB4BH4HuI+SIU=
 knative.dev/test-infra v0.0.0-20200513011557-d03429a76034/go.mod h1:aMif0KXL4g19YCYwsy4Ocjjz5xgPlseYV+B95Oo4JGE=
@@ -1821,6 +1821,8 @@ knative.dev/test-infra v0.0.0-20200519015156-82551620b0a9/go.mod h1:A5b2OAXTOeHT
 knative.dev/test-infra v0.0.0-20200707183444-aed09e56ddc7/go.mod h1:RjYAhXnZqeHw9+B0zsbqSPlae0lCvjekO/nw5ZMpLCs=
 knative.dev/test-infra v0.0.0-20200803175002-5efff0c4bd0a h1:0woae+DQoLaB8PBL1V2LKoPVOm3rldG4G1HYGROo1bo=
 knative.dev/test-infra v0.0.0-20200803175002-5efff0c4bd0a/go.mod h1:Pmg2c7Z7q7BGFUV/GOpU5BlrD3ePJft4MPqx8AYBplc=
+knative.dev/test-infra v0.0.0-20200806191129-68b7defbd189 h1:PkTuK9kgtsdwrIxUAmaCmDwfRKBoXujiqNRDWO1r8cc=
+knative.dev/test-infra v0.0.0-20200806191129-68b7defbd189/go.mod h1:Pmg2c7Z7q7BGFUV/GOpU5BlrD3ePJft4MPqx8AYBplc=
 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/apis/config/features.go b/pkg/apis/config/features.go
index bd33649d2..7f4a3650c 100644
--- a/pkg/apis/config/features.go
+++ b/pkg/apis/config/features.go
@@ -40,7 +40,7 @@ const (
 
 func defaultFeaturesConfig() *Features {
 	return &Features{
-		MultiContainer:       Disabled,
+		MultiContainer:       Enabled,
 		PodSpecAffinity:      Disabled,
 		PodSpecFieldRef:      Disabled,
 		PodSpecDryRun:        Allowed,
diff --git a/pkg/apis/serving/v1/revision_lifecycle.go b/pkg/apis/serving/v1/revision_lifecycle.go
index fcbf1e446..0130bf30a 100644
--- a/pkg/apis/serving/v1/revision_lifecycle.go
+++ b/pkg/apis/serving/v1/revision_lifecycle.go
@@ -171,7 +171,10 @@ func (rs *RevisionStatus) PropagateAutoscalerStatus(ps *av1alpha1.PodAutoscalerS
 		return
 	}
 
-	if ps.IsScaleTargetInitialized() {
+	// Don't mark the resources available, if deployment status already determined
+	// it isn't so.
+	resUnavailable := !rs.GetCondition(RevisionConditionResourcesAvailable).IsFalse()
+	if ps.IsScaleTargetInitialized() && resUnavailable {
 		// Precondition for PA being initialized is SKS being active and
 		// that implies that |service.endpoints| > 0.
 		rs.MarkResourcesAvailableTrue()
@@ -192,7 +195,7 @@ func (rs *RevisionStatus) PropagateAutoscalerStatus(ps *av1alpha1.PodAutoscalerS
 		// Progress status to become `true`, since successful scale down means
 		// progress has been achieved.
 		// If the ResourcesAvailable is already false, don't override the message.
-		if !ps.IsScaleTargetInitialized() && !rs.GetCondition(RevisionConditionResourcesAvailable).IsFalse() {
+		if !ps.IsScaleTargetInitialized() && resUnavailable {
 			rs.MarkResourcesAvailableFalse(ReasonProgressDeadlineExceeded,
 				"Initial scale was never achieved")
 		}
diff --git a/pkg/reconciler/autoscaling/kpa/scaler.go b/pkg/reconciler/autoscaling/kpa/scaler.go
index 11f231986..c19d99bf7 100644
--- a/pkg/reconciler/autoscaling/kpa/scaler.go
+++ b/pkg/reconciler/autoscaling/kpa/scaler.go
@@ -61,7 +61,7 @@ const (
 	// the Revision to re-reconcile and diagnose pod failures. If we use the same timeout here, we will
 	// race the Revision reconciler and scale down the pods before it can actually surface the pod errors.
 	// We should instead do pod failure diagnostics here immediately before scaling down the Deployment.
-	activationTimeoutBuffer = 10 * time.Second
+	activationTimeoutBuffer = 30 * time.Second
 )
 
 var probeOptions = []interface{}{
diff --git a/pkg/reconciler/revision/reconcile_resources.go b/pkg/reconciler/revision/reconcile_resources.go
index 57912b412..040f36053 100644
--- a/pkg/reconciler/revision/reconcile_resources.go
+++ b/pkg/reconciler/revision/reconcile_resources.go
@@ -82,11 +82,13 @@ func (c *Reconciler) reconcileDeployment(ctx context.Context, rev *v1.Revision)
 		pods, err := c.kubeclient.CoreV1().Pods(ns).List(metav1.ListOptions{LabelSelector: metav1.FormatLabelSelector(deployment.Spec.Selector)})
 		if err != nil {
 			logger.Errorw("Error getting pods", zap.Error(err))
-		} else if len(pods.Items) > 0 {
+			return nil
+		}
+		if len(pods.Items) > 0 {
 			// Arbitrarily grab the very first pod, as they all should be crashing
 			pod := pods.Items[0]
 
-			// Update the revision status if pod cannot be scheduled(possibly resource constraints)
+			// Update the revision status if pod cannot be scheduled (possibly resource constraints)
 			// If pod cannot be scheduled then we expect the container status to be empty.
 			for _, cond := range pod.Status.Conditions {
 				if cond.Type == corev1.PodScheduled && cond.Status == corev1.ConditionFalse {
diff --git a/pkg/reconciler/route/resources/ingress.go b/pkg/reconciler/route/resources/ingress.go
index 641025a83..9f5608462 100644
--- a/pkg/reconciler/route/resources/ingress.go
+++ b/pkg/reconciler/route/resources/ingress.go
@@ -19,6 +19,7 @@ package resources
 import (
 	"context"
 	"sort"
+	"time"
 
 	corev1 "k8s.io/api/core/v1"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
@@ -29,6 +30,7 @@ import (
 	netv1alpha1 "knative.dev/networking/pkg/apis/networking/v1alpha1"
 	"knative.dev/pkg/kmeta"
 	"knative.dev/serving/pkg/activator"
+	defaults "knative.dev/serving/pkg/apis/config"
 	"knative.dev/serving/pkg/apis/serving"
 	servingv1 "knative.dev/serving/pkg/apis/serving/v1"
 	"knative.dev/serving/pkg/reconciler/route/config"
@@ -114,7 +116,7 @@ func MakeIngressSpec(
 			if err != nil {
 				return netv1alpha1.IngressSpec{}, err
 			}
-			rule := makeIngressRule([]string{domain}, r.Namespace, visibility, targets[name])
+			rule := makeIngressRule(ctx, []string{domain}, r.Namespace, visibility, targets[name])
 			if networkConfig.TagHeaderBasedRouting {
 				if rule.HTTP.Paths[0].AppendHeaders == nil {
 					rule.HTTP.Paths[0].AppendHeaders = make(map[string]string)
@@ -130,7 +132,7 @@ func MakeIngressSpec(
 					// If a request has one of the `names`(tag name) except the default path,
 					// the request will be routed via one of the ingress paths, corresponding to the tag name.
 					rule.HTTP.Paths = append(
-						makeTagBasedRoutingIngressPaths(r.Namespace, targets, names), rule.HTTP.Paths...)
+						makeTagBasedRoutingIngressPaths(ctx, r.Namespace, targets, names), rule.HTTP.Paths...)
 				} else {
 					// If a request is routed by a tag-attached hostname instead of the tag header,
 					// the request may not have the tag header "Knative-Serving-Tag",
@@ -203,25 +205,27 @@ func makeACMEIngressPaths(challenges map[string]netv1alpha1.HTTP01Challenge, dom
 	return paths
 }
 
-func makeIngressRule(domains []string, ns string,
+func makeIngressRule(ctx context.Context,
+	domains []string, ns string,
 	visibility netv1alpha1.IngressVisibility, targets traffic.RevisionTargets) netv1alpha1.IngressRule {
 	return netv1alpha1.IngressRule{
 		Hosts:      domains,
 		Visibility: visibility,
 		HTTP: &netv1alpha1.HTTPIngressRuleValue{
 			Paths: []netv1alpha1.HTTPIngressPath{
-				*makeBaseIngressPath(ns, targets),
+				*makeBaseIngressPath(ctx, ns, targets),
 			},
 		},
 	}
 }
 
-func makeTagBasedRoutingIngressPaths(ns string, targets map[string]traffic.RevisionTargets, names []string) []netv1alpha1.HTTPIngressPath {
+func makeTagBasedRoutingIngressPaths(
+	ctx context.Context, ns string, targets map[string]traffic.RevisionTargets, names []string) []netv1alpha1.HTTPIngressPath {
 	paths := make([]netv1alpha1.HTTPIngressPath, 0, len(names))
 
 	for _, name := range names {
 		if name != traffic.DefaultTarget {
-			path := makeBaseIngressPath(ns, targets[name])
+			path := makeBaseIngressPath(ctx, ns, targets[name])
 			path.Headers = map[string]netv1alpha1.HeaderMatch{network.TagHeaderName: {Exact: name}}
 			paths = append(paths, *path)
 		}
@@ -230,7 +234,8 @@ func makeTagBasedRoutingIngressPaths(ns string, targets map[string]traffic.Revis
 	return paths
 }
 
-func makeBaseIngressPath(ns string, targets traffic.RevisionTargets) *netv1alpha1.HTTPIngressPath {
+func makeBaseIngressPath(
+	ctx context.Context, ns string, targets traffic.RevisionTargets) *netv1alpha1.HTTPIngressPath {
 	// Optimistically allocate |targets| elements.
 	splits := make([]netv1alpha1.IngressBackendSplit, 0, len(targets))
 	for _, t := range targets {
@@ -256,6 +261,36 @@ func makeBaseIngressPath(ns string, targets traffic.RevisionTargets) *netv1alpha
 
 	return &netv1alpha1.HTTPIngressPath{
 		Splits: splits,
-		// TODO(lichuqiang): #2201, plumbing to config timeout and retries.
+		Timeout: &metav1.Duration{
+			Duration: ingressTimeout(ctx),
+		},
+	}
+}
+
+// Before https://github.com/knative/networking/pull/64 we used a
+// default value in the KIngress timeout settings. However, that
+// does not work well with gRPC streaming timeout, so we stop the
+// defaulting going forward.
+//
+// However, that is a breaking change for KIngress
+// implementations. It broke Contour, and breaks Gloo.
+//
+// In order to give the Ingress implementers to have time to
+// implement this `no timeout` behavior we will specify a high
+// timeout value in Route controller in the mean time.
+func ingressTimeout(ctx context.Context) time.Duration {
+	// We want to set the ingress timeout to a really long timeout to
+	// helps with issues like
+	// https://github.com/knative/serving/issues/7350#issuecomment-669278261
+	longTimeout := time.Hour * 48
+
+	// However, if the MaxRevisionTimeout is longer, we should still honor that.
+	if defaults.FromContext(ctx) != nil && defaults.FromContext(ctx).Defaults != nil {
+		maxRevisionTimeout := time.Duration(
+			defaults.FromContext(ctx).Defaults.MaxRevisionTimeoutSeconds) * time.Second
+		if maxRevisionTimeout > longTimeout {
+			return maxRevisionTimeout
+		}
 	}
+	return longTimeout
 }
diff --git a/pkg/reconciler/route/route.go b/pkg/reconciler/route/route.go
index 11127aaf9..e7dd4c7ae 100644
--- a/pkg/reconciler/route/route.go
+++ b/pkg/reconciler/route/route.go
@@ -105,7 +105,7 @@ func (c *Reconciler) getServices(route *v1.Route) ([]*corev1.Service, error) {
 
 func (c *Reconciler) ReconcileKind(ctx context.Context, r *v1.Route) pkgreconciler.Event {
 	logger := logging.FromContext(ctx)
-	logger.Debugf("Reconciling route: %#v", r)
+	logger.Debugf("Reconciling route: %#v", r.Spec)
 
 	// Configure traffic based on the RouteSpec.
 	traffic, err := c.configureTraffic(ctx, r)
diff --git a/vendor/knative.dev/networking/pkg/apis/config/defaults.go b/vendor/knative.dev/networking/pkg/apis/config/defaults.go
deleted file mode 100644
index b23e4c89d..000000000
--- a/vendor/knative.dev/networking/pkg/apis/config/defaults.go
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
-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.
-*/
-
-package config
-
-import (
-	"fmt"
-
-	corev1 "k8s.io/api/core/v1"
-	"k8s.io/apimachinery/pkg/api/resource"
-
-	cm "knative.dev/pkg/configmap"
-)
-
-const (
-	// DefaultsConfigName is the name of config map for the defaults.
-	DefaultsConfigName = "config-defaults"
-
-	// DefaultRevisionTimeoutSeconds will be set if timeoutSeconds not specified.
-	DefaultRevisionTimeoutSeconds = 5 * 60
-
-	// DefaultMaxRevisionTimeoutSeconds will be set if MaxRevisionTimeoutSeconds is not specified.
-	DefaultMaxRevisionTimeoutSeconds = 10 * 60
-)
-
-func defaultConfig() *Defaults {
-	return &Defaults{
-		RevisionTimeoutSeconds:    DefaultRevisionTimeoutSeconds,
-		MaxRevisionTimeoutSeconds: DefaultMaxRevisionTimeoutSeconds,
-	}
-}
-
-// NewDefaultsConfigFromMap creates a Defaults from the supplied Map.
-func NewDefaultsConfigFromMap(data map[string]string) (*Defaults, error) {
-	nc := defaultConfig()
-
-	if err := cm.Parse(data,
-		cm.AsInt64("revision-timeout-seconds", &nc.RevisionTimeoutSeconds),
-		cm.AsInt64("max-revision-timeout-seconds", &nc.MaxRevisionTimeoutSeconds),
-	); err != nil {
-		return nil, err
-	}
-
-	if nc.RevisionTimeoutSeconds > nc.MaxRevisionTimeoutSeconds {
-		return nil, fmt.Errorf("revision-timeout-seconds (%d) cannot be greater than max-revision-timeout-seconds (%d)", nc.RevisionTimeoutSeconds, nc.MaxRevisionTimeoutSeconds)
-	}
-	return nc, nil
-}
-
-// NewDefaultsConfigFromConfigMap creates a Defaults from the supplied configMap.
-func NewDefaultsConfigFromConfigMap(config *corev1.ConfigMap) (*Defaults, error) {
-	return NewDefaultsConfigFromMap(config.Data)
-}
-
-// Defaults includes the default values to be populated by the webhook.
-type Defaults struct {
-	RevisionTimeoutSeconds int64
-	// This is the timeout set for ingress.
-	// RevisionTimeoutSeconds must be less than this value.
-	MaxRevisionTimeoutSeconds int64
-}
-
-// asQuantity parses the value at key as a *resource.Quantity into the target, if it exists.
-func asQuantity(key string, target **resource.Quantity) cm.ParseFunc {
-	return func(data map[string]string) error {
-		if raw, ok := data[key]; !ok {
-			*target = nil
-		} else if val, err := resource.ParseQuantity(raw); err != nil {
-			return err
-		} else {
-			*target = &val
-		}
-		return nil
-	}
-}
diff --git a/vendor/knative.dev/networking/pkg/apis/config/doc.go b/vendor/knative.dev/networking/pkg/apis/config/doc.go
deleted file mode 100644
index a0d4319ef..000000000
--- a/vendor/knative.dev/networking/pkg/apis/config/doc.go
+++ /dev/null
@@ -1,21 +0,0 @@
-/*
-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.
-*/
-
-// +k8s:deepcopy-gen=package
-
-// Package config holds the typed objects that define the schemas for
-// ConfigMap objects that pertain to our API objects.
-package config
diff --git a/vendor/knative.dev/networking/pkg/apis/config/store.go b/vendor/knative.dev/networking/pkg/apis/config/store.go
deleted file mode 100644
index a0dfc8645..000000000
--- a/vendor/knative.dev/networking/pkg/apis/config/store.go
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
-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 config
-
-import (
-	"context"
-
-	"knative.dev/pkg/configmap"
-)
-
-type cfgKey struct{}
-
-// Config holds the collection of configurations that we attach to contexts.
-// +k8s:deepcopy-gen=false
-type Config struct {
-	Defaults *Defaults
-}
-
-// FromContext extracts a Config from the provided context.
-func FromContext(ctx context.Context) *Config {
-	x, ok := ctx.Value(cfgKey{}).(*Config)
-	if ok {
-		return x
-	}
-	return nil
-}
-
-// FromContextOrDefaults is like FromContext, but when no Config is attached it
-// returns a Config populated with the defaults for each of the Config fields.
-func FromContextOrDefaults(ctx context.Context) *Config {
-	if cfg := FromContext(ctx); cfg != nil {
-		return cfg
-	}
-	defaults, _ := NewDefaultsConfigFromMap(map[string]string{})
-	return &Config{
-		Defaults: defaults,
-	}
-}
-
-// ToContext attaches the provided Config to the provided context, returning the
-// new context with the Config attached.
-func ToContext(ctx context.Context, c *Config) context.Context {
-	return context.WithValue(ctx, cfgKey{}, c)
-}
-
-// Store is a typed wrapper around configmap.Untyped store to handle our configmaps.
-// +k8s:deepcopy-gen=false
-type Store struct {
-	*configmap.UntypedStore
-}
-
-// NewStore creates a new store of Configs and optionally calls functions when ConfigMaps are updated.
-func NewStore(logger configmap.Logger, onAfterStore ...func(name string, value interface{})) *Store {
-	store := &Store{
-		UntypedStore: configmap.NewUntypedStore(
-			"defaults",
-			logger,
-			configmap.Constructors{
-				DefaultsConfigName: NewDefaultsConfigFromConfigMap,
-			},
-			onAfterStore...,
-		),
-	}
-
-	return store
-}
-
-// ToContext attaches the current Config state to the provided context.
-func (s *Store) ToContext(ctx context.Context) context.Context {
-	return ToContext(ctx, s.Load())
-}
-
-// Load creates a Config from the current config state of the Store.
-func (s *Store) Load() *Config {
-	return &Config{
-		Defaults: s.UntypedLoad(DefaultsConfigName).(*Defaults).DeepCopy(),
-	}
-}
diff --git a/vendor/knative.dev/networking/pkg/apis/config/zz_generated.deepcopy.go b/vendor/knative.dev/networking/pkg/apis/config/zz_generated.deepcopy.go
deleted file mode 100644
index 5169897dd..000000000
--- a/vendor/knative.dev/networking/pkg/apis/config/zz_generated.deepcopy.go
+++ /dev/null
@@ -1,37 +0,0 @@
-// +build !ignore_autogenerated
-
-/*
-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.
-*/
-
-// Code generated by deepcopy-gen. DO NOT EDIT.
-
-package config
-
-// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
-func (in *Defaults) DeepCopyInto(out *Defaults) {
-	*out = *in
-	return
-}
-
-// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Defaults.
-func (in *Defaults) DeepCopy() *Defaults {
-	if in == nil {
-		return nil
-	}
-	out := new(Defaults)
-	in.DeepCopyInto(out)
-	return out
-}
diff --git a/vendor/knative.dev/networking/pkg/apis/networking/v1alpha1/ingress_defaults.go b/vendor/knative.dev/networking/pkg/apis/networking/v1alpha1/ingress_defaults.go
index eeee8a36e..4e3b40362 100644
--- a/vendor/knative.dev/networking/pkg/apis/networking/v1alpha1/ingress_defaults.go
+++ b/vendor/knative.dev/networking/pkg/apis/networking/v1alpha1/ingress_defaults.go
@@ -18,12 +18,8 @@ package v1alpha1
 
 import (
 	"context"
-	"time"
 
-	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 	"knative.dev/pkg/apis"
-
-	"knative.dev/networking/pkg/apis/config"
 )
 
 // SetDefaults populates default values in Ingress
@@ -69,11 +65,4 @@ func (p *HTTPIngressPath) SetDefaults(ctx context.Context) {
 	if len(p.Splits) == 1 && p.Splits[0].Percent == 0 {
 		p.Splits[0].Percent = 100
 	}
-
-	cfg := config.FromContextOrDefaults(ctx)
-	maxTimeout := time.Duration(cfg.Defaults.MaxRevisionTimeoutSeconds) * time.Second
-
-	if p.Timeout == nil {
-		p.Timeout = &metav1.Duration{Duration: maxTimeout}
-	}
 }
diff --git a/vendor/knative.dev/pkg/controller/controller.go b/vendor/knative.dev/pkg/controller/controller.go
index e32db29bd..121db8567 100644
--- a/vendor/knative.dev/pkg/controller/controller.go
+++ b/vendor/knative.dev/pkg/controller/controller.go
@@ -262,7 +262,9 @@ func (c *Impl) EnqueueAfter(obj interface{}, after time.Duration) {
 // and enqueues that key in the slow lane.
 func (c *Impl) EnqueueSlowKey(key types.NamespacedName) {
 	c.workQueue.SlowLane().Add(key)
-	c.logger.Debugf("Adding to the slow queue %s (depth(total/slow): %d/%d)", safeKey(key), c.workQueue.Len(), c.workQueue.SlowLane().Len())
+	c.logger.With(zap.Object(logkey.Key, logging.NamespacedName(key))).
+		Debug("Adding to the slow queue %s (depth(total/slow): %d/%d)",
+			safeKey(key), c.workQueue.Len(), c.workQueue.SlowLane().Len())
 }
 
 // EnqueueSlow extracts namesspeced name from the object and enqueues it on the slow
@@ -388,7 +390,8 @@ func (c *Impl) EnqueueNamespaceOf(obj interface{}) {
 // EnqueueKey takes a namespace/name string and puts it onto the work queue.
 func (c *Impl) EnqueueKey(key types.NamespacedName) {
 	c.workQueue.Add(key)
-	c.logger.Debugf("Adding to queue %s (depth: %d)", safeKey(key), c.workQueue.Len())
+	c.logger.With(zap.Object(logkey.Key, logging.NamespacedName(key))).
+		Debugf("Adding to queue %s (depth: %d)", safeKey(key), c.workQueue.Len())
 }
 
 // MaybeEnqueueBucketKey takes a Bucket and namespace/name string and puts it onto
@@ -403,7 +406,8 @@ func (c *Impl) MaybeEnqueueBucketKey(bkt reconciler.Bucket, key types.Namespaced
 // the work queue after given delay.
 func (c *Impl) EnqueueKeyAfter(key types.NamespacedName, delay time.Duration) {
 	c.workQueue.AddAfter(key, delay)
-	c.logger.Debugf("Adding to queue %s (delay: %v, depth: %d)", safeKey(key), delay, c.workQueue.Len())
+	c.logger.With(zap.Object(logkey.Key, logging.NamespacedName(key))).
+		Debugf("Adding to queue %s (delay: %v, depth: %d)", safeKey(key), delay, c.workQueue.Len())
 }
 
 // RunContext starts the controller's worker threads, the number of which is threadiness.
diff --git a/vendor/knative.dev/pkg/metrics/stackdriver_exporter.go b/vendor/knative.dev/pkg/metrics/stackdriver_exporter.go
index 44ae68b68..befb95dba 100644
--- a/vendor/knative.dev/pkg/metrics/stackdriver_exporter.go
+++ b/vendor/knative.dev/pkg/metrics/stackdriver_exporter.go
@@ -21,6 +21,7 @@ import (
 	"fmt"
 	"path"
 	"sync"
+	"time"
 
 	sd "contrib.go.opencensus.io/exporter/stackdriver"
 	"go.opencensus.io/resource"
@@ -49,6 +50,8 @@ const (
 	StackdriverSecretNameDefault = "stackdriver-service-account-key"
 	// secretDataFieldKey is the name of the k8s Secret field that contains the Secret's key.
 	secretDataFieldKey = "key.json"
+	// stackdriverApiTimeout is the timeout value of Stackdriver API service side.
+	stackdriverApiTimeout = 12 * time.Second
 )
 
 var (
@@ -186,6 +189,7 @@ func newStackdriverExporter(config *metricsConfig, logger *zap.SugaredLogger) (v
 		GetMetricPrefix:         mpf,
 		ReportingInterval:       config.reportingPeriod,
 		DefaultMonitoringLabels: &sd.Labels{},
+		Timeout:                 stackdriverApiTimeout,
 	})
 	if err != nil {
 		logger.Errorw("Failed to create the Stackdriver exporter: ", zap.Error(err))
diff --git a/vendor/modules.txt b/vendor/modules.txt
index 36ddfc286..25d7a9112 100644
--- a/vendor/modules.txt
+++ b/vendor/modules.txt
@@ -1025,10 +1025,9 @@ 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-20200805173129-ef35174c9ced
+# knative.dev/networking v0.0.0-20200806231028-6309580426f4
 ## explicit
 knative.dev/networking/pkg
-knative.dev/networking/pkg/apis/config
 knative.dev/networking/pkg/apis/networking
 knative.dev/networking/pkg/apis/networking/v1alpha1
 knative.dev/networking/pkg/client/clientset/versioned
@@ -1053,7 +1052,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-20200806022228-2aae6f373dda
+# knative.dev/pkg v0.0.0-20200806230728-62f2560aa795
 ## explicit
 knative.dev/pkg/apiextensions/storageversion
 knative.dev/pkg/apiextensions/storageversion/cmd/migrate
@@ -1177,7 +1176,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-20200803175002-5efff0c4bd0a
+# knative.dev/test-infra v0.0.0-20200806191129-68b7defbd189
 ## explicit
 knative.dev/test-infra/scripts
 # sigs.k8s.io/yaml v1.2.0


Test patch:
diff --git a/pkg/apis/config/store_test.go b/pkg/apis/config/store_test.go
index 2debf2d59..624e36ce6 100644
--- a/pkg/apis/config/store_test.go
+++ b/pkg/apis/config/store_test.go
@@ -106,7 +106,7 @@ func TestStoreImmutableConfig(t *testing.T) {
 	config := store.Load()
 
 	config.Defaults.RevisionTimeoutSeconds = 1234
-	config.Features.MultiContainer = Enabled
+	config.Features.MultiContainer = Disabled
 	config.Autoscaler.TargetBurstCapacity = 99
 
 	newConfig := store.Load()
@@ -115,7 +115,7 @@ func TestStoreImmutableConfig(t *testing.T) {
 		t.Error("Defaults config is not immutable")
 	}
 
-	if newConfig.Features.MultiContainer == Enabled {
+	if newConfig.Features.MultiContainer == Disabled {
 		t.Error("Features config is not immutable")
 	}
 
diff --git a/pkg/apis/serving/k8s_validation_test.go b/pkg/apis/serving/k8s_validation_test.go
index 99b41885b..9711f0d51 100644
--- a/pkg/apis/serving/k8s_validation_test.go
+++ b/pkg/apis/serving/k8s_validation_test.go
@@ -34,9 +34,9 @@ import (
 
 type configOption func(*config.Config) *config.Config
 
-func withMultiContainerEnabled() configOption {
+func withMultiContainerDisabled() configOption {
 	return func(cfg *config.Config) *config.Config {
-		cfg.Features.MultiContainer = config.Enabled
+		cfg.Features.MultiContainer = config.Disabled
 		return cfg
 	}
 }
@@ -71,9 +71,10 @@ func withPodSpecTolerationsEnabled() configOption {
 
 func TestPodSpecValidation(t *testing.T) {
 	tests := []struct {
-		name string
-		ps   corev1.PodSpec
-		want *apis.FieldError
+		name    string
+		ps      corev1.PodSpec
+		cfgOpts []configOption
+		want    *apis.FieldError
 	}{{
 		name: "valid",
 		ps: corev1.PodSpec{
@@ -197,7 +198,8 @@ func TestPodSpecValidation(t *testing.T) {
 				Image: "helloworld",
 			}},
 		},
-		want: &apis.FieldError{Message: "multi-container is off, but found 2 containers"},
+		cfgOpts: []configOption{withMultiContainerDisabled()},
+		want:    &apis.FieldError{Message: "multi-container is off, but found 2 containers"},
 	}, {
 		name: "extra field",
 		ps: corev1.PodSpec{
@@ -222,7 +224,15 @@ func TestPodSpecValidation(t *testing.T) {
 
 	for _, test := range tests {
 		t.Run(test.name, func(t *testing.T) {
-			got := ValidatePodSpec(context.Background(), test.ps)
+			ctx := context.Background()
+			if test.cfgOpts != nil {
+				cfg := config.FromContextOrDefaults(ctx)
+				for _, opt := range test.cfgOpts {
+					cfg = opt(cfg)
+				}
+				ctx = config.ToContext(ctx, cfg)
+			}
+			got := ValidatePodSpec(ctx, test.ps)
 			if diff := cmp.Diff(test.want.Error(), got.Error()); diff != "" {
 				t.Errorf("ValidatePodSpec (-want, +got): \n%s", diff)
 			}
@@ -248,7 +258,8 @@ func TestPodSpecMultiContainerValidation(t *testing.T) {
 				Image: "helloworld",
 			}},
 		},
-		want: &apis.FieldError{Message: "multi-container is off, but found 2 containers"},
+		cfgOpts: []configOption{withMultiContainerDisabled()},
+		want:    &apis.FieldError{Message: "multi-container is off, but found 2 containers"},
 	}, {
 		name: "flag enabled: more than one container with one container port",
 		ps: corev1.PodSpec{
@@ -261,8 +272,7 @@ func TestPodSpecMultiContainerValidation(t *testing.T) {
 				Image: "helloworld",
 			}},
 		},
-		cfgOpts: []configOption{withMultiContainerEnabled()},
-		want:    nil,
+		want: nil,
 	}, {
 		name: "flag enabled: probes are not allowed for non serving containers",
 		ps: corev1.PodSpec{
@@ -281,7 +291,6 @@ func TestPodSpecMultiContainerValidation(t *testing.T) {
 				},
 			}},
 		},
-		cfgOpts: []configOption{withMultiContainerEnabled()},
 		want: &apis.FieldError{
 			Message: "must not set the field(s)",
 			Paths:   []string{"containers[1].livenessProbe.timeoutSeconds", "containers[1].readinessProbe.timeoutSeconds"},
@@ -295,8 +304,7 @@ func TestPodSpecMultiContainerValidation(t *testing.T) {
 				Image: "helloworld",
 			}},
 		},
-		cfgOpts: []configOption{withMultiContainerEnabled()},
-		want:    apis.ErrMissingField("containers.ports"),
+		want: apis.ErrMissingField("containers.ports"),
 	}, {
 		name: "flag enabled: multiple containers with multiple port",
 		ps: corev1.PodSpec{
@@ -312,8 +320,7 @@ func TestPodSpecMultiContainerValidation(t *testing.T) {
 				}},
 			}},
 		},
-		cfgOpts: []configOption{withMultiContainerEnabled()},
-		want:    apis.ErrMultipleOneOf("containers.ports"),
+		want: apis.ErrMultipleOneOf("containers.ports"),
 	}, {
 		name: "flag enabled: multiple containers with multiple ports for each container",
 		ps: corev1.PodSpec{
@@ -331,7 +338,6 @@ func TestPodSpecMultiContainerValidation(t *testing.T) {
 				}},
 			}},
 		},
-		cfgOpts: []configOption{withMultiContainerEnabled()},
 		want: apis.ErrMultipleOneOf("containers.ports").Also(&apis.FieldError{
 			Message: "More than one container port is set",
 			Paths:   []string{"containers[0].ports"},
@@ -351,7 +357,6 @@ func TestPodSpecMultiContainerValidation(t *testing.T) {
 				Image: "helloworld",
 			}},
 		},
-		cfgOpts: []configOption{withMultiContainerEnabled()},
 		want: apis.ErrMultipleOneOf("containers.ports").Also(&apis.FieldError{
 			Message: "More than one container port is set",
 			Paths:   []string{"containers[0].ports"},
@@ -376,7 +381,6 @@ func TestPodSpecMultiContainerValidation(t *testing.T) {
 				}},
 			}},
 		},
-		cfgOpts: []configOption{withMultiContainerEnabled()},
 		want: &apis.FieldError{
 			Message: `"K_SERVICE" is a reserved environment variable`,
 			Paths:   []string{"containers[1].env[1].name"},
@@ -397,8 +401,7 @@ func TestPodSpecMultiContainerValidation(t *testing.T) {
 				}},
 			}},
 		},
-		cfgOpts: []configOption{withMultiContainerEnabled()},
-		want:    nil,
+		want: nil,
 	}, {
 		name: "Volume mounts ok with single container",
 		ps: corev1.PodSpec{
@@ -477,7 +480,6 @@ func TestPodSpecMultiContainerValidation(t *testing.T) {
 				},
 			},
 		},
-		cfgOpts: []configOption{withMultiContainerEnabled()},
 	}, {
 		name: "Volume not mounted when having multiple containers",
 		ps: corev1.PodSpec{
@@ -509,7 +511,6 @@ func TestPodSpecMultiContainerValidation(t *testing.T) {
 				{Image: "busybox"},
 			},
 		},
-		cfgOpts: []configOption{withMultiContainerEnabled()},
 		want: &apis.FieldError{
 			Message: "volume with name \"the-name2\" not mounted",
 			Paths:   []string{"volumes[1].name"},
diff --git a/pkg/apis/serving/v1/revision_lifecycle_test.go b/pkg/apis/serving/v1/revision_lifecycle_test.go
index 4b1a5cca8..3544b9d8e 100644
--- a/pkg/apis/serving/v1/revision_lifecycle_test.go
+++ b/pkg/apis/serving/v1/revision_lifecycle_test.go
@@ -575,6 +575,35 @@ func TestPropagateAutoscalerStatus(t *testing.T) {
 	apistest.CheckConditionSucceeded(r, RevisionConditionResourcesAvailable, t)
 }
 
+func TestPAResAvailableNoOverride(t *testing.T) {
+	r := &RevisionStatus{}
+	r.InitializeConditions()
+	apistest.CheckConditionOngoing(r, RevisionConditionReady, t)
+
+	// Deployment determined that something's wrong, e.g. the only pod
+	// has crashed.
+	r.MarkResourcesAvailableFalse("somehow", "somewhere")
+
+	// PodAutoscaler achieved initial scale.
+	r.PropagateAutoscalerStatus(&av1alpha1.PodAutoscalerStatus{
+		Status: duckv1.Status{
+			Conditions: duckv1.Conditions{{
+				Type:   av1alpha1.PodAutoscalerConditionReady,
+				Status: corev1.ConditionUnknown,
+			}, {
+				Type:   av1alpha1.PodAutoscalerConditionScaleTargetInitialized,
+				Status: corev1.ConditionTrue,
+			}},
+		},
+	})
+	// Verify we did not override this.
+	apistest.CheckConditionFailed(r, RevisionConditionResourcesAvailable, t)
+	cond := r.GetCondition(RevisionConditionResourcesAvailable)
+	if got, notWant := cond.Reason, ReasonProgressDeadlineExceeded; got == notWant {
+		t.Error("PA Status propagation overrode the ResourcesAvailable status")
+	}
+}
+
 func TestPropagateAutoscalerStatusNoProgress(t *testing.T) {
 	r := &RevisionStatus{}
 	r.InitializeConditions()
diff --git a/pkg/apis/serving/v1/revision_validation_test.go b/pkg/apis/serving/v1/revision_validation_test.go
index da6ab75ef..2135c9651 100644
--- a/pkg/apis/serving/v1/revision_validation_test.go
+++ b/pkg/apis/serving/v1/revision_validation_test.go
@@ -321,6 +321,21 @@ func TestRevisionSpecValidation(t *testing.T) {
 			},
 		},
 		want: nil,
+	}, {
+		name: "with multi containers (ok)",
+		rs: &RevisionSpec{
+			PodSpec: corev1.PodSpec{
+				Containers: []corev1.Container{{
+					Image: "busybox",
+					Ports: []corev1.ContainerPort{{
+						ContainerPort: 8881,
+					}},
+				}, {
+					Image: "helloworld",
+				}},
+			},
+		},
+		want: nil,
 	}, {
 		name: "with volume name collision",
 		rs: &RevisionSpec{
@@ -383,6 +398,20 @@ func TestRevisionSpecValidation(t *testing.T) {
 				}},
 			},
 		},
+		wc: func(ctx context.Context) context.Context {
+			s := config.NewStore(logtesting.TestLogger(t))
+			s.OnConfigChanged(&corev1.ConfigMap{ObjectMeta: metav1.ObjectMeta{Name: autoscalerconfig.ConfigName}})
+			s.OnConfigChanged(&corev1.ConfigMap{ObjectMeta: metav1.ObjectMeta{Name: config.DefaultsConfigName}})
+			s.OnConfigChanged(&corev1.ConfigMap{
+				ObjectMeta: metav1.ObjectMeta{
+					Name: config.FeaturesConfigName,
+				},
+				Data: map[string]string{
+					"multi-container": "disabled",
+				},
+			})
+			return s.ToContext(ctx)
+		},
 		want: &apis.FieldError{Message: "multi-container is off, but found 2 containers"},
 	}, {
 		name: "exceed max timeout",
diff --git a/pkg/apis/serving/v1beta1/revision_validation_test.go b/pkg/apis/serving/v1beta1/revision_validation_test.go
index 1b6a36a98..41a8191e1 100644
--- a/pkg/apis/serving/v1beta1/revision_validation_test.go
+++ b/pkg/apis/serving/v1beta1/revision_validation_test.go
@@ -384,6 +384,20 @@ func TestRevisionSpecValidation(t *testing.T) {
 				}},
 			},
 		},
+		wc: func(ctx context.Context) context.Context {
+			s := config.NewStore(logtesting.TestLogger(t))
+			s.OnConfigChanged(&corev1.ConfigMap{ObjectMeta: metav1.ObjectMeta{Name: autoscalerconfig.ConfigName}})
+			s.OnConfigChanged(&corev1.ConfigMap{ObjectMeta: metav1.ObjectMeta{Name: config.DefaultsConfigName}})
+			s.OnConfigChanged(&corev1.ConfigMap{
+				ObjectMeta: metav1.ObjectMeta{
+					Name: config.FeaturesConfigName,
+				},
+				Data: map[string]string{
+					"multi-container": "disabled",
+				},
+			})
+			return s.ToContext(ctx)
+		},
 		want: &apis.FieldError{Message: "multi-container is off, but found 2 containers"},
 	}, {
 		name: "exceed max timeout",
diff --git a/pkg/reconciler/route/resources/ingress_test.go b/pkg/reconciler/route/resources/ingress_test.go
index fba0cc72e..d754490ae 100644
--- a/pkg/reconciler/route/resources/ingress_test.go
+++ b/pkg/reconciler/route/resources/ingress_test.go
@@ -20,6 +20,7 @@ import (
 	"context"
 	"strings"
 	"testing"
+	"time"
 
 	corev1 "k8s.io/api/core/v1"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
@@ -33,6 +34,7 @@ import (
 	"knative.dev/pkg/kmeta"
 	"knative.dev/pkg/ptr"
 	"knative.dev/pkg/system"
+	apiConfig "knative.dev/serving/pkg/apis/config"
 	"knative.dev/serving/pkg/apis/serving"
 	v1 "knative.dev/serving/pkg/apis/serving/v1"
 	"knative.dev/serving/pkg/reconciler/route/config"
@@ -77,7 +79,7 @@ func TestMakeIngressCorrectMetadata(t *testing.T) {
 		},
 		OwnerReferences: []metav1.OwnerReference{*kmeta.NewControllerRef(r)},
 	}
-	ia, err := MakeIngress(getContext(), r, &traffic.Config{Targets: targets}, nil, ingressClass)
+	ia, err := MakeIngress(testContext(), r, &traffic.Config{Targets: targets}, nil, ingressClass)
 	if err != nil {
 		t.Errorf("Unexpected error %v", err)
 	}
@@ -93,7 +95,7 @@ func TestIngress_NoKubectlAnnotation(t *testing.T) {
 		networking.IngressClassAnnotationKey: testIngressClass,
 		corev1.LastAppliedConfigAnnotation:   testAnnotationValue,
 	}), WithRouteUID("1234-5678"), WithURL)
-	ia, err := MakeIngress(getContext(), r, &traffic.Config{Targets: targets}, nil, testIngressClass)
+	ia, err := MakeIngress(testContext(), r, &traffic.Config{Targets: targets}, nil, testIngressClass)
 	if err != nil {
 		t.Errorf("Unexpected error %v", err)
 	}
@@ -144,6 +146,7 @@ func TestMakeIngressSpec_CorrectRules(t *testing.T) {
 						"Knative-Serving-Namespace": ns,
 					},
 				}},
+				Timeout: &metav1.Duration{Duration: 48 * time.Hour},
 			}},
 		},
 		Visibility: netv1alpha1.IngressVisibilityClusterLocal,
@@ -165,6 +168,7 @@ func TestMakeIngressSpec_CorrectRules(t *testing.T) {
 						"Knative-Serving-Namespace": ns,
 					},
 				}},
+				Timeout: &metav1.Duration{Duration: 48 * time.Hour},
 			}},
 		},
 		Visibility: netv1alpha1.IngressVisibilityExternalIP,
@@ -186,6 +190,7 @@ func TestMakeIngressSpec_CorrectRules(t *testing.T) {
 						"Knative-Serving-Namespace": ns,
 					},
 				}},
+				Timeout: &metav1.Duration{Duration: 48 * time.Hour},
 			}},
 		},
 		Visibility: netv1alpha1.IngressVisibilityClusterLocal,
@@ -207,12 +212,13 @@ func TestMakeIngressSpec_CorrectRules(t *testing.T) {
 						"Knative-Serving-Namespace": ns,
 					},
 				}},
+				Timeout: &metav1.Duration{Duration: 48 * time.Hour},
 			}},
 		},
 		Visibility: netv1alpha1.IngressVisibilityExternalIP,
 	}}
 
-	ci, err := MakeIngressSpec(getContext(), r, nil, targets, nil /* visibility */)
+	ci, err := MakeIngressSpec(testContext(), r, nil, targets, nil /* visibility */)
 	if err != nil {
 		t.Errorf("Unexpected error %v", err)
 	}
@@ -288,7 +294,7 @@ func TestMakeIngressSpec_CorrectRuleVisibility(t *testing.T) {
 	}}
 	for _, c := range cases {
 		t.Run(c.name, func(t *testing.T) {
-			ci, err := MakeIngressSpec(getContext(), c.route, nil, c.targets, c.serviceVisibility)
+			ci, err := MakeIngressSpec(testContext(), c.route, nil, c.targets, c.serviceVisibility)
 			if err != nil {
 				t.Errorf("Unexpected error %v", err)
 			}
@@ -353,6 +359,7 @@ func TestMakeIngressSpec_CorrectRulesWithTagBasedRouting(t *testing.T) {
 						"Knative-Serving-Namespace": ns,
 					},
 				}},
+				Timeout: &metav1.Duration{Duration: 48 * time.Hour},
 			}, {
 				AppendHeaders: map[string]string{
 					network.DefaultRouteHeaderName: "true",
@@ -369,6 +376,7 @@ func TestMakeIngressSpec_CorrectRulesWithTagBasedRouting(t *testing.T) {
 						"Knative-Serving-Namespace": ns,
 					},
 				}},
+				Timeout: &metav1.Duration{Duration: 48 * time.Hour},
 			}},
 		},
 		Visibility: netv1alpha1.IngressVisibilityClusterLocal,
@@ -395,6 +403,7 @@ func TestMakeIngressSpec_CorrectRulesWithTagBasedRouting(t *testing.T) {
 						"Knative-Serving-Namespace": ns,
 					},
 				}},
+				Timeout: &metav1.Duration{Duration: 48 * time.Hour},
 			}, {
 				AppendHeaders: map[string]string{
 					network.DefaultRouteHeaderName: "true",
@@ -411,6 +420,7 @@ func TestMakeIngressSpec_CorrectRulesWithTagBasedRouting(t *testing.T) {
 						"Knative-Serving-Namespace": ns,
 					},
 				}},
+				Timeout: &metav1.Duration{Duration: 48 * time.Hour},
 			}},
 		},
 		Visibility: netv1alpha1.IngressVisibilityExternalIP,
@@ -435,6 +445,7 @@ func TestMakeIngressSpec_CorrectRulesWithTagBasedRouting(t *testing.T) {
 						"Knative-Serving-Namespace": ns,
 					},
 				}},
+				Timeout: &metav1.Duration{Duration: 48 * time.Hour},
 			}},
 		},
 		Visibility: netv1alpha1.IngressVisibilityClusterLocal,
@@ -459,14 +470,14 @@ func TestMakeIngressSpec_CorrectRulesWithTagBasedRouting(t *testing.T) {
 						"Knative-Serving-Namespace": ns,
 					},
 				}},
+				Timeout: &metav1.Duration{Duration: 48 * time.Hour},
 			}},
 		},
 		Visibility: netv1alpha1.IngressVisibilityExternalIP,
 	}}
 
-	cfg := testConfig()
-	cfg.Network.TagHeaderBasedRouting = true
-	ctx := config.ToContext(context.Background(), cfg)
+	ctx := testContext()
+	config.FromContext(ctx).Network.TagHeaderBasedRouting = true
 
 	ci, err := MakeIngressSpec(ctx, r, nil, targets, nil /* visibility */)
 	if err != nil {
@@ -490,7 +501,7 @@ func TestMakeIngressRule_Vanilla(t *testing.T) {
 		Active:      true,
 	}}
 	domains := []string{"a.com", "b.org"}
-	rule := makeIngressRule(domains, ns, netv1alpha1.IngressVisibilityExternalIP, targets)
+	rule := makeIngressRule(testContext(), domains, ns, netv1alpha1.IngressVisibilityExternalIP, targets)
 	expected := netv1alpha1.IngressRule{
 		Hosts: []string{
 			"a.com",
@@ -510,6 +521,7 @@ func TestMakeIngressRule_Vanilla(t *testing.T) {
 						"Knative-Serving-Namespace": ns,
 					},
 				}},
+				Timeout: &metav1.Duration{Duration: 48 * time.Hour},
 			}},
 		},
 		Visibility: netv1alpha1.IngressVisibilityExternalIP,
@@ -539,7 +551,7 @@ func TestMakeIngressRule_ZeroPercentTarget(t *testing.T) {
 		Active: true,
 	}}
 	domains := []string{"test.org"}
-	rule := makeIngressRule(domains, ns, netv1alpha1.IngressVisibilityExternalIP, targets)
+	rule := makeIngressRule(testContext(), domains, ns, netv1alpha1.IngressVisibilityExternalIP, targets)
 	expected := netv1alpha1.IngressRule{
 		Hosts: []string{"test.org"},
 		HTTP: &netv1alpha1.HTTPIngressRuleValue{
@@ -556,6 +568,7 @@ func TestMakeIngressRule_ZeroPercentTarget(t *testing.T) {
 						"Knative-Serving-Namespace": ns,
 					},
 				}},
+				Timeout: &metav1.Duration{Duration: 48 * time.Hour},
 			}},
 		},
 		Visibility: netv1alpha1.IngressVisibilityExternalIP,
@@ -585,7 +598,7 @@ func TestMakeIngressRule_NilPercentTarget(t *testing.T) {
 		Active: true,
 	}}
 	domains := []string{"test.org"}
-	rule := makeIngressRule(domains, ns, netv1alpha1.IngressVisibilityExternalIP, targets)
+	rule := makeIngressRule(testContext(), domains, ns, netv1alpha1.IngressVisibilityExternalIP, targets)
 	expected := netv1alpha1.IngressRule{
 		Hosts: []string{"test.org"},
 		HTTP: &netv1alpha1.HTTPIngressRuleValue{
@@ -602,6 +615,7 @@ func TestMakeIngressRule_NilPercentTarget(t *testing.T) {
 						"Knative-Serving-Namespace": ns,
 					},
 				}},
+				Timeout: &metav1.Duration{Duration: 48 * time.Hour},
 			}},
 		},
 		Visibility: netv1alpha1.IngressVisibilityExternalIP,
@@ -632,7 +646,7 @@ func TestMakeIngressRule_TwoTargets(t *testing.T) {
 		Active:      true,
 	}}
 	domains := []string{"test.org"}
-	rule := makeIngressRule(domains, ns, netv1alpha1.IngressVisibilityExternalIP, targets)
+	rule := makeIngressRule(testContext(), domains, ns, netv1alpha1.IngressVisibilityExternalIP, targets)
 	expected := netv1alpha1.IngressRule{
 		Hosts: []string{"test.org"},
 		HTTP: &netv1alpha1.HTTPIngressRuleValue{
@@ -660,6 +674,7 @@ func TestMakeIngressRule_TwoTargets(t *testing.T) {
 						"Knative-Serving-Revision":  "new-revision",
 					},
 				}},
+				Timeout: &metav1.Duration{Duration: 48 * time.Hour},
 			}},
 		},
 		Visibility: netv1alpha1.IngressVisibilityExternalIP,
@@ -682,7 +697,7 @@ func TestMakeIngressRule_InactiveTarget(t *testing.T) {
 		Active:      false,
 	}}
 	domains := []string{"a.com", "b.org"}
-	rule := makeIngressRule(domains, ns, netv1alpha1.IngressVisibilityExternalIP, targets)
+	rule := makeIngressRule(testContext(), domains, ns, netv1alpha1.IngressVisibilityExternalIP, targets)
 	expected := netv1alpha1.IngressRule{
 		Hosts: []string{
 			"a.com",
@@ -702,6 +717,7 @@ func TestMakeIngressRule_InactiveTarget(t *testing.T) {
 						"Knative-Serving-Namespace": ns,
 					},
 				}},
+				Timeout: &metav1.Duration{Duration: 48 * time.Hour},
 			}},
 		},
 		Visibility: netv1alpha1.IngressVisibilityExternalIP,
@@ -731,7 +747,7 @@ func TestMakeIngressRule_TwoInactiveTargets(t *testing.T) {
 		Active:      false,
 	}}
 	domains := []string{"a.com", "b.org"}
-	rule := makeIngressRule(domains, ns, netv1alpha1.IngressVisibilityExternalIP, targets)
+	rule := makeIngressRule(testContext(), domains, ns, netv1alpha1.IngressVisibilityExternalIP, targets)
 	expected := netv1alpha1.IngressRule{
 		Hosts: []string{
 			"a.com",
@@ -762,6 +778,7 @@ func TestMakeIngressRule_TwoInactiveTargets(t *testing.T) {
 						"Knative-Serving-Namespace": ns,
 					},
 				}},
+				Timeout: &metav1.Duration{Duration: 48 * time.Hour},
 			}},
 		},
 		Visibility: netv1alpha1.IngressVisibilityExternalIP,
@@ -789,7 +806,7 @@ func TestMakeIngressRule_ZeroPercentTargetInactive(t *testing.T) {
 		Active: false,
 	}}
 	domains := []string{"test.org"}
-	rule := makeIngressRule(domains, ns, netv1alpha1.IngressVisibilityExternalIP, targets)
+	rule := makeIngressRule(testContext(), domains, ns, netv1alpha1.IngressVisibilityExternalIP, targets)
 	expected := netv1alpha1.IngressRule{
 		Hosts: []string{"test.org"},
 		HTTP: &netv1alpha1.HTTPIngressRuleValue{
@@ -806,6 +823,7 @@ func TestMakeIngressRule_ZeroPercentTargetInactive(t *testing.T) {
 						"Knative-Serving-Namespace": ns,
 					},
 				}},
+				Timeout: &metav1.Duration{Duration: 48 * time.Hour},
 			}},
 		},
 		Visibility: netv1alpha1.IngressVisibilityExternalIP,
@@ -834,7 +852,7 @@ func TestMakeIngressRule_NilPercentTargetInactive(t *testing.T) {
 		Active: false,
 	}}
 	domains := []string{"test.org"}
-	rule := makeIngressRule(domains, ns, netv1alpha1.IngressVisibilityExternalIP, targets)
+	rule := makeIngressRule(testContext(), domains, ns, netv1alpha1.IngressVisibilityExternalIP, targets)
 	expected := netv1alpha1.IngressRule{
 		Hosts: []string{"test.org"},
 		HTTP: &netv1alpha1.HTTPIngressRuleValue{
@@ -851,6 +869,7 @@ func TestMakeIngressRule_NilPercentTargetInactive(t *testing.T) {
 						"Knative-Serving-Namespace": ns,
 					},
 				}},
+				Timeout: &metav1.Duration{Duration: 48 * time.Hour},
 			}},
 		},
 		Visibility: netv1alpha1.IngressVisibilityExternalIP,
@@ -887,7 +906,7 @@ func TestMakeIngressWithTLS(t *testing.T) {
 			TLS:   tls,
 		},
 	}
-	got, err := MakeIngress(getContext(), r, &traffic.Config{Targets: targets}, tls, ingressClass)
+	got, err := MakeIngress(testContext(), r, &traffic.Config{Targets: targets}, tls, ingressClass)
 	if err != nil {
 		t.Errorf("Unexpected error: %v", err)
 	}
@@ -978,6 +997,7 @@ func TestMakeIngressACMEChallenges(t *testing.T) {
 						"Knative-Serving-Namespace": "test-ns",
 					},
 				}},
+				Timeout: &metav1.Duration{Duration: 48 * time.Hour},
 			}}},
 	}, {
 		Hosts: []string{
@@ -1008,10 +1028,11 @@ func TestMakeIngressACMEChallenges(t *testing.T) {
 						"Knative-Serving-Namespace": "test-ns",
 					},
 				}},
+				Timeout: &metav1.Duration{Duration: 48 * time.Hour},
 			}}},
 	}}
 
-	ci, err := MakeIngressSpec(getContext(), r, nil, targets, nil /* visibility */, acmeChallenge)
+	ci, err := MakeIngressSpec(testContext(), r, nil, targets, nil /* visibility */, acmeChallenge)
 	if err != nil {
 		t.Errorf("Unexpected error %v", err)
 	}
@@ -1038,14 +1059,13 @@ func TestMakeIngressFailToGenerateDomain(t *testing.T) {
 	r := Route(ns, "test-route", WithURL)
 
 	// Create a context that has a bad domain template.
-	badContext := config.ToContext(context.Background(), &config.Config{
-		Domain: &config.Domain{Domains: map[string]*config.LabelSelector{"example.com": {}}},
-		Network: &network.Config{
-			DefaultIngressClass: "test-ingress-class",
-			DomainTemplate:      "{{.UnknownField}}.{{.NonExistentField}}.{{.BadField}}",
-			TagTemplate:         network.DefaultTagTemplate,
-		},
-	})
+	badContext := testContext()
+	config.FromContext(badContext).Domain = &config.Domain{Domains: map[string]*config.LabelSelector{"example.com": {}}}
+	config.FromContext(badContext).Network = &network.Config{
+		DefaultIngressClass: "test-ingress-class",
+		DomainTemplate:      "{{.UnknownField}}.{{.NonExistentField}}.{{.BadField}}",
+		TagTemplate:         network.DefaultTagTemplate,
+	}
 	_, err := MakeIngress(badContext, r, &traffic.Config{Targets: targets}, nil, "")
 	if err == nil {
 		t.Error("Expected error, saw none")
@@ -1080,14 +1100,13 @@ func TestMakeIngressFailToGenerateTagHost(t *testing.T) {
 	r := Route(ns, "test-route", WithURL)
 
 	// Create a context that has a bad domain template.
-	badContext := config.ToContext(context.Background(), &config.Config{
-		Domain: &config.Domain{Domains: map[string]*config.LabelSelector{"example.com": {}}},
-		Network: &network.Config{
-			DefaultIngressClass: "test-ingress-class",
-			DomainTemplate:      network.DefaultDomainTemplate,
-			TagTemplate:         "{{.UnknownField}}.{{.NonExistentField}}.{{.BadField}}",
-		},
-	})
+	badContext := testContext()
+	config.FromContext(badContext).Domain = &config.Domain{Domains: map[string]*config.LabelSelector{"example.com": {}}}
+	config.FromContext(badContext).Network = &network.Config{
+		DefaultIngressClass: "test-ingress-class",
+		DomainTemplate:      network.DefaultDomainTemplate,
+		TagTemplate:         "{{.UnknownField}}.{{.NonExistentField}}.{{.BadField}}",
+	}
 	_, err := MakeIngress(badContext, r, &traffic.Config{Targets: targets}, nil, "")
 	if err == nil {
 		t.Error("Expected error, saw none")
@@ -1097,8 +1116,11 @@ func TestMakeIngressFailToGenerateTagHost(t *testing.T) {
 	}
 }
 
-func getContext() context.Context {
+func testContext() context.Context {
 	ctx := context.Background()
 	cfg := testConfig()
-	return config.ToContext(ctx, cfg)
+	configDefaults, _ := apiConfig.NewDefaultsConfigFromMap(nil)
+	return config.ToContext(apiConfig.ToContext(ctx, &apiConfig.Config{
+		Defaults: configDefaults,
+	}), cfg)
 }
diff --git a/pkg/reconciler/route/route_test.go b/pkg/reconciler/route/route_test.go
index 27c83284d..8200c30d3 100644
--- a/pkg/reconciler/route/route_test.go
+++ b/pkg/reconciler/route/route_test.go
@@ -288,6 +288,7 @@ func TestCreateRouteForOneReserveRevision(t *testing.T) {
 							"Knative-Serving-Namespace": testNamespace,
 						},
 					}},
+					Timeout: &metav1.Duration{Duration: 48 * time.Hour},
 				}},
 			},
 		}, {
@@ -309,6 +310,7 @@ func TestCreateRouteForOneReserveRevision(t *testing.T) {
 							"Knative-Serving-Namespace": testNamespace,
 						},
 					}},
+					Timeout: &metav1.Duration{Duration: 48 * time.Hour},
 				}},
 			},
 		}},
@@ -425,6 +427,7 @@ func TestCreateRouteWithMultipleTargets(t *testing.T) {
 							"Knative-Serving-Namespace": testNamespace,
 						},
 					}},
+					Timeout: &metav1.Duration{Duration: 48 * time.Hour},
 				}},
 			},
 			Visibility: v1alpha1.IngressVisibilityClusterLocal,
@@ -457,6 +460,7 @@ func TestCreateRouteWithMultipleTargets(t *testing.T) {
 							"Knative-Serving-Namespace": testNamespace,
 						},
 					}},
+					Timeout: &metav1.Duration{Duration: 48 * time.Hour},
 				}},
 			},
 			Visibility: v1alpha1.IngressVisibilityExternalIP,
@@ -540,6 +544,7 @@ func TestCreateRouteWithOneTargetReserve(t *testing.T) {
 							"Knative-Serving-Namespace": testNamespace,
 						},
 					}},
+					Timeout: &metav1.Duration{Duration: 48 * time.Hour},
 				}},
 			},
 			Visibility: v1alpha1.IngressVisibilityClusterLocal,
@@ -572,6 +577,7 @@ func TestCreateRouteWithOneTargetReserve(t *testing.T) {
 							"Knative-Serving-Namespace": testNamespace,
 						},
 					}},
+					Timeout: &metav1.Duration{Duration: 48 * time.Hour},
 				}},
 			},
 			Visibility: v1alpha1.IngressVisibilityExternalIP,
@@ -669,6 +675,7 @@ func TestCreateRouteWithDuplicateTargets(t *testing.T) {
 							"Knative-Serving-Namespace": testNamespace,
 						},
 					}},
+					Timeout: &metav1.Duration{Duration: 48 * time.Hour},
 				}},
 			},
 			Visibility: v1alpha1.IngressVisibilityClusterLocal,
@@ -701,6 +708,7 @@ func TestCreateRouteWithDuplicateTargets(t *testing.T) {
 							"Knative-Serving-Namespace": testNamespace,
 						},
 					}},
+					Timeout: &metav1.Duration{Duration: 48 * time.Hour},
 				}},
 			},
 			Visibility: v1alpha1.IngressVisibilityExternalIP,
@@ -722,6 +730,7 @@ func TestCreateRouteWithDuplicateTargets(t *testing.T) {
 							"Knative-Serving-Namespace": testNamespace,
 						},
 					}},
+					Timeout: &metav1.Duration{Duration: 48 * time.Hour},
 				}},
 			},
 			Visibility: v1alpha1.IngressVisibilityClusterLocal,
@@ -743,6 +752,7 @@ func TestCreateRouteWithDuplicateTargets(t *testing.T) {
 							"Knative-Serving-Namespace": testNamespace,
 						},
 					}},
+					Timeout: &metav1.Duration{Duration: 48 * time.Hour},
 				}},
 			},
 			Visibility: v1alpha1.IngressVisibilityExternalIP,
@@ -764,6 +774,7 @@ func TestCreateRouteWithDuplicateTargets(t *testing.T) {
 							"Knative-Serving-Namespace": testNamespace,
 						},
 					}},
+					Timeout: &metav1.Duration{Duration: 48 * time.Hour},
 				}},
 			},
 			Visibility: v1alpha1.IngressVisibilityClusterLocal,
@@ -785,6 +796,7 @@ func TestCreateRouteWithDuplicateTargets(t *testing.T) {
 							"Knative-Serving-Namespace": testNamespace,
 						},
 					}},
+					Timeout: &metav1.Duration{Duration: 48 * time.Hour},
 				}},
 			},
 			Visibility: v1alpha1.IngressVisibilityExternalIP,
@@ -869,6 +881,7 @@ func TestCreateRouteWithNamedTargets(t *testing.T) {
 							"Knative-Serving-Namespace": testNamespace,
 						},
 					}},
+					Timeout: &metav1.Duration{Duration: 48 * time.Hour},
 				}},
 			},
 			Visibility: v1alpha1.IngressVisibilityClusterLocal,
@@ -901,6 +914,7 @@ func TestCreateRouteWithNamedTargets(t *testing.T) {
 							"Knative-Serving-Namespace": testNamespace,
 						},
 					}},
+					Timeout: &metav1.Duration{Duration: 48 * time.Hour},
 				}},
 			},
 			Visibility: v1alpha1.IngressVisibilityExternalIP,
@@ -922,6 +936,7 @@ func TestCreateRouteWithNamedTargets(t *testing.T) {
 							"Knative-Serving-Namespace": testNamespace,
 						},
 					}},
+					Timeout: &metav1.Duration{Duration: 48 * time.Hour},
 				}},
 			},
 			Visibility: v1alpha1.IngressVisibilityClusterLocal,
@@ -943,6 +958,7 @@ func TestCreateRouteWithNamedTargets(t *testing.T) {
 							"Knative-Serving-Namespace": testNamespace,
 						},
 					}},
+					Timeout: &metav1.Duration{Duration: 48 * time.Hour},
 				}},
 			},
 			Visibility: v1alpha1.IngressVisibilityExternalIP,
@@ -964,6 +980,7 @@ func TestCreateRouteWithNamedTargets(t *testing.T) {
 							"Knative-Serving-Namespace": testNamespace,
 						},
 					}},
+					Timeout: &metav1.Duration{Duration: 48 * time.Hour},
 				}},
 			},
 			Visibility: v1alpha1.IngressVisibilityClusterLocal,
@@ -985,6 +1002,7 @@ func TestCreateRouteWithNamedTargets(t *testing.T) {
 							"Knative-Serving-Namespace": testNamespace,
 						},
 					}},
+					Timeout: &metav1.Duration{Duration: 48 * time.Hour},
 				}},
 			},
 			Visibility: v1alpha1.IngressVisibilityExternalIP,
@@ -1074,6 +1092,7 @@ func TestCreateRouteWithNamedTargetsAndTagBasedRouting(t *testing.T) {
 							},
 						},
 					},
+					Timeout: &metav1.Duration{Duration: 48 * time.Hour},
 				}, {
 					Headers: map[string]v1alpha1.HeaderMatch{
 						network.TagHeaderName: {
@@ -1094,6 +1113,7 @@ func TestCreateRouteWithNamedTargetsAndTagBasedRouting(t *testing.T) {
 							},
 						},
 					},
+					Timeout: &metav1.Duration{Duration: 48 * time.Hour},
 				}, {
 					AppendHeaders: map[string]string{
 						network.DefaultRouteHeaderName: "true",
@@ -1121,6 +1141,7 @@ func TestCreateRouteWithNamedTargetsAndTagBasedRouting(t *testing.T) {
 							"Knative-Serving-Namespace": testNamespace,
 						},
 					}},
+					Timeout: &metav1.Duration{Duration: 48 * time.Hour},
 				}},
 			},
 			Visibility: v1alpha1.IngressVisibilityClusterLocal,
@@ -1149,6 +1170,7 @@ func TestCreateRouteWithNamedTargetsAndTagBasedRouting(t *testing.T) {
 							},
 						},
 					},
+					Timeout: &metav1.Duration{Duration: 48 * time.Hour},
 				}, {
 					Headers: map[string]v1alpha1.HeaderMatch{
 						network.TagHeaderName: {
@@ -1169,6 +1191,7 @@ func TestCreateRouteWithNamedTargetsAndTagBasedRouting(t *testing.T) {
 							},
 						},
 					},
+					Timeout: &metav1.Duration{Duration: 48 * time.Hour},
 				}, {
 					AppendHeaders: map[string]string{
 						network.DefaultRouteHeaderName: "true",
@@ -1196,6 +1219,7 @@ func TestCreateRouteWithNamedTargetsAndTagBasedRouting(t *testing.T) {
 							"Knative-Serving-Namespace": testNamespace,
 						},
 					}},
+					Timeout: &metav1.Duration{Duration: 48 * time.Hour},
 				}},
 			},
 			Visibility: v1alpha1.IngressVisibilityExternalIP,
@@ -1220,6 +1244,7 @@ func TestCreateRouteWithNamedTargetsAndTagBasedRouting(t *testing.T) {
 					AppendHeaders: map[string]string{
 						network.TagHeaderName: "bar",
 					},
+					Timeout: &metav1.Duration{Duration: 48 * time.Hour},
 				}},
 			},
 			Visibility: v1alpha1.IngressVisibilityClusterLocal,
@@ -1244,6 +1269,7 @@ func TestCreateRouteWithNamedTargetsAndTagBasedRouting(t *testing.T) {
 					AppendHeaders: map[string]string{
 						network.TagHeaderName: "bar",
 					},
+					Timeout: &metav1.Duration{Duration: 48 * time.Hour},
 				}},
 			},
 			Visibility: v1alpha1.IngressVisibilityExternalIP,
@@ -1265,6 +1291,7 @@ func TestCreateRouteWithNamedTargetsAndTagBasedRouting(t *testing.T) {
 							"Knative-Serving-Namespace": testNamespace,
 						},
 					}},
+					Timeout: &metav1.Duration{Duration: 48 * time.Hour},
 					AppendHeaders: map[string]string{
 						network.TagHeaderName: "foo",
 					},
@@ -1289,6 +1316,7 @@ func TestCreateRouteWithNamedTargetsAndTagBasedRouting(t *testing.T) {
 							"Knative-Serving-Namespace": testNamespace,
 						},
 					}},
+					Timeout: &metav1.Duration{Duration: 48 * time.Hour},
 					AppendHeaders: map[string]string{
 						network.TagHeaderName: "foo",
 					},
diff --git a/test/conformance/api/v1/errorcondition_test.go b/test/conformance/api/v1/errorcondition_test.go
index 6a2fbaa8a..98bf83713 100644
--- a/test/conformance/api/v1/errorcondition_test.go
+++ b/test/conformance/api/v1/errorcondition_test.go
@@ -67,10 +67,10 @@ func TestContainerErrorMsg(t *testing.T) {
 	names.Config = serviceresourcenames.Configuration(svc)
 	names.Route = serviceresourcenames.Route(svc)
 
-	manifestUnknown := string(transport.ManifestUnknownErrorCode)
-	t.Log("When the imagepath is invalid, the Configuration should have error status.")
+	const manifestUnknown = string(transport.ManifestUnknownErrorCode)
 
 	// Wait for ServiceState becomes NotReady. It also waits for the creation of Configuration.
+	t.Log("When the imagepath is invalid, the Configuration should have error status.")
 	if err := v1test.WaitForServiceState(clients.ServingClient, names.Service, v1test.IsServiceAndChildrenFailed, "ServiceIsFailed"); err != nil {
 		t.Fatalf("The Service %s was unexpected state: %v", names.Service, err)
 	}
@@ -82,10 +82,11 @@ func TestContainerErrorMsg(t *testing.T) {
 			if strings.Contains(cond.Message, manifestUnknown) && cond.IsFalse() {
 				return true, nil
 			}
-			t.Logf("Reason: %s ; Message: %s ; Status %s", cond.Reason, cond.Message, cond.Status)
+			t.Logf("Reason: %s; Message: %s; Status %s", cond.Reason, cond.Message, cond.Status)
 			return true, fmt.Errorf("The configuration %s was not marked with expected error condition (Reason=%q, Message=%q, Status=%q), but with (Reason=%q, Message=%q, Status=%q)",
 				names.Config, containerMissing, manifestUnknown, "False", cond.Reason, cond.Message, cond.Status)
 		}
+		t.Logf("Config %s Ready status = %v", names.Config, cond)
 		return false, nil
 	})
 
@@ -99,7 +100,7 @@ func TestContainerErrorMsg(t *testing.T) {
 	}
 
 	t.Log("When the imagepath is invalid, the revision should have error status.")
-	err = v1test.CheckRevisionState(clients.ServingClient, revisionName, func(r *v1.Revision) (bool, error) {
+	if err = v1test.CheckRevisionState(clients.ServingClient, revisionName, func(r *v1.Revision) (bool, error) {
 		cond := r.Status.GetCondition(v1.RevisionConditionReady)
 		if cond != nil {
 			if cond.Reason == containerMissing && strings.Contains(cond.Message, manifestUnknown) {
@@ -108,10 +109,9 @@ func TestContainerErrorMsg(t *testing.T) {
 			return true, fmt.Errorf("The revision %s was not marked with expected error condition (Reason=%q, Message=%q), but with (Reason=%q, Message=%q)",
 				revisionName, containerMissing, manifestUnknown, cond.Reason, cond.Message)
 		}
+		t.Logf("Revision %s Ready state = %#v", revisionName, cond)
 		return false, nil
-	})
-
-	if err != nil {
+	}); err != nil {
 		t.Fatal("Failed to validate revision state:", err)
 	}
 
@@ -174,20 +174,20 @@ func TestContainerExitingMsg(t *testing.T) {
 
 			t.Log("When the containers keep crashing, the Configuration should have error status.")
 
-			err := v1test.WaitForConfigurationState(clients.ServingClient, names.Config, func(r *v1.Configuration) (bool, error) {
+			if err := v1test.WaitForConfigurationState(clients.ServingClient, names.Config, func(r *v1.Configuration) (bool, error) {
 				cond := r.Status.GetCondition(v1.ConfigurationConditionReady)
 				if cond != nil && !cond.IsUnknown() {
+					// Check that it failed and for the right reason.
 					if strings.Contains(cond.Message, errorLog) && cond.IsFalse() {
 						return true, nil
 					}
-					t.Logf("Reason: %s ; Message: %s ; Status: %s", cond.Reason, cond.Message, cond.Status)
-					return true, fmt.Errorf("The configuration %s was not marked with expected error condition (Reason=%q, Message=%q, Status=%q), but with (Reason=%q, Message=%q, Status=%q)",
+					t.Logf("Reason: %s; Message: %q; Status: %s", cond.Reason, cond.Message, cond.Status)
+					return true, fmt.Errorf("The configuration %s was not marked with expected error condition (Reason=%s, Message=%q, Status=%s), but with (Reason=%s, Message=%q, Status=%s)",
 						names.Config, containerMissing, errorLog, "False", cond.Reason, cond.Message, cond.Status)
 				}
+				t.Logf("Configuration %s Ready = %#v", names.Config, cond)
 				return false, nil
-			}, "ConfigContainersCrashing")
-
-			if err != nil {
+			}, "ConfigContainersCrashing"); err != nil {
 				t.Fatal("Failed to validate configuration state:", err)
 			}
 
@@ -203,9 +203,10 @@ func TestContainerExitingMsg(t *testing.T) {
 					if cond.Reason == exitCodeReason && strings.Contains(cond.Message, errorLog) {
 						return true, nil
 					}
-					return true, fmt.Errorf("The revision %s was not marked with expected error condition (Reason=%q, Message=%q), but with (Reason=%q, Message=%q)",
+					return true, fmt.Errorf("the revision %s was not marked with expected error condition (Reason=%s, Message=%q), but with (Reason=%s, Message=%q)",
 						revisionName, exitCodeReason, errorLog, cond.Reason, cond.Message)
 				}
+				t.Logf("Revision %s Ready state = %#v", revisionName, cond)
 				return false, nil
 			}, "RevisionContainersCrashing")
 
diff --git a/test/conformance/certificate/README.md b/test/conformance/certificate/README.md
deleted file mode 100644
index 063616e41..000000000
--- a/test/conformance/certificate/README.md
+++ /dev/null
@@ -1,32 +0,0 @@
-# Certificate Conformance Testing
-
-## Adding a test
-
-Tests need to be exported and accessible downstream so they should be placed in
-non-test files (ie. sometest.go). Additionally, invoke your test in the default
-`RunConformance` function in [`run.go`](./http01/run.go). This function is the
-entry point by which tests are executed.
-
-This approach aims to reduce the changes required when tests are added &
-removed.
-
-## Running the tests downstream
-
-To run all the conformance tests in your own repo we encourage adopting the
-[`RunConformance`](./http01/run.go) function to run all your tests.
-
-To do so would look something like:
-
-```go
-package conformance
-
-import (
-	"testing"
-	"knative.dev/serving/test/conformance/certificate/http01"
-)
-
-func TestYourHTTP01ProviderConformance(t *testing.T) {
-	http01.RunConformance(t)
-}
-
-```
diff --git a/test/conformance/certificate/http01/certificate.go b/test/conformance/certificate/http01/certificate.go
deleted file mode 100644
index 9df5bf70d..000000000
--- a/test/conformance/certificate/http01/certificate.go
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
-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 http01
-
-import (
-	"testing"
-
-	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
-	"knative.dev/networking/pkg/apis/networking/v1alpha1"
-	"knative.dev/serving/test"
-	utils "knative.dev/serving/test/conformance/certificate"
-)
-
-// TestHTTP01Challenge verifies that HTTP challenges are created for a certificate
-func TestHTTP01Challenge(t *testing.T) {
-	subDomain := test.ObjectNameForTest(t)
-	clients := test.Setup(t)
-
-	certDomains := [][]string{
-		{subDomain + ".example.com"},
-		{subDomain + "2.example.com", subDomain + "3.example.com"},
-	}
-
-	for _, domains := range certDomains {
-		cert := utils.CreateCertificate(t, clients, domains)
-
-		if err := utils.WaitForCertificateState(clients.NetworkingClient, cert.Name,
-			func(c *v1alpha1.Certificate) (bool, error) {
-				return len(c.Status.HTTP01Challenges) == len(c.Spec.DNSNames), nil
-			},
-			t.Name()); err != nil {
-			t.Fatal("failed to wait for HTTP01 challenges:", err)
-		}
-
-		cert, err := clients.NetworkingClient.Certificates.Get(cert.Name, metav1.GetOptions{})
-		if err != nil {
-			t.Fatal("failed to fetch certificate:", err)
-		}
-
-		utils.VerifyChallenges(t, clients, cert)
-	}
-}
diff --git a/test/conformance/certificate/http01/run.go b/test/conformance/certificate/http01/run.go
deleted file mode 100644
index e57440166..000000000
--- a/test/conformance/certificate/http01/run.go
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
-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 http01
-
-import "testing"
-
-func RunConformance(t *testing.T) {
-	t.Run("http01", TestHTTP01Challenge)
-}
diff --git a/test/conformance/certificate/http01/run_test.go b/test/conformance/certificate/http01/run_test.go
deleted file mode 100644
index 18bf81315..000000000
--- a/test/conformance/certificate/http01/run_test.go
+++ /dev/null
@@ -1,25 +0,0 @@
-// +build e2e
-
-/*
-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 http01
-
-import "testing"
-
-func TestCertificateConformance(t *testing.T) {
-	RunConformance(t)
-}
diff --git a/test/conformance/certificate/nonhttp01/certificate.go b/test/conformance/certificate/nonhttp01/certificate.go
deleted file mode 100644
index 0f53294c7..000000000
--- a/test/conformance/certificate/nonhttp01/certificate.go
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
-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 nonhttp01
-
-import (
-	"testing"
-
-	"knative.dev/serving/test"
-	utils "knative.dev/serving/test/conformance/certificate"
-)
-
-// TestSecret verifies that a certificate creates a secret
-func TestSecret(t *testing.T) {
-	clients := test.Setup(t)
-	certName := test.ObjectNameForTest(t) + ".example.com"
-
-	cert := utils.CreateCertificate(t, clients, []string{certName})
-
-	t.Logf("Waiting for Certificate %q to transition to Ready", cert.Name)
-	if err := utils.WaitForCertificateState(clients.NetworkingClient, cert.Name, utils.IsCertificateReady, "CertificateIsReady"); err != nil {
-		t.Fatal("Error waiting for the certificate to become ready for the latest revision:", err)
-	}
-
-	err := utils.WaitForCertificateSecret(t, clients, cert, t.Name())
-	if err != nil {
-		t.Errorf("Failed to wait for secret: %v", err)
-	}
-}
diff --git a/test/conformance/certificate/nonhttp01/run.go b/test/conformance/certificate/nonhttp01/run.go
deleted file mode 100644
index 60e4c7879..000000000
--- a/test/conformance/certificate/nonhttp01/run.go
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
-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 nonhttp01
-
-import "testing"
-
-func RunConformance(t *testing.T) {
-	t.Run("secret", TestSecret)
-}
diff --git a/test/conformance/certificate/nonhttp01/run_test.go b/test/conformance/certificate/nonhttp01/run_test.go
deleted file mode 100644
index 64db2b152..000000000
--- a/test/conformance/certificate/nonhttp01/run_test.go
+++ /dev/null
@@ -1,25 +0,0 @@
-// +build e2e
-
-/*
-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 nonhttp01
-
-import "testing"
-
-func TestCertificateConformance(t *testing.T) {
-	RunConformance(t)
-}
diff --git a/test/conformance/certificate/utils.go b/test/conformance/certificate/utils.go
deleted file mode 100644
index 3a38d4ed3..000000000
--- a/test/conformance/certificate/utils.go
+++ /dev/null
@@ -1,153 +0,0 @@
-/*
-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 certificate
-
-import (
-	"context"
-	"crypto/x509"
-	"encoding/pem"
-	"errors"
-	"fmt"
-	"testing"
-
-	"github.com/google/go-cmp/cmp"
-	corev1 "k8s.io/api/core/v1"
-	apierrs "k8s.io/apimachinery/pkg/api/errors"
-	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
-	"k8s.io/apimachinery/pkg/util/sets"
-	"k8s.io/apimachinery/pkg/util/wait"
-	"knative.dev/networking/pkg/apis/networking"
-	"knative.dev/networking/pkg/apis/networking/v1alpha1"
-	"knative.dev/pkg/test/logging"
-	"knative.dev/serving/test"
-)
-
-// CreateCertificate creates a Certificate with the given DNS names. The
-// certificate is automatically cleaned up when the test ends or is
-// interrupted.
-func CreateCertificate(t *testing.T, clients *test.Clients, dnsNames []string) *v1alpha1.Certificate {
-	t.Helper()
-
-	name := test.ObjectNameForTest(t)
-	cert := &v1alpha1.Certificate{
-		ObjectMeta: metav1.ObjectMeta{
-			Name:      name,
-			Namespace: test.ServingNamespace,
-			Annotations: map[string]string{
-				networking.CertificateClassAnnotationKey: test.ServingFlags.CertificateClass,
-			},
-		},
-		Spec: v1alpha1.CertificateSpec{
-			DNSNames:   dnsNames,
-			SecretName: name,
-		},
-	}
-
-	test.EnsureCleanup(t, func() {
-		clients.NetworkingClient.Certificates.Delete(cert.Name, &metav1.DeleteOptions{})
-		clients.KubeClient.Kube.CoreV1().Secrets(test.ServingNamespace).Delete(cert.Spec.SecretName, &metav1.DeleteOptions{})
-	})
-
-	cert, err := clients.NetworkingClient.Certificates.Create(cert)
-	if err != nil {
-		t.Fatal("Error creating Certificate:", err)
-	}
-
-	return cert
-}
-
-// IsCertificateReady will check the status conditions of the certificate and return true if the certificate is
-// ready.
-func IsCertificateReady(c *v1alpha1.Certificate) (bool, error) {
-	return c.IsReady(), nil
-}
-
-// WaitForCertificateSecret polls the status of the Secret for the provided Certificate
-// until it exists or the timeout is exceeded. It then validates its contents
-func WaitForCertificateSecret(t *testing.T, client *test.Clients, cert *v1alpha1.Certificate, desc string) error {
-	span := logging.GetEmitableSpan(context.Background(), fmt.Sprintf("WaitForCertificateSecret/%s/%s", cert.Spec.SecretName, desc))
-	defer span.End()
-
-	return wait.PollImmediate(test.PollInterval, test.PollTimeout, func() (bool, error) {
-		secret, err := client.KubeClient.Kube.CoreV1().Secrets(test.ServingNamespace).Get(cert.Spec.SecretName, metav1.GetOptions{})
-
-		if apierrs.IsNotFound(err) {
-			return false, nil
-		} else if err != nil {
-			return true, fmt.Errorf("failed to get secret: %w", err)
-		}
-
-		block, _ := pem.Decode(secret.Data[corev1.TLSCertKey])
-		if block == nil {
-			// PEM files are text, so just dump it here.
-			t.Logf("Bad PEM file:\n%s", secret.Data[corev1.TLSCertKey])
-			return true, errors.New("failed to decode PEM data")
-		}
-
-		certData, err := x509.ParseCertificate(block.Bytes)
-		if err != nil {
-			return true, fmt.Errorf("failed to parse certificate: %w", err)
-		}
-
-		if got, want := certData.DNSNames, cert.Spec.DNSNames; !cmp.Equal(got, want) {
-			return true, fmt.Errorf("incorrect DNSNames in secret. Got %v, want %v", got, want)
-		}
-
-		return true, nil
-	})
-}
-
-// WaitForCertificateState polls the status of the Certificate called name from client
-// every PollInterval until inState returns `true` indicating it is done, returns an
-// error or PollTimeout. desc will be used to name the metric that is emitted to
-// track how long it took for name to get into the state checked by inState.
-func WaitForCertificateState(client *test.NetworkingClients, name string, inState func(r *v1alpha1.Certificate) (bool, error), desc string) error {
-	span := logging.GetEmitableSpan(context.Background(), fmt.Sprintf("WaitForCertificateState/%s/%s", name, desc))
-	defer span.End()
-
-	var lastState *v1alpha1.Certificate
-	return wait.PollImmediate(test.PollInterval, test.PollTimeout, func() (bool, error) {
-		var err error
-		lastState, err = client.Certificates.Get(name, metav1.GetOptions{})
-		if err != nil {
-			return true, err
-		}
-		return inState(lastState)
-	})
-}
-
-// VerifyChallenges verifies that the given certificate has the correct number
-// of HTTP01challenges and they contain valid data.
-func VerifyChallenges(t *testing.T, client *test.Clients, cert *v1alpha1.Certificate) {
-	t.Helper()
-
-	certDomains := sets.NewString(cert.Spec.DNSNames...)
-
-	for _, challenge := range cert.Status.HTTP01Challenges {
-		if challenge.ServiceName == "" {
-			t.Error("HTTP01 Challenge missing solver service name")
-		}
-
-		if !certDomains.Has(challenge.URL.Host) {
-			t.Errorf("HTTP01 Challenge host %s is not one of: %v", challenge.URL.Host, cert.Spec.DNSNames)
-		}
-		_, err := client.KubeClient.Kube.CoreV1().Services(challenge.ServiceNamespace).Get(challenge.ServiceName, metav1.GetOptions{})
-		if apierrs.IsNotFound(err) {
-			t.Errorf("failed to find solver service for challenge: %v", err)
-		}
-	}
-}
diff --git a/test/conformance/ingress/README.md b/test/conformance/ingress/README.md
deleted file mode 100644
index 5867ea8dc..000000000
--- a/test/conformance/ingress/README.md
+++ /dev/null
@@ -1,108 +0,0 @@
-# Ingress Conformance Testing
-
-This directory contains Ingress conformance tests for Knative Ingress resource.
-
-## Environment requirements
-
-### Development tools
-
-1. [`go`](https://golang.org/doc/install): The language `Knative Serving` is
-   built in (1.13 or later)
-1. [`ko`](https://github.com/google/ko): Build tool to setup the environment.
-1. [`kubectl`](https://kubernetes.io/docs/tasks/tools/install-kubectl/): For
-   managing development environments.
-
-### Test environment
-
-1. [A running `Knative Serving` cluster.](../../../DEVELOPMENT.md#prerequisites),
-   with the Ingress implementation of choice installed.
-   ```bash
-   # Set the Ingress class annotation to use in tests.
-   # Some examples:
-   #   export INGRESS_CLASS=gloo.ingress.networking.knative.dev      # Gloo Ingress
-   #   export INGRESS_CLASS=istio.ingress.networking.knative.dev     # Istio Ingress
-   #   export INGRESS_CLASS=kourier.ingress.networking.knative.dev   # Kourier Ingress
-   export INGRESS_CLASS=<your-ingress-class-annotation>
-   ```
-1. Knative Serving source code check out at `${SERVING_ROOT}`. Often this is
-   `$GO_PATH/src/go/knative.dev/serving`. This contains all the tests and the
-   test images.
-   ```bash
-   export SERVING_ROOT=<where-you-checked-out-knative/serving>
-   ```
-1. A docker repo containing [the test images](#test-images) `KO_DOCKER_REPO`:
-   The docker repository to which developer images should be pushed (e.g.
-   `gcr.io/[gcloud-project]`).
-
-   ```bash
-   export KO_DOCKER_REPO=<your-docker-repository>
-   ```
-
-1. The `knative-testing` resources
-
-   ```bash
-   ko apply -f "$SERVING_ROOT/test/config"
-   ```
-
-## Building the test images
-
-Note: this is only required when you run conformance/e2e tests locally with
-`go test` commands.
-
-The [`upload-test-images.sh`](../../upload-test-images.sh) script can be used to
-build and push the test images used by the conformance and e2e tests. The script
-expects your environment to be setup as described in
-[DEVELOPMENT.md](../../../DEVELOPMENT.md#install-requirements).
-
-To run the script for all end to end test images:
-
-```bash
-$SERVING_ROOT/test/upload-test-images.sh
-```
-
-## Adding a test
-
-Tests need to be exported and accessible downstream so they should be placed in
-non-test files (ie. sometest.go). Additionally, invoke your test in the default
-`RunConformance` function in [`run.go`](./run.go). This function is the entry
-point by which tests are executed.
-
-This approach aims to reduce the changes required when tests are added &
-removed.
-
-## Running the tests
-
-```bash
-cd "$SERVING_ROOT"
-
-# Set the endpoint of your Ingress installation.
-#
-# For example:
-#    export INGRESS_ENDPOINT="$(minikube ip):31380"
-export INGRESS_ENDPOINT=<your-ingress-ip/url>:<your-ingress-port>
-
-go test -v -tags=e2e -count=1 test/conformance/ingress \
-    --ingressClass="$INGRESS_CLASS" \
-    --ingressendpoint=$INGRESSENDPOINT
-```
-
-## Running the tests downstream
-
-To run all the conformance tests in your own repo we encourage adopting the
-[`RunConformance`](./run.go) function to run all your tests.
-
-To do so would look something like:
-
-```go
-package conformance
-
-import (
-	"testing"
-	"knative.dev/serving/test/conformance/ingress"
-)
-
-func TestYourIngressConformance(t *testing.T) {
-	ingress.RunConformance(t)
-}
-
-```
diff --git a/test/conformance/ingress/basic.go b/test/conformance/ingress/basic.go
deleted file mode 100644
index 907a70646..000000000
--- a/test/conformance/ingress/basic.go
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
-Copyright 2019 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 ingress
-
-import (
-	"testing"
-
-	"k8s.io/apimachinery/pkg/util/intstr"
-	"knative.dev/networking/pkg/apis/networking"
-	"knative.dev/networking/pkg/apis/networking/v1alpha1"
-	"knative.dev/serving/test"
-)
-
-// TestBasics verifies that a no frills Ingress exposes a simple Pod/Service via the public load balancer.
-func TestBasics(t *testing.T) {
-	t.Parallel()
-	clients := test.Setup(t)
-
-	name, port, cancel := CreateRuntimeService(t, clients, networking.ServicePortNameHTTP1)
-	defer cancel()
-
-	// Create a simple Ingress over the Service.
-	_, client, cancel := CreateIngressReady(t, clients, v1alpha1.IngressSpec{
-		Rules: []v1alpha1.IngressRule{{
-			Hosts:      []string{name + ".example.com"},
-			Visibility: v1alpha1.IngressVisibilityExternalIP,
-			HTTP: &v1alpha1.HTTPIngressRuleValue{
-				Paths: []v1alpha1.HTTPIngressPath{{
-					Splits: []v1alpha1.IngressBackendSplit{{
-						IngressBackend: v1alpha1.IngressBackend{
-							ServiceName:      name,
-							ServiceNamespace: test.ServingNamespace,
-							ServicePort:      intstr.FromInt(port),
-						},
-					}},
-				}},
-			},
-		}},
-	})
-	defer cancel()
-
-	RuntimeRequest(t, client, "http://"+name+".example.com")
-}
-
-// TestBasicsHTTP2 verifies that the same no-frills Ingress over a Service with http/2 configured
-// will see a ProtoMajor of 2.
-func TestBasicsHTTP2(t *testing.T) {
-	t.Parallel()
-	clients := test.Setup(t)
-
-	name, port, cancel := CreateRuntimeService(t, clients, networking.ServicePortNameH2C)
-	defer cancel()
-
-	// Create a simple Ingress over the Service.
-	_, client, cancel := CreateIngressReady(t, clients, v1alpha1.IngressSpec{
-		Rules: []v1alpha1.IngressRule{{
-			Hosts:      []string{name + ".example.com"},
-			Visibility: v1alpha1.IngressVisibilityExternalIP,
-			HTTP: &v1alpha1.HTTPIngressRuleValue{
-				Paths: []v1alpha1.HTTPIngressPath{{
-					Splits: []v1alpha1.IngressBackendSplit{{
-						IngressBackend: v1alpha1.IngressBackend{
-							ServiceName:      name,
-							ServiceNamespace: test.ServingNamespace,
-							ServicePort:      intstr.FromInt(port),
-						},
-					}},
-				}},
-			},
-		}},
-	})
-	defer cancel()
-
-	ri := RuntimeRequest(t, client, "http://"+name+".example.com")
-	if ri == nil {
-		return
-	}
-
-	if want, got := 2, ri.Request.ProtoMajor; want != got {
-		t.Errorf("ProtoMajor = %d, wanted %d", got, want)
-	}
-}
diff --git a/test/conformance/ingress/grpc.go b/test/conformance/ingress/grpc.go
deleted file mode 100644
index 403cb12ff..000000000
--- a/test/conformance/ingress/grpc.go
+++ /dev/null
@@ -1,219 +0,0 @@
-/*
-Copyright 2019 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 ingress
-
-import (
-	"context"
-	"fmt"
-	"math/rand"
-	"net"
-	"strings"
-	"testing"
-	"time"
-
-	"github.com/google/go-cmp/cmp"
-	"google.golang.org/grpc"
-	"k8s.io/apimachinery/pkg/util/intstr"
-	"k8s.io/apimachinery/pkg/util/sets"
-	"knative.dev/networking/pkg/apis/networking/v1alpha1"
-	"knative.dev/serving/test"
-	ping "knative.dev/serving/test/test_images/grpc-ping/proto"
-)
-
-// TestGRPC verifies that GRPC may be used via a simple Ingress.
-func TestGRPC(t *testing.T) {
-	t.Parallel()
-	clients := test.Setup(t)
-
-	const suffix = "- pong"
-	name, port, cancel := CreateGRPCService(t, clients, suffix)
-	defer cancel()
-
-	domain := name + ".example.com"
-
-	// Create a simple Ingress over the Service.
-	_, dialCtx, cancel := CreateIngressReadyDialContext(t, clients, v1alpha1.IngressSpec{
-		Rules: []v1alpha1.IngressRule{{
-			Hosts:      []string{domain},
-			Visibility: v1alpha1.IngressVisibilityExternalIP,
-			HTTP: &v1alpha1.HTTPIngressRuleValue{
-				Paths: []v1alpha1.HTTPIngressPath{{
-					Splits: []v1alpha1.IngressBackendSplit{{
-						IngressBackend: v1alpha1.IngressBackend{
-							ServiceName:      name,
-							ServiceNamespace: test.ServingNamespace,
-							ServicePort:      intstr.FromInt(port),
-						},
-					}},
-				}},
-			},
-		}},
-	})
-	defer cancel()
-
-	conn, err := grpc.Dial(
-		domain+":80",
-		grpc.WithInsecure(),
-		grpc.WithContextDialer(func(ctx context.Context, addr string) (net.Conn, error) {
-			return dialCtx(ctx, "unused", addr)
-		}),
-	)
-	if err != nil {
-		t.Fatal("Dial() =", err)
-	}
-	defer conn.Close()
-	pc := ping.NewPingServiceClient(conn)
-
-	ctx, cancel := context.WithTimeout(context.Background(), 60*time.Second)
-	defer cancel()
-
-	stream, err := pc.PingStream(ctx)
-	if err != nil {
-		t.Fatal("PingStream() =", err)
-	}
-
-	for i := 0; i < 100; i++ {
-		checkGRPCRoundTrip(t, stream, suffix)
-	}
-}
-
-// TestGRPCSplit verifies that websockets may be used across a traffic split.
-func TestGRPCSplit(t *testing.T) {
-	t.Parallel()
-	clients := test.Setup(t)
-
-	const suffixBlue = "- blue"
-	blueName, bluePort, cancel := CreateGRPCService(t, clients, suffixBlue)
-	defer cancel()
-
-	const suffixGreen = "- green"
-	greenName, greenPort, cancel := CreateGRPCService(t, clients, suffixGreen)
-	defer cancel()
-
-	// The suffixes we expect to see.
-	want := sets.NewString(suffixBlue, suffixGreen)
-
-	// Create a simple Ingress over the Service.
-	name := test.ObjectNameForTest(t)
-	domain := name + ".example.com"
-	_, dialCtx, cancel := CreateIngressReadyDialContext(t, clients, v1alpha1.IngressSpec{
-		Rules: []v1alpha1.IngressRule{{
-			Hosts:      []string{domain},
-			Visibility: v1alpha1.IngressVisibilityExternalIP,
-			HTTP: &v1alpha1.HTTPIngressRuleValue{
-				Paths: []v1alpha1.HTTPIngressPath{{
-					Splits: []v1alpha1.IngressBackendSplit{{
-						IngressBackend: v1alpha1.IngressBackend{
-							ServiceName:      blueName,
-							ServiceNamespace: test.ServingNamespace,
-							ServicePort:      intstr.FromInt(bluePort),
-						},
-						Percent: 50,
-					}, {
-						IngressBackend: v1alpha1.IngressBackend{
-							ServiceName:      greenName,
-							ServiceNamespace: test.ServingNamespace,
-							ServicePort:      intstr.FromInt(greenPort),
-						},
-						Percent: 50,
-					}},
-				}},
-			},
-		}},
-	})
-	defer cancel()
-
-	conn, err := grpc.Dial(
-		domain+":80",
-		grpc.WithInsecure(),
-		grpc.WithContextDialer(func(ctx context.Context, addr string) (net.Conn, error) {
-			return dialCtx(ctx, "unused", addr)
-		}),
-	)
-	if err != nil {
-		t.Fatal("Dial() =", err)
-	}
-	defer conn.Close()
-	pc := ping.NewPingServiceClient(conn)
-
-	ctx, cancel := context.WithTimeout(context.Background(), 60*time.Second)
-	defer cancel()
-
-	const maxRequests = 100
-	got := sets.NewString()
-	for i := 0; i < maxRequests; i++ {
-		stream, err := pc.PingStream(ctx)
-		if err != nil {
-			t.Errorf("PingStream() = %v", err)
-			continue
-		}
-
-		suffix := findGRPCSuffix(t, stream)
-		if suffix == "" {
-			continue
-		}
-		got.Insert(suffix)
-
-		for j := 0; j < 10; j++ {
-			checkGRPCRoundTrip(t, stream, suffix)
-		}
-
-		if want.Equal(got) {
-			// Short circuit if we've seen all splits.
-			return
-		}
-	}
-
-	// Us getting here means we haven't seen splits.
-	t.Errorf("(over %d requests) (-want, +got) = %s", maxRequests, cmp.Diff(want, got))
-}
-
-func findGRPCSuffix(t *testing.T, stream ping.PingService_PingStreamClient) string {
-	// Establish the suffix that corresponds to this stream.
-	message := fmt.Sprintf("ping - %d", rand.Intn(1000))
-	if err := stream.Send(&ping.Request{Msg: message}); err != nil {
-		t.Errorf("Error sending request: %v", err)
-		return ""
-	}
-
-	resp, err := stream.Recv()
-	if err != nil {
-		t.Errorf("Error receiving response: %v", err)
-		return ""
-	}
-	gotMsg := resp.Msg
-	if !strings.HasPrefix(gotMsg, message) {
-		t.Errorf("Recv() = %s, wanted %s prefix", gotMsg, message)
-		return ""
-	}
-	return strings.TrimSpace(strings.TrimPrefix(gotMsg, message))
-}
-
-func checkGRPCRoundTrip(t *testing.T, stream ping.PingService_PingStreamClient, suffix string) {
-	message := fmt.Sprintf("ping - %d", rand.Intn(1000))
-	if err := stream.Send(&ping.Request{Msg: message}); err != nil {
-		t.Errorf("Error sending request: %v", err)
-		return
-	}
-
-	// Read back the echoed message and compared with sent.
-	if resp, err := stream.Recv(); err != nil {
-		t.Errorf("Error receiving response: %v", err)
-	} else if got, want := resp.Msg, message+suffix; got != want {
-		t.Errorf("Recv() = %s, wanted %s", got, want)
-	}
-}
diff --git a/test/conformance/ingress/headers.go b/test/conformance/ingress/headers.go
deleted file mode 100644
index b5680db4c..000000000
--- a/test/conformance/ingress/headers.go
+++ /dev/null
@@ -1,288 +0,0 @@
-/*
-Copyright 2019 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 ingress
-
-import (
-	"net/http"
-	"testing"
-
-	"github.com/google/go-cmp/cmp"
-	"k8s.io/apimachinery/pkg/util/intstr"
-	"k8s.io/apimachinery/pkg/util/sets"
-	network "knative.dev/networking/pkg"
-	"knative.dev/networking/pkg/apis/networking"
-	"knative.dev/networking/pkg/apis/networking/v1alpha1"
-	"knative.dev/pkg/ptr"
-	"knative.dev/serving/test"
-)
-
-// TestTagHeaders verifies that an Ingress properly dispaches to backends based on the tag header
-//
-// See proposal doc for reference:
-// https://docs.google.com/document/d/12t_3NE4EqvW_l0hfVlQcAGKkwkAM56tTn2wN_JtHbSQ/edit?usp=sharing
-func TestTagHeaders(t *testing.T) {
-	t.Parallel()
-	clients := test.Setup(t)
-
-	name, port, cancel := CreateRuntimeService(t, clients, networking.ServicePortNameHTTP1)
-	t.Cleanup(cancel)
-
-	const (
-		tagName           = "the-tag"
-		backendHeader     = "Which-Backend"
-		backendWithTag    = "tag"
-		backendWithoutTag = "no-tag"
-	)
-
-	_, client, cancel := CreateIngressReady(t, clients, v1alpha1.IngressSpec{
-		Rules: []v1alpha1.IngressRule{{
-			Hosts:      []string{name + ".example.com"},
-			Visibility: v1alpha1.IngressVisibilityExternalIP,
-			HTTP: &v1alpha1.HTTPIngressRuleValue{
-				Paths: []v1alpha1.HTTPIngressPath{{
-					Headers: map[string]v1alpha1.HeaderMatch{
-						network.TagHeaderName: {
-							Exact: tagName,
-						},
-					},
-					AppendHeaders: map[string]string{
-						backendHeader: backendWithTag,
-					},
-					Splits: []v1alpha1.IngressBackendSplit{{
-						IngressBackend: v1alpha1.IngressBackend{
-							ServiceName:      name,
-							ServiceNamespace: test.ServingNamespace,
-							ServicePort:      intstr.FromInt(port),
-						},
-					}},
-				}, {
-					AppendHeaders: map[string]string{
-						backendHeader: backendWithoutTag,
-					},
-					Splits: []v1alpha1.IngressBackendSplit{{
-						IngressBackend: v1alpha1.IngressBackend{
-							ServiceName:      name,
-							ServiceNamespace: test.ServingNamespace,
-							ServicePort:      intstr.FromInt(port),
-						},
-					}},
-				}},
-			},
-		}},
-	})
-	t.Cleanup(cancel)
-
-	tests := []struct {
-		Name        string
-		TagHeader   *string
-		WantBackend string
-	}{{
-		Name:        "matching tag header",
-		TagHeader:   ptr.String(tagName),
-		WantBackend: backendWithTag,
-	}, {
-		Name:        "no tag header",
-		WantBackend: backendWithoutTag,
-	}, {
-		// Note: Behavior may change in Phase 2 (see Proposal doc)
-		Name:        "empty tag header",
-		TagHeader:   ptr.String(""),
-		WantBackend: backendWithoutTag,
-	}, {
-		// Note: Behavior may change in Phase 2 (see Proposal doc)
-		Name:        "non-matching tag header",
-		TagHeader:   ptr.String("not-" + tagName),
-		WantBackend: backendWithoutTag,
-	}}
-
-	for _, tt := range tests {
-		t.Run(tt.Name, func(t *testing.T) {
-			ros := []RequestOption{}
-
-			if tt.TagHeader != nil {
-				ros = append(ros, func(r *http.Request) {
-					r.Header.Set(network.TagHeaderName, *tt.TagHeader)
-				})
-			}
-
-			ri := RuntimeRequest(t, client, "http://"+name+".example.com", ros...)
-			if ri == nil {
-				t.Error("Couldn't make request")
-				return
-			}
-
-			if got, want := ri.Request.Headers.Get(backendHeader), tt.WantBackend; got != want {
-				t.Errorf("Header[%q] = %q, wanted %q", backendHeader, got, want)
-			}
-		})
-	}
-
-}
-
-// TestPreSplitSetHeaders verifies that an Ingress that specified AppendHeaders pre-split has the appropriate header(s) set.
-func TestPreSplitSetHeaders(t *testing.T) {
-	t.Parallel()
-	clients := test.Setup(t)
-
-	name, port, cancel := CreateRuntimeService(t, clients, networking.ServicePortNameHTTP1)
-	defer cancel()
-
-	const headerName = "Foo-Bar-Baz"
-
-	// Create a simple Ingress over the 10 Services.
-	_, client, cancel := CreateIngressReady(t, clients, v1alpha1.IngressSpec{
-		Rules: []v1alpha1.IngressRule{{
-			Hosts:      []string{name + ".example.com"},
-			Visibility: v1alpha1.IngressVisibilityExternalIP,
-			HTTP: &v1alpha1.HTTPIngressRuleValue{
-				Paths: []v1alpha1.HTTPIngressPath{{
-					AppendHeaders: map[string]string{
-						headerName: name,
-					},
-					Splits: []v1alpha1.IngressBackendSplit{{
-						IngressBackend: v1alpha1.IngressBackend{
-							ServiceName:      name,
-							ServiceNamespace: test.ServingNamespace,
-							ServicePort:      intstr.FromInt(port),
-						},
-					}},
-				}},
-			},
-		}},
-	})
-	defer cancel()
-
-	t.Run("Check without passing header", func(t *testing.T) {
-		ri := RuntimeRequest(t, client, "http://"+name+".example.com")
-		if ri == nil {
-			return
-		}
-
-		if got, want := ri.Request.Headers.Get(headerName), name; got != want {
-			t.Errorf("Headers[%q] = %q, wanted %q", headerName, got, want)
-		}
-	})
-
-	t.Run("Check with passing header", func(t *testing.T) {
-		ri := RuntimeRequest(t, client, "http://"+name+".example.com", func(req *http.Request) {
-			// Specify a value for the header to verify that implementations
-			// use set vs. append semantics.
-			req.Header.Set(headerName, "bogus")
-		})
-		if ri == nil {
-			return
-		}
-
-		if got, want := ri.Request.Headers.Get(headerName), name; got != want {
-			t.Errorf("Headers[%q] = %q, wanted %q", headerName, got, want)
-		}
-	})
-}
-
-// TestPostSplitSetHeaders verifies that an Ingress that specified AppendHeaders post-split has the appropriate header(s) set.
-func TestPostSplitSetHeaders(t *testing.T) {
-	t.Parallel()
-	clients := test.Setup(t)
-
-	const (
-		headerName  = "Foo-Bar-Baz"
-		splits      = 4
-		maxRequests = 100
-	)
-
-	backends := make([]v1alpha1.IngressBackendSplit, 0, splits)
-	names := make(sets.String, splits)
-	for i := 0; i < splits; i++ {
-		name, port, cancel := CreateRuntimeService(t, clients, networking.ServicePortNameHTTP1)
-		defer cancel()
-		backends = append(backends, v1alpha1.IngressBackendSplit{
-			IngressBackend: v1alpha1.IngressBackend{
-				ServiceName:      name,
-				ServiceNamespace: test.ServingNamespace,
-				ServicePort:      intstr.FromInt(port),
-			},
-			// Append different headers to each split, which lets us identify
-			// which backend we hit.
-			AppendHeaders: map[string]string{
-				headerName: name,
-			},
-			Percent: 100 / splits,
-		})
-		names.Insert(name)
-	}
-
-	// Create a simple Ingress over the 10 Services.
-	name := test.ObjectNameForTest(t)
-	_, client, cancel := CreateIngressReady(t, clients, v1alpha1.IngressSpec{
-		Rules: []v1alpha1.IngressRule{{
-			Hosts:      []string{name + ".example.com"},
-			Visibility: v1alpha1.IngressVisibilityExternalIP,
-			HTTP: &v1alpha1.HTTPIngressRuleValue{
-				Paths: []v1alpha1.HTTPIngressPath{{
-					Splits: backends,
-				}},
-			},
-		}},
-	})
-	defer cancel()
-
-	t.Run("Check without passing header", func(t *testing.T) {
-		// Make enough requests that the likelihood of us seeing each variation is high,
-		// but don't check the distribution of requests, as that isn't the point of this
-		// particular test.
-		seen := make(sets.String, len(names))
-		for i := 0; i < maxRequests; i++ {
-			ri := RuntimeRequest(t, client, "http://"+name+".example.com")
-			if ri == nil {
-				return
-			}
-			seen.Insert(ri.Request.Headers.Get(headerName))
-			if seen.Equal(names) {
-				// Short circuit if we've seen all headers.
-				return
-			}
-		}
-		// Us getting here means we haven't seen all headers, print the diff.
-		t.Errorf("(over %d requests) Header[%q] (-want, +got) = %s",
-			maxRequests, headerName, cmp.Diff(names, seen))
-	})
-
-	t.Run("Check with passing header", func(t *testing.T) {
-		// Make enough requests that the likelihood of us seeing each variation is high,
-		// but don't check the distribution of requests, as that isn't the point of this
-		// particular test.
-		seen := make(sets.String, len(names))
-		for i := 0; i < maxRequests; i++ {
-			ri := RuntimeRequest(t, client, "http://"+name+".example.com", func(req *http.Request) {
-				// Specify a value for the header to verify that implementations
-				// use set vs. append semantics.
-				req.Header.Set(headerName, "bogus")
-			})
-			if ri == nil {
-				return
-			}
-			seen.Insert(ri.Request.Headers.Get(headerName))
-			if seen.Equal(names) {
-				// Short circuit if we've seen all headers.
-				return
-			}
-		}
-		// Us getting here means we haven't seen all headers, print the diff.
-		t.Errorf("(over %d requests) Header[%q] (-want, +got) = %s",
-			maxRequests, headerName, cmp.Diff(names, seen))
-	})
-}
diff --git a/test/conformance/ingress/hosts.go b/test/conformance/ingress/hosts.go
deleted file mode 100644
index 78c76bad8..000000000
--- a/test/conformance/ingress/hosts.go
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
-Copyright 2019 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 ingress
-
-import (
-	"testing"
-
-	"k8s.io/apimachinery/pkg/util/intstr"
-	"knative.dev/networking/pkg/apis/networking"
-	"knative.dev/networking/pkg/apis/networking/v1alpha1"
-	"knative.dev/serving/test"
-)
-
-// TestMultipleHosts verifies that an Ingress can respond to multiple hosts.
-func TestMultipleHosts(t *testing.T) {
-	t.Parallel()
-	clients := test.Setup(t)
-
-	name, port, cancel := CreateRuntimeService(t, clients, networking.ServicePortNameHTTP1)
-	defer cancel()
-
-	// TODO(mattmoor): Once .svc.cluster.local stops being a special case
-	// for Visibility, add it here.
-	hosts := []string{
-		"foo.com",
-		"www.foo.com",
-		"a-b-1.something-really-really-long.knative.dev",
-		"add.your.interesting.domain.here.io",
-	}
-
-	// Create a simple Ingress over the Service.
-	_, client, cancel := CreateIngressReady(t, clients, v1alpha1.IngressSpec{
-		Rules: []v1alpha1.IngressRule{{
-			Hosts:      hosts,
-			Visibility: v1alpha1.IngressVisibilityExternalIP,
-			HTTP: &v1alpha1.HTTPIngressRuleValue{
-				Paths: []v1alpha1.HTTPIngressPath{{
-					Splits: []v1alpha1.IngressBackendSplit{{
-						IngressBackend: v1alpha1.IngressBackend{
-							ServiceName:      name,
-							ServiceNamespace: test.ServingNamespace,
-							ServicePort:      intstr.FromInt(port),
-						},
-					}},
-				}},
-			},
-		}},
-	})
-	defer cancel()
-
-	for _, host := range hosts {
-		RuntimeRequest(t, client, "http://"+host)
-	}
-}
diff --git a/test/conformance/ingress/path.go b/test/conformance/ingress/path.go
deleted file mode 100644
index 8de136699..000000000
--- a/test/conformance/ingress/path.go
+++ /dev/null
@@ -1,249 +0,0 @@
-/*
-Copyright 2019 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 ingress
-
-import (
-	"errors"
-	"math"
-	"testing"
-
-	"k8s.io/apimachinery/pkg/util/intstr"
-	"k8s.io/apimachinery/pkg/util/sets"
-	"knative.dev/networking/pkg/apis/networking"
-	"knative.dev/networking/pkg/apis/networking/v1alpha1"
-	"knative.dev/pkg/pool"
-	"knative.dev/serving/test"
-)
-
-// TestPath verifies that an Ingress properly dispatches to backends based on the path of the URL.
-func TestPath(t *testing.T) {
-	t.Parallel()
-	clients := test.Setup(t)
-
-	// For /foo
-	fooName, fooPort, cancel := CreateRuntimeService(t, clients, networking.ServicePortNameHTTP1)
-	defer cancel()
-
-	// For /bar
-	barName, barPort, cancel := CreateRuntimeService(t, clients, networking.ServicePortNameHTTP1)
-	defer cancel()
-
-	// For /baz
-	bazName, bazPort, cancel := CreateRuntimeService(t, clients, networking.ServicePortNameHTTP1)
-	defer cancel()
-
-	name, port, cancel := CreateRuntimeService(t, clients, networking.ServicePortNameHTTP1)
-	defer cancel()
-
-	// Use a post-split injected header to establish which split we are sending traffic to.
-	const headerName = "Which-Backend"
-
-	_, client, cancel := CreateIngressReady(t, clients, v1alpha1.IngressSpec{
-		Rules: []v1alpha1.IngressRule{{
-			Hosts:      []string{name + ".example.com"},
-			Visibility: v1alpha1.IngressVisibilityExternalIP,
-			HTTP: &v1alpha1.HTTPIngressRuleValue{
-				Paths: []v1alpha1.HTTPIngressPath{{
-					Path: "/foo",
-					Splits: []v1alpha1.IngressBackendSplit{{
-						IngressBackend: v1alpha1.IngressBackend{
-							ServiceName:      fooName,
-							ServiceNamespace: test.ServingNamespace,
-							ServicePort:      intstr.FromInt(fooPort),
-						},
-						// Append different headers to each split, which lets us identify
-						// which backend we hit.
-						AppendHeaders: map[string]string{
-							headerName: fooName,
-						},
-						Percent: 100,
-					}},
-				}, {
-					Path: "/bar",
-					Splits: []v1alpha1.IngressBackendSplit{{
-						IngressBackend: v1alpha1.IngressBackend{
-							ServiceName:      barName,
-							ServiceNamespace: test.ServingNamespace,
-							ServicePort:      intstr.FromInt(barPort),
-						},
-						// Append different headers to each split, which lets us identify
-						// which backend we hit.
-						AppendHeaders: map[string]string{
-							headerName: barName,
-						},
-						Percent: 100,
-					}},
-				}, {
-					Path: "/baz",
-					Splits: []v1alpha1.IngressBackendSplit{{
-						IngressBackend: v1alpha1.IngressBackend{
-							ServiceName:      bazName,
-							ServiceNamespace: test.ServingNamespace,
-							ServicePort:      intstr.FromInt(bazPort),
-						},
-						// Append different headers to each split, which lets us identify
-						// which backend we hit.
-						AppendHeaders: map[string]string{
-							headerName: bazName,
-						},
-						Percent: 100,
-					}},
-				}, {
-					Splits: []v1alpha1.IngressBackendSplit{{
-						IngressBackend: v1alpha1.IngressBackend{
-							ServiceName:      name,
-							ServiceNamespace: test.ServingNamespace,
-							ServicePort:      intstr.FromInt(port),
-						},
-						// Append different headers to each split, which lets us identify
-						// which backend we hit.
-						AppendHeaders: map[string]string{
-							headerName: name,
-						},
-						Percent: 100,
-					}},
-				}},
-			},
-		}},
-	})
-	defer cancel()
-
-	tests := map[string]string{
-		"/foo":  fooName,
-		"/bar":  barName,
-		"/baz":  bazName,
-		"":      name,
-		"/asdf": name,
-	}
-
-	for path, want := range tests {
-		t.Run(path, func(t *testing.T) {
-			ri := RuntimeRequest(t, client, "http://"+name+".example.com"+path)
-			if ri == nil {
-				return
-			}
-
-			got := ri.Request.Headers.Get(headerName)
-			if got != want {
-				t.Errorf("Header[%q] = %q, wanted %q", headerName, got, want)
-			}
-		})
-	}
-}
-
-func TestPathAndPercentageSplit(t *testing.T) {
-	t.Parallel()
-	clients := test.Setup(t)
-
-	fooName, fooPort, cancel := CreateRuntimeService(t, clients, networking.ServicePortNameHTTP1)
-	defer cancel()
-
-	barName, barPort, cancel := CreateRuntimeService(t, clients, networking.ServicePortNameHTTP1)
-	defer cancel()
-
-	name, port, cancel := CreateRuntimeService(t, clients, networking.ServicePortNameHTTP1)
-	defer cancel()
-
-	// Use a post-split injected header to establish which split we are sending traffic to.
-	const headerName = "Which-Backend"
-
-	_, client, cancel := CreateIngressReady(t, clients, v1alpha1.IngressSpec{
-		Rules: []v1alpha1.IngressRule{{
-			Hosts:      []string{name + ".example.com"},
-			Visibility: v1alpha1.IngressVisibilityExternalIP,
-			HTTP: &v1alpha1.HTTPIngressRuleValue{
-				Paths: []v1alpha1.HTTPIngressPath{{
-					Path: "/foo",
-					Splits: []v1alpha1.IngressBackendSplit{{
-						IngressBackend: v1alpha1.IngressBackend{
-							ServiceName:      fooName,
-							ServiceNamespace: test.ServingNamespace,
-							ServicePort:      intstr.FromInt(fooPort),
-						},
-						AppendHeaders: map[string]string{
-							headerName: fooName,
-						},
-						Percent: 50,
-					}, {
-						IngressBackend: v1alpha1.IngressBackend{
-							ServiceName:      barName,
-							ServiceNamespace: test.ServingNamespace,
-							ServicePort:      intstr.FromInt(barPort),
-						},
-						AppendHeaders: map[string]string{
-							headerName: barName,
-						},
-						Percent: 50,
-					}},
-				}, {
-					Splits: []v1alpha1.IngressBackendSplit{{
-						IngressBackend: v1alpha1.IngressBackend{
-							ServiceName:      name,
-							ServiceNamespace: test.ServingNamespace,
-							ServicePort:      intstr.FromInt(port),
-						},
-						// Append different headers to each split, which lets us identify
-						// which backend we hit.
-						AppendHeaders: map[string]string{
-							headerName: name,
-						},
-						Percent: 100,
-					}},
-				}},
-			},
-		}},
-	})
-	defer cancel()
-
-	const (
-		total     = 1000
-		totalHalf = total / 2
-		tolerance = total * 0.15
-	)
-	wantKeys := sets.NewString(fooName, barName)
-	resultCh := make(chan string, total)
-
-	wg := pool.New(8)
-
-	for i := 0; i < total; i++ {
-		wg.Go(func() error {
-			ri := RuntimeRequest(t, client, "http://"+name+".example.com/foo")
-			if ri == nil {
-				return errors.New("failed to request")
-			}
-			resultCh <- ri.Request.Headers.Get(headerName)
-			return nil
-		})
-	}
-	if err := wg.Wait(); err != nil {
-		t.Errorf("Error while sending requests: %v", err)
-	}
-	close(resultCh)
-
-	got := make(map[string]float64, len(wantKeys))
-	for r := range resultCh {
-		got[r]++
-	}
-	for k, v := range got {
-		if !wantKeys.Has(k) {
-			t.Errorf("%s is not in the expected header say %v", k, wantKeys)
-		}
-		if math.Abs(v-totalHalf) > tolerance {
-			t.Errorf("Header %s got: %v times, want in [%v, %v] range", k, v, totalHalf-tolerance, totalHalf+tolerance)
-		}
-	}
-}
diff --git a/test/conformance/ingress/percentage.go b/test/conformance/ingress/percentage.go
deleted file mode 100644
index b3763ed52..000000000
--- a/test/conformance/ingress/percentage.go
+++ /dev/null
@@ -1,133 +0,0 @@
-/*
-Copyright 2019 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 ingress
-
-import (
-	"errors"
-	"math"
-	"testing"
-
-	"k8s.io/apimachinery/pkg/util/intstr"
-	"knative.dev/networking/pkg/apis/networking"
-	"knative.dev/networking/pkg/apis/networking/v1alpha1"
-	"knative.dev/pkg/pool"
-	"knative.dev/serving/test"
-)
-
-// TestPercentage verifies that an Ingress splitting over multiple backends respects
-// the given percentage distribution.
-func TestPercentage(t *testing.T) {
-	t.Parallel()
-	clients := test.Setup(t)
-
-	// Use a post-split injected header to establish which split we are sending traffic to.
-	const headerName = "Foo-Bar-Baz"
-
-	backends := make([]v1alpha1.IngressBackendSplit, 0, 10)
-	weights := make(map[string]float64, len(backends))
-
-	// Double the percentage of the split each iteration until it would overflow, and then
-	// give the last route the remainder.
-	percent, total := 1, 0
-	for i := 0; i < 10; i++ {
-		name, port, cancel := CreateRuntimeService(t, clients, networking.ServicePortNameHTTP1)
-		defer cancel()
-		backends = append(backends, v1alpha1.IngressBackendSplit{
-			IngressBackend: v1alpha1.IngressBackend{
-				ServiceName:      name,
-				ServiceNamespace: test.ServingNamespace,
-				ServicePort:      intstr.FromInt(port),
-			},
-			// Append different headers to each split, which lets us identify
-			// which backend we hit.
-			AppendHeaders: map[string]string{
-				headerName: name,
-			},
-			Percent: percent,
-		})
-		weights[name] = float64(percent)
-
-		total += percent
-		percent *= 2
-		// Cap the final non-zero bucket so that we total 100%
-		// After that, this will zero out remaining buckets.
-		if total+percent > 100 {
-			percent = 100 - total
-		}
-	}
-
-	// Create a simple Ingress over the 10 Services.
-	name := test.ObjectNameForTest(t)
-	_, client, cancel := CreateIngressReady(t, clients, v1alpha1.IngressSpec{
-		Rules: []v1alpha1.IngressRule{{
-			Hosts:      []string{name + ".example.com"},
-			Visibility: v1alpha1.IngressVisibilityExternalIP,
-			HTTP: &v1alpha1.HTTPIngressRuleValue{
-				Paths: []v1alpha1.HTTPIngressPath{{
-					Splits: backends,
-				}},
-			},
-		}},
-	})
-	defer cancel()
-
-	// Create a large enough population of requests that we can reasonably assess how
-	// well the Ingress respected the percentage split.
-	seen := make(map[string]float64, len(backends))
-
-	const (
-		// The total number of requests to make (as a float to avoid conversions in later computations).
-		totalRequests = 1000.0
-		// The increment to make for each request, so that the values of seen reflect the
-		// percentage of the total number of requests we are making.
-		increment = 100.0 / totalRequests
-		// Allow the Ingress to be within 10% of the configured value.
-		margin = 10.0
-	)
-	wg := pool.New(8)
-	resultCh := make(chan string, totalRequests)
-
-	for i := 0.0; i < totalRequests; i++ {
-		wg.Go(func() error {
-			ri := RuntimeRequest(t, client, "http://"+name+".example.com")
-			if ri == nil {
-				return errors.New("failed to request")
-			}
-			resultCh <- ri.Request.Headers.Get(headerName)
-			return nil
-		})
-	}
-	if err := wg.Wait(); err != nil {
-		t.Errorf("Error while sending requests: %v", err)
-	}
-	close(resultCh)
-
-	for r := range resultCh {
-		seen[r] += increment
-	}
-
-	for name, want := range weights {
-		got := seen[name]
-		switch {
-		case want == 0.0 && got > 0.0:
-			// For 0% targets, we have tighter requirements.
-			t.Errorf("Target %q received traffic, wanted none (0%% target).", name)
-		case math.Abs(got-want) > margin:
-			t.Errorf("Target %q received %f%%, wanted %f +/- %f", name, got, want, margin)
-		}
-	}
-}
diff --git a/test/conformance/ingress/retry.go b/test/conformance/ingress/retry.go
deleted file mode 100644
index 640e3c88e..000000000
--- a/test/conformance/ingress/retry.go
+++ /dev/null
@@ -1,138 +0,0 @@
-/*
-Copyright 2019 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 ingress
-
-import (
-	"fmt"
-	"net/http"
-	"testing"
-
-	"k8s.io/apimachinery/pkg/util/intstr"
-	"knative.dev/networking/pkg/apis/networking/v1alpha1"
-	"knative.dev/serving/test"
-)
-
-// TestRetry verifies that an Ingress configured to retry N times properly masks transient failures.
-func TestRetry(t *testing.T) {
-	for i := 2; i < 12; i++ {
-		i := i
-		t.Run(fmt.Sprintf("period=%d,attempts=%d", i, i), func(t *testing.T) {
-			t.Parallel()
-			clients := test.Setup(t)
-			// When the period matches, then it shouldn't fail.
-			name, port, cancel := CreateFlakyService(t, clients, i)
-			defer cancel()
-
-			domain := name + ".example.com"
-
-			// Create a simple Ingress over the Service.
-			_, client, cancel := CreateIngressReady(t, clients, v1alpha1.IngressSpec{
-				Rules: []v1alpha1.IngressRule{{
-					Hosts:      []string{domain},
-					Visibility: v1alpha1.IngressVisibilityExternalIP,
-					HTTP: &v1alpha1.HTTPIngressRuleValue{
-						Paths: []v1alpha1.HTTPIngressPath{{
-							Retries: retries(i),
-							Splits: []v1alpha1.IngressBackendSplit{{
-								IngressBackend: v1alpha1.IngressBackend{
-									ServiceName:      name,
-									ServiceNamespace: test.ServingNamespace,
-									ServicePort:      intstr.FromInt(port),
-								},
-							}},
-						}},
-					},
-				}},
-			})
-			defer cancel()
-
-			for j := 0; j < 5; j++ {
-				resp, err := client.Get("http://" + domain)
-				if err != nil {
-					t.Errorf("Error making GET request: %v", err)
-					continue
-				}
-				defer resp.Body.Close()
-				if resp.StatusCode != http.StatusOK {
-					t.Errorf("Got non-OK status: %d", resp.StatusCode)
-					DumpResponse(t, resp)
-				}
-			}
-		})
-
-		t.Run(fmt.Sprintf("period=%d,attempts=%d", i, i-1), func(t *testing.T) {
-			t.Parallel()
-			clients := test.Setup(t)
-			// When the period matches, then it shouldn't fail.
-			name, port, cancel := CreateFlakyService(t, clients, i)
-			defer cancel()
-
-			domain := name + ".example.com"
-
-			// Create a simple Ingress over the Service.
-			_, client, cancel := CreateIngressReady(t, clients, v1alpha1.IngressSpec{
-				Rules: []v1alpha1.IngressRule{{
-					Hosts:      []string{domain},
-					Visibility: v1alpha1.IngressVisibilityExternalIP,
-					HTTP: &v1alpha1.HTTPIngressRuleValue{
-						Paths: []v1alpha1.HTTPIngressPath{{
-							Retries: retries(i - 1),
-							Splits: []v1alpha1.IngressBackendSplit{{
-								IngressBackend: v1alpha1.IngressBackend{
-									ServiceName:      name,
-									ServiceNamespace: test.ServingNamespace,
-									ServicePort:      intstr.FromInt(port),
-								},
-							}},
-						}},
-					},
-				}},
-			})
-			defer cancel()
-
-			// When the period is one more than the number of attempts (retries+1), then what we should see is:
-			//   500 {count=4}
-			//   200 {count=5}
-			//   500 {count=9}
-			//   200 {count=10}
-			//   500 {count=14}
-			//   200 {count=15}
-			current, next := http.StatusInternalServerError, http.StatusOK
-			for j := 0; j < 5; j++ {
-				resp, err := client.Get("http://" + domain)
-				if err != nil {
-					t.Errorf("Error making GET request: %v", err)
-					continue
-				}
-				defer resp.Body.Close()
-				if want, got := current, resp.StatusCode; got != want {
-					t.Errorf("Status = %d, wanted %d", got, want)
-					DumpResponse(t, resp)
-				}
-				// Swap things.
-				current, next = next, current
-			}
-		})
-	}
-}
-
-func retries(attempts int) *v1alpha1.HTTPRetry {
-	return &v1alpha1.HTTPRetry{
-		// retries is one less than the number of attempts
-		Attempts: attempts - 1,
-	}
-}
diff --git a/test/conformance/ingress/rewrite.go b/test/conformance/ingress/rewrite.go
deleted file mode 100644
index 3d4290b73..000000000
--- a/test/conformance/ingress/rewrite.go
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
-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 ingress
-
-import (
-	"testing"
-
-	"k8s.io/apimachinery/pkg/util/intstr"
-	"knative.dev/networking/pkg/apis/networking"
-	"knative.dev/networking/pkg/apis/networking/v1alpha1"
-	"knative.dev/serving/test"
-)
-
-// TestRewriteHost verifies that a RewriteHost rule can be used to implement vanity URLs.
-func TestRewriteHost(t *testing.T) {
-	t.Parallel()
-	clients := test.Setup(t)
-
-	name, port, cancel := CreateRuntimeService(t, clients, networking.ServicePortNameHTTP1)
-	defer cancel()
-
-	// Create a simple Ingress over the Service.
-	_, _, cancel = CreateIngressReady(t, clients, v1alpha1.IngressSpec{
-		Rules: []v1alpha1.IngressRule{{
-			Visibility: v1alpha1.IngressVisibilityClusterLocal,
-			Hosts:      []string{name + ".example.com"},
-			HTTP: &v1alpha1.HTTPIngressRuleValue{
-				Paths: []v1alpha1.HTTPIngressPath{{
-					Splits: []v1alpha1.IngressBackendSplit{{
-						IngressBackend: v1alpha1.IngressBackend{
-							ServiceName:      name,
-							ServiceNamespace: test.ServingNamespace,
-							ServicePort:      intstr.FromInt(port),
-						},
-					}},
-				}},
-			},
-		}},
-	})
-	defer cancel()
-
-	// Now create a RewriteHost ingress to point a custom Host at the Service
-	_, client, cancel := CreateIngressReady(t, clients, v1alpha1.IngressSpec{
-		Rules: []v1alpha1.IngressRule{{
-			Hosts:      []string{"vanity.ismy.name", "vanity.isalsomy.number"},
-			Visibility: v1alpha1.IngressVisibilityExternalIP,
-			HTTP: &v1alpha1.HTTPIngressRuleValue{
-				Paths: []v1alpha1.HTTPIngressPath{{
-					RewriteHost: name + ".example.com",
-				}},
-			},
-		}},
-	})
-	defer cancel()
-
-	RuntimeRequest(t, client, "http://vanity.ismy.name")
-	RuntimeRequest(t, client, "http://vanity.isalsomy.number")
-}
diff --git a/test/conformance/ingress/run.go b/test/conformance/ingress/run.go
deleted file mode 100644
index 7882a5c8f..000000000
--- a/test/conformance/ingress/run.go
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
-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 ingress
-
-import (
-	"testing"
-
-	"knative.dev/serving/test"
-)
-
-// RunConformance will run ingress conformance tests
-//
-// Depending on the options it may test alpha and beta features
-func RunConformance(t *testing.T) {
-	t.Run("basics", TestBasics)
-	t.Run("basics/http2", TestBasicsHTTP2)
-
-	t.Run("grpc", TestGRPC)
-	t.Run("grpc/split", TestGRPCSplit)
-
-	t.Run("headers/pre-split", TestPreSplitSetHeaders)
-	t.Run("headers/post-split", TestPostSplitSetHeaders)
-
-	t.Run("hosts/multiple", TestMultipleHosts)
-
-	t.Run("dispatch/path", TestPath)
-	t.Run("dispatch/percentage", TestPercentage)
-	t.Run("dispatch/path_and_percentage", TestPathAndPercentageSplit)
-
-	t.Run("retry", TestRetry)
-	t.Run("timeout", TestTimeout)
-
-	t.Run("tls", TestIngressTLS)
-	t.Run("update", TestUpdate)
-
-	t.Run("visibility", TestVisibility)
-	t.Run("visibility/split", TestVisibilitySplit)
-	t.Run("visibility/path", TestVisibilityPath)
-
-	t.Run("websocket", TestWebsocket)
-	t.Run("websocket/split", TestWebsocketSplit)
-
-	// TODO(dprotaso) we'll need something more robust
-	// in the long term that lets downstream
-	// implementations to better select which tests
-	// should be run -  selection across various
-	// dimensions
-	// ie. state - alpha, beta, ga
-	// ie. requirement - must, should, may
-
-	//if test.ServingFlags.EnableBetaFeatures {
-	// Add your conformance test for beta features
-	//}
-
-	if test.ServingFlags.EnableAlphaFeatures {
-		// Add your conformance test for alpha features
-		t.Run("headers/tags", TestTagHeaders)
-		t.Run("host-rewrite", TestRewriteHost)
-	}
-}
diff --git a/test/conformance/ingress/run_test.go b/test/conformance/ingress/run_test.go
deleted file mode 100644
index 0ebadcce5..000000000
--- a/test/conformance/ingress/run_test.go
+++ /dev/null
@@ -1,25 +0,0 @@
-// +build e2e
-
-/*
-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 ingress
-
-import "testing"
-
-func TestIngressConformance(t *testing.T) {
-	RunConformance(t)
-}
diff --git a/test/conformance/ingress/timeout.go b/test/conformance/ingress/timeout.go
deleted file mode 100644
index bca3de323..000000000
--- a/test/conformance/ingress/timeout.go
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
-Copyright 2019 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 ingress
-
-import (
-	"fmt"
-	"net/http"
-	"testing"
-	"time"
-
-	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
-	"k8s.io/apimachinery/pkg/util/intstr"
-	"knative.dev/networking/pkg/apis/networking/v1alpha1"
-	"knative.dev/serving/test"
-)
-
-// TestTimeout verifies that an Ingress configured with a timeout respects that.
-func TestTimeout(t *testing.T) {
-	t.Parallel()
-	clients := test.Setup(t)
-
-	name, port, cancel := CreateTimeoutService(t, clients)
-	defer cancel()
-
-	// The timeout, and an epsilon value to use as jitter for testing requests
-	// either hit or miss the timeout (without getting so close that we flake).
-	const (
-		timeout = 1 * time.Second
-		epsilon = 100 * time.Millisecond
-	)
-
-	// Create a simple Ingress over the Service.
-	_, client, cancel := CreateIngressReady(t, clients, v1alpha1.IngressSpec{
-		Rules: []v1alpha1.IngressRule{{
-			Hosts:      []string{name + ".example.com"},
-			Visibility: v1alpha1.IngressVisibilityExternalIP,
-			HTTP: &v1alpha1.HTTPIngressRuleValue{
-				Paths: []v1alpha1.HTTPIngressPath{{
-					Timeout: &metav1.Duration{Duration: timeout},
-					Splits: []v1alpha1.IngressBackendSplit{{
-						IngressBackend: v1alpha1.IngressBackend{
-							ServiceName:      name,
-							ServiceNamespace: test.ServingNamespace,
-							ServicePort:      intstr.FromInt(port),
-						},
-					}},
-				}},
-			},
-		}},
-	})
-	defer cancel()
-
-	tests := []struct {
-		name         string
-		code         int
-		initialDelay time.Duration
-		delay        time.Duration
-	}{{
-		name: "no delays is OK",
-		code: http.StatusOK,
-	}, {
-		name:  "large delay after headers is ok",
-		code:  http.StatusOK,
-		delay: timeout + timeout,
-	}, {
-		name:         "initial delay less than timeout is ok",
-		code:         http.StatusOK,
-		initialDelay: timeout - epsilon,
-	}, {
-		name:         "initial delay over timeout is NOT ok",
-		code:         http.StatusGatewayTimeout,
-		initialDelay: timeout + epsilon,
-	}}
-
-	for _, test := range tests {
-		t.Run(test.name, func(t *testing.T) {
-			checkTimeout(t, client, name, test.code, test.initialDelay, test.delay)
-		})
-	}
-}
-
-func checkTimeout(t *testing.T, client *http.Client, name string, code int, initial time.Duration, timeout time.Duration) {
-	t.Helper()
-
-	resp, err := client.Get(fmt.Sprintf("http://%s.example.com?initialTimeout=%d&timeout=%d",
-		name, initial.Milliseconds(), timeout.Milliseconds()))
-	if err != nil {
-		t.Fatal("Error making GET request:", err)
-	}
-	defer resp.Body.Close()
-	if resp.StatusCode != code {
-		t.Errorf("Unexpected status code: %d, wanted %d", resp.StatusCode, code)
-		DumpResponse(t, resp)
-	}
-}
diff --git a/test/conformance/ingress/tls.go b/test/conformance/ingress/tls.go
deleted file mode 100644
index fdad1c4e1..000000000
--- a/test/conformance/ingress/tls.go
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
-Copyright 2019 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 ingress
-
-import (
-	"testing"
-
-	"k8s.io/apimachinery/pkg/util/intstr"
-	"knative.dev/networking/pkg/apis/networking"
-	"knative.dev/networking/pkg/apis/networking/v1alpha1"
-	"knative.dev/serving/test"
-)
-
-// TestIngressTLS verifies that the Ingress properly handles the TLS field.
-func TestIngressTLS(t *testing.T) {
-	t.Parallel()
-	clients := test.Setup(t)
-
-	name, port, cancel := CreateRuntimeService(t, clients, networking.ServicePortNameHTTP1)
-	defer cancel()
-
-	hosts := []string{name + ".example.com"}
-
-	secretName, cancel := CreateTLSSecret(t, clients, hosts)
-	defer cancel()
-
-	_, client, cancel := CreateIngressReady(t, clients, v1alpha1.IngressSpec{
-		Rules: []v1alpha1.IngressRule{{
-			Hosts:      hosts,
-			Visibility: v1alpha1.IngressVisibilityExternalIP,
-			HTTP: &v1alpha1.HTTPIngressRuleValue{
-				Paths: []v1alpha1.HTTPIngressPath{{
-					Splits: []v1alpha1.IngressBackendSplit{{
-						IngressBackend: v1alpha1.IngressBackend{
-							ServiceName:      name,
-							ServiceNamespace: test.ServingNamespace,
-							ServicePort:      intstr.FromInt(port),
-						},
-					}},
-				}},
-			},
-		}},
-		TLS: []v1alpha1.IngressTLS{{
-			Hosts:           hosts,
-			SecretName:      secretName,
-			SecretNamespace: test.ServingNamespace,
-		}},
-	})
-	defer cancel()
-
-	t.Run("verify HTTP", func(t *testing.T) {
-		RuntimeRequest(t, client, "http://"+name+".example.com")
-	})
-
-	t.Run("verify HTTPS", func(t *testing.T) {
-		RuntimeRequest(t, client, "https://"+name+".example.com")
-	})
-}
-
-// TODO(mattmoor): Consider adding variants where we have multiple hosts with distinct certificates.
diff --git a/test/conformance/ingress/update.go b/test/conformance/ingress/update.go
deleted file mode 100644
index 50ae44bb9..000000000
--- a/test/conformance/ingress/update.go
+++ /dev/null
@@ -1,202 +0,0 @@
-/*
-Copyright 2019 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 ingress
-
-import (
-	"context"
-	"net/http"
-	"testing"
-	"time"
-
-	"k8s.io/apimachinery/pkg/util/intstr"
-	"knative.dev/networking/pkg/apis/networking"
-	"knative.dev/networking/pkg/apis/networking/v1alpha1"
-	"knative.dev/serving/test"
-)
-
-// Header to disambiguate what version we're talking to.
-const updateHeaderName = "Who-Are-You"
-
-// TestUpdate verifies that when the network programming changes that traffic isn't dropped.
-func TestUpdate(t *testing.T) {
-	t.Parallel()
-	clients := test.Setup(t)
-
-	firstName, firstPort, firstCancel := CreateRuntimeService(t, clients, networking.ServicePortNameHTTP1)
-
-	// Create a simple Ingress over the Service.
-	hostname := test.ObjectNameForTest(t)
-	ing, client, cancel := CreateIngressReady(t, clients, v1alpha1.IngressSpec{
-		Rules: []v1alpha1.IngressRule{{
-			Hosts:      []string{hostname + ".example.com"},
-			Visibility: v1alpha1.IngressVisibilityExternalIP,
-			HTTP: &v1alpha1.HTTPIngressRuleValue{
-				Paths: []v1alpha1.HTTPIngressPath{{
-					Splits: []v1alpha1.IngressBackendSplit{{
-						IngressBackend: v1alpha1.IngressBackend{
-							ServiceName:      firstName,
-							ServiceNamespace: test.ServingNamespace,
-							ServicePort:      intstr.FromInt(firstPort),
-						},
-						// Append different headers to each split, which lets us identify
-						// which backend we hit.
-						AppendHeaders: map[string]string{
-							updateHeaderName: firstName,
-						},
-					}},
-				}},
-			},
-		}},
-	})
-
-	previousVersionCancel := func() {
-		t.Logf("Tearing down %q", firstName)
-		firstCancel()
-	}
-
-	proberCancel := checkOK(t, "http://"+hostname+".example.com", client)
-	defer func() {
-		proberCancel()
-		previousVersionCancel()
-		cancel()
-	}()
-
-	// Give the prober a chance to get started.
-	time.Sleep(1 * time.Second)
-
-	// First test with only sentinel changes.
-	for i := 0; i < 10; i++ {
-		sentinel := test.ObjectNameForTest(t)
-
-		t.Logf("Rolling out %q w/ %q", firstName, sentinel)
-
-		// Update the Ingress, and wait for it to report ready.
-		UpdateIngressReady(t, clients, ing.Name, v1alpha1.IngressSpec{
-			Rules: []v1alpha1.IngressRule{{
-				Hosts:      []string{hostname + ".example.com"},
-				Visibility: v1alpha1.IngressVisibilityExternalIP,
-				HTTP: &v1alpha1.HTTPIngressRuleValue{
-					Paths: []v1alpha1.HTTPIngressPath{{
-						Splits: []v1alpha1.IngressBackendSplit{{
-							IngressBackend: v1alpha1.IngressBackend{
-								ServiceName:      firstName,
-								ServiceNamespace: test.ServingNamespace,
-								ServicePort:      intstr.FromInt(firstPort),
-							},
-							AppendHeaders: map[string]string{
-								updateHeaderName: sentinel,
-							},
-						}},
-					}},
-				},
-			}},
-		})
-
-		// Check that it serves the right message as soon as we get "Ready",
-		// but before we stop probing.
-		ri := RuntimeRequest(t, client, "http://"+hostname+".example.com")
-		if ri != nil {
-			if got := ri.Request.Headers.Get(updateHeaderName); got != sentinel {
-				t.Errorf("Header[%q] = %q, wanted %q", updateHeaderName, got, sentinel)
-			}
-		}
-	}
-
-	// Next test with varying sentinels AND fresh services each time.
-	previousVersionCancel = func() {
-		t.Logf("Tearing down %q", firstName)
-		firstCancel()
-	}
-	for i := 0; i < 10; i++ {
-		sentinel := test.ObjectNameForTest(t)
-		nextName, nextPort, nextCancel := CreateRuntimeService(t, clients, networking.ServicePortNameHTTP1)
-
-		t.Logf("Rolling out %q w/ %q", nextName, sentinel)
-
-		// Update the Ingress, and wait for it to report ready.
-		UpdateIngressReady(t, clients, ing.Name, v1alpha1.IngressSpec{
-			Rules: []v1alpha1.IngressRule{{
-				Hosts:      []string{hostname + ".example.com"},
-				Visibility: v1alpha1.IngressVisibilityExternalIP,
-				HTTP: &v1alpha1.HTTPIngressRuleValue{
-					Paths: []v1alpha1.HTTPIngressPath{{
-						Splits: []v1alpha1.IngressBackendSplit{{
-							IngressBackend: v1alpha1.IngressBackend{
-								ServiceName:      nextName,
-								ServiceNamespace: test.ServingNamespace,
-								ServicePort:      intstr.FromInt(nextPort),
-							},
-							AppendHeaders: map[string]string{
-								updateHeaderName: sentinel,
-							},
-						}},
-					}},
-				},
-			}},
-		})
-
-		// Check that it serves the right message as soon as we get "Ready",
-		// but before we stop probing.
-		ri := RuntimeRequest(t, client, "http://"+hostname+".example.com")
-		if ri != nil {
-			if got := ri.Request.Headers.Get(updateHeaderName); got != sentinel {
-				t.Errorf("Header[%q] = %q, wanted %q", updateHeaderName, got, sentinel)
-			}
-		}
-
-		// Once we've rolled out, cancel the previous version.
-		previousVersionCancel()
-		// Then make ourselves the next to be cancelled.
-		previousVersionCancel = func() {
-			t.Logf("Tearing down %q", nextName)
-			nextCancel()
-		}
-	}
-}
-
-func checkOK(t *testing.T, url string, client *http.Client) context.CancelFunc {
-	stopCh := make(chan struct{})
-	doneCh := make(chan struct{})
-
-	// Launch the prober
-	go func() {
-		defer close(doneCh)
-		for {
-			// Each iteration check for cancellation.
-			select {
-			case <-stopCh:
-				return
-			default:
-			}
-			// Scope the defer below to avoid leaking until the test completes.
-			func() {
-				ri := RuntimeRequest(t, client, url)
-				if ri != nil {
-					// Use the updateHeaderName as a debug marker to identify which version
-					// (of programming) is responding.
-					t.Logf("[%s] Got OK status!", ri.Request.Headers.Get(updateHeaderName))
-				}
-			}()
-		}
-	}()
-
-	// Return a cancel function that stops the prober and then waits for it to complete.
-	return func() {
-		close(stopCh)
-		<-doneCh
-	}
-}
diff --git a/test/conformance/ingress/util.go b/test/conformance/ingress/util.go
deleted file mode 100644
index d6b4eb128..000000000
--- a/test/conformance/ingress/util.go
+++ /dev/null
@@ -1,945 +0,0 @@
-/*
-Copyright 2019 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 ingress
-
-import (
-	"bytes"
-	"context"
-	"crypto/ecdsa"
-	"crypto/elliptic"
-	cryptorand "crypto/rand"
-	"crypto/tls"
-	"crypto/x509"
-	"crypto/x509/pkix"
-	"encoding/json"
-	"encoding/pem"
-	"errors"
-	"fmt"
-	"io/ioutil"
-	"math/big"
-	"math/rand"
-	"net"
-	"net/http"
-	"net/http/httputil"
-	"net/url"
-	"strconv"
-	"strings"
-	"testing"
-	"time"
-
-	corev1 "k8s.io/api/core/v1"
-	apierrs "k8s.io/apimachinery/pkg/api/errors"
-	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
-	"k8s.io/apimachinery/pkg/util/intstr"
-	"k8s.io/apimachinery/pkg/util/sets"
-	"k8s.io/apimachinery/pkg/util/wait"
-	"knative.dev/networking/pkg/apis/networking"
-	"knative.dev/networking/pkg/apis/networking/v1alpha1"
-	"knative.dev/pkg/network"
-	pkgTest "knative.dev/pkg/test"
-	"knative.dev/serving/test"
-	"knative.dev/serving/test/types"
-	v1a1test "knative.dev/serving/test/v1alpha1"
-)
-
-var rootCAs = x509.NewCertPool()
-
-var dialBackoff = wait.Backoff{
-	Duration: 50 * time.Millisecond,
-	Factor:   1.4,
-	Jitter:   0.1, // At most 10% jitter.
-	Steps:    100,
-	Cap:      10 * time.Second,
-}
-
-// uaRoundTripper wraps the given http.RoundTripper and
-// sets a custom UserAgent.
-type uaRoundTripper struct {
-	http.RoundTripper
-	ua string
-}
-
-// RoundTrip implements http.RoundTripper.
-func (ua *uaRoundTripper) RoundTrip(rq *http.Request) (*http.Response, error) {
-	rq.Header.Set("User-Agent", ua.ua)
-	return ua.RoundTripper.RoundTrip(rq)
-}
-
-// CreateRuntimeService creates a Kubernetes service that will respond to the protocol
-// specified with the given portName.  It returns the service name, the port on
-// which the service is listening, and a "cancel" function to clean up the
-// created resources.
-func CreateRuntimeService(t *testing.T, clients *test.Clients, portName string) (string, int, context.CancelFunc) {
-	t.Helper()
-	name := test.ObjectNameForTest(t)
-
-	// Avoid zero, but pick a low port number.
-	port := 50 + rand.Intn(50)
-	t.Logf("[%s] Using port %d", name, port)
-
-	// Pick a high port number.
-	containerPort := 8000 + rand.Intn(100)
-	t.Logf("[%s] Using containerPort %d", name, containerPort)
-
-	pod := &corev1.Pod{
-		ObjectMeta: metav1.ObjectMeta{
-			Name:      name,
-			Namespace: test.ServingNamespace,
-			Labels: map[string]string{
-				"test-pod": name,
-			},
-		},
-		Spec: corev1.PodSpec{
-			Containers: []corev1.Container{{
-				Name:  "foo",
-				Image: pkgTest.ImagePath("runtime"),
-				Ports: []corev1.ContainerPort{{
-					Name:          portName,
-					ContainerPort: int32(containerPort),
-				}},
-				// This is needed by the runtime image we are using.
-				Env: []corev1.EnvVar{{
-					Name:  "PORT",
-					Value: strconv.Itoa(containerPort),
-				}},
-				ReadinessProbe: &corev1.Probe{
-					Handler: corev1.Handler{
-						HTTPGet: &corev1.HTTPGetAction{
-							Path: "/healthz",
-							Port: intstr.FromInt(containerPort),
-						},
-					},
-				},
-			}},
-		},
-	}
-
-	svc := &corev1.Service{
-		ObjectMeta: metav1.ObjectMeta{
-			Name:      name,
-			Namespace: test.ServingNamespace,
-			Labels: map[string]string{
-				"test-pod": name,
-			},
-		},
-		Spec: corev1.ServiceSpec{
-			Type: "ClusterIP",
-			Ports: []corev1.ServicePort{{
-				Name:       portName,
-				Port:       int32(port),
-				TargetPort: intstr.FromInt(containerPort),
-			}},
-			Selector: map[string]string{
-				"test-pod": name,
-			},
-		},
-	}
-
-	return name, port, createPodAndService(t, clients, pod, svc)
-}
-
-// CreateProxyService creates a Kubernetes service that will forward requests to
-// the specified target.  It returns the service name, the port on which the service
-// is listening, and a "cancel" function to clean up the created resources.
-func CreateProxyService(t *testing.T, clients *test.Clients, target string, gatewayDomain string) (string, int, context.CancelFunc) {
-	t.Helper()
-	name := test.ObjectNameForTest(t)
-
-	// Avoid zero, but pick a low port number.
-	port := 50 + rand.Intn(50)
-	t.Logf("[%s] Using port %d", name, port)
-
-	// Pick a high port number.
-	containerPort := 8000 + rand.Intn(100)
-	t.Logf("[%s] Using containerPort %d", name, containerPort)
-
-	pod := &corev1.Pod{
-		ObjectMeta: metav1.ObjectMeta{
-			Name:      name,
-			Namespace: test.ServingNamespace,
-			Labels: map[string]string{
-				"test-pod": name,
-			},
-		},
-		Spec: corev1.PodSpec{
-			Containers: []corev1.Container{{
-				Name:  "foo",
-				Image: pkgTest.ImagePath("httpproxy"),
-				Ports: []corev1.ContainerPort{{
-					ContainerPort: int32(containerPort),
-				}},
-				Env: []corev1.EnvVar{{
-					Name:  "TARGET_HOST",
-					Value: target,
-				}, {
-					Name:  "PORT",
-					Value: strconv.Itoa(containerPort),
-				}},
-			}},
-		},
-	}
-
-	svc := &corev1.Service{
-		ObjectMeta: metav1.ObjectMeta{
-			Name:      name,
-			Namespace: test.ServingNamespace,
-			Labels: map[string]string{
-				"test-pod": name,
-			},
-		},
-		Spec: corev1.ServiceSpec{
-			Type: "ClusterIP",
-			Ports: []corev1.ServicePort{{
-				Port:       int32(port),
-				TargetPort: intstr.FromInt(containerPort),
-			}},
-			Selector: map[string]string{
-				"test-pod": name,
-			},
-		},
-	}
-	proxyServiceCancel := createPodAndService(t, clients, pod, svc)
-
-	targetName := strings.Split(target, ".")
-	externalNameSvc := &corev1.Service{
-		ObjectMeta: metav1.ObjectMeta{
-			Name:      targetName[0],
-			Namespace: targetName[1],
-		},
-		Spec: corev1.ServiceSpec{
-			Type:            corev1.ServiceTypeExternalName,
-			ExternalName:    gatewayDomain,
-			SessionAffinity: corev1.ServiceAffinityNone,
-		},
-	}
-
-	externalNameServiceCancel := createService(t, clients, externalNameSvc)
-
-	return name, port, func() {
-		externalNameServiceCancel()
-		proxyServiceCancel()
-	}
-}
-
-// CreateTimeoutService creates a Kubernetes service that will respond to the protocol
-// specified with the given portName.  It returns the service name, the port on
-// which the service is listening, and a "cancel" function to clean up the
-// created resources.
-func CreateTimeoutService(t *testing.T, clients *test.Clients) (string, int, context.CancelFunc) {
-	t.Helper()
-	name := test.ObjectNameForTest(t)
-
-	// Avoid zero, but pick a low port number.
-	port := 50 + rand.Intn(50)
-	t.Logf("[%s] Using port %d", name, port)
-
-	// Pick a high port number.
-	containerPort := 8000 + rand.Intn(100)
-	t.Logf("[%s] Using containerPort %d", name, containerPort)
-
-	pod := &corev1.Pod{
-		ObjectMeta: metav1.ObjectMeta{
-			Name:      name,
-			Namespace: test.ServingNamespace,
-			Labels: map[string]string{
-				"test-pod": name,
-			},
-		},
-		Spec: corev1.PodSpec{
-			Containers: []corev1.Container{{
-				Name:  "foo",
-				Image: pkgTest.ImagePath("timeout"),
-				Ports: []corev1.ContainerPort{{
-					Name:          networking.ServicePortNameHTTP1,
-					ContainerPort: int32(containerPort),
-				}},
-				// This is needed by the timeout image we are using.
-				Env: []corev1.EnvVar{{
-					Name:  "PORT",
-					Value: strconv.Itoa(containerPort),
-				}},
-				ReadinessProbe: &corev1.Probe{
-					Handler: corev1.Handler{
-						HTTPGet: &corev1.HTTPGetAction{
-							Port: intstr.FromInt(containerPort),
-						},
-					},
-				},
-			}},
-		},
-	}
-
-	svc := &corev1.Service{
-		ObjectMeta: metav1.ObjectMeta{
-			Name:      name,
-			Namespace: test.ServingNamespace,
-			Labels: map[string]string{
-				"test-pod": name,
-			},
-		},
-		Spec: corev1.ServiceSpec{
-			Type: "ClusterIP",
-			Ports: []corev1.ServicePort{{
-				Name:       networking.ServicePortNameHTTP1,
-				Port:       int32(port),
-				TargetPort: intstr.FromInt(containerPort),
-			}},
-			Selector: map[string]string{
-				"test-pod": name,
-			},
-		},
-	}
-
-	return name, port, createPodAndService(t, clients, pod, svc)
-}
-
-// CreateFlakyService creates a Kubernetes service where the backing pod will
-// succeed only every Nth request.
-func CreateFlakyService(t *testing.T, clients *test.Clients, period int) (string, int, context.CancelFunc) {
-	t.Helper()
-	name := test.ObjectNameForTest(t)
-
-	// Avoid zero, but pick a low port number.
-	port := 50 + rand.Intn(50)
-	t.Logf("[%s] Using port %d", name, port)
-
-	// Pick a high port number.
-	containerPort := 8000 + rand.Intn(100)
-	t.Logf("[%s] Using containerPort %d", name, containerPort)
-
-	pod := &corev1.Pod{
-		ObjectMeta: metav1.ObjectMeta{
-			Name:      name,
-			Namespace: test.ServingNamespace,
-			Labels: map[string]string{
-				"test-pod": name,
-			},
-		},
-		Spec: corev1.PodSpec{
-			Containers: []corev1.Container{{
-				Name:  "foo",
-				Image: pkgTest.ImagePath("flaky"),
-				Ports: []corev1.ContainerPort{{
-					Name:          networking.ServicePortNameHTTP1,
-					ContainerPort: int32(containerPort),
-				}},
-				// This is needed by the runtime image we are using.
-				Env: []corev1.EnvVar{{
-					Name:  "PORT",
-					Value: strconv.Itoa(containerPort),
-				}, {
-					Name:  "PERIOD",
-					Value: strconv.Itoa(period),
-				}},
-				ReadinessProbe: &corev1.Probe{
-					Handler: corev1.Handler{
-						HTTPGet: &corev1.HTTPGetAction{
-							Path: "/",
-							Port: intstr.FromInt(containerPort),
-						},
-					},
-				},
-			}},
-		},
-	}
-
-	svc := &corev1.Service{
-		ObjectMeta: metav1.ObjectMeta{
-			Name:      name,
-			Namespace: test.ServingNamespace,
-			Labels: map[string]string{
-				"test-pod": name,
-			},
-		},
-		Spec: corev1.ServiceSpec{
-			Type: "ClusterIP",
-			Ports: []corev1.ServicePort{{
-				Name:       networking.ServicePortNameHTTP1,
-				Port:       int32(port),
-				TargetPort: intstr.FromInt(containerPort),
-			}},
-			Selector: map[string]string{
-				"test-pod": name,
-			},
-		},
-	}
-
-	return name, port, createPodAndService(t, clients, pod, svc)
-}
-
-// CreateWebsocketService creates a Kubernetes service that will upgrade the connection
-// to use websockets and echo back the received messages with the provided suffix.
-func CreateWebsocketService(t *testing.T, clients *test.Clients, suffix string) (string, int, context.CancelFunc) {
-	t.Helper()
-	name := test.ObjectNameForTest(t)
-
-	// Avoid zero, but pick a low port number.
-	port := 50 + rand.Intn(50)
-	t.Logf("[%s] Using port %d", name, port)
-
-	// Pick a high port number.
-	containerPort := 8000 + rand.Intn(100)
-	t.Logf("[%s] Using containerPort %d", name, containerPort)
-
-	pod := &corev1.Pod{
-		ObjectMeta: metav1.ObjectMeta{
-			Name:      name,
-			Namespace: test.ServingNamespace,
-			Labels: map[string]string{
-				"test-pod": name,
-			},
-		},
-		Spec: corev1.PodSpec{
-			Containers: []corev1.Container{{
-				Name:  "foo",
-				Image: pkgTest.ImagePath("wsserver"),
-				Ports: []corev1.ContainerPort{{
-					Name:          networking.ServicePortNameHTTP1,
-					ContainerPort: int32(containerPort),
-				}},
-				// This is needed by the runtime image we are using.
-				Env: []corev1.EnvVar{{
-					Name:  "PORT",
-					Value: strconv.Itoa(containerPort),
-				}, {
-					Name:  "SUFFIX",
-					Value: suffix,
-				}},
-				ReadinessProbe: &corev1.Probe{
-					Handler: corev1.Handler{
-						HTTPGet: &corev1.HTTPGetAction{
-							Path: "/",
-							Port: intstr.FromInt(containerPort),
-						},
-					},
-				},
-			}},
-		},
-	}
-
-	svc := &corev1.Service{
-		ObjectMeta: metav1.ObjectMeta{
-			Name:      name,
-			Namespace: test.ServingNamespace,
-			Labels: map[string]string{
-				"test-pod": name,
-			},
-		},
-		Spec: corev1.ServiceSpec{
-			Type: "ClusterIP",
-			Ports: []corev1.ServicePort{{
-				Name:       networking.ServicePortNameHTTP1,
-				Port:       int32(port),
-				TargetPort: intstr.FromInt(containerPort),
-			}},
-			Selector: map[string]string{
-				"test-pod": name,
-			},
-		},
-	}
-
-	return name, port, createPodAndService(t, clients, pod, svc)
-}
-
-// CreateGRPCService creates a Kubernetes service that will upgrade the connection
-// to use GRPC and echo back the received messages with the provided suffix.
-func CreateGRPCService(t *testing.T, clients *test.Clients, suffix string) (string, int, context.CancelFunc) {
-	t.Helper()
-	name := test.ObjectNameForTest(t)
-
-	// Avoid zero, but pick a low port number.
-	port := 50 + rand.Intn(50)
-	t.Logf("[%s] Using port %d", name, port)
-
-	// Pick a high port number.
-	containerPort := 8000 + rand.Intn(100)
-	t.Logf("[%s] Using containerPort %d", name, containerPort)
-
-	pod := &corev1.Pod{
-		ObjectMeta: metav1.ObjectMeta{
-			Name:      name,
-			Namespace: test.ServingNamespace,
-			Labels: map[string]string{
-				"test-pod": name,
-			},
-		},
-		Spec: corev1.PodSpec{
-			Containers: []corev1.Container{{
-				Name:  "foo",
-				Image: pkgTest.ImagePath("grpc-ping"),
-				Ports: []corev1.ContainerPort{{
-					Name:          networking.ServicePortNameH2C,
-					ContainerPort: int32(containerPort),
-				}},
-				// This is needed by the runtime image we are using.
-				Env: []corev1.EnvVar{{
-					Name:  "PORT",
-					Value: strconv.Itoa(containerPort),
-				}, {
-					Name:  "SUFFIX",
-					Value: suffix,
-				}},
-				ReadinessProbe: &corev1.Probe{
-					Handler: corev1.Handler{
-						TCPSocket: &corev1.TCPSocketAction{
-							Port: intstr.FromInt(containerPort),
-						},
-					},
-				},
-			}},
-		},
-	}
-
-	svc := &corev1.Service{
-		ObjectMeta: metav1.ObjectMeta{
-			Name:      name,
-			Namespace: test.ServingNamespace,
-			Labels: map[string]string{
-				"test-pod": name,
-			},
-		},
-		Spec: corev1.ServiceSpec{
-			Type: "ClusterIP",
-			Ports: []corev1.ServicePort{{
-				Name:       networking.ServicePortNameH2C,
-				Port:       int32(port),
-				TargetPort: intstr.FromInt(containerPort),
-			}},
-			Selector: map[string]string{
-				"test-pod": name,
-			},
-		},
-	}
-
-	return name, port, createPodAndService(t, clients, pod, svc)
-}
-
-// createService is a helper for creating the service resource.
-func createService(t *testing.T, clients *test.Clients, svc *corev1.Service) context.CancelFunc {
-	t.Helper()
-
-	test.CleanupOnInterrupt(func() {
-		clients.KubeClient.Kube.CoreV1().Services(svc.Namespace).Delete(svc.Name, &metav1.DeleteOptions{})
-	})
-	svc, err := clients.KubeClient.Kube.CoreV1().Services(svc.Namespace).Create(svc)
-	if err != nil {
-		t.Fatal("Error creating Service:", err)
-	}
-
-	return func() {
-		err := clients.KubeClient.Kube.CoreV1().Services(svc.Namespace).Delete(svc.Name, &metav1.DeleteOptions{})
-		if err != nil {
-			t.Errorf("Error cleaning up Service %s: %v", svc.Name, err)
-		}
-	}
-}
-
-// createPodAndService is a helper for creating the pod and service resources, setting
-// up their context.CancelFunc, and waiting for it to become ready.
-func createPodAndService(t *testing.T, clients *test.Clients, pod *corev1.Pod, svc *corev1.Service) context.CancelFunc {
-	t.Helper()
-
-	test.CleanupOnInterrupt(func() { clients.KubeClient.Kube.CoreV1().Pods(pod.Namespace).Delete(pod.Name, &metav1.DeleteOptions{}) })
-	pod, err := clients.KubeClient.Kube.CoreV1().Pods(pod.Namespace).Create(pod)
-	if err != nil {
-		t.Fatal("Error creating Pod:", err)
-	}
-	cancel := func() {
-		err := clients.KubeClient.Kube.CoreV1().Pods(pod.Namespace).Delete(pod.Name, &metav1.DeleteOptions{})
-		if err != nil {
-			t.Errorf("Error cleaning up Pod %s", pod.Name)
-		}
-	}
-
-	test.CleanupOnInterrupt(func() {
-		clients.KubeClient.Kube.CoreV1().Services(svc.Namespace).Delete(svc.Name, &metav1.DeleteOptions{})
-	})
-	svc, err = clients.KubeClient.Kube.CoreV1().Services(svc.Namespace).Create(svc)
-	if err != nil {
-		cancel()
-		t.Fatal("Error creating Service:", err)
-	}
-
-	// Wait for the Pod to show up in the Endpoints resource.
-	waitErr := wait.PollImmediate(test.PollInterval, test.PollTimeout, func() (bool, error) {
-		ep, err := clients.KubeClient.Kube.CoreV1().Endpoints(svc.Namespace).Get(svc.Name, metav1.GetOptions{})
-		if apierrs.IsNotFound(err) {
-			return false, nil
-		} else if err != nil {
-			return true, err
-		}
-		for _, subset := range ep.Subsets {
-			if len(subset.Addresses) == 0 {
-				return false, nil
-			}
-		}
-		return len(ep.Subsets) > 0, nil
-	})
-	if waitErr != nil {
-		cancel()
-		t.Fatal("Error waiting for Endpoints to contain a Pod IP:", waitErr)
-	}
-
-	return func() {
-		err := clients.KubeClient.Kube.CoreV1().Services(svc.Namespace).Delete(svc.Name, &metav1.DeleteOptions{})
-		if err != nil {
-			t.Errorf("Error cleaning up Service %s: %v", svc.Name, err)
-		}
-		cancel()
-	}
-}
-
-// CreateIngress creates a Knative Ingress resource
-func CreateIngress(t *testing.T, clients *test.Clients, spec v1alpha1.IngressSpec) (*v1alpha1.Ingress, context.CancelFunc) {
-	t.Helper()
-
-	name := test.ObjectNameForTest(t)
-
-	// Create a simple Ingress over the Service.
-	ing := &v1alpha1.Ingress{
-		ObjectMeta: metav1.ObjectMeta{
-			Name:      name,
-			Namespace: test.ServingNamespace,
-			Annotations: map[string]string{
-				networking.IngressClassAnnotationKey: test.ServingFlags.IngressClass,
-			},
-		},
-		Spec: spec,
-	}
-	test.CleanupOnInterrupt(func() { clients.NetworkingClient.Ingresses.Delete(ing.Name, &metav1.DeleteOptions{}) })
-	ing, err := clients.NetworkingClient.Ingresses.Create(ing)
-	if err != nil {
-		t.Fatal("Error creating Ingress:", err)
-	}
-
-	return ing, func() {
-		err := clients.NetworkingClient.Ingresses.Delete(ing.Name, &metav1.DeleteOptions{})
-		if err != nil {
-			t.Errorf("Error cleaning up Ingress %s: %v", ing.Name, err)
-		}
-	}
-}
-
-func CreateIngressReadyDialContext(t *testing.T, clients *test.Clients, spec v1alpha1.IngressSpec) (*v1alpha1.Ingress, func(context.Context, string, string) (net.Conn, error), context.CancelFunc) {
-	t.Helper()
-	ing, cancel := CreateIngress(t, clients, spec)
-
-	if err := v1a1test.WaitForIngressState(clients.NetworkingClient, ing.Name, v1a1test.IsIngressReady, t.Name()); err != nil {
-		cancel()
-		t.Fatal("Error waiting for ingress state:", err)
-	}
-	ing, err := clients.NetworkingClient.Ingresses.Get(ing.Name, metav1.GetOptions{})
-	if err != nil {
-		cancel()
-		t.Fatal("Error getting Ingress:", err)
-	}
-
-	// Create a dialer based on the Ingress' public load balancer.
-	return ing, CreateDialContext(t, ing, clients), cancel
-}
-
-func CreateIngressReady(t *testing.T, clients *test.Clients, spec v1alpha1.IngressSpec) (*v1alpha1.Ingress, *http.Client, context.CancelFunc) {
-	t.Helper()
-
-	// Create a client with a dialer based on the Ingress' public load balancer.
-	ing, dialer, cancel := CreateIngressReadyDialContext(t, clients, spec)
-
-	// TODO(mattmoor): How to get ing?
-	var tlsConfig *tls.Config
-	if len(ing.Spec.TLS) > 0 {
-		// CAs are added to this as TLS secrets are created.
-		tlsConfig = &tls.Config{
-			RootCAs: rootCAs,
-		}
-	}
-
-	return ing, &http.Client{
-		Transport: &uaRoundTripper{
-			RoundTripper: &http.Transport{
-				DialContext:     dialer,
-				TLSClientConfig: tlsConfig,
-			},
-			ua: fmt.Sprintf("knative.dev/%s/%s", t.Name(), ing.Name),
-		},
-	}, cancel
-}
-
-// UpdateIngress updates a Knative Ingress resource
-func UpdateIngress(t *testing.T, clients *test.Clients, name string, spec v1alpha1.IngressSpec) {
-	t.Helper()
-
-	ing, err := clients.NetworkingClient.Ingresses.Get(name, metav1.GetOptions{})
-	if err != nil {
-		t.Fatal("Error getting Ingress:", err)
-	}
-
-	ing.Spec = spec
-	if _, err := clients.NetworkingClient.Ingresses.Update(ing); err != nil {
-		t.Fatal("Error updating Ingress:", err)
-	}
-}
-
-func UpdateIngressReady(t *testing.T, clients *test.Clients, name string, spec v1alpha1.IngressSpec) {
-	t.Helper()
-	UpdateIngress(t, clients, name, spec)
-
-	if err := v1a1test.WaitForIngressState(clients.NetworkingClient, name, v1a1test.IsIngressReady, t.Name()); err != nil {
-		t.Fatal("Error waiting for ingress state:", err)
-	}
-}
-
-// This is based on https://golang.org/src/crypto/tls/generate_cert.go
-func CreateTLSSecret(t *testing.T, clients *test.Clients, hosts []string) (string, context.CancelFunc) {
-	return CreateTLSSecretWithCertPool(t, clients, hosts, test.ServingNamespace, rootCAs)
-}
-
-// CreateTLSSecretWithCertPool creates TLS certificate with given CertPool.
-func CreateTLSSecretWithCertPool(t *testing.T, clients *test.Clients, hosts []string, ns string, cas *x509.CertPool) (string, context.CancelFunc) {
-	t.Helper()
-
-	priv, err := ecdsa.GenerateKey(elliptic.P256(), cryptorand.Reader)
-	if err != nil {
-		t.Fatal("ecdsa.GenerateKey() =", err)
-	}
-
-	serialNumberLimit := new(big.Int).Lsh(big.NewInt(1), 128)
-	serialNumber, err := cryptorand.Int(cryptorand.Reader, serialNumberLimit)
-	if err != nil {
-		t.Fatal("Failed to generate serial number:", err)
-	}
-
-	template := x509.Certificate{
-		SerialNumber: serialNumber,
-		Subject: pkix.Name{
-			Organization: []string{"Knative Ingress Conformance Testing"},
-		},
-
-		// Only let it live briefly.
-		NotBefore: time.Now(),
-		NotAfter:  time.Now().Add(5 * time.Minute),
-
-		IsCA:                  true,
-		KeyUsage:              x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature | x509.KeyUsageCertSign,
-		ExtKeyUsage:           []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth},
-		BasicConstraintsValid: true,
-
-		DNSNames: hosts,
-	}
-
-	derBytes, err := x509.CreateCertificate(cryptorand.Reader, &template, &template, &priv.PublicKey, priv)
-	if err != nil {
-		t.Fatal("x509.CreateCertificate() =", err)
-	}
-
-	cert, err := x509.ParseCertificate(derBytes)
-	if err != nil {
-		t.Fatal("ParseCertificate() =", err)
-	}
-	// Ideally we'd undo this in "cancel", but there doesn't
-	// seem to be a mechanism to remove things from a pool.
-	cas.AddCert(cert)
-
-	certPEM := &bytes.Buffer{}
-	if err := pem.Encode(certPEM, &pem.Block{Type: "CERTIFICATE", Bytes: derBytes}); err != nil {
-		t.Fatal("Failed to write data to cert.pem:", err)
-	}
-
-	privBytes, err := x509.MarshalPKCS8PrivateKey(priv)
-	if err != nil {
-		t.Fatal("Unable to marshal private key:", err)
-	}
-	privPEM := &bytes.Buffer{}
-	if err := pem.Encode(privPEM, &pem.Block{Type: "PRIVATE KEY", Bytes: privBytes}); err != nil {
-		t.Fatal("Failed to write data to key.pem:", err)
-	}
-
-	name := test.ObjectNameForTest(t)
-	secret := &corev1.Secret{
-		ObjectMeta: metav1.ObjectMeta{
-			Name:      name,
-			Namespace: ns,
-			Labels: map[string]string{
-				"test-secret": name,
-			},
-		},
-		Type: corev1.SecretTypeTLS,
-		StringData: map[string]string{
-			corev1.TLSCertKey:       certPEM.String(),
-			corev1.TLSPrivateKeyKey: privPEM.String(),
-		},
-	}
-	test.CleanupOnInterrupt(func() {
-		clients.KubeClient.Kube.CoreV1().Secrets(secret.Namespace).Delete(secret.Name, &metav1.DeleteOptions{})
-	})
-	if _, err := clients.KubeClient.Kube.CoreV1().Secrets(secret.Namespace).Create(secret); err != nil {
-		t.Fatal("Error creating Secret:", err)
-	}
-	return name, func() {
-		err := clients.KubeClient.Kube.CoreV1().Secrets(secret.Namespace).Delete(secret.Name, &metav1.DeleteOptions{})
-		if err != nil {
-			t.Errorf("Error cleaning up Secret %s: %v", secret.Name, err)
-		}
-	}
-}
-
-// CreateDialContext looks up the endpoint information to create a "dialer" for
-// the provided Ingress' public ingress loas balancer.  It can be used to
-// contact external-visibility services with an HTTP client via:
-//
-//	client := &http.Client{
-//		Transport: &http.Transport{
-//			DialContext: CreateDialContext(t, ing, clients),
-//		},
-//	}
-func CreateDialContext(t *testing.T, ing *v1alpha1.Ingress, clients *test.Clients) func(context.Context, string, string) (net.Conn, error) {
-	t.Helper()
-	if ing.Status.PublicLoadBalancer == nil || len(ing.Status.PublicLoadBalancer.Ingress) < 1 {
-		t.Fatal("Ingress does not have a public load balancer assigned.")
-	}
-
-	// TODO(mattmoor): I'm open to tricks that would let us cleanly test multiple
-	// public load balancers or LBs with multiple ingresses (below), but want to
-	// keep our simple tests simple, thus the [0]s...
-
-	// We expect an ingress LB with the form foo.bar.svc.cluster.local (though
-	// we aren't strictly sensitive to the suffix, this is just illustrative.
-	internalDomain := ing.Status.PublicLoadBalancer.Ingress[0].DomainInternal
-	parts := strings.SplitN(internalDomain, ".", 3)
-	if len(parts) < 3 {
-		t.Fatal("Too few parts in internal domain:", internalDomain)
-	}
-	name, namespace := parts[0], parts[1]
-
-	svc, err := clients.KubeClient.Kube.CoreV1().Services(namespace).Get(name, metav1.GetOptions{})
-	if err != nil {
-		t.Fatalf("Unable to retrieve Kubernetes service %s/%s: %v", namespace, name, err)
-	}
-	if len(svc.Status.LoadBalancer.Ingress) < 1 {
-		t.Fatal("Service does not have any ingresses (not type LoadBalancer?).")
-	}
-	ingress := svc.Status.LoadBalancer.Ingress[0]
-	dial := network.NewBackoffDialer(dialBackoff)
-	return func(ctx context.Context, _ string, address string) (net.Conn, error) {
-		_, port, err := net.SplitHostPort(address)
-		if err != nil {
-			return nil, err
-		}
-		// Allow "ingressendpoint" flag to override the discovered ingress IP/hostname,
-		// this is required in minikube-like environments.
-		if pkgTest.Flags.IngressEndpoint != "" {
-			return dial(ctx, "tcp", pkgTest.Flags.IngressEndpoint)
-		}
-		if ingress.IP != "" {
-			return dial(ctx, "tcp", ingress.IP+":"+port)
-		}
-		if ingress.Hostname != "" {
-			return dial(ctx, "tcp", ingress.Hostname+":"+port)
-		}
-		return nil, errors.New("service ingress does not contain dialing information")
-	}
-}
-
-type RequestOption func(*http.Request)
-type ResponseExpectation func(response *http.Response) error
-
-func RuntimeRequest(t *testing.T, client *http.Client, url string, opts ...RequestOption) *types.RuntimeInfo {
-	return RuntimeRequestWithExpectations(t, client, url,
-		[]ResponseExpectation{StatusCodeExpectation(sets.NewInt(http.StatusOK))},
-		false,
-		opts...)
-}
-
-// RuntimeRequestWithExpectations attempts to make a request to url and return runtime information.
-// If connection is successful only then it will validate all response expectations.
-// If allowDialError is set to true then function will not fail if connection is a dial error.
-func RuntimeRequestWithExpectations(t *testing.T, client *http.Client, url string,
-	responseExpectations []ResponseExpectation,
-	allowDialError bool,
-	opts ...RequestOption) *types.RuntimeInfo {
-	t.Helper()
-
-	req, err := http.NewRequest(http.MethodGet, url, nil)
-	if err != nil {
-		t.Errorf("Error creating Request: %v", err)
-		return nil
-	}
-
-	for _, opt := range opts {
-		opt(req)
-	}
-
-	resp, err := client.Do(req)
-
-	if err != nil {
-		if !allowDialError || !IsDialError(err) {
-			t.Errorf("Error making GET request: %v", err)
-		}
-		return nil
-	}
-
-	defer resp.Body.Close()
-
-	for _, e := range responseExpectations {
-		if err := e(resp); err != nil {
-			t.Errorf("Error meeting response expectations: %v", err)
-			DumpResponse(t, resp)
-			return nil
-		}
-	}
-
-	if resp.StatusCode == http.StatusOK {
-		b, err := ioutil.ReadAll(resp.Body)
-		if err != nil {
-			t.Errorf("Unable to read response body: %v", err)
-			DumpResponse(t, resp)
-			return nil
-		}
-		ri := &types.RuntimeInfo{}
-		if err := json.Unmarshal(b, ri); err != nil {
-			t.Errorf("Unable to parse runtime image's response payload: %v", err)
-			return nil
-		}
-		return ri
-	}
-	return nil
-}
-
-func DumpResponse(t *testing.T, resp *http.Response) {
-	t.Helper()
-	b, err := httputil.DumpResponse(resp, true)
-	if err != nil {
-		t.Errorf("Error dumping response: %v", err)
-	}
-	t.Log(string(b))
-}
-
-func StatusCodeExpectation(statusCodes sets.Int) ResponseExpectation {
-	return func(response *http.Response) error {
-		if !statusCodes.Has(response.StatusCode) {
-			return fmt.Errorf("got unexpected status: %d, expected %v", response.StatusCode, statusCodes)
-		}
-		return nil
-	}
-}
-
-func IsDialError(err error) bool {
-	if err, ok := err.(*url.Error); ok {
-		err, ok := err.Err.(*net.OpError)
-		return ok && err.Op == "dial"
-	}
-	return false
-}
diff --git a/test/conformance/ingress/visibility.go b/test/conformance/ingress/visibility.go
deleted file mode 100644
index 95ac081cb..000000000
--- a/test/conformance/ingress/visibility.go
+++ /dev/null
@@ -1,369 +0,0 @@
-/*
-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 ingress
-
-import (
-	"errors"
-	"fmt"
-	"math"
-	"net/http"
-	"testing"
-
-	"k8s.io/apimachinery/pkg/util/intstr"
-	"k8s.io/apimachinery/pkg/util/sets"
-	"knative.dev/networking/pkg/apis/networking"
-	"knative.dev/networking/pkg/apis/networking/v1alpha1"
-	"knative.dev/pkg/pool"
-	"knative.dev/serving/test"
-)
-
-func TestVisibility(t *testing.T) {
-	t.Parallel()
-	clients := test.Setup(t)
-
-	// Create the private backend
-	name, port, cancel := CreateRuntimeService(t, clients, networking.ServicePortNameHTTP1)
-	defer cancel()
-
-	privateServiceName := test.ObjectNameForTest(t)
-	privateHostName := privateServiceName + "." + test.ServingNamespace + ".svc.cluster.local"
-	ingress, client, cancel := CreateIngressReady(t, clients, v1alpha1.IngressSpec{
-		Rules: []v1alpha1.IngressRule{{
-			Hosts:      []string{privateHostName},
-			Visibility: v1alpha1.IngressVisibilityClusterLocal,
-			HTTP: &v1alpha1.HTTPIngressRuleValue{
-				Paths: []v1alpha1.HTTPIngressPath{{
-					Splits: []v1alpha1.IngressBackendSplit{{
-						IngressBackend: v1alpha1.IngressBackend{
-							ServiceName:      name,
-							ServiceNamespace: test.ServingNamespace,
-							ServicePort:      intstr.FromInt(port),
-						},
-					}},
-				}},
-			},
-		}},
-	})
-	defer cancel()
-
-	// Ensure the service is not publicly accessible
-	RuntimeRequestWithExpectations(t, client, "http://"+privateHostName, []ResponseExpectation{StatusCodeExpectation(sets.NewInt(http.StatusNotFound))}, true)
-
-	loadbalancerAddress := ingress.Status.PrivateLoadBalancer.Ingress[0].DomainInternal
-	proxyName, proxyPort, cancel := CreateProxyService(t, clients, privateHostName, loadbalancerAddress)
-	defer cancel()
-
-	publicHostName := "publicproxy.example.com"
-	_, client, cancel = CreateIngressReady(t, clients, v1alpha1.IngressSpec{
-		Rules: []v1alpha1.IngressRule{{
-			Hosts:      []string{publicHostName},
-			Visibility: v1alpha1.IngressVisibilityExternalIP,
-			HTTP: &v1alpha1.HTTPIngressRuleValue{
-				Paths: []v1alpha1.HTTPIngressPath{{
-					Splits: []v1alpha1.IngressBackendSplit{{
-						IngressBackend: v1alpha1.IngressBackend{
-							ServiceName:      proxyName,
-							ServiceNamespace: test.ServingNamespace,
-							ServicePort:      intstr.FromInt(proxyPort),
-						},
-					}},
-				}},
-			},
-		}},
-	})
-	defer cancel()
-
-	// Ensure the service is accessible from within the cluster.
-	RuntimeRequest(t, client, "http://"+publicHostName)
-}
-
-func TestVisibilitySplit(t *testing.T) {
-	t.Parallel()
-	clients := test.Setup(t)
-
-	// Use a post-split injected header to establish which split we are sending traffic to.
-	const headerName = "Foo-Bar-Baz"
-
-	backends := make([]v1alpha1.IngressBackendSplit, 0, 10)
-	weights := make(map[string]float64, len(backends))
-
-	// Double the percentage of the split each iteration until it would overflow, and then
-	// give the last route the remainder.
-	percent, total := 1, 0
-	for i := 0; i < 10; i++ {
-		name, port, cancel := CreateRuntimeService(t, clients, networking.ServicePortNameHTTP1)
-		defer cancel()
-		backends = append(backends, v1alpha1.IngressBackendSplit{
-			IngressBackend: v1alpha1.IngressBackend{
-				ServiceName:      name,
-				ServiceNamespace: test.ServingNamespace,
-				ServicePort:      intstr.FromInt(port),
-			},
-			// Append different headers to each split, which lets us identify
-			// which backend we hit.
-			AppendHeaders: map[string]string{
-				headerName: name,
-			},
-			Percent: percent,
-		})
-		weights[name] = float64(percent)
-
-		total += percent
-		percent *= 2
-		// Cap the final non-zero bucket so that we total 100%
-		// After that, this will zero out remaining buckets.
-		if total+percent > 100 {
-			percent = 100 - total
-		}
-	}
-
-	name := test.ObjectNameForTest(t)
-
-	// Create a simple Ingress over the 10 Services.
-	privateHostName := fmt.Sprintf("%s.%s.%s", name, test.ServingNamespace, "svc.cluster.local")
-	localIngress, client, cancel := CreateIngressReady(t, clients, v1alpha1.IngressSpec{
-		Rules: []v1alpha1.IngressRule{{
-			Hosts:      []string{privateHostName},
-			Visibility: v1alpha1.IngressVisibilityClusterLocal,
-			HTTP: &v1alpha1.HTTPIngressRuleValue{
-				Paths: []v1alpha1.HTTPIngressPath{{
-					Splits: backends,
-				}},
-			},
-		}},
-	})
-	defer cancel()
-
-	// Ensure we can't connect to the private resources
-	RuntimeRequestWithExpectations(t, client, "http://"+privateHostName, []ResponseExpectation{StatusCodeExpectation(sets.NewInt(http.StatusNotFound))}, true)
-
-	loadbalancerAddress := localIngress.Status.PrivateLoadBalancer.Ingress[0].DomainInternal
-	proxyName, proxyPort, cancel := CreateProxyService(t, clients, privateHostName, loadbalancerAddress)
-	defer cancel()
-
-	publicHostName := fmt.Sprintf("%s.%s", name, "example.com")
-	_, client, cancel = CreateIngressReady(t, clients, v1alpha1.IngressSpec{
-		Rules: []v1alpha1.IngressRule{{
-			Hosts:      []string{publicHostName},
-			Visibility: v1alpha1.IngressVisibilityExternalIP,
-			HTTP: &v1alpha1.HTTPIngressRuleValue{
-				Paths: []v1alpha1.HTTPIngressPath{{
-					Splits: []v1alpha1.IngressBackendSplit{{
-						IngressBackend: v1alpha1.IngressBackend{
-							ServiceName:      proxyName,
-							ServiceNamespace: test.ServingNamespace,
-							ServicePort:      intstr.FromInt(proxyPort),
-						},
-					}},
-				}},
-			},
-		}},
-	})
-	defer cancel()
-
-	// Create a large enough population of requests that we can reasonably assess how
-	// well the Ingress respected the percentage split.
-	seen := make(map[string]float64, len(backends))
-
-	const (
-		// The total number of requests to make (as a float to avoid conversions in later computations).
-		totalRequests = 1000.0
-		// The increment to make for each request, so that the values of seen reflect the
-		// percentage of the total number of requests we are making.
-		increment = 100.0 / totalRequests
-		// Allow the Ingress to be within 10% of the configured value.
-		margin = 10.0
-	)
-	wg := pool.New(8)
-	resultCh := make(chan string, totalRequests)
-
-	for i := 0.0; i < totalRequests; i++ {
-		wg.Go(func() error {
-			ri := RuntimeRequest(t, client, "http://"+publicHostName)
-			if ri == nil {
-				return errors.New("failed to request")
-			}
-			resultCh <- ri.Request.Headers.Get(headerName)
-			return nil
-		})
-	}
-	if err := wg.Wait(); err != nil {
-		t.Errorf("Error while sending requests: %v", err)
-	}
-	close(resultCh)
-
-	for r := range resultCh {
-		seen[r] += increment
-	}
-
-	for name, want := range weights {
-		got := seen[name]
-		switch {
-		case want == 0.0 && got > 0.0:
-			// For 0% targets, we have tighter requirements.
-			t.Errorf("Target %q received traffic, wanted none (0%% target).", name)
-		case math.Abs(got-want) > margin:
-			t.Errorf("Target %q received %f%%, wanted %f +/- %f", name, got, want, margin)
-		}
-	}
-}
-
-func TestVisibilityPath(t *testing.T) {
-	t.Parallel()
-	clients := test.Setup(t)
-
-	// For /foo
-	fooName, fooPort, cancel := CreateRuntimeService(t, clients, networking.ServicePortNameHTTP1)
-	defer cancel()
-
-	// For /bar
-	barName, barPort, cancel := CreateRuntimeService(t, clients, networking.ServicePortNameHTTP1)
-	defer cancel()
-
-	// For /baz
-	bazName, bazPort, cancel := CreateRuntimeService(t, clients, networking.ServicePortNameHTTP1)
-	defer cancel()
-
-	mainName, port, cancel := CreateRuntimeService(t, clients, networking.ServicePortNameHTTP1)
-	defer cancel()
-
-	// Use a post-split injected header to establish which split we are sending traffic to.
-	const headerName = "Which-Backend"
-
-	name := test.ObjectNameForTest(t)
-	privateHostName := fmt.Sprintf("%s.%s.%s", name, test.ServingNamespace, "svc.cluster.local")
-	localIngress, client, cancel := CreateIngressReady(t, clients, v1alpha1.IngressSpec{
-		Rules: []v1alpha1.IngressRule{{
-			Hosts:      []string{privateHostName},
-			Visibility: v1alpha1.IngressVisibilityClusterLocal,
-			HTTP: &v1alpha1.HTTPIngressRuleValue{
-				Paths: []v1alpha1.HTTPIngressPath{{
-					Path: "/foo",
-					Splits: []v1alpha1.IngressBackendSplit{{
-						IngressBackend: v1alpha1.IngressBackend{
-							ServiceName:      fooName,
-							ServiceNamespace: test.ServingNamespace,
-							ServicePort:      intstr.FromInt(fooPort),
-						},
-						// Append different headers to each split, which lets us identify
-						// which backend we hit.
-						AppendHeaders: map[string]string{
-							headerName: fooName,
-						},
-						Percent: 100,
-					}},
-				}, {
-					Path: "/bar",
-					Splits: []v1alpha1.IngressBackendSplit{{
-						IngressBackend: v1alpha1.IngressBackend{
-							ServiceName:      barName,
-							ServiceNamespace: test.ServingNamespace,
-							ServicePort:      intstr.FromInt(barPort),
-						},
-						// Append different headers to each split, which lets us identify
-						// which backend we hit.
-						AppendHeaders: map[string]string{
-							headerName: barName,
-						},
-						Percent: 100,
-					}},
-				}, {
-					Path: "/baz",
-					Splits: []v1alpha1.IngressBackendSplit{{
-						IngressBackend: v1alpha1.IngressBackend{
-							ServiceName:      bazName,
-							ServiceNamespace: test.ServingNamespace,
-							ServicePort:      intstr.FromInt(bazPort),
-						},
-						// Append different headers to each split, which lets us identify
-						// which backend we hit.
-						AppendHeaders: map[string]string{
-							headerName: bazName,
-						},
-						Percent: 100,
-					}},
-				}, {
-					Splits: []v1alpha1.IngressBackendSplit{{
-						IngressBackend: v1alpha1.IngressBackend{
-							ServiceName:      mainName,
-							ServiceNamespace: test.ServingNamespace,
-							ServicePort:      intstr.FromInt(port),
-						},
-						// Append different headers to each split, which lets us identify
-						// which backend we hit.
-						AppendHeaders: map[string]string{
-							headerName: mainName,
-						},
-						Percent: 100,
-					}},
-				}},
-			},
-		}},
-	})
-	defer cancel()
-
-	// Ensure we can't connect to the private resources
-	for _, path := range []string{"", "/foo", "/bar", "/baz"} {
-		RuntimeRequestWithExpectations(t, client, "http://"+privateHostName+path, []ResponseExpectation{StatusCodeExpectation(sets.NewInt(http.StatusNotFound))}, true)
-	}
-
-	loadbalancerAddress := localIngress.Status.PrivateLoadBalancer.Ingress[0].DomainInternal
-	proxyName, proxyPort, cancel := CreateProxyService(t, clients, privateHostName, loadbalancerAddress)
-	defer cancel()
-
-	publicHostName := fmt.Sprintf("%s.%s", name, "example.com")
-	_, client, cancel = CreateIngressReady(t, clients, v1alpha1.IngressSpec{
-		Rules: []v1alpha1.IngressRule{{
-			Hosts:      []string{publicHostName},
-			Visibility: v1alpha1.IngressVisibilityExternalIP,
-			HTTP: &v1alpha1.HTTPIngressRuleValue{
-				Paths: []v1alpha1.HTTPIngressPath{{
-					Splits: []v1alpha1.IngressBackendSplit{{
-						IngressBackend: v1alpha1.IngressBackend{
-							ServiceName:      proxyName,
-							ServiceNamespace: test.ServingNamespace,
-							ServicePort:      intstr.FromInt(proxyPort),
-						},
-					}},
-				}},
-			},
-		}},
-	})
-	defer cancel()
-
-	tests := map[string]string{
-		"/foo":  fooName,
-		"/bar":  barName,
-		"/baz":  bazName,
-		"":      mainName,
-		"/asdf": mainName,
-	}
-
-	for path, want := range tests {
-		t.Run(path, func(t *testing.T) {
-			ri := RuntimeRequest(t, client, "http://"+publicHostName+path)
-			if ri == nil {
-				return
-			}
-
-			got := ri.Request.Headers.Get(headerName)
-			if got != want {
-				t.Errorf("Header[%q] = %q, wanted %q", headerName, got, want)
-			}
-		})
-	}
-}
diff --git a/test/conformance/ingress/websocket.go b/test/conformance/ingress/websocket.go
deleted file mode 100644
index 57aa7733a..000000000
--- a/test/conformance/ingress/websocket.go
+++ /dev/null
@@ -1,201 +0,0 @@
-/*
-Copyright 2019 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 ingress
-
-import (
-	"fmt"
-	"math/rand"
-	"net/http"
-	"net/url"
-	"strings"
-	"testing"
-	"time"
-
-	"github.com/google/go-cmp/cmp"
-	"github.com/gorilla/websocket"
-	"k8s.io/apimachinery/pkg/util/intstr"
-	"k8s.io/apimachinery/pkg/util/sets"
-	"knative.dev/networking/pkg/apis/networking/v1alpha1"
-	"knative.dev/serving/test"
-)
-
-// TestWebsocket verifies that websockets may be used via a simple Ingress.
-func TestWebsocket(t *testing.T) {
-	t.Parallel()
-	clients := test.Setup(t)
-
-	const suffix = "- pong"
-	name, port, cancel := CreateWebsocketService(t, clients, suffix)
-	defer cancel()
-
-	domain := name + ".example.com"
-
-	// Create a simple Ingress over the Service.
-	_, dialCtx, cancel := CreateIngressReadyDialContext(t, clients, v1alpha1.IngressSpec{
-		Rules: []v1alpha1.IngressRule{{
-			Hosts:      []string{domain},
-			Visibility: v1alpha1.IngressVisibilityExternalIP,
-			HTTP: &v1alpha1.HTTPIngressRuleValue{
-				Paths: []v1alpha1.HTTPIngressPath{{
-					Splits: []v1alpha1.IngressBackendSplit{{
-						IngressBackend: v1alpha1.IngressBackend{
-							ServiceName:      name,
-							ServiceNamespace: test.ServingNamespace,
-							ServicePort:      intstr.FromInt(port),
-						},
-					}},
-				}},
-			},
-		}},
-	})
-	defer cancel()
-
-	dialer := websocket.Dialer{
-		NetDialContext:   dialCtx,
-		Proxy:            http.ProxyFromEnvironment,
-		HandshakeTimeout: 45 * time.Second,
-	}
-
-	u := url.URL{Scheme: "ws", Host: domain, Path: "/"}
-	conn, _, err := dialer.Dial(u.String(), http.Header{"Host": {domain}})
-	if err != nil {
-		t.Fatal("Dial() =", err)
-	}
-	defer conn.Close()
-
-	for i := 0; i < 100; i++ {
-		checkWebsocketRoundTrip(t, conn, suffix)
-	}
-}
-
-// TestWebsocketSplit verifies that websockets may be used across a traffic split.
-func TestWebsocketSplit(t *testing.T) {
-	t.Parallel()
-	clients := test.Setup(t)
-
-	const suffixBlue = "- blue"
-	blueName, bluePort, cancel := CreateWebsocketService(t, clients, suffixBlue)
-	defer cancel()
-
-	const suffixGreen = "- green"
-	greenName, greenPort, cancel := CreateWebsocketService(t, clients, suffixGreen)
-	defer cancel()
-
-	// The suffixes we expect to see.
-	want := sets.NewString(suffixBlue, suffixGreen)
-
-	// Create a simple Ingress over the Service.
-	name := test.ObjectNameForTest(t)
-	domain := name + ".example.com"
-	_, dialCtx, cancel := CreateIngressReadyDialContext(t, clients, v1alpha1.IngressSpec{
-		Rules: []v1alpha1.IngressRule{{
-			Hosts:      []string{domain},
-			Visibility: v1alpha1.IngressVisibilityExternalIP,
-			HTTP: &v1alpha1.HTTPIngressRuleValue{
-				Paths: []v1alpha1.HTTPIngressPath{{
-					Splits: []v1alpha1.IngressBackendSplit{{
-						IngressBackend: v1alpha1.IngressBackend{
-							ServiceName:      blueName,
-							ServiceNamespace: test.ServingNamespace,
-							ServicePort:      intstr.FromInt(bluePort),
-						},
-						Percent: 50,
-					}, {
-						IngressBackend: v1alpha1.IngressBackend{
-							ServiceName:      greenName,
-							ServiceNamespace: test.ServingNamespace,
-							ServicePort:      intstr.FromInt(greenPort),
-						},
-						Percent: 50,
-					}},
-				}},
-			},
-		}},
-	})
-	defer cancel()
-
-	dialer := websocket.Dialer{
-		NetDialContext:   dialCtx,
-		Proxy:            http.ProxyFromEnvironment,
-		HandshakeTimeout: 45 * time.Second,
-	}
-	u := url.URL{Scheme: "ws", Host: domain, Path: "/"}
-
-	const maxRequests = 100
-	got := sets.NewString()
-	for i := 0; i < maxRequests; i++ {
-		conn, _, err := dialer.Dial(u.String(), http.Header{"Host": {domain}})
-		if err != nil {
-			t.Fatal("Dial() =", err)
-		}
-		defer conn.Close()
-
-		suffix := findWebsocketSuffix(t, conn)
-		if suffix == "" {
-			continue
-		}
-		got.Insert(suffix)
-
-		for j := 0; j < 10; j++ {
-			checkWebsocketRoundTrip(t, conn, suffix)
-		}
-
-		if want.Equal(got) {
-			// Short circuit if we've seen all splits.
-			return
-		}
-	}
-
-	// Us getting here means we haven't seen splits.
-	t.Errorf("(over %d requests) (-want, +got) = %s", maxRequests, cmp.Diff(want, got))
-}
-
-func findWebsocketSuffix(t *testing.T, conn *websocket.Conn) string {
-	// Establish the suffix that corresponds to this socket.
-	message := fmt.Sprintf("ping - %d", rand.Intn(1000))
-	if err := conn.WriteMessage(websocket.TextMessage, []byte(message)); err != nil {
-		t.Errorf("WriteMessage() = %v", err)
-		return ""
-	}
-
-	_, recv, err := conn.ReadMessage()
-	if err != nil {
-		t.Errorf("ReadMessage() = %v", err)
-		return ""
-	}
-	gotMsg := string(recv)
-	if !strings.HasPrefix(gotMsg, message) {
-		t.Errorf("ReadMessage() = %s, wanted %s prefix", gotMsg, message)
-		return ""
-	}
-	return strings.TrimSpace(strings.TrimPrefix(gotMsg, message))
-}
-
-func checkWebsocketRoundTrip(t *testing.T, conn *websocket.Conn, suffix string) {
-	message := fmt.Sprintf("ping - %d", rand.Intn(1000))
-	if err := conn.WriteMessage(websocket.TextMessage, []byte(message)); err != nil {
-		t.Errorf("WriteMessage() = %v", err)
-		return
-	}
-
-	// Read back the echoed message and compared with sent.
-	if _, recv, err := conn.ReadMessage(); err != nil {
-		t.Errorf("ReadMessage() = %v", err)
-	} else if got, want := string(recv), message+" "+suffix; got != want {
-		t.Errorf("ReadMessage() = %s, wanted %s", got, want)
-	}
-}
diff --git a/test/e2e-common.sh b/test/e2e-common.sh
index e14cbd677..b565ed461 100644
--- a/test/e2e-common.sh
+++ b/test/e2e-common.sh
@@ -645,6 +645,19 @@ function toggle_feature() {
   sleep 30
 }
 
+function immediate_gc() {
+  echo -n "Setting config-gc to immediate garbage collection"
+  local DATA='{"data":{'`
+      `'"retain-since-create-time":"disabled",'`
+      `'"retain-since-last-active-time":"disabled",'`
+      `'"min-non-active-revisions":"0",'`
+      `'"max-non-active-revisions":"0"'`
+      `"}}"
+  kubectl patch cm "config-gc" -n "${SYSTEM_NAMESPACE}" -p "${DATA}"
+  echo "Waiting 30s for change to get picked up."
+  sleep 30
+}
+
 function scale_controlplane() {
   for deployment in "$@"; do
     # Make sure all pods run in leader-elected mode.
diff --git a/test/e2e-tests.sh b/test/e2e-tests.sh
index bea93ee5f..7a1aec890 100755
--- a/test/e2e-tests.sh
+++ b/test/e2e-tests.sh
@@ -92,17 +92,11 @@ sleep 30
 # Run conformance and e2e tests.
 
 go_test_e2e -timeout=30m \
-  ./test/conformance/api/... ./test/conformance/runtime/... \
-  ./test/e2e \
+ ./test/conformance/api/... ./test/conformance/runtime/... \
+ ./test/e2e \
   ${parallelism} \
   "--resolvabledomain=$(use_resolvable_domain)" "${use_https}" "$(ingress_class)" || failed=1
 
-# We run KIngress conformance ingress separately, to make it easier to skip some tests.
-go_test_e2e -timeout=20m ./test/conformance/ingress ${parallelism}  \
-  `# Skip TestUpdate due to excessive flaking https://github.com/knative/serving/issues/8032` \
-  -run="TestIngressConformance/^[^u]" \
-  "--resolvabledomain=$(use_resolvable_domain)" "${use_https}" "$(ingress_class)" || failed=1
-
 if (( HTTPS )); then
   kubectl delete -f ${TMP_DIR}/test/config/autotls/certmanager/caissuer/ --ignore-not-found
   toggle_feature autoTLS Disabled config-network
@@ -117,21 +111,13 @@ go_test_e2e -timeout=2m ./test/e2e/multicontainer || failed=1
 toggle_feature multi-container Disabled
 
 toggle_feature responsive-revision-gc Enabled
+GC_CONFIG=$(kubectl get cm "config-gc" -n "${SYSTEM_NAMESPACE}" -o yaml)
+add_trap "kubectl patch cm 'config-gc' -n ${SYSTEM_NAMESPACE} -p ${GC_CONFIG}" SIGKILL SIGTERM SIGQUIT
+immediate_gc
 go_test_e2e -timeout=2m ./test/e2e/gc || failed=1
+kubectl patch cm "config-gc" -n ${SYSTEM_NAMESPACE} -p ${GC_CONFIG}
 toggle_feature responsive-revision-gc Disabled
 
-# Certificate conformance tests must be run separately
-# because they need cert-manager specific configurations.
-kubectl apply -f ${TMP_DIR}/test/config/autotls/certmanager/selfsigned/
-add_trap "kubectl delete -f ${TMP_DIR}/test/config/autotls/certmanager/selfsigned/ --ignore-not-found" SIGKILL SIGTERM SIGQUIT
-go_test_e2e -timeout=10m ./test/conformance/certificate/nonhttp01 "$(certificate_class)" || failed=1
-kubectl delete -f ${TMP_DIR}/test/config/autotls/certmanager/selfsigned/
-
-kubectl apply -f ${TMP_DIR}/test/config/autotls/certmanager/http01/
-add_trap "kubectl delete -f ${TMP_DIR}/test/config/autotls/certmanager/http01/ --ignore-not-found" SIGKILL SIGTERM SIGQUIT
-go_test_e2e -timeout=10m ./test/conformance/certificate/http01 "$(certificate_class)" || failed=1
-kubectl delete -f ${TMP_DIR}/test/config/autotls/certmanager/http01/
-
 # Run scale tests.
 go_test_e2e -timeout=10m ${parallelism} ./test/scale || failed=1
 
diff --git a/test/e2e/autotls/auto_tls_test.go b/test/e2e/autotls/auto_tls_test.go
index a3dbac427..3c67cc147 100644
--- a/test/e2e/autotls/auto_tls_test.go
+++ b/test/e2e/autotls/auto_tls_test.go
@@ -32,7 +32,6 @@ import (
 	servingv1 "knative.dev/serving/pkg/apis/serving/v1"
 	routenames "knative.dev/serving/pkg/reconciler/route/resources/names"
 	"knative.dev/serving/test"
-	testingress "knative.dev/serving/test/conformance/ingress"
 	"knative.dev/serving/test/e2e"
 	v1test "knative.dev/serving/test/v1"
 )
@@ -85,7 +84,7 @@ func testAutoTLS(t *testing.T) {
 	certName := getCertificateName(t, clients, objects)
 	rootCAs := createRootCAs(t, clients, objects.Route.Namespace, certName)
 	httpsClient := createHTTPSClient(t, clients, objects, rootCAs)
-	testingress.RuntimeRequest(t, httpsClient, objects.Service.Status.URL.String())
+	runtimeRequest(t, httpsClient, objects.Service.Status.URL.String())
 
 	t.Run("Tag route", func(t *testing.T) {
 		// Probe main URL while we update the route
@@ -131,7 +130,7 @@ func testAutoTLS(t *testing.T) {
 		}
 		httpsClient := createHTTPSClient(t, clients, objects, rootCAs)
 		for _, traffic := range route.Status.Traffic {
-			testingress.RuntimeRequest(t, httpsClient, traffic.URL.String())
+			runtimeRequest(t, httpsClient, traffic.URL.String())
 		}
 	})
 }
@@ -190,7 +189,7 @@ func createHTTPSClient(t *testing.T, clients *test.Clients, objects *v1test.Reso
 	if err != nil {
 		t.Fatalf("Failed to get Ingress %s: %v", routenames.Ingress(objects.Route), err)
 	}
-	dialer := testingress.CreateDialContext(t, ing, clients)
+	dialer := CreateDialContext(t, ing, clients)
 	tlsConfig := &tls.Config{
 		RootCAs: rootCAs,
 	}
diff --git a/test/e2e/autotls/util.go b/test/e2e/autotls/util.go
new file mode 100644
index 000000000..2951553bb
--- /dev/null
+++ b/test/e2e/autotls/util.go
@@ -0,0 +1,201 @@
+/*
+Copyright 2019 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 autotls
+
+import (
+	"context"
+	"crypto/x509"
+	"encoding/json"
+	"errors"
+	"fmt"
+	"io/ioutil"
+	"net"
+	"net/http"
+	"net/http/httputil"
+	"net/url"
+	"strings"
+	"testing"
+	"time"
+
+	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+	pkgTest "knative.dev/pkg/test"
+
+	"k8s.io/apimachinery/pkg/util/sets"
+	"k8s.io/apimachinery/pkg/util/wait"
+	"knative.dev/networking/pkg/apis/networking/v1alpha1"
+	"knative.dev/pkg/network"
+	"knative.dev/serving/test"
+	"knative.dev/serving/test/types"
+)
+
+var rootCAs = x509.NewCertPool()
+
+var dialBackoff = wait.Backoff{
+	Duration: 50 * time.Millisecond,
+	Factor:   1.4,
+	Jitter:   0.1, // At most 10% jitter.
+	Steps:    100,
+	Cap:      10 * time.Second,
+}
+
+// CreateDialContext looks up the endpoint information to create a "dialer" for
+// the provided Ingress' public ingress loas balancer.  It can be used to
+// contact external-visibility services with an HTTP client via:
+//
+//	client := &http.Client{
+//		Transport: &http.Transport{
+//			DialContext: CreateDialContext(t, ing, clients),
+//		},
+//	}
+func CreateDialContext(t *testing.T, ing *v1alpha1.Ingress, clients *test.Clients) func(context.Context, string, string) (net.Conn, error) {
+	t.Helper()
+	if ing.Status.PublicLoadBalancer == nil || len(ing.Status.PublicLoadBalancer.Ingress) < 1 {
+		t.Fatal("Ingress does not have a public load balancer assigned.")
+	}
+
+	// TODO(mattmoor): I'm open to tricks that would let us cleanly test multiple
+	// public load balancers or LBs with multiple ingresses (below), but want to
+	// keep our simple tests simple, thus the [0]s...
+
+	// We expect an ingress LB with the form foo.bar.svc.cluster.local (though
+	// we aren't strictly sensitive to the suffix, this is just illustrative.
+	internalDomain := ing.Status.PublicLoadBalancer.Ingress[0].DomainInternal
+	parts := strings.SplitN(internalDomain, ".", 3)
+	if len(parts) < 3 {
+		t.Fatal("Too few parts in internal domain:", internalDomain)
+	}
+	name, namespace := parts[0], parts[1]
+
+	svc, err := clients.KubeClient.Kube.CoreV1().Services(namespace).Get(name, metav1.GetOptions{})
+	if err != nil {
+		t.Fatalf("Unable to retrieve Kubernetes service %s/%s: %v", namespace, name, err)
+	}
+	if len(svc.Status.LoadBalancer.Ingress) < 1 {
+		t.Fatal("Service does not have any ingresses (not type LoadBalancer?).")
+	}
+	ingress := svc.Status.LoadBalancer.Ingress[0]
+	dial := network.NewBackoffDialer(dialBackoff)
+	return func(ctx context.Context, _ string, address string) (net.Conn, error) {
+		_, port, err := net.SplitHostPort(address)
+		if err != nil {
+			return nil, err
+		}
+		// Allow "ingressendpoint" flag to override the discovered ingress IP/hostname,
+		// this is required in minikube-like environments.
+		if pkgTest.Flags.IngressEndpoint != "" {
+			return dial(ctx, "tcp", pkgTest.Flags.IngressEndpoint)
+		}
+		if ingress.IP != "" {
+			return dial(ctx, "tcp", ingress.IP+":"+port)
+		}
+		if ingress.Hostname != "" {
+			return dial(ctx, "tcp", ingress.Hostname+":"+port)
+		}
+		return nil, errors.New("service ingress does not contain dialing information")
+	}
+}
+
+type requestOption func(*http.Request)
+type responseExpectation func(response *http.Response) error
+
+func runtimeRequest(t *testing.T, client *http.Client, url string, opts ...requestOption) *types.RuntimeInfo {
+	return runtimeRequestWithExpectations(t, client, url,
+		[]responseExpectation{statusCodeExpectation(sets.NewInt(http.StatusOK))},
+		false,
+		opts...)
+}
+
+// runtimeRequestWithExpectations attempts to make a request to url and return runtime information.
+// If connection is successful only then it will validate all response expectations.
+// If allowDialError is set to true then function will not fail if connection is a dial error.
+func runtimeRequestWithExpectations(t *testing.T, client *http.Client, url string,
+	responseExpectations []responseExpectation,
+	allowDialError bool,
+	opts ...requestOption) *types.RuntimeInfo {
+	t.Helper()
+
+	req, err := http.NewRequest(http.MethodGet, url, nil)
+	if err != nil {
+		t.Errorf("Error creating Request: %v", err)
+		return nil
+	}
+
+	for _, opt := range opts {
+		opt(req)
+	}
+
+	resp, err := client.Do(req)
+
+	if err != nil {
+		if !allowDialError || !isDialError(err) {
+			t.Errorf("Error making GET request: %v", err)
+		}
+		return nil
+	}
+
+	defer resp.Body.Close()
+
+	for _, e := range responseExpectations {
+		if err := e(resp); err != nil {
+			t.Errorf("Error meeting response expectations: %v", err)
+			dumpResponse(t, resp)
+			return nil
+		}
+	}
+
+	if resp.StatusCode == http.StatusOK {
+		b, err := ioutil.ReadAll(resp.Body)
+		if err != nil {
+			t.Errorf("Unable to read response body: %v", err)
+			dumpResponse(t, resp)
+			return nil
+		}
+		ri := &types.RuntimeInfo{}
+		if err := json.Unmarshal(b, ri); err != nil {
+			t.Errorf("Unable to parse runtime image's response payload: %v", err)
+			return nil
+		}
+		return ri
+	}
+	return nil
+}
+
+func dumpResponse(t *testing.T, resp *http.Response) {
+	t.Helper()
+	b, err := httputil.DumpResponse(resp, true)
+	if err != nil {
+		t.Errorf("Error dumping response: %v", err)
+	}
+	t.Log(string(b))
+}
+
+func statusCodeExpectation(statusCodes sets.Int) responseExpectation {
+	return func(response *http.Response) error {
+		if !statusCodes.Has(response.StatusCode) {
+			return fmt.Errorf("got unexpected status: %d, expected %v", response.StatusCode, statusCodes)
+		}
+		return nil
+	}
+}
+
+func isDialError(err error) bool {
+	if err, ok := err.(*url.Error); ok {
+		err, ok := err.Err.(*net.OpError)
+		return ok && err.Op == "dial"
+	}
+	return false
+}
diff --git a/test/e2e/gc/gc_test.go b/test/e2e/gc/gc_test.go
index 3bb1b78e8..784779723 100644
--- a/test/e2e/gc/gc_test.go
+++ b/test/e2e/gc/gc_test.go
@@ -20,15 +20,21 @@ package gc
 
 import (
 	"testing"
+	"time"
 
+	apierrs "k8s.io/apimachinery/pkg/api/errors"
+	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+	"k8s.io/apimachinery/pkg/util/wait"
+
+	pkgTest "knative.dev/pkg/test"
 	"knative.dev/serving/pkg/apis/serving"
+	v1 "knative.dev/serving/pkg/apis/serving/v1"
+	rtesting "knative.dev/serving/pkg/testing/v1"
 	"knative.dev/serving/test"
 	"knative.dev/serving/test/e2e"
 	v1test "knative.dev/serving/test/v1"
 )
 
-// TODO(whaught): This tests that the labeler applies the new label, but we need to update the GC config
-// and assert deletion of old revisions.
 func TestRevisionGC(t *testing.T) {
 	t.Parallel()
 
@@ -52,4 +58,37 @@ func TestRevisionGC(t *testing.T) {
 	if val := revision.Labels[serving.RoutingStateLabelKey]; val != "active" {
 		t.Fatalf(`Got revision label %s=%q, want="active"`, serving.RoutingStateLabelKey, val)
 	}
+
+	t.Log("Updating the Service to use a different image.")
+	names.Image = test.PizzaPlanet2
+	image2 := pkgTest.ImagePath(names.Image)
+	if _, err := v1test.PatchService(t, clients, resources.Service, rtesting.WithServiceImage(image2)); err != nil {
+		t.Fatalf("Patch update for Service %s with new image %s failed: %v", names.Service, image2, err)
+	}
+
+	t.Log("Service should reflect new revision created and ready in status.")
+	names.Revision, err = v1test.WaitForServiceLatestRevision(clients, names)
+	if err != nil {
+		t.Fatal("New image not reflected in Service:", err)
+	}
+	t.Log("Waiting for Service to transition to Ready.")
+	if err := v1test.WaitForServiceState(clients.ServingClient, names.Service, v1test.IsServiceReady, "ServiceIsReady"); err != nil {
+		t.Fatal("Error waiting for the service to become ready for the latest revision:", err)
+	}
+
+	// Poll for a minute to see not_found on the original revision.
+	var originalRevision *v1.Revision
+	err = wait.PollImmediate(5*time.Second, time.Minute, func() (bool, error) {
+		originalRevision, err = clients.ServingClient.Revisions.Get(revision.GetName(), metav1.GetOptions{})
+		if apierrs.IsNotFound(err) {
+			return true, nil
+		}
+		return false, err
+	})
+	if err == wait.ErrWaitTimeout {
+		t.Fatalf("Got revision %v, expected not_found", originalRevision)
+	}
+	if err != nil {
+		t.Fatalf("Got %q, expected not_found", err)
+	}
 }
diff --git a/test/test_images/failing/failing.go b/test/test_images/failing/failing.go
index 6d35ef6c5..60300cc4b 100644
--- a/test/test_images/failing/failing.go
+++ b/test/test_images/failing/failing.go
@@ -25,8 +25,7 @@ import (
 func main() {
 	log.Println("Started...")
 
-	// Sleep for 10 seconds to force a race condition, where this
-	// container becomes ready if no readinessProbe is set.
+	// Sleep for 10 seconds and then crash.
 	time.Sleep(10 * time.Second)
 
 	log.Println("Crashed...")
diff --git a/test/v1/revision.go b/test/v1/revision.go
index 04e65c09b..6d9a94276 100644
--- a/test/v1/revision.go
+++ b/test/v1/revision.go
@@ -60,9 +60,11 @@ func CheckRevisionState(client *test.ServingClients, name string, inState func(r
 	if err != nil {
 		return err
 	}
-	if done, err := inState(r); err != nil {
+	done, err := inState(r)
+	if err != nil {
 		return err
-	} else if !done {
+	}
+	if !done {
 		return fmt.Errorf("revision %q is not in desired state, got: %+v", name, r)
 	}
 	return nil
diff --git a/vendor/knative.dev/pkg/test/logstream/interface.go b/vendor/knative.dev/pkg/test/logstream/interface.go
index 7506546ae..bb85de7f6 100644
--- a/vendor/knative.dev/pkg/test/logstream/interface.go
+++ b/vendor/knative.dev/pkg/test/logstream/interface.go
@@ -18,6 +18,7 @@ package logstream
 
 import (
 	"os"
+	"sync"
 
 	"knative.dev/pkg/system"
 	"knative.dev/pkg/test"
@@ -31,6 +32,17 @@ type Canceler func()
 // `test.ObjectNameForTest(t)` to `t.Log`.  It returns a Canceler, which must
 // be called before the test completes.
 func Start(t test.TLegacy) Canceler {
+	// Do this lazily to make import ordering less important.
+	once.Do(func() {
+		if ns := os.Getenv(system.NamespaceEnvKey); ns != "" {
+			// If SYSTEM_NAMESPACE is set, then start the stream.
+			stream = &kubelogs{namespace: ns}
+		} else {
+			// Otherwise set up a null stream.
+			stream = &null{}
+		}
+	})
+
 	return stream.Start(t)
 }
 
@@ -38,15 +50,7 @@ type streamer interface {
 	Start(t test.TLegacy) Canceler
 }
 
-var stream streamer
-
-func init() {
-	ns := os.Getenv(system.NamespaceEnvKey)
-	if ns != "" {
-		// If SYSTEM_NAMESPACE is set, then start the stream.
-		stream = &kubelogs{namespace: ns}
-	} else {
-		// Otherwise set up a null stream.
-		stream = &null{}
-	}
-}
+var (
+	stream streamer
+	once   sync.Once
+)
diff --git a/vendor/knative.dev/pkg/test/logstream/kubelogs.go b/vendor/knative.dev/pkg/test/logstream/kubelogs.go
index b28ac6851..fcca1fefd 100644
--- a/vendor/knative.dev/pkg/test/logstream/kubelogs.go
+++ b/vendor/knative.dev/pkg/test/logstream/kubelogs.go
@@ -24,7 +24,6 @@ import (
 	"sync"
 	"time"
 
-	"golang.org/x/sync/errgroup"
 	corev1 "k8s.io/api/core/v1"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 	"k8s.io/apimachinery/pkg/util/sets"
@@ -52,7 +51,7 @@ var _ streamer = (*kubelogs)(nil)
 // timeFormat defines a simple timestamp with millisecond granularity
 const timeFormat = "15:04:05.000"
 
-func (k *kubelogs) startForPod(eg *errgroup.Group, pod *corev1.Pod) {
+func (k *kubelogs) startForPod(pod *corev1.Pod) {
 	// Grab data from all containers in the pods.  We need this in case
 	// an envoy sidecar is injected for mesh installs.  This should be
 	// equivalent to --all-containers.
@@ -67,10 +66,10 @@ func (k *kubelogs) startForPod(eg *errgroup.Group, pod *corev1.Pod) {
 			handleLine = k.handleGenericLine
 		}
 
-		eg.Go(func() error {
+		go func() {
 			options := &corev1.PodLogOptions{
 				Container: cn,
-				// Follow directs the api server to continuously stream logs back.
+				// Follow directs the API server to continuously stream logs back.
 				Follow: true,
 				// Only return new logs (this value is being used for "epsilon").
 				SinceSeconds: ptr.Int64(1),
@@ -79,7 +78,11 @@ func (k *kubelogs) startForPod(eg *errgroup.Group, pod *corev1.Pod) {
 			req := k.kc.Kube.CoreV1().Pods(psn).GetLogs(pn, options)
 			stream, err := req.Stream()
 			if err != nil {
-				return err
+				func() {
+					k.m.Lock()
+					defer k.m.Unlock()
+					k.err = err
+				}()
 			}
 			defer stream.Close()
 			// Read this container's stream.
@@ -89,8 +92,7 @@ func (k *kubelogs) startForPod(eg *errgroup.Group, pod *corev1.Pod) {
 			}
 			// Pods get killed with chaos duck, so logs might end
 			// before the test does. So don't report an error here.
-			return nil
-		})
+		}()
 	}
 }
 
@@ -111,8 +113,7 @@ func (k *kubelogs) watchPods(t test.TLegacy) {
 		t.Error("Logstream knative pod watch failed, logs might be missing", "error", err)
 		return
 	}
-	eg := errgroup.Group{}
-	eg.Go(func() error {
+	go func() error {
 		watchedPods := sets.NewString()
 		for ev := range wi.ResultChan() {
 			p := ev.Object.(*corev1.Pod)
@@ -125,21 +126,12 @@ func (k *kubelogs) watchPods(t test.TLegacy) {
 				}
 				if podIsReady(p) {
 					watchedPods.Insert(p.Name)
-					k.startForPod(&eg, p)
+					k.startForPod(p)
 					continue
 				}
 			}
 		}
 		return nil
-	})
-	// Monitor the error group in the background and surface an error on the kubelogs
-	// in case anything had an active stream open.
-	go func() {
-		if err := eg.Wait(); err != nil {
-			k.m.Lock()
-			defer k.m.Unlock()
-			k.err = err
-		}
 	}()
 }
 
diff --git a/vendor/knative.dev/pkg/test/logstream/null.go b/vendor/knative.dev/pkg/test/logstream/null.go
index 7a8ad1bc4..22d21c628 100644
--- a/vendor/knative.dev/pkg/test/logstream/null.go
+++ b/vendor/knative.dev/pkg/test/logstream/null.go
@@ -24,5 +24,6 @@ var _ streamer = (*null)(nil)
 
 // Start implements streamer
 func (*null) Start(t test.TLegacy) Canceler {
+	t.Log("logstream was requested, but SYSTEM_NAMESPACE was unset.")
 	return func() {}
 }