Browse Source

parser: fix combining of Dow and Dom

Relevant portion of the spec (https://en.wikipedia.org/wiki/Cron):

    While normally the job is executed when the time/date specification fields all
    match the current time and date, there is one exception: if both "day of month"
    (field 3) and "day of week" (field 5) are restricted (not "*"), then one or both
    must match the current day.[3]

When originally written, I incorrectly allowed restricted stars like "*/10" to
trigger the "all must match" behavior. This bug would cause some schedules to
run less frequently, or not at all.

Fixes #70
Rob Figueiredo 6 years ago
parent
commit
0f01e6b177
3 changed files with 7 additions and 4 deletions
  1. 3 0
      parser.go
  2. 1 1
      parser_test.go
  3. 3 3
      spec_test.go

+ 3 - 0
parser.go

@@ -322,6 +322,9 @@ func getRange(expr string, r bounds) (uint64, error) {
 		if singleDigit {
 			end = r.max
 		}
+		if step > 1 {
+			extra = 0
+		}
 	default:
 		return 0, fmt.Errorf("too many slashes: %s", expr)
 	}

+ 1 - 1
parser_test.go

@@ -30,7 +30,7 @@ func TestRange(t *testing.T) {
 		{"5-7/1", 0, 7, 1<<5 | 1<<6 | 1<<7, ""},
 
 		{"*", 1, 3, 1<<1 | 1<<2 | 1<<3 | starBit, ""},
-		{"*/2", 1, 3, 1<<1 | 1<<3 | starBit, ""},
+		{"*/2", 1, 3, 1<<1 | 1<<3, ""},
 
 		{"5--5", 0, 0, zero, "too many hyphens"},
 		{"jan-x", 0, 0, zero, "failed to parse int from"},

+ 3 - 3
spec_test.go

@@ -43,14 +43,14 @@ func TestActivation(t *testing.T) {
 		{"Sun Jul 1 00:00 2012", "@monthly", true},
 
 		// Test interaction of DOW and DOM.
-		// If both are specified, then only one needs to match.
+		// If both are restricted, then only one needs to match.
 		{"Sun Jul 15 00:00 2012", "* * 1,15 * Sun", true},
 		{"Fri Jun 15 00:00 2012", "* * 1,15 * Sun", true},
 		{"Wed Aug 1 00:00 2012", "* * 1,15 * Sun", true},
+		{"Sun Jul 15 00:00 2012", "* * */10 * Sun", true}, // verifies #70
 
 		// However, if one has a star, then both need to match.
 		{"Sun Jul 15 00:00 2012", "* * * * Mon", false},
-		{"Sun Jul 15 00:00 2012", "* * */10 * Sun", false},
 		{"Mon Jul 9 00:00 2012", "* * 1,15 * *", false},
 		{"Sun Jul 15 00:00 2012", "* * 1,15 * *", true},
 		{"Sun Jul 15 00:00 2012", "* * */2 * Sun", true},
@@ -97,7 +97,7 @@ func TestNext(t *testing.T) {
 
 		// Wrap around months
 		{"Mon Jul 9 23:35 2012", "0 0 0 9 Apr-Oct ?", "Thu Aug 9 00:00 2012"},
-		{"Mon Jul 9 23:35 2012", "0 0 0 */5 Apr,Aug,Oct Mon", "Mon Aug 6 00:00 2012"},
+		{"Mon Jul 9 23:35 2012", "0 0 0 */5 Apr,Aug,Oct Mon", "Tue Aug 1 00:00 2012"},
 		{"Mon Jul 9 23:35 2012", "0 0 0 */5 Oct Mon", "Mon Oct 1 00:00 2012"},
 
 		// Wrap around years