github.com/geofffranks/garden-linux@v0.0.0-20160715111146-26c893169cfa/network/devices/bridge_linux_test.go (about) 1 package devices_test 2 3 import ( 4 "fmt" 5 "io/ioutil" 6 "net" 7 8 "code.cloudfoundry.org/garden-linux/network/devices" 9 . "github.com/onsi/ginkgo" 10 . "github.com/onsi/gomega" 11 ) 12 13 var _ = Describe("Bridge Management", func() { 14 var ( 15 b devices.Bridge 16 name string 17 addr string 18 ip net.IP 19 subnet *net.IPNet 20 ) 21 22 BeforeEach(func() { 23 name = fmt.Sprintf("gdn-test-intf-%d", GinkgoParallelNode()) 24 25 var err error 26 addr = "10.9.0.1/30" 27 ip, subnet, err = net.ParseCIDR(addr) 28 Expect(err).ToNot(HaveOccurred()) 29 }) 30 31 AfterEach(func() { 32 cleanup(name) 33 }) 34 35 Describe("Create", func() { 36 Context("when the bridge does not already exist", func() { 37 It("creates a bridge", func() { 38 _, err := b.Create(name, ip, subnet) 39 Expect(err).ToNot(HaveOccurred()) 40 }) 41 42 It("sets the bridge name", func() { 43 bridge, err := b.Create(name, ip, subnet) 44 Expect(err).ToNot(HaveOccurred()) 45 46 Expect(bridge.Name).To(Equal(name)) 47 }) 48 49 It("assigns a mac address so that the bridge address does not change", func() { 50 _, err := b.Create(name, ip, subnet) 51 Expect(err).ToNot(HaveOccurred()) 52 53 // 1 means the kernel auto-assigns a mac address based on the lowest-attached 54 // device. This is bad because it can change (!) when devices are added/removed 55 // and mess stuff up. 3 means we assigned an explicit address so this shouldnt happen. 56 Expect(ioutil.ReadFile(fmt.Sprintf("/sys/class/net/%s/addr_assign_type", name))).To(Equal([]byte("3\n"))) 57 }) 58 59 It("sets the bridge address", func() { 60 bridge, err := b.Create(name, ip, subnet) 61 Expect(err).ToNot(HaveOccurred()) 62 63 addrs, err := bridge.Addrs() 64 Expect(err).ToNot(HaveOccurred()) 65 66 Expect(addrs).To(HaveLen(1)) 67 Expect(addrs[0].String()).To(Equal(addr)) 68 }) 69 }) 70 71 Context("when the bridge exists", func() { 72 var ( 73 existingIfc *net.Interface 74 ) 75 BeforeEach(func() { 76 var err error 77 existingIfc, err = b.Create(name, ip, subnet) 78 Expect(err).ToNot(HaveOccurred()) 79 }) 80 81 It("returns the interface for it", func() { 82 ifc, err := b.Create(name, ip, subnet) 83 Expect(err).ToNot(HaveOccurred()) 84 Expect(ifc).To(Equal(existingIfc)) 85 }) 86 87 It("does not change the existing bridge", func() { 88 ip2, subnet2, _ := net.ParseCIDR("10.8.0.2/30") 89 _, err := b.Create(name, ip2, subnet2) 90 Expect(err).ToNot(HaveOccurred()) 91 92 intf, err := net.InterfaceByName(name) 93 Expect(err).ToNot(HaveOccurred()) 94 95 addrs, err := intf.Addrs() 96 Expect(err).ToNot(HaveOccurred()) 97 98 Expect(addrs[0].String()).To(Equal(addr)) 99 }) 100 }) 101 }) 102 103 Describe("Destroy", func() { 104 Context("when the bridge exists", func() { 105 It("deletes it", func() { 106 br, err := b.Create(name, ip, subnet) 107 Expect(err).ToNot(HaveOccurred()) 108 109 // sanity check 110 Expect(interfaceNames()).To(ContainElement(name)) 111 112 // delete 113 Expect(b.Destroy(br.Name)).To(Succeed()) 114 115 // should be gone 116 Eventually(interfaceNames).ShouldNot(ContainElement(name)) 117 }) 118 }) 119 120 Context("when the bridge does not exist", func() { 121 It("does not return an error (because Destroy should be idempotent)", func() { 122 Expect(b.Destroy("something")).To(Succeed()) 123 }) 124 }) 125 }) 126 }) 127 128 func interfaceNames() []string { 129 intfs, err := net.Interfaces() 130 Expect(err).ToNot(HaveOccurred()) 131 132 v := make([]string, 0) 133 for _, i := range intfs { 134 v = append(v, i.Name) 135 } 136 137 return v 138 }