remove unused files
[platform/upstream/gcc48.git] / libgo / go / net / tcp_test.go
1 // Copyright 2012 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
4
5 package net
6
7 import (
8         "fmt"
9         "reflect"
10         "runtime"
11         "testing"
12         "time"
13 )
14
15 func BenchmarkTCP4OneShot(b *testing.B) {
16         benchmarkTCP(b, false, false, "127.0.0.1:0")
17 }
18
19 func BenchmarkTCP4OneShotTimeout(b *testing.B) {
20         benchmarkTCP(b, false, true, "127.0.0.1:0")
21 }
22
23 func BenchmarkTCP4Persistent(b *testing.B) {
24         benchmarkTCP(b, true, false, "127.0.0.1:0")
25 }
26
27 func BenchmarkTCP4PersistentTimeout(b *testing.B) {
28         benchmarkTCP(b, true, true, "127.0.0.1:0")
29 }
30
31 func BenchmarkTCP6OneShot(b *testing.B) {
32         if !supportsIPv6 {
33                 b.Skip("ipv6 is not supported")
34         }
35         benchmarkTCP(b, false, false, "[::1]:0")
36 }
37
38 func BenchmarkTCP6OneShotTimeout(b *testing.B) {
39         if !supportsIPv6 {
40                 b.Skip("ipv6 is not supported")
41         }
42         benchmarkTCP(b, false, true, "[::1]:0")
43 }
44
45 func BenchmarkTCP6Persistent(b *testing.B) {
46         if !supportsIPv6 {
47                 b.Skip("ipv6 is not supported")
48         }
49         benchmarkTCP(b, true, false, "[::1]:0")
50 }
51
52 func BenchmarkTCP6PersistentTimeout(b *testing.B) {
53         if !supportsIPv6 {
54                 b.Skip("ipv6 is not supported")
55         }
56         benchmarkTCP(b, true, true, "[::1]:0")
57 }
58
59 func benchmarkTCP(b *testing.B, persistent, timeout bool, laddr string) {
60         const msgLen = 512
61         conns := b.N
62         numConcurrent := runtime.GOMAXPROCS(-1) * 16
63         msgs := 1
64         if persistent {
65                 conns = numConcurrent
66                 msgs = b.N / conns
67                 if msgs == 0 {
68                         msgs = 1
69                 }
70                 if conns > b.N {
71                         conns = b.N
72                 }
73         }
74         sendMsg := func(c Conn, buf []byte) bool {
75                 n, err := c.Write(buf)
76                 if n != len(buf) || err != nil {
77                         b.Logf("Write failed: %v", err)
78                         return false
79                 }
80                 return true
81         }
82         recvMsg := func(c Conn, buf []byte) bool {
83                 for read := 0; read != len(buf); {
84                         n, err := c.Read(buf)
85                         read += n
86                         if err != nil {
87                                 b.Logf("Read failed: %v", err)
88                                 return false
89                         }
90                 }
91                 return true
92         }
93         ln, err := Listen("tcp", laddr)
94         if err != nil {
95                 b.Fatalf("Listen failed: %v", err)
96         }
97         defer ln.Close()
98         // Acceptor.
99         go func() {
100                 for {
101                         c, err := ln.Accept()
102                         if err != nil {
103                                 break
104                         }
105                         // Server connection.
106                         go func(c Conn) {
107                                 defer c.Close()
108                                 if timeout {
109                                         c.SetDeadline(time.Now().Add(time.Hour)) // Not intended to fire.
110                                 }
111                                 var buf [msgLen]byte
112                                 for m := 0; m < msgs; m++ {
113                                         if !recvMsg(c, buf[:]) || !sendMsg(c, buf[:]) {
114                                                 break
115                                         }
116                                 }
117                         }(c)
118                 }
119         }()
120         sem := make(chan bool, numConcurrent)
121         for i := 0; i < conns; i++ {
122                 sem <- true
123                 // Client connection.
124                 go func() {
125                         defer func() {
126                                 <-sem
127                         }()
128                         c, err := Dial("tcp", ln.Addr().String())
129                         if err != nil {
130                                 b.Logf("Dial failed: %v", err)
131                                 return
132                         }
133                         defer c.Close()
134                         if timeout {
135                                 c.SetDeadline(time.Now().Add(time.Hour)) // Not intended to fire.
136                         }
137                         var buf [msgLen]byte
138                         for m := 0; m < msgs; m++ {
139                                 if !sendMsg(c, buf[:]) || !recvMsg(c, buf[:]) {
140                                         break
141                                 }
142                         }
143                 }()
144         }
145         for i := 0; i < cap(sem); i++ {
146                 sem <- true
147         }
148 }
149
150 type resolveTCPAddrTest struct {
151         net     string
152         litAddr string
153         addr    *TCPAddr
154         err     error
155 }
156
157 var resolveTCPAddrTests = []resolveTCPAddrTest{
158         {"tcp", "127.0.0.1:0", &TCPAddr{IP: IPv4(127, 0, 0, 1), Port: 0}, nil},
159         {"tcp4", "127.0.0.1:65535", &TCPAddr{IP: IPv4(127, 0, 0, 1), Port: 65535}, nil},
160
161         {"tcp", "[::1]:1", &TCPAddr{IP: ParseIP("::1"), Port: 1}, nil},
162         {"tcp6", "[::1]:65534", &TCPAddr{IP: ParseIP("::1"), Port: 65534}, nil},
163
164         {"tcp", "[::1%en0]:1", &TCPAddr{IP: ParseIP("::1"), Port: 1, Zone: "en0"}, nil},
165         {"tcp6", "[::1%911]:2", &TCPAddr{IP: ParseIP("::1"), Port: 2, Zone: "911"}, nil},
166
167         {"", "127.0.0.1:0", &TCPAddr{IP: IPv4(127, 0, 0, 1), Port: 0}, nil}, // Go 1.0 behavior
168         {"", "[::1]:0", &TCPAddr{IP: ParseIP("::1"), Port: 0}, nil},         // Go 1.0 behavior
169
170         {"http", "127.0.0.1:0", nil, UnknownNetworkError("http")},
171 }
172
173 func init() {
174         if ifi := loopbackInterface(); ifi != nil {
175                 index := fmt.Sprintf("%v", ifi.Index)
176                 resolveTCPAddrTests = append(resolveTCPAddrTests, []resolveTCPAddrTest{
177                         {"tcp6", "[fe80::1%" + ifi.Name + "]:3", &TCPAddr{IP: ParseIP("fe80::1"), Port: 3, Zone: zoneToString(ifi.Index)}, nil},
178                         {"tcp6", "[fe80::1%" + index + "]:4", &TCPAddr{IP: ParseIP("fe80::1"), Port: 4, Zone: index}, nil},
179                 }...)
180         }
181 }
182
183 func TestResolveTCPAddr(t *testing.T) {
184         for _, tt := range resolveTCPAddrTests {
185                 addr, err := ResolveTCPAddr(tt.net, tt.litAddr)
186                 if err != tt.err {
187                         t.Fatalf("ResolveTCPAddr(%v, %v) failed: %v", tt.net, tt.litAddr, err)
188                 }
189                 if !reflect.DeepEqual(addr, tt.addr) {
190                         t.Fatalf("got %#v; expected %#v", addr, tt.addr)
191                 }
192         }
193 }
194
195 var tcpListenerNameTests = []struct {
196         net   string
197         laddr *TCPAddr
198 }{
199         {"tcp4", &TCPAddr{IP: IPv4(127, 0, 0, 1)}},
200         {"tcp4", &TCPAddr{}},
201         {"tcp4", nil},
202 }
203
204 func TestTCPListenerName(t *testing.T) {
205         if testing.Short() || !*testExternal {
206                 t.Skip("skipping test to avoid external network")
207         }
208
209         for _, tt := range tcpListenerNameTests {
210                 ln, err := ListenTCP(tt.net, tt.laddr)
211                 if err != nil {
212                         t.Fatalf("ListenTCP failed: %v", err)
213                 }
214                 defer ln.Close()
215                 la := ln.Addr()
216                 if a, ok := la.(*TCPAddr); !ok || a.Port == 0 {
217                         t.Fatalf("got %v; expected a proper address with non-zero port number", la)
218                 }
219         }
220 }
221
222 func TestIPv6LinkLocalUnicastTCP(t *testing.T) {
223         if testing.Short() || !*testExternal {
224                 t.Skip("skipping test to avoid external network")
225         }
226         if !supportsIPv6 {
227                 t.Skip("ipv6 is not supported")
228         }
229         ifi := loopbackInterface()
230         if ifi == nil {
231                 t.Skip("loopback interface not found")
232         }
233         laddr := ipv6LinkLocalUnicastAddr(ifi)
234         if laddr == "" {
235                 t.Skip("ipv6 unicast address on loopback not found")
236         }
237
238         type test struct {
239                 net, addr  string
240                 nameLookup bool
241         }
242         var tests = []test{
243                 {"tcp", "[" + laddr + "%" + ifi.Name + "]:0", false},
244                 {"tcp6", "[" + laddr + "%" + ifi.Name + "]:0", false},
245         }
246         switch runtime.GOOS {
247         case "darwin", "freebsd", "opensbd", "netbsd":
248                 tests = append(tests, []test{
249                         {"tcp", "[localhost%" + ifi.Name + "]:0", true},
250                         {"tcp6", "[localhost%" + ifi.Name + "]:0", true},
251                 }...)
252         case "linux":
253                 tests = append(tests, []test{
254                         {"tcp", "[ip6-localhost%" + ifi.Name + "]:0", true},
255                         {"tcp6", "[ip6-localhost%" + ifi.Name + "]:0", true},
256                 }...)
257         }
258         for _, tt := range tests {
259                 ln, err := Listen(tt.net, tt.addr)
260                 if err != nil {
261                         // It might return "LookupHost returned no
262                         // suitable address" error on some platforms.
263                         t.Logf("Listen failed: %v", err)
264                         continue
265                 }
266                 defer ln.Close()
267                 if la, ok := ln.Addr().(*TCPAddr); !ok || !tt.nameLookup && la.Zone == "" {
268                         t.Fatalf("got %v; expected a proper address with zone identifier", la)
269                 }
270
271                 done := make(chan int)
272                 go transponder(t, ln, done)
273
274                 c, err := Dial(tt.net, ln.Addr().String())
275                 if err != nil {
276                         t.Fatalf("Dial failed: %v", err)
277                 }
278                 defer c.Close()
279                 if la, ok := c.LocalAddr().(*TCPAddr); !ok || !tt.nameLookup && la.Zone == "" {
280                         t.Fatalf("got %v; expected a proper address with zone identifier", la)
281                 }
282                 if ra, ok := c.RemoteAddr().(*TCPAddr); !ok || !tt.nameLookup && ra.Zone == "" {
283                         t.Fatalf("got %v; expected a proper address with zone identifier", ra)
284                 }
285
286                 if _, err := c.Write([]byte("TCP OVER IPV6 LINKLOCAL TEST")); err != nil {
287                         t.Fatalf("Conn.Write failed: %v", err)
288                 }
289                 b := make([]byte, 32)
290                 if _, err := c.Read(b); err != nil {
291                         t.Fatalf("Conn.Read failed: %v", err)
292                 }
293
294                 <-done
295         }
296 }