Source file
src/net/rawconn_test.go
1
2
3
4
5
6
7 package net
8
9 import (
10 "bytes"
11 "runtime"
12 "testing"
13 "time"
14 )
15
16 func TestRawConnReadWrite(t *testing.T) {
17 switch runtime.GOOS {
18 case "plan9":
19 t.Skipf("not supported on %s", runtime.GOOS)
20 }
21
22 t.Run("TCP", func(t *testing.T) {
23 handler := func(ls *localServer, ln Listener) {
24 c, err := ln.Accept()
25 if err != nil {
26 t.Error(err)
27 return
28 }
29 defer c.Close()
30
31 cc, err := ln.(*TCPListener).SyscallConn()
32 if err != nil {
33 t.Fatal(err)
34 }
35 called := false
36 op := func(uintptr) bool {
37 called = true
38 return true
39 }
40 err = cc.Write(op)
41 if err == nil {
42 t.Error("Write should return an error")
43 }
44 if called {
45 t.Error("Write shouldn't call op")
46 }
47 called = false
48 err = cc.Read(op)
49 if err == nil {
50 t.Error("Read should return an error")
51 }
52 if called {
53 t.Error("Read shouldn't call op")
54 }
55
56 var b [32]byte
57 n, err := c.Read(b[:])
58 if err != nil {
59 t.Error(err)
60 return
61 }
62 if _, err := c.Write(b[:n]); err != nil {
63 t.Error(err)
64 return
65 }
66 }
67 ls := newLocalServer(t, "tcp")
68 defer ls.teardown()
69 if err := ls.buildup(handler); err != nil {
70 t.Fatal(err)
71 }
72
73 c, err := Dial(ls.Listener.Addr().Network(), ls.Listener.Addr().String())
74 if err != nil {
75 t.Fatal(err)
76 }
77 defer c.Close()
78
79 cc, err := c.(*TCPConn).SyscallConn()
80 if err != nil {
81 t.Fatal(err)
82 }
83 data := []byte("HELLO-R-U-THERE")
84 if err := writeRawConn(cc, data); err != nil {
85 t.Fatal(err)
86 }
87 var b [32]byte
88 n, err := readRawConn(cc, b[:])
89 if err != nil {
90 t.Fatal(err)
91 }
92 if bytes.Compare(b[:n], data) != 0 {
93 t.Fatalf("got %q; want %q", b[:n], data)
94 }
95 })
96 t.Run("Deadline", func(t *testing.T) {
97 switch runtime.GOOS {
98 case "windows":
99 t.Skipf("not supported on %s", runtime.GOOS)
100 }
101
102 ln := newLocalListener(t, "tcp")
103 defer ln.Close()
104
105 c, err := Dial(ln.Addr().Network(), ln.Addr().String())
106 if err != nil {
107 t.Fatal(err)
108 }
109 defer c.Close()
110
111 cc, err := c.(*TCPConn).SyscallConn()
112 if err != nil {
113 t.Fatal(err)
114 }
115 var b [1]byte
116
117 c.SetDeadline(noDeadline)
118 if err := c.SetDeadline(time.Now().Add(-1)); err != nil {
119 t.Fatal(err)
120 }
121 if err = writeRawConn(cc, b[:]); err == nil {
122 t.Fatal("Write should fail")
123 }
124 if perr := parseWriteError(err); perr != nil {
125 t.Error(perr)
126 }
127 if !isDeadlineExceeded(err) {
128 t.Errorf("got %v; want timeout", err)
129 }
130 if _, err = readRawConn(cc, b[:]); err == nil {
131 t.Fatal("Read should fail")
132 }
133 if perr := parseReadError(err); perr != nil {
134 t.Error(perr)
135 }
136 if !isDeadlineExceeded(err) {
137 t.Errorf("got %v; want timeout", err)
138 }
139
140 c.SetReadDeadline(noDeadline)
141 if err := c.SetReadDeadline(time.Now().Add(-1)); err != nil {
142 t.Fatal(err)
143 }
144 if _, err = readRawConn(cc, b[:]); err == nil {
145 t.Fatal("Read should fail")
146 }
147 if perr := parseReadError(err); perr != nil {
148 t.Error(perr)
149 }
150 if !isDeadlineExceeded(err) {
151 t.Errorf("got %v; want timeout", err)
152 }
153
154 c.SetWriteDeadline(noDeadline)
155 if err := c.SetWriteDeadline(time.Now().Add(-1)); err != nil {
156 t.Fatal(err)
157 }
158 if err = writeRawConn(cc, b[:]); err == nil {
159 t.Fatal("Write should fail")
160 }
161 if perr := parseWriteError(err); perr != nil {
162 t.Error(perr)
163 }
164 if !isDeadlineExceeded(err) {
165 t.Errorf("got %v; want timeout", err)
166 }
167 })
168 }
169
170 func TestRawConnControl(t *testing.T) {
171 switch runtime.GOOS {
172 case "plan9":
173 t.Skipf("not supported on %s", runtime.GOOS)
174 }
175
176 t.Run("TCP", func(t *testing.T) {
177 ln := newLocalListener(t, "tcp")
178 defer ln.Close()
179
180 cc1, err := ln.(*TCPListener).SyscallConn()
181 if err != nil {
182 t.Fatal(err)
183 }
184 if err := controlRawConn(cc1, ln.Addr()); err != nil {
185 t.Fatal(err)
186 }
187
188 c, err := Dial(ln.Addr().Network(), ln.Addr().String())
189 if err != nil {
190 t.Fatal(err)
191 }
192 defer c.Close()
193
194 cc2, err := c.(*TCPConn).SyscallConn()
195 if err != nil {
196 t.Fatal(err)
197 }
198 if err := controlRawConn(cc2, c.LocalAddr()); err != nil {
199 t.Fatal(err)
200 }
201
202 ln.Close()
203 if err := controlRawConn(cc1, ln.Addr()); err == nil {
204 t.Fatal("Control after Close should fail")
205 }
206 c.Close()
207 if err := controlRawConn(cc2, c.LocalAddr()); err == nil {
208 t.Fatal("Control after Close should fail")
209 }
210 })
211 }
212
View as plain text