github.com/argoproj/argo-events@v1.9.1/common/cronutil_test.go (about)

     1  package common
     2  
     3  import (
     4  	"strings"
     5  	"testing"
     6  	"time"
     7  
     8  	cronlib "github.com/robfig/cron/v3"
     9  )
    10  
    11  func TestPrevCronTime(t *testing.T) {
    12  	runs := []struct {
    13  		time, spec  string
    14  		expected    string
    15  		expectedErr bool
    16  	}{
    17  		// Simple cases
    18  		{"Mon Jul 9 15:00 2012", "0 0/15 * * * *", "Mon Jul 9 14:45 2012", false},
    19  		{"Mon Jul 9 14:59 2012", "0 0/15 * * * *", "Mon Jul 9 14:45 2012", false},
    20  		{"Mon Jul 9 15:01:59 2012", "0 0/15 * * * *", "Mon Jul 9 15:00 2012", false},
    21  
    22  		// Wrap around hours
    23  		{"Mon Jul 9 15:10 2012", "0 20-35/15 * * * *", "Mon Jul 9 14:35 2012", false},
    24  
    25  		// Wrap around days
    26  		{"Tue Jul 10 00:00 2012", "0 */15 * * * *", "Tue Jul 9 23:45 2012", false},
    27  		{"Tue Jul 10 00:00 2012", "0 20-35/15 * * * *", "Tue Jul 9 23:35 2012", false},
    28  
    29  		// Wrap around months
    30  		{"Mon Jul 9 09:35 2012", "0 0 12 9 Apr-Oct ?", "Sat Jun 9 12:00 2012", false},
    31  
    32  		// Leap year
    33  		{"Mon Jul 9 23:35 2018", "0 0 0 29 Feb ?", "Mon Feb 29 00:00 2016", false},
    34  
    35  		// Daylight savings time 3am EDT (-4) -> 2am EST (-5)
    36  		{"2013-03-11T02:30:00-0400", "TZ=America/New_York 0 0 12 9 Mar ?", "2013-03-09T12:00:00-0500", false},
    37  
    38  		// hourly job
    39  		{"2012-03-11T01:00:00-0500", "TZ=America/New_York 0 0 * * * ?", "2012-03-11T00:00:00-0500", false},
    40  
    41  		// 2am nightly job (skipped)
    42  		{"2012-03-12T00:00:00-0400", "TZ=America/New_York 0 0 2 * * ?", "2012-03-10T02:00:00-0500", false},
    43  
    44  		// 2am nightly job
    45  		{"2012-11-04T02:00:00-0500", "TZ=America/New_York 0 0 0 * * ?", "2012-11-04T00:00:00-0400", false},
    46  		{"2012-11-05T02:00:00-0500", "TZ=America/New_York 0 0 2 * * ?", "2012-11-04T02:00:00-0500", false},
    47  
    48  		// Unsatisfiable
    49  		{"Mon Jul 9 23:35 2012", "0 0 0 30 Feb ?", "", true},
    50  		{"Mon Jul 9 23:35 2012", "0 0 0 31 Apr ?", "", true},
    51  
    52  		// Monthly job
    53  		{"TZ=America/New_York 2012-12-03T00:00:00-0500", "0 0 3 3 * ?", "2012-11-03T03:00:00-0400", false},
    54  	}
    55  
    56  	parser := cronlib.NewParser(cronlib.Second | cronlib.Minute | cronlib.Hour | cronlib.Dom | cronlib.Month | cronlib.DowOptional | cronlib.Descriptor)
    57  
    58  	for _, c := range runs {
    59  		actual, err := PrevCronTime(c.spec, parser, getTime(c.time))
    60  		if c.expectedErr {
    61  			if err == nil {
    62  				t.Errorf("%s, \"%s\": should have received error but didn't", c.time, c.spec)
    63  			}
    64  		} else {
    65  			if err != nil {
    66  				t.Errorf("%s, \"%s\": error: %v", c.time, c.spec, err)
    67  			} else {
    68  				expected := getTime(c.expected)
    69  				if !actual.Equal(expected) {
    70  					t.Errorf("%s, \"%s\": (expected) %v != %v (actual)", c.time, c.spec, expected, actual)
    71  				}
    72  			}
    73  		}
    74  	}
    75  }
    76  
    77  func getTime(value string) time.Time {
    78  	if value == "" {
    79  		return time.Time{}
    80  	}
    81  
    82  	var location = time.Local
    83  	if strings.HasPrefix(value, "TZ=") {
    84  		parts := strings.Fields(value)
    85  		loc, err := time.LoadLocation(parts[0][len("TZ="):])
    86  		if err != nil {
    87  			panic("could not parse location:" + err.Error())
    88  		}
    89  		location = loc
    90  		value = parts[1]
    91  	}
    92  
    93  	var layouts = []string{
    94  		"Mon Jan 2 15:04 2006",
    95  		"Mon Jan 2 15:04:05 2006",
    96  	}
    97  	for _, layout := range layouts {
    98  		if t, err := time.ParseInLocation(layout, value, location); err == nil {
    99  			return t
   100  		}
   101  	}
   102  	if t, err := time.ParseInLocation("2006-01-02T15:04:05-0700", value, location); err == nil {
   103  		return t
   104  	}
   105  	panic("could not parse time value " + value)
   106  }