github.com/schwarzm/garden-linux@v0.0.0-20150507151835-33bca2147c47/network/devices/link_linux_test.go (about) 1 package devices_test 2 3 import ( 4 "fmt" 5 "net" 6 "os/exec" 7 "strconv" 8 "strings" 9 10 "github.com/cloudfoundry-incubator/garden-linux/network/devices" 11 "github.com/docker/libcontainer/netlink" 12 . "github.com/onsi/ginkgo" 13 . "github.com/onsi/gomega" 14 "github.com/onsi/gomega/gexec" 15 ) 16 17 var _ = Describe("Link Management", func() { 18 var ( 19 l devices.Link 20 name string 21 intf *net.Interface 22 ) 23 24 BeforeEach(func() { 25 name = fmt.Sprintf("gdn-test-%d", GinkgoParallelNode()) 26 Expect(netlink.NetworkLinkAdd(name, "dummy")).To(Succeed()) 27 intf, _ = net.InterfaceByName(name) 28 }) 29 30 AfterEach(func() { 31 cleanup(name) 32 }) 33 34 Describe("AddIP", func() { 35 Context("when the interface exists", func() { 36 It("adds the IP succesffuly", func() { 37 ip, subnet, _ := net.ParseCIDR("1.2.3.4/5") 38 Expect(l.AddIP(intf, ip, subnet)).To(Succeed()) 39 40 intf, err := net.InterfaceByName(name) 41 Expect(err).ToNot(HaveOccurred()) 42 addrs, err := intf.Addrs() 43 Expect(err).ToNot(HaveOccurred()) 44 45 Expect(addrs).To(HaveLen(1)) 46 Expect(addrs[0].String()).To(Equal("1.2.3.4/5")) 47 }) 48 }) 49 }) 50 51 Describe("SetUp", func() { 52 Context("when the interface does not exist", func() { 53 It("returns an error", func() { 54 Expect(l.SetUp(&net.Interface{Name: "something"})).ToNot(Succeed()) 55 }) 56 }) 57 58 Context("when the interface exists", func() { 59 Context("and it is down", func() { 60 It("should bring the interface up", func() { 61 Expect(l.SetUp(intf)).To(Succeed()) 62 63 intf, err := net.InterfaceByName(name) 64 Expect(err).ToNot(HaveOccurred()) 65 Expect(intf.Flags & net.FlagUp).To(Equal(net.FlagUp)) 66 }) 67 }) 68 69 Context("and it is already up", func() { 70 It("should still succeed", func() { 71 Expect(l.SetUp(intf)).To(Succeed()) 72 Expect(l.SetUp(intf)).To(Succeed()) 73 74 intf, err := net.InterfaceByName(name) 75 Expect(err).ToNot(HaveOccurred()) 76 Expect(intf.Flags & net.FlagUp).To(Equal(net.FlagUp)) 77 }) 78 }) 79 }) 80 }) 81 82 Describe("SetMTU", func() { 83 Context("when the interface does not exist", func() { 84 It("returns an error", func() { 85 Expect(l.SetMTU(&net.Interface{Name: "something"}, 1234)).ToNot(Succeed()) 86 }) 87 }) 88 89 Context("when the interface exists", func() { 90 It("sets the mtu", func() { 91 Expect(l.SetMTU(intf, 1234)).To(Succeed()) 92 93 intf, err := net.InterfaceByName(name) 94 Expect(err).ToNot(HaveOccurred()) 95 Expect(intf.MTU).To(Equal(1234)) 96 }) 97 }) 98 }) 99 100 Describe("SetNs", func() { 101 BeforeEach(func() { 102 cmd, err := gexec.Start(exec.Command("sh", "-c", "mount -n -t tmpfs tmpfs /sys; ip netns add gdnsetnstest"), GinkgoWriter, GinkgoWriter) 103 Expect(err).ToNot(HaveOccurred()) 104 Eventually(cmd).Should(gexec.Exit(0)) 105 }) 106 107 AfterEach(func() { 108 cmd, err := gexec.Start(exec.Command("sh", "-c", "ip netns delete gdnsetnstest; umount /sys"), GinkgoWriter, GinkgoWriter) 109 Expect(err).ToNot(HaveOccurred()) 110 Eventually(cmd).Should(gexec.Exit(0)) 111 }) 112 113 It("moves the interface in to the given namespace by pid", func() { 114 // look at this perfectly ordinary hat 115 netns, err := gexec.Start(exec.Command("ip", "netns", "exec", "gdnsetnstest", "sleep", "6312736"), GinkgoWriter, GinkgoWriter) 116 Expect(err).ToNot(HaveOccurred()) 117 defer netns.Kill() 118 119 // (it has the following pid) 120 ps, err := gexec.Start(exec.Command("sh", "-c", "ps -A -opid,command | grep 'sleep 6312736' | head -n 1 | awk '{print $1}'"), GinkgoWriter, GinkgoWriter) // look at my hat 121 Expect(err).ToNot(HaveOccurred()) 122 Eventually(ps).Should(gexec.Exit(0)) 123 pid, err := strconv.Atoi(strings.TrimSuffix(string(ps.Out.Contents()), "\n")) 124 Expect(err).ToNot(HaveOccurred()) 125 126 // I wave the magic wand 127 Expect(l.SetNs(intf, pid)).To(Succeed()) 128 129 // the bunny has vanished! where is the bunny? 130 intfs, _ := net.Interfaces() 131 Expect(intfs).ToNot(ContainElement(intf)) 132 133 // oh my word it's in the hat! 134 session, err := gexec.Start(exec.Command("sh", "-c", fmt.Sprintf("ip netns exec gdnsetnstest ifconfig %s", name)), GinkgoWriter, GinkgoWriter) 135 Expect(err).ToNot(HaveOccurred()) 136 Eventually(session).Should(gexec.Exit(0)) 137 138 }) 139 }) 140 141 Describe("InterfaceByName", func() { 142 Context("when the interface exists", func() { 143 It("returns the interface with the given name, and true", func() { 144 returnedIntf, found, err := l.InterfaceByName(name) 145 Expect(err).ToNot(HaveOccurred()) 146 147 Expect(returnedIntf).To(Equal(intf)) 148 Expect(found).To(BeTrue()) 149 }) 150 }) 151 152 Context("when the interface does not exist", func() { 153 It("does not return an error", func() { 154 _, found, err := l.InterfaceByName("sandwich") 155 Expect(err).ToNot(HaveOccurred()) 156 Expect(found).To(BeFalse()) 157 }) 158 }) 159 }) 160 161 Describe("List", func() { 162 It("lists all the interfaces", func() { 163 names, err := l.List() 164 Expect(err).ToNot(HaveOccurred()) 165 166 Expect(names).To(ContainElement(name)) 167 }) 168 }) 169 })