/* * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ package netaddr import ( "bytes" "sort" "testing" ) func TestNewNetAddrDoesTheObvious(t *testing.T) { expected := &NetAddr{[]byte{192, 0, 2, 0}, uint8(24)} actual := NewNetAddr(expected.address, int(expected.length)) if !actual.IsEqual(expected) { t.Errorf("Expected %#v; got %#v", *expected, *actual) } } func TestIPParsesCIDR(t *testing.T) { actual, _ := IP("192.0.2.0/24") expected := &NetAddr{[]byte{192, 0, 2, 0}, uint8(24)} if !actual.IsEqual(expected) { t.Errorf("Expected %+v but got %+v", expected, actual) } } func TestIPParsesTruncatedPrefix(t *testing.T) { actual, err := IP("192.0.2/24") if err != nil { t.Errorf("failed to parse input: %v", err) return } expected := &NetAddr{[]byte{192, 0, 2, 0}, uint8(24)} if !actual.IsEqual(expected) { t.Errorf("Expected %+v but got %+v", expected, actual) } } func TestIPParsesOtherTruncatedPrefix(t *testing.T) { actual, err := IP("0/0") if err != nil { t.Errorf("failed to parse input: %v", err) return } expected := &NetAddr{[]byte{0, 0, 0, 0}, uint8(0)} if !actual.IsEqual(expected) { t.Errorf("Expected %+v but got %+v", expected, actual) } } func TestIPParsesAnotherTruncatedPrefix(t *testing.T) { actual, err := IP("0/8") if err != nil { t.Errorf("failed to parse input: %v", err) return } expected := &NetAddr{[]byte{0, 0, 0, 0}, uint8(8)} if !actual.IsEqual(expected) { t.Errorf("Expected %+v but got %+v", expected, actual) } } func TestIPParsesYetAnotherTruncatedPrefix(t *testing.T) { actual, err := IP("0/32") if err != nil { t.Errorf("failed to parse input: %v", err) return } expected := &NetAddr{[]byte{0, 0, 0, 0}, uint8(32)} if !actual.IsEqual(expected) { t.Errorf("Expected %+v but got %+v", expected, actual) } } func TestIPParsesStillAnotherTruncatedPrefix(t *testing.T) { actual, err := IP("10/8") if err != nil { t.Errorf("failed to parse input: %v", err) return } expected := &NetAddr{[]byte{10, 0, 0, 0}, uint8(8)} if !actual.IsEqual(expected) { t.Errorf("Expected %+v but got %+v", expected, actual) } } func TestIPParsesIPv4AddressWithContext(t *testing.T) { actual, _ := IP("192.0.2.1/24") expected := &NetAddr{[]byte{192, 0, 2, 1}, uint8(24)} if !actual.IsEqual(expected) { t.Errorf("Expected %+v but got %+v", expected, actual) } } func TestIPParsesIPv4AddressWithoutContext(t *testing.T) { actual, _ := IP("192.0.2.1") expected := &NetAddr{[]byte{192, 0, 2, 1}, uint8(32)} if !actual.IsEqual(expected) { t.Errorf("Expected %+v but got %+v", expected, actual) } } func TestIPParsesOtherIPv4AddressWithoutContext(t *testing.T) { actual, err := IP("172.31.254.5") if err != nil { t.Errorf("got error: %v", err) return } expected := &NetAddr{[]byte{172, 31, 254, 5}, uint8(32)} if !actual.IsEqual(expected) { t.Errorf("Expected %+v but got %+v", expected, actual) } } func TestIPParsesIPv6AddressWithContext(t *testing.T) { actual, _ := IP("2001:db8::1/64") expected := &NetAddr{ address: []byte{ 0x20, 0x01, 0x0d, 0xb8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, }, length: uint8(64), } if !actual.IsEqual(expected) { t.Errorf("Expected %+v but got %+v", expected, actual) } } func TestIPParsesIPv6AddressWithoutContext(t *testing.T) { actual, _ := IP("2001:db8::1") expected := &NetAddr{ address: []byte{ 0x20, 0x01, 0x0d, 0xb8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, }, length: uint8(128), } if !actual.IsEqual(expected) { t.Errorf("Expected %+v but got %+v", expected, actual) } } func TestIPFailsToParseJunk(t *testing.T) { _, err := IP("256.0.0.0") if err == nil { t.Error("Expected error but got nil") } } func TestIPFailsToParseOtherJunk(t *testing.T) { _, err := IP("255.0.0.0.0") if err == nil { t.Error("Expected error but got nil") } } func TestNetAddrToInteger(t *testing.T) { na, _ := IP("1.1.1.1") actual := na.Integer() expected := uint64(1 + 256 + 256*256 + 256*256*256) if actual != expected { t.Errorf("Expected %+v but got %+v", expected, actual) } } func TestContainsIsNotStrict(t *testing.T) { na, _ := IP("192.0.2.0/24") actual := na.Contains(na) expected := true if actual != expected { t.Errorf("Expected %+v but got %+v", expected, actual) } } func TestContainsReturnsTrue(t *testing.T) { na1, _ := IP("192.0.2.0/24") na2, _ := IP("192.0.2.0/25") actual := na1.Contains(na2) expected := true if actual != expected { t.Errorf("Expected %+v but got %+v", expected, actual) } } func TestContainsReturnsFalseOnShorterLen(t *testing.T) { na1, _ := IP("192.0.2.0/24") na2, _ := IP("192.0.2.0/25") actual := na2.Contains(na1) expected := false if actual != expected { t.Errorf("Expected %+v but got %+v", expected, actual) } } func TestContainsReturnsFalseOnAdjacent(t *testing.T) { na1, _ := IP("192.0.2.0/25") na2, _ := IP("192.0.2.128/25") actual := na1.Contains(na2) expected := false if actual != expected { t.Errorf("Expected %+v but got %+v", expected, actual) } } func TestIsSubsetIsNotStrict(t *testing.T) { na, _ := IP("192.0.2.0/24") actual := na.IsSubset(na) expected := true if actual != expected { t.Errorf("Expected %+v but got %+v", expected, actual) } } func TestIsSubsetReturnsTrue(t *testing.T) { na1, _ := IP("192.0.2.0/24") na2, _ := IP("192.0.2.0/25") actual := na2.IsSubset(na1) expected := true if actual != expected { t.Errorf("Expected %+v but got %+v", expected, actual) } } func TestIsSubsetReturnsFalseOnShorterLen(t *testing.T) { na1, _ := IP("192.0.2.0/24") na2, _ := IP("192.0.2.0/25") actual := na1.IsSubset(na2) expected := false if actual != expected { t.Errorf("Expected %+v but got %+v", expected, actual) } } func TestIsSubsetReturnsFalseOnAdjacent(t *testing.T) { na1, _ := IP("192.0.2.0/25") na2, _ := IP("192.0.2.128/25") actual := na2.IsSubset(na1) expected := false if actual != expected { t.Errorf("Expected %+v but got %+v", expected, actual) } } func TestFirstAddressWorks(t *testing.T) { na, _ := IP("192.0.2.127/27") actual := na.FirstAddress() expected := &NetAddr{[]byte{192, 0, 2, 96}, uint8(27)} if !actual.IsEqual(expected) { t.Errorf("Expected %+v but got %+v", expected, actual) } } func TestLastAddressWorks(t *testing.T) { na, _ := IP("192.0.2.96/27") actual := na.LastAddress() expected := &NetAddr{[]byte{192, 0, 2, 127}, uint8(27)} if !actual.IsEqual(expected) { t.Errorf("Expected %+v but got %+v", expected, actual) } } func TestStringWorksForIPv4(t *testing.T) { expected := "192.0.2.1/24" na, _ := IP(expected) actual := na.String() if actual != expected { t.Errorf("Expected %+v but got %v", expected, actual) } } func TestStringWorksForIPv6(t *testing.T) { expected := "fe80::1/64" na, _ := IP(expected) actual := na.String() if actual != expected { t.Errorf("Expected %+v but got %v", expected, actual) } } func TestIsRFC1918DetectsPrivate(t *testing.T) { expected := true na, _ := IP("10.255.255.255/32") actual := na.IsRFC1918() if actual != expected { t.Errorf("Expected %+v but got %v", expected, actual) } } func TestIsRFC1918DetectsOtherPrivate(t *testing.T) { expected := true na, _ := IP("172.31.255.255/32") actual := na.IsRFC1918() if actual != expected { t.Errorf("Expected %+v but got %v", expected, actual) } } func TestIsRFC1918DetectsYetAnotherPrivate(t *testing.T) { expected := true na, _ := IP("192.168.255.255/32") actual := na.IsRFC1918() if actual != expected { t.Errorf("Expected %+v but got %v", expected, actual) } } func TestIsRFC1918DetectsNonPrivates(t *testing.T) { expected := false na, _ := IP("192.0.2.133/27") actual := na.IsRFC1918() if actual != expected { t.Errorf("Expected %+v but got %v", expected, actual) } } func TestMaskGeneratesCorrectMasks(t *testing.T) { na, _ := IP("192.0.2/24") expected := []byte{255, 255, 255, 0} if !bytes.Equal(na.Mask(), expected) { t.Errorf("Expected %v but got %v", expected, na.Mask()) } expected = []byte{255, 255, 255, 128} na = na.SetLength(na.Length() + 1) if !bytes.Equal(na.Mask(), expected) { t.Errorf("Expected %v but got %v", expected, na.Mask()) } expected = []byte{255, 255, 255, 192} na = na.SetLength(na.Length() + 1) if !bytes.Equal(na.Mask(), expected) { t.Errorf("Expected %v but got %v", expected, na.Mask()) } expected = []byte{255, 255, 255, 224} na = na.SetLength(na.Length() + 1) if !bytes.Equal(na.Mask(), expected) { t.Errorf("Expected %v but got %v", expected, na.Mask()) } expected = []byte{255, 255, 255, 240} na = na.SetLength(na.Length() + 1) if !bytes.Equal(na.Mask(), expected) { t.Errorf("Expected %v but got %v", expected, na.Mask()) } expected = []byte{255, 255, 255, 248} na = na.SetLength(na.Length() + 1) if !bytes.Equal(na.Mask(), expected) { t.Errorf("Expected %v but got %v", expected, na.Mask()) } expected = []byte{255, 255, 255, 252} na = na.SetLength(na.Length() + 1) if !bytes.Equal(na.Mask(), expected) { t.Errorf("Expected %v but got %v", expected, na.Mask()) } expected = []byte{255, 255, 255, 254} na = na.SetLength(na.Length() + 1) if !bytes.Equal(na.Mask(), expected) { t.Errorf("Expected %v but got %v", expected, na.Mask()) } expected = []byte{255, 255, 255, 255} na = na.SetLength(na.Length() + 1) if !bytes.Equal(na.Mask(), expected) { t.Errorf("Expected %v but got %v", expected, na.Mask()) } } func TestLessThanDoesTheObvious(t *testing.T) { na1, _ := IP("192.0.2/24") na2, _ := IP("192.0.2/25") if LessThan(na1, na2) { t.Errorf("Expected %s >= %s", na1, na2) } if !LessThan(na2, na1) { t.Errorf("Expected %s < %s", na2, na1) } na3, _ := IP("192.0.2/24") na4, _ := IP("198.51.100.0/24") if !LessThan(na3, na4) { t.Errorf("Expected %s < %s", na3, na4) } } func TestLessThanSortsIntegersInOrder(t *testing.T) { cnt := 257 prefixes := make([]*NetAddr, 0, cnt) for i := 0; i < cnt; i++ { o2 := byte(i & 255) o1 := byte((i - int(o2)) >> 8) na := &NetAddr{[]byte{o1, o2}, uint8(16)} prefixes = append(prefixes, na) } sort.Slice(prefixes, func(i, j int) bool { return LessThan(prefixes[i], prefixes[j]) }) for i, p := range prefixes { o2 := byte(i & 255) o1 := byte((i - int(o2)) >> 8) na := &NetAddr{[]byte{o1, o2}, uint8(16)} dec := int(p.address[0])<<8 + int(p.address[1]) if i != dec { t.Errorf("Expected %d (%s) == %d (%s)", i, na, dec, p) } } } func TestOverlapsDoesTheObvious(t *testing.T) { na1, _ := IP("192.0.2/24") na2, _ := IP("192.0.2/25") if !na1.Overlaps(na2) { t.Errorf("Expected %s to overlap %s", na1, na2) } if !na2.Overlaps(na1) { t.Errorf("Expected %s to overlap %s", na2, na1) } na3, _ := IP("192.0.2.128/25") if na2.Overlaps(na3) { t.Errorf("Expected %s to not overlap %s", na2, na3) } if na3.Overlaps(na2) { t.Errorf("Expected %s to not overlap %s", na3, na2) } } func TestContiguousWorks(t *testing.T) { na1, _ := IP("192.0.2.1/25") na2, _ := IP("192.0.2.129/25") if !Contiguous(na1, na2) { t.Errorf("failed to detect that 192.0.2.1/25 and 192.0.2.129/25 are contiguous") } } func TestLeftAdjacentWorks(t *testing.T) { na1, _ := IP("192.0.2.1/25") na2, _ := IP("192.0.2.129/26") if !LeftAdjacent(na1, na2) { t.Errorf("failed to detect that 192.0.2.1/25 is left-adjacent to 192.0.2.129/26") } } func TestJoinIsIdempotent(t *testing.T) { na, _ := IP("192.0.2.0/24") actual := Join(na, na) if !actual.IsEqual(na) { t.Errorf("Expected %s v %s = %s; got %s", na, na, na, actual) } } func TestSplitWorks(t *testing.T) { na, _ := IP("192.0.2.70/24") expectedL, _ := IP("192.0.2.0/25") expectedR, _ := IP("192.0.2.128/25") actualL, actualR := Split(na) if !actualL.IsEqual(expectedL) || !actualR.IsEqual(expectedR) { t.Errorf("Expected (%s, %s); got (%s, %s)", expectedL, expectedR, actualL, actualR) } }