pkg/ttl: split timer sync tests into integrationtest#66866
pkg/ttl: split timer sync tests into integrationtest#66866hawkingrei wants to merge 2 commits intopingcap:masterfrom
Conversation
|
Review failed due to infrastructure/execution failure after retries. Please re-trigger review. ℹ️ Learn more details on Pantheon AI. |
📝 WalkthroughWalkthroughReorganized TTL worker tests: removed Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Warning There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure. 🔧 golangci-lint (2.5.0)Command failed Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@pkg/ttl/ttlworker/integrationtest/helpers_test.go`:
- Around line 44-60: The wrapper currently declares a shadow field "pool
syssession.Pool" leaving the embedded syssession.Pool nil; update
wrapPoolForTest and the struct so the embedded Pool is initialized and used:
remove the explicit "pool" field from poolTestWrapper (or stop using it), change
the constructor to return &poolTestWrapper{Pool: pool}, and update WithSession
to call w.Pool.WithSession(...) (or simply w.WithSession via the embedded field)
so the promoted methods (Get/Put/WithForceBlockGCSession) are backed by the
initialized embedded syssession.Pool.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro
Run ID: a2eb9584-8e3a-45f6-b66a-d8d93b1a9db0
📒 Files selected for processing (4)
pkg/ttl/ttlworker/BUILD.bazelpkg/ttl/ttlworker/integrationtest/BUILD.bazelpkg/ttl/ttlworker/integrationtest/helpers_test.gopkg/ttl/ttlworker/integrationtest/timer_sync_test.go
💤 Files with no reviewable changes (1)
- pkg/ttl/ttlworker/BUILD.bazel
| type poolTestWrapper struct { | ||
| syssession.Pool | ||
| pool syssession.Pool | ||
| inuse atomic.Int64 | ||
| } | ||
|
|
||
| func wrapPoolForTest(pool syssession.Pool) *poolTestWrapper { | ||
| return &poolTestWrapper{pool: pool} | ||
| } | ||
|
|
||
| func (w *poolTestWrapper) WithSession(fn func(*syssession.Session) error) error { | ||
| return w.pool.WithSession(func(s *syssession.Session) error { | ||
| w.inuse.Add(1) | ||
| defer w.inuse.Add(-1) | ||
| return fn(s) | ||
| }) | ||
| } |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "helpers_test.go:"
sed -n '44,60p' pkg/ttl/ttlworker/integrationtest/helpers_test.go
echo
echo "syssession.Pool interface:"
sed -n '38,50p' pkg/session/syssession/pool.go
echo
python - <<'PY'
from pathlib import Path
import re
text = Path("pkg/ttl/ttlworker/integrationtest/helpers_test.go").read_text()
ctor = re.search(r'return\s+&poolTestWrapper\{([^}]*)\}', text, re.S)
if not ctor:
raise SystemExit("constructor not found")
fields = ctor.group(1).strip().replace("\n", " ")
print("constructor fields:", fields)
print("initializes embedded Pool field:", "Pool:" in fields)
print("initializes shadow pool field:", "pool:" in fields)
PYRepository: pingcap/tidb
Length of output: 1197
🏁 Script executed:
# Search for usages of wrapPoolForTest and poolTestWrapper
rg 'wrapPoolForTest|poolTestWrapper' --type goRepository: pingcap/tidb
Length of output: 2161
🏁 Script executed:
# Check what methods are called on the pool wrapper in the test files
echo "=== task_manager_integration_test.go context around pool usage ==="
rg -A 10 -B 2 'pool := wrapPoolForTest' pkg/ttl/ttlworker/task_manager_integration_test.go | head -60
echo ""
echo "=== job_manager_integration_test.go context around pool usage ==="
rg -A 10 -B 2 'pool := wrapPoolForTest' pkg/ttl/ttlworker/job_manager_integration_test.go | head -60
echo ""
echo "=== timer_sync_test.go context around pool usage ==="
rg -A 10 -B 2 'pool := wrapPoolForTest' pkg/ttl/ttlworker/integrationtest/timer_sync_test.go | head -60
echo ""
echo "=== Check all method calls on pool variable ==="
rg '(?:pool|p)\.(?:Get|Put|WithForceBlockGCSession|WithSession|AssertNoSessionInUse)' pkg/ttl/ttlworker/task_manager_integration_test.go pkg/ttl/ttlworker/job_manager_integration_test.go pkg/ttl/ttlworker/integrationtest/timer_sync_test.goRepository: pingcap/tidb
Length of output: 5641
🏁 Script executed:
# Check what NewManagerJobAdapter, NewJobManager, and NewTTLTimerSyncer do with the pool parameter
echo "=== NewManagerJobAdapter implementation ==="
rg -A 20 'func NewManagerJobAdapter' pkg/ttl/ttlworker/
echo ""
echo "=== NewJobManager implementation ==="
rg -A 20 'func NewJobManager' pkg/ttl/ttlworker/
echo ""
echo "=== NewTTLTimerSyncer implementation ==="
rg -A 20 'func NewTTLTimerSyncer' pkg/ttl/ttlworker/
echo ""
echo "=== Check for Get/Put/WithForceBlockGCSession calls in these files ==="
rg '\.(Get|Put|WithForceBlockGCSession)\(' pkg/ttl/ttlworker/manager_job_adapter.go pkg/ttl/ttlworker/job_manager.go pkg/ttl/ttlworker/timer_sync.go 2>/dev/null || echo "Files not found, searching in all ttlworker"
rg '\.(Get|Put|WithForceBlockGCSession)\(' pkg/ttl/ttlworker/*.go | grep -v testRepository: pingcap/tidb
Length of output: 5117
🏁 Script executed:
# Search for the withSession helper function
echo "=== withSession helper function ==="
rg -B 2 -A 10 'func withSession' pkg/ttl/ttlworker/
echo ""
echo "=== Check what methods are called on sessPool in job_manager.go ==="
rg 'sessPool\.' pkg/ttl/ttlworker/job_manager.go
echo ""
echo "=== Check what methods are called on pool in timer_sync.go ==="
rg 'g\.pool\.' pkg/ttl/ttlworker/timer_sync.goRepository: pingcap/tidb
Length of output: 1093
🏁 Script executed:
# Search more broadly for pool usage in these files
echo "=== All references to sessPool in job_manager.go ==="
rg 'sessPool' pkg/ttl/ttlworker/job_manager.go
echo ""
echo "=== All references to pool in timer_sync.go ==="
rg '\bpool\b' pkg/ttl/ttlworker/timer_sync.go | head -30Repository: pingcap/tidb
Length of output: 1635
🏁 Script executed:
# Final verification: check if faultSessionPool (used in job_manager_integration_test.go) calls other methods
echo "=== Check newFaultSessionPool implementation ==="
rg -B 5 -A 30 'func newFaultSessionPool' pkg/ttl/ttlworker/job_manager_integration_test.go
echo ""
echo "=== Check faultSessionPool methods ==="
rg 'func.*faultSessionPool' pkg/ttl/ttlworker/job_manager_integration_test.goRepository: pingcap/tidb
Length of output: 144
🏁 Script executed:
# Search for newFaultSessionPool more carefully
rg -i 'fault.*pool' pkg/ttl/ttlworker/job_manager_integration_test.go
echo ""
echo "=== Look at the context where faultPool is used ==="
rg -B 3 -A 8 'faultPool :=' pkg/ttl/ttlworker/job_manager_integration_test.goRepository: pingcap/tidb
Length of output: 791
🏁 Script executed:
# Find the newFaultSessionPool definition
rg -B 5 -A 20 'func newFaultSessionPool' pkg/ttl/ttlworker/job_manager_integration_test.go
echo ""
echo "=== Check faultSessionPool struct and methods ==="
rg -B 2 -A 15 'type faultSessionPool' pkg/ttl/ttlworker/job_manager_integration_test.goRepository: pingcap/tidb
Length of output: 106
🏁 Script executed:
# Search for faultSessionPool definition across all test files
rg 'faultSessionPool|newFaultSessionPool' --type go -B 2 -A 15
echo ""
echo "=== Check what methods the test actually calls on the wrapper ==="
rg '(\.Get|\.Put|\.WithForceBlockGCSession)\(' pkg/ttl/ttlworker/ --type goRepository: pingcap/tidb
Length of output: 11848
Initialize the embedded syssession.Pool, not a shadow field.
poolTestWrapper embeds syssession.Pool to delegate Get/Put/WithForceBlockGCSession, but wrapPoolForTest only initializes pool. This leaves the promoted interface nil, so any call to these methods through the wrapper will panic. Although current tests avoid this by calling only WithSession (which is overridden), the wrapper violates the interface contract and will fail if future code calls other interface methods.
Suggested fix
type poolTestWrapper struct {
syssession.Pool
- pool syssession.Pool
inuse atomic.Int64
}
func wrapPoolForTest(pool syssession.Pool) *poolTestWrapper {
- return &poolTestWrapper{pool: pool}
+ return &poolTestWrapper{Pool: pool}
}
func (w *poolTestWrapper) WithSession(fn func(*syssession.Session) error) error {
- return w.pool.WithSession(func(s *syssession.Session) error {
+ return w.Pool.WithSession(func(s *syssession.Session) error {
w.inuse.Add(1)
defer w.inuse.Add(-1)
return fn(s)
})
}📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| type poolTestWrapper struct { | |
| syssession.Pool | |
| pool syssession.Pool | |
| inuse atomic.Int64 | |
| } | |
| func wrapPoolForTest(pool syssession.Pool) *poolTestWrapper { | |
| return &poolTestWrapper{pool: pool} | |
| } | |
| func (w *poolTestWrapper) WithSession(fn func(*syssession.Session) error) error { | |
| return w.pool.WithSession(func(s *syssession.Session) error { | |
| w.inuse.Add(1) | |
| defer w.inuse.Add(-1) | |
| return fn(s) | |
| }) | |
| } | |
| type poolTestWrapper struct { | |
| syssession.Pool | |
| inuse atomic.Int64 | |
| } | |
| func wrapPoolForTest(pool syssession.Pool) *poolTestWrapper { | |
| return &poolTestWrapper{Pool: pool} | |
| } | |
| func (w *poolTestWrapper) WithSession(fn func(*syssession.Session) error) error { | |
| return w.Pool.WithSession(func(s *syssession.Session) error { | |
| w.inuse.Add(1) | |
| defer w.inuse.Add(-1) | |
| return fn(s) | |
| }) | |
| } |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@pkg/ttl/ttlworker/integrationtest/helpers_test.go` around lines 44 - 60, The
wrapper currently declares a shadow field "pool syssession.Pool" leaving the
embedded syssession.Pool nil; update wrapPoolForTest and the struct so the
embedded Pool is initialized and used: remove the explicit "pool" field from
poolTestWrapper (or stop using it), change the constructor to return
&poolTestWrapper{Pool: pool}, and update WithSession to call
w.Pool.WithSession(...) (or simply w.WithSession via the embedded field) so the
promoted methods (Get/Put/WithForceBlockGCSession) are backed by the initialized
embedded syssession.Pool.
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## master #66866 +/- ##
================================================
- Coverage 77.6716% 77.4341% -0.2375%
================================================
Files 2009 1930 -79
Lines 550314 537782 -12532
================================================
- Hits 427438 416427 -11011
- Misses 121168 121353 +185
+ Partials 1708 2 -1706
Flags with carried forward coverage won't be shown. Click here to find out more.
🚀 New features to boost your workflow:
|
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@pkg/ttl/ttlworker/integrationtest/manager_job_adapter_test.go`:
- Around line 205-218: The test calls insertJob(...) three times but never calls
GetJob(...) after each insert, so the subsequent require.NoError(t, err) and
require.Nil(t, job) assertions are still checking results from the earlier
GetJob; fix by invoking GetJob with the corresponding tableID, physicalID and
requestID immediately after each insertJob call (e.g., job, err = GetJob(ctx,
tableID, physicalID, requestID) or using the test's adapter.GetJob), then assert
require.NoError(t, err) and require.Nil(t, job) on those fresh results to verify
nil is returned for mismatched tableID/physicalID/requestID.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro
Run ID: dc65a6f8-2562-4937-95cc-bbfa74747796
📒 Files selected for processing (3)
pkg/ttl/ttlworker/integrationtest/BUILD.bazelpkg/ttl/ttlworker/integrationtest/manager_job_adapter_test.gopkg/ttl/ttlworker/job_manager_integration_test.go
💤 Files with no reviewable changes (1)
- pkg/ttl/ttlworker/job_manager_integration_test.go
| insertJob(2, 2, "req1", cache.JobStatusFinished) | ||
| require.NoError(t, err) | ||
| require.Nil(t, job) | ||
| tk.MustExec("delete from mysql.tidb_ttl_job_history") | ||
|
|
||
| insertJob(1, 3, "req1", cache.JobStatusFinished) | ||
| require.NoError(t, err) | ||
| require.Nil(t, job) | ||
| tk.MustExec("delete from mysql.tidb_ttl_job_history") | ||
|
|
||
| insertJob(1, 2, "req2", cache.JobStatusFinished) | ||
| require.NoError(t, err) | ||
| require.Nil(t, job) | ||
| tk.MustExec("delete from mysql.tidb_ttl_job_history") |
There was a problem hiding this comment.
Missing GetJob calls after insertJob make these assertions ineffective.
Lines 206-207, 211-212, and 216-217 assert on err and job from the previous GetJob call at line 201, not from a new call after insertJob. These assertions don't actually verify that GetJob correctly returns nil for mismatched tableID, physicalID, or requestID.
🐛 Proposed fix to add GetJob calls
insertJob(2, 2, "req1", cache.JobStatusFinished)
+ job, err = adapter.GetJob(context.TODO(), 1, 2, "req1")
require.NoError(t, err)
require.Nil(t, job)
tk.MustExec("delete from mysql.tidb_ttl_job_history")
insertJob(1, 3, "req1", cache.JobStatusFinished)
+ job, err = adapter.GetJob(context.TODO(), 1, 2, "req1")
require.NoError(t, err)
require.Nil(t, job)
tk.MustExec("delete from mysql.tidb_ttl_job_history")
insertJob(1, 2, "req2", cache.JobStatusFinished)
+ job, err = adapter.GetJob(context.TODO(), 1, 2, "req1")
require.NoError(t, err)
require.Nil(t, job)
tk.MustExec("delete from mysql.tidb_ttl_job_history")📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| insertJob(2, 2, "req1", cache.JobStatusFinished) | |
| require.NoError(t, err) | |
| require.Nil(t, job) | |
| tk.MustExec("delete from mysql.tidb_ttl_job_history") | |
| insertJob(1, 3, "req1", cache.JobStatusFinished) | |
| require.NoError(t, err) | |
| require.Nil(t, job) | |
| tk.MustExec("delete from mysql.tidb_ttl_job_history") | |
| insertJob(1, 2, "req2", cache.JobStatusFinished) | |
| require.NoError(t, err) | |
| require.Nil(t, job) | |
| tk.MustExec("delete from mysql.tidb_ttl_job_history") | |
| insertJob(2, 2, "req1", cache.JobStatusFinished) | |
| job, err = adapter.GetJob(context.TODO(), 1, 2, "req1") | |
| require.NoError(t, err) | |
| require.Nil(t, job) | |
| tk.MustExec("delete from mysql.tidb_ttl_job_history") | |
| insertJob(1, 3, "req1", cache.JobStatusFinished) | |
| job, err = adapter.GetJob(context.TODO(), 1, 2, "req1") | |
| require.NoError(t, err) | |
| require.Nil(t, job) | |
| tk.MustExec("delete from mysql.tidb_ttl_job_history") | |
| insertJob(1, 2, "req2", cache.JobStatusFinished) | |
| job, err = adapter.GetJob(context.TODO(), 1, 2, "req1") | |
| require.NoError(t, err) | |
| require.Nil(t, job) | |
| tk.MustExec("delete from mysql.tidb_ttl_job_history") |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@pkg/ttl/ttlworker/integrationtest/manager_job_adapter_test.go` around lines
205 - 218, The test calls insertJob(...) three times but never calls GetJob(...)
after each insert, so the subsequent require.NoError(t, err) and require.Nil(t,
job) assertions are still checking results from the earlier GetJob; fix by
invoking GetJob with the corresponding tableID, physicalID and requestID
immediately after each insertJob call (e.g., job, err = GetJob(ctx, tableID,
physicalID, requestID) or using the test's adapter.GetJob), then assert
require.NoError(t, err) and require.Nil(t, job) on those fresh results to verify
nil is returned for mismatched tableID/physicalID/requestID.
|
/retest |
|
[APPROVALNOTIFIER] This PR is APPROVED This pull-request has been approved by: YangKeao 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 |
[LGTM Timeline notifier]Timeline:
|
|
/retest |
|
/retest |
What problem does this PR solve?
Issue Number: None
Problem Summary:
pkg/ttl/ttlworkertest target has accumulated many tests.timer_sync_test.gois a low-risk candidate to move first because it depends only on a small pair of local helpers and exportedttlworkerAPIs.What changed and how does it work?
pkg/ttl/ttlworker/timer_sync_test.gointopkg/ttl/ttlworker/integrationtest/timer_sync_test.go.pkg/ttl/ttlworker/integrationtest/helpers_test.goto keep the moved test self-contained.pkg/ttl/ttlworker/BUILD.bazel.Check List
Tests
Test commands:
make bazel_preparemake failpoint-enablego test -run TestValidateTTLWork -tags=intest,deadlock -vet=off ./pkg/ttl/ttlworkergo test -run 'TestTTLManualTriggerOneTimer|TestTTLTimerSync' -tags=intest,deadlock -vet=off ./pkg/ttl/ttlworker/integrationtestmake failpoint-disablemake lintSide effects
Documentation
Release note
Please refer to Release Notes Language Style Guide to write a quality release note.
Summary by CodeRabbit