github.com/TeaOSLab/EdgeNode@v1.3.8/internal/iplibrary/ip_list_test.go (about) 1 package iplibrary_test 2 3 import ( 4 "fmt" 5 "github.com/TeaOSLab/EdgeCommon/pkg/iputils" 6 "github.com/TeaOSLab/EdgeNode/internal/iplibrary" 7 "github.com/TeaOSLab/EdgeNode/internal/utils/fasttime" 8 "github.com/TeaOSLab/EdgeNode/internal/utils/testutils" 9 "github.com/iwind/TeaGo/assert" 10 "github.com/iwind/TeaGo/logs" 11 "github.com/iwind/TeaGo/rands" 12 "math/rand" 13 "runtime" 14 "runtime/debug" 15 "strconv" 16 "sync" 17 "testing" 18 "time" 19 ) 20 21 func TestIPList_Add_Empty(t *testing.T) { 22 var ipList = iplibrary.NewIPList() 23 ipList.Add(&iplibrary.IPItem{ 24 Id: 1, 25 }) 26 logs.PrintAsJSON(ipList.ItemsMap(), t) 27 logs.PrintAsJSON(ipList.AllItemsMap(), t) 28 logs.PrintAsJSON(ipList.IPMap(), t) 29 } 30 31 func TestIPList_Add_One(t *testing.T) { 32 var a = assert.NewAssertion(t) 33 34 var ipList = iplibrary.NewIPList() 35 ipList.Add(&iplibrary.IPItem{ 36 Id: 1, 37 IPFrom: iputils.ToBytes("192.168.1.1"), 38 }) 39 ipList.Add(&iplibrary.IPItem{ 40 Id: 2, 41 IPTo: iputils.ToBytes("192.168.1.2"), 42 }) 43 ipList.Add(&iplibrary.IPItem{ 44 Id: 3, 45 IPFrom: iputils.ToBytes("192.168.0.2"), 46 }) 47 ipList.Add(&iplibrary.IPItem{ 48 Id: 4, 49 IPFrom: iputils.ToBytes("192.168.0.2"), 50 IPTo: iputils.ToBytes("192.168.0.1"), 51 }) 52 ipList.Add(&iplibrary.IPItem{ 53 Id: 5, 54 IPFrom: iputils.ToBytes("2001:db8:0:1::101"), 55 }) 56 ipList.Add(&iplibrary.IPItem{ 57 Id: 6, 58 IPFrom: nil, 59 Type: "all", 60 }) 61 t.Log("===items===") 62 logs.PrintAsJSON(ipList.ItemsMap(), t) 63 64 t.Log("===sorted items===") 65 logs.PrintAsJSON(ipList.SortedRangeItems(), t) 66 67 t.Log("===all items===") 68 a.IsTrue(len(ipList.AllItemsMap()) == 1) 69 logs.PrintAsJSON(ipList.AllItemsMap(), t) // ip => items 70 71 t.Log("===ip items===") 72 logs.PrintAsJSON(ipList.IPMap()) 73 } 74 75 func TestIPList_Update(t *testing.T) { 76 var ipList = iplibrary.NewIPList() 77 ipList.Add(&iplibrary.IPItem{ 78 Id: 1, 79 IPFrom: iputils.ToBytes("192.168.1.1"), 80 }) 81 82 t.Log("===before===") 83 logs.PrintAsJSON(ipList.ItemsMap(), t) 84 logs.PrintAsJSON(ipList.SortedRangeItems(), t) 85 logs.PrintAsJSON(ipList.IPMap(), t) 86 87 /**ipList.Add(&iplibrary.IPItem{ 88 Id: 2, 89 IPFrom: iputils.ToBytes("192.168.1.1"), 90 })**/ 91 ipList.Add(&iplibrary.IPItem{ 92 Id: 1, 93 //IPFrom: 123, 94 IPTo: iputils.ToBytes("192.168.1.2"), 95 }) 96 97 t.Log("===after===") 98 logs.PrintAsJSON(ipList.ItemsMap(), t) 99 logs.PrintAsJSON(ipList.SortedRangeItems(), t) 100 logs.PrintAsJSON(ipList.IPMap(), t) 101 } 102 103 func TestIPList_Update_AllItems(t *testing.T) { 104 var ipList = iplibrary.NewIPList() 105 ipList.Add(&iplibrary.IPItem{ 106 Id: 1, 107 Type: iplibrary.IPItemTypeAll, 108 IPFrom: nil, 109 }) 110 ipList.Add(&iplibrary.IPItem{ 111 Id: 1, 112 IPTo: nil, 113 }) 114 t.Log("===items map===") 115 logs.PrintAsJSON(ipList.ItemsMap(), t) 116 t.Log("===all items map===") 117 logs.PrintAsJSON(ipList.AllItemsMap(), t) 118 t.Log("===ip map===") 119 logs.PrintAsJSON(ipList.IPMap()) 120 } 121 122 func TestIPList_Add_Range(t *testing.T) { 123 var a = assert.NewAssertion(t) 124 125 var ipList = iplibrary.NewIPList() 126 ipList.Add(&iplibrary.IPItem{ 127 Id: 1, 128 IPFrom: iputils.ToBytes("192.168.1.1"), 129 IPTo: iputils.ToBytes("192.168.2.1"), 130 }) 131 ipList.Add(&iplibrary.IPItem{ 132 Id: 2, 133 IPTo: iputils.ToBytes("192.168.1.2"), 134 }) 135 ipList.Add(&iplibrary.IPItem{ 136 Id: 3, 137 IPFrom: iputils.ToBytes("192.168.0.1"), 138 IPTo: iputils.ToBytes("192.168.0.2"), 139 }) 140 141 a.IsTrue(len(ipList.SortedRangeItems()) == 2) 142 143 t.Log(len(ipList.ItemsMap()), "ips") 144 t.Log("===items map===") 145 logs.PrintAsJSON(ipList.ItemsMap(), t) 146 t.Log("===sorted range items===") 147 logs.PrintAsJSON(ipList.SortedRangeItems()) 148 t.Log("===all items map===") 149 logs.PrintAsJSON(ipList.AllItemsMap(), t) 150 151 t.Log("===ip map===") 152 logs.PrintAsJSON(ipList.IPMap(), t) 153 } 154 155 func TestNewIPList_Memory(t *testing.T) { 156 var list = iplibrary.NewIPList() 157 158 var count = 100 159 if testutils.IsSingleTesting() { 160 count = 2_000_000 161 } 162 var stat1 = testutils.ReadMemoryStat() 163 164 for i := 0; i < count; i++ { 165 list.AddDelay(&iplibrary.IPItem{ 166 Id: uint64(i), 167 IPFrom: iputils.ToBytes(testutils.RandIP()), 168 IPTo: iputils.ToBytes(testutils.RandIP()), 169 ExpiredAt: time.Now().Unix(), 170 }) 171 } 172 173 list.Sort() 174 175 runtime.GC() 176 177 var stat2 = testutils.ReadMemoryStat() 178 t.Log((stat2.HeapInuse-stat1.HeapInuse)>>20, "MB") 179 } 180 181 func TestIPList_Contains(t *testing.T) { 182 var a = assert.NewAssertion(t) 183 184 var list = iplibrary.NewIPList() 185 for i := 0; i < 255; i++ { 186 list.Add(&iplibrary.IPItem{ 187 Id: uint64(i), 188 IPFrom: iputils.ToBytes(strconv.Itoa(i) + ".168.0.1"), 189 IPTo: iputils.ToBytes(strconv.Itoa(i) + ".168.255.1"), 190 ExpiredAt: 0, 191 }) 192 } 193 for i := 0; i < 255; i++ { 194 list.Add(&iplibrary.IPItem{ 195 Id: uint64(1000 + i), 196 IPFrom: iputils.ToBytes("192.167.2." + strconv.Itoa(i)), 197 }) 198 } 199 200 list.Add(&iplibrary.IPItem{ 201 Id: 10000, 202 IPFrom: iputils.ToBytes("::1"), 203 }) 204 list.Add(&iplibrary.IPItem{ 205 Id: 10001, 206 IPFrom: iputils.ToBytes("::2"), 207 IPTo: iputils.ToBytes("::5"), 208 }) 209 210 t.Log(len(list.ItemsMap()), "ip") 211 212 var before = time.Now() 213 a.IsTrue(list.Contains(iputils.ToBytes("192.168.1.100"))) 214 a.IsTrue(list.Contains(iputils.ToBytes("192.168.2.100"))) 215 a.IsFalse(list.Contains(iputils.ToBytes("192.169.3.100"))) 216 a.IsFalse(list.Contains(iputils.ToBytes("192.167.3.100"))) 217 a.IsTrue(list.Contains(iputils.ToBytes("192.167.2.100"))) 218 a.IsTrue(list.Contains(iputils.ToBytes("::1"))) 219 a.IsTrue(list.Contains(iputils.ToBytes("::3"))) 220 a.IsFalse(list.Contains(iputils.ToBytes("::8"))) 221 t.Log(time.Since(before).Seconds()*1000, "ms") 222 } 223 224 func TestIPList_Contains_Many(t *testing.T) { 225 var list = iplibrary.NewIPList() 226 for i := 0; i < 1_000_000; i++ { 227 list.AddDelay(&iplibrary.IPItem{ 228 Id: uint64(i), 229 IPFrom: iputils.ToBytes(strconv.Itoa(rands.Int(0, 255)) + "." + strconv.Itoa(rands.Int(0, 255)) + "." + strconv.Itoa(rands.Int(0, 255)) + "." + strconv.Itoa(rands.Int(0, 255))), 230 IPTo: iputils.ToBytes(strconv.Itoa(rands.Int(0, 255)) + "." + strconv.Itoa(rands.Int(0, 255)) + "." + strconv.Itoa(rands.Int(0, 255)) + "." + strconv.Itoa(rands.Int(0, 255))), 231 ExpiredAt: 0, 232 }) 233 } 234 235 var before = time.Now() 236 list.Sort() 237 t.Log("sort cost:", time.Since(before).Seconds()*1000, "ms") 238 t.Log(len(list.ItemsMap()), "ip") 239 240 before = time.Now() 241 _ = list.Contains(iputils.ToBytes("192.168.1.100")) 242 t.Log("contains cost:", time.Since(before).Seconds()*1000, "ms") 243 } 244 245 func TestIPList_ContainsAll(t *testing.T) { 246 var a = assert.NewAssertion(t) 247 248 { 249 var list = iplibrary.NewIPList() 250 list.Add(&iplibrary.IPItem{ 251 Id: 1, 252 Type: "all", 253 IPFrom: nil, 254 }) 255 var b = list.Contains(iputils.ToBytes("192.168.1.1")) 256 a.IsTrue(b) 257 258 list.Delete(1) 259 260 b = list.Contains(iputils.ToBytes("192.168.1.1")) 261 a.IsFalse(b) 262 } 263 264 { 265 var list = iplibrary.NewIPList() 266 list.Add(&iplibrary.IPItem{ 267 Id: 1, 268 Type: "all", 269 IPFrom: iputils.ToBytes("0.0.0.0"), 270 }) 271 var b = list.Contains(iputils.ToBytes("192.168.1.1")) 272 a.IsTrue(b) 273 274 list.Delete(1) 275 276 b = list.Contains(iputils.ToBytes("192.168.1.1")) 277 a.IsFalse(b) 278 } 279 } 280 281 func TestIPList_ContainsIPStrings(t *testing.T) { 282 var a = assert.NewAssertion(t) 283 284 var list = iplibrary.NewIPList() 285 for i := 0; i < 255; i++ { 286 list.Add(&iplibrary.IPItem{ 287 Id: uint64(i), 288 IPFrom: iputils.ToBytes(strconv.Itoa(i) + ".168.0.1"), 289 IPTo: iputils.ToBytes(strconv.Itoa(i) + ".168.255.1"), 290 ExpiredAt: 0, 291 }) 292 } 293 t.Log(len(list.ItemsMap()), "ip") 294 295 { 296 item, ok := list.ContainsIPStrings([]string{"192.168.1.100"}) 297 t.Log("item:", item) 298 a.IsTrue(ok) 299 } 300 { 301 item, ok := list.ContainsIPStrings([]string{"192.167.1.100"}) 302 t.Log("item:", item) 303 a.IsFalse(ok) 304 } 305 } 306 307 func TestIPList_Delete(t *testing.T) { 308 var list = iplibrary.NewIPList() 309 list.Add(&iplibrary.IPItem{ 310 Id: 1, 311 IPFrom: iputils.ToBytes("192.168.0.1"), 312 ExpiredAt: 0, 313 }) 314 list.Add(&iplibrary.IPItem{ 315 Id: 2, 316 IPFrom: iputils.ToBytes("192.168.0.1"), 317 ExpiredAt: 0, 318 }) 319 list.Add(&iplibrary.IPItem{ 320 Id: 3, 321 IPFrom: iputils.ToBytes("192.168.1.1"), 322 IPTo: iputils.ToBytes("192.168.2.1"), 323 ExpiredAt: 0, 324 }) 325 t.Log("===before===") 326 logs.PrintAsJSON(list.ItemsMap(), t) 327 logs.PrintAsJSON(list.AllItemsMap(), t) 328 logs.PrintAsJSON(list.SortedRangeItems()) 329 logs.PrintAsJSON(list.IPMap(), t) 330 331 { 332 var found bool 333 for _, item := range list.SortedRangeItems() { 334 if item.Id == 3 { 335 found = true 336 break 337 } 338 } 339 if !found { 340 t.Fatal("should be found") 341 } 342 } 343 344 list.Delete(1) 345 346 t.Log("===after===") 347 logs.PrintAsJSON(list.ItemsMap(), t) 348 logs.PrintAsJSON(list.AllItemsMap(), t) 349 logs.PrintAsJSON(list.SortedRangeItems()) 350 logs.PrintAsJSON(list.IPMap(), t) 351 352 list.Delete(3) 353 354 { 355 var found bool 356 for _, item := range list.SortedRangeItems() { 357 if item.Id == 3 { 358 found = true 359 break 360 } 361 } 362 if found { 363 t.Fatal("should be not found") 364 } 365 } 366 } 367 368 func TestIPList_GC(t *testing.T) { 369 var a = assert.NewAssertion(t) 370 371 var list = iplibrary.NewIPList() 372 list.Add(&iplibrary.IPItem{ 373 Id: 1, 374 IPFrom: iputils.ToBytes("192.168.1.100"), 375 IPTo: iputils.ToBytes("192.168.1.101"), 376 ExpiredAt: time.Now().Unix() + 1, 377 }) 378 list.Add(&iplibrary.IPItem{ 379 Id: 2, 380 IPFrom: iputils.ToBytes("192.168.1.102"), 381 IPTo: iputils.ToBytes("192.168.1.103"), 382 ExpiredAt: 0, 383 }) 384 logs.PrintAsJSON(list.ItemsMap(), t) 385 logs.PrintAsJSON(list.AllItemsMap(), t) 386 387 time.Sleep(3 * time.Second) 388 389 t.Log("===AFTER GC===") 390 logs.PrintAsJSON(list.ItemsMap(), t) 391 logs.PrintAsJSON(list.SortedRangeItems(), t) 392 393 a.IsTrue(len(list.ItemsMap()) == 1) 394 a.IsTrue(len(list.SortedRangeItems()) == 1) 395 } 396 397 func TestManyLists(t *testing.T) { 398 debug.SetMaxThreads(20) 399 400 var lists = []*iplibrary.IPList{} 401 var locker = &sync.Mutex{} 402 for i := 0; i < 1000; i++ { 403 locker.Lock() 404 lists = append(lists, iplibrary.NewIPList()) 405 locker.Unlock() 406 } 407 408 if testutils.IsSingleTesting() { 409 time.Sleep(3 * time.Second) 410 } 411 t.Log(runtime.NumGoroutine()) 412 t.Log(len(lists), "lists") 413 } 414 415 func BenchmarkIPList_Add(b *testing.B) { 416 runtime.GOMAXPROCS(1) 417 418 var list = iplibrary.NewIPList() 419 for i := 1; i < 200_000; i++ { 420 list.AddDelay(&iplibrary.IPItem{ 421 Id: uint64(i), 422 IPFrom: iputils.ToBytes(strconv.Itoa(rands.Int(0, 255)) + "." + strconv.Itoa(rands.Int(0, 255)) + ".0.1"), 423 IPTo: iputils.ToBytes(strconv.Itoa(rands.Int(0, 255)) + "." + strconv.Itoa(rands.Int(0, 255)) + ".0.1"), 424 ExpiredAt: time.Now().Unix() + 60, 425 }) 426 } 427 428 list.Sort() 429 430 b.Log(len(list.ItemsMap()), "ip") 431 432 b.ResetTimer() 433 434 for i := 0; i < b.N; i++ { 435 var ip = fmt.Sprintf("%d.%d.%d.%d", rand.Int()%255, rand.Int()%255, rand.Int()%255, rand.Int()%255) 436 list.Add(&iplibrary.IPItem{ 437 Type: "", 438 Id: uint64(i % 1_000_000), 439 IPFrom: iputils.ToBytes(ip), 440 IPTo: nil, 441 ExpiredAt: fasttime.Now().Unix() + 3600, 442 EventLevel: "", 443 }) 444 } 445 } 446 447 func BenchmarkIPList_Contains(b *testing.B) { 448 runtime.GOMAXPROCS(1) 449 450 var list = iplibrary.NewIPList() 451 for i := 1; i < 1_000_000; i++ { 452 var item = &iplibrary.IPItem{ 453 Id: uint64(i), 454 IPFrom: iputils.ToBytes(strconv.Itoa(rands.Int(0, 255)) + "." + strconv.Itoa(rands.Int(0, 255)) + ".0.1"), 455 ExpiredAt: time.Now().Unix() + 60, 456 } 457 if i%100 == 0 { 458 item.IPTo = iputils.ToBytes(strconv.Itoa(rands.Int(0, 255)) + "." + strconv.Itoa(rands.Int(0, 255)) + ".0.1") 459 } 460 list.Add(item) 461 } 462 463 //b.Log(len(list.ItemsMap()), "ip") 464 465 b.ResetTimer() 466 b.RunParallel(func(pb *testing.PB) { 467 for pb.Next() { 468 _ = list.Contains(iputils.ToBytes(testutils.RandIP())) 469 } 470 }) 471 } 472 473 func BenchmarkIPList_Sort(b *testing.B) { 474 var list = iplibrary.NewIPList() 475 for i := 0; i < 1_000_000; i++ { 476 var item = &iplibrary.IPItem{ 477 Id: uint64(i), 478 IPFrom: iputils.ToBytes(strconv.Itoa(rands.Int(0, 255)) + "." + strconv.Itoa(rands.Int(0, 255)) + ".0.1"), 479 ExpiredAt: time.Now().Unix() + 60, 480 } 481 482 if i%100 == 0 { 483 item.IPTo = iputils.ToBytes(strconv.Itoa(rands.Int(0, 255)) + "." + strconv.Itoa(rands.Int(0, 255)) + ".0.1") 484 } 485 486 list.AddDelay(item) 487 } 488 489 b.ResetTimer() 490 b.RunParallel(func(pb *testing.PB) { 491 for pb.Next() { 492 list.Sort() 493 } 494 }) 495 }