Test coverage on bridge
Signed-off-by: Arnaud Porterie <arnaud.porterie@docker.com>
This commit is contained in:
parent
8ca185e2ee
commit
3845ec20c4
|
@ -0,0 +1,53 @@
|
||||||
|
package bridge
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/docker/libnetwork"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestCreate(t *testing.T) {
|
||||||
|
defer libnetwork.SetupTestNetNS(t)()
|
||||||
|
|
||||||
|
config := &Configuration{BridgeName: DefaultBridgeName}
|
||||||
|
netw, err := Create(config)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Failed to create bridge: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if expected := NetworkType; netw.Type() != NetworkType {
|
||||||
|
t.Fatalf("Expected networkType %q, got %q", expected, netw.Type())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestCreateFail(t *testing.T) {
|
||||||
|
defer libnetwork.SetupTestNetNS(t)()
|
||||||
|
|
||||||
|
config := &Configuration{BridgeName: "dummy0"}
|
||||||
|
if _, err := Create(config); err == nil {
|
||||||
|
t.Fatal("Bridge creation was expected to fail")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestCreateFullOptions(t *testing.T) {
|
||||||
|
defer libnetwork.SetupTestNetNS(t)()
|
||||||
|
|
||||||
|
config := &Configuration{
|
||||||
|
BridgeName: DefaultBridgeName,
|
||||||
|
EnableIPv6: true,
|
||||||
|
FixedCIDR: bridgeNetworks[0],
|
||||||
|
EnableIPTables: true,
|
||||||
|
EnableIPForwarding: true,
|
||||||
|
}
|
||||||
|
_, config.FixedCIDRv6, _ = net.ParseCIDR("2001:db8::/48")
|
||||||
|
|
||||||
|
netw, err := Create(config)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Failed to create bridge: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if expected := NetworkType; netw.Type() != NetworkType {
|
||||||
|
t.Fatalf("Expected networkType %q, got %q", expected, netw.Type())
|
||||||
|
}
|
||||||
|
}
|
|
@ -44,5 +44,8 @@ func (i *Interface) Addresses() (netlink.Addr, []netlink.Addr, error) {
|
||||||
return netlink.Addr{}, nil, err
|
return netlink.Addr{}, nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if len(v4addr) == 0 {
|
||||||
|
return netlink.Addr{}, v6addr, nil
|
||||||
|
}
|
||||||
return v4addr[0], v6addr, nil
|
return v4addr[0], v6addr, nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,32 @@
|
||||||
|
package bridge
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/docker/libnetwork"
|
||||||
|
"github.com/vishvananda/netlink"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestInterfaceDefaultName(t *testing.T) {
|
||||||
|
defer libnetwork.SetupTestNetNS(t)()
|
||||||
|
|
||||||
|
if inf := NewInterface(&Configuration{}); inf.Config.BridgeName != DefaultBridgeName {
|
||||||
|
t.Fatalf("Expected default interface name %q, got %q", DefaultBridgeName, inf.Config.BridgeName)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestAddressesEmptyInterface(t *testing.T) {
|
||||||
|
defer libnetwork.SetupTestNetNS(t)()
|
||||||
|
|
||||||
|
inf := NewInterface(&Configuration{})
|
||||||
|
addrv4, addrsv6, err := inf.Addresses()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Failed to get addresses of default interface: %v", err)
|
||||||
|
}
|
||||||
|
if expected := (netlink.Addr{}); addrv4 != expected {
|
||||||
|
t.Fatalf("Default interface has unexpected IPv4: %s", addrv4)
|
||||||
|
}
|
||||||
|
if len(addrsv6) != 0 {
|
||||||
|
t.Fatalf("Default interface has unexpected IPv6: %v", addrsv6)
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,53 @@
|
||||||
|
package bridge
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestResolveConfRead(t *testing.T) {
|
||||||
|
b, err := readResolvConf()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Failed to read resolv.conf: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if b == nil {
|
||||||
|
t.Fatal("Reading resolv.conf returned no content")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestResolveConfReadLines(t *testing.T) {
|
||||||
|
commentChar := []byte("#")
|
||||||
|
|
||||||
|
b, _ := readResolvConf()
|
||||||
|
lines := getLines(b, commentChar)
|
||||||
|
if lines == nil {
|
||||||
|
t.Fatal("Failed to read resolv.conf lines")
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, line := range lines {
|
||||||
|
if bytes.Index(line, commentChar) != -1 {
|
||||||
|
t.Fatal("Returned comment content from resolv.conf")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestResolvConfNameserversAsCIDR(t *testing.T) {
|
||||||
|
resolvConf := `# Commented line
|
||||||
|
nameserver 1.2.3.4
|
||||||
|
|
||||||
|
nameserver 5.6.7.8 # Test
|
||||||
|
`
|
||||||
|
|
||||||
|
cidrs := getNameserversAsCIDR([]byte(resolvConf))
|
||||||
|
if expected := 2; len(cidrs) != expected {
|
||||||
|
t.Fatalf("Expected %d nameservers, got %d", expected, len(cidrs))
|
||||||
|
}
|
||||||
|
|
||||||
|
expected := []string{"1.2.3.4/32", "5.6.7.8/32"}
|
||||||
|
for i, exp := range expected {
|
||||||
|
if cidrs[i] != exp {
|
||||||
|
t.Fatalf("Expected nameservers %s, got %s", exp, cidrs[i])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,6 +1,8 @@
|
||||||
package bridge
|
package bridge
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
log "github.com/Sirupsen/logrus"
|
log "github.com/Sirupsen/logrus"
|
||||||
"github.com/docker/docker/daemon/networkdriver/ipallocator"
|
"github.com/docker/docker/daemon/networkdriver/ipallocator"
|
||||||
)
|
)
|
||||||
|
@ -12,5 +14,9 @@ func SetupFixedCIDRv4(i *Interface) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Debugf("Using IPv4 subnet: %v", i.Config.FixedCIDR)
|
log.Debugf("Using IPv4 subnet: %v", i.Config.FixedCIDR)
|
||||||
return ipallocator.RegisterSubnet(addrv4.IPNet, i.Config.FixedCIDR)
|
if err := ipallocator.RegisterSubnet(addrv4.IPNet, i.Config.FixedCIDR); err != nil {
|
||||||
|
return fmt.Errorf("Setup FixedCIDRv4 failed for subnet %s in %s: %v", i.Config.FixedCIDR, addrv4.IPNet, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,59 @@
|
||||||
|
package bridge
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/docker/docker/daemon/networkdriver/ipallocator"
|
||||||
|
"github.com/docker/libnetwork"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestSetupFixedCIDRv4(t *testing.T) {
|
||||||
|
defer libnetwork.SetupTestNetNS(t)()
|
||||||
|
|
||||||
|
br := &Interface{
|
||||||
|
Config: &Configuration{
|
||||||
|
BridgeName: DefaultBridgeName,
|
||||||
|
AddressIPv4: &net.IPNet{IP: net.ParseIP("192.168.1.1"), Mask: net.CIDRMask(16, 32)},
|
||||||
|
FixedCIDR: &net.IPNet{IP: net.ParseIP("192.168.2.0"), Mask: net.CIDRMask(24, 32)},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
if err := SetupDevice(br); err != nil {
|
||||||
|
t.Fatalf("Bridge creation failed: %v", err)
|
||||||
|
}
|
||||||
|
if err := SetupBridgeIPv4(br); err != nil {
|
||||||
|
t.Fatalf("Assign IPv4 to bridge failed: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := SetupFixedCIDRv4(br); err != nil {
|
||||||
|
t.Fatalf("Failed to setup bridge FixedCIDRv4: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if ip, err := ipallocator.RequestIP(br.Config.FixedCIDR, nil); err != nil {
|
||||||
|
t.Fatalf("Failed to request IP to allocator: %v", err)
|
||||||
|
} else if expected := "192.168.2.1"; ip.String() != expected {
|
||||||
|
t.Fatalf("Expected allocated IP %s, got %s", expected, ip)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestSetupBadFixedCIDRv4(t *testing.T) {
|
||||||
|
defer libnetwork.SetupTestNetNS(t)()
|
||||||
|
|
||||||
|
br := &Interface{
|
||||||
|
Config: &Configuration{
|
||||||
|
BridgeName: DefaultBridgeName,
|
||||||
|
AddressIPv4: &net.IPNet{IP: net.ParseIP("192.168.1.1"), Mask: net.CIDRMask(24, 32)},
|
||||||
|
FixedCIDR: &net.IPNet{IP: net.ParseIP("192.168.2.0"), Mask: net.CIDRMask(24, 32)},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
if err := SetupDevice(br); err != nil {
|
||||||
|
t.Fatalf("Bridge creation failed: %v", err)
|
||||||
|
}
|
||||||
|
if err := SetupBridgeIPv4(br); err != nil {
|
||||||
|
t.Fatalf("Assign IPv4 to bridge failed: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := SetupFixedCIDRv4(br); err == nil {
|
||||||
|
t.Fatal("Setup bridge FixedCIDRv4 should have failed")
|
||||||
|
}
|
||||||
|
}
|
|
@ -105,13 +105,11 @@ func checkRouteOverlaps(toCheck *net.IPNet) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func networkOverlaps(netX *net.IPNet, netY *net.IPNet) bool {
|
func networkOverlaps(netX *net.IPNet, netY *net.IPNet) bool {
|
||||||
if len(netX.IP) == len(netY.IP) {
|
if firstIP, _ := networkRange(netX); netY.Contains(firstIP) {
|
||||||
if firstIP, _ := networkRange(netX); netY.Contains(firstIP) {
|
return true
|
||||||
return true
|
}
|
||||||
}
|
if firstIP, _ := networkRange(netY); netX.Contains(firstIP) {
|
||||||
if firstIP, _ := networkRange(netY); netX.Contains(firstIP) {
|
return true
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,10 @@
|
||||||
package bridge
|
package bridge
|
||||||
|
|
||||||
import "fmt"
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/vishvananda/netlink"
|
||||||
|
)
|
||||||
|
|
||||||
func SetupVerifyConfiguredAddresses(i *Interface) error {
|
func SetupVerifyConfiguredAddresses(i *Interface) error {
|
||||||
// Fetch a single IPv4 and a slice of IPv6 addresses from the bridge.
|
// Fetch a single IPv4 and a slice of IPv6 addresses from the bridge.
|
||||||
|
@ -9,6 +13,11 @@ func SetupVerifyConfiguredAddresses(i *Interface) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Verify that the bridge does have an IPv4 address.
|
||||||
|
if addrv4.IPNet == nil {
|
||||||
|
return fmt.Errorf("Bridge has no IPv4 address configured")
|
||||||
|
}
|
||||||
|
|
||||||
// Verify that the bridge IPv4 address matches the requested configuration.
|
// Verify that the bridge IPv4 address matches the requested configuration.
|
||||||
if i.Config.AddressIPv4 != nil && !addrv4.IP.Equal(i.Config.AddressIPv4.IP) {
|
if i.Config.AddressIPv4 != nil && !addrv4.IP.Equal(i.Config.AddressIPv4.IP) {
|
||||||
return fmt.Errorf("Bridge IPv4 (%s) does not match requested configuration %s", addrv4.IP, i.Config.AddressIPv4.IP)
|
return fmt.Errorf("Bridge IPv4 (%s) does not match requested configuration %s", addrv4.IP, i.Config.AddressIPv4.IP)
|
||||||
|
@ -16,11 +25,18 @@ func SetupVerifyConfiguredAddresses(i *Interface) error {
|
||||||
|
|
||||||
// Verify that one of the bridge IPv6 addresses matches the requested
|
// Verify that one of the bridge IPv6 addresses matches the requested
|
||||||
// configuration.
|
// configuration.
|
||||||
for _, addrv6 := range addrsv6 {
|
if i.Config.EnableIPv6 && !findIPv6Address(netlink.Addr{IPNet: BridgeIPv6}, addrsv6) {
|
||||||
if addrv6.String() == BridgeIPv6.String() {
|
return fmt.Errorf("Bridge IPv6 addresses do not match the expected bridge configuration %s", BridgeIPv6)
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return fmt.Errorf("Bridge IPv6 addresses do not match the expected bridge configuration %s", BridgeIPv6)
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func findIPv6Address(addr netlink.Addr, addresses []netlink.Addr) bool {
|
||||||
|
for _, addrv6 := range addresses {
|
||||||
|
if addrv6.String() == addr.String() {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,105 @@
|
||||||
|
package bridge
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/docker/libnetwork"
|
||||||
|
"github.com/vishvananda/netlink"
|
||||||
|
)
|
||||||
|
|
||||||
|
func setupVerifyTest(t *testing.T) *Interface {
|
||||||
|
inf := &Interface{Config: &Configuration{}}
|
||||||
|
|
||||||
|
br := netlink.Bridge{}
|
||||||
|
br.LinkAttrs.Name = "default0"
|
||||||
|
if err := netlink.LinkAdd(&br); err == nil {
|
||||||
|
inf.Link = &br
|
||||||
|
} else {
|
||||||
|
t.Fatalf("Failed to create bridge interface: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return inf
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestSetupVerify(t *testing.T) {
|
||||||
|
defer libnetwork.SetupTestNetNS(t)()
|
||||||
|
|
||||||
|
addrv4 := net.IPv4(192, 168, 1, 1)
|
||||||
|
inf := setupVerifyTest(t)
|
||||||
|
inf.Config.AddressIPv4 = &net.IPNet{IP: addrv4, Mask: addrv4.DefaultMask()}
|
||||||
|
|
||||||
|
if err := netlink.AddrAdd(inf.Link, &netlink.Addr{IPNet: inf.Config.AddressIPv4}); err != nil {
|
||||||
|
t.Fatalf("Failed to assign IPv4 %s to interface: %v", inf.Config.AddressIPv4, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := SetupVerifyConfiguredAddresses(inf); err != nil {
|
||||||
|
t.Fatalf("Address verification failed: %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestSetupVerifyBad(t *testing.T) {
|
||||||
|
defer libnetwork.SetupTestNetNS(t)()
|
||||||
|
|
||||||
|
addrv4 := net.IPv4(192, 168, 1, 1)
|
||||||
|
inf := setupVerifyTest(t)
|
||||||
|
inf.Config.AddressIPv4 = &net.IPNet{IP: addrv4, Mask: addrv4.DefaultMask()}
|
||||||
|
|
||||||
|
ipnet := &net.IPNet{IP: net.IPv4(192, 168, 1, 2), Mask: addrv4.DefaultMask()}
|
||||||
|
if err := netlink.AddrAdd(inf.Link, &netlink.Addr{IPNet: ipnet}); err != nil {
|
||||||
|
t.Fatalf("Failed to assign IPv4 %s to interface: %v", ipnet, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := SetupVerifyConfiguredAddresses(inf); err == nil {
|
||||||
|
t.Fatal("Address verification was expected to fail")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestSetupVerifyMissing(t *testing.T) {
|
||||||
|
defer libnetwork.SetupTestNetNS(t)()
|
||||||
|
|
||||||
|
addrv4 := net.IPv4(192, 168, 1, 1)
|
||||||
|
inf := setupVerifyTest(t)
|
||||||
|
inf.Config.AddressIPv4 = &net.IPNet{IP: addrv4, Mask: addrv4.DefaultMask()}
|
||||||
|
|
||||||
|
if err := SetupVerifyConfiguredAddresses(inf); err == nil {
|
||||||
|
t.Fatal("Address verification was expected to fail")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestSetupVerifyIPv6(t *testing.T) {
|
||||||
|
defer libnetwork.SetupTestNetNS(t)()
|
||||||
|
|
||||||
|
addrv4 := net.IPv4(192, 168, 1, 1)
|
||||||
|
inf := setupVerifyTest(t)
|
||||||
|
inf.Config.AddressIPv4 = &net.IPNet{IP: addrv4, Mask: addrv4.DefaultMask()}
|
||||||
|
inf.Config.EnableIPv6 = true
|
||||||
|
|
||||||
|
if err := netlink.AddrAdd(inf.Link, &netlink.Addr{IPNet: BridgeIPv6}); err != nil {
|
||||||
|
t.Fatalf("Failed to assign IPv6 %s to interface: %v", BridgeIPv6, err)
|
||||||
|
}
|
||||||
|
if err := netlink.AddrAdd(inf.Link, &netlink.Addr{IPNet: inf.Config.AddressIPv4}); err != nil {
|
||||||
|
t.Fatalf("Failed to assign IPv4 %s to interface: %v", inf.Config.AddressIPv4, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := SetupVerifyConfiguredAddresses(inf); err != nil {
|
||||||
|
t.Fatalf("Address verification failed: %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestSetupVerifyIPv6Missing(t *testing.T) {
|
||||||
|
defer libnetwork.SetupTestNetNS(t)()
|
||||||
|
|
||||||
|
addrv4 := net.IPv4(192, 168, 1, 1)
|
||||||
|
inf := setupVerifyTest(t)
|
||||||
|
inf.Config.AddressIPv4 = &net.IPNet{IP: addrv4, Mask: addrv4.DefaultMask()}
|
||||||
|
inf.Config.EnableIPv6 = true
|
||||||
|
|
||||||
|
if err := netlink.AddrAdd(inf.Link, &netlink.Addr{IPNet: inf.Config.AddressIPv4}); err != nil {
|
||||||
|
t.Fatalf("Failed to assign IPv4 %s to interface: %v", inf.Config.AddressIPv4, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := SetupVerifyConfiguredAddresses(inf); err == nil {
|
||||||
|
t.Fatal("Address verification was expected to fail")
|
||||||
|
}
|
||||||
|
}
|
|
@ -17,7 +17,7 @@
|
||||||
// // For each new container: allocate IP and interfaces. The returned network
|
// // For each new container: allocate IP and interfaces. The returned network
|
||||||
// // settings will be used for container infos (inspect and such), as well as
|
// // settings will be used for container infos (inspect and such), as well as
|
||||||
// // iptables rules for port publishing.
|
// // iptables rules for port publishing.
|
||||||
// interfaces, err := network.CreateInterfaces(containerID)
|
// interfaces, err := network.Link(containerID)
|
||||||
// if err != nil {
|
// if err != nil {
|
||||||
// return err
|
// return err
|
||||||
// }
|
// }
|
||||||
|
|
Loading…
Reference in New Issue