github.com/gravitational/teleport/api@v0.0.0-20240507183017-3110591cbafc/types/instance_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/coreos/go-semver/semver" 24 "github.com/stretchr/testify/require" 25 ) 26 27 func TestInstanceFilter(t *testing.T) { 28 iis := []struct { 29 id string 30 version string 31 services []SystemRole 32 upgrader string 33 }{ 34 { 35 id: "a1", 36 version: "v1.2.3", 37 services: []SystemRole{RoleAuth}, 38 }, 39 { 40 id: "a2", 41 version: "v2.3.4", 42 services: []SystemRole{RoleAuth, RoleNode}, 43 upgrader: "kube", 44 }, 45 { 46 id: "p1", 47 version: "v1.2.1", 48 services: []SystemRole{RoleProxy}, 49 }, 50 { 51 id: "p2", 52 version: "v2.3.1", 53 services: []SystemRole{RoleProxy, RoleNode}, 54 upgrader: "unit", 55 }, 56 } 57 58 // set up group of test instances 59 var instances []Instance 60 for _, ii := range iis { 61 ins, err := NewInstance(ii.id, InstanceSpecV1{ 62 Version: ii.version, 63 Services: ii.services, 64 ExternalUpgrader: ii.upgrader, 65 }) 66 67 require.NoError(t, err, "id=%s", ii.id) 68 instances = append(instances, ins) 69 } 70 71 // set up test scenarios 72 tts := []struct { 73 desc string 74 filter InstanceFilter 75 matches []string 76 }{ 77 { 78 desc: "match-all", 79 filter: InstanceFilter{}, 80 matches: []string{ 81 "a1", 82 "a2", 83 "p1", 84 "p2", 85 }, 86 }, 87 { 88 desc: "match-proxies", 89 filter: InstanceFilter{ 90 Services: []SystemRole{ 91 RoleProxy, 92 }, 93 }, 94 matches: []string{ 95 "p1", 96 "p2", 97 }, 98 }, 99 { 100 desc: "match-old", 101 filter: InstanceFilter{ 102 OlderThanVersion: "v2", 103 }, 104 matches: []string{ 105 "a1", 106 "p1", 107 }, 108 }, 109 { 110 desc: "match-new", 111 filter: InstanceFilter{ 112 NewerThanVersion: "v2", 113 }, 114 matches: []string{ 115 "a2", 116 "p2", 117 }, 118 }, 119 { 120 desc: "match-version-range", 121 filter: InstanceFilter{ 122 NewerThanVersion: "v1.2.2", 123 OlderThanVersion: "v2.3.3", 124 }, 125 matches: []string{ 126 "a1", 127 "p2", 128 }, 129 }, 130 { 131 desc: "match-kube-upgrader", 132 filter: InstanceFilter{ 133 ExternalUpgrader: "kube", 134 }, 135 matches: []string{ 136 "a2", 137 }, 138 }, 139 { 140 desc: "match-no-upgrader", 141 filter: InstanceFilter{ 142 NoExtUpgrader: true, 143 }, 144 matches: []string{ 145 "a1", 146 "p1", 147 }, 148 }, 149 } 150 151 for _, tt := range tts { 152 var matches []string 153 for _, ins := range instances { 154 if tt.filter.Match(ins) { 155 matches = append(matches, ins.GetName()) 156 } 157 } 158 159 require.Equal(t, tt.matches, matches) 160 } 161 } 162 163 // TestVersionShorthand verifies our ability to decode go-style semver with the more 164 // opinionated semver library. 165 func TestVersionShorthand(t *testing.T) { 166 tts := []struct { 167 version string 168 expect string 169 invalid bool 170 }{ 171 { 172 version: "v1", 173 expect: "1.0.0", 174 }, 175 { 176 version: "1.1", 177 expect: "1.1.0", 178 }, 179 { 180 version: "1", 181 expect: "1.0.0", 182 }, 183 { 184 version: "v1.2.3", 185 expect: "1.2.3", 186 }, 187 { 188 version: "v1.2", 189 expect: "1.2.0", 190 }, 191 { 192 version: "1.2.3-alpha.1", 193 expect: "1.2.3-alpha.1", 194 }, 195 { 196 version: "v1.2.3-alpha.1", 197 expect: "1.2.3-alpha.1", 198 }, 199 { 200 version: "1.2.3+amd64", 201 expect: "1.2.3+amd64", 202 }, 203 { 204 version: "1.2.3-alpha.1+amd64", 205 expect: "1.2.3-alpha.1+amd64", 206 }, 207 { 208 version: "v1.2.3-alpha.1+amd64", 209 expect: "1.2.3-alpha.1+amd64", 210 }, 211 { 212 version: "1v2.3", 213 invalid: true, 214 }, 215 { 216 version: "", 217 invalid: true, 218 }, 219 { 220 version: ".", 221 invalid: true, 222 }, 223 { 224 version: "v", 225 invalid: true, 226 }, 227 { 228 version: "vv", 229 invalid: true, 230 }, 231 { 232 version: "v1-alpha.1", 233 invalid: true, 234 }, 235 { 236 version: "v1.2-alpha.1", 237 invalid: true, 238 }, 239 } 240 241 for _, tt := range tts { 242 vr, ok := parseVersionRelaxed(tt.version) 243 if tt.invalid { 244 require.False(t, ok, "tt=%+v", tt) 245 continue 246 } 247 248 require.True(t, ok, "tt=%+v", tt) 249 250 vs, err := semver.NewVersion(tt.expect) 251 require.NoError(t, err, "tt=%+v", tt) 252 253 require.Equal(t, tt.expect, vr.String(), "tt=%+v", tt) 254 require.True(t, vr.Equal(*vs), "tt=%+v", tt) 255 } 256 } 257 258 func TestInstanceControlLogExpiry(t *testing.T) { 259 const ttl = time.Minute 260 now := time.Now() 261 instance, err := NewInstance("test-instance", InstanceSpecV1{ 262 LastSeen: now, 263 }) 264 require.NoError(t, err) 265 266 instance.AppendControlLog( 267 InstanceControlLogEntry{ 268 Type: "foo", 269 Time: now, 270 TTL: ttl, 271 }, 272 InstanceControlLogEntry{ 273 Type: "bar", 274 Time: now.Add(-ttl / 2), 275 TTL: ttl, 276 }, 277 InstanceControlLogEntry{ 278 Type: "bin", 279 Time: now.Add(-ttl * 2), 280 TTL: ttl, 281 }, 282 InstanceControlLogEntry{ 283 Type: "baz", 284 Time: now, 285 TTL: time.Hour, 286 }, 287 ) 288 289 require.Len(t, instance.GetControlLog(), 4) 290 291 instance.SyncLogAndResourceExpiry(ttl) 292 293 require.Len(t, instance.GetControlLog(), 3) 294 require.Equal(t, now.Add(time.Hour).UTC(), instance.Expiry()) 295 296 instance.SetLastSeen(now.Add(ttl)) 297 298 instance.SyncLogAndResourceExpiry(ttl) 299 300 require.Len(t, instance.GetControlLog(), 2) 301 require.Equal(t, now.Add(time.Hour).UTC(), instance.Expiry()) 302 303 instance.AppendControlLog( 304 InstanceControlLogEntry{ 305 Type: "long-lived", 306 Time: now, 307 TTL: time.Hour * 2, 308 }, 309 ) 310 311 instance.SyncLogAndResourceExpiry(ttl) 312 313 require.Len(t, instance.GetControlLog(), 3) 314 require.Equal(t, now.Add(time.Hour*2).UTC(), instance.Expiry()) 315 }