blob: b6e4e76f93045a9d70847c1d551d53d89193491b [file] [log] [blame]
Bill Yi7fb3c4c2015-03-23 09:04:07 -07001// 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// This file implements API tests across platforms and will never have a build
6// tag.
7
8package net
9
10import (
11 "os"
12 "runtime"
13 "strings"
14 "testing"
15 "time"
16)
17
18func packetConnTestData(t *testing.T, net string, i int) ([]byte, func()) {
19 switch net {
20 case "udp":
21 return []byte("UDP PACKETCONN TEST"), nil
22 case "ip":
23 if skip, skipmsg := skipRawSocketTest(t); skip {
24 return nil, func() {
25 t.Logf(skipmsg)
26 }
27 }
28 b, err := (&icmpMessage{
29 Type: icmpv4EchoRequest, Code: 0,
30 Body: &icmpEcho{
31 ID: os.Getpid() & 0xffff, Seq: i + 1,
32 Data: []byte("IP PACKETCONN TEST"),
33 },
34 }).Marshal()
35 if err != nil {
36 return nil, func() {
37 t.Fatalf("icmpMessage.Marshal failed: %v", err)
38 }
39 }
40 return b, nil
41 case "unixgram":
42 switch runtime.GOOS {
43 case "nacl", "plan9", "windows":
44 return nil, func() {
45 t.Logf("skipping %q test on %q", net, runtime.GOOS)
46 }
47 default:
48 return []byte("UNIXGRAM PACKETCONN TEST"), nil
49 }
50 default:
51 return nil, func() {
52 t.Logf("skipping %q test", net)
53 }
54 }
55}
56
57var packetConnTests = []struct {
58 net string
59 addr1 string
60 addr2 string
61}{
62 {"udp", "127.0.0.1:0", "127.0.0.1:0"},
63 {"ip:icmp", "127.0.0.1", "127.0.0.1"},
64 {"unixgram", testUnixAddr(), testUnixAddr()},
65}
66
67func TestPacketConn(t *testing.T) {
68 closer := func(c PacketConn, net, addr1, addr2 string) {
69 c.Close()
70 switch net {
71 case "unixgram":
72 os.Remove(addr1)
73 os.Remove(addr2)
74 }
75 }
76
77 for i, tt := range packetConnTests {
78 netstr := strings.Split(tt.net, ":")
79 wb, skipOrFatalFn := packetConnTestData(t, netstr[0], i)
80 if skipOrFatalFn != nil {
81 skipOrFatalFn()
82 continue
83 }
84
85 c1, err := ListenPacket(tt.net, tt.addr1)
86 if err != nil {
87 t.Fatalf("ListenPacket failed: %v", err)
88 }
89 defer closer(c1, netstr[0], tt.addr1, tt.addr2)
90 c1.LocalAddr()
91 c1.SetDeadline(time.Now().Add(100 * time.Millisecond))
92 c1.SetReadDeadline(time.Now().Add(100 * time.Millisecond))
93 c1.SetWriteDeadline(time.Now().Add(100 * time.Millisecond))
94
95 c2, err := ListenPacket(tt.net, tt.addr2)
96 if err != nil {
97 t.Fatalf("ListenPacket failed: %v", err)
98 }
99 defer closer(c2, netstr[0], tt.addr1, tt.addr2)
100 c2.LocalAddr()
101 c2.SetDeadline(time.Now().Add(100 * time.Millisecond))
102 c2.SetReadDeadline(time.Now().Add(100 * time.Millisecond))
103 c2.SetWriteDeadline(time.Now().Add(100 * time.Millisecond))
104
105 if _, err := c1.WriteTo(wb, c2.LocalAddr()); err != nil {
106 t.Fatalf("PacketConn.WriteTo failed: %v", err)
107 }
108 rb2 := make([]byte, 128)
109 if _, _, err := c2.ReadFrom(rb2); err != nil {
110 t.Fatalf("PacketConn.ReadFrom failed: %v", err)
111 }
112 if _, err := c2.WriteTo(wb, c1.LocalAddr()); err != nil {
113 t.Fatalf("PacketConn.WriteTo failed: %v", err)
114 }
115 rb1 := make([]byte, 128)
116 if _, _, err := c1.ReadFrom(rb1); err != nil {
117 t.Fatalf("PacketConn.ReadFrom failed: %v", err)
118 }
119 }
120}
121
122func TestConnAndPacketConn(t *testing.T) {
123 closer := func(c PacketConn, net, addr1, addr2 string) {
124 c.Close()
125 switch net {
126 case "unixgram":
127 os.Remove(addr1)
128 os.Remove(addr2)
129 }
130 }
131
132 for i, tt := range packetConnTests {
133 var wb []byte
134 netstr := strings.Split(tt.net, ":")
135 wb, skipOrFatalFn := packetConnTestData(t, netstr[0], i)
136 if skipOrFatalFn != nil {
137 skipOrFatalFn()
138 continue
139 }
140
141 c1, err := ListenPacket(tt.net, tt.addr1)
142 if err != nil {
143 t.Fatalf("ListenPacket failed: %v", err)
144 }
145 defer closer(c1, netstr[0], tt.addr1, tt.addr2)
146 c1.LocalAddr()
147 c1.SetDeadline(time.Now().Add(100 * time.Millisecond))
148 c1.SetReadDeadline(time.Now().Add(100 * time.Millisecond))
149 c1.SetWriteDeadline(time.Now().Add(100 * time.Millisecond))
150
151 c2, err := Dial(tt.net, c1.LocalAddr().String())
152 if err != nil {
153 t.Fatalf("Dial failed: %v", err)
154 }
155 defer c2.Close()
156 c2.LocalAddr()
157 c2.RemoteAddr()
158 c2.SetDeadline(time.Now().Add(100 * time.Millisecond))
159 c2.SetReadDeadline(time.Now().Add(100 * time.Millisecond))
160 c2.SetWriteDeadline(time.Now().Add(100 * time.Millisecond))
161
162 if _, err := c2.Write(wb); err != nil {
163 t.Fatalf("Conn.Write failed: %v", err)
164 }
165 rb1 := make([]byte, 128)
166 if _, _, err := c1.ReadFrom(rb1); err != nil {
167 t.Fatalf("PacketConn.ReadFrom failed: %v", err)
168 }
169 var dst Addr
170 switch netstr[0] {
171 case "ip":
172 dst = &IPAddr{IP: IPv4(127, 0, 0, 1)}
173 case "unixgram":
174 continue
175 default:
176 dst = c2.LocalAddr()
177 }
178 if _, err := c1.WriteTo(wb, dst); err != nil {
179 t.Fatalf("PacketConn.WriteTo failed: %v", err)
180 }
181 rb2 := make([]byte, 128)
182 if _, err := c2.Read(rb2); err != nil {
183 t.Fatalf("Conn.Read failed: %v", err)
184 }
185 }
186}