]> Cypherpunks.ru repositories - gostls13.git/blob - src/net/interface_unix_test.go
cmd/compile/internal/inline: score call sites exposed by inlines
[gostls13.git] / src / net / interface_unix_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 //go:build darwin || dragonfly || freebsd || linux || netbsd || openbsd
6
7 package net
8
9 import (
10         "fmt"
11         "os"
12         "os/exec"
13         "runtime"
14         "strings"
15         "testing"
16         "time"
17 )
18
19 type testInterface struct {
20         name         string
21         local        string
22         remote       string
23         setupCmds    []*exec.Cmd
24         teardownCmds []*exec.Cmd
25 }
26
27 func (ti *testInterface) setup() error {
28         for _, cmd := range ti.setupCmds {
29                 if out, err := cmd.CombinedOutput(); err != nil {
30                         return fmt.Errorf("args=%v out=%q err=%v", cmd.Args, string(out), err)
31                 }
32         }
33         return nil
34 }
35
36 func (ti *testInterface) teardown() error {
37         for _, cmd := range ti.teardownCmds {
38                 if out, err := cmd.CombinedOutput(); err != nil {
39                         return fmt.Errorf("args=%v out=%q err=%v ", cmd.Args, string(out), err)
40                 }
41         }
42         return nil
43 }
44
45 func TestPointToPointInterface(t *testing.T) {
46         if testing.Short() {
47                 t.Skip("avoid external network")
48         }
49         if runtime.GOOS == "darwin" || runtime.GOOS == "ios" {
50                 t.Skipf("not supported on %s", runtime.GOOS)
51         }
52         if os.Getuid() != 0 {
53                 t.Skip("must be root")
54         }
55
56         // We suppose that using IPv4 link-local addresses doesn't
57         // harm anyone.
58         local, remote := "169.254.0.1", "169.254.0.254"
59         ip := ParseIP(remote)
60         for i := 0; i < 3; i++ {
61                 ti := &testInterface{local: local, remote: remote}
62                 if err := ti.setPointToPoint(5963 + i); err != nil {
63                         t.Skipf("test requires external command: %v", err)
64                 }
65                 if err := ti.setup(); err != nil {
66                         if e := err.Error(); strings.Contains(e, "No such device") && strings.Contains(e, "gre0") {
67                                 t.Skip("skipping test; no gre0 device. likely running in container?")
68                         }
69                         t.Fatal(err)
70                 } else {
71                         time.Sleep(3 * time.Millisecond)
72                 }
73                 ift, err := Interfaces()
74                 if err != nil {
75                         ti.teardown()
76                         t.Fatal(err)
77                 }
78                 for _, ifi := range ift {
79                         if ti.name != ifi.Name {
80                                 continue
81                         }
82                         ifat, err := ifi.Addrs()
83                         if err != nil {
84                                 ti.teardown()
85                                 t.Fatal(err)
86                         }
87                         for _, ifa := range ifat {
88                                 if ip.Equal(ifa.(*IPNet).IP) {
89                                         ti.teardown()
90                                         t.Fatalf("got %v", ifa)
91                                 }
92                         }
93                 }
94                 if err := ti.teardown(); err != nil {
95                         t.Fatal(err)
96                 } else {
97                         time.Sleep(3 * time.Millisecond)
98                 }
99         }
100 }
101
102 func TestInterfaceArrivalAndDeparture(t *testing.T) {
103         if testing.Short() {
104                 t.Skip("avoid external network")
105         }
106         if os.Getuid() != 0 {
107                 t.Skip("must be root")
108         }
109
110         // We suppose that using IPv4 link-local addresses and the
111         // dot1Q ID for Token Ring and FDDI doesn't harm anyone.
112         local, remote := "169.254.0.1", "169.254.0.254"
113         ip := ParseIP(remote)
114         for _, vid := range []int{1002, 1003, 1004, 1005} {
115                 ift1, err := Interfaces()
116                 if err != nil {
117                         t.Fatal(err)
118                 }
119                 ti := &testInterface{local: local, remote: remote}
120                 if err := ti.setBroadcast(vid); err != nil {
121                         t.Skipf("test requires external command: %v", err)
122                 }
123                 if err := ti.setup(); err != nil {
124                         t.Fatal(err)
125                 } else {
126                         time.Sleep(3 * time.Millisecond)
127                 }
128                 ift2, err := Interfaces()
129                 if err != nil {
130                         ti.teardown()
131                         t.Fatal(err)
132                 }
133                 if len(ift2) <= len(ift1) {
134                         for _, ifi := range ift1 {
135                                 t.Logf("before: %v", ifi)
136                         }
137                         for _, ifi := range ift2 {
138                                 t.Logf("after: %v", ifi)
139                         }
140                         ti.teardown()
141                         t.Fatalf("got %v; want gt %v", len(ift2), len(ift1))
142                 }
143                 for _, ifi := range ift2 {
144                         if ti.name != ifi.Name {
145                                 continue
146                         }
147                         ifat, err := ifi.Addrs()
148                         if err != nil {
149                                 ti.teardown()
150                                 t.Fatal(err)
151                         }
152                         for _, ifa := range ifat {
153                                 if ip.Equal(ifa.(*IPNet).IP) {
154                                         ti.teardown()
155                                         t.Fatalf("got %v", ifa)
156                                 }
157                         }
158                 }
159                 if err := ti.teardown(); err != nil {
160                         t.Fatal(err)
161                 } else {
162                         time.Sleep(3 * time.Millisecond)
163                 }
164                 ift3, err := Interfaces()
165                 if err != nil {
166                         t.Fatal(err)
167                 }
168                 if len(ift3) >= len(ift2) {
169                         for _, ifi := range ift2 {
170                                 t.Logf("before: %v", ifi)
171                         }
172                         for _, ifi := range ift3 {
173                                 t.Logf("after: %v", ifi)
174                         }
175                         t.Fatalf("got %v; want lt %v", len(ift3), len(ift2))
176                 }
177         }
178 }
179
180 func TestInterfaceArrivalAndDepartureZoneCache(t *testing.T) {
181         if testing.Short() {
182                 t.Skip("avoid external network")
183         }
184         if os.Getuid() != 0 {
185                 t.Skip("must be root")
186         }
187
188         // Ensure zoneCache is filled:
189         _, _ = Listen("tcp", "[fe80::1%nonexistent]:0")
190
191         ti := &testInterface{local: "fe80::1"}
192         if err := ti.setLinkLocal(0); err != nil {
193                 t.Skipf("test requires external command: %v", err)
194         }
195         if err := ti.setup(); err != nil {
196                 if e := err.Error(); strings.Contains(e, "Permission denied") {
197                         t.Skipf("permission denied, skipping test: %v", e)
198                 }
199                 t.Fatal(err)
200         }
201         defer ti.teardown()
202
203         time.Sleep(3 * time.Millisecond)
204
205         // If Listen fails (on Linux with “bind: invalid argument”), zoneCache was
206         // not updated when encountering a nonexistent interface:
207         ln, err := Listen("tcp", "[fe80::1%"+ti.name+"]:0")
208         if err != nil {
209                 t.Fatal(err)
210         }
211         ln.Close()
212         if err := ti.teardown(); err != nil {
213                 t.Fatal(err)
214         }
215 }