planner: flaky test TestBatchDropBindings#66559
Conversation
|
Review Failed Environment preparation failed after 3 attempts due to infrastructure service unavailability (503 Service Unavailable). Please retry the review request later when the upstream services recover. |
|
Hi @terry1purcell. Thanks for your PR. PRs from untrusted users cannot be marked as trusted with 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 |
There was a problem hiding this comment.
Pull request overview
Fixes flakiness in TestBatchDropBindings by making the bindinfo lease deterministic during the test, preventing background binding worker activity from introducing timing-dependent behavior.
Changes:
- Temporarily set
bindinfo.Leaseto0at the start ofTestBatchDropBindings. - Restore the original
bindinfo.Leasevalue viadeferto avoid leaking global state across tests.
|
@pantheon-bot please review |
|
Review Failed Environment preparation failed after 3 attempts due to infrastructure service unavailability (503 Service Unavailable). Please retry the review request later when the upstream services recover. |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## master #66559 +/- ##
================================================
- Coverage 77.6882% 77.5654% -0.1229%
================================================
Files 2006 1928 -78
Lines 548796 536467 -12329
================================================
- Hits 426350 416113 -10237
+ Misses 120785 120348 -437
+ Partials 1661 6 -1655
Flags with carried forward coverage won't be shown. Click here to find out more.
🚀 New features to boost your workflow:
|
|
/retest-required |
|
/retest |
|
/retest |
mjonss
left a comment
There was a problem hiding this comment.
Is this a test issue and not an actual issue with DROP BINDING?
|
[APPROVALNOTIFIER] This PR is APPROVED This pull-request has been approved by: fixdb, mjonss 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 |
|
In response to a cherrypick label: new pull request created to branch |
What problem does this PR solve?
Issue Number: close #66371
Problem Summary:
What changed and how does it work?
Decision was made here to fix the test rather than the underlying behavior. The test does expose a race condition - but the likelihood that a customer sees this as a critical issue, or that it has any significant impact to their operations - is arguably low.
The issue is - if the binding cache reload (which occurs every 3 seconds) had begun before the drop completed, then the dropped binding could be reloaded - and exist for 3 seconds longer than the user intended. The solution for that would be to add a mutex to the bindingCacheUpdater - but that would then be executed every 3 seconds. However, if a customer exposes this problem - then it may be necessary to add this fix.
Analysis of the issue:
Root Cause: Race Between Background Binding Loader and DROP
The test does not set bindinfo.Lease = 0, so the background goroutine globalBindHandleWorkerLoop (started in domain.go:1571) runs every 3 seconds, calling LoadFromStorageToCache(false, false). This races with the DropBinding operation's own deferred LoadFromStorageToCache call.
The Race in Detail
LoadFromStorageToCache (binding_cache.go:64) is not atomic — it first reads bindings from storage via SQL, then iterates over them updating the cache one-by-one. There is no mutex protecting the entire read-process cycle. Two concurrent calls can interleave.
Here's the problematic sequence:
Why the stale data persists
At step 4, the background goroutine also stores lastUpdateTime = T0 (from its stale snapshot), potentially overwriting the DROP's stored T1. This makes lastUpdateTime go backwards. The 10-second timeLagTolerance (binding_cache.go:94) means the next incremental load will likely catch the T1 deleted record again, but there's a transient window (up to the next 3-second tick) where the cache has stale data.
Key code locations
Evidence: other tests avoid this
TestGCBindRecord (bind_test.go:371-377) explicitly sets bindinfo.Lease = 0 before creating the mock store/domain, preventing the background goroutine from starting. TestBatchDropBindings does not.
Session bindings are not affected
removeAllBindings(tk, false) for session bindings uses DropSessionBinding (session_handle.go:90), which is a simple in-memory map delete with no background reload — no race possible there.
Summary
The flakiness is caused by the background globalBindHandleWorkerLoop goroutine's LoadFromStorageToCache interleaving with the DropBinding deferred LoadFromStorageToCache, re-adding stale (enabled) bindings to the cache after the DROP already removed them. The fix would be to set bindinfo.Lease = 0 at the start of the test (as TestGCBindRecord does), or to add mutual exclusion around LoadFromStorageToCache.
Check List
Tests
Side effects
Documentation
Release note
Please refer to Release Notes Language Style Guide to write a quality release note.