-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcron_test.go
More file actions
169 lines (150 loc) · 3.94 KB
/
Copy pathcron_test.go
File metadata and controls
169 lines (150 loc) · 3.94 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
package scheduler
import (
"testing"
"time"
)
func TestCalculateNextStart(t *testing.T) {
t.Run("non-recurring job returns nil", func(t *testing.T) {
job := &Job{
Interval: "",
}
next, err := calculateNextStart(job, 0)
if err != nil {
t.Errorf("unexpected error: %v", err)
}
if next != nil {
t.Error("expected nil for non-recurring job")
}
})
t.Run("invalid cron expression returns error", func(t *testing.T) {
job := &Job{
Interval: "invalid cron",
}
next, err := calculateNextStart(job, 0)
if err == nil {
t.Error("expected error for invalid cron expression")
}
if next != nil {
t.Error("expected nil when error occurs")
}
})
t.Run("calculates next execution time", func(t *testing.T) {
now := time.Now()
job := &Job{
SleepUntil: &now,
Interval: "*/5 * * * * *", // every 5 seconds (at :00, :05, :10, :15, etc.)
}
next, err := calculateNextStart(job, 0)
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
if next == nil {
t.Fatal("expected next execution time")
}
// Next execution should be at the next multiple of 5 seconds
// Delay should be > 0 and <= 5 seconds
diff := next.Sub(now)
if diff <= 0 || diff > 5*time.Second {
t.Errorf("expected 0 < delay <= 5 seconds, got %v", diff)
}
// The seconds value should be a multiple of 5
if next.Second()%5 != 0 {
t.Errorf("expected seconds to be multiple of 5, got %d", next.Second())
}
})
t.Run("respects reprocess delay", func(t *testing.T) {
now := time.Now()
job := &Job{
SleepUntil: &now,
Interval: "* * * * * *", // every second
}
reprocessDelay := 3 * time.Second
next, err := calculateNextStart(job, reprocessDelay)
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
if next == nil {
t.Fatal("expected next execution time")
}
// Should be at least reprocessDelay from now
diff := next.Sub(now)
if diff < reprocessDelay {
t.Errorf("expected at least %v delay, got %v", reprocessDelay, diff)
}
})
t.Run("returns nil when past repeatUntil", func(t *testing.T) {
now := time.Now()
past := now.Add(-1 * time.Hour)
job := &Job{
SleepUntil: &now,
Interval: "* * * * * *",
RepeatUntil: &past,
}
next, err := calculateNextStart(job, 0)
if err != nil {
t.Errorf("unexpected error: %v", err)
}
if next != nil {
t.Error("expected nil when past repeatUntil")
}
})
t.Run("returns now for old recurring jobs", func(t *testing.T) {
// Job that should have run 1 hour ago
past := time.Now().Add(-1 * time.Hour)
job := &Job{
SleepUntil: &past,
Interval: "* * * * * *", // every second
}
next, err := calculateNextStart(job, 0)
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
if next == nil {
t.Fatal("expected next execution time")
}
// Should return approximately now, not a past time
now := time.Now()
diff := next.Sub(now)
if diff > 1*time.Second || diff < -1*time.Second {
t.Errorf("expected approximately now, got diff of %v", diff)
}
})
t.Run("handles various cron expressions", func(t *testing.T) {
tests := []struct {
name string
interval string
wantErr bool
}{
{"every second", "* * * * * *", false},
{"every minute", "0 * * * * *", false},
{"every hour", "0 0 * * * *", false},
{"every 5 seconds", "*/5 * * * * *", false},
{"every 15 minutes", "0 */15 * * * *", false},
{"specific time", "0 0 12 * * *", false},
{"invalid", "not a cron", true},
{"too few fields", "* *", true},
}
now := time.Now()
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
job := &Job{
SleepUntil: &now,
Interval: tt.interval,
}
next, err := calculateNextStart(job, 0)
if tt.wantErr {
if err == nil {
t.Error("expected error but got none")
}
} else {
if err != nil {
t.Errorf("unexpected error: %v", err)
}
if next == nil {
t.Error("expected next time but got nil")
}
}
})
}
})
}