Files
EdgeNode/internal/iplibrary/ip_list_test.go
2024-04-06 10:07:39 +08:00

463 lines
11 KiB
Go

package iplibrary_test
import (
"fmt"
"github.com/TeaOSLab/EdgeNode/internal/iplibrary"
"github.com/TeaOSLab/EdgeNode/internal/utils/fasttime"
"github.com/TeaOSLab/EdgeNode/internal/utils/testutils"
"github.com/iwind/TeaGo/assert"
"github.com/iwind/TeaGo/logs"
"github.com/iwind/TeaGo/rands"
"math/rand"
"runtime"
"runtime/debug"
"strconv"
"sync"
"testing"
"time"
)
func TestIPList_Add_Empty(t *testing.T) {
var ipList = iplibrary.NewIPList()
ipList.Add(&iplibrary.IPItem{
Id: 1,
})
logs.PrintAsJSON(ipList.ItemsMap(), t)
logs.PrintAsJSON(ipList.AllItemsMap(), t)
logs.PrintAsJSON(ipList.IPMap(), t)
}
func TestIPList_Add_One(t *testing.T) {
var a = assert.NewAssertion(t)
var ipList = iplibrary.NewIPList()
ipList.Add(&iplibrary.IPItem{
Id: 1,
IPFrom: iplibrary.IPBytes("192.168.1.1"),
})
ipList.Add(&iplibrary.IPItem{
Id: 2,
IPTo: iplibrary.IPBytes("192.168.1.2"),
})
ipList.Add(&iplibrary.IPItem{
Id: 3,
IPFrom: iplibrary.IPBytes("192.168.0.2"),
})
ipList.Add(&iplibrary.IPItem{
Id: 4,
IPFrom: iplibrary.IPBytes("192.168.0.2"),
IPTo: iplibrary.IPBytes("192.168.0.1"),
})
ipList.Add(&iplibrary.IPItem{
Id: 5,
IPFrom: iplibrary.IPBytes("2001:db8:0:1::101"),
})
ipList.Add(&iplibrary.IPItem{
Id: 6,
IPFrom: nil,
Type: "all",
})
t.Log("===items===")
logs.PrintAsJSON(ipList.ItemsMap(), t)
t.Log("===sorted items===")
logs.PrintAsJSON(ipList.SortedRangeItems(), t)
t.Log("===all items===")
a.IsTrue(len(ipList.AllItemsMap()) == 1)
logs.PrintAsJSON(ipList.AllItemsMap(), t) // ip => items
t.Log("===ip items===")
logs.PrintAsJSON(ipList.IPMap())
}
func TestIPList_Update(t *testing.T) {
var ipList = iplibrary.NewIPList()
ipList.Add(&iplibrary.IPItem{
Id: 1,
IPFrom: iplibrary.IPBytes("192.168.1.1"),
})
t.Log("===before===")
logs.PrintAsJSON(ipList.ItemsMap(), t)
logs.PrintAsJSON(ipList.SortedRangeItems(), t)
logs.PrintAsJSON(ipList.IPMap(), t)
/**ipList.Add(&iplibrary.IPItem{
Id: 2,
IPFrom: iplibrary.IPBytes("192.168.1.1"),
})**/
ipList.Add(&iplibrary.IPItem{
Id: 1,
//IPFrom: 123,
IPTo: iplibrary.IPBytes("192.168.1.2"),
})
t.Log("===after===")
logs.PrintAsJSON(ipList.ItemsMap(), t)
logs.PrintAsJSON(ipList.SortedRangeItems(), t)
logs.PrintAsJSON(ipList.IPMap(), t)
}
func TestIPList_Update_AllItems(t *testing.T) {
var ipList = iplibrary.NewIPList()
ipList.Add(&iplibrary.IPItem{
Id: 1,
Type: iplibrary.IPItemTypeAll,
IPFrom: nil,
})
ipList.Add(&iplibrary.IPItem{
Id: 1,
IPTo: nil,
})
t.Log("===items map===")
logs.PrintAsJSON(ipList.ItemsMap(), t)
t.Log("===all items map===")
logs.PrintAsJSON(ipList.AllItemsMap(), t)
t.Log("===ip map===")
logs.PrintAsJSON(ipList.IPMap())
}
func TestIPList_Add_Range(t *testing.T) {
var a = assert.NewAssertion(t)
var ipList = iplibrary.NewIPList()
ipList.Add(&iplibrary.IPItem{
Id: 1,
IPFrom: iplibrary.IPBytes("192.168.1.1"),
IPTo: iplibrary.IPBytes("192.168.2.1"),
})
ipList.Add(&iplibrary.IPItem{
Id: 2,
IPTo: iplibrary.IPBytes("192.168.1.2"),
})
ipList.Add(&iplibrary.IPItem{
Id: 3,
IPFrom: iplibrary.IPBytes("192.168.0.1"),
IPTo: iplibrary.IPBytes("192.168.0.2"),
})
a.IsTrue(len(ipList.SortedRangeItems()) == 2)
t.Log(len(ipList.ItemsMap()), "ips")
t.Log("===items map===")
logs.PrintAsJSON(ipList.ItemsMap(), t)
t.Log("===sorted range items===")
logs.PrintAsJSON(ipList.SortedRangeItems())
t.Log("===all items map===")
logs.PrintAsJSON(ipList.AllItemsMap(), t)
t.Log("===ip map===")
logs.PrintAsJSON(ipList.IPMap(), t)
}
func TestNewIPList_Memory(t *testing.T) {
var list = iplibrary.NewIPList()
var count = 100
if testutils.IsSingleTesting() {
count = 2_000_000
}
var stat1 = testutils.ReadMemoryStat()
for i := 0; i < count; i++ {
list.AddDelay(&iplibrary.IPItem{
Id: uint64(i),
IPFrom: iplibrary.IPBytes(testutils.RandIP()),
IPTo: iplibrary.IPBytes(testutils.RandIP()),
ExpiredAt: time.Now().Unix(),
})
}
list.Sort()
runtime.GC()
var stat2 = testutils.ReadMemoryStat()
t.Log((stat2.HeapInuse-stat1.HeapInuse)>>20, "MB")
}
func TestIPList_Contains(t *testing.T) {
var a = assert.NewAssertion(t)
var list = iplibrary.NewIPList()
for i := 0; i < 255; i++ {
list.Add(&iplibrary.IPItem{
Id: uint64(i),
IPFrom: iplibrary.IPBytes(strconv.Itoa(i) + ".168.0.1"),
IPTo: iplibrary.IPBytes(strconv.Itoa(i) + ".168.255.1"),
ExpiredAt: 0,
})
}
for i := 0; i < 255; i++ {
list.Add(&iplibrary.IPItem{
Id: uint64(1000 + i),
IPFrom: iplibrary.IPBytes("192.167.2." + strconv.Itoa(i)),
})
}
t.Log(len(list.ItemsMap()), "ip")
var before = time.Now()
a.IsTrue(list.Contains(iplibrary.IPBytes("192.168.1.100")))
a.IsTrue(list.Contains(iplibrary.IPBytes("192.168.2.100")))
a.IsFalse(list.Contains(iplibrary.IPBytes("192.169.3.100")))
a.IsFalse(list.Contains(iplibrary.IPBytes("192.167.3.100")))
a.IsTrue(list.Contains(iplibrary.IPBytes("192.167.2.100")))
t.Log(time.Since(before).Seconds()*1000, "ms")
}
func TestIPList_Contains_Many(t *testing.T) {
var list = iplibrary.NewIPList()
for i := 0; i < 1_000_000; i++ {
list.AddDelay(&iplibrary.IPItem{
Id: uint64(i),
IPFrom: iplibrary.IPBytes(strconv.Itoa(rands.Int(0, 255)) + "." + strconv.Itoa(rands.Int(0, 255)) + "." + strconv.Itoa(rands.Int(0, 255)) + "." + strconv.Itoa(rands.Int(0, 255))),
IPTo: iplibrary.IPBytes(strconv.Itoa(rands.Int(0, 255)) + "." + strconv.Itoa(rands.Int(0, 255)) + "." + strconv.Itoa(rands.Int(0, 255)) + "." + strconv.Itoa(rands.Int(0, 255))),
ExpiredAt: 0,
})
}
var before = time.Now()
list.Sort()
t.Log("sort cost:", time.Since(before).Seconds()*1000, "ms")
t.Log(len(list.ItemsMap()), "ip")
before = time.Now()
_ = list.Contains(iplibrary.IPBytes("192.168.1.100"))
t.Log("contains cost:", time.Since(before).Seconds()*1000, "ms")
}
func TestIPList_ContainsAll(t *testing.T) {
var a = assert.NewAssertion(t)
var list = iplibrary.NewIPList()
list.Add(&iplibrary.IPItem{
Id: 1,
Type: "all",
IPFrom: nil,
})
var b = list.Contains(iplibrary.IPBytes("192.168.1.1"))
a.IsTrue(b)
list.Delete(1)
b = list.Contains(iplibrary.IPBytes("192.168.1.1"))
a.IsFalse(b)
}
func TestIPList_ContainsIPStrings(t *testing.T) {
var a = assert.NewAssertion(t)
var list = iplibrary.NewIPList()
for i := 0; i < 255; i++ {
list.Add(&iplibrary.IPItem{
Id: uint64(i),
IPFrom: iplibrary.IPBytes(strconv.Itoa(i) + ".168.0.1"),
IPTo: iplibrary.IPBytes(strconv.Itoa(i) + ".168.255.1"),
ExpiredAt: 0,
})
}
t.Log(len(list.ItemsMap()), "ip")
{
item, ok := list.ContainsIPStrings([]string{"192.168.1.100"})
t.Log("item:", item)
a.IsTrue(ok)
}
{
item, ok := list.ContainsIPStrings([]string{"192.167.1.100"})
t.Log("item:", item)
a.IsFalse(ok)
}
}
func TestIPList_Delete(t *testing.T) {
var list = iplibrary.NewIPList()
list.Add(&iplibrary.IPItem{
Id: 1,
IPFrom: iplibrary.IPBytes("192.168.0.1"),
ExpiredAt: 0,
})
list.Add(&iplibrary.IPItem{
Id: 2,
IPFrom: iplibrary.IPBytes("192.168.0.1"),
ExpiredAt: 0,
})
list.Add(&iplibrary.IPItem{
Id: 3,
IPFrom: iplibrary.IPBytes("192.168.1.1"),
IPTo: iplibrary.IPBytes("192.168.2.1"),
ExpiredAt: 0,
})
t.Log("===before===")
logs.PrintAsJSON(list.ItemsMap(), t)
logs.PrintAsJSON(list.AllItemsMap(), t)
logs.PrintAsJSON(list.SortedRangeItems())
logs.PrintAsJSON(list.IPMap(), t)
{
var found bool
for _, item := range list.SortedRangeItems() {
if item.Id == 3 {
found = true
break
}
}
if !found {
t.Fatal("should be found")
}
}
list.Delete(1)
t.Log("===after===")
logs.PrintAsJSON(list.ItemsMap(), t)
logs.PrintAsJSON(list.AllItemsMap(), t)
logs.PrintAsJSON(list.SortedRangeItems())
logs.PrintAsJSON(list.IPMap(), t)
list.Delete(3)
{
var found bool
for _, item := range list.SortedRangeItems() {
if item.Id == 3 {
found = true
break
}
}
if found {
t.Fatal("should be not found")
}
}
}
func TestIPList_GC(t *testing.T) {
var a = assert.NewAssertion(t)
var list = iplibrary.NewIPList()
list.Add(&iplibrary.IPItem{
Id: 1,
IPFrom: iplibrary.IPBytes("192.168.1.100"),
IPTo: iplibrary.IPBytes("192.168.1.101"),
ExpiredAt: time.Now().Unix() + 1,
})
list.Add(&iplibrary.IPItem{
Id: 2,
IPFrom: iplibrary.IPBytes("192.168.1.102"),
IPTo: iplibrary.IPBytes("192.168.1.103"),
ExpiredAt: 0,
})
logs.PrintAsJSON(list.ItemsMap(), t)
logs.PrintAsJSON(list.AllItemsMap(), t)
time.Sleep(3 * time.Second)
t.Log("===AFTER GC===")
logs.PrintAsJSON(list.ItemsMap(), t)
logs.PrintAsJSON(list.SortedRangeItems(), t)
a.IsTrue(len(list.ItemsMap()) == 1)
a.IsTrue(len(list.SortedRangeItems()) == 1)
}
func TestManyLists(t *testing.T) {
debug.SetMaxThreads(20)
var lists = []*iplibrary.IPList{}
var locker = &sync.Mutex{}
for i := 0; i < 1000; i++ {
locker.Lock()
lists = append(lists, iplibrary.NewIPList())
locker.Unlock()
}
if testutils.IsSingleTesting() {
time.Sleep(3 * time.Second)
}
t.Log(runtime.NumGoroutine())
t.Log(len(lists), "lists")
}
func BenchmarkIPList_Add(b *testing.B) {
runtime.GOMAXPROCS(1)
var list = iplibrary.NewIPList()
for i := 1; i < 200_000; i++ {
list.AddDelay(&iplibrary.IPItem{
Id: uint64(i),
IPFrom: iplibrary.IPBytes(strconv.Itoa(rands.Int(0, 255)) + "." + strconv.Itoa(rands.Int(0, 255)) + ".0.1"),
IPTo: iplibrary.IPBytes(strconv.Itoa(rands.Int(0, 255)) + "." + strconv.Itoa(rands.Int(0, 255)) + ".0.1"),
ExpiredAt: time.Now().Unix() + 60,
})
}
list.Sort()
b.Log(len(list.ItemsMap()), "ip")
b.ResetTimer()
for i := 0; i < b.N; i++ {
var ip = fmt.Sprintf("%d.%d.%d.%d", rand.Int()%255, rand.Int()%255, rand.Int()%255, rand.Int()%255)
list.Add(&iplibrary.IPItem{
Type: "",
Id: uint64(i % 1_000_000),
IPFrom: iplibrary.IPBytes(ip),
IPTo: nil,
ExpiredAt: fasttime.Now().Unix() + 3600,
EventLevel: "",
})
}
}
func BenchmarkIPList_Contains(b *testing.B) {
runtime.GOMAXPROCS(1)
var list = iplibrary.NewIPList()
for i := 1; i < 1_000_000; i++ {
var item = &iplibrary.IPItem{
Id: uint64(i),
IPFrom: iplibrary.IPBytes(strconv.Itoa(rands.Int(0, 255)) + "." + strconv.Itoa(rands.Int(0, 255)) + ".0.1"),
ExpiredAt: time.Now().Unix() + 60,
}
if i%100 == 0 {
item.IPTo = iplibrary.IPBytes(strconv.Itoa(rands.Int(0, 255)) + "." + strconv.Itoa(rands.Int(0, 255)) + ".0.1")
}
list.Add(item)
}
//b.Log(len(list.ItemsMap()), "ip")
b.ResetTimer()
b.RunParallel(func(pb *testing.PB) {
for pb.Next() {
_ = list.Contains(iplibrary.IPBytes(testutils.RandIP()))
}
})
}
func BenchmarkIPList_Sort(b *testing.B) {
var list = iplibrary.NewIPList()
for i := 0; i < 1_000_000; i++ {
var item = &iplibrary.IPItem{
Id: uint64(i),
IPFrom: iplibrary.IPBytes(strconv.Itoa(rands.Int(0, 255)) + "." + strconv.Itoa(rands.Int(0, 255)) + ".0.1"),
ExpiredAt: time.Now().Unix() + 60,
}
if i%100 == 0 {
item.IPTo = iplibrary.IPBytes(strconv.Itoa(rands.Int(0, 255)) + "." + strconv.Itoa(rands.Int(0, 255)) + ".0.1")
}
list.AddDelay(item)
}
b.ResetTimer()
b.RunParallel(func(pb *testing.PB) {
for pb.Next() {
list.Sort()
}
})
}