OSDN Git Service

new repo
[bytom/vapor.git] / vendor / golang.org / x / net / ipv6 / readwrite_test.go
1 // Copyright 2013 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 ipv6_test
6
7 import (
8         "bytes"
9         "net"
10         "runtime"
11         "strings"
12         "sync"
13         "testing"
14
15         "golang.org/x/net/internal/iana"
16         "golang.org/x/net/internal/nettest"
17         "golang.org/x/net/ipv6"
18 )
19
20 func BenchmarkReadWriteUnicast(b *testing.B) {
21         c, err := nettest.NewLocalPacketListener("udp6")
22         if err != nil {
23                 b.Skipf("not supported on %s/%s: %v", runtime.GOOS, runtime.GOARCH, err)
24         }
25         defer c.Close()
26
27         dst := c.LocalAddr()
28         wb, rb := []byte("HELLO-R-U-THERE"), make([]byte, 128)
29
30         b.Run("NetUDP", func(b *testing.B) {
31                 for i := 0; i < b.N; i++ {
32                         if _, err := c.WriteTo(wb, dst); err != nil {
33                                 b.Fatal(err)
34                         }
35                         if _, _, err := c.ReadFrom(rb); err != nil {
36                                 b.Fatal(err)
37                         }
38                 }
39         })
40         b.Run("IPv6UDP", func(b *testing.B) {
41                 p := ipv6.NewPacketConn(c)
42                 cf := ipv6.FlagTrafficClass | ipv6.FlagHopLimit | ipv6.FlagSrc | ipv6.FlagDst | ipv6.FlagInterface | ipv6.FlagPathMTU
43                 if err := p.SetControlMessage(cf, true); err != nil {
44                         b.Fatal(err)
45                 }
46                 cm := ipv6.ControlMessage{
47                         TrafficClass: iana.DiffServAF11 | iana.CongestionExperienced,
48                         HopLimit:     1,
49                 }
50                 ifi := nettest.RoutedInterface("ip6", net.FlagUp|net.FlagLoopback)
51                 if ifi != nil {
52                         cm.IfIndex = ifi.Index
53                 }
54
55                 for i := 0; i < b.N; i++ {
56                         if _, err := p.WriteTo(wb, &cm, dst); err != nil {
57                                 b.Fatal(err)
58                         }
59                         if _, _, _, err := p.ReadFrom(rb); err != nil {
60                                 b.Fatal(err)
61                         }
62                 }
63         })
64 }
65
66 func TestPacketConnConcurrentReadWriteUnicastUDP(t *testing.T) {
67         switch runtime.GOOS {
68         case "nacl", "plan9", "windows":
69                 t.Skipf("not supported on %s", runtime.GOOS)
70         }
71         if !supportsIPv6 {
72                 t.Skip("ipv6 is not supported")
73         }
74
75         c, err := nettest.NewLocalPacketListener("udp6")
76         if err != nil {
77                 t.Fatal(err)
78         }
79         defer c.Close()
80         p := ipv6.NewPacketConn(c)
81         defer p.Close()
82
83         dst := c.LocalAddr()
84         ifi := nettest.RoutedInterface("ip6", net.FlagUp|net.FlagLoopback)
85         cf := ipv6.FlagTrafficClass | ipv6.FlagHopLimit | ipv6.FlagSrc | ipv6.FlagDst | ipv6.FlagInterface | ipv6.FlagPathMTU
86         wb := []byte("HELLO-R-U-THERE")
87
88         if err := p.SetControlMessage(cf, true); err != nil { // probe before test
89                 if nettest.ProtocolNotSupported(err) {
90                         t.Skipf("not supported on %s", runtime.GOOS)
91                 }
92                 t.Fatal(err)
93         }
94
95         var wg sync.WaitGroup
96         reader := func() {
97                 defer wg.Done()
98                 rb := make([]byte, 128)
99                 if n, cm, _, err := p.ReadFrom(rb); err != nil {
100                         t.Error(err)
101                         return
102                 } else if !bytes.Equal(rb[:n], wb) {
103                         t.Errorf("got %v; want %v", rb[:n], wb)
104                         return
105                 } else {
106                         s := cm.String()
107                         if strings.Contains(s, ",") {
108                                 t.Errorf("should be space-separated values: %s", s)
109                         }
110                 }
111         }
112         writer := func(toggle bool) {
113                 defer wg.Done()
114                 cm := ipv6.ControlMessage{
115                         TrafficClass: iana.DiffServAF11 | iana.CongestionExperienced,
116                         Src:          net.IPv6loopback,
117                 }
118                 if ifi != nil {
119                         cm.IfIndex = ifi.Index
120                 }
121                 if err := p.SetControlMessage(cf, toggle); err != nil {
122                         t.Error(err)
123                         return
124                 }
125                 if n, err := p.WriteTo(wb, &cm, dst); err != nil {
126                         t.Error(err)
127                         return
128                 } else if n != len(wb) {
129                         t.Errorf("got %d; want %d", n, len(wb))
130                         return
131                 }
132         }
133
134         const N = 10
135         wg.Add(N)
136         for i := 0; i < N; i++ {
137                 go reader()
138         }
139         wg.Add(2 * N)
140         for i := 0; i < 2*N; i++ {
141                 go writer(i%2 != 0)
142         }
143         wg.Add(N)
144         for i := 0; i < N; i++ {
145                 go reader()
146         }
147         wg.Wait()
148 }