Skip to content

Commit 76862a4

Browse files
authored
Merge pull request #406 from andyxning/fix_cronjob_parse
fix cronjob parse
2 parents 4c8a7f7 + fb350ab commit 76862a4

2 files changed

Lines changed: 84 additions & 20 deletions

File tree

collectors/cronjob.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,7 @@ func (cjc *cronJobCollector) Collect(ch chan<- prometheus.Metric) {
143143
}
144144

145145
func getNextScheduledTime(schedule string, lastScheduleTime *metav1.Time, createdTime metav1.Time) (time.Time, error) {
146-
sched, err := cron.Parse(schedule)
146+
sched, err := cron.ParseStandard(schedule)
147147
if err != nil {
148148
return time.Time{}, fmt.Errorf("Failed to parse cron job schedule '%s': %s", schedule, err)
149149
}

collectors/cronjob_test.go

Lines changed: 83 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ limitations under the License.
1717
package collectors
1818

1919
import (
20+
"fmt"
21+
"math"
2022
"testing"
2123
"time"
2224

@@ -26,13 +28,14 @@ import (
2628
)
2729

2830
var (
29-
SuspendTrue bool = true
30-
SuspendFalse bool = false
31+
SuspendTrue = true
32+
SuspendFalse = false
3133
StartingDeadlineSeconds300 int64 = 300
3234

33-
ActiveRunningCronJob1LastScheduleTime = time.Unix(1500000000, 0)
34-
SuspendedCronJob1LastScheduleTime = time.Unix(1500000000+5.5*3600, 0) // 5.5 hours later
35-
ActiveCronJob1NoLastScheduledCreationTimestamp = time.Unix(1500000000+6.5*3600, 0)
35+
// "1520742896" is "2018/3/11 12:34:56" in "Asia/Shanghai".
36+
ActiveRunningCronJob1LastScheduleTime = time.Unix(1520742896, 0)
37+
SuspendedCronJob1LastScheduleTime = time.Unix(1520742896+5.5*3600, 0) // 5.5 hours later
38+
ActiveCronJob1NoLastScheduledCreationTimestamp = time.Unix(1520742896+6.5*3600, 0)
3639
)
3740

3841
type mockCronJobStore struct {
@@ -46,6 +49,65 @@ func (cjs mockCronJobStore) List() (cronJobs []batchv1beta1.CronJob, err error)
4649
func TestCronJobCollector(t *testing.T) {
4750
// Fixed metadata on type and help text. We prepend this to every expected
4851
// output so we only have to modify a single place when doing adjustments.
52+
53+
hour := ActiveRunningCronJob1LastScheduleTime.Hour()
54+
ActiveRunningCronJob1NextScheduleTime := time.Time{}
55+
switch {
56+
case hour < 6:
57+
ActiveRunningCronJob1NextScheduleTime = time.Date(
58+
ActiveRunningCronJob1LastScheduleTime.Year(),
59+
ActiveRunningCronJob1LastScheduleTime.Month(),
60+
ActiveRunningCronJob1LastScheduleTime.Day(),
61+
6,
62+
0,
63+
0, 0, time.Local)
64+
case hour < 12:
65+
ActiveRunningCronJob1NextScheduleTime = time.Date(
66+
ActiveRunningCronJob1LastScheduleTime.Year(),
67+
ActiveRunningCronJob1LastScheduleTime.Month(),
68+
ActiveRunningCronJob1LastScheduleTime.Day(),
69+
12,
70+
0,
71+
0, 0, time.Local)
72+
case hour < 18:
73+
ActiveRunningCronJob1NextScheduleTime = time.Date(
74+
ActiveRunningCronJob1LastScheduleTime.Year(),
75+
ActiveRunningCronJob1LastScheduleTime.Month(),
76+
ActiveRunningCronJob1LastScheduleTime.Day(),
77+
18,
78+
0,
79+
0, 0, time.Local)
80+
case hour < 24:
81+
ActiveRunningCronJob1NextScheduleTime = time.Date(
82+
ActiveRunningCronJob1LastScheduleTime.Year(),
83+
ActiveRunningCronJob1LastScheduleTime.Month(),
84+
ActiveRunningCronJob1LastScheduleTime.Day(),
85+
24,
86+
0,
87+
0, 0, time.Local)
88+
}
89+
90+
minute := ActiveCronJob1NoLastScheduledCreationTimestamp.Minute()
91+
ActiveCronJob1NoLastScheduledNextScheduleTime := time.Time{}
92+
switch {
93+
case minute < 25:
94+
ActiveCronJob1NoLastScheduledNextScheduleTime = time.Date(
95+
ActiveCronJob1NoLastScheduledCreationTimestamp.Year(),
96+
ActiveCronJob1NoLastScheduledCreationTimestamp.Month(),
97+
ActiveCronJob1NoLastScheduledCreationTimestamp.Day(),
98+
ActiveCronJob1NoLastScheduledCreationTimestamp.Hour(),
99+
25,
100+
0, 0, time.Local)
101+
default:
102+
ActiveCronJob1NoLastScheduledNextScheduleTime = time.Date(
103+
ActiveCronJob1NoLastScheduledNextScheduleTime.Year(),
104+
ActiveCronJob1NoLastScheduledNextScheduleTime.Month(),
105+
ActiveCronJob1NoLastScheduledNextScheduleTime.Day(),
106+
ActiveCronJob1NoLastScheduledNextScheduleTime.Hour()+1,
107+
25,
108+
0, 0, time.Local)
109+
}
110+
49111
const metadata = `
50112
# HELP kube_cronjob_labels Kubernetes labels converted to Prometheus labels.
51113
# TYPE kube_cronjob_labels gauge
@@ -80,14 +142,14 @@ func TestCronJobCollector(t *testing.T) {
80142
},
81143
},
82144
Status: batchv1beta1.CronJobStatus{
83-
Active: []v1.ObjectReference{v1.ObjectReference{Name: "FakeJob1"}, v1.ObjectReference{Name: "FakeJob2"}},
145+
Active: []v1.ObjectReference{{Name: "FakeJob1"}, {Name: "FakeJob2"}},
84146
LastScheduleTime: &metav1.Time{Time: ActiveRunningCronJob1LastScheduleTime},
85147
},
86148
Spec: batchv1beta1.CronJobSpec{
87149
StartingDeadlineSeconds: &StartingDeadlineSeconds300,
88150
ConcurrencyPolicy: "Forbid",
89151
Suspend: &SuspendFalse,
90-
Schedule: "0 */6 * * * *",
152+
Schedule: "0 */6 * * *",
91153
},
92154
}, {
93155
ObjectMeta: metav1.ObjectMeta{
@@ -106,7 +168,7 @@ func TestCronJobCollector(t *testing.T) {
106168
StartingDeadlineSeconds: &StartingDeadlineSeconds300,
107169
ConcurrencyPolicy: "Forbid",
108170
Suspend: &SuspendTrue,
109-
Schedule: "0 */3 * * * *",
171+
Schedule: "0 */3 * * *",
110172
},
111173
}, {
112174
ObjectMeta: metav1.ObjectMeta{
@@ -126,24 +188,26 @@ func TestCronJobCollector(t *testing.T) {
126188
StartingDeadlineSeconds: &StartingDeadlineSeconds300,
127189
ConcurrencyPolicy: "Forbid",
128190
Suspend: &SuspendFalse,
129-
Schedule: "25 * * * * *",
191+
Schedule: "25 * * * *",
130192
},
131193
},
132194
},
133195
want: metadata + `
134-
kube_cronjob_created{cronjob="ActiveCronJob1NoLastScheduled",namespace="ns1"} 1.5000234e+09
196+
kube_cronjob_created{cronjob="ActiveCronJob1NoLastScheduled",namespace="ns1"} 1.520766296e+09
135197
136-
kube_cronjob_info{concurrency_policy="Forbid",cronjob="ActiveRunningCronJob1",namespace="ns1",schedule="0 */6 * * * *"} 1
137-
kube_cronjob_info{concurrency_policy="Forbid",cronjob="SuspendedCronJob1",namespace="ns1",schedule="0 */3 * * * *"} 1
138-
kube_cronjob_info{concurrency_policy="Forbid",cronjob="ActiveCronJob1NoLastScheduled",namespace="ns1",schedule="25 * * * * *"} 1
198+
kube_cronjob_info{concurrency_policy="Forbid",cronjob="ActiveRunningCronJob1",namespace="ns1",schedule="0 */6 * * *"} 1
199+
kube_cronjob_info{concurrency_policy="Forbid",cronjob="SuspendedCronJob1",namespace="ns1",schedule="0 */3 * * *"} 1
200+
kube_cronjob_info{concurrency_policy="Forbid",cronjob="ActiveCronJob1NoLastScheduled",namespace="ns1",schedule="25 * * * *"} 1
139201
140202
kube_cronjob_labels{cronjob="ActiveCronJob1NoLastScheduled",label_app="example-active-no-last-scheduled-1",namespace="ns1"} 1
141203
kube_cronjob_labels{cronjob="ActiveRunningCronJob1",label_app="example-active-running-1",namespace="ns1"} 1
142204
kube_cronjob_labels{cronjob="SuspendedCronJob1",label_app="example-suspended-1",namespace="ns1"} 1
143-
144-
kube_cronjob_next_schedule_time{cronjob="ActiveCronJob1NoLastScheduled",namespace="ns1"} 1.500023425e+09
145-
kube_cronjob_next_schedule_time{cronjob="ActiveRunningCronJob1",namespace="ns1"} 1.50000012e+09
146-
205+
` +
206+
fmt.Sprintf("kube_cronjob_next_schedule_time{cronjob=\"ActiveCronJob1NoLastScheduled\",namespace=\"ns1\"} %ve+09\n",
207+
float64(ActiveCronJob1NoLastScheduledNextScheduleTime.Unix())/math.Pow10(9)) +
208+
fmt.Sprintf("kube_cronjob_next_schedule_time{cronjob=\"ActiveRunningCronJob1\",namespace=\"ns1\"} %ve+09\n",
209+
float64(ActiveRunningCronJob1NextScheduleTime.Unix())/math.Pow10(9)) +
210+
`
147211
kube_cronjob_spec_starting_deadline_seconds{cronjob="ActiveCronJob1NoLastScheduled",namespace="ns1"} 300
148212
kube_cronjob_spec_starting_deadline_seconds{cronjob="ActiveRunningCronJob1",namespace="ns1"} 300
149213
kube_cronjob_spec_starting_deadline_seconds{cronjob="SuspendedCronJob1",namespace="ns1"} 300
@@ -156,8 +220,8 @@ func TestCronJobCollector(t *testing.T) {
156220
kube_cronjob_status_active{cronjob="SuspendedCronJob1",namespace="ns1"} 0
157221
kube_cronjob_status_active{cronjob="ActiveCronJob1NoLastScheduled",namespace="ns1"} 0
158222
159-
kube_cronjob_status_last_schedule_time{cronjob="ActiveRunningCronJob1",namespace="ns1"} 1.5e+09
160-
kube_cronjob_status_last_schedule_time{cronjob="SuspendedCronJob1",namespace="ns1"} 1.5000198e+09
223+
kube_cronjob_status_last_schedule_time{cronjob="ActiveRunningCronJob1",namespace="ns1"} 1.520742896e+09
224+
kube_cronjob_status_last_schedule_time{cronjob="SuspendedCronJob1",namespace="ns1"} 1.520762696e+09
161225
`,
162226
},
163227
}

0 commit comments

Comments
 (0)