Move port mapper tests out of core and into portmapper

Docker-DCO-1.1-Signed-off-by: Michael Crosby <michael@crosbymichael.com> (github: crosbymichael)
This commit is contained in:
Michael Crosby 2014-01-28 16:28:32 -08:00
Родитель 99756ef11f
Коммит b3b12f0059
5 изменённых файлов: 136 добавлений и 89 удалений

Просмотреть файл

@ -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{

Просмотреть файл

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

Просмотреть файл

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

Просмотреть файл

@ -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
proxy/stub_proxy.go Normal file
Просмотреть файл

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