github.com/niedbalski/juju@v0.0.0-20190215020005-8ff100488e47/network/debinterfaces/bridge_test.go (about) 1 // Copyright 2017 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package debinterfaces_test 5 6 import ( 7 "runtime" 8 9 gc "gopkg.in/check.v1" 10 11 "github.com/juju/juju/network/debinterfaces" 12 "github.com/juju/testing" 13 ) 14 15 type BridgeSuite struct { 16 testing.IsolationSuite 17 18 expander debinterfaces.WordExpander 19 } 20 21 var _ = gc.Suite(&BridgeSuite{}) 22 23 func (s *BridgeSuite) SetUpSuite(c *gc.C) { 24 if runtime.GOOS == "windows" { 25 c.Skip("skipping ActivationSuite tests on windows") 26 } 27 s.IsolationSuite.SetUpSuite(c) 28 } 29 30 func format(stanzas []debinterfaces.Stanza) string { 31 return debinterfaces.FormatStanzas(stanzas, 4) 32 } 33 34 func (s *BridgeSuite) SetUpTest(c *gc.C) { 35 s.expander = debinterfaces.NewWordExpander() 36 } 37 38 func (s *BridgeSuite) assertParse(c *gc.C, content string) []debinterfaces.Stanza { 39 stanzas, err := debinterfaces.ParseSource("", content, s.expander) 40 c.Assert(err, gc.IsNil) 41 return stanzas 42 } 43 44 func (s *BridgeSuite) checkBridge(input, expected string, c *gc.C, devices map[string]string) { 45 stanzas := s.assertParse(c, input) 46 bridged := debinterfaces.Bridge(stanzas, devices) 47 c.Check(format(bridged), gc.Equals, expected) 48 s.assertParse(c, format(bridged)) 49 } 50 51 func (s *BridgeSuite) checkBridgeUnchanged(input string, c *gc.C, devices map[string]string) { 52 stanzas := s.assertParse(c, input) 53 bridged := debinterfaces.Bridge(stanzas, devices) 54 c.Check(format(bridged), gc.Equals, input[1:]) 55 s.assertParse(c, format(bridged)) 56 } 57 58 func (s *BridgeSuite) TestBridgeDeviceNameNotMatched(c *gc.C) { 59 input := ` 60 auto eth0 61 iface eth0 inet manual` 62 s.checkBridgeUnchanged(input, c, map[string]string{"non-existent-interface": "br-non-existent"}) 63 } 64 65 func (s *BridgeSuite) TestBridgeDeviceNameAlreadyBridged(c *gc.C) { 66 input := ` 67 auto br-eth0 68 iface br-eth0 inet dhcp 69 bridge_ports eth0` 70 s.checkBridgeUnchanged(input, c, map[string]string{"br-eth0": "br-eth0-2"}) 71 } 72 73 func (s *BridgeSuite) TestBridgeDeviceIsBridgeable(c *gc.C) { 74 input := ` 75 auto eth0 76 iface eth0 inet dhcp` 77 78 expected := ` 79 auto eth0 80 iface eth0 inet manual 81 82 auto br-eth0 83 iface br-eth0 inet dhcp 84 bridge_ports eth0` 85 s.checkBridge(input, expected[1:], c, map[string]string{"eth0": "br-eth0"}) 86 } 87 88 func (s *BridgeSuite) TestBridgeDeviceIsBridgeableButHasNoAutoStanza(c *gc.C) { 89 input := ` 90 iface eth0 inet dhcp` 91 92 expected := ` 93 iface eth0 inet manual 94 95 iface br-eth0 inet dhcp 96 bridge_ports eth0` 97 s.checkBridge(input, expected[1:], c, map[string]string{"eth0": "br-eth0"}) 98 } 99 100 func (s *BridgeSuite) TestBridgeDeviceIsNotBridgeable(c *gc.C) { 101 input := ` 102 iface work-wireless bootp` 103 s.checkBridgeUnchanged(input, c, map[string]string{"work-wireless": "br-work-wireless"}) 104 } 105 106 func (s *BridgeSuite) TestBridgeSpecialOptionsGetMoved(c *gc.C) { 107 input := ` 108 auto eth0 109 iface eth0 inet static 110 mtu 1500 111 112 auto eth1 113 iface eth1 inet static 114 address 192.168.1.254 115 gateway 192.168.1.1 116 netmask 255.255.255.0 117 dns-nameservers 8.8.8.8 118 dns-search ubuntu.com 119 dns-sortlist 192.168.1.1/24 10.245.168.0/21 192.168.1.0/24 120 mtu 1500` 121 122 expected := ` 123 auto eth0 124 iface eth0 inet manual 125 mtu 1500 126 127 auto eth1 128 iface eth1 inet manual 129 mtu 1500 130 131 auto br-eth0 132 iface br-eth0 inet static 133 bridge_ports eth0 134 135 auto br-eth1 136 iface br-eth1 inet static 137 address 192.168.1.254 138 gateway 192.168.1.1 139 netmask 255.255.255.0 140 dns-nameservers 8.8.8.8 141 dns-search ubuntu.com 142 dns-sortlist 192.168.1.1/24 10.245.168.0/21 192.168.1.0/24 143 bridge_ports eth1` 144 s.checkBridge(input, expected[1:], c, map[string]string{"eth0": "br-eth0", "eth1": "br-eth1"}) 145 } 146 147 func (s *BridgeSuite) TestBridgeVLAN(c *gc.C) { 148 input := ` 149 auto eth0.2 150 iface eth0.2 inet static 151 address 192.168.2.3/24 152 vlan-raw-device eth0 153 mtu 1500 154 vlan_id 2` 155 156 expected := ` 157 auto eth0.2 158 iface eth0.2 inet manual 159 vlan-raw-device eth0 160 mtu 1500 161 vlan_id 2 162 163 auto br-eth0.2 164 iface br-eth0.2 inet static 165 address 192.168.2.3/24 166 bridge_ports eth0.2` 167 s.checkBridge(input, expected[1:], c, map[string]string{"eth0.2": "br-eth0.2"}) 168 } 169 170 func (s *BridgeSuite) TestBridgeBond(c *gc.C) { 171 input := ` 172 auto eth0 173 iface eth0 inet manual 174 bond-miimon 100 175 bond-master bond0 176 bond-mode active-backup 177 bond-lacp-rate slow 178 bond-xmit-hash-policy layer2 179 mtu 1500 180 181 auto eth1 182 iface eth1 inet manual 183 bond-miimon 100 184 bond-master bond0 185 bond-mode active-backup 186 bond-lacp-rate slow 187 bond-xmit-hash-policy layer2 188 mtu 1500 189 190 auto bond0 191 iface bond0 inet static 192 address 10.17.20.211/24 193 gateway 10.17.20.1 194 dns-nameservers 10.17.20.200 195 bond-slaves eth0 eth1 196 bond-mode active-backup 197 bond-xmit_hash_policy layer2 198 bond-miimon 100 199 mtu 1500 200 hwaddress 52:54:00:1c:f1:5b 201 bond-lacp_rate slow` 202 203 expected := ` 204 auto eth0 205 iface eth0 inet manual 206 bond-miimon 100 207 bond-master bond0 208 bond-mode active-backup 209 bond-lacp-rate slow 210 bond-xmit-hash-policy layer2 211 mtu 1500 212 213 auto eth1 214 iface eth1 inet manual 215 bond-miimon 100 216 bond-master bond0 217 bond-mode active-backup 218 bond-lacp-rate slow 219 bond-xmit-hash-policy layer2 220 mtu 1500 221 222 auto bond0 223 iface bond0 inet manual 224 bond-slaves eth0 eth1 225 bond-mode active-backup 226 bond-xmit_hash_policy layer2 227 bond-miimon 100 228 mtu 1500 229 hwaddress 52:54:00:1c:f1:5b 230 bond-lacp_rate slow 231 232 auto br-bond0 233 iface br-bond0 inet static 234 address 10.17.20.211/24 235 gateway 10.17.20.1 236 dns-nameservers 10.17.20.200 237 hwaddress 52:54:00:1c:f1:5b 238 bridge_ports bond0` 239 s.checkBridge(input, expected[1:], c, map[string]string{"bond0": "br-bond0"}) 240 } 241 242 func (s *BridgeSuite) TestBridgingIdempotent(c *gc.C) { 243 input := ` 244 auto eth0 245 iface eth0 inet manual 246 bond-miimon 100 247 bond-master bond0 248 bond-mode active-backup 249 bond-lacp-rate slow 250 bond-xmit-hash-policy layer2 251 mtu 1500 252 253 auto bond0 254 iface bond0 inet manual 255 bond-mode active-backup 256 bond-xmit-hash-policy layer2 257 hwaddress ether 7c:d3:0a:bb:e2:0a 258 bond-slaves eth0 259 mtu 1500 260 bond-lacp-rate slow 261 bond-miimon 100 262 263 auto br-bond0 264 iface br-bond0 inet static 265 address 10.20.2.253/22 266 gateway 10.20.0.1 267 bridge_ports bond0` 268 269 s.checkBridgeUnchanged(input, c, map[string]string{"bond0": "br-bond0", "bond0.1000": "br-bond0.1000", "bond0.1001": "br-bond0.1001", "bond0.1002": "br-bond0.1002"}) 270 } 271 272 func (s *BridgeSuite) TestBridgeNoIfacesDefined(c *gc.C) { 273 input := ` 274 mapping eth0 275 script /path/to/pcmcia-compat.sh 276 map home,*,*,* home 277 map work,*,*,00:11:22:33:44:55 work-wireless 278 map work,*,*,01:12:23:34:45:50 work-static` 279 s.checkBridgeUnchanged(input, c, map[string]string{"eth0": "br-eth0"}) 280 } 281 282 func (s *BridgeSuite) TestBridgeBondMaster(c *gc.C) { 283 input := ` 284 auto ens5 285 iface ens5 inet manual 286 bond-lacp_rate slow 287 mtu 1500 288 bond-master bond0 289 bond-xmit_hash_policy layer2 290 bond-mode active-backup 291 bond-miimon 100` 292 s.checkBridgeUnchanged(input, c, map[string]string{"ens5": "br-ens5"}) 293 } 294 295 func (s *BridgeSuite) TestBridgeNoIfacesDefinedFromFile(c *gc.C) { 296 stanzas, err := debinterfaces.ParseSource("testdata/ifupdown-examples", nil, s.expander) 297 c.Assert(err, gc.IsNil) 298 input := format(stanzas) 299 s.checkBridge(input, input, c, map[string]string{"non-existent-interface": "non-existent-bridge"}) 300 } 301 302 func (s *BridgeSuite) TestBridgeAlias(c *gc.C) { 303 input := ` 304 auto eth0 305 iface eth0 inet static 306 gateway 10.14.0.1 307 address 10.14.0.102/24 308 309 auto eth0:1 310 iface eth0:1 inet static 311 address 1.2.3.5` 312 313 expected := ` 314 auto eth0 315 iface eth0 inet manual 316 317 auto br-eth0:1 318 iface br-eth0:1 inet static 319 address 1.2.3.5 320 321 auto br-eth0 322 iface br-eth0 inet static 323 gateway 10.14.0.1 324 address 10.14.0.102/24 325 bridge_ports eth0` 326 s.checkBridge(input, expected[1:], c, map[string]string{"eth0": "br-eth0", "eth0:1": "br-eth0:1"}) 327 } 328 329 func (s *BridgeSuite) TestBridgeMultipleInterfaces(c *gc.C) { 330 input := ` 331 auto enp1s0f3 332 iface enp1s0f3 inet static 333 address 192.168.1.64/24 334 gateway 192.168.1.254 335 dns-nameservers 192.168.1.254 336 dns-search home 337 338 iface enp1s0f3 inet6 dhcp` 339 340 expected := ` 341 auto enp1s0f3 342 iface enp1s0f3 inet manual 343 344 iface enp1s0f3 inet6 manual 345 346 auto br-enp1s0f3 347 iface br-enp1s0f3 inet static 348 address 192.168.1.64/24 349 gateway 192.168.1.254 350 dns-nameservers 192.168.1.254 351 dns-search home 352 bridge_ports enp1s0f3 353 354 iface br-enp1s0f3 inet6 dhcp 355 bridge_ports enp1s0f3` 356 s.checkBridge(input, expected[1:], c, map[string]string{"enp1s0f3": "br-enp1s0f3"}) 357 } 358 359 func (s *BridgeSuite) TestSourceStanzaWithRelativeFilenames(c *gc.C) { 360 stanzas, err := debinterfaces.Parse("testdata/TestInputSourceStanza/interfaces") 361 c.Assert(err, gc.IsNil) 362 c.Assert(stanzas, gc.HasLen, 3) 363 bridged := debinterfaces.Bridge(stanzas, map[string]string{"eth0": "br-eth0"}) 364 365 expected := ` 366 auto lo 367 iface lo inet loopback 368 369 auto eth0 370 iface eth0 inet manual 371 372 auto eth1 373 iface eth1 inet static 374 address 192.168.1.64 375 dns-nameservers 192.168.1.254 376 377 auto eth2 378 iface eth2 inet manual 379 380 auto br-eth0 381 iface br-eth0 inet dhcp 382 bridge_ports eth0` 383 384 c.Assert(debinterfaces.FormatStanzas(debinterfaces.FlattenStanzas(bridged), 4), gc.Equals, expected[1:]) 385 } 386 387 func (s *BridgeSuite) TestSourceDirectoryStanzaWithRelativeFilenames(c *gc.C) { 388 stanzas, err := debinterfaces.Parse("testdata/TestInputSourceDirectoryStanza/interfaces") 389 c.Assert(err, gc.IsNil) 390 c.Assert(stanzas, gc.HasLen, 3) 391 392 bridged := debinterfaces.Bridge(stanzas, map[string]string{"eth3": "br-eth3"}) 393 394 expected := ` 395 auto lo 396 iface lo inet loopback 397 398 auto eth3 399 iface eth3 inet manual 400 401 auto br-eth3 402 iface br-eth3 inet static 403 address 192.168.1.128 404 dns-nameservers 192.168.1.254 405 bridge_ports eth3` 406 407 c.Assert(debinterfaces.FormatStanzas(debinterfaces.FlattenStanzas(bridged), 4), gc.Equals, expected[1:]) 408 } 409 410 func (s *BridgeSuite) TestBridgeInet6Only(c *gc.C) { 411 input := ` 412 auto enxe0db55e41d5b 413 iface enxe0db55e41d5b inet6 static 414 address 3ffe:1234:5678::1/64 415 gateway 3ffe:1234:5678::2 416 ` 417 expected := ` 418 auto enxe0db55e41d5b 419 iface enxe0db55e41d5b inet6 manual 420 421 auto br-xe0db55e41d5b 422 iface br-xe0db55e41d5b inet6 static 423 address 3ffe:1234:5678::1/64 424 gateway 3ffe:1234:5678::2 425 bridge_ports enxe0db55e41d5b` 426 427 s.checkBridge(input, expected[1:], c, map[string]string{"enxe0db55e41d5b": "br-xe0db55e41d5b"}) 428 }