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  })