Repository navigation
Conversation
Motivation: test/rekt.TestSinkBindingV1Deployment_BrokerAsSinkTLS's "Broker has HTTPS address" requirement flakes occasionally in CI (about 1 in 5 runs per knative-prow-updater-robot's tracking). The same "Broker has HTTPS address" requirement is also used by the PingSource, ApiServerSource, and Broker BrokerAsSinkTLS rekt features. Approach: addressable.ValidateAddress polled Address() until it returned any non-nil address, then called the validate predicate (e.g. AssertHTTPSAddress, which checks addr.URL.Scheme == "https") exactly once with no retry. A Broker's status.address can be reported before it satisfies a given predicate, e.g. reported as http:// before the reconciler flips it to https:// once the Broker's TLS state becomes ready. That one-shot check would fail immediately instead of waiting for the address to settle, causing the observed flake. ValidateAddress now polls (same wait.PollUntilContextTimeout idiom already used in this file and elsewhere in the codebase, e.g. broker.WaitForCondition) until the address is both present and passes validate(), retrying on a validation failure instead of erroring immediately. On timeout it reports the last validation error if one occurred, which is more actionable than a generic timeout error. Address() itself, and its ~8 other callers, are unchanged. Validation: Added test/rekt/resources/addressable/addressable_test.go, which seeds a fake dynamic client with an object whose status.address.url starts as http://, flips it to https:// after 60ms from a background goroutine (simulating the real timing race), and asserts ValidateAddress retries until it observes the https address rather than failing on the initial http one. - go test ./test/rekt/resources/addressable/... -run TestValidateAddress -v: PASS. - Confirmed the new test FAILS against the pre-fix code (verified via git stash on only addressable.go, rerunning the test: fails with "address is not HTTPS"), and PASSES with the fix - a failing-then-passing reproduction of the race, not a live cluster run. - go test -race -count=20 ./test/rekt/resources/addressable/...: PASS, no data race. - go build ./... and go vet ./test/rekt/...: clean. - go test ./test/rekt/...: all non-e2e-tagged packages pass. - golangci-lint run ./test/rekt/resources/addressable/...: 0 issues. - gofmt -l on changed files: clean. This change only affects test code (test/rekt), not production code paths. Report: knative#9378 Signed-off-by: Pujitha Paladugu <10557236+pujitha24@users.noreply.github.com> Assisted-by: claude-sonnet-5 (via Claude Code)
|
Hi @pujitha24. Thanks for your PR. I'm waiting for a knative member to verify that this patch is reasonable to test. If it is, they should reply with Regular contributors should join the org to skip this step. Once the patch is verified, the new status will be reflected by the I understand the commands that are listed here. DetailsInstructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository. |
|
/ok-to-test |
|
/retest |
| interval, timeout := k8s.PollTimings(ctx, timings) | ||
| var validateErr error | ||
| err := wait.PollUntilContextTimeout(ctx, interval, timeout, true, func(ctx context.Context) (bool, error) { |
There was a problem hiding this comment.
It's going into a good direction. I agree that it should stabilize tests that wait for https URL to be populated.
But this part is almost 1 to 1 copy of the very similar poll loop (L38-L56) a few lines above in Address. We shouldn't just copy it over, but rather refactor to create common polling function to be shared, and testable.
| err := wait.PollUntilContextTimeout(ctx, interval, timeout, true, func(ctx context.Context) (bool, error) { | ||
| addr, err := k8s.Address(ctx, gvr, name) | ||
| if err != nil { | ||
| if apierrors.IsNotFound(err) { |
There was a problem hiding this comment.
We can think of more transient cases, like timeouts or too many requests that are intermittently occur in e2e tests from the cluster, but can be retried. If the motivation is to improve stability.
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #9407 +/- ##
==========================================
+ Coverage 51.18% 51.26% +0.08%
==========================================
Files 411 411
Lines 22176 22179 +3
==========================================
+ Hits 11351 11371 +20
+ Misses 9951 9927 -24
- Partials 874 881 +7 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
|
/retest |
1 similar comment
|
/retest |
dsimansk
left a comment
There was a problem hiding this comment.
Per my last comment, there are code cleanups to be followed to reduce code duplication.
Extract the polling logic shared by Address and ValidateAddress into a single pollAddress helper, and retry timeout/throttling errors from the apiserver in addition to NotFound, per review feedback on knative#9407. Signed-off-by: Pujitha Paladugu <10557236+pujitha24@users.noreply.github.com>
Add tests for the shared pollAddress loop through Address(): it retries NotFound, Timeout, ServerTimeout and TooManyRequests errors until the address is returned, and stops on a non-transient error (Forbidden) instead of waiting for the timeout. Move the fake Broker setup into a helper shared by the new tests and the existing ValidateAddress test. Signed-off-by: Pujitha Paladugu <10557236+pujitha24@users.noreply.github.com> Assisted-by: claude-opus-5-5 (via Claude Code)
ValidateAddress reported the last validation error whenever pollAddress returned one, even if polling had then stopped on a non-transient error (e.g. Forbidden), which hid the real failure. Only prefer the validation error when the poll was interrupted by its timeout, and add tests for both cases. Signed-off-by: Pujitha Paladugu <10557236+pujitha24@users.noreply.github.com> Assisted-by: claude-opus-5-5 (via Claude Code)
|
Both points are handled in 806a1ab. 9203767 and 24d1e2d add tests for the shared loop.
|
|
/test reconciler-tests |
|
/approve |
|
[APPROVALNOTIFIER] This PR is APPROVED This pull-request has been approved by: dsimansk, pujitha24 The full list of commands accepted by this bot can be found here. The pull request process is described here DetailsNeeds approval from an approver in each of these files:
Approvers can indicate their approval by writing |
Motivation:
test/rekt.TestSinkBindingV1Deployment_BrokerAsSinkTLS's "Broker has HTTPS
address" requirement flakes occasionally in CI (about 1 in 5 runs per
knative-prow-updater-robot's tracking). The same "Broker has HTTPS
address" requirement is also used by the PingSource, ApiServerSource, and
Broker BrokerAsSinkTLS rekt features.
Approach:
addressable.ValidateAddress polled Address() until it returned any
non-nil address, then called the validate predicate (e.g.
AssertHTTPSAddress, which checks addr.URL.Scheme == "https") exactly
once with no retry. A Broker's status.address can be reported before it
satisfies a given predicate, e.g. reported as http:// before the
reconciler flips it to https:// once the Broker's TLS state becomes
ready. That one-shot check would fail immediately instead of waiting for
the address to settle, causing the observed flake.
ValidateAddress now polls (same wait.PollUntilContextTimeout idiom
already used in this file and elsewhere in the codebase, e.g.
broker.WaitForCondition) until the address is both present and passes
validate(), retrying on a validation failure instead of erroring
immediately. On timeout it reports the last validation error if one
occurred, which is more actionable than a generic timeout error.
Address() itself, and its ~8 other callers, are unchanged.
Validation:
Added test/rekt/resources/addressable/addressable_test.go, which seeds a
fake dynamic client with an object whose status.address.url starts as
http://, flips it to https:// after 60ms from a background goroutine
(simulating the real timing race), and asserts ValidateAddress retries
until it observes the https address rather than failing on the initial
http one.
git stash on only addressable.go, rerunning the test: fails with
"address is not HTTPS"), and PASSES with the fix - a failing-then-passing
reproduction of the race, not a live cluster run.
data race.
This change only affects test code (test/rekt), not production code paths.
Report: #9378
Signed-off-by: Pujitha Paladugu 10557236+pujitha24@users.noreply.github.com
Assisted-by: claude-sonnet-5 (via Claude Code)
Fixes #9378