Repository: knative/serving
Pull request #9933 (2020-10-23 18:35:11)

Use proper zap.Error usage for errors
/assign mattmoor @dprotaso @julz 

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

This pull-request has been approved by: *<a href="https://github.com/knative/serving/pull/9933#" title="Author self-approved">vagababov</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/OWNERS](https://github.com/knative/serving/blob/master/pkg/reconciler/OWNERS)~~ [vagababov]

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":[]} -->
codecov[bot]: # [Codecov](https://codecov.io/gh/knative/serving/pull/9933?src=pr&el=h1) Report
> Merging [#9933](https://codecov.io/gh/knative/serving/pull/9933?src=pr&el=desc) into [master](https://codecov.io/gh/knative/serving/commit/d16dfead3480900db8e4a6a95ad4c8059c0287f5?el=desc) will **not change** coverage.
> The diff coverage is `100.00%`.

[![Impacted file tree graph](https://codecov.io/gh/knative/serving/pull/9933/graphs/tree.svg?width=650&height=150&src=pr&token=MPpDfAj4Ui)](https://codecov.io/gh/knative/serving/pull/9933?src=pr&el=tree)

```diff
@@           Coverage Diff           @@
##           master    #9933   +/-   ##
=======================================
  Coverage   87.85%   87.85%           
=======================================
  Files         183      183           
  Lines        8630     8630           
=======================================
  Hits         7582     7582           
  Misses        799      799           
  Partials      249      249           
```


| [Impacted Files](https://codecov.io/gh/knative/serving/pull/9933?src=pr&el=tree) | Coverage Δ | |
|---|---|---|
| [pkg/reconciler/revision/controller.go](https://codecov.io/gh/knative/serving/pull/9933/diff?src=pr&el=tree#diff-cGtnL3JlY29uY2lsZXIvcmV2aXNpb24vY29udHJvbGxlci5nbw==) | `85.10% <100.00%> (ø)` | |

------

[Continue to review full report at Codecov](https://codecov.io/gh/knative/serving/pull/9933?src=pr&el=continue).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/knative/serving/pull/9933?src=pr&el=footer). Last update [d16dfea...a53a3d2](https://codecov.io/gh/knative/serving/pull/9933?src=pr&el=lastupdated). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments).


Patch:
diff --git a/DEVELOPMENT.md b/DEVELOPMENT.md
index 38c750d85..a7599c51c 100644
--- a/DEVELOPMENT.md
+++ b/DEVELOPMENT.md
@@ -139,36 +139,6 @@ Kubernetes installation. Please go back to
 [your cluster setup](https://www.knative.dev/docs/install/) to reconfigure your
 Kubernetes cluster in your designated environment, if necessary.
 
-### Deploy Istio
-
-```shell
-kubectl apply -f "https://raw.githubusercontent.com/knative-sandbox/net-istio/master/third_party/istio-stable/istio-crds.yaml"
-while [[ $(kubectl get crd gateways.networking.istio.io -o jsonpath='{.status.conditions[?(@.type=="Established")].status}') != 'True' ]]; do
-  echo "Waiting on Istio CRDs"; sleep 1
-done
-kubectl apply -f "https://raw.githubusercontent.com/knative-sandbox/net-istio/master/third_party/istio-stable/istio-minimal.yaml"
-kubectl apply -f ./third_party/net-istio.yaml
-```
-
-Follow the
-[instructions](https://www.knative.dev/docs/serving/gke-assigning-static-ip-address/)
-if you need to set up static IP for Ingresses in the cluster.
-
-If you want to adopt preinstalled Istio, please check whether the
-`cluster-local-gateway` Service is deployed in namespace `istio-system` or not
-(you can check by running
-`kubectl get service cluster-local-gateway -n istio-system`). If it's not
-installed, please install it with the following command. You could also adjust
-parameters if needed.
-
-```shell
-kubectl apply -f "https://raw.githubusercontent.com/knative-sandbox/net-istio/master/third_party/istio-stable/istio-knative-extras.yaml"
-```
-
-> If you want to customize the `istio*.yaml` files you can refer to the
-> [Istio installation doc](https://github.com/knative/docs/blob/master/docs/install/installing-istio.md)
-> for more information.
-
 ### Deploy cert-manager
 
 1. Deploy `cert-manager` CRDs
@@ -207,7 +177,6 @@ while [[ $(kubectl get crd images.caching.internal.knative.dev -o jsonpath='{.st
 done
 
 ko apply -Rf config/core/
-kubectl apply -f ./third_party/net-istio.yaml
 
 # Optional steps
 
@@ -219,8 +188,7 @@ ko apply -f config/post-install/default-domain.yaml
 
 The above step is equivalent to applying the `serving-crds.yaml`,
 `serving-core.yaml`, `serving-hpa.yaml` and `serving-nscert.yaml` for released
-versions of Knative Serving and additionally applying **net-istio** as the
-ingress implementation.
+versions of Knative Serving.
 
 You can see things running with:
 
@@ -231,8 +199,6 @@ activator-7454cd659f-rrz86            1/1     Running   0          105s
 autoscaler-58cbfd4985-fl5h7           1/1     Running   0          105s
 autoscaler-hpa-77964b9b8c-9sbgq       1/1     Running   0          105s
 controller-847b7cc977-5mvvq           1/1     Running   0          105s
-istio-webhook-69bf66f869-cgc4l        1/1     Running   0          105s
-networking-istio-dcf7944fb-5m25h      1/1     Running   0          105s
 networking-ns-cert-56c58544db-sgstd   1/1     Running   0          105s
 webhook-6b6c77567f-flr59              1/1     Running   0          105s
 ```
@@ -249,6 +215,25 @@ check the
 page to ensure that all services are up and running (and not blocked by a quota
 issue, for example).
 
+### Deploy Knative Ingress
+
+Knative supports a variety of Ingress solutions.
+
+For simplicity, you can just run the following command to install Kourier.
+
+```
+kubectl apply -f https://github.com/knative/net-kourier/releases/download/v0.18.0/kourier.yaml
+
+kubectl patch configmap/config-network \
+  -n knative-serving \
+  --type merge \
+  -p '{"data":{"ingress.class":"kourier.ingress.networking.knative.dev"}}'
+```
+
+If you want to choose another Ingress solution, you can follow step 3 in the [Knative installation
+doc](https://knative.dev/docs/install/any-kubernetes-cluster/#installing-the-serving-component) to
+pick up an alternative Ingress solution and install it.
+
 ## Iterating
 
 As you make changes to the code-base, there are two special cases to be aware
@@ -300,9 +285,7 @@ You can delete all of the service components with:
 ```shell
 ko delete --ignore-not-found=true \
   -Rf config/core/ \
-  -f ./third_party/net-istio.yaml \
-  -f "https://raw.githubusercontent.com/knative-sandbox/net-istio/master/third_party/istio-stable/istio-minimal.yaml" \
-  -f "https://raw.githubusercontent.com/knative-sandbox/net-istio/master/third_party/istio-stable/istio-crds.yaml" \
+  -f https://github.com/knative/net-kourier/releases/download/v0.18.0/kourier.yaml \
   -f ./third_party/cert-manager-0.12.0/cert-manager-crds.yaml \
   -f ./third_party/cert-manager-0.12.0/cert-manager.yaml
 ```
diff --git a/pkg/apis/serving/v1/route_defaults.go b/pkg/apis/serving/v1/route_defaults.go
index 55bcc825f..652eef568 100644
--- a/pkg/apis/serving/v1/route_defaults.go
+++ b/pkg/apis/serving/v1/route_defaults.go
@@ -55,4 +55,11 @@ func (tt *TrafficTarget) SetDefaults(ctx context.Context) {
 	if tt.LatestRevision == nil {
 		tt.LatestRevision = ptr.Bool(tt.RevisionName == "")
 	}
+	// Despite the fact that we have the field percent
+	// as required, historically we were lenient about checking this.
+	// But by setting explicit `0` we can eliminate lots of checking
+	// downstream in validation and controllers.
+	if tt.Percent == nil {
+		tt.Percent = ptr.Int64(0)
+	}
 }
diff --git a/pkg/reconciler/revision/controller.go b/pkg/reconciler/revision/controller.go
index 6ec0e9a33..043adb94e 100644
--- a/pkg/reconciler/revision/controller.go
+++ b/pkg/reconciler/revision/controller.go
@@ -20,6 +20,7 @@ import (
 	"context"
 	"net/http"
 
+	"go.uber.org/zap"
 	cachingclient "knative.dev/caching/pkg/client/injection/client"
 	imageinformer "knative.dev/caching/pkg/client/injection/informers/caching/v1alpha1/image"
 	kubeclient "knative.dev/pkg/client/injection/kube/client"
@@ -105,7 +106,7 @@ func newControllerWithOptions(
 
 	transport := http.DefaultTransport
 	if rt, err := newResolverTransport(k8sCertPath, digestResolutionWorkers, digestResolutionWorkers); err != nil {
-		logging.FromContext(ctx).Error("Failed to create resolver transport: ", err)
+		logging.FromContext(ctx).Errorw("Failed to create resolver transport", zap.Error(err))
 	} else {
 		transport = rt
 	}
diff --git a/pkg/reconciler/route/traffic/rollout.go b/pkg/reconciler/route/traffic/rollout.go
index aef33dcde..32e4afcde 100644
--- a/pkg/reconciler/route/traffic/rollout.go
+++ b/pkg/reconciler/route/traffic/rollout.go
@@ -43,6 +43,11 @@ type ConfigurationRollout struct {
 	ConfigurationName string `json:"configurationName"`
 	Tag               string `json:"tag,omitempty"`
 
+	// Percent denotes the total percentage for this configuration.
+	// The individual percentages of the Revisions below will sum to this
+	// number.
+	Percent int `json:"percent"`
+
 	// The revisions in the rollout. In steady state this should
 	// contain 0 (no revision is ready) or 1 (rollout done).
 	// During the actual rollout it will contain N revisions
diff --git a/pkg/reconciler/route/traffic/traffic.go b/pkg/reconciler/route/traffic/traffic.go
index 88906cf1b..e7c440111 100644
--- a/pkg/reconciler/route/traffic/traffic.go
+++ b/pkg/reconciler/route/traffic/traffic.go
@@ -167,6 +167,8 @@ func newBuilder(
 
 // BuildRollout builds the current rollout state.
 // It is expected to be invoked after applySpecTraffic.
+// Returned Rollout will be sorted by tag and within tag by configuration
+// (only default tag can have more than configuration object attached).
 // TODO(vagababov): actually deal with rollouts, vs just report desired state.
 func (cfg *Config) BuildRollout() *Rollout {
 	rollout := &Rollout{}
@@ -205,9 +207,12 @@ func buildRolloutForTag(r *Rollout, tag string, rts RevisionTargets) {
 		r.Configurations = append(r.Configurations, ConfigurationRollout{
 			ConfigurationName: rt.ConfigurationName,
 			Tag:               tag,
+			Percent:           int(zeroIfNil(rt.Percent)),
 			Revisions: []RevisionRollout{{
 				RevisionName: rt.RevisionName,
-				Percent:      int(valIfNil(0, rt.Percent)),
+				// Note: this will match config value in steady state, but
+				// during rollout it will be overridden by the rollout logic.
+				Percent: int(zeroIfNil(rt.Percent)),
 			}},
 		})
 	}
@@ -340,10 +345,10 @@ func (cb *configBuilder) addRevisionTarget(tt *v1.TrafficTarget) error {
 	return nil
 }
 
-// valIfNil returns `val` if `ptr==nil`, or `*ptr` otherwise.
-func valIfNil(val int64, ptr *int64) int64 {
+// zeroIfNil returns `0` if `ptr==nil`, or `*ptr` otherwise.
+func zeroIfNil(ptr *int64) int64 {
 	if ptr == nil {
-		return val
+		return 0
 	}
 	return *ptr
 }
@@ -354,7 +359,7 @@ func mergeIfNecessary(rts RevisionTargets, rt RevisionTarget) RevisionTargets {
 	for i := range rts {
 		if rts[i].Tag == rt.Tag && rts[i].RevisionName == rt.RevisionName &&
 			*rt.LatestRevision == *rts[i].LatestRevision {
-			rts[i].Percent = ptr.Int64(valIfNil(0, rts[i].Percent) + valIfNil(0, rt.Percent))
+			rts[i].Percent = ptr.Int64(zeroIfNil(rts[i].Percent) + zeroIfNil(rt.Percent))
 			return rts
 		}
 	}
diff --git a/third_party/net-istio.yaml b/third_party/net-istio.yaml
index 6a2bb8b87..521b65fe5 100644
--- a/third_party/net-istio.yaml
+++ b/third_party/net-istio.yaml
@@ -18,7 +18,7 @@ metadata:
   # These are the permissions needed by the Istio Ingress implementation.
   name: knative-serving-istio
   labels:
-    serving.knative.dev/release: "v20201022-7bda3d56"
+    serving.knative.dev/release: "v20201023-3b6e0d50"
     serving.knative.dev/controller: "true"
     networking.knative.dev/ingress-provider: istio
 rules:
@@ -48,7 +48,7 @@ metadata:
   name: knative-ingress-gateway
   namespace: knative-serving
   labels:
-    serving.knative.dev/release: "v20201022-7bda3d56"
+    serving.knative.dev/release: "v20201023-3b6e0d50"
     networking.knative.dev/ingress-provider: istio
 spec:
   selector:
@@ -85,7 +85,7 @@ metadata:
   name: cluster-local-gateway
   namespace: knative-serving
   labels:
-    serving.knative.dev/release: "v20201022-7bda3d56"
+    serving.knative.dev/release: "v20201023-3b6e0d50"
     networking.knative.dev/ingress-provider: istio
 spec:
   selector:
@@ -104,7 +104,7 @@ metadata:
   name: knative-local-gateway
   namespace: knative-serving
   labels:
-    serving.knative.dev/release: "v20201022-7bda3d56"
+    serving.knative.dev/release: "v20201023-3b6e0d50"
     networking.knative.dev/ingress-provider: istio
 spec:
   selector:
@@ -123,7 +123,7 @@ metadata:
   name: knative-local-gateway
   namespace: knative-serving
   labels:
-    serving.knative.dev/release: "v20201022-7bda3d56"
+    serving.knative.dev/release: "v20201023-3b6e0d50"
     networking.knative.dev/ingress-provider: istio
 spec:
   type: ClusterIP
@@ -181,7 +181,7 @@ kind: MutatingWebhookConfiguration
 metadata:
   name: webhook.istio.networking.internal.knative.dev
   labels:
-    serving.knative.dev/release: "v20201022-7bda3d56"
+    serving.knative.dev/release: "v20201023-3b6e0d50"
     networking.knative.dev/ingress-provider: istio
 webhooks:
   - admissionReviewVersions:
@@ -217,7 +217,7 @@ kind: ValidatingWebhookConfiguration
 metadata:
   name: config.webhook.istio.networking.internal.knative.dev
   labels:
-    serving.knative.dev/release: "v20201022-7bda3d56"
+    serving.knative.dev/release: "v20201023-3b6e0d50"
     networking.knative.dev/ingress-provider: istio
 webhooks:
   - admissionReviewVersions:
@@ -255,7 +255,7 @@ metadata:
   name: istio-webhook-certs
   namespace: knative-serving
   labels:
-    serving.knative.dev/release: "v20201022-7bda3d56"
+    serving.knative.dev/release: "v20201023-3b6e0d50"
     networking.knative.dev/ingress-provider: istio
 
 ---
@@ -279,7 +279,7 @@ metadata:
   name: config-istio
   namespace: knative-serving
   labels:
-    serving.knative.dev/release: "v20201022-7bda3d56"
+    serving.knative.dev/release: "v20201023-3b6e0d50"
     networking.knative.dev/ingress-provider: istio
 data:
   _example: |
@@ -349,7 +349,7 @@ metadata:
   name: networking-istio
   namespace: knative-serving
   labels:
-    serving.knative.dev/release: "v20201022-7bda3d56"
+    serving.knative.dev/release: "v20201023-3b6e0d50"
     networking.knative.dev/ingress-provider: istio
 spec:
   selector:
@@ -365,14 +365,14 @@ spec:
         sidecar.istio.io/inject: "false"
       labels:
         app: networking-istio
-        serving.knative.dev/release: "v20201022-7bda3d56"
+        serving.knative.dev/release: "v20201023-3b6e0d50"
     spec:
       serviceAccountName: controller
       containers:
         - name: networking-istio
           # This is the Go import path for the binary that is containerized
           # and substituted here.
-          image: gcr.io/knative-nightly/knative.dev/net-istio/cmd/controller@sha256:b4750acde7a10a1a91f91884dfd5083b4bdac8bda4da8d1f1ddb3ff235793544
+          image: gcr.io/knative-nightly/knative.dev/net-istio/cmd/controller@sha256:b7d30876d7f9a5d476667cf92c62fb66977a7e7724509d8940eafee62bacc433
           resources:
             requests:
               cpu: 30m
@@ -424,7 +424,7 @@ metadata:
   name: istio-webhook
   namespace: knative-serving
   labels:
-    serving.knative.dev/release: "v20201022-7bda3d56"
+    serving.knative.dev/release: "v20201023-3b6e0d50"
     networking.knative.dev/ingress-provider: istio
 spec:
   selector:
@@ -438,14 +438,14 @@ spec:
       labels:
         app: istio-webhook
         role: istio-webhook
-        serving.knative.dev/release: "v20201022-7bda3d56"
+        serving.knative.dev/release: "v20201023-3b6e0d50"
     spec:
       serviceAccountName: controller
       containers:
         - name: webhook
           # This is the Go import path for the binary that is containerized
           # and substituted here.
-          image: gcr.io/knative-nightly/knative.dev/net-istio/cmd/webhook@sha256:8bc42e9af355c20d6fa0db45f7eb0e34e169d0528288cac8f8e70e7e9955a4ae
+          image: gcr.io/knative-nightly/knative.dev/net-istio/cmd/webhook@sha256:50842889b16c4a44444d9ef3f396c4557ae005a809e648e2e8dc01c4b495b1c8
           resources:
             requests:
               cpu: 20m
@@ -499,7 +499,7 @@ metadata:
   namespace: knative-serving
   labels:
     role: istio-webhook
-    serving.knative.dev/release: "v20201022-7bda3d56"
+    serving.knative.dev/release: "v20201023-3b6e0d50"
     networking.knative.dev/ingress-provider: istio
 spec:
   ports:


Test patch:
diff --git a/pkg/apis/serving/v1/route_defaults_test.go b/pkg/apis/serving/v1/route_defaults_test.go
index 7773c305e..9f409cb43 100644
--- a/pkg/apis/serving/v1/route_defaults_test.go
+++ b/pkg/apis/serving/v1/route_defaults_test.go
@@ -51,7 +51,7 @@ func TestRouteDefaulting(t *testing.T) {
 		},
 		wc: WithDefaultConfigurationName,
 	}, {
-		// Make sure it keeps a 'nil' as a 'nil' and not 'zero'
+		// Make sure it replaces a 'nil' as a '0'.
 		name: "implied zero percent",
 		in: &Route{
 			Spec: RouteSpec{
@@ -70,8 +70,8 @@ func TestRouteDefaulting(t *testing.T) {
 					LatestRevision: ptr.Bool(true),
 				}, {
 					RevisionName:   "bar",
-					Percent:        nil,
 					LatestRevision: ptr.Bool(false),
+					Percent:        ptr.Int64(0),
 				}},
 			},
 		},
diff --git a/pkg/apis/serving/v1/service_defaults_test.go b/pkg/apis/serving/v1/service_defaults_test.go
index 31b88e5ba..01547042a 100644
--- a/pkg/apis/serving/v1/service_defaults_test.go
+++ b/pkg/apis/serving/v1/service_defaults_test.go
@@ -253,6 +253,7 @@ func TestServiceDefaulting(t *testing.T) {
 						LatestRevision: ptr.Bool(false),
 					}, {
 						Tag:            "latest",
+						Percent:        ptr.Int64(0),
 						LatestRevision: ptr.Bool(true),
 					}},
 				},
diff --git a/pkg/reconciler/route/traffic/traffic_test.go b/pkg/reconciler/route/traffic/traffic_test.go
index d2656f55a..28e4cfafe 100644
--- a/pkg/reconciler/route/traffic/traffic_test.go
+++ b/pkg/reconciler/route/traffic/traffic_test.go
@@ -179,6 +179,7 @@ func TestBuildTrafficConfigurationVanilla(t *testing.T) {
 	wantR := &Rollout{
 		Configurations: []ConfigurationRollout{{
 			ConfigurationName: goodConfig.Name,
+			Percent:           100,
 			Revisions: []RevisionRollout{{
 				RevisionName: goodNewRev.Name,
 				Percent:      100,
@@ -282,6 +283,7 @@ func TestBuildTrafficConfigurationVanillaScaledToZero(t *testing.T) {
 	wantR := &Rollout{
 		Configurations: []ConfigurationRollout{{
 			ConfigurationName: inactiveConfig.Name,
+			Percent:           100,
 			Revisions: []RevisionRollout{{
 				RevisionName: inactiveRev.Name,
 				Percent:      100,
@@ -432,6 +434,7 @@ func TestBuildTrafficConfigurationTwoEntriesSameConfig(t *testing.T) {
 	wantR := &Rollout{
 		Configurations: []ConfigurationRollout{{
 			ConfigurationName: niceConfig.Name,
+			Percent:           100,
 			Revisions: []RevisionRollout{{
 				RevisionName: niceNewRev.Name,
 				Percent:      100,
@@ -566,18 +569,21 @@ func TestBuildTrafficConfigThreeConfigs(t *testing.T) {
 		// Default tag configs are sorted as well.
 		Configurations: []ConfigurationRollout{{
 			ConfigurationName: goodConfig.Name,
+			Percent:           35,
 			Revisions: []RevisionRollout{{
 				RevisionName: goodNewRev.Name,
 				Percent:      35,
 			}},
 		}, {
 			ConfigurationName: inactiveConfig.Name,
+			Percent:           35,
 			Revisions: []RevisionRollout{{
 				RevisionName: inactiveRev.Name,
 				Percent:      35,
 			}},
 		}, {
 			ConfigurationName: niceConfig.Name,
+			Percent:           30,
 			Revisions: []RevisionRollout{{
 				RevisionName: niceNewRev.Name,
 				Percent:      30,
@@ -586,6 +592,7 @@ func TestBuildTrafficConfigThreeConfigs(t *testing.T) {
 			// Note sorting flipped these two.
 			ConfigurationName: inactiveConfig.Name,
 			Tag:               "jackson",
+			Percent:           100,
 			Revisions: []RevisionRollout{{
 				RevisionName: inactiveRev.Name,
 				Percent:      100,
@@ -593,6 +600,7 @@ func TestBuildTrafficConfigThreeConfigs(t *testing.T) {
 		}, {
 			ConfigurationName: goodConfig.Name,
 			Tag:               "robert",
+			Percent:           100,
 			Revisions: []RevisionRollout{{
 				RevisionName: goodNewRev.Name,
 				Percent:      100,
@@ -675,6 +683,7 @@ func TestBuildTrafficConfigurationTwoEntriesSameConfigDifferentTags(t *testing.T
 	wantR := &Rollout{
 		Configurations: []ConfigurationRollout{{
 			ConfigurationName: niceConfig.Name,
+			Percent:           100,
 			Revisions: []RevisionRollout{{
 				RevisionName: niceNewRev.Name,
 				Percent:      100,
@@ -682,6 +691,7 @@ func TestBuildTrafficConfigurationTwoEntriesSameConfigDifferentTags(t *testing.T
 		}, {
 			ConfigurationName: niceConfig.Name,
 			Tag:               "robert",
+			Percent:           100,
 			Revisions: []RevisionRollout{{
 				RevisionName: niceNewRev.Name,
 				Percent:      100,
@@ -1030,6 +1040,7 @@ func TestBuildTrafficConfigurationPreliminary(t *testing.T) {
 					ConfigurationName: goodConfig.Name,
 					RevisionName:      goodNewRev.Name,
 					LatestRevision:    ptr.Bool(false),
+					Percent:           ptr.Int64(0),
 				},
 				Active:   true,
 				Protocol: net.ProtocolH2C,
@@ -1038,6 +1049,7 @@ func TestBuildTrafficConfigurationPreliminary(t *testing.T) {
 					Tag:               "alpha",
 					ConfigurationName: niceConfig.Name,
 					RevisionName:      niceNewRev.Name,
+					Percent:           ptr.Int64(0),
 					LatestRevision:    ptr.Bool(true),
 				},
 				Active:   true,
@@ -1081,6 +1093,7 @@ func TestBuildTrafficConfigurationPreliminary(t *testing.T) {
 				ConfigurationName: goodConfig.Name,
 				RevisionName:      goodNewRev.Name,
 				LatestRevision:    ptr.Bool(false),
+				Percent:           ptr.Int64(0),
 			},
 			Active:   true,
 			Protocol: net.ProtocolH2C,
@@ -1090,6 +1103,7 @@ func TestBuildTrafficConfigurationPreliminary(t *testing.T) {
 				ConfigurationName: niceConfig.Name,
 				RevisionName:      niceNewRev.Name,
 				LatestRevision:    ptr.Bool(true),
+				Percent:           ptr.Int64(0),
 			},
 			Active:   true,
 			Protocol: net.ProtocolH2C,
@@ -1318,11 +1332,13 @@ func TestRoundTripping(t *testing.T) {
 		RevisionName:   goodNewRev.Name,
 		URL:            domains.URL(domains.HTTPScheme, "beta-test-route.test.example.com"),
 		LatestRevision: ptr.Bool(false),
+		Percent:        ptr.Int64(0),
 	}, {
 		Tag:            "alpha",
 		RevisionName:   niceNewRev.Name,
 		URL:            domains.URL(domains.HTTPScheme, "alpha-test-route.test.example.com"),
 		LatestRevision: ptr.Bool(true),
+		Percent:        ptr.Int64(0),
 	}}
 	route := testRouteWithTrafficTargets(WithSpecTraffic(v1.TrafficTarget{
 		RevisionName: goodOldRev.Name,
diff --git a/test/conformance/api/v1/service_test.go b/test/conformance/api/v1/service_test.go
index 718ba3aeb..2d9b8f5df 100644
--- a/test/conformance/api/v1/service_test.go
+++ b/test/conformance/api/v1/service_test.go
@@ -24,6 +24,7 @@ import (
 
 	"github.com/google/go-cmp/cmp"
 	"github.com/google/go-cmp/cmp/cmpopts"
+
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 	"knative.dev/pkg/ptr"
 	pkgTest "knative.dev/pkg/test"
@@ -305,6 +306,7 @@ func TestServiceWithTrafficSplit(t *testing.T) {
 			Tag:            "latest",
 			RevisionName:   objects.Config.Status.LatestReadyRevisionName,
 			LatestRevision: ptr.Bool(true),
+			Percent:        ptr.Int64(0),
 		},
 	}
 	t.Log("Waiting for Service to become ready with the new shape.")
@@ -338,6 +340,7 @@ func TestServiceWithTrafficSplit(t *testing.T) {
 		Tag:            "latest",
 		RevisionName:   secondRevision,
 		LatestRevision: ptr.Bool(true),
+		Percent:        ptr.Int64(0),
 	}
 	t.Log("Waiting for Service to become ready with the new shape.")
 	if err := waitForDesiredTrafficShape(t, names.Service, desiredTrafficShape, clients); err != nil {
@@ -365,8 +368,7 @@ func TestServiceWithTrafficSplit(t *testing.T) {
 			RevisionName: secondRevision,
 			Percent:      ptr.Int64(50),
 		}, {
-			Tag:     "latest",
-			Percent: nil,
+			Tag: "latest",
 		}},
 	})
 	if err != nil {
@@ -390,6 +392,7 @@ func TestServiceWithTrafficSplit(t *testing.T) {
 			Tag:            "latest",
 			RevisionName:   secondRevision,
 			LatestRevision: ptr.Bool(true),
+			Percent:        ptr.Int64(0),
 		},
 	}
 	t.Log("Waiting for Service to become ready with the new shape.")
@@ -421,6 +424,7 @@ func TestServiceWithTrafficSplit(t *testing.T) {
 		Tag:            "latest",
 		RevisionName:   thirdRevision,
 		LatestRevision: ptr.Bool(true),
+		Percent:        ptr.Int64(0),
 	}
 	t.Log("Waiting for Service to become ready with the new shape.")
 	if err := waitForDesiredTrafficShape(t, names.Service, desiredTrafficShape, clients); err != nil {
diff --git a/test/e2e-tests.sh b/test/e2e-tests.sh
index 4414e6b86..b22de1b4c 100755
--- a/test/e2e-tests.sh
+++ b/test/e2e-tests.sh
@@ -132,7 +132,7 @@ go_test_e2e -timeout=20m -parallel=300 ./test/scale || failed=1
 
 # Run HA tests separately as they're stopping core Knative Serving pods
 # Define short -spoofinterval to ensure frequent probing while stopping pods
-go_test_e2e -timeout=15m -failfast -parallel=1 ./test/ha \
+go_test_e2e -timeout=25m -failfast -parallel=1 ./test/ha \
 	    -replicas="${REPLICAS:-1}" -buckets="${BUCKETS:-1}" -spoofinterval="10ms" || failed=1
 
 (( failed )) && fail_test