github.com/squaremo/docker@v1.3.2-0.20150516120342-42cfc9554972/daemon/networkdriver/bridge/driver_test.go (about) 1 package bridge 2 3 import ( 4 "fmt" 5 "net" 6 "strconv" 7 "testing" 8 9 "github.com/docker/docker/daemon/network" 10 "github.com/docker/docker/daemon/networkdriver/portmapper" 11 "github.com/docker/docker/nat" 12 "github.com/docker/docker/pkg/iptables" 13 ) 14 15 func init() { 16 // reset the new proxy command for mocking out the userland proxy in tests 17 portmapper.NewProxy = portmapper.NewMockProxyCommand 18 } 19 20 func findFreePort(t *testing.T) string { 21 l, err := net.Listen("tcp", ":0") 22 if err != nil { 23 t.Fatal("Failed to find a free port") 24 } 25 defer l.Close() 26 27 result, err := net.ResolveTCPAddr("tcp", l.Addr().String()) 28 if err != nil { 29 t.Fatal("Failed to resolve address to identify free port") 30 } 31 return strconv.Itoa(result.Port) 32 } 33 34 func TestAllocatePortDetection(t *testing.T) { 35 freePort := findFreePort(t) 36 37 if err := InitDriver(new(Config)); err != nil { 38 t.Fatal("Failed to initialize network driver") 39 } 40 41 // Allocate interface 42 if _, err := Allocate("container_id", "", "", ""); err != nil { 43 t.Fatal("Failed to allocate network interface") 44 } 45 46 port := nat.Port(freePort + "/tcp") 47 binding := nat.PortBinding{HostIp: "127.0.0.1", HostPort: freePort} 48 49 // Allocate same port twice, expect failure on second call 50 if _, err := AllocatePort("container_id", port, binding); err != nil { 51 t.Fatal("Failed to find a free port to allocate") 52 } 53 if _, err := AllocatePort("container_id", port, binding); err == nil { 54 t.Fatal("Duplicate port allocation granted by AllocatePort") 55 } 56 } 57 58 func TestHostnameFormatChecking(t *testing.T) { 59 freePort := findFreePort(t) 60 61 if err := InitDriver(new(Config)); err != nil { 62 t.Fatal("Failed to initialize network driver") 63 } 64 65 // Allocate interface 66 if _, err := Allocate("container_id", "", "", ""); err != nil { 67 t.Fatal("Failed to allocate network interface") 68 } 69 70 port := nat.Port(freePort + "/tcp") 71 binding := nat.PortBinding{HostIp: "localhost", HostPort: freePort} 72 73 if _, err := AllocatePort("container_id", port, binding); err == nil { 74 t.Fatal("Failed to check invalid HostIP") 75 } 76 } 77 78 func newInterfaceAllocation(t *testing.T, globalIPv6 *net.IPNet, requestedMac, requestedIP, requestedIPv6 string, expectFail bool) *network.Settings { 79 // set IPv6 global if given 80 if globalIPv6 != nil { 81 globalIPv6Network = globalIPv6 82 } 83 84 networkSettings, err := Allocate("container_id", requestedMac, requestedIP, requestedIPv6) 85 if err == nil && expectFail { 86 t.Fatal("Doesn't fail to allocate network interface") 87 } else if err != nil && !expectFail { 88 t.Fatal("Failed to allocate network interface") 89 90 } 91 92 if globalIPv6 != nil { 93 // check for bug #11427 94 if globalIPv6Network.IP.String() != globalIPv6.IP.String() { 95 t.Fatal("globalIPv6Network was modified during allocation") 96 } 97 // clean up IPv6 global 98 globalIPv6Network = nil 99 } 100 101 return networkSettings 102 } 103 104 func TestIPv6InterfaceAllocationAutoNetmaskGt80(t *testing.T) { 105 _, subnet, _ := net.ParseCIDR("2001:db8:1234:1234:1234::/81") 106 networkSettings := newInterfaceAllocation(t, subnet, "", "", "", false) 107 108 // ensure low manually assigend global ip 109 ip := net.ParseIP(networkSettings.GlobalIPv6Address) 110 _, subnet, _ = net.ParseCIDR(fmt.Sprintf("%s/%d", subnet.IP.String(), 120)) 111 if !subnet.Contains(ip) { 112 t.Fatalf("Error ip %s not in subnet %s", ip.String(), subnet.String()) 113 } 114 } 115 116 func TestIPv6InterfaceAllocationAutoNetmaskLe80(t *testing.T) { 117 _, subnet, _ := net.ParseCIDR("2001:db8:1234:1234:1234::/80") 118 networkSettings := newInterfaceAllocation(t, subnet, "ab:cd:ab:cd:ab:cd", "", "", false) 119 120 // ensure global ip with mac 121 ip := net.ParseIP(networkSettings.GlobalIPv6Address) 122 expectedIP := net.ParseIP("2001:db8:1234:1234:1234:abcd:abcd:abcd") 123 if ip.String() != expectedIP.String() { 124 t.Fatalf("Error ip %s should be %s", ip.String(), expectedIP.String()) 125 } 126 127 // ensure link local format 128 ip = net.ParseIP(networkSettings.LinkLocalIPv6Address) 129 expectedIP = net.ParseIP("fe80::a9cd:abff:fecd:abcd") 130 if ip.String() != expectedIP.String() { 131 t.Fatalf("Error ip %s should be %s", ip.String(), expectedIP.String()) 132 } 133 134 } 135 136 func TestIPv6InterfaceAllocationRequest(t *testing.T) { 137 _, subnet, _ := net.ParseCIDR("2001:db8:1234:1234:1234::/80") 138 expectedIP := "2001:db8:1234:1234:1234::1328" 139 140 networkSettings := newInterfaceAllocation(t, subnet, "", "", expectedIP, false) 141 142 // ensure global ip with mac 143 ip := net.ParseIP(networkSettings.GlobalIPv6Address) 144 if ip.String() != expectedIP { 145 t.Fatalf("Error ip %s should be %s", ip.String(), expectedIP) 146 } 147 148 // retry -> fails for duplicated address 149 _ = newInterfaceAllocation(t, subnet, "", "", expectedIP, true) 150 } 151 152 func TestMacAddrGeneration(t *testing.T) { 153 ip := net.ParseIP("192.168.0.1") 154 mac := generateMacAddr(ip).String() 155 156 // Should be consistent. 157 if generateMacAddr(ip).String() != mac { 158 t.Fatal("Inconsistent MAC address") 159 } 160 161 // Should be unique. 162 ip2 := net.ParseIP("192.168.0.2") 163 if generateMacAddr(ip2).String() == mac { 164 t.Fatal("Non-unique MAC address") 165 } 166 } 167 168 func TestLinkContainers(t *testing.T) { 169 // Init driver 170 if err := InitDriver(new(Config)); err != nil { 171 t.Fatal("Failed to initialize network driver") 172 } 173 174 // Allocate interface 175 if _, err := Allocate("container_id", "", "", ""); err != nil { 176 t.Fatal("Failed to allocate network interface") 177 } 178 179 bridgeIface = "lo" 180 if _, err := iptables.NewChain("DOCKER", bridgeIface, iptables.Filter, false); err != nil { 181 t.Fatal(err) 182 } 183 184 if err := LinkContainers("-I", "172.17.0.1", "172.17.0.2", []nat.Port{nat.Port("1234")}, false); err != nil { 185 t.Fatal("LinkContainers failed") 186 } 187 188 // flush rules 189 if _, err := iptables.Raw([]string{"-F", "DOCKER"}...); err != nil { 190 t.Fatal(err) 191 } 192 193 }