github.com/swiftstack/ProxyFS@v0.0.0-20210203235616-4017c267d62f/inode/cron_test.go (about)

     1  // Copyright (c) 2015-2021, NVIDIA CORPORATION.
     2  // SPDX-License-Identifier: Apache-2.0
     3  
     4  package inode
     5  
     6  import (
     7  	"testing"
     8  	"time"
     9  
    10  	"github.com/swiftstack/ProxyFS/conf"
    11  )
    12  
    13  func TestLoadSnapShotPolicy(t *testing.T) {
    14  	var (
    15  		err                error
    16  		testConfMap        conf.ConfMap
    17  		testConfMapStrings []string
    18  		volume             *volumeStruct
    19  	)
    20  
    21  	// Case 1 - no SnapShotPolicy
    22  
    23  	testConfMapStrings = []string{}
    24  
    25  	testConfMap, err = conf.MakeConfMapFromStrings(testConfMapStrings)
    26  	if nil != err {
    27  		t.Fatalf("Case 1: conf.MakeConfMapFromStrings() failed: %v", err)
    28  	}
    29  
    30  	volume = &volumeStruct{volumeName: "TestVolume", snapShotPolicy: nil}
    31  
    32  	err = volume.loadSnapShotPolicy(testConfMap)
    33  	if nil != err {
    34  		t.Fatalf("Case 1: loadSnapShotPolicy() failed: %v", err)
    35  	}
    36  
    37  	if nil != volume.snapShotPolicy {
    38  		t.Fatalf("Case 1: loadSnapShotPolicy() returned non-nil snapShotPolicy")
    39  	}
    40  
    41  	// Case 2 - SnapShotPolicy with empty ScheduleList and no TimeZone
    42  
    43  	testConfMapStrings = []string{
    44  		"SnapShotPolicy:CommonSnapShotPolicy.ScheduleList=",
    45  		"Volume:TestVolume.SnapShotPolicy=CommonSnapShotPolicy",
    46  	}
    47  
    48  	testConfMap, err = conf.MakeConfMapFromStrings(testConfMapStrings)
    49  	if nil != err {
    50  		t.Fatalf("Case 2: conf.MakeConfMapFromStrings() failed: %v", err)
    51  	}
    52  
    53  	volume = &volumeStruct{volumeName: "TestVolume", snapShotPolicy: nil}
    54  
    55  	err = volume.loadSnapShotPolicy(testConfMap)
    56  	if nil != err {
    57  		t.Fatalf("Case 2: loadSnapShotPolicy() failed: %v", err)
    58  	}
    59  
    60  	if nil != volume.snapShotPolicy {
    61  		t.Fatalf("Case 2: loadSnapShotPolicy() returned non-nil snapShotPolicy")
    62  	}
    63  
    64  	// Case 3 - SnapShotPolicy with trivial ScheduleList and no TimeZone
    65  
    66  	testConfMapStrings = []string{
    67  		"SnapShotSchedule:MinutelySnapShotSchedule.CronTab=* * * * *", // ==> snapShotPolicy.schedule[0]
    68  		"SnapShotSchedule:MinutelySnapShotSchedule.Keep=59",
    69  		"SnapShotPolicy:CommonSnapShotPolicy.ScheduleList=MinutelySnapShotSchedule",
    70  		"Volume:TestVolume.SnapShotPolicy=CommonSnapShotPolicy",
    71  	}
    72  
    73  	testConfMap, err = conf.MakeConfMapFromStrings(testConfMapStrings)
    74  	if nil != err {
    75  		t.Fatalf("Case 3: conf.MakeConfMapFromStrings() failed: %v", err)
    76  	}
    77  
    78  	volume = &volumeStruct{volumeName: "TestVolume", snapShotPolicy: nil}
    79  
    80  	err = volume.loadSnapShotPolicy(testConfMap)
    81  	if nil != err {
    82  		t.Fatalf("Case 3: loadSnapShotPolicy() failed: %v", err)
    83  	}
    84  
    85  	if "CommonSnapShotPolicy" != volume.snapShotPolicy.name {
    86  		t.Fatalf("Case 3: loadSnapShotPolicy() returned snapShotPolicy with unexpected .name")
    87  	}
    88  	if 1 != len(volume.snapShotPolicy.schedule) {
    89  		t.Fatalf("Case 3: loadSnapShotPolicy() returned snapShotPolicy with unexpected .schedule")
    90  	}
    91  	if "MinutelySnapShotSchedule" != volume.snapShotPolicy.schedule[0].name {
    92  		t.Fatalf("Case 3: loadSnapShotPolicy() returned snapShotPolicy.schedule[0] with unexpected .name")
    93  	}
    94  	if volume.snapShotPolicy.schedule[0].minuteSpecified {
    95  		t.Fatalf("Case 3: loadSnapShotPolicy() returned snapShotPolicy.schedule[0] with unexpected .minuteSpecified")
    96  	}
    97  	if volume.snapShotPolicy.schedule[0].hourSpecified {
    98  		t.Fatalf("Case 3: loadSnapShotPolicy() returned snapShotPolicy.schedule[0] with unexpected .hourSpecified")
    99  	}
   100  	if volume.snapShotPolicy.schedule[0].dayOfMonthSpecified {
   101  		t.Fatalf("Case 3: loadSnapShotPolicy() returned snapShotPolicy.schedule[0] with unexpected .dayOfMonthSpecified")
   102  	}
   103  	if volume.snapShotPolicy.schedule[0].monthSpecified {
   104  		t.Fatalf("Case 3: loadSnapShotPolicy() returned snapShotPolicy.schedule[0] with unexpected .monthSpecified")
   105  	}
   106  	if volume.snapShotPolicy.schedule[0].dayOfWeekSpecified {
   107  		t.Fatalf("Case 3: loadSnapShotPolicy() returned snapShotPolicy.schedule[0] with unexpected .dayOfWeekSpecified")
   108  	}
   109  	if 59 != volume.snapShotPolicy.schedule[0].keep {
   110  		t.Fatalf("Case 3: loadSnapShotPolicy() returned snapShotPolicy.schedule[0] with unexpected .keep")
   111  	}
   112  	if "UTC" != volume.snapShotPolicy.location.String() {
   113  		t.Fatalf("Case 3: loadSnapShotPolicy() returned snapShotPolicy with unexpected .location")
   114  	}
   115  
   116  	// Case 4 - SnapShotPolicy with trivial ScheduleList and empty TimeZone
   117  
   118  	testConfMapStrings = []string{
   119  		"SnapShotSchedule:MinutelySnapShotSchedule.CronTab=* * * * *", // ==> snapShotPolicy.schedule[0]
   120  		"SnapShotSchedule:MinutelySnapShotSchedule.Keep=59",
   121  		"SnapShotPolicy:CommonSnapShotPolicy.ScheduleList=MinutelySnapShotSchedule",
   122  		"SnapShotPolicy:CommonSnapShotPolicy.TimeZone=",
   123  		"Volume:TestVolume.SnapShotPolicy=CommonSnapShotPolicy",
   124  	}
   125  
   126  	testConfMap, err = conf.MakeConfMapFromStrings(testConfMapStrings)
   127  	if nil != err {
   128  		t.Fatalf("Case 4: conf.MakeConfMapFromStrings() failed: %v", err)
   129  	}
   130  
   131  	volume = &volumeStruct{volumeName: "TestVolume", snapShotPolicy: nil}
   132  
   133  	err = volume.loadSnapShotPolicy(testConfMap)
   134  	if nil != err {
   135  		t.Fatalf("Case 4: loadSnapShotPolicy() failed: %v", err)
   136  	}
   137  
   138  	if "CommonSnapShotPolicy" != volume.snapShotPolicy.name {
   139  		t.Fatalf("Case 4: loadSnapShotPolicy() returned snapShotPolicy with unexpected .name")
   140  	}
   141  	if 1 != len(volume.snapShotPolicy.schedule) {
   142  		t.Fatalf("Case 4: loadSnapShotPolicy() returned snapShotPolicy with unexpected .schedule")
   143  	}
   144  	if "MinutelySnapShotSchedule" != volume.snapShotPolicy.schedule[0].name {
   145  		t.Fatalf("Case 4: loadSnapShotPolicy() returned snapShotPolicy.schedule[0] with unexpected .name")
   146  	}
   147  	if volume.snapShotPolicy.schedule[0].minuteSpecified {
   148  		t.Fatalf("Case 4: loadSnapShotPolicy() returned snapShotPolicy.schedule[0] with unexpected .minuteSpecified")
   149  	}
   150  	if volume.snapShotPolicy.schedule[0].hourSpecified {
   151  		t.Fatalf("Case 4: loadSnapShotPolicy() returned snapShotPolicy.schedule[0] with unexpected .hourSpecified")
   152  	}
   153  	if volume.snapShotPolicy.schedule[0].dayOfMonthSpecified {
   154  		t.Fatalf("Case 4: loadSnapShotPolicy() returned snapShotPolicy.schedule[0] with unexpected .dayOfMonthSpecified")
   155  	}
   156  	if volume.snapShotPolicy.schedule[0].monthSpecified {
   157  		t.Fatalf("Case 4: loadSnapShotPolicy() returned snapShotPolicy.schedule[0] with unexpected .monthSpecified")
   158  	}
   159  	if volume.snapShotPolicy.schedule[0].dayOfWeekSpecified {
   160  		t.Fatalf("Case 4: loadSnapShotPolicy() returned snapShotPolicy.schedule[0] with unexpected .dayOfWeekSpecified")
   161  	}
   162  	if 59 != volume.snapShotPolicy.schedule[0].keep {
   163  		t.Fatalf("Case 4: loadSnapShotPolicy() returned snapShotPolicy.schedule[0] with unexpected .keep")
   164  	}
   165  	if "UTC" != volume.snapShotPolicy.location.String() {
   166  		t.Fatalf("Case 4: loadSnapShotPolicy() returned snapShotPolicy with unexpected .location")
   167  	}
   168  
   169  	// Case 5 - SnapShotPolicy with trivial ScheduleList and TimeZone of "UTC"
   170  
   171  	testConfMapStrings = []string{
   172  		"SnapShotSchedule:MinutelySnapShotSchedule.CronTab=* * * * *", // ==> snapShotPolicy.schedule[0]
   173  		"SnapShotSchedule:MinutelySnapShotSchedule.Keep=59",
   174  		"SnapShotPolicy:CommonSnapShotPolicy.ScheduleList=MinutelySnapShotSchedule",
   175  		"SnapShotPolicy:CommonSnapShotPolicy.TimeZone=UTC",
   176  		"Volume:TestVolume.SnapShotPolicy=CommonSnapShotPolicy",
   177  	}
   178  
   179  	testConfMap, err = conf.MakeConfMapFromStrings(testConfMapStrings)
   180  	if nil != err {
   181  		t.Fatalf("Case 5: conf.MakeConfMapFromStrings() failed: %v", err)
   182  	}
   183  
   184  	volume = &volumeStruct{volumeName: "TestVolume", snapShotPolicy: nil}
   185  
   186  	err = volume.loadSnapShotPolicy(testConfMap)
   187  	if nil != err {
   188  		t.Fatalf("Case 5: loadSnapShotPolicy() failed: %v", err)
   189  	}
   190  
   191  	if "CommonSnapShotPolicy" != volume.snapShotPolicy.name {
   192  		t.Fatalf("Case 5: loadSnapShotPolicy() returned snapShotPolicy with unexpected .name")
   193  	}
   194  	if 1 != len(volume.snapShotPolicy.schedule) {
   195  		t.Fatalf("Case 5: loadSnapShotPolicy() returned snapShotPolicy with unexpected .schedule")
   196  	}
   197  	if "MinutelySnapShotSchedule" != volume.snapShotPolicy.schedule[0].name {
   198  		t.Fatalf("Case 5: loadSnapShotPolicy() returned snapShotPolicy.schedule[0] with unexpected .name")
   199  	}
   200  	if volume.snapShotPolicy.schedule[0].minuteSpecified {
   201  		t.Fatalf("Case 5: loadSnapShotPolicy() returned snapShotPolicy.schedule[0] with unexpected .minuteSpecified")
   202  	}
   203  	if volume.snapShotPolicy.schedule[0].hourSpecified {
   204  		t.Fatalf("Case 5: loadSnapShotPolicy() returned snapShotPolicy.schedule[0] with unexpected .hourSpecified")
   205  	}
   206  	if volume.snapShotPolicy.schedule[0].dayOfMonthSpecified {
   207  		t.Fatalf("Case 5: loadSnapShotPolicy() returned snapShotPolicy.schedule[0] with unexpected .dayOfMonthSpecified")
   208  	}
   209  	if volume.snapShotPolicy.schedule[0].monthSpecified {
   210  		t.Fatalf("Case 5: loadSnapShotPolicy() returned snapShotPolicy.schedule[0] with unexpected .monthSpecified")
   211  	}
   212  	if volume.snapShotPolicy.schedule[0].dayOfWeekSpecified {
   213  		t.Fatalf("Case 5: loadSnapShotPolicy() returned snapShotPolicy.schedule[0] with unexpected .dayOfWeekSpecified")
   214  	}
   215  	if 59 != volume.snapShotPolicy.schedule[0].keep {
   216  		t.Fatalf("Case 5: loadSnapShotPolicy() returned snapShotPolicy.schedule[0] with unexpected .keep")
   217  	}
   218  	if "UTC" != volume.snapShotPolicy.location.String() {
   219  		t.Fatalf("Case 5: loadSnapShotPolicy() returned snapShotPolicy with unexpected .location")
   220  	}
   221  
   222  	// Case 6 - SnapShotPolicy with trivial ScheduleList and TimeZone of "Local"
   223  
   224  	testConfMapStrings = []string{
   225  		"SnapShotSchedule:MinutelySnapShotSchedule.CronTab=* * * * *", // ==> snapShotPolicy.schedule[0]
   226  		"SnapShotSchedule:MinutelySnapShotSchedule.Keep=59",
   227  		"SnapShotPolicy:CommonSnapShotPolicy.ScheduleList=MinutelySnapShotSchedule",
   228  		"SnapShotPolicy:CommonSnapShotPolicy.TimeZone=Local",
   229  		"Volume:TestVolume.SnapShotPolicy=CommonSnapShotPolicy",
   230  	}
   231  
   232  	testConfMap, err = conf.MakeConfMapFromStrings(testConfMapStrings)
   233  	if nil != err {
   234  		t.Fatalf("Case 6: conf.MakeConfMapFromStrings() failed: %v", err)
   235  	}
   236  
   237  	volume = &volumeStruct{volumeName: "TestVolume", snapShotPolicy: nil}
   238  
   239  	err = volume.loadSnapShotPolicy(testConfMap)
   240  	if nil != err {
   241  		t.Fatalf("Case 6: loadSnapShotPolicy() failed: %v", err)
   242  	}
   243  
   244  	if "CommonSnapShotPolicy" != volume.snapShotPolicy.name {
   245  		t.Fatalf("Case 6: loadSnapShotPolicy() returned snapShotPolicy with unexpected .name")
   246  	}
   247  	if 1 != len(volume.snapShotPolicy.schedule) {
   248  		t.Fatalf("Case 6: loadSnapShotPolicy() returned snapShotPolicy with unexpected .schedule")
   249  	}
   250  	if "MinutelySnapShotSchedule" != volume.snapShotPolicy.schedule[0].name {
   251  		t.Fatalf("Case 6: loadSnapShotPolicy() returned snapShotPolicy.schedule[0] with unexpected .name")
   252  	}
   253  	if volume.snapShotPolicy.schedule[0].minuteSpecified {
   254  		t.Fatalf("Case 6: loadSnapShotPolicy() returned snapShotPolicy.schedule[0] with unexpected .minuteSpecified")
   255  	}
   256  	if volume.snapShotPolicy.schedule[0].hourSpecified {
   257  		t.Fatalf("Case 6: loadSnapShotPolicy() returned snapShotPolicy.schedule[0] with unexpected .hourSpecified")
   258  	}
   259  	if volume.snapShotPolicy.schedule[0].dayOfMonthSpecified {
   260  		t.Fatalf("Case 6: loadSnapShotPolicy() returned snapShotPolicy.schedule[0] with unexpected .dayOfMonthSpecified")
   261  	}
   262  	if volume.snapShotPolicy.schedule[0].monthSpecified {
   263  		t.Fatalf("Case 6: loadSnapShotPolicy() returned snapShotPolicy.schedule[0] with unexpected .monthSpecified")
   264  	}
   265  	if volume.snapShotPolicy.schedule[0].dayOfWeekSpecified {
   266  		t.Fatalf("Case 6: loadSnapShotPolicy() returned snapShotPolicy.schedule[0] with unexpected .dayOfWeekSpecified")
   267  	}
   268  	if 59 != volume.snapShotPolicy.schedule[0].keep {
   269  		t.Fatalf("Case 6: loadSnapShotPolicy() returned snapShotPolicy.schedule[0] with unexpected .keep")
   270  	}
   271  	if "Local" != volume.snapShotPolicy.location.String() {
   272  		t.Fatalf("Case 6: loadSnapShotPolicy() returned snapShotPolicy with unexpected .location")
   273  	}
   274  
   275  	// Case 7 - SnapShotPolicy with exhaustive ScheduleList and a specific TimeZone
   276  
   277  	testConfMapStrings = []string{
   278  		"SnapShotSchedule:MinutelySnapShotSchedule.CronTab=* * * * *", // ==> snapShotPolicy.schedule[0]
   279  		"SnapShotSchedule:MinutelySnapShotSchedule.Keep=59",
   280  		"SnapShotSchedule:HourlySnapShotSchedule.CronTab=0 * * * *", //   ==> snapShotPolicy.schedule[1]
   281  		"SnapShotSchedule:HourlySnapShotSchedule.Keep=23",
   282  		"SnapShotSchedule:DailySnapShotSchedule.CronTab=0 0 * * *", //    ==> snapShotPolicy.schedule[2]
   283  		"SnapShotSchedule:DailySnapShotSchedule.Keep=6",
   284  		"SnapShotSchedule:WeeklySnapShotSchedule.CronTab=0 0 * * 0", //   ==> snapShotPolicy.schedule[3]
   285  		"SnapShotSchedule:WeeklySnapShotSchedule.Keep=8",
   286  		"SnapShotSchedule:MonthlySnapShotSchedule.CronTab=0 0 1 * *", //  ==> snapShotPolicy.schedule[4]
   287  		"SnapShotSchedule:MonthlySnapShotSchedule.Keep=11",
   288  		"SnapShotSchedule:YearlySnapShotSchedule.CronTab=0 0 1 1 *", //   ==> snapShotPolicy.schedule[5]
   289  		"SnapShotSchedule:YearlySnapShotSchedule.Keep=4",
   290  		"SnapShotPolicy:CommonSnapShotPolicy.ScheduleList=MinutelySnapShotSchedule,HourlySnapShotSchedule,DailySnapShotSchedule,WeeklySnapShotSchedule,MonthlySnapShotSchedule,YearlySnapShotSchedule",
   291  		"SnapShotPolicy:CommonSnapShotPolicy.TimeZone=America/Los_Angeles",
   292  		"Volume:TestVolume.SnapShotPolicy=CommonSnapShotPolicy",
   293  	}
   294  
   295  	testConfMap, err = conf.MakeConfMapFromStrings(testConfMapStrings)
   296  	if nil != err {
   297  		t.Fatalf("Case 7: conf.MakeConfMapFromStrings() failed: %v", err)
   298  	}
   299  
   300  	volume = &volumeStruct{volumeName: "TestVolume", snapShotPolicy: nil}
   301  
   302  	err = volume.loadSnapShotPolicy(testConfMap)
   303  	if nil != err {
   304  		t.Fatalf("Case 7: loadSnapShotPolicy() failed: %v", err)
   305  	}
   306  
   307  	if "CommonSnapShotPolicy" != volume.snapShotPolicy.name {
   308  		t.Fatalf("Case 7: loadSnapShotPolicy() returned snapShotPolicy with unexpected .name")
   309  	}
   310  
   311  	if 6 != len(volume.snapShotPolicy.schedule) {
   312  		t.Fatalf("Case 7: loadSnapShotPolicy() returned snapShotPolicy with unexpected .schedule")
   313  	}
   314  
   315  	if "MinutelySnapShotSchedule" != volume.snapShotPolicy.schedule[0].name {
   316  		t.Fatalf("Case 7: loadSnapShotPolicy() returned snapShotPolicy.schedule[0] with unexpected .name")
   317  	}
   318  	if volume.snapShotPolicy.schedule[0].minuteSpecified {
   319  		t.Fatalf("Case 7: loadSnapShotPolicy() returned snapShotPolicy.schedule[0] with unexpected .minuteSpecified")
   320  	}
   321  	if volume.snapShotPolicy.schedule[0].hourSpecified {
   322  		t.Fatalf("Case 7: loadSnapShotPolicy() returned snapShotPolicy.schedule[0] with unexpected .hourSpecified")
   323  	}
   324  	if volume.snapShotPolicy.schedule[0].dayOfMonthSpecified {
   325  		t.Fatalf("Case 7: loadSnapShotPolicy() returned snapShotPolicy.schedule[0] with unexpected .dayOfMonthSpecified")
   326  	}
   327  	if volume.snapShotPolicy.schedule[0].monthSpecified {
   328  		t.Fatalf("Case 7: loadSnapShotPolicy() returned snapShotPolicy.schedule[0] with unexpected .monthSpecified")
   329  	}
   330  	if volume.snapShotPolicy.schedule[0].dayOfWeekSpecified {
   331  		t.Fatalf("Case 7: loadSnapShotPolicy() returned snapShotPolicy.schedule[0] with unexpected .dayOfWeekSpecified")
   332  	}
   333  	if 59 != volume.snapShotPolicy.schedule[0].keep {
   334  		t.Fatalf("Case 7: loadSnapShotPolicy() returned snapShotPolicy.schedule[0] with unexpected .keep")
   335  	}
   336  
   337  	if "HourlySnapShotSchedule" != volume.snapShotPolicy.schedule[1].name {
   338  		t.Fatalf("Case 7: loadSnapShotPolicy() returned snapShotPolicy.schedule[1] with unexpected .name")
   339  	}
   340  	if !volume.snapShotPolicy.schedule[1].minuteSpecified {
   341  		t.Fatalf("Case 7: loadSnapShotPolicy() returned snapShotPolicy.schedule[1] with unexpected .minuteSpecified")
   342  	}
   343  	if 0 != volume.snapShotPolicy.schedule[1].minute {
   344  		t.Fatalf("Case 7: loadSnapShotPolicy() returned snapShotPolicy.schedule[1] with unexpected .minute")
   345  	}
   346  	if volume.snapShotPolicy.schedule[1].hourSpecified {
   347  		t.Fatalf("Case 7: loadSnapShotPolicy() returned snapShotPolicy.schedule[1] with unexpected .hourSpecified")
   348  	}
   349  	if volume.snapShotPolicy.schedule[1].dayOfMonthSpecified {
   350  		t.Fatalf("Case 7: loadSnapShotPolicy() returned snapShotPolicy.schedule[1] with unexpected .dayOfMonthSpecified")
   351  	}
   352  	if volume.snapShotPolicy.schedule[1].monthSpecified {
   353  		t.Fatalf("Case 7: loadSnapShotPolicy() returned snapShotPolicy.schedule[1] with unexpected .monthSpecified")
   354  	}
   355  	if volume.snapShotPolicy.schedule[1].dayOfWeekSpecified {
   356  		t.Fatalf("Case 7: loadSnapShotPolicy() returned snapShotPolicy.schedule[1] with unexpected .dayOfWeekSpecified")
   357  	}
   358  	if 23 != volume.snapShotPolicy.schedule[1].keep {
   359  		t.Fatalf("Case 7: loadSnapShotPolicy() returned snapShotPolicy.schedule[1] with unexpected .keep")
   360  	}
   361  
   362  	if "DailySnapShotSchedule" != volume.snapShotPolicy.schedule[2].name {
   363  		t.Fatalf("Case 7: loadSnapShotPolicy() returned snapShotPolicy.schedule[2] with unexpected .name")
   364  	}
   365  	if !volume.snapShotPolicy.schedule[2].minuteSpecified {
   366  		t.Fatalf("Case 7: loadSnapShotPolicy() returned snapShotPolicy.schedule[2] with unexpected .minuteSpecified")
   367  	}
   368  	if 0 != volume.snapShotPolicy.schedule[2].minute {
   369  		t.Fatalf("Case 7: loadSnapShotPolicy() returned snapShotPolicy.schedule[2] with unexpected .minute")
   370  	}
   371  	if !volume.snapShotPolicy.schedule[2].hourSpecified {
   372  		t.Fatalf("Case 7: loadSnapShotPolicy() returned snapShotPolicy.schedule[2] with unexpected .hourSpecified")
   373  	}
   374  	if 0 != volume.snapShotPolicy.schedule[2].hour {
   375  		t.Fatalf("Case 7: loadSnapShotPolicy() returned snapShotPolicy.schedule[2] with unexpected .hour")
   376  	}
   377  	if volume.snapShotPolicy.schedule[2].dayOfMonthSpecified {
   378  		t.Fatalf("Case 7: loadSnapShotPolicy() returned snapShotPolicy.schedule[2] with unexpected .dayOfMonthSpecified")
   379  	}
   380  	if volume.snapShotPolicy.schedule[2].monthSpecified {
   381  		t.Fatalf("Case 7: loadSnapShotPolicy() returned snapShotPolicy.schedule[2] with unexpected .monthSpecified")
   382  	}
   383  	if volume.snapShotPolicy.schedule[2].dayOfWeekSpecified {
   384  		t.Fatalf("Case 7: loadSnapShotPolicy() returned snapShotPolicy.schedule[2] with unexpected .dayOfWeekSpecified")
   385  	}
   386  	if 6 != volume.snapShotPolicy.schedule[2].keep {
   387  		t.Fatalf("Case 7: loadSnapShotPolicy() returned snapShotPolicy.schedule[2] with unexpected .keep")
   388  	}
   389  
   390  	if "WeeklySnapShotSchedule" != volume.snapShotPolicy.schedule[3].name {
   391  		t.Fatalf("Case 7: loadSnapShotPolicy() returned snapShotPolicy.schedule[3] with unexpected .name")
   392  	}
   393  	if !volume.snapShotPolicy.schedule[3].minuteSpecified {
   394  		t.Fatalf("Case 7: loadSnapShotPolicy() returned snapShotPolicy.schedule[3] with unexpected .minuteSpecified")
   395  	}
   396  	if 0 != volume.snapShotPolicy.schedule[3].minute {
   397  		t.Fatalf("Case 7: loadSnapShotPolicy() returned snapShotPolicy.schedule[3] with unexpected .minute")
   398  	}
   399  	if !volume.snapShotPolicy.schedule[3].hourSpecified {
   400  		t.Fatalf("Case 7: loadSnapShotPolicy() returned snapShotPolicy.schedule[3] with unexpected .hourSpecified")
   401  	}
   402  	if 0 != volume.snapShotPolicy.schedule[3].hour {
   403  		t.Fatalf("Case 7: loadSnapShotPolicy() returned snapShotPolicy.schedule[3] with unexpected .hour")
   404  	}
   405  	if volume.snapShotPolicy.schedule[3].dayOfMonthSpecified {
   406  		t.Fatalf("Case 7: loadSnapShotPolicy() returned snapShotPolicy.schedule[3] with unexpected .dayOfMonthSpecified")
   407  	}
   408  	if volume.snapShotPolicy.schedule[3].monthSpecified {
   409  		t.Fatalf("Case 7: loadSnapShotPolicy() returned snapShotPolicy.schedule[3] with unexpected .monthSpecified")
   410  	}
   411  	if !volume.snapShotPolicy.schedule[3].dayOfWeekSpecified {
   412  		t.Fatalf("Case 7: loadSnapShotPolicy() returned snapShotPolicy.schedule[3] with unexpected .dayOfWeekSpecified")
   413  	}
   414  	if 0 != volume.snapShotPolicy.schedule[3].dayOfWeek {
   415  		t.Fatalf("Case 7: loadSnapShotPolicy() returned snapShotPolicy.schedule[3] with unexpected .dayOfWeek")
   416  	}
   417  	if 8 != volume.snapShotPolicy.schedule[3].keep {
   418  		t.Fatalf("Case 7: loadSnapShotPolicy() returned snapShotPolicy.schedule[3] with unexpected .keep")
   419  	}
   420  
   421  	if "MonthlySnapShotSchedule" != volume.snapShotPolicy.schedule[4].name {
   422  		t.Fatalf("Case 7: loadSnapShotPolicy() returned snapShotPolicy.schedule[4] with unexpected .name")
   423  	}
   424  	if !volume.snapShotPolicy.schedule[4].minuteSpecified {
   425  		t.Fatalf("Case 7: loadSnapShotPolicy() returned snapShotPolicy.schedule[4] with unexpected .minuteSpecified")
   426  	}
   427  	if 0 != volume.snapShotPolicy.schedule[4].minute {
   428  		t.Fatalf("Case 7: loadSnapShotPolicy() returned snapShotPolicy.schedule[4] with unexpected .minute")
   429  	}
   430  	if !volume.snapShotPolicy.schedule[4].hourSpecified {
   431  		t.Fatalf("Case 7: loadSnapShotPolicy() returned snapShotPolicy.schedule[4] with unexpected .hourSpecified")
   432  	}
   433  	if 0 != volume.snapShotPolicy.schedule[4].hour {
   434  		t.Fatalf("Case 7: loadSnapShotPolicy() returned snapShotPolicy.schedule[4] with unexpected .hour")
   435  	}
   436  	if !volume.snapShotPolicy.schedule[4].dayOfMonthSpecified {
   437  		t.Fatalf("Case 7: loadSnapShotPolicy() returned snapShotPolicy.schedule[4] with unexpected .dayOfMonthSpecified")
   438  	}
   439  	if 1 != volume.snapShotPolicy.schedule[4].dayOfMonth {
   440  		t.Fatalf("Case 7: loadSnapShotPolicy() returned snapShotPolicy.schedule[4] with unexpected .dayOfMonth")
   441  	}
   442  	if volume.snapShotPolicy.schedule[4].monthSpecified {
   443  		t.Fatalf("Case 7: loadSnapShotPolicy() returned snapShotPolicy.schedule[4] with unexpected .monthSpecified")
   444  	}
   445  	if volume.snapShotPolicy.schedule[4].dayOfWeekSpecified {
   446  		t.Fatalf("Case 7: loadSnapShotPolicy() returned snapShotPolicy.schedule[4] with unexpected .dayOfWeekSpecified")
   447  	}
   448  	if 11 != volume.snapShotPolicy.schedule[4].keep {
   449  		t.Fatalf("Case 7: loadSnapShotPolicy() returned snapShotPolicy.schedule[4] with unexpected .keep")
   450  	}
   451  
   452  	if "YearlySnapShotSchedule" != volume.snapShotPolicy.schedule[5].name {
   453  		t.Fatalf("Case 7: loadSnapShotPolicy() returned snapShotPolicy.schedule[5] with unexpected .name")
   454  	}
   455  	if !volume.snapShotPolicy.schedule[5].minuteSpecified {
   456  		t.Fatalf("Case 7: loadSnapShotPolicy() returned snapShotPolicy.schedule[5] with unexpected .minuteSpecified")
   457  	}
   458  	if 0 != volume.snapShotPolicy.schedule[5].minute {
   459  		t.Fatalf("Case 7: loadSnapShotPolicy() returned snapShotPolicy.schedule[5] with unexpected .minute")
   460  	}
   461  	if !volume.snapShotPolicy.schedule[5].hourSpecified {
   462  		t.Fatalf("Case 7: loadSnapShotPolicy() returned snapShotPolicy.schedule[5] with unexpected .hourSpecified")
   463  	}
   464  	if 0 != volume.snapShotPolicy.schedule[5].hour {
   465  		t.Fatalf("Case 7: loadSnapShotPolicy() returned snapShotPolicy.schedule[5] with unexpected .hour")
   466  	}
   467  	if !volume.snapShotPolicy.schedule[5].dayOfMonthSpecified {
   468  		t.Fatalf("Case 7: loadSnapShotPolicy() returned snapShotPolicy.schedule[5] with unexpected .dayOfMonthSpecified")
   469  	}
   470  	if 1 != volume.snapShotPolicy.schedule[5].dayOfMonth {
   471  		t.Fatalf("Case 7: loadSnapShotPolicy() returned snapShotPolicy.schedule[5] with unexpected .dayOfMonth")
   472  	}
   473  	if !volume.snapShotPolicy.schedule[5].monthSpecified {
   474  		t.Fatalf("Case 7: loadSnapShotPolicy() returned snapShotPolicy.schedule[5] with unexpected .monthSpecified")
   475  	}
   476  	if 1 != volume.snapShotPolicy.schedule[5].month {
   477  		t.Fatalf("Case 7: loadSnapShotPolicy() returned snapShotPolicy.schedule[5] with unexpected .month")
   478  	}
   479  	if volume.snapShotPolicy.schedule[5].dayOfWeekSpecified {
   480  		t.Fatalf("Case 7: loadSnapShotPolicy() returned snapShotPolicy.schedule[5] with unexpected .dayOfWeekSpecified")
   481  	}
   482  	if 4 != volume.snapShotPolicy.schedule[5].keep {
   483  		t.Fatalf("Case 7: loadSnapShotPolicy() returned snapShotPolicy.schedule[5] with unexpected .keep")
   484  	}
   485  
   486  	if "America/Los_Angeles" != volume.snapShotPolicy.location.String() {
   487  		t.Fatalf("Case 7: loadSnapShotPolicy() returned snapShotPolicy with unexpected .location")
   488  	}
   489  }
   490  
   491  func TestSnapShotScheduleCompare(t *testing.T) {
   492  	var (
   493  		err                error
   494  		matches            bool
   495  		matchingTime       time.Time
   496  		mismatchingTime    time.Time
   497  		testConfMap        conf.ConfMap
   498  		testConfMapStrings []string
   499  		volume             *volumeStruct
   500  	)
   501  
   502  	testConfMapStrings = []string{
   503  		"SnapShotSchedule:MinutelySnapShotSchedule.CronTab=* * * * *", // ==> snapShotPolicy.schedule[0]
   504  		"SnapShotSchedule:MinutelySnapShotSchedule.Keep=59",
   505  		"SnapShotSchedule:HourlySnapShotSchedule.CronTab=0 * * * *", //   ==> snapShotPolicy.schedule[1]
   506  		"SnapShotSchedule:HourlySnapShotSchedule.Keep=23",
   507  		"SnapShotSchedule:DailySnapShotSchedule.CronTab=0 0 * * *", //    ==> snapShotPolicy.schedule[2]
   508  		"SnapShotSchedule:DailySnapShotSchedule.Keep=6",
   509  		"SnapShotSchedule:WeeklySnapShotSchedule.CronTab=0 0 * * 0", //   ==> snapShotPolicy.schedule[3]
   510  		"SnapShotSchedule:WeeklySnapShotSchedule.Keep=8",
   511  		"SnapShotSchedule:MonthlySnapShotSchedule.CronTab=0 0 1 * *", //  ==> snapShotPolicy.schedule[4]
   512  		"SnapShotSchedule:MonthlySnapShotSchedule.Keep=11",
   513  		"SnapShotSchedule:YearlySnapShotSchedule.CronTab=0 0 1 1 *", //   ==> snapShotPolicy.schedule[5]
   514  		"SnapShotSchedule:YearlySnapShotSchedule.Keep=4",
   515  		"SnapShotPolicy:CommonSnapShotPolicy.ScheduleList=MinutelySnapShotSchedule,HourlySnapShotSchedule,DailySnapShotSchedule,WeeklySnapShotSchedule,MonthlySnapShotSchedule,YearlySnapShotSchedule",
   516  		"SnapShotPolicy:CommonSnapShotPolicy.TimeZone=America/Los_Angeles",
   517  		"Volume:TestVolume.SnapShotPolicy=CommonSnapShotPolicy",
   518  	}
   519  
   520  	testConfMap, err = conf.MakeConfMapFromStrings(testConfMapStrings)
   521  	if nil != err {
   522  		t.Fatalf("conf.MakeConfMapFromStrings() failed: %v", err)
   523  	}
   524  
   525  	volume = &volumeStruct{volumeName: "TestVolume", snapShotPolicy: nil}
   526  
   527  	err = volume.loadSnapShotPolicy(testConfMap)
   528  	if nil != err {
   529  		t.Fatalf("loadSnapShotPolicy() failed: %v", err)
   530  	}
   531  
   532  	matchingTime = time.Date(2017, time.January, 1, 0, 0, 0, 0, volume.snapShotPolicy.location) // A Sunday
   533  
   534  	mismatchingTime = time.Date(2017, time.January, 1, 0, 0, 1, 0, volume.snapShotPolicy.location) // +1 second
   535  	matches = volume.snapShotPolicy.schedule[0].compare(matchingTime)
   536  	if !matches {
   537  		t.Fatalf("snapShotPolicy.schedule[0].compare(matchingTime) should have returned true")
   538  	}
   539  	matches = volume.snapShotPolicy.schedule[0].compare(mismatchingTime)
   540  	if matches {
   541  		t.Fatalf("snapShotPolicy.schedule[0].compare(mismatchingTime) should have returned false")
   542  	}
   543  
   544  	mismatchingTime = time.Date(2017, time.January, 1, 0, 1, 0, 0, volume.snapShotPolicy.location) // +1 minute
   545  	matches = volume.snapShotPolicy.schedule[1].compare(matchingTime)
   546  	if !matches {
   547  		t.Fatalf("snapShotPolicy.schedule[1].compare(matchingTime) should have returned true")
   548  	}
   549  	matches = volume.snapShotPolicy.schedule[1].compare(mismatchingTime)
   550  	if matches {
   551  		t.Fatalf("snapShotPolicy.schedule[1].compare(mismatchingTime) should have returned false")
   552  	}
   553  
   554  	mismatchingTime = time.Date(2017, time.January, 1, 1, 0, 0, 0, volume.snapShotPolicy.location) // +1 hour
   555  	matches = volume.snapShotPolicy.schedule[2].compare(matchingTime)
   556  	if !matches {
   557  		t.Fatalf("snapShotPolicy.schedule[2].compare(matchingTime) should have returned true")
   558  	}
   559  	matches = volume.snapShotPolicy.schedule[2].compare(mismatchingTime)
   560  	if matches {
   561  		t.Fatalf("snapShotPolicy.schedule[2].compare(mismatchingTime) should have returned false")
   562  	}
   563  
   564  	mismatchingTime = time.Date(2017, time.January, 2, 0, 0, 0, 0, volume.snapShotPolicy.location) // +1 day
   565  	matches = volume.snapShotPolicy.schedule[3].compare(matchingTime)
   566  	if !matches {
   567  		t.Fatalf("snapShotPolicy.schedule[3].compare(matchingTime) should have returned true")
   568  	}
   569  	matches = volume.snapShotPolicy.schedule[3].compare(mismatchingTime)
   570  	if matches {
   571  		t.Fatalf("snapShotPolicy.schedule[3].compare(mismatchingTime) should have returned false")
   572  	}
   573  
   574  	mismatchingTime = time.Date(2017, time.January, 2, 0, 0, 0, 0, volume.snapShotPolicy.location) // A Monday
   575  	matches = volume.snapShotPolicy.schedule[4].compare(matchingTime)
   576  	if !matches {
   577  		t.Fatalf("snapShotPolicy.schedule[4].compare(matchingTime) should have returned true")
   578  	}
   579  	matches = volume.snapShotPolicy.schedule[4].compare(mismatchingTime)
   580  	if matches {
   581  		t.Fatalf("snapShotPolicy.schedule[4].compare(mismatchingTime) should have returned false")
   582  	}
   583  
   584  	mismatchingTime = time.Date(2017, time.February, 1, 0, 0, 0, 0, volume.snapShotPolicy.location) // +1 month
   585  	matches = volume.snapShotPolicy.schedule[5].compare(matchingTime)
   586  	if !matches {
   587  		t.Fatalf("snapShotPolicy.schedule[5].compare(matchingTime) should have returned true")
   588  	}
   589  	matches = volume.snapShotPolicy.schedule[5].compare(mismatchingTime)
   590  	if matches {
   591  		t.Fatalf("snapShotPolicy.schedule[5].compare(mismatchingTime) should have returned false")
   592  	}
   593  }
   594  
   595  func TestSnapShotScheduleNext(t *testing.T) {
   596  	var (
   597  		err                error
   598  		nextTime           time.Time
   599  		testConfMap        conf.ConfMap
   600  		testConfMapStrings []string
   601  		timeNow            time.Time
   602  		volume             *volumeStruct
   603  	)
   604  
   605  	testConfMapStrings = []string{
   606  		"SnapShotSchedule:MinutelySnapShotSchedule.CronTab=* * * * *", // ==> snapShotPolicy.schedule[0]
   607  		"SnapShotSchedule:MinutelySnapShotSchedule.Keep=59",
   608  		"SnapShotSchedule:HourlySnapShotSchedule.CronTab=0 * * * *", //   ==> snapShotPolicy.schedule[1]
   609  		"SnapShotSchedule:HourlySnapShotSchedule.Keep=23",
   610  		"SnapShotSchedule:DailySnapShotSchedule.CronTab=0 0 * * *", //    ==> snapShotPolicy.schedule[2]
   611  		"SnapShotSchedule:DailySnapShotSchedule.Keep=6",
   612  		"SnapShotSchedule:WeeklySnapShotSchedule.CronTab=0 0 * * 0", //   ==> snapShotPolicy.schedule[3]
   613  		"SnapShotSchedule:WeeklySnapShotSchedule.Keep=8",
   614  		"SnapShotSchedule:MonthlySnapShotSchedule.CronTab=0 0 1 * *", //  ==> snapShotPolicy.schedule[4]
   615  		"SnapShotSchedule:MonthlySnapShotSchedule.Keep=11",
   616  		"SnapShotSchedule:YearlySnapShotSchedule.CronTab=0 0 1 1 *", //   ==> snapShotPolicy.schedule[5]
   617  		"SnapShotSchedule:YearlySnapShotSchedule.Keep=4",
   618  		"SnapShotPolicy:CommonSnapShotPolicy.ScheduleList=MinutelySnapShotSchedule,HourlySnapShotSchedule,DailySnapShotSchedule,WeeklySnapShotSchedule,MonthlySnapShotSchedule,YearlySnapShotSchedule",
   619  		"SnapShotPolicy:CommonSnapShotPolicy.TimeZone=America/Los_Angeles",
   620  		"Volume:TestVolume.SnapShotPolicy=CommonSnapShotPolicy",
   621  	}
   622  
   623  	testConfMap, err = conf.MakeConfMapFromStrings(testConfMapStrings)
   624  	if nil != err {
   625  		t.Fatalf("conf.MakeConfMapFromStrings() failed: %v", err)
   626  	}
   627  
   628  	volume = &volumeStruct{volumeName: "TestVolume", snapShotPolicy: nil}
   629  
   630  	err = volume.loadSnapShotPolicy(testConfMap)
   631  	if nil != err {
   632  		t.Fatalf("loadSnapShotPolicy() failed: %v", err)
   633  	}
   634  
   635  	timeNow = time.Date(2017, time.January, 1, 0, 0, 0, 0, volume.snapShotPolicy.location) // A Sunday
   636  
   637  	nextTime = volume.snapShotPolicy.schedule[0].next(timeNow)
   638  	if !nextTime.Equal(time.Date(2017, time.January, 1, 0, 1, 0, 0, volume.snapShotPolicy.location)) {
   639  		t.Fatalf("snapShotPolicy.schedule[0].next(timeNow) returned unexpected time: %v", nextTime)
   640  	}
   641  
   642  	nextTime = volume.snapShotPolicy.schedule[1].next(timeNow)
   643  	if !nextTime.Equal(time.Date(2017, time.January, 1, 1, 0, 0, 0, volume.snapShotPolicy.location)) {
   644  		t.Fatalf("snapShotPolicy.schedule[1].next(timeNow) returned unexpected time: %v", nextTime)
   645  	}
   646  
   647  	nextTime = volume.snapShotPolicy.schedule[2].next(timeNow)
   648  	if !nextTime.Equal(time.Date(2017, time.January, 2, 0, 0, 0, 0, volume.snapShotPolicy.location)) {
   649  		t.Fatalf("snapShotPolicy.schedule[2].next(timeNow) returned unexpected time: %v", nextTime)
   650  	}
   651  
   652  	nextTime = volume.snapShotPolicy.schedule[3].next(timeNow)
   653  	if !nextTime.Equal(time.Date(2017, time.January, 8, 0, 0, 0, 0, volume.snapShotPolicy.location)) {
   654  		t.Fatalf("snapShotPolicy.schedule[3].next(timeNow) returned unexpected time: %v", nextTime)
   655  	}
   656  
   657  	nextTime = volume.snapShotPolicy.schedule[4].next(timeNow)
   658  	if !nextTime.Equal(time.Date(2017, time.February, 1, 0, 0, 0, 0, volume.snapShotPolicy.location)) {
   659  		t.Fatalf("snapShotPolicy.schedule[4].next(timeNow) returned unexpected time: %v", nextTime)
   660  	}
   661  
   662  	nextTime = volume.snapShotPolicy.schedule[5].next(timeNow)
   663  	if !nextTime.Equal(time.Date(2018, time.January, 1, 0, 0, 0, 0, volume.snapShotPolicy.location)) {
   664  		t.Fatalf("snapShotPolicy.schedule[5].next(timeNow) returned unexpected time: %v", nextTime)
   665  	}
   666  }
   667  
   668  func TestSnapShotPolicyNext(t *testing.T) {
   669  	var (
   670  		err                    error
   671  		testConfMap            conf.ConfMap
   672  		testConfMapStrings     []string
   673  		timeMidnight           time.Time
   674  		timeMidnightNext       time.Time
   675  		timeOhThirtyAM         time.Time
   676  		timeOneFortyFiveAM     time.Time
   677  		timeOneFortyFiveAMNext time.Time
   678  		timeTwoAM              time.Time
   679  		volume                 *volumeStruct
   680  	)
   681  
   682  	testConfMapStrings = []string{
   683  		"SnapShotSchedule:HalfPastTheHourSnapShotSchedule.CronTab=30 * * * *", // ==> snapShotPolicy.schedule[0]
   684  		"SnapShotSchedule:HalfPastTheHourSnapShotSchedule.Keep=99",
   685  		"SnapShotSchedule:TwoAMSnapShotSchedule.CronTab=0 2 * * *", //            ==> snapShotPolicy.schedule[1]
   686  		"SnapShotSchedule:TwoAMSnapShotSchedule.Keep=99",
   687  		"SnapShotPolicy:CommonSnapShotPolicy.ScheduleList=HalfPastTheHourSnapShotSchedule,TwoAMSnapShotSchedule",
   688  		"SnapShotPolicy:CommonSnapShotPolicy.TimeZone=America/Los_Angeles",
   689  		"Volume:TestVolume.SnapShotPolicy=CommonSnapShotPolicy",
   690  	}
   691  
   692  	testConfMap, err = conf.MakeConfMapFromStrings(testConfMapStrings)
   693  	if nil != err {
   694  		t.Fatalf("conf.MakeConfMapFromStrings() failed: %v", err)
   695  	}
   696  
   697  	volume = &volumeStruct{volumeName: "TestVolume", snapShotPolicy: nil}
   698  
   699  	err = volume.loadSnapShotPolicy(testConfMap)
   700  	if nil != err {
   701  		t.Fatalf("loadSnapShotPolicy() failed: %v", err)
   702  	}
   703  
   704  	timeMidnight = time.Date(2017, time.January, 1, 0, 0, 0, 0, volume.snapShotPolicy.location)
   705  	timeOhThirtyAM = time.Date(2017, time.January, 1, 0, 30, 0, 0, volume.snapShotPolicy.location)
   706  	timeOneFortyFiveAM = time.Date(2017, time.January, 1, 1, 45, 0, 0, volume.snapShotPolicy.location)
   707  	timeTwoAM = time.Date(2017, time.January, 1, 2, 0, 0, 0, volume.snapShotPolicy.location)
   708  
   709  	timeMidnightNext = volume.snapShotPolicy.schedule[0].next(timeMidnight)
   710  	timeOneFortyFiveAMNext = volume.snapShotPolicy.schedule[1].next(timeOneFortyFiveAM)
   711  
   712  	if timeMidnightNext != timeOhThirtyAM {
   713  		t.Fatalf("snapShotPolicy.schedule[0].next(timeMidnight) returned unexpected time: %v", timeMidnightNext)
   714  	}
   715  	if timeOneFortyFiveAMNext != timeTwoAM {
   716  		t.Fatalf("snapShotPolicy.schedule[1].next(timeOneFortyFiveAM) returned unexpected time: %v", timeOneFortyFiveAMNext)
   717  	}
   718  
   719  	timeMidnightNext = volume.snapShotPolicy.next(timeMidnight)
   720  	timeOneFortyFiveAMNext = volume.snapShotPolicy.next(timeOneFortyFiveAM)
   721  
   722  	if timeMidnightNext != timeOhThirtyAM {
   723  		t.Fatalf("snapShotPolicy.next(timeMidnight) returned unexpected time: %v", timeMidnightNext)
   724  	}
   725  	if timeOneFortyFiveAMNext != timeTwoAM {
   726  		t.Fatalf("snapShotPolicy.next(timeOneFortyFiveAM) returned unexpected time: %v", timeOneFortyFiveAMNext)
   727  	}
   728  }