Skip to content

Commit 0c3e232

Browse files
authored
Fix scheduling week N (#92)
We incorrectly returned an error in the helper function `CheckIsoWeek` if ISO week `N` did not match current week. This PR fixes the return value to `false` and the error to nil as expected.
1 parent 32e16ff commit 0c3e232

3 files changed

Lines changed: 110 additions & 23 deletions

File tree

controllers/upgradeconfig_controller.go

Lines changed: 2 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import (
2121

2222
managedupgradev1beta1 "github.com/appuio/openshift-upgrade-controller/api/v1beta1"
2323
"github.com/appuio/openshift-upgrade-controller/pkg/clusterversion"
24+
"github.com/appuio/openshift-upgrade-controller/pkg/scheduleutils"
2425
)
2526

2627
const (
@@ -287,7 +288,7 @@ func calcNextRun(earliest time.Time, sched cron.Schedule, schedISOWeek string) (
287288
nextRun := sched.Next(earliest)
288289
// if the next run is more than 1000 runs away, we assume that the cron schedule is invalid as a safe guard
289290
for i := 0; i < 1000; i++ {
290-
isoWeekOK, err := checkIsoWeek(nextRun, schedISOWeek)
291+
isoWeekOK, err := scheduleutils.CheckIsoWeek(nextRun, schedISOWeek)
291292
if err != nil {
292293
return time.Time{}, err
293294
}
@@ -298,25 +299,3 @@ func calcNextRun(earliest time.Time, sched cron.Schedule, schedISOWeek string) (
298299
}
299300
return time.Time{}, fmt.Errorf("could not find next run, max time: %s", nextRun)
300301
}
301-
302-
// checkIsoWeek checks if the given time is in the given iso week.
303-
// The iso week can be one of the following:
304-
// - "": every iso week
305-
// - "@even": every even iso week
306-
// - "@odd": every odd iso week
307-
// - "<N>": every iso week N
308-
func checkIsoWeek(t time.Time, schedISOWeek string) (bool, error) {
309-
_, iw := t.ISOWeek()
310-
switch schedISOWeek {
311-
case "":
312-
return true, nil
313-
case "@even":
314-
return iw%2 == 0, nil
315-
case "@odd":
316-
return iw%2 == 1, nil
317-
case strconv.Itoa(iw):
318-
return true, nil
319-
default:
320-
return false, fmt.Errorf("unknown iso week: %s", schedISOWeek)
321-
}
322-
}

pkg/scheduleutils/scheduleutils.go

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
package scheduleutils
2+
3+
import (
4+
"fmt"
5+
"strconv"
6+
"time"
7+
)
8+
9+
// CheckIsoWeek checks if the given time is in the given iso week.
10+
// The iso week can be one of the following:
11+
// - "": every iso week
12+
// - "@even": every even iso week
13+
// - "@odd": every odd iso week
14+
// - "<N>": every iso week N
15+
func CheckIsoWeek(t time.Time, schedISOWeek string) (bool, error) {
16+
_, iw := t.ISOWeek()
17+
switch schedISOWeek {
18+
case "":
19+
return true, nil
20+
case "@even":
21+
return iw%2 == 0, nil
22+
case "@odd":
23+
return iw%2 == 1, nil
24+
}
25+
26+
nw, err := strconv.ParseInt(schedISOWeek, 10, 64)
27+
if err == nil {
28+
return nw == int64(iw), nil
29+
}
30+
return false, fmt.Errorf("unknown iso week: %s", schedISOWeek)
31+
}
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
package scheduleutils
2+
3+
import (
4+
"fmt"
5+
"testing"
6+
"time"
7+
8+
"github.com/stretchr/testify/require"
9+
)
10+
11+
func TestCheckIsoWeek(t *testing.T) {
12+
tc := []struct {
13+
t time.Time
14+
schedISOWeek string
15+
expected bool
16+
expectedErr error
17+
}{
18+
{
19+
t: time.Date(2021, 1, 1, 0, 0, 0, 0, time.UTC),
20+
schedISOWeek: "",
21+
expected: true,
22+
},
23+
{
24+
t: time.Date(2021, 1, 1, 0, 0, 0, 0, time.UTC),
25+
schedISOWeek: "@even",
26+
expected: false,
27+
},
28+
{
29+
t: time.Date(2021, 1, 13, 0, 0, 0, 0, time.UTC),
30+
schedISOWeek: "@even",
31+
expected: true,
32+
},
33+
{
34+
t: time.Date(2021, 1, 1, 0, 0, 0, 0, time.UTC),
35+
schedISOWeek: "@odd",
36+
expected: true,
37+
},
38+
{
39+
t: time.Date(2021, 1, 13, 0, 0, 0, 0, time.UTC),
40+
schedISOWeek: "@odd",
41+
expected: false,
42+
},
43+
{
44+
t: time.Date(2021, 1, 1, 0, 0, 0, 0, time.UTC),
45+
schedISOWeek: "53",
46+
expected: true,
47+
},
48+
{
49+
t: time.Date(2021, 1, 1, 0, 0, 0, 0, time.UTC),
50+
schedISOWeek: "1",
51+
expected: false,
52+
},
53+
{
54+
t: time.Date(2021, 1, 1, 0, 0, 0, 0, time.UTC),
55+
schedISOWeek: "invalid",
56+
expectedErr: fmt.Errorf("unknown iso week: invalid"),
57+
},
58+
}
59+
60+
for _, c := range tc {
61+
_, iw := c.t.ISOWeek()
62+
t.Run(fmt.Sprintf("sched: %s, iso week from time: %d", c.schedISOWeek, iw), func(t *testing.T) {
63+
got, err := CheckIsoWeek(c.t, c.schedISOWeek)
64+
if err != nil {
65+
if c.expectedErr == nil {
66+
t.Fatalf("unexpected error: %v", err)
67+
}
68+
require.Equal(t, c.expectedErr.Error(), err.Error())
69+
return
70+
}
71+
if c.expectedErr != nil {
72+
t.Fatalf("expected error %q, got nil", c.expectedErr)
73+
}
74+
require.Equal(t, c.expected, got)
75+
})
76+
}
77+
}

0 commit comments

Comments
 (0)