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  **/