mirror of https://github.com/go-co-op/gocron.git
feat: test next run with multiple jobs
This commit is contained in:
parent
cb2774ecae
commit
97400fd553
100
job_test.go
100
job_test.go
|
|
@ -1195,3 +1195,103 @@ func TestWithIntervalFromCompletion_FirstRun(t *testing.T) {
|
||||||
assert.Less(t, timeSinceStart.Seconds(), 1.0,
|
assert.Less(t, timeSinceStart.Seconds(), 1.0,
|
||||||
"First run should happen quickly with WithStartImmediately")
|
"First run should happen quickly with WithStartImmediately")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestJob_NextRun_MultipleJobsSimultaneously(t *testing.T) {
|
||||||
|
// This test reproduces the bug where multiple jobs completing simultaneously
|
||||||
|
// would cause NextRun() to return stale values due to race conditions in
|
||||||
|
// nextScheduled cleanup.
|
||||||
|
|
||||||
|
testTime := time.Date(2000, 1, 1, 0, 0, 0, 0, time.UTC)
|
||||||
|
fakeClock := clockwork.NewFakeClockAt(testTime)
|
||||||
|
|
||||||
|
s := newTestScheduler(t,
|
||||||
|
WithClock(fakeClock),
|
||||||
|
WithLocation(time.UTC),
|
||||||
|
)
|
||||||
|
|
||||||
|
jobsCompleted := make(chan struct{}, 4)
|
||||||
|
|
||||||
|
// Create multiple jobs with different intervals that will complete around the same time
|
||||||
|
job1, err := s.NewJob(
|
||||||
|
DurationJob(1*time.Minute),
|
||||||
|
NewTask(func() {
|
||||||
|
jobsCompleted <- struct{}{}
|
||||||
|
}),
|
||||||
|
WithName("job1"),
|
||||||
|
WithStartAt(WithStartImmediately()),
|
||||||
|
)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
job2, err := s.NewJob(
|
||||||
|
DurationJob(2*time.Minute),
|
||||||
|
NewTask(func() {
|
||||||
|
jobsCompleted <- struct{}{}
|
||||||
|
}),
|
||||||
|
WithName("job2"),
|
||||||
|
WithStartAt(WithStartImmediately()),
|
||||||
|
)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
job3, err := s.NewJob(
|
||||||
|
DurationJob(3*time.Minute),
|
||||||
|
NewTask(func() {
|
||||||
|
jobsCompleted <- struct{}{}
|
||||||
|
}),
|
||||||
|
WithName("job3"),
|
||||||
|
WithStartAt(WithStartImmediately()),
|
||||||
|
)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
job4, err := s.NewJob(
|
||||||
|
DurationJob(4*time.Minute),
|
||||||
|
NewTask(func() {
|
||||||
|
jobsCompleted <- struct{}{}
|
||||||
|
}),
|
||||||
|
WithName("job4"),
|
||||||
|
WithStartAt(WithStartImmediately()),
|
||||||
|
)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
s.Start()
|
||||||
|
|
||||||
|
// Wait for all 4 jobs to complete their immediate run
|
||||||
|
for i := 0; i < 4; i++ {
|
||||||
|
<-jobsCompleted
|
||||||
|
}
|
||||||
|
|
||||||
|
// Give the scheduler time to process the completions and reschedule
|
||||||
|
time.Sleep(50 * time.Millisecond)
|
||||||
|
|
||||||
|
// Verify that NextRun() returns the correct next scheduled time for each job
|
||||||
|
// and not a stale value from the just-completed run
|
||||||
|
|
||||||
|
nextRun1, err := job1.NextRun()
|
||||||
|
require.NoError(t, err)
|
||||||
|
assert.Equal(t, testTime.Add(1*time.Minute), nextRun1, "job1 NextRun should be 1 minute from start")
|
||||||
|
|
||||||
|
nextRun2, err := job2.NextRun()
|
||||||
|
require.NoError(t, err)
|
||||||
|
assert.Equal(t, testTime.Add(2*time.Minute), nextRun2, "job2 NextRun should be 2 minutes from start")
|
||||||
|
|
||||||
|
nextRun3, err := job3.NextRun()
|
||||||
|
require.NoError(t, err)
|
||||||
|
assert.Equal(t, testTime.Add(3*time.Minute), nextRun3, "job3 NextRun should be 3 minutes from start")
|
||||||
|
|
||||||
|
nextRun4, err := job4.NextRun()
|
||||||
|
require.NoError(t, err)
|
||||||
|
assert.Equal(t, testTime.Add(4*time.Minute), nextRun4, "job4 NextRun should be 4 minutes from start")
|
||||||
|
|
||||||
|
// Advance time to trigger job1's next run
|
||||||
|
fakeClock.Advance(1 * time.Minute)
|
||||||
|
|
||||||
|
// Wait for job1 to complete
|
||||||
|
<-jobsCompleted
|
||||||
|
time.Sleep(50 * time.Millisecond)
|
||||||
|
|
||||||
|
// After job1's second run, it should be scheduled for +2 minutes from start
|
||||||
|
nextRun1, err = job1.NextRun()
|
||||||
|
require.NoError(t, err)
|
||||||
|
assert.Equal(t, testTime.Add(2*time.Minute), nextRun1, "job1 NextRun should be 2 minutes from start after first interval")
|
||||||
|
|
||||||
|
require.NoError(t, s.Shutdown())
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue