mirror of
https://github.com/TeaOSLab/EdgeNode.git
synced 2025-11-03 06:40:25 +08:00
418 lines
7.3 KiB
Go
418 lines
7.3 KiB
Go
// Copyright 2024 GoEdge CDN goedge.cdn@gmail.com. All rights reserved. Official site: https://goedge.cn .
|
|
|
|
package kvstore_test
|
|
|
|
import (
|
|
"fmt"
|
|
"github.com/TeaOSLab/EdgeNode/internal/utils/kvstore"
|
|
"github.com/TeaOSLab/EdgeNode/internal/utils/testutils"
|
|
"github.com/iwind/TeaGo/assert"
|
|
"github.com/iwind/TeaGo/types"
|
|
"math/rand"
|
|
"runtime"
|
|
"strconv"
|
|
"testing"
|
|
"time"
|
|
)
|
|
|
|
func TestTable_Set(t *testing.T) {
|
|
store, err := kvstore.OpenStore("test")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
defer func() {
|
|
_ = store.Close()
|
|
}()
|
|
|
|
db, err := store.NewDB("TEST_DB")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
table, err := kvstore.NewTable[string]("users", kvstore.NewStringValueEncoder[string]())
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
db.AddTable(table)
|
|
|
|
const originValue = "b12345"
|
|
|
|
err = table.Set("a", originValue)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
value, err := table.Get("a")
|
|
if err != nil {
|
|
if kvstore.IsNotFound(err) {
|
|
t.Log("not found key")
|
|
return
|
|
}
|
|
t.Fatal(err)
|
|
}
|
|
t.Log("value:", value)
|
|
|
|
var a = assert.NewAssertion(t)
|
|
a.IsTrue(originValue == value)
|
|
}
|
|
|
|
func TestTable_Get(t *testing.T) {
|
|
store, err := kvstore.OpenStore("test")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
defer func() {
|
|
_ = store.Close()
|
|
}()
|
|
|
|
db, err := store.NewDB("TEST_DB")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
table, err := kvstore.NewTable[string]("users", kvstore.NewStringValueEncoder[string]())
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
db.AddTable(table)
|
|
|
|
for _, key := range []string{"a", "b", "c"} {
|
|
value, getErr := table.Get(key)
|
|
if getErr != nil {
|
|
if kvstore.IsNotFound(getErr) {
|
|
t.Log("not found key", key)
|
|
continue
|
|
}
|
|
t.Fatal(getErr)
|
|
}
|
|
t.Log(key, "=>", "value:", value)
|
|
}
|
|
}
|
|
|
|
func TestTable_Exist(t *testing.T) {
|
|
store, err := kvstore.OpenStore("test")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
defer func() {
|
|
_ = store.Close()
|
|
}()
|
|
|
|
db, err := store.NewDB("TEST_DB")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
table, err := kvstore.NewTable[string]("users", kvstore.NewStringValueEncoder[string]())
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
db.AddTable(table)
|
|
|
|
for _, key := range []string{"a", "b", "c", "12345"} {
|
|
b, checkErr := table.Exist(key)
|
|
if checkErr != nil {
|
|
t.Fatal(checkErr)
|
|
}
|
|
t.Log(key, "=>", b)
|
|
}
|
|
}
|
|
|
|
func TestTable_Delete(t *testing.T) {
|
|
var a = assert.NewAssertion(t)
|
|
|
|
store, err := kvstore.OpenStore("test")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
defer func() {
|
|
_ = store.Close()
|
|
}()
|
|
|
|
db, err := store.NewDB("TEST_DB")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
table, err := kvstore.NewTable[string]("users", kvstore.NewStringValueEncoder[string]())
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
db.AddTable(table)
|
|
|
|
value, err := table.Get("a123")
|
|
if err != nil {
|
|
if !kvstore.IsNotFound(err) {
|
|
t.Fatal(err)
|
|
}
|
|
} else {
|
|
t.Log("old value:", value)
|
|
}
|
|
|
|
err = table.Set("a123", "123456")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
{
|
|
value, err = table.Get("a123")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
a.IsTrue(value == "123456")
|
|
}
|
|
|
|
err = table.Delete("a123")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
{
|
|
_, err = table.Get("a123")
|
|
a.IsTrue(kvstore.IsNotFound(err))
|
|
}
|
|
}
|
|
|
|
func TestTable_Delete_Empty(t *testing.T) {
|
|
var a = assert.NewAssertion(t)
|
|
|
|
store, err := kvstore.OpenStore("test")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
defer func() {
|
|
_ = store.Close()
|
|
}()
|
|
|
|
db, err := store.NewDB("TEST_DB")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
table, err := kvstore.NewTable[string]("users", kvstore.NewStringValueEncoder[string]())
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
db.AddTable(table)
|
|
|
|
{
|
|
err = table.Delete("a1", "a2", "a3", "a4", "")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
}
|
|
|
|
{
|
|
err = table.Delete()
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
}
|
|
|
|
// set new
|
|
err = table.Set("a123", "123456")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
// delete again
|
|
{
|
|
err = table.Delete("a1", "a2", "a3", "a4", "")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
}
|
|
|
|
{
|
|
err = table.Delete()
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
}
|
|
|
|
// read
|
|
{
|
|
var value string
|
|
value, err = table.Get("a123")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
a.IsTrue(value == "123456")
|
|
}
|
|
}
|
|
|
|
func TestTable_Count(t *testing.T) {
|
|
var table = testOpenStoreTable[*testCachedItem](t, "cache_items", &testCacheItemEncoder[*testCachedItem]{})
|
|
|
|
defer func() {
|
|
_ = testingStore.Close()
|
|
}()
|
|
|
|
var before = time.Now()
|
|
count, err := table.Count()
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
var costSeconds = time.Since(before).Seconds()
|
|
t.Log("count:", count, "cost:", costSeconds*1000, "ms", "qps:", fmt.Sprintf("%.2fM/s", float64(count)/costSeconds/1_000_000))
|
|
|
|
// watch memory usage
|
|
if testutils.IsSingleTesting() {
|
|
//time.Sleep(5 * time.Minute)
|
|
}
|
|
}
|
|
|
|
func TestTable_Truncate(t *testing.T) {
|
|
var table = testOpenStoreTable[*testCachedItem](t, "cache_items", &testCacheItemEncoder[*testCachedItem]{})
|
|
|
|
defer func() {
|
|
_ = testingStore.Close()
|
|
}()
|
|
|
|
var before = time.Now()
|
|
err := table.Truncate()
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
var costSeconds = time.Since(before).Seconds()
|
|
t.Log("cost:", costSeconds*1000, "ms")
|
|
|
|
t.Log("===after truncate===")
|
|
testInspectDB(t)
|
|
}
|
|
|
|
func TestTable_ComposeFieldKey(t *testing.T) {
|
|
var a = assert.NewAssertion(t)
|
|
|
|
var table = testOpenStoreTable[*testCachedItem](t, "cache_items", &testCacheItemEncoder[*testCachedItem]{})
|
|
|
|
defer func() {
|
|
_ = testingStore.Close()
|
|
}()
|
|
|
|
var fieldKeyBytes = table.ComposeFieldKey([]byte("Lily"), "username", []byte("lucy"))
|
|
t.Log(string(fieldKeyBytes))
|
|
fieldValueBytes, keyValueBytes, err := table.DecodeFieldKey("username", fieldKeyBytes)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
t.Log("field:", string(fieldValueBytes), "key:", string(keyValueBytes))
|
|
a.IsTrue(string(fieldValueBytes) == "lucy")
|
|
a.IsTrue(string(keyValueBytes) == "Lily")
|
|
}
|
|
|
|
func BenchmarkTable_Set(b *testing.B) {
|
|
runtime.GOMAXPROCS(4)
|
|
|
|
store, err := kvstore.OpenStore("test")
|
|
if err != nil {
|
|
b.Fatal(err)
|
|
}
|
|
defer func() {
|
|
_ = store.Close()
|
|
}()
|
|
|
|
db, err := store.NewDB("TEST_DB")
|
|
if err != nil {
|
|
b.Fatal(err)
|
|
}
|
|
|
|
table, err := kvstore.NewTable[uint8]("users", kvstore.NewIntValueEncoder[uint8]())
|
|
if err != nil {
|
|
b.Fatal(err)
|
|
}
|
|
|
|
db.AddTable(table)
|
|
|
|
b.ResetTimer()
|
|
|
|
b.RunParallel(func(pb *testing.PB) {
|
|
for pb.Next() {
|
|
putErr := table.Set(strconv.Itoa(rand.Int()), 1)
|
|
if putErr != nil {
|
|
b.Fatal(putErr)
|
|
}
|
|
}
|
|
})
|
|
}
|
|
|
|
func BenchmarkTable_Get(b *testing.B) {
|
|
runtime.GOMAXPROCS(4)
|
|
|
|
store, err := kvstore.OpenStore("test")
|
|
if err != nil {
|
|
b.Fatal(err)
|
|
}
|
|
defer func() {
|
|
_ = store.Close()
|
|
}()
|
|
|
|
db, err := store.NewDB("TEST_DB")
|
|
if err != nil {
|
|
b.Fatal(err)
|
|
}
|
|
|
|
table, err := kvstore.NewTable[uint8]("users", kvstore.NewIntValueEncoder[uint8]())
|
|
if err != nil {
|
|
b.Fatal(err)
|
|
}
|
|
|
|
db.AddTable(table)
|
|
|
|
b.ResetTimer()
|
|
|
|
b.RunParallel(func(pb *testing.PB) {
|
|
for pb.Next() {
|
|
_, putErr := table.Get(types.String(rand.Int()))
|
|
if putErr != nil {
|
|
if kvstore.IsNotFound(putErr) {
|
|
continue
|
|
}
|
|
b.Fatal(putErr)
|
|
}
|
|
}
|
|
})
|
|
}
|
|
|
|
/**func BenchmarkTable_NextId(b *testing.B) {
|
|
runtime.GOMAXPROCS(4)
|
|
|
|
store, err := kvstore.OpenStore("test")
|
|
if err != nil {
|
|
b.Fatal(err)
|
|
}
|
|
defer func() {
|
|
_ = store.Close()
|
|
}()
|
|
|
|
db, err := store.NewDB("TEST_DB")
|
|
if err != nil {
|
|
b.Fatal(err)
|
|
}
|
|
|
|
table, err := kvstore.NewTable[uint8]("users", kvstore.NewIntValueEncoder[uint8]())
|
|
if err != nil {
|
|
b.Fatal(err)
|
|
}
|
|
|
|
db.AddTable(table)
|
|
|
|
b.ResetTimer()
|
|
|
|
b.RunParallel(func(pb *testing.PB) {
|
|
for pb.Next() {
|
|
_, nextErr := table.NextId("a")
|
|
if nextErr != nil {
|
|
b.Fatal(nextErr)
|
|
}
|
|
}
|
|
})
|
|
}
|
|
**/
|