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