1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
|
package bridge
import (
"fmt"
"net"
"strconv"
"testing"
"github.com/dotcloud/docker/engine"
)
func findFreePort(t *testing.T) int {
l, err := net.Listen("tcp", ":0")
if err != nil {
t.Fatal("Failed to find a free port")
}
defer l.Close()
result, err := net.ResolveTCPAddr("tcp", l.Addr().String())
if err != nil {
t.Fatal("Failed to resolve address to identify free port")
}
return result.Port
}
func newPortAllocationJob(eng *engine.Engine, port int) (job *engine.Job) {
strPort := strconv.Itoa(port)
job = eng.Job("allocate_port", "container_id")
job.Setenv("HostIP", "127.0.0.1")
job.Setenv("HostPort", strPort)
job.Setenv("Proto", "tcp")
job.Setenv("ContainerPort", strPort)
return
}
func TestAllocatePortDetection(t *testing.T) {
eng := engine.New()
eng.Logging = false
freePort := findFreePort(t)
// Init driver
job := eng.Job("initdriver")
if res := InitDriver(job); res != engine.StatusOK {
t.Fatal("Failed to initialize network driver")
}
// Allocate interface
job = eng.Job("allocate_interface", "container_id")
if res := Allocate(job); res != engine.StatusOK {
t.Fatal("Failed to allocate network interface")
}
// Allocate same port twice, expect failure on second call
job = newPortAllocationJob(eng, freePort)
if res := AllocatePort(job); res != engine.StatusOK {
t.Fatal("Failed to find a free port to allocate")
}
if res := AllocatePort(job); res == engine.StatusOK {
t.Fatal("Duplicate port allocation granted by AllocatePort")
}
}
func TestAllocatePortReclaim(t *testing.T) {
eng := engine.New()
eng.Logging = false
freePort := findFreePort(t)
// Init driver
job := eng.Job("initdriver")
if res := InitDriver(job); res != engine.StatusOK {
t.Fatal("Failed to initialize network driver")
}
// Allocate interface
job = eng.Job("allocate_interface", "container_id")
if res := Allocate(job); res != engine.StatusOK {
t.Fatal("Failed to allocate network interface")
}
// Occupy port
listenAddr := fmt.Sprintf(":%d", freePort)
tcpListenAddr, err := net.ResolveTCPAddr("tcp", listenAddr)
if err != nil {
t.Fatalf("Failed to resolve TCP address '%s'", listenAddr)
}
l, err := net.ListenTCP("tcp", tcpListenAddr)
if err != nil {
t.Fatalf("Fail to listen on port %d", freePort)
}
// Allocate port, expect failure
job = newPortAllocationJob(eng, freePort)
if res := AllocatePort(job); res == engine.StatusOK {
t.Fatal("Successfully allocated currently used port")
}
// Reclaim port, retry allocation
l.Close()
if res := AllocatePort(job); res != engine.StatusOK {
t.Fatal("Failed to allocate previously reclaimed port")
}
}
|