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// This file implements API tests across platforms and will never have a build
6// tag.
7
8package net
9
10import (
11	"internal/testenv"
12	"os"
13	"runtime"
14	"testing"
15	"time"
16)
17
18// The full stack test cases for IPConn have been moved to the
19// following:
20//	golang.org/x/net/ipv4
21//	golang.org/x/net/ipv6
22//	golang.org/x/net/icmp
23
24func TestTCPListenerSpecificMethods(t *testing.T) {
25	switch runtime.GOOS {
26	case "plan9":
27		t.Skipf("not supported on %s", runtime.GOOS)
28	}
29
30	la, err := ResolveTCPAddr("tcp4", "127.0.0.1:0")
31	if err != nil {
32		t.Fatal(err)
33	}
34	ln, err := ListenTCP("tcp4", la)
35	if err != nil {
36		t.Fatal(err)
37	}
38	defer ln.Close()
39	ln.Addr()
40	mustSetDeadline(t, ln.SetDeadline, 30*time.Nanosecond)
41
42	if c, err := ln.Accept(); err != nil {
43		if !err.(Error).Timeout() {
44			t.Fatal(err)
45		}
46	} else {
47		c.Close()
48	}
49	if c, err := ln.AcceptTCP(); err != nil {
50		if !err.(Error).Timeout() {
51			t.Fatal(err)
52		}
53	} else {
54		c.Close()
55	}
56
57	if f, err := ln.File(); err != nil {
58		condFatalf(t, "file+net", "%v", err)
59	} else {
60		f.Close()
61	}
62}
63
64func TestTCPConnSpecificMethods(t *testing.T) {
65	la, err := ResolveTCPAddr("tcp4", "127.0.0.1:0")
66	if err != nil {
67		t.Fatal(err)
68	}
69	ln, err := ListenTCP("tcp4", la)
70	if err != nil {
71		t.Fatal(err)
72	}
73	ch := make(chan error, 1)
74	handler := func(ls *localServer, ln Listener) { ls.transponder(ls.Listener, ch) }
75	ls := (&streamListener{Listener: ln}).newLocalServer()
76	defer ls.teardown()
77	if err := ls.buildup(handler); err != nil {
78		t.Fatal(err)
79	}
80
81	ra, err := ResolveTCPAddr("tcp4", ls.Listener.Addr().String())
82	if err != nil {
83		t.Fatal(err)
84	}
85	c, err := DialTCP("tcp4", nil, ra)
86	if err != nil {
87		t.Fatal(err)
88	}
89	defer c.Close()
90	c.SetKeepAlive(false)
91	c.SetKeepAlivePeriod(3 * time.Second)
92	c.SetLinger(0)
93	c.SetNoDelay(false)
94	c.LocalAddr()
95	c.RemoteAddr()
96	c.SetDeadline(time.Now().Add(someTimeout))
97	c.SetReadDeadline(time.Now().Add(someTimeout))
98	c.SetWriteDeadline(time.Now().Add(someTimeout))
99
100	if _, err := c.Write([]byte("TCPCONN TEST")); err != nil {
101		t.Fatal(err)
102	}
103	rb := make([]byte, 128)
104	if _, err := c.Read(rb); err != nil {
105		t.Fatal(err)
106	}
107
108	for err := range ch {
109		t.Error(err)
110	}
111}
112
113func TestUDPConnSpecificMethods(t *testing.T) {
114	la, err := ResolveUDPAddr("udp4", "127.0.0.1:0")
115	if err != nil {
116		t.Fatal(err)
117	}
118	c, err := ListenUDP("udp4", la)
119	if err != nil {
120		t.Fatal(err)
121	}
122	defer c.Close()
123	c.LocalAddr()
124	c.RemoteAddr()
125	c.SetDeadline(time.Now().Add(someTimeout))
126	c.SetReadDeadline(time.Now().Add(someTimeout))
127	c.SetWriteDeadline(time.Now().Add(someTimeout))
128	c.SetReadBuffer(2048)
129	c.SetWriteBuffer(2048)
130
131	wb := []byte("UDPCONN TEST")
132	rb := make([]byte, 128)
133	if _, err := c.WriteToUDP(wb, c.LocalAddr().(*UDPAddr)); err != nil {
134		t.Fatal(err)
135	}
136	if _, _, err := c.ReadFromUDP(rb); err != nil {
137		t.Fatal(err)
138	}
139	if _, _, err := c.WriteMsgUDP(wb, nil, c.LocalAddr().(*UDPAddr)); err != nil {
140		condFatalf(t, c.LocalAddr().Network(), "%v", err)
141	}
142	if _, _, _, _, err := c.ReadMsgUDP(rb, nil); err != nil {
143		condFatalf(t, c.LocalAddr().Network(), "%v", err)
144	}
145
146	if f, err := c.File(); err != nil {
147		condFatalf(t, "file+net", "%v", err)
148	} else {
149		f.Close()
150	}
151
152	defer func() {
153		if p := recover(); p != nil {
154			t.Fatalf("panicked: %v", p)
155		}
156	}()
157
158	c.WriteToUDP(wb, nil)
159	c.WriteMsgUDP(wb, nil, nil)
160}
161
162func TestIPConnSpecificMethods(t *testing.T) {
163	if !testableNetwork("ip4") {
164		t.Skip("skipping: ip4 not supported")
165	}
166
167	la, err := ResolveIPAddr("ip4", "127.0.0.1")
168	if err != nil {
169		t.Fatal(err)
170	}
171	c, err := ListenIP("ip4:icmp", la)
172	if testenv.SyscallIsNotSupported(err) {
173		// May be inside a container that disallows creating a socket or
174		// not running as root.
175		t.Skipf("skipping: %v", err)
176	} else if err != nil {
177		t.Fatal(err)
178	}
179	defer c.Close()
180	c.LocalAddr()
181	c.RemoteAddr()
182	c.SetDeadline(time.Now().Add(someTimeout))
183	c.SetReadDeadline(time.Now().Add(someTimeout))
184	c.SetWriteDeadline(time.Now().Add(someTimeout))
185	c.SetReadBuffer(2048)
186	c.SetWriteBuffer(2048)
187
188	if f, err := c.File(); err != nil {
189		condFatalf(t, "file+net", "%v", err)
190	} else {
191		f.Close()
192	}
193
194	defer func() {
195		if p := recover(); p != nil {
196			t.Fatalf("panicked: %v", p)
197		}
198	}()
199
200	wb := []byte("IPCONN TEST")
201	c.WriteToIP(wb, nil)
202	c.WriteMsgIP(wb, nil, nil)
203}
204
205func TestUnixListenerSpecificMethods(t *testing.T) {
206	if !testableNetwork("unix") {
207		t.Skip("unix test")
208	}
209
210	addr := testUnixAddr(t)
211	la, err := ResolveUnixAddr("unix", addr)
212	if err != nil {
213		t.Fatal(err)
214	}
215	ln, err := ListenUnix("unix", la)
216	if err != nil {
217		t.Fatal(err)
218	}
219	defer ln.Close()
220	defer os.Remove(addr)
221	ln.Addr()
222	mustSetDeadline(t, ln.SetDeadline, 30*time.Nanosecond)
223
224	if c, err := ln.Accept(); err != nil {
225		if !err.(Error).Timeout() {
226			t.Fatal(err)
227		}
228	} else {
229		c.Close()
230	}
231	if c, err := ln.AcceptUnix(); err != nil {
232		if !err.(Error).Timeout() {
233			t.Fatal(err)
234		}
235	} else {
236		c.Close()
237	}
238
239	if f, err := ln.File(); err != nil {
240		condFatalf(t, "file+net", "%v", err)
241	} else {
242		f.Close()
243	}
244}
245
246func TestUnixConnSpecificMethods(t *testing.T) {
247	if !testableNetwork("unixgram") {
248		t.Skip("unixgram test")
249	}
250
251	addr1, addr2, addr3 := testUnixAddr(t), testUnixAddr(t), testUnixAddr(t)
252
253	a1, err := ResolveUnixAddr("unixgram", addr1)
254	if err != nil {
255		t.Fatal(err)
256	}
257	c1, err := DialUnix("unixgram", a1, nil)
258	if err != nil {
259		t.Fatal(err)
260	}
261	defer c1.Close()
262	defer os.Remove(addr1)
263	c1.LocalAddr()
264	c1.RemoteAddr()
265	c1.SetDeadline(time.Now().Add(someTimeout))
266	c1.SetReadDeadline(time.Now().Add(someTimeout))
267	c1.SetWriteDeadline(time.Now().Add(someTimeout))
268	c1.SetReadBuffer(2048)
269	c1.SetWriteBuffer(2048)
270
271	a2, err := ResolveUnixAddr("unixgram", addr2)
272	if err != nil {
273		t.Fatal(err)
274	}
275	c2, err := DialUnix("unixgram", a2, nil)
276	if err != nil {
277		t.Fatal(err)
278	}
279	defer c2.Close()
280	defer os.Remove(addr2)
281	c2.LocalAddr()
282	c2.RemoteAddr()
283	c2.SetDeadline(time.Now().Add(someTimeout))
284	c2.SetReadDeadline(time.Now().Add(someTimeout))
285	c2.SetWriteDeadline(time.Now().Add(someTimeout))
286	c2.SetReadBuffer(2048)
287	c2.SetWriteBuffer(2048)
288
289	a3, err := ResolveUnixAddr("unixgram", addr3)
290	if err != nil {
291		t.Fatal(err)
292	}
293	c3, err := ListenUnixgram("unixgram", a3)
294	if err != nil {
295		t.Fatal(err)
296	}
297	defer c3.Close()
298	defer os.Remove(addr3)
299	c3.LocalAddr()
300	c3.RemoteAddr()
301	c3.SetDeadline(time.Now().Add(someTimeout))
302	c3.SetReadDeadline(time.Now().Add(someTimeout))
303	c3.SetWriteDeadline(time.Now().Add(someTimeout))
304	c3.SetReadBuffer(2048)
305	c3.SetWriteBuffer(2048)
306
307	wb := []byte("UNIXCONN TEST")
308	rb1 := make([]byte, 128)
309	rb2 := make([]byte, 128)
310	rb3 := make([]byte, 128)
311	if _, _, err := c1.WriteMsgUnix(wb, nil, a2); err != nil {
312		t.Fatal(err)
313	}
314	if _, _, _, _, err := c2.ReadMsgUnix(rb2, nil); err != nil {
315		t.Fatal(err)
316	}
317	if _, err := c2.WriteToUnix(wb, a1); err != nil {
318		t.Fatal(err)
319	}
320	if _, _, err := c1.ReadFromUnix(rb1); err != nil {
321		t.Fatal(err)
322	}
323	if _, err := c3.WriteToUnix(wb, a1); err != nil {
324		t.Fatal(err)
325	}
326	if _, _, err := c1.ReadFromUnix(rb1); err != nil {
327		t.Fatal(err)
328	}
329	if _, err := c2.WriteToUnix(wb, a3); err != nil {
330		t.Fatal(err)
331	}
332	if _, _, err := c3.ReadFromUnix(rb3); err != nil {
333		t.Fatal(err)
334	}
335
336	if f, err := c1.File(); err != nil {
337		condFatalf(t, "file+net", "%v", err)
338	} else {
339		f.Close()
340	}
341
342	defer func() {
343		if p := recover(); p != nil {
344			t.Fatalf("panicked: %v", p)
345		}
346	}()
347
348	c1.WriteToUnix(wb, nil)
349	c1.WriteMsgUnix(wb, nil, nil)
350	c3.WriteToUnix(wb, nil)
351	c3.WriteMsgUnix(wb, nil, nil)
352}
353