| // Copyright 2016 The Netstack Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style |
| // license that can be found in the LICENSE file. |
| |
| package tcpip |
| |
| import ( |
| "strings" |
| "testing" |
| ) |
| |
| func TestSubnetContains(t *testing.T) { |
| tests := []struct { |
| s Address |
| m AddressMask |
| a Address |
| want bool |
| }{ |
| {"\xa0", "\xf0", "\x90", false}, |
| {"\xa0", "\xf0", "\xa0", true}, |
| {"\xa0", "\xf0", "\xa5", true}, |
| {"\xa0", "\xf0", "\xaf", true}, |
| {"\xa0", "\xf0", "\xb0", false}, |
| {"\xa0", "\xf0", "", false}, |
| {"\xa0", "\xf0", "\xa0\x00", false}, |
| {"\xc2\x80", "\xff\xf0", "\xc2\x80", true}, |
| {"\xc2\x80", "\xff\xf0", "\xc2\x00", false}, |
| {"\xc2\x00", "\xff\xf0", "\xc2\x00", true}, |
| {"\xc2\x00", "\xff\xf0", "\xc2\x80", false}, |
| } |
| for _, tt := range tests { |
| s, err := NewSubnet(tt.s, tt.m) |
| if err != nil { |
| t.Errorf("NewSubnet(%v, %v) = %v", tt.s, tt.m, err) |
| continue |
| } |
| if got := s.Contains(tt.a); got != tt.want { |
| t.Errorf("Subnet(%v).Contains(%v) = %v, want %v", s, tt.a, got, tt.want) |
| } |
| } |
| } |
| |
| func TestSubnetBits(t *testing.T) { |
| tests := []struct { |
| a AddressMask |
| want1 int |
| want0 int |
| }{ |
| {"\x00", 0, 8}, |
| {"\x00\x00", 0, 16}, |
| {"\x36", 4, 4}, |
| {"\x5c", 4, 4}, |
| {"\x5c\x5c", 8, 8}, |
| {"\x5c\x36", 8, 8}, |
| {"\x36\x5c", 8, 8}, |
| {"\x36\x36", 8, 8}, |
| {"\xff", 8, 0}, |
| {"\xff\xff", 16, 0}, |
| } |
| for _, tt := range tests { |
| s := &Subnet{mask: tt.a} |
| got1, got0 := s.Bits() |
| if got1 != tt.want1 || got0 != tt.want0 { |
| t.Errorf("Subnet{mask: %x}.Bits() = %d, %d, want %d, %d", tt.a, got1, got0, tt.want1, tt.want0) |
| } |
| } |
| } |
| |
| func TestSubnetPrefix(t *testing.T) { |
| tests := []struct { |
| a AddressMask |
| want int |
| }{ |
| {"\x00", 0}, |
| {"\x00\x00", 0}, |
| {"\x36", 0}, |
| {"\x86", 1}, |
| {"\xc5", 2}, |
| {"\xff\x00", 8}, |
| {"\xff\x36", 8}, |
| {"\xff\x8c", 9}, |
| {"\xff\xc8", 10}, |
| {"\xff", 8}, |
| {"\xff\xff", 16}, |
| } |
| for _, tt := range tests { |
| s := &Subnet{mask: tt.a} |
| got := s.Prefix() |
| if got != tt.want { |
| t.Errorf("Subnet{mask: %x}.Bits() = %d want %d", tt.a, got, tt.want) |
| } |
| } |
| } |
| |
| func TestSubnetCreation(t *testing.T) { |
| tests := []struct { |
| a Address |
| m AddressMask |
| want error |
| }{ |
| {"\xa0", "\xf0", nil}, |
| {"\xa0\xa0", "\xf0", errSubnetLengthMismatch}, |
| {"\xaa", "\xf0", errSubnetAddressMasked}, |
| {"", "", nil}, |
| } |
| for _, tt := range tests { |
| if _, err := NewSubnet(tt.a, tt.m); err != tt.want { |
| t.Errorf("NewSubnet(%v, %v) = %v, want %v", tt.a, tt.m, err, tt.want) |
| } |
| } |
| } |
| |
| func TestRouteMatch(t *testing.T) { |
| tests := []struct { |
| d Address |
| m Address |
| a Address |
| want bool |
| }{ |
| {"\xc2\x80", "\xff\xf0", "\xc2\x80", true}, |
| {"\xc2\x80", "\xff\xf0", "\xc2\x00", false}, |
| {"\xc2\x00", "\xff\xf0", "\xc2\x00", true}, |
| {"\xc2\x00", "\xff\xf0", "\xc2\x80", false}, |
| } |
| for _, tt := range tests { |
| r := Route{Destination: tt.d, Mask: tt.m} |
| if got := r.Match(tt.a); got != tt.want { |
| t.Errorf("Route(%v).Match(%v) = %v, want %v", r, tt.a, got, tt.want) |
| } |
| } |
| } |
| |
| func TestParse(t *testing.T) { |
| tests := []struct { |
| txt string |
| addr Address |
| }{ |
| {"::", Address(strings.Repeat("\x00", 16))}, |
| {"8::", Address("\x00\x08" + strings.Repeat("\x00", 14))}, |
| {"::8a", Address(strings.Repeat("\x00", 14) + "\x00\x8a")}, |
| {"fe80::1234:5678", "\xfe\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x12\x34\x56\x78"}, |
| {"fe80::b097:c9ff:fe02:477", "\xfe\x80\x00\x00\x00\x00\x00\x00\xb0\x97\xc9\xff\xfe\x02\x04\x77"}, |
| {"a:b:c:d:1:2:3:4", "\x00\x0a\x00\x0b\x00\x0c\x00\x0d\x00\x01\x00\x02\x00\x03\x00\x04"}, |
| {"a:b:c::2:3:4", "\x00\x0a\x00\x0b\x00\x0c\x00\x00\x00\x00\x00\x02\x00\x03\x00\x04"}, |
| {"000a:000b:000c::", "\x00\x0a\x00\x0b\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"}, |
| {"0000:0000:0000::0001", Address(strings.Repeat("\x00", 15) + "\x01")}, |
| {"0:0::1", Address(strings.Repeat("\x00", 15) + "\x01")}, |
| } |
| |
| for _, test := range tests { |
| got := Parse(test.txt) |
| if got != test.addr { |
| t.Errorf("Parse(%v)=%v, want %v", test.txt, got, test.addr) |
| } |
| } |
| } |
| |
| func TestAddressString(t *testing.T) { |
| tests := []string{ |
| "a:b:c::2:3:4", |
| "8::", |
| "fe80::5054:ff:fe12:3456", |
| "::1", |
| } |
| for _, want := range tests { |
| addr := Parse(want) |
| if got := addr.String(); got != want { |
| t.Errorf("Address(%x).String()=%q, want %q", addr, got, want) |
| } |
| } |
| } |