go.ligato.io/vpp-agent/v3@v3.5.0/proto/ligato/linux/interfaces/models_test.go (about) 1 // Copyright (c) 2018 Cisco and/or its affiliates. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at: 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package linux_interfaces 16 17 import ( 18 "testing" 19 20 "go.ligato.io/vpp-agent/v3/proto/ligato/netalloc" 21 ) 22 23 func TestInterfaceAddressKey(t *testing.T) { 24 tests := []struct { 25 name string 26 iface string 27 address string 28 source netalloc.IPAddressSource 29 expectedKey string 30 }{ 31 { 32 name: "IPv4 address", 33 iface: "memif0", 34 address: "192.168.1.12/24", 35 source: netalloc.IPAddressSource_STATIC, 36 expectedKey: "linux/interface/memif0/address/static/192.168.1.12/24", 37 }, 38 { 39 name: "IPv4 address from DHCP", 40 iface: "memif0", 41 address: "192.168.1.12/24", 42 source: netalloc.IPAddressSource_FROM_DHCP, 43 expectedKey: "linux/interface/memif0/address/from_dhcp/192.168.1.12/24", 44 }, 45 { 46 name: "IPv6 address", 47 iface: "memif0", 48 address: "2001:db8::/32", 49 source: netalloc.IPAddressSource_STATIC, 50 expectedKey: "linux/interface/memif0/address/static/2001:db8::/32", 51 }, 52 { 53 name: "IPv6 address from DHCP", 54 iface: "memif0", 55 address: "2001:db8::/32", 56 source: netalloc.IPAddressSource_FROM_DHCP, 57 expectedKey: "linux/interface/memif0/address/from_dhcp/2001:db8::/32", 58 }, 59 { 60 name: "invalid interface", 61 iface: "", 62 address: "10.10.10.10/32", 63 source: netalloc.IPAddressSource_STATIC, 64 expectedKey: "linux/interface/<invalid>/address/static/10.10.10.10/32", 65 }, 66 { 67 name: "undefined source", 68 iface: "memif1", 69 address: "10.10.10.10/32", 70 expectedKey: "linux/interface/memif1/address/undefined_source/10.10.10.10/32", 71 }, 72 { 73 name: "invalid address", 74 iface: "tap0", 75 address: "invalid-addr", 76 source: netalloc.IPAddressSource_STATIC, 77 expectedKey: "linux/interface/tap0/address/static/invalid-addr", 78 }, 79 { 80 name: "missing mask", 81 iface: "tap1", 82 address: "10.10.10.10", 83 source: netalloc.IPAddressSource_STATIC, 84 expectedKey: "linux/interface/tap1/address/static/10.10.10.10", 85 }, 86 { 87 name: "empty address", 88 iface: "tap1", 89 address: "", 90 source: netalloc.IPAddressSource_STATIC, 91 expectedKey: "linux/interface/tap1/address/static/", 92 }, 93 { 94 name: "IPv4 address requested from netalloc", 95 iface: "memif0", 96 address: "alloc:net1", 97 source: netalloc.IPAddressSource_STATIC, 98 expectedKey: "linux/interface/memif0/address/alloc_ref/alloc:net1", 99 }, 100 { 101 name: "IPv6 address requested from netalloc", 102 iface: "memif0", 103 address: "alloc:net1/IPV6_ADDR", 104 source: netalloc.IPAddressSource_STATIC, 105 expectedKey: "linux/interface/memif0/address/alloc_ref/alloc:net1/IPV6_ADDR", 106 }, 107 } 108 for _, test := range tests { 109 t.Run(test.name, func(t *testing.T) { 110 key := InterfaceAddressKey(test.iface, test.address, test.source) 111 if key != test.expectedKey { 112 t.Errorf("failed for: iface=%s address=%s source=%s\n"+ 113 "expected key:\n\t%q\ngot key:\n\t%q", 114 test.iface, test.address, string(test.source), test.expectedKey, key) 115 } 116 }) 117 } 118 } 119 120 func TestParseInterfaceAddressKey(t *testing.T) { 121 tests := []struct { 122 name string 123 key string 124 expectedIface string 125 expectedIfaceAddr string 126 expectedSource netalloc.IPAddressSource 127 expectedInvalidKey bool 128 expectedIsAddrKey bool 129 }{ 130 { 131 name: "IPv4 address", 132 key: "linux/interface/memif0/address/static/192.168.1.12/24", 133 expectedIface: "memif0", 134 expectedIfaceAddr: "192.168.1.12/24", 135 expectedSource: netalloc.IPAddressSource_STATIC, 136 expectedIsAddrKey: true, 137 }, 138 { 139 name: "IPv4 address from DHCP", 140 key: "linux/interface/memif0/address/from_dhcp/192.168.1.12/24", 141 expectedIface: "memif0", 142 expectedIfaceAddr: "192.168.1.12/24", 143 expectedSource: netalloc.IPAddressSource_FROM_DHCP, 144 expectedIsAddrKey: true, 145 }, 146 { 147 name: "IPv4 address requested from Netalloc", 148 key: "linux/interface/memif0/address/alloc_ref/alloc:net1", 149 expectedIface: "memif0", 150 expectedIfaceAddr: "alloc:net1", 151 expectedSource: netalloc.IPAddressSource_ALLOC_REF, 152 expectedIsAddrKey: true, 153 }, 154 { 155 name: "IPv6 address", 156 key: "linux/interface/tap1/address/static/2001:db8:85a3::8a2e:370:7334/48", 157 expectedIface: "tap1", 158 expectedIfaceAddr: "2001:db8:85a3::8a2e:370:7334/48", 159 expectedSource: netalloc.IPAddressSource_STATIC, 160 expectedIsAddrKey: true, 161 }, 162 { 163 name: "IPv6 address requested from netalloc", 164 key: "linux/interface/tap1/address/alloc_ref/alloc:net1/IPV6_ADDR", 165 expectedIface: "tap1", 166 expectedIfaceAddr: "alloc:net1/IPV6_ADDR", 167 expectedSource: netalloc.IPAddressSource_ALLOC_REF, 168 expectedIsAddrKey: true, 169 }, 170 { 171 name: "IPv6 address from DHCP", 172 key: "linux/interface/tap1/address/from_dhcp/2001:db8:85a3::8a2e:370:7334/48", 173 expectedIface: "tap1", 174 expectedIfaceAddr: "2001:db8:85a3::8a2e:370:7334/48", 175 expectedSource: netalloc.IPAddressSource_FROM_DHCP, 176 expectedIsAddrKey: true, 177 }, 178 { 179 name: "invalid interface", 180 key: "linux/interface/<invalid>/address/static/10.10.10.10/30", 181 expectedIface: "<invalid>", 182 expectedIfaceAddr: "10.10.10.10/30", 183 expectedSource: netalloc.IPAddressSource_STATIC, 184 expectedIsAddrKey: true, 185 }, 186 { 187 name: "gbe interface", 188 key: "linux/interface/GigabitEthernet0/8/0/address/static/192.168.5.5/16", 189 expectedIface: "GigabitEthernet0/8/0", 190 expectedIfaceAddr: "192.168.5.5/16", 191 expectedSource: netalloc.IPAddressSource_STATIC, 192 expectedIsAddrKey: true, 193 }, 194 { 195 name: "missing interface", 196 key: "linux/interface//address/static/192.168.5.5/16", 197 expectedIface: "<invalid>", 198 expectedIfaceAddr: "192.168.5.5/16", 199 expectedSource: netalloc.IPAddressSource_STATIC, 200 expectedInvalidKey: true, 201 expectedIsAddrKey: true, 202 }, 203 { 204 name: "missing interface (from DHCP)", 205 key: "linux/interface//address/from_dhcp/192.168.5.5/16", 206 expectedIface: "<invalid>", 207 expectedIfaceAddr: "192.168.5.5/16", 208 expectedSource: netalloc.IPAddressSource_FROM_DHCP, 209 expectedInvalidKey: true, 210 expectedIsAddrKey: true, 211 }, 212 { 213 name: "missing IP", 214 key: "linux/interface/tap3/address/static/", 215 expectedIface: "tap3", 216 expectedIfaceAddr: "", 217 expectedSource: netalloc.IPAddressSource_STATIC, 218 expectedInvalidKey: true, 219 expectedIsAddrKey: true, 220 }, 221 { 222 name: "missing IP (from DHCP)", 223 key: "linux/interface/tap3/address/from_dhcp/", 224 expectedIface: "tap3", 225 expectedIfaceAddr: "", 226 expectedSource: netalloc.IPAddressSource_FROM_DHCP, 227 expectedInvalidKey: true, 228 expectedIsAddrKey: true, 229 }, 230 { 231 name: "missing IP for Gbe", 232 key: "linux/interface/Gbe0/1/2/address/static/", 233 expectedIface: "Gbe0/1/2", 234 expectedIfaceAddr: "", 235 expectedSource: netalloc.IPAddressSource_STATIC, 236 expectedInvalidKey: true, 237 expectedIsAddrKey: true, 238 }, 239 { 240 name: "not interface address key", 241 key: "linux/config/v2/interface/GigabitEthernet0/8/0", 242 expectedIface: "", 243 expectedIfaceAddr: "", 244 expectedIsAddrKey: false, 245 }, 246 { 247 name: "not interface address key #2", 248 key: "linux/interface/veth0/vrf/blue", 249 expectedIface: "", 250 expectedIfaceAddr: "", 251 expectedIsAddrKey: false, 252 }, 253 { 254 name: "invalid address source", 255 key: "linux/interface/memif0/address/<invalid>/192.168.1.12/24", 256 expectedIface: "memif0", 257 expectedInvalidKey: true, 258 expectedIsAddrKey: true, 259 }, 260 { 261 name: "empty address source", 262 key: "linux/interface/memif0/address//192.168.1.12/24", 263 expectedIface: "memif0", 264 expectedInvalidKey: true, 265 expectedIsAddrKey: true, 266 }, 267 { 268 name: "missing address source", 269 key: "linux/interface/memif0/address/192.168.1.12/24", 270 expectedIface: "memif0", 271 expectedInvalidKey: true, 272 expectedIsAddrKey: true, 273 }, 274 } 275 for _, test := range tests { 276 t.Run(test.name, func(t *testing.T) { 277 iface, ipAddr, source, invalidKey, isAddrKey := ParseInterfaceAddressKey(test.key) 278 if isAddrKey != test.expectedIsAddrKey { 279 t.Errorf("expected isAddrKey: %v\tgot: %v", test.expectedIsAddrKey, isAddrKey) 280 } 281 if source != test.expectedSource { 282 t.Errorf("expected source: %v\tgot: %v", test.expectedSource, source) 283 } 284 if invalidKey != test.expectedInvalidKey { 285 t.Errorf("expected invalidKey: %v\tgot: %v", test.expectedInvalidKey, invalidKey) 286 } 287 if iface != test.expectedIface { 288 t.Errorf("expected iface: %s\tgot: %s", test.expectedIface, iface) 289 } 290 if ipAddr != test.expectedIfaceAddr { 291 t.Errorf("expected ipAddr: %s\tgot: %s", test.expectedIfaceAddr, ipAddr) 292 } 293 }) 294 } 295 } 296 297 func TestInterfaceVrfKey(t *testing.T) { 298 tests := []struct { 299 name string 300 iface string 301 vrf string 302 expectedKey string 303 }{ 304 { 305 name: "VRF 'blue'", 306 iface: "veth0", 307 vrf: "blue", 308 expectedKey: "linux/interface/veth0/vrf/blue", 309 }, 310 { 311 name: "VRF 'red'", 312 iface: "veth0", 313 vrf: "red", 314 expectedKey: "linux/interface/veth0/vrf/red", 315 }, 316 { 317 name: "invalid interface", 318 iface: "", 319 vrf: "blue", 320 expectedKey: "linux/interface/<invalid>/vrf/blue", 321 }, 322 { 323 name: "invalid VRF", 324 iface: "veth0", 325 vrf: "", 326 expectedKey: "linux/interface/veth0/vrf/<invalid>", 327 }, 328 } 329 for _, test := range tests { 330 t.Run(test.name, func(t *testing.T) { 331 key := InterfaceVrfKey(test.iface, test.vrf) 332 if key != test.expectedKey { 333 t.Errorf("failed for: iface=%s vrf=%s\n"+ 334 "expected key:\n\t%q\ngot key:\n\t%q", 335 test.iface, test.vrf, test.expectedKey, key) 336 } 337 }) 338 } 339 } 340 341 func TestParseInterfaceVrfKey(t *testing.T) { 342 tests := []struct { 343 name string 344 key string 345 expectedIface string 346 expectedIfaceVrf string 347 expectedInvalidKey bool 348 expectedIsVrfKey bool 349 }{ 350 { 351 name: "VRF 'blue'", 352 key: "linux/interface/veth0/vrf/blue", 353 expectedIface: "veth0", 354 expectedIfaceVrf: "blue", 355 expectedIsVrfKey: true, 356 }, 357 { 358 name: "VRF 'red'", 359 key: "linux/interface/veth0/vrf/red", 360 expectedIface: "veth0", 361 expectedIfaceVrf: "red", 362 expectedIsVrfKey: true, 363 }, 364 { 365 name: "missing interface", 366 key: "linux/interface//vrf/blue", 367 expectedIface: "<invalid>", 368 expectedIfaceVrf: "blue", 369 expectedInvalidKey: true, 370 expectedIsVrfKey: true, 371 }, 372 { 373 name: "missing VRF", 374 key: "linux/interface/veth0/vrf", 375 expectedIface: "veth0", 376 expectedIfaceVrf: "<invalid>", 377 expectedInvalidKey: true, 378 expectedIsVrfKey: true, 379 }, 380 { 381 name: "not interface VRF key", 382 key: "linux/interface/tap1/address/static/2001:db8:85a3::8a2e:370:7334/48", 383 expectedIsVrfKey: false, 384 }, 385 { 386 name: "not interface VRF key #2", 387 key: "linux/interface/tap1/address/static/192.168.1.1/32/vrf/blue", 388 expectedIsVrfKey: false, 389 }, 390 } 391 for _, test := range tests { 392 t.Run(test.name, func(t *testing.T) { 393 iface, vrf, invalidKey, isVrfKey := ParseInterfaceVrfKey(test.key) 394 if isVrfKey != test.expectedIsVrfKey { 395 t.Errorf("expected isVrfKey: %v\tgot: %v", test.expectedIsVrfKey, isVrfKey) 396 } 397 if invalidKey != test.expectedInvalidKey { 398 t.Errorf("expected invalidKey: %v\tgot: %v", test.expectedInvalidKey, invalidKey) 399 } 400 if iface != test.expectedIface { 401 t.Errorf("expected iface: %s\tgot: %s", test.expectedIface, iface) 402 } 403 if vrf != test.expectedIfaceVrf { 404 t.Errorf("expected vrf: %s\tgot: %s", test.expectedIfaceVrf, vrf) 405 } 406 }) 407 } 408 }