github.com/TeaOSLab/EdgeNode@v1.3.8/internal/utils/kvstore/table_test.go (about) 1 // Copyright 2024 GoEdge CDN goedge.cdn@gmail.com. All rights reserved. Official site: https://goedge.cn . 2 3 package kvstore_test 4 5 import ( 6 "fmt" 7 "github.com/TeaOSLab/EdgeNode/internal/utils/kvstore" 8 "github.com/TeaOSLab/EdgeNode/internal/utils/testutils" 9 "github.com/iwind/TeaGo/assert" 10 "github.com/iwind/TeaGo/types" 11 "math/rand" 12 "runtime" 13 "strconv" 14 "testing" 15 "time" 16 ) 17 18 func TestTable_Set(t *testing.T) { 19 store, err := kvstore.OpenStore("test") 20 if err != nil { 21 t.Fatal(err) 22 } 23 defer func() { 24 _ = store.Close() 25 }() 26 27 db, err := store.NewDB("TEST_DB") 28 if err != nil { 29 t.Fatal(err) 30 } 31 32 table, err := kvstore.NewTable[string]("users", kvstore.NewStringValueEncoder[string]()) 33 if err != nil { 34 t.Fatal(err) 35 } 36 37 db.AddTable(table) 38 39 const originValue = "b12345" 40 41 err = table.Set("a", originValue) 42 if err != nil { 43 t.Fatal(err) 44 } 45 46 value, err := table.Get("a") 47 if err != nil { 48 if kvstore.IsNotFound(err) { 49 t.Log("not found key") 50 return 51 } 52 t.Fatal(err) 53 } 54 t.Log("value:", value) 55 56 var a = assert.NewAssertion(t) 57 a.IsTrue(originValue == value) 58 } 59 60 func TestTable_Get(t *testing.T) { 61 store, err := kvstore.OpenStore("test") 62 if err != nil { 63 t.Fatal(err) 64 } 65 defer func() { 66 _ = store.Close() 67 }() 68 69 db, err := store.NewDB("TEST_DB") 70 if err != nil { 71 t.Fatal(err) 72 } 73 74 table, err := kvstore.NewTable[string]("users", kvstore.NewStringValueEncoder[string]()) 75 if err != nil { 76 t.Fatal(err) 77 } 78 79 db.AddTable(table) 80 81 for _, key := range []string{"a", "b", "c"} { 82 value, getErr := table.Get(key) 83 if getErr != nil { 84 if kvstore.IsNotFound(getErr) { 85 t.Log("not found key", key) 86 continue 87 } 88 t.Fatal(getErr) 89 } 90 t.Log(key, "=>", "value:", value) 91 } 92 } 93 94 func TestTable_Exist(t *testing.T) { 95 store, err := kvstore.OpenStore("test") 96 if err != nil { 97 t.Fatal(err) 98 } 99 defer func() { 100 _ = store.Close() 101 }() 102 103 db, err := store.NewDB("TEST_DB") 104 if err != nil { 105 t.Fatal(err) 106 } 107 108 table, err := kvstore.NewTable[string]("users", kvstore.NewStringValueEncoder[string]()) 109 if err != nil { 110 t.Fatal(err) 111 } 112 113 db.AddTable(table) 114 115 for _, key := range []string{"a", "b", "c", "12345"} { 116 b, checkErr := table.Exist(key) 117 if checkErr != nil { 118 t.Fatal(checkErr) 119 } 120 t.Log(key, "=>", b) 121 } 122 } 123 124 func TestTable_Delete(t *testing.T) { 125 var a = assert.NewAssertion(t) 126 127 store, err := kvstore.OpenStore("test") 128 if err != nil { 129 t.Fatal(err) 130 } 131 defer func() { 132 _ = store.Close() 133 }() 134 135 db, err := store.NewDB("TEST_DB") 136 if err != nil { 137 t.Fatal(err) 138 } 139 140 table, err := kvstore.NewTable[string]("users", kvstore.NewStringValueEncoder[string]()) 141 if err != nil { 142 t.Fatal(err) 143 } 144 145 db.AddTable(table) 146 147 value, err := table.Get("a123") 148 if err != nil { 149 if !kvstore.IsNotFound(err) { 150 t.Fatal(err) 151 } 152 } else { 153 t.Log("old value:", value) 154 } 155 156 err = table.Set("a123", "123456") 157 if err != nil { 158 t.Fatal(err) 159 } 160 161 { 162 value, err = table.Get("a123") 163 if err != nil { 164 t.Fatal(err) 165 } 166 a.IsTrue(value == "123456") 167 } 168 169 err = table.Delete("a123") 170 if err != nil { 171 t.Fatal(err) 172 } 173 174 { 175 _, err = table.Get("a123") 176 a.IsTrue(kvstore.IsNotFound(err)) 177 } 178 } 179 180 func TestTable_Delete_Empty(t *testing.T) { 181 var a = assert.NewAssertion(t) 182 183 store, err := kvstore.OpenStore("test") 184 if err != nil { 185 t.Fatal(err) 186 } 187 defer func() { 188 _ = store.Close() 189 }() 190 191 db, err := store.NewDB("TEST_DB") 192 if err != nil { 193 t.Fatal(err) 194 } 195 196 table, err := kvstore.NewTable[string]("users", kvstore.NewStringValueEncoder[string]()) 197 if err != nil { 198 t.Fatal(err) 199 } 200 201 db.AddTable(table) 202 203 { 204 err = table.Delete("a1", "a2", "a3", "a4", "") 205 if err != nil { 206 t.Fatal(err) 207 } 208 } 209 210 { 211 err = table.Delete() 212 if err != nil { 213 t.Fatal(err) 214 } 215 } 216 217 // set new 218 err = table.Set("a123", "123456") 219 if err != nil { 220 t.Fatal(err) 221 } 222 223 // delete again 224 { 225 err = table.Delete("a1", "a2", "a3", "a4", "") 226 if err != nil { 227 t.Fatal(err) 228 } 229 } 230 231 { 232 err = table.Delete() 233 if err != nil { 234 t.Fatal(err) 235 } 236 } 237 238 // read 239 { 240 var value string 241 value, err = table.Get("a123") 242 if err != nil { 243 t.Fatal(err) 244 } 245 a.IsTrue(value == "123456") 246 } 247 } 248 249 func TestTable_Count(t *testing.T) { 250 var table = testOpenStoreTable[*testCachedItem](t, "cache_items", &testCacheItemEncoder[*testCachedItem]{}) 251 252 defer func() { 253 _ = testingStore.Close() 254 }() 255 256 var before = time.Now() 257 count, err := table.Count() 258 if err != nil { 259 t.Fatal(err) 260 } 261 var costSeconds = time.Since(before).Seconds() 262 t.Log("count:", count, "cost:", costSeconds*1000, "ms", "qps:", fmt.Sprintf("%.2fM/s", float64(count)/costSeconds/1_000_000)) 263 264 // watch memory usage 265 if testutils.IsSingleTesting() { 266 //time.Sleep(5 * time.Minute) 267 } 268 } 269 270 func TestTable_Truncate(t *testing.T) { 271 var table = testOpenStoreTable[*testCachedItem](t, "cache_items", &testCacheItemEncoder[*testCachedItem]{}) 272 273 defer func() { 274 _ = testingStore.Close() 275 }() 276 277 var before = time.Now() 278 err := table.Truncate() 279 if err != nil { 280 t.Fatal(err) 281 } 282 283 var costSeconds = time.Since(before).Seconds() 284 t.Log("cost:", costSeconds*1000, "ms") 285 286 t.Log("===after truncate===") 287 testInspectDB(t) 288 } 289 290 func TestTable_ComposeFieldKey(t *testing.T) { 291 var a = assert.NewAssertion(t) 292 293 var table = testOpenStoreTable[*testCachedItem](t, "cache_items", &testCacheItemEncoder[*testCachedItem]{}) 294 295 defer func() { 296 _ = testingStore.Close() 297 }() 298 299 var fieldKeyBytes = table.ComposeFieldKey([]byte("Lily"), "username", []byte("lucy")) 300 t.Log(string(fieldKeyBytes)) 301 fieldValueBytes, keyValueBytes, err := table.DecodeFieldKey("username", fieldKeyBytes) 302 if err != nil { 303 t.Fatal(err) 304 } 305 t.Log("field:", string(fieldValueBytes), "key:", string(keyValueBytes)) 306 a.IsTrue(string(fieldValueBytes) == "lucy") 307 a.IsTrue(string(keyValueBytes) == "Lily") 308 } 309 310 func BenchmarkTable_Set(b *testing.B) { 311 runtime.GOMAXPROCS(4) 312 313 store, err := kvstore.OpenStore("test") 314 if err != nil { 315 b.Fatal(err) 316 } 317 defer func() { 318 _ = store.Close() 319 }() 320 321 db, err := store.NewDB("TEST_DB") 322 if err != nil { 323 b.Fatal(err) 324 } 325 326 table, err := kvstore.NewTable[uint8]("users", kvstore.NewIntValueEncoder[uint8]()) 327 if err != nil { 328 b.Fatal(err) 329 } 330 331 db.AddTable(table) 332 333 b.ResetTimer() 334 335 b.RunParallel(func(pb *testing.PB) { 336 for pb.Next() { 337 putErr := table.Set(strconv.Itoa(rand.Int()), 1) 338 if putErr != nil { 339 b.Fatal(putErr) 340 } 341 } 342 }) 343 } 344 345 func BenchmarkTable_Get(b *testing.B) { 346 runtime.GOMAXPROCS(4) 347 348 store, err := kvstore.OpenStore("test") 349 if err != nil { 350 b.Fatal(err) 351 } 352 defer func() { 353 _ = store.Close() 354 }() 355 356 db, err := store.NewDB("TEST_DB") 357 if err != nil { 358 b.Fatal(err) 359 } 360 361 table, err := kvstore.NewTable[uint8]("users", kvstore.NewIntValueEncoder[uint8]()) 362 if err != nil { 363 b.Fatal(err) 364 } 365 366 db.AddTable(table) 367 368 b.ResetTimer() 369 370 b.RunParallel(func(pb *testing.PB) { 371 for pb.Next() { 372 _, putErr := table.Get(types.String(rand.Int())) 373 if putErr != nil { 374 if kvstore.IsNotFound(putErr) { 375 continue 376 } 377 b.Fatal(putErr) 378 } 379 } 380 }) 381 } 382 383 /**func BenchmarkTable_NextId(b *testing.B) { 384 runtime.GOMAXPROCS(4) 385 386 store, err := kvstore.OpenStore("test") 387 if err != nil { 388 b.Fatal(err) 389 } 390 defer func() { 391 _ = store.Close() 392 }() 393 394 db, err := store.NewDB("TEST_DB") 395 if err != nil { 396 b.Fatal(err) 397 } 398 399 table, err := kvstore.NewTable[uint8]("users", kvstore.NewIntValueEncoder[uint8]()) 400 if err != nil { 401 b.Fatal(err) 402 } 403 404 db.AddTable(table) 405 406 b.ResetTimer() 407 408 b.RunParallel(func(pb *testing.PB) { 409 for pb.Next() { 410 _, nextErr := table.NextId("a") 411 if nextErr != nil { 412 b.Fatal(nextErr) 413 } 414 } 415 }) 416 } 417 **/