فهرست منبع

Move port mapper tests out of core and into portmapper

Docker-DCO-1.1-Signed-off-by: Michael Crosby <michael@crosbymichael.com> (github: crosbymichael)
Michael Crosby 11 سال پیش
والد
کامیت
b3b12f0059
5فایلهای تغییر یافته به همراه136 افزوده شده و 89 حذف شده
  1. 4 2
      network.go
  2. 0 72
      network_test.go
  3. 3 15
      networkdriver/portmapper/mapper.go
  4. 107 0
      networkdriver/portmapper/mapper_test.go
  5. 22 0
      proxy/stub_proxy.go

+ 4 - 2
network.go

@@ -392,14 +392,16 @@ func newNetworkManager(config *DaemonConfig) (*NetworkManager, error) {
 	}
 
 	// We can always try removing the iptables
-	if err := portmapper.RemoveIpTablesChain("DOCKER"); err != nil {
+	if err := iptables.RemoveExistingChain("DOCKER"); err != nil {
 		return nil, err
 	}
 
 	if config.EnableIptables {
-		if err := portmapper.RegisterIpTablesChain("DOCKER", config.BridgeIface); err != nil {
+		chain, err := iptables.NewChain("DOCKER", config.BridgeIface)
+		if err != nil {
 			return nil, err
 		}
+		portmapper.SetIptablesChain(chain)
 	}
 
 	manager := &NetworkManager{

+ 0 - 72
network_test.go

@@ -1,72 +0,0 @@
-package docker
-
-import (
-	"github.com/dotcloud/docker/pkg/iptables"
-	"github.com/dotcloud/docker/proxy"
-	"net"
-	"testing"
-)
-
-type StubProxy struct {
-	frontendAddr *net.Addr
-	backendAddr  *net.Addr
-}
-
-func (proxy *StubProxy) Run()                   {}
-func (proxy *StubProxy) Close()                 {}
-func (proxy *StubProxy) FrontendAddr() net.Addr { return *proxy.frontendAddr }
-func (proxy *StubProxy) BackendAddr() net.Addr  { return *proxy.backendAddr }
-
-func NewStubProxy(frontendAddr, backendAddr net.Addr) (proxy.Proxy, error) {
-	return &StubProxy{
-		frontendAddr: &frontendAddr,
-		backendAddr:  &backendAddr,
-	}, nil
-}
-
-func TestPortMapper(t *testing.T) {
-	// FIXME: is this iptables chain still used anywhere?
-	var chain *iptables.Chain
-	mapper := &PortMapper{
-		tcpMapping:       make(map[string]*net.TCPAddr),
-		tcpProxies:       make(map[string]proxy.Proxy),
-		udpMapping:       make(map[string]*net.UDPAddr),
-		udpProxies:       make(map[string]proxy.Proxy),
-		iptables:         chain,
-		defaultIp:        net.IP("0.0.0.0"),
-		proxyFactoryFunc: NewStubProxy,
-	}
-
-	dstIp1 := net.ParseIP("192.168.0.1")
-	dstIp2 := net.ParseIP("192.168.0.2")
-	srcAddr1 := &net.TCPAddr{Port: 1080, IP: net.ParseIP("172.16.0.1")}
-	srcAddr2 := &net.TCPAddr{Port: 1080, IP: net.ParseIP("172.16.0.2")}
-
-	if err := mapper.Map(dstIp1, 80, srcAddr1); err != nil {
-		t.Fatalf("Failed to allocate port: %s", err)
-	}
-
-	if mapper.Map(dstIp1, 80, srcAddr1) == nil {
-		t.Fatalf("Port is in use - mapping should have failed")
-	}
-
-	if mapper.Map(dstIp1, 80, srcAddr2) == nil {
-		t.Fatalf("Port is in use - mapping should have failed")
-	}
-
-	if err := mapper.Map(dstIp2, 80, srcAddr2); err != nil {
-		t.Fatalf("Failed to allocate port: %s", err)
-	}
-
-	if mapper.Unmap(dstIp1, 80, "tcp") != nil {
-		t.Fatalf("Failed to release port")
-	}
-
-	if mapper.Unmap(dstIp2, 80, "tcp") != nil {
-		t.Fatalf("Failed to release port")
-	}
-
-	if mapper.Unmap(dstIp2, 80, "tcp") == nil {
-		t.Fatalf("Port already released, but no error reported")
-	}
-}

+ 3 - 15
networkdriver/portmapper/mapper.go

@@ -22,6 +22,7 @@ var (
 
 	// udp:ip:port
 	currentMappings = make(map[string]*mapping)
+	newProxy        = proxy.NewProxy
 )
 
 var (
@@ -30,21 +31,8 @@ var (
 	ErrPortNotMapped             = errors.New("port is not mapped")
 )
 
-func RegisterIpTablesChain(name, bridge string) error {
-	c, err := iptables.NewChain(name, bridge)
-	if err != nil {
-		return fmt.Errorf("failed to create %s chain: %s", name, err)
-	}
+func SetIptablesChain(c *iptables.Chain) {
 	chain = c
-	return nil
-}
-
-func RemoveIpTablesChain(name string) error {
-	if err := iptables.RemoveExistingChain(name); err != nil {
-		return err
-	}
-	chain = nil
-	return nil
 }
 
 func Map(container net.Addr, hostIP net.IP, hostPort int) error {
@@ -79,7 +67,7 @@ func Map(container net.Addr, hostIP net.IP, hostPort int) error {
 		return err
 	}
 
-	p, err := proxy.NewProxy(m.host, m.container)
+	p, err := newProxy(m.host, m.container)
 	if err != nil {
 		// need to undo the iptables rules before we reutrn
 		forward(iptables.Delete, m.proto, hostIP, hostPort, containerIP.String(), containerPort)

+ 107 - 0
networkdriver/portmapper/mapper_test.go

@@ -0,0 +1,107 @@
+package portmapper
+
+import (
+	"github.com/dotcloud/docker/pkg/iptables"
+	"github.com/dotcloud/docker/proxy"
+	"net"
+	"testing"
+)
+
+func init() {
+	// override this func to mock out the proxy server
+	newProxy = proxy.NewStubProxy
+}
+
+func reset() {
+	chain = nil
+	currentMappings = make(map[string]*mapping)
+}
+
+func TestSetIptablesChain(t *testing.T) {
+	defer reset()
+
+	c := &iptables.Chain{
+		Name:   "TEST",
+		Bridge: "192.168.1.1",
+	}
+
+	if chain != nil {
+		t.Fatal("chain should be nil at init")
+	}
+
+	SetIptablesChain(c)
+	if chain == nil {
+		t.Fatal("chain should not be nil after set")
+	}
+}
+
+func TestMapPorts(t *testing.T) {
+	dstIp1 := net.ParseIP("192.168.0.1")
+	dstIp2 := net.ParseIP("192.168.0.2")
+	dstAddr1 := &net.TCPAddr{IP: dstIp1, Port: 80}
+	dstAddr2 := &net.TCPAddr{IP: dstIp2, Port: 80}
+
+	srcAddr1 := &net.TCPAddr{Port: 1080, IP: net.ParseIP("172.16.0.1")}
+	srcAddr2 := &net.TCPAddr{Port: 1080, IP: net.ParseIP("172.16.0.2")}
+
+	if err := Map(srcAddr1, dstIp1, 80); err != nil {
+		t.Fatalf("Failed to allocate port: %s", err)
+	}
+
+	if Map(srcAddr1, dstIp1, 80) == nil {
+		t.Fatalf("Port is in use - mapping should have failed")
+	}
+
+	if Map(srcAddr2, dstIp1, 80) == nil {
+		t.Fatalf("Port is in use - mapping should have failed")
+	}
+
+	if err := Map(srcAddr2, dstIp2, 80); err != nil {
+		t.Fatalf("Failed to allocate port: %s", err)
+	}
+
+	if Unmap(dstAddr1) != nil {
+		t.Fatalf("Failed to release port")
+	}
+
+	if Unmap(dstAddr2) != nil {
+		t.Fatalf("Failed to release port")
+	}
+
+	if Unmap(dstAddr2) == nil {
+		t.Fatalf("Port already released, but no error reported")
+	}
+}
+
+func TestGetUDPKey(t *testing.T) {
+	addr := &net.UDPAddr{IP: net.ParseIP("192.168.1.5"), Port: 53}
+
+	key := getKey(addr)
+
+	if expected := "192.168.1.5:53/udp"; key != expected {
+		t.Fatalf("expected key %s got %s", expected, key)
+	}
+}
+
+func TestGetTCPKey(t *testing.T) {
+	addr := &net.TCPAddr{IP: net.ParseIP("192.168.1.5"), Port: 80}
+
+	key := getKey(addr)
+
+	if expected := "192.168.1.5:80/tcp"; key != expected {
+		t.Fatalf("expected key %s got %s", expected, key)
+	}
+}
+
+func TestGetUDPIPAndPort(t *testing.T) {
+	addr := &net.UDPAddr{IP: net.ParseIP("192.168.1.5"), Port: 53}
+
+	ip, port := getIPAndPort(addr)
+	if expected := "192.168.1.5"; ip.String() != expected {
+		t.Fatalf("expected ip %s got %s", expected, ip)
+	}
+
+	if ep := 53; port != ep {
+		t.Fatalf("expected port %d got %d", ep, port)
+	}
+}

+ 22 - 0
proxy/stub_proxy.go

@@ -0,0 +1,22 @@
+package proxy
+
+import (
+	"net"
+)
+
+type StubProxy struct {
+	frontendAddr net.Addr
+	backendAddr  net.Addr
+}
+
+func (p *StubProxy) Run()                   {}
+func (p *StubProxy) Close()                 {}
+func (p *StubProxy) FrontendAddr() net.Addr { return p.frontendAddr }
+func (p *StubProxy) BackendAddr() net.Addr  { return p.backendAddr }
+
+func NewStubProxy(frontendAddr, backendAddr net.Addr) (Proxy, error) {
+	return &StubProxy{
+		frontendAddr: frontendAddr,
+		backendAddr:  backendAddr,
+	}, nil
+}