e1778779cf591f29bdfd294eb6216d04d869cc4c
[platform/upstream/gcc.git] / libgo / go / net / udp_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         "reflect"
9         "runtime"
10         "strings"
11         "testing"
12 )
13
14 func TestResolveUDPAddr(t *testing.T) {
15         for _, tt := range resolveTCPAddrTests {
16                 net := strings.Replace(tt.net, "tcp", "udp", -1)
17                 addr, err := ResolveUDPAddr(net, tt.litAddrOrName)
18                 if err != tt.err {
19                         t.Fatalf("ResolveUDPAddr(%q, %q) failed: %v", net, tt.litAddrOrName, err)
20                 }
21                 if !reflect.DeepEqual(addr, (*UDPAddr)(tt.addr)) {
22                         t.Fatalf("ResolveUDPAddr(%q, %q) = %#v, want %#v", net, tt.litAddrOrName, addr, tt.addr)
23                 }
24                 if err == nil {
25                         str := addr.String()
26                         addr1, err := ResolveUDPAddr(net, str)
27                         if err != nil {
28                                 t.Fatalf("ResolveUDPAddr(%q, %q) [from %q]: %v", net, str, tt.litAddrOrName, err)
29                         }
30                         if !reflect.DeepEqual(addr1, addr) {
31                                 t.Fatalf("ResolveUDPAddr(%q, %q) [from %q] = %#v, want %#v", net, str, tt.litAddrOrName, addr1, addr)
32                         }
33                 }
34         }
35 }
36
37 func TestWriteToUDP(t *testing.T) {
38         switch runtime.GOOS {
39         case "plan9":
40                 t.Skipf("skipping test on %q", runtime.GOOS)
41         }
42
43         l, err := ListenPacket("udp", "127.0.0.1:0")
44         if err != nil {
45                 t.Fatalf("Listen failed: %v", err)
46         }
47         defer l.Close()
48
49         testWriteToConn(t, l.LocalAddr().String())
50         testWriteToPacketConn(t, l.LocalAddr().String())
51 }
52
53 func testWriteToConn(t *testing.T, raddr string) {
54         c, err := Dial("udp", raddr)
55         if err != nil {
56                 t.Fatalf("Dial failed: %v", err)
57         }
58         defer c.Close()
59
60         ra, err := ResolveUDPAddr("udp", raddr)
61         if err != nil {
62                 t.Fatalf("ResolveUDPAddr failed: %v", err)
63         }
64
65         _, err = c.(*UDPConn).WriteToUDP([]byte("Connection-oriented mode socket"), ra)
66         if err == nil {
67                 t.Fatal("WriteToUDP should fail")
68         }
69         if err != nil && err.(*OpError).Err != ErrWriteToConnected {
70                 t.Fatalf("WriteToUDP should fail as ErrWriteToConnected: %v", err)
71         }
72
73         _, err = c.(*UDPConn).WriteTo([]byte("Connection-oriented mode socket"), ra)
74         if err == nil {
75                 t.Fatal("WriteTo should fail")
76         }
77         if err != nil && err.(*OpError).Err != ErrWriteToConnected {
78                 t.Fatalf("WriteTo should fail as ErrWriteToConnected: %v", err)
79         }
80
81         _, err = c.Write([]byte("Connection-oriented mode socket"))
82         if err != nil {
83                 t.Fatalf("Write failed: %v", err)
84         }
85 }
86
87 func testWriteToPacketConn(t *testing.T, raddr string) {
88         c, err := ListenPacket("udp", "127.0.0.1:0")
89         if err != nil {
90                 t.Fatalf("ListenPacket failed: %v", err)
91         }
92         defer c.Close()
93
94         ra, err := ResolveUDPAddr("udp", raddr)
95         if err != nil {
96                 t.Fatalf("ResolveUDPAddr failed: %v", err)
97         }
98
99         _, err = c.(*UDPConn).WriteToUDP([]byte("Connection-less mode socket"), ra)
100         if err != nil {
101                 t.Fatalf("WriteToUDP failed: %v", err)
102         }
103
104         _, err = c.WriteTo([]byte("Connection-less mode socket"), ra)
105         if err != nil {
106                 t.Fatalf("WriteTo failed: %v", err)
107         }
108
109         _, err = c.(*UDPConn).Write([]byte("Connection-less mode socket"))
110         if err == nil {
111                 t.Fatal("Write should fail")
112         }
113 }
114
115 var udpConnLocalNameTests = []struct {
116         net   string
117         laddr *UDPAddr
118 }{
119         {"udp4", &UDPAddr{IP: IPv4(127, 0, 0, 1)}},
120         {"udp4", &UDPAddr{}},
121         {"udp4", nil},
122 }
123
124 func TestUDPConnLocalName(t *testing.T) {
125         if testing.Short() || !*testExternal {
126                 t.Skip("skipping test to avoid external network")
127         }
128
129         for _, tt := range udpConnLocalNameTests {
130                 c, err := ListenUDP(tt.net, tt.laddr)
131                 if err != nil {
132                         t.Fatalf("ListenUDP failed: %v", err)
133                 }
134                 defer c.Close()
135                 la := c.LocalAddr()
136                 if a, ok := la.(*UDPAddr); !ok || a.Port == 0 {
137                         t.Fatalf("got %v; expected a proper address with non-zero port number", la)
138                 }
139         }
140 }
141
142 func TestUDPConnLocalAndRemoteNames(t *testing.T) {
143         for _, laddr := range []string{"", "127.0.0.1:0"} {
144                 c1, err := ListenPacket("udp", "127.0.0.1:0")
145                 if err != nil {
146                         t.Fatalf("ListenUDP failed: %v", err)
147                 }
148                 defer c1.Close()
149
150                 var la *UDPAddr
151                 if laddr != "" {
152                         var err error
153                         if la, err = ResolveUDPAddr("udp", laddr); err != nil {
154                                 t.Fatalf("ResolveUDPAddr failed: %v", err)
155                         }
156                 }
157                 c2, err := DialUDP("udp", la, c1.LocalAddr().(*UDPAddr))
158                 if err != nil {
159                         t.Fatalf("DialUDP failed: %v", err)
160                 }
161                 defer c2.Close()
162
163                 var connAddrs = [4]struct {
164                         got Addr
165                         ok  bool
166                 }{
167                         {c1.LocalAddr(), true},
168                         {c1.(*UDPConn).RemoteAddr(), false},
169                         {c2.LocalAddr(), true},
170                         {c2.RemoteAddr(), true},
171                 }
172                 for _, ca := range connAddrs {
173                         if a, ok := ca.got.(*UDPAddr); ok != ca.ok || ok && a.Port == 0 {
174                                 t.Fatalf("got %v; expected a proper address with non-zero port number", ca.got)
175                         }
176                 }
177         }
178 }
179
180 func TestIPv6LinkLocalUnicastUDP(t *testing.T) {
181         if testing.Short() || !*testExternal {
182                 t.Skip("skipping test to avoid external network")
183         }
184         if !supportsIPv6 {
185                 t.Skip("ipv6 is not supported")
186         }
187         ifi := loopbackInterface()
188         if ifi == nil {
189                 t.Skip("loopback interface not found")
190         }
191         laddr := ipv6LinkLocalUnicastAddr(ifi)
192         if laddr == "" {
193                 t.Skip("ipv6 unicast address on loopback not found")
194         }
195
196         type test struct {
197                 net, addr  string
198                 nameLookup bool
199         }
200         var tests = []test{
201                 {"udp", "[" + laddr + "%" + ifi.Name + "]:0", false},
202                 {"udp6", "[" + laddr + "%" + ifi.Name + "]:0", false},
203         }
204         // The first udp test fails on DragonFly - see issue 7473.
205         if runtime.GOOS == "dragonfly" {
206                 tests = tests[1:]
207         }
208         switch runtime.GOOS {
209         case "darwin", "dragonfly", "freebsd", "openbsd", "netbsd":
210                 tests = append(tests, []test{
211                         {"udp", "[localhost%" + ifi.Name + "]:0", true},
212                         {"udp6", "[localhost%" + ifi.Name + "]:0", true},
213                 }...)
214         case "linux":
215                 tests = append(tests, []test{
216                         {"udp", "[ip6-localhost%" + ifi.Name + "]:0", true},
217                         {"udp6", "[ip6-localhost%" + ifi.Name + "]:0", true},
218                 }...)
219         }
220         for _, tt := range tests {
221                 c1, err := ListenPacket(tt.net, tt.addr)
222                 if err != nil {
223                         // It might return "LookupHost returned no
224                         // suitable address" error on some platforms.
225                         t.Logf("ListenPacket failed: %v", err)
226                         continue
227                 }
228                 defer c1.Close()
229                 if la, ok := c1.LocalAddr().(*UDPAddr); !ok || !tt.nameLookup && la.Zone == "" {
230                         t.Fatalf("got %v; expected a proper address with zone identifier", la)
231                 }
232
233                 c2, err := Dial(tt.net, c1.LocalAddr().String())
234                 if err != nil {
235                         t.Fatalf("Dial failed: %v", err)
236                 }
237                 defer c2.Close()
238                 if la, ok := c2.LocalAddr().(*UDPAddr); !ok || !tt.nameLookup && la.Zone == "" {
239                         t.Fatalf("got %v; expected a proper address with zone identifier", la)
240                 }
241                 if ra, ok := c2.RemoteAddr().(*UDPAddr); !ok || !tt.nameLookup && ra.Zone == "" {
242                         t.Fatalf("got %v; expected a proper address with zone identifier", ra)
243                 }
244
245                 if _, err := c2.Write([]byte("UDP OVER IPV6 LINKLOCAL TEST")); err != nil {
246                         t.Fatalf("Conn.Write failed: %v", err)
247                 }
248                 b := make([]byte, 32)
249                 if _, from, err := c1.ReadFrom(b); err != nil {
250                         t.Fatalf("PacketConn.ReadFrom failed: %v", err)
251                 } else {
252                         if ra, ok := from.(*UDPAddr); !ok || !tt.nameLookup && ra.Zone == "" {
253                                 t.Fatalf("got %v; expected a proper address with zone identifier", ra)
254                         }
255                 }
256         }
257 }