github.com/gravitational/teleport/api@v0.0.0-20240507183017-3110591cbafc/types/maintenance_test.go (about) 1 /* 2 Copyright 2022 Gravitational, Inc. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package types 18 19 import ( 20 "testing" 21 "time" 22 23 "github.com/stretchr/testify/require" 24 ) 25 26 func TestAgentUpgradeWindow(t *testing.T) { 27 newTime := func(day int, hour int) time.Time { 28 return time.Date( 29 2000, 30 time.January, 31 day, 32 hour, 33 0, // min 34 0, // sec 35 0, // nsec 36 time.UTC, 37 ) 38 } 39 40 from := newTime(1, 12) 41 42 require.Equal(t, time.Saturday, from.Weekday()) // verify that newTime starts from expected pos 43 44 conf := AgentUpgradeWindow{ 45 UTCStartHour: 2, 46 } 47 48 tts := []struct{ start, stop time.Time }{ 49 {newTime(1, 2), newTime(1, 3)}, 50 {newTime(2, 2), newTime(2, 3)}, 51 {newTime(3, 2), newTime(3, 3)}, 52 {newTime(4, 2), newTime(4, 3)}, 53 {newTime(5, 2), newTime(5, 3)}, 54 {newTime(6, 2), newTime(6, 3)}, 55 {newTime(7, 2), newTime(7, 3)}, 56 {newTime(8, 2), newTime(8, 3)}, 57 {newTime(9, 2), newTime(9, 3)}, 58 } 59 60 gen := conf.generator(from) 61 62 for _, tt := range tts { 63 start, stop := gen() 64 require.Equal(t, tt.start, start) 65 require.Equal(t, tt.stop, stop) 66 } 67 68 // set weekdays fileter s.t. windows limited to m-f. 69 conf.Weekdays = []string{ 70 "Monday", 71 "tue", 72 "Wed", 73 "thursday", 74 "Friday", 75 } 76 77 tts = []struct{ start, stop time.Time }{ 78 // sat {newTime(1, 2), newTime(1, 3)}, 79 // sun {newTime(2, 2), newTime(2, 3)}, 80 {newTime(3, 2), newTime(3, 3)}, 81 {newTime(4, 2), newTime(4, 3)}, 82 {newTime(5, 2), newTime(5, 3)}, 83 {newTime(6, 2), newTime(6, 3)}, 84 {newTime(7, 2), newTime(7, 3)}, 85 // sat {newTime(8, 2), newTime(8, 3)}, 86 // sun {newTime(9, 2), newTime(9, 3)}, 87 } 88 89 gen = conf.generator(from) 90 91 for _, tt := range tts { 92 start, stop := gen() 93 require.Equal(t, tt.start, start) 94 require.Equal(t, tt.stop, stop) 95 } 96 97 // verify that invalid weekdays are omitted from filter. 98 conf.Weekdays = []string{ 99 "Monday", 100 "tues", // invalid 101 "Wed", 102 "Th", // invalid 103 "Friday", 104 } 105 106 tts = []struct{ start, stop time.Time }{ 107 // sat {newTime(1, 2), newTime(1, 3)}, 108 // sun {newTime(2, 2), newTime(2, 3)}, 109 {newTime(3, 2), newTime(3, 3)}, 110 // tue {newTime(4, 2), newTime(4, 3)}, 111 {newTime(5, 2), newTime(5, 3)}, 112 // thu {newTime(6, 2), newTime(6, 3)}, 113 {newTime(7, 2), newTime(7, 3)}, 114 // sat {newTime(8, 2), newTime(8, 3)}, 115 // sun {newTime(9, 2), newTime(9, 3)}, 116 } 117 118 gen = conf.generator(from) 119 120 for _, tt := range tts { 121 start, stop := gen() 122 require.Equal(t, tt.start, start) 123 require.Equal(t, tt.stop, stop) 124 } 125 126 // if all weekdays are invalid, revert to firing every day 127 conf.Weekdays = []string{ 128 "Mo", 129 "Tu", 130 "We", 131 "Th", 132 "Fr", 133 } 134 135 tts = []struct{ start, stop time.Time }{ 136 {newTime(1, 2), newTime(1, 3)}, 137 {newTime(2, 2), newTime(2, 3)}, 138 {newTime(3, 2), newTime(3, 3)}, 139 {newTime(4, 2), newTime(4, 3)}, 140 {newTime(5, 2), newTime(5, 3)}, 141 {newTime(6, 2), newTime(6, 3)}, 142 {newTime(7, 2), newTime(7, 3)}, 143 {newTime(8, 2), newTime(8, 3)}, 144 {newTime(9, 2), newTime(9, 3)}, 145 } 146 147 gen = conf.generator(from) 148 149 for _, tt := range tts { 150 start, stop := gen() 151 require.Equal(t, tt.start, start) 152 require.Equal(t, tt.stop, stop) 153 } 154 } 155 156 // verify that the default (empty) maintenance window value is valid. 157 func TestClusterMaintenanceConfigDefault(t *testing.T) { 158 t.Parallel() 159 160 mw := NewClusterMaintenanceConfig() 161 162 require.NoError(t, mw.CheckAndSetDefaults()) 163 } 164 165 func TestWeekdayParser(t *testing.T) { 166 t.Parallel() 167 168 tts := []struct { 169 input string 170 expect time.Weekday 171 fail bool 172 }{ 173 { 174 input: "Tue", 175 expect: time.Tuesday, 176 }, 177 { 178 input: "tue", 179 expect: time.Tuesday, 180 }, 181 { 182 input: "tues", 183 fail: true, // only 3-letter shorthand is accepted 184 }, 185 { 186 input: "Saturday", 187 expect: time.Saturday, 188 }, 189 { 190 input: "saturday", 191 expect: time.Saturday, 192 }, 193 { 194 input: "sun", 195 expect: time.Sunday, 196 }, 197 { 198 input: "sundae", // containing a valid prefix is insufficient 199 fail: true, 200 }, 201 { 202 input: "", 203 fail: true, 204 }, 205 } 206 207 for _, tt := range tts { 208 day, ok := parseWeekday(tt.input) 209 if tt.fail { 210 require.False(t, ok) 211 continue 212 } 213 214 require.Equal(t, tt.expect, day) 215 } 216 } 217 218 func TestWithinUpgradeWindow(t *testing.T) { 219 t.Parallel() 220 221 tests := []struct { 222 desc string 223 upgradeWindow AgentUpgradeWindow 224 date string 225 withinWindow bool 226 }{ 227 { 228 desc: "within upgrade window", 229 upgradeWindow: AgentUpgradeWindow{ 230 UTCStartHour: 8, 231 }, 232 date: "Mon, 02 Jan 2006 08:04:05 UTC", 233 withinWindow: true, 234 }, 235 { 236 desc: "not within upgrade window", 237 upgradeWindow: AgentUpgradeWindow{ 238 UTCStartHour: 8, 239 }, 240 date: "Mon, 02 Jan 2006 09:04:05 UTC", 241 withinWindow: false, 242 }, 243 { 244 desc: "within upgrade window weekday", 245 upgradeWindow: AgentUpgradeWindow{ 246 UTCStartHour: 8, 247 Weekdays: []string{"Monday"}, 248 }, 249 date: "Mon, 02 Jan 2006 08:04:05 UTC", 250 withinWindow: true, 251 }, 252 { 253 desc: "not within upgrade window weekday", 254 upgradeWindow: AgentUpgradeWindow{ 255 UTCStartHour: 8, 256 Weekdays: []string{"Tuesday"}, 257 }, 258 date: "Mon, 02 Jan 2006 08:04:05 UTC", 259 withinWindow: false, 260 }, 261 } 262 263 for _, tt := range tests { 264 t.Run(tt.desc, func(t *testing.T) { 265 cmc := NewClusterMaintenanceConfig() 266 cmc.SetAgentUpgradeWindow(tt.upgradeWindow) 267 268 date, err := time.Parse(time.RFC1123, tt.date) 269 require.NoError(t, err) 270 require.Equal(t, tt.withinWindow, cmc.WithinUpgradeWindow(date)) 271 }) 272 } 273 }