// Copyright 2022 The Ip2Region Authors. All rights reserved. // Use of this source code is governed by a Apache2.0-style // license that can be found in the LICENSE file. package xdb import ( "encoding/binary" "fmt" "os" "testing" ) func TestParseIP(t *testing.T) { var ips = []string{"29.34.191.255", "2c0f:fff0::", "2fff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"} for _, ip := range ips { bytes, err := ParseIP(ip) if err != nil { t.Errorf("check ip `%s`: %s\n", IP2String(bytes), err) } nip := IP2String(bytes) fmt.Printf("checkip: (%s / %s), isEqual: %v\n", ip, nip, ip == nip) } } func TestIPCompare(t *testing.T) { var ipPairs = [][]string{ {"1.2.3.4", "1.2.3.5"}, {"58.250.36.41", "58.250.30.41"}, {"2c10::", "2e00::"}, {"fdff:ffff:ffff:ffff:ffff:ffff:ffff:ffff", "febf:ffff:ffff:ffff:ffff:ffff:ffff:ffff"}, {"fe7f:ffff:ffff:ffff:ffff:ffff:ffff:ffff", "fe00::"}, } for _, pairs := range ipPairs { fmt.Printf("IPCompare(%s, %s): %d\n", pairs[0], pairs[1], IPCompare([]byte(pairs[0]), []byte(pairs[1]))) } } func TestIPAddOne(t *testing.T) { var ipPairs = [][]string{ {"1.2.3.4", "1.2.3.5"}, {"2.3.4.5", "2.3.4.6"}, {"fdff:ffff:ffff:ffff:ffff:ffff:ffff:ffff", "fe00::"}, {"2fff:ffff:ffff:ffff:ffff:ffff:ffff:ffff", "3000::"}, {"2fff:ffff:ffff:ffff:ffff:ffff:ffff:ffff", "3000::1"}, } for _, pairs := range ipPairs { sip, err := ParseIP(pairs[0]) if err != nil { t.Errorf("parse ip `%s`: %s\n", pairs[0], err) } eip, err := ParseIP(pairs[1]) if err != nil { t.Errorf("parse ip `%s`: %s\n", pairs[1], err) } fmt.Printf("IPAddOne(%s) = %s ? %d\n", pairs[0], pairs[1], IPCompare(IPAddOne(sip), eip)) } } func TestIPAddOne2(t *testing.T) { var ip = []byte{0, 1, 2, 3} nip := IPAddOne(ip) fmt.Printf("nip: %+v, ip:%+v", ip, nip) } func TestIPSubOne(t *testing.T) { var ipPairs = [][]string{ {"1.2.3.4", "1.2.3.5"}, {"2.3.4.5", "2.3.4.6"}, {"fdff:ffff:ffff:ffff:ffff:ffff:ffff:ffff", "fe00::"}, {"2fff:ffff:ffff:ffff:ffff:ffff:ffff:ffff", "3000::"}, {"2fff:ffff:ffff:ffff:ffff:ffff:ffff:ffff", "3000::1"}, } for _, pairs := range ipPairs { sip, err := ParseIP(pairs[0]) if err != nil { t.Errorf("parse ip `%s`: %s\n", pairs[0], err) } eip, err := ParseIP(pairs[1]) if err != nil { t.Errorf("parse ip `%s`: %s\n", pairs[1], err) } fmt.Printf("IPSubOne(%s) = %s ? %d\n", pairs[1], pairs[0], IPCompare(IPSubOne(eip), sip)) } } func TestIPSubOne2(t *testing.T) { var ip = []byte{0, 1, 2, 3} nip := IPSubOne(ip) fmt.Printf("nip: %+v, ip:%+v", ip, nip) } func TestIPSub(t *testing.T) { var strToSub = "1.2.3.4" bytesToSub, err := ParseIP(strToSub) if err != nil { t.Fatalf("failed to parse ip %s", strToSub) } var intToSub = int(binary.BigEndian.Uint32(bytesToSub)) t.Logf("to sub ip: %d -> %s", intToSub, strToSub) counter := 0 buf := make([]byte, 4) for i := 0; i < 0x2FFFFFFF; i++ { binary.BigEndian.PutUint32(buf, uint32(i)) subVal, err := IPSub(buf, bytesToSub) if err != nil { t.Fatalf("failed to IPSub(%s,%s): %s", IP2String(buf), strToSub, err) } // do it as two integers byteSub := int(binary.BigEndian.Uint32(subVal)) intSub := i + intToSub if byteSub != intSub { t.Fatal("byte and int sub value are not the same") } counter++ } t.Logf("test done with %d ips", counter) } func TestIPHalf(t *testing.T) { var buf = make([]byte, 4) for i := 0; i < 0xFFFFFFFF; i++ { binary.BigEndian.PutUint32(buf, uint32(i)) half := IPHalf(buf) // do it as two integers byteMiddle := binary.BigEndian.Uint32(half) intMidle := i >> 1 if byteMiddle != uint32(intMidle) { t.Fatal("byte middle and int middle are not the same") } } } func TestSubOverflow(t *testing.T) { var ip1Str = "255.255.255.250" ip1Bytes, err := ParseIP(ip1Str) if err != nil { t.Fatalf("failed to ParseIP(%s): %s", ip1Str, err) } var buff = make([]byte, 4) for i := 0; i < 10; i++ { binary.BigEndian.PutUint32(buff, uint32(i)) ipSub, err := IPSub(ip1Bytes, buff) if err != nil { t.Fatalf("failed to IPSub(%s, %s): %s", ip1Str, IP2String(buff), err) } t.Logf("IPSub(%s, %s) = %+v", ip1Str, IP2String(buff), ipSub) } } func TestIPMiddle(t *testing.T) { var sIPStr = "0.0.0.0" sBytes, err := ParseIP(sIPStr) if err != nil { t.Fatalf("failed to parse ip %s", sIPStr) } var sInt = int(binary.BigEndian.Uint32(sBytes)) t.Logf("start ip: %d -> %s", sInt, sIPStr) counter := 0 buf := make([]byte, 4) for i := 0; i < 0x0FFFFFFF; i++ { binary.BigEndian.PutUint32(buf, uint32(i)) midVal, err := IPMiddle(sBytes, buf) if err != nil { t.Fatalf("failed to IPMiddle(%s,%s): %s", sIPStr, IP2String(buf), err) } // do it as two integers byteMid := int(binary.BigEndian.Uint32(midVal)) intMid := (sInt + i) >> 1 if byteMid != intMid { t.Fatal("byte and int middle value are not the same") } counter++ } t.Logf("test done with %d ips", counter) } func TestSplitSegmentV4(t *testing.T) { // var str = "1.1.0.0|1.3.3.24|中国|广东|深圳|电信" // var str = "0.0.0.0|1.255.225.254|0|0|0|内网IP|内网IP" // var str = "29.0.0.0|29.34.191.255|美国|0|0|0|0" var str = "28.201.224.0|29.34.191.255|美国|0|0|0|0" seg, err := SegmentFrom(str) if err != nil { t.Fatalf("failed to parser segment '%s': %s", str, err) } fmt.Printf("idx: src, seg: %s\n", seg.String()) var segList = seg.Split() err = CheckSegments(segList) if err != nil { t.Fatalf("check segments: %s", err.Error()) } for i, s := range segList { fmt.Printf("idx: %3d, seg: %s\n", i, s.String()) } } func TestRegionFiltering(t *testing.T) { var line = "2001:1203:31:8000::|2001:1203:31:bfff:ffff:ffff:ffff:ffff||墨西哥|瓜纳华托州||||专线用户|" seg, err := SegmentFrom(line) if err != nil { t.Fatalf("failed to parse segment '%s': %s", line, err) } fReg, err := RegionFiltering(seg.Region, []int{1, 2, 4, 6}) if err != nil { t.Fatalf("failed to filter region '%s': %s", seg.Region, err) } fmt.Printf("region: %s, filtered: %s\n", seg.Region, fReg) } func TestSplitSegmentV6(t *testing.T) { var str = "fec0::|ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff||瑞士|弗里堡州||||专线用户|IANA" seg, err := SegmentFrom(str) if err != nil { t.Fatalf("failed to parser segment '%s': %s", str, err) } fmt.Printf("idx: src, seg: %s\n", seg.String()) var segList = seg.Split() err = CheckSegments(segList) if err != nil { t.Fatalf("check segments: %s", err.Error()) } for i, s := range segList { fmt.Printf("idx: %3d, seg: %s\n", i, s.String()) } } func TestIterateSegments(t *testing.T) { handle, err := os.OpenFile("../../../data/sample/segments.tests.mixed", os.O_RDONLY, 0600) if err != nil { t.Fatalf("failed to open tests file: %s", err) } _, _, _ = IterateSegments(handle, true, func(l string) { // fmt.Printf("load segment: `%s`\n", l) }, nil, func(seg *Segment) error { fmt.Printf("get segment: `%s`\n", seg) return nil }) }