OSDN Git Service

new repo
[bytom/vapor.git] / vendor / golang.org / x / net / internal / socket / socket_go1_9_test.go
1 // Copyright 2017 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 // +build go1.9
6 // +build darwin dragonfly freebsd linux netbsd openbsd solaris
7
8 package socket_test
9
10 import (
11         "bytes"
12         "fmt"
13         "net"
14         "runtime"
15         "testing"
16
17         "golang.org/x/net/internal/nettest"
18         "golang.org/x/net/internal/socket"
19 )
20
21 type mockControl struct {
22         Level int
23         Type  int
24         Data  []byte
25 }
26
27 func TestControlMessage(t *testing.T) {
28         for _, tt := range []struct {
29                 cs []mockControl
30         }{
31                 {
32                         []mockControl{
33                                 {Level: 1, Type: 1},
34                         },
35                 },
36                 {
37                         []mockControl{
38                                 {Level: 2, Type: 2, Data: []byte{0xfe}},
39                         },
40                 },
41                 {
42                         []mockControl{
43                                 {Level: 3, Type: 3, Data: []byte{0xfe, 0xff, 0xff, 0xfe}},
44                         },
45                 },
46                 {
47                         []mockControl{
48                                 {Level: 4, Type: 4, Data: []byte{0xfe, 0xff, 0xff, 0xfe, 0xfe, 0xff, 0xff, 0xfe}},
49                         },
50                 },
51                 {
52                         []mockControl{
53                                 {Level: 4, Type: 4, Data: []byte{0xfe, 0xff, 0xff, 0xfe, 0xfe, 0xff, 0xff, 0xfe}},
54                                 {Level: 2, Type: 2, Data: []byte{0xfe}},
55                         },
56                 },
57         } {
58                 var w []byte
59                 var tailPadLen int
60                 mm := socket.NewControlMessage([]int{0})
61                 for i, c := range tt.cs {
62                         m := socket.NewControlMessage([]int{len(c.Data)})
63                         l := len(m) - len(mm)
64                         if i == len(tt.cs)-1 && l > len(c.Data) {
65                                 tailPadLen = l - len(c.Data)
66                         }
67                         w = append(w, m...)
68                 }
69
70                 var err error
71                 ww := make([]byte, len(w))
72                 copy(ww, w)
73                 m := socket.ControlMessage(ww)
74                 for _, c := range tt.cs {
75                         if err = m.MarshalHeader(c.Level, c.Type, len(c.Data)); err != nil {
76                                 t.Fatalf("(%v).MarshalHeader() = %v", tt.cs, err)
77                         }
78                         copy(m.Data(len(c.Data)), c.Data)
79                         m = m.Next(len(c.Data))
80                 }
81                 m = socket.ControlMessage(w)
82                 for _, c := range tt.cs {
83                         m, err = m.Marshal(c.Level, c.Type, c.Data)
84                         if err != nil {
85                                 t.Fatalf("(%v).Marshal() = %v", tt.cs, err)
86                         }
87                 }
88                 if !bytes.Equal(ww, w) {
89                         t.Fatalf("got %#v; want %#v", ww, w)
90                 }
91
92                 ws := [][]byte{w}
93                 if tailPadLen > 0 {
94                         // Test a message with no tail padding.
95                         nopad := w[:len(w)-tailPadLen]
96                         ws = append(ws, [][]byte{nopad}...)
97                 }
98                 for _, w := range ws {
99                         ms, err := socket.ControlMessage(w).Parse()
100                         if err != nil {
101                                 t.Fatalf("(%v).Parse() = %v", tt.cs, err)
102                         }
103                         for i, m := range ms {
104                                 lvl, typ, dataLen, err := m.ParseHeader()
105                                 if err != nil {
106                                         t.Fatalf("(%v).ParseHeader() = %v", tt.cs, err)
107                                 }
108                                 if lvl != tt.cs[i].Level || typ != tt.cs[i].Type || dataLen != len(tt.cs[i].Data) {
109                                         t.Fatalf("%v: got %d, %d, %d; want %d, %d, %d", tt.cs[i], lvl, typ, dataLen, tt.cs[i].Level, tt.cs[i].Type, len(tt.cs[i].Data))
110                                 }
111                         }
112                 }
113         }
114 }
115
116 func TestUDP(t *testing.T) {
117         c, err := nettest.NewLocalPacketListener("udp")
118         if err != nil {
119                 t.Skipf("not supported on %s/%s: %v", runtime.GOOS, runtime.GOARCH, err)
120         }
121         defer c.Close()
122
123         t.Run("Message", func(t *testing.T) {
124                 testUDPMessage(t, c.(net.Conn))
125         })
126         switch runtime.GOOS {
127         case "linux":
128                 t.Run("Messages", func(t *testing.T) {
129                         testUDPMessages(t, c.(net.Conn))
130                 })
131         }
132 }
133
134 func testUDPMessage(t *testing.T, c net.Conn) {
135         cc, err := socket.NewConn(c)
136         if err != nil {
137                 t.Fatal(err)
138         }
139         data := []byte("HELLO-R-U-THERE")
140         wm := socket.Message{
141                 Buffers: bytes.SplitAfter(data, []byte("-")),
142                 Addr:    c.LocalAddr(),
143         }
144         if err := cc.SendMsg(&wm, 0); err != nil {
145                 t.Fatal(err)
146         }
147         b := make([]byte, 32)
148         rm := socket.Message{
149                 Buffers: [][]byte{b[:1], b[1:3], b[3:7], b[7:11], b[11:]},
150         }
151         if err := cc.RecvMsg(&rm, 0); err != nil {
152                 t.Fatal(err)
153         }
154         if !bytes.Equal(b[:rm.N], data) {
155                 t.Fatalf("got %#v; want %#v", b[:rm.N], data)
156         }
157 }
158
159 func testUDPMessages(t *testing.T, c net.Conn) {
160         cc, err := socket.NewConn(c)
161         if err != nil {
162                 t.Fatal(err)
163         }
164         data := []byte("HELLO-R-U-THERE")
165         wmbs := bytes.SplitAfter(data, []byte("-"))
166         wms := []socket.Message{
167                 {Buffers: wmbs[:1], Addr: c.LocalAddr()},
168                 {Buffers: wmbs[1:], Addr: c.LocalAddr()},
169         }
170         n, err := cc.SendMsgs(wms, 0)
171         if err != nil {
172                 t.Fatal(err)
173         }
174         if n != len(wms) {
175                 t.Fatalf("got %d; want %d", n, len(wms))
176         }
177         b := make([]byte, 32)
178         rmbs := [][][]byte{{b[:len(wmbs[0])]}, {b[len(wmbs[0]):]}}
179         rms := []socket.Message{
180                 {Buffers: rmbs[0]},
181                 {Buffers: rmbs[1]},
182         }
183         n, err = cc.RecvMsgs(rms, 0)
184         if err != nil {
185                 t.Fatal(err)
186         }
187         if n != len(rms) {
188                 t.Fatalf("got %d; want %d", n, len(rms))
189         }
190         nn := 0
191         for i := 0; i < n; i++ {
192                 nn += rms[i].N
193         }
194         if !bytes.Equal(b[:nn], data) {
195                 t.Fatalf("got %#v; want %#v", b[:nn], data)
196         }
197 }
198
199 func BenchmarkUDP(b *testing.B) {
200         c, err := nettest.NewLocalPacketListener("udp")
201         if err != nil {
202                 b.Skipf("not supported on %s/%s: %v", runtime.GOOS, runtime.GOARCH, err)
203         }
204         defer c.Close()
205         cc, err := socket.NewConn(c.(net.Conn))
206         if err != nil {
207                 b.Fatal(err)
208         }
209         data := []byte("HELLO-R-U-THERE")
210         wm := socket.Message{
211                 Buffers: [][]byte{data},
212                 Addr:    c.LocalAddr(),
213         }
214         rm := socket.Message{
215                 Buffers: [][]byte{make([]byte, 128)},
216                 OOB:     make([]byte, 128),
217         }
218
219         for M := 1; M <= 1<<9; M = M << 1 {
220                 b.Run(fmt.Sprintf("Iter-%d", M), func(b *testing.B) {
221                         for i := 0; i < b.N; i++ {
222                                 for j := 0; j < M; j++ {
223                                         if err := cc.SendMsg(&wm, 0); err != nil {
224                                                 b.Fatal(err)
225                                         }
226                                         if err := cc.RecvMsg(&rm, 0); err != nil {
227                                                 b.Fatal(err)
228                                         }
229                                 }
230                         }
231                 })
232                 switch runtime.GOOS {
233                 case "linux":
234                         wms := make([]socket.Message, M)
235                         for i := range wms {
236                                 wms[i].Buffers = [][]byte{data}
237                                 wms[i].Addr = c.LocalAddr()
238                         }
239                         rms := make([]socket.Message, M)
240                         for i := range rms {
241                                 rms[i].Buffers = [][]byte{make([]byte, 128)}
242                                 rms[i].OOB = make([]byte, 128)
243                         }
244                         b.Run(fmt.Sprintf("Batch-%d", M), func(b *testing.B) {
245                                 for i := 0; i < b.N; i++ {
246                                         if _, err := cc.SendMsgs(wms, 0); err != nil {
247                                                 b.Fatal(err)
248                                         }
249                                         if _, err := cc.RecvMsgs(rms, 0); err != nil {
250                                                 b.Fatal(err)
251                                         }
252                                 }
253                         })
254                 }
255         }
256 }