github.com/aigarnetwork/aigar@v0.0.0-20191115204914-d59a6eb70f8e/p2p/netutil/net_test.go (about) 1 // Copyright 2018 The go-ethereum Authors 2 // Copyright 2019 The go-aigar Authors 3 // This file is part of the go-aigar library. 4 // 5 // The go-aigar library is free software: you can redistribute it and/or modify 6 // it under the terms of the GNU Lesser General Public License as published by 7 // the Free Software Foundation, either version 3 of the License, or 8 // (at your option) any later version. 9 // 10 // The go-aigar library is distributed in the hope that it will be useful, 11 // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 // GNU Lesser General Public License for more details. 14 // 15 // You should have received a copy of the GNU Lesser General Public License 16 // along with the go-aigar library. If not, see <http://www.gnu.org/licenses/>. 17 18 package netutil 19 20 import ( 21 "fmt" 22 "net" 23 "reflect" 24 "testing" 25 "testing/quick" 26 27 "github.com/davecgh/go-spew/spew" 28 ) 29 30 func TestParseNetlist(t *testing.T) { 31 var tests = []struct { 32 input string 33 wantErr error 34 wantList *Netlist 35 }{ 36 { 37 input: "", 38 wantList: &Netlist{}, 39 }, 40 { 41 input: "127.0.0.0/8", 42 wantErr: nil, 43 wantList: &Netlist{{IP: net.IP{127, 0, 0, 0}, Mask: net.CIDRMask(8, 32)}}, 44 }, 45 { 46 input: "127.0.0.0/44", 47 wantErr: &net.ParseError{Type: "CIDR address", Text: "127.0.0.0/44"}, 48 }, 49 { 50 input: "127.0.0.0/16, 23.23.23.23/24,", 51 wantList: &Netlist{ 52 {IP: net.IP{127, 0, 0, 0}, Mask: net.CIDRMask(16, 32)}, 53 {IP: net.IP{23, 23, 23, 0}, Mask: net.CIDRMask(24, 32)}, 54 }, 55 }, 56 } 57 58 for _, test := range tests { 59 l, err := ParseNetlist(test.input) 60 if !reflect.DeepEqual(err, test.wantErr) { 61 t.Errorf("%q: got error %q, want %q", test.input, err, test.wantErr) 62 continue 63 } 64 if !reflect.DeepEqual(l, test.wantList) { 65 spew.Dump(l) 66 spew.Dump(test.wantList) 67 t.Errorf("%q: got %v, want %v", test.input, l, test.wantList) 68 } 69 } 70 } 71 72 func TestNilNetListContains(t *testing.T) { 73 var list *Netlist 74 checkContains(t, list.Contains, nil, []string{"1.2.3.4"}) 75 } 76 77 func TestIsLAN(t *testing.T) { 78 checkContains(t, IsLAN, 79 []string{ // included 80 "0.0.0.0", 81 "0.2.0.8", 82 "127.0.0.1", 83 "10.0.1.1", 84 "10.22.0.3", 85 "172.31.252.251", 86 "192.168.1.4", 87 "fe80::f4a1:8eff:fec5:9d9d", 88 "febf::ab32:2233", 89 "fc00::4", 90 }, 91 []string{ // excluded 92 "192.0.2.1", 93 "1.0.0.0", 94 "172.32.0.1", 95 "fec0::2233", 96 }, 97 ) 98 } 99 100 func TestIsSpecialNetwork(t *testing.T) { 101 checkContains(t, IsSpecialNetwork, 102 []string{ // included 103 "192.0.2.1", 104 "192.0.2.44", 105 "2001:db8:85a3:8d3:1319:8a2e:370:7348", 106 "255.255.255.255", 107 "224.0.0.22", // IPv4 multicast 108 "ff05::1:3", // IPv6 multicast 109 }, 110 []string{ // excluded 111 "192.0.3.1", 112 "1.0.0.0", 113 "172.32.0.1", 114 "fec0::2233", 115 }, 116 ) 117 } 118 119 func checkContains(t *testing.T, fn func(net.IP) bool, inc, exc []string) { 120 for _, s := range inc { 121 if !fn(parseIP(s)) { 122 t.Error("returned false for included address", s) 123 } 124 } 125 for _, s := range exc { 126 if fn(parseIP(s)) { 127 t.Error("returned true for excluded address", s) 128 } 129 } 130 } 131 132 func parseIP(s string) net.IP { 133 ip := net.ParseIP(s) 134 if ip == nil { 135 panic("invalid " + s) 136 } 137 return ip 138 } 139 140 func TestCheckRelayIP(t *testing.T) { 141 tests := []struct { 142 sender, addr string 143 want error 144 }{ 145 {"127.0.0.1", "0.0.0.0", errUnspecified}, 146 {"192.168.0.1", "0.0.0.0", errUnspecified}, 147 {"23.55.1.242", "0.0.0.0", errUnspecified}, 148 {"127.0.0.1", "255.255.255.255", errSpecial}, 149 {"192.168.0.1", "255.255.255.255", errSpecial}, 150 {"23.55.1.242", "255.255.255.255", errSpecial}, 151 {"192.168.0.1", "127.0.2.19", errLoopback}, 152 {"23.55.1.242", "192.168.0.1", errLAN}, 153 154 {"127.0.0.1", "127.0.2.19", nil}, 155 {"127.0.0.1", "192.168.0.1", nil}, 156 {"127.0.0.1", "23.55.1.242", nil}, 157 {"192.168.0.1", "192.168.0.1", nil}, 158 {"192.168.0.1", "23.55.1.242", nil}, 159 {"23.55.1.242", "23.55.1.242", nil}, 160 } 161 162 for _, test := range tests { 163 err := CheckRelayIP(parseIP(test.sender), parseIP(test.addr)) 164 if err != test.want { 165 t.Errorf("%s from %s: got %q, want %q", test.addr, test.sender, err, test.want) 166 } 167 } 168 } 169 170 func BenchmarkCheckRelayIP(b *testing.B) { 171 sender := parseIP("23.55.1.242") 172 addr := parseIP("23.55.1.2") 173 for i := 0; i < b.N; i++ { 174 CheckRelayIP(sender, addr) 175 } 176 } 177 178 func TestSameNet(t *testing.T) { 179 tests := []struct { 180 ip, other string 181 bits uint 182 want bool 183 }{ 184 {"0.0.0.0", "0.0.0.0", 32, true}, 185 {"0.0.0.0", "0.0.0.1", 0, true}, 186 {"0.0.0.0", "0.0.0.1", 31, true}, 187 {"0.0.0.0", "0.0.0.1", 32, false}, 188 {"0.33.0.1", "0.34.0.2", 8, true}, 189 {"0.33.0.1", "0.34.0.2", 13, true}, 190 {"0.33.0.1", "0.34.0.2", 15, false}, 191 } 192 193 for _, test := range tests { 194 if ok := SameNet(test.bits, parseIP(test.ip), parseIP(test.other)); ok != test.want { 195 t.Errorf("SameNet(%d, %s, %s) == %t, want %t", test.bits, test.ip, test.other, ok, test.want) 196 } 197 } 198 } 199 200 func ExampleSameNet() { 201 // This returns true because the IPs are in the same /24 network: 202 fmt.Println(SameNet(24, net.IP{127, 0, 0, 1}, net.IP{127, 0, 0, 3})) 203 // This call returns false: 204 fmt.Println(SameNet(24, net.IP{127, 3, 0, 1}, net.IP{127, 5, 0, 3})) 205 // Output: 206 // true 207 // false 208 } 209 210 func TestDistinctNetSet(t *testing.T) { 211 ops := []struct { 212 add, remove string 213 fails bool 214 }{ 215 {add: "127.0.0.1"}, 216 {add: "127.0.0.2"}, 217 {add: "127.0.0.3", fails: true}, 218 {add: "127.32.0.1"}, 219 {add: "127.32.0.2"}, 220 {add: "127.32.0.3", fails: true}, 221 {add: "127.33.0.1", fails: true}, 222 {add: "127.34.0.1"}, 223 {add: "127.34.0.2"}, 224 {add: "127.34.0.3", fails: true}, 225 // Make room for an address, then add again. 226 {remove: "127.0.0.1"}, 227 {add: "127.0.0.3"}, 228 {add: "127.0.0.3", fails: true}, 229 } 230 231 set := DistinctNetSet{Subnet: 15, Limit: 2} 232 for _, op := range ops { 233 var desc string 234 if op.add != "" { 235 desc = fmt.Sprintf("Add(%s)", op.add) 236 if ok := set.Add(parseIP(op.add)); ok != !op.fails { 237 t.Errorf("%s == %t, want %t", desc, ok, !op.fails) 238 } 239 } else { 240 desc = fmt.Sprintf("Remove(%s)", op.remove) 241 set.Remove(parseIP(op.remove)) 242 } 243 t.Logf("%s: %v", desc, set) 244 } 245 } 246 247 func TestDistinctNetSetAddRemove(t *testing.T) { 248 cfg := &quick.Config{} 249 fn := func(ips []net.IP) bool { 250 s := DistinctNetSet{Limit: 3, Subnet: 2} 251 for _, ip := range ips { 252 s.Add(ip) 253 } 254 for _, ip := range ips { 255 s.Remove(ip) 256 } 257 return s.Len() == 0 258 } 259 260 if err := quick.Check(fn, cfg); err != nil { 261 t.Fatal(err) 262 } 263 }