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  }