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 // +build darwin dragonfly freebsd linux netbsd openbsd 6 7 package net 8 9 import ( 10 "os" 11 "os/exec" 12 "runtime" 13 "testing" 14 "time" 15 ) 16 17 type testInterface struct { 18 name string 19 local string 20 remote string 21 setupCmds []*exec.Cmd 22 teardownCmds []*exec.Cmd 23 } 24 25 func (ti *testInterface) setup() error { 26 for _, cmd := range ti.setupCmds { 27 if err := cmd.Run(); err != nil { 28 return err 29 } 30 } 31 return nil 32 } 33 34 func (ti *testInterface) teardown() error { 35 for _, cmd := range ti.teardownCmds { 36 if err := cmd.Run(); err != nil { 37 return err 38 } 39 } 40 return nil 41 } 42 43 func TestPointToPointInterface(t *testing.T) { 44 if testing.Short() { 45 t.Skip("avoid external network") 46 } 47 if runtime.GOOS == "darwin" { 48 t.Skipf("not supported on %s", runtime.GOOS) 49 } 50 if os.Getuid() != 0 { 51 t.Skip("must be root") 52 } 53 54 local, remote := "169.254.0.1", "169.254.0.254" 55 ip := ParseIP(remote) 56 for i := 0; i < 3; i++ { 57 ti := &testInterface{local: local, remote: remote} 58 if err := ti.setPointToPoint(5963 + i); err != nil { 59 t.Skipf("test requries external command: %v", err) 60 } 61 if err := ti.setup(); err != nil { 62 t.Fatal(err) 63 } else { 64 time.Sleep(3 * time.Millisecond) 65 } 66 ift, err := Interfaces() 67 if err != nil { 68 ti.teardown() 69 t.Fatal(err) 70 } 71 for _, ifi := range ift { 72 if ti.name != ifi.Name { 73 continue 74 } 75 ifat, err := ifi.Addrs() 76 if err != nil { 77 ti.teardown() 78 t.Fatal(err) 79 } 80 for _, ifa := range ifat { 81 if ip.Equal(ifa.(*IPNet).IP) { 82 ti.teardown() 83 t.Fatalf("got %v", ifa) 84 } 85 } 86 } 87 if err := ti.teardown(); err != nil { 88 t.Fatal(err) 89 } else { 90 time.Sleep(3 * time.Millisecond) 91 } 92 } 93 } 94 95 func TestInterfaceArrivalAndDeparture(t *testing.T) { 96 if testing.Short() { 97 t.Skip("avoid external network") 98 } 99 if os.Getuid() != 0 { 100 t.Skip("must be root") 101 } 102 103 local, remote := "169.254.0.1", "169.254.0.254" 104 ip := ParseIP(remote) 105 for i := 0; i < 3; i++ { 106 ift1, err := Interfaces() 107 if err != nil { 108 t.Fatal(err) 109 } 110 ti := &testInterface{local: local, remote: remote} 111 if err := ti.setBroadcast(5682 + i); err != nil { 112 t.Skipf("test requires external command: %v", err) 113 } 114 if err := ti.setup(); err != nil { 115 t.Fatal(err) 116 } else { 117 time.Sleep(3 * time.Millisecond) 118 } 119 ift2, err := Interfaces() 120 if err != nil { 121 ti.teardown() 122 t.Fatal(err) 123 } 124 if len(ift2) <= len(ift1) { 125 for _, ifi := range ift1 { 126 t.Logf("before: %v", ifi) 127 } 128 for _, ifi := range ift2 { 129 t.Logf("after: %v", ifi) 130 } 131 ti.teardown() 132 t.Fatalf("got %v; want gt %v", len(ift2), len(ift1)) 133 } 134 for _, ifi := range ift2 { 135 if ti.name != ifi.Name { 136 continue 137 } 138 ifat, err := ifi.Addrs() 139 if err != nil { 140 ti.teardown() 141 t.Fatal(err) 142 } 143 for _, ifa := range ifat { 144 if ip.Equal(ifa.(*IPNet).IP) { 145 ti.teardown() 146 t.Fatalf("got %v", ifa) 147 } 148 } 149 } 150 if err := ti.teardown(); err != nil { 151 t.Fatal(err) 152 } else { 153 time.Sleep(3 * time.Millisecond) 154 } 155 ift3, err := Interfaces() 156 if err != nil { 157 t.Fatal(err) 158 } 159 if len(ift3) >= len(ift2) { 160 for _, ifi := range ift2 { 161 t.Logf("before: %v", ifi) 162 } 163 for _, ifi := range ift3 { 164 t.Logf("after: %v", ifi) 165 } 166 t.Fatalf("got %v; want lt %v", len(ift3), len(ift2)) 167 } 168 } 169 } 170