mirror of
				https://github.com/gofiber/storage.git
				synced 2025-10-27 02:10:21 +08:00 
			
		
		
		
	
		
			
				
	
	
		
			285 lines
		
	
	
		
			5.4 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			285 lines
		
	
	
		
			5.4 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| package leveldb
 | ||
| 
 | ||
| import (
 | ||
| 	"os"
 | ||
| 	"testing"
 | ||
| 	"time"
 | ||
| 
 | ||
| 	"github.com/stretchr/testify/require"
 | ||
| )
 | ||
| 
 | ||
| func removeAllFiles(dir string) error {
 | ||
| 	return os.RemoveAll(dir)
 | ||
| }
 | ||
| 
 | ||
| func Test_New_EmptyConfig(t *testing.T) {
 | ||
| 	db := New()
 | ||
| 	require.NotNil(t, db)
 | ||
| 
 | ||
| 	_, err := os.Stat("./fiber.leveldb")
 | ||
| 	require.Nil(t, err)
 | ||
| 
 | ||
| 	err = removeAllFiles("./fiber.leveldb")
 | ||
| 	require.Nil(t, err)
 | ||
| }
 | ||
| 
 | ||
| func Test_New_WithConfig(t *testing.T) {
 | ||
| 	db := New(Config{
 | ||
| 		Path: "./testdb",
 | ||
| 	})
 | ||
| 	require.NotNil(t, db)
 | ||
| 	_, err := os.Stat("./testdb")
 | ||
| 	require.Nil(t, err)
 | ||
| 
 | ||
| 	err = removeAllFiles("./testdb")
 | ||
| 	require.Nil(t, err)
 | ||
| }
 | ||
| 
 | ||
| func Test_Set_Overwrite(t *testing.T) {
 | ||
| 	db := New()
 | ||
| 
 | ||
| 	db.Set("key", []byte("value"), time.Second*1)
 | ||
| 	db.Set("key", []byte("value2"), time.Second*1)
 | ||
| 
 | ||
| 	value, err := db.Get("key")
 | ||
| 	require.Nil(t, err)
 | ||
| 	require.Equal(t, []byte("value2"), value)
 | ||
| 
 | ||
| 	err = removeAllFiles("./fiber.leveldb")
 | ||
| 	require.Nil(t, err)
 | ||
| }
 | ||
| 
 | ||
| func Test_Get_For0Second(t *testing.T) {
 | ||
| 	db := New()
 | ||
| 
 | ||
| 	db.Set("key", []byte("value"), 0)
 | ||
| 
 | ||
| 	_, err := db.Get("key")
 | ||
| 	require.Nil(t, err)
 | ||
| 
 | ||
| 	err = removeAllFiles("./fiber.leveldb")
 | ||
| 	require.Nil(t, err)
 | ||
| }
 | ||
| 
 | ||
| func Test_Get_ForExpired100Millisecond(t *testing.T) {
 | ||
| 	db := New()
 | ||
| 
 | ||
| 	require.NoError(t, db.Set("key", []byte("value"), time.Millisecond*100))
 | ||
| 
 | ||
| 	// Anahtarın silinmesini bekle
 | ||
| 	deadline := time.Now().Add(time.Second)
 | ||
| 	for time.Now().Before(deadline) {
 | ||
| 		value, err := db.Get("key")
 | ||
| 		if err == nil && value == nil {
 | ||
| 			break
 | ||
| 		}
 | ||
| 		time.Sleep(time.Millisecond * 10)
 | ||
| 	}
 | ||
| 
 | ||
| 	value, err := db.Get("key")
 | ||
| 	require.Nil(t, err)
 | ||
| 	require.Nil(t, value)
 | ||
| 
 | ||
| 	err = removeAllFiles("./fiber.leveldb")
 | ||
| 	require.Nil(t, err)
 | ||
| }
 | ||
| 
 | ||
| func Test_Delete_WhileThereIsData(t *testing.T) {
 | ||
| 	db := New()
 | ||
| 
 | ||
| 	db.Set("key", []byte("value"), time.Second*1)
 | ||
| 
 | ||
| 	err := db.Delete("key")
 | ||
| 	require.Nil(t, err)
 | ||
| 
 | ||
| 	value, err := db.Get("key")
 | ||
| 	require.Nil(t, err)
 | ||
| 	require.Nil(t, value)
 | ||
| 
 | ||
| 	err = removeAllFiles("./fiber.leveldb")
 | ||
| 	require.Nil(t, err)
 | ||
| 
 | ||
| }
 | ||
| 
 | ||
| func Test_Reset(t *testing.T) {
 | ||
| 	db := New()
 | ||
| 
 | ||
| 	db.Set("key1", []byte("value1"), time.Second*1)
 | ||
| 	db.Set("key2", []byte("value2"), time.Second*1)
 | ||
| 	db.Set("key3", []byte("value3"), time.Second*1)
 | ||
| 
 | ||
| 	require.NoError(t, db.Reset())
 | ||
| 
 | ||
| 	value, err := db.Get("key1")
 | ||
| 	require.Nil(t, err)
 | ||
| 	require.Nil(t, value)
 | ||
| 
 | ||
| 	value, err = db.Get("key2")
 | ||
| 	require.Nil(t, err)
 | ||
| 	require.Nil(t, value)
 | ||
| 
 | ||
| 	value, err = db.Get("key3")
 | ||
| 	require.Nil(t, err)
 | ||
| 	require.Nil(t, value)
 | ||
| 
 | ||
| 	err = removeAllFiles("./fiber.leveldb")
 | ||
| 	require.Nil(t, err)
 | ||
| 
 | ||
| }
 | ||
| 
 | ||
| func Test_Close(t *testing.T) {
 | ||
| 	db := New()
 | ||
| 
 | ||
| 	db.Close()
 | ||
| 
 | ||
| 	err := db.Conn().Put([]byte("key"), []byte("value"), nil)
 | ||
| 	require.Error(t, err)
 | ||
| 
 | ||
| 	err = removeAllFiles("./fiber.leveldb")
 | ||
| 	require.Nil(t, err)
 | ||
| }
 | ||
| 
 | ||
| func Test_GarbageCollection_AfterWorking(t *testing.T) {
 | ||
| 	db := New(Config{
 | ||
| 		GCInterval: time.Millisecond * 100,
 | ||
| 	})
 | ||
| 
 | ||
| 	require.NoError(t, db.Set("key", []byte("value"), time.Millisecond*100))
 | ||
| 
 | ||
| 	deadline := time.Now().Add(time.Second)
 | ||
| 	for time.Now().Before(deadline) {
 | ||
| 		_, err := db.Conn().Get([]byte("key"), nil)
 | ||
| 		if err != nil {
 | ||
| 			break
 | ||
| 		}
 | ||
| 		time.Sleep(time.Millisecond * 10)
 | ||
| 	}
 | ||
| 
 | ||
| 	value, err := db.Conn().Get([]byte("key"), nil)
 | ||
| 	require.Error(t, err)
 | ||
| 	require.Equal(t, []byte{}, value)
 | ||
| 
 | ||
| 	err = removeAllFiles("./fiber.leveldb")
 | ||
| 	require.Nil(t, err)
 | ||
| }
 | ||
| 
 | ||
| func Test_GarbageCollection_BeforeWorking(t *testing.T) {
 | ||
| 	t.Cleanup(func() {
 | ||
| 		require.NoError(t, removeAllFiles("./fiber.leveldb"))
 | ||
| 	})
 | ||
| 
 | ||
| 	db := New(Config{
 | ||
| 		GCInterval: time.Second * 1,
 | ||
| 	})
 | ||
| 	require.NoError(t, db.Set("key", []byte("value"), time.Second*1))
 | ||
| 
 | ||
| 	value, err := db.Conn().Get([]byte("key"), nil)
 | ||
| 	require.Nil(t, err)
 | ||
| 	require.NotNil(t, value)
 | ||
| }
 | ||
| 
 | ||
| func Test_GarbageCollection_Interval(t *testing.T) {
 | ||
| 	t.Cleanup(func() {
 | ||
| 		require.NoError(t, removeAllFiles("./fiber.leveldb"))
 | ||
| 	})
 | ||
| 
 | ||
| 	db := New(Config{
 | ||
| 		GCInterval: time.Hour, // Uzun aralık
 | ||
| 	})
 | ||
| 	require.NoError(t, db.Set("key", []byte("value"), time.Millisecond))
 | ||
| 
 | ||
| 	// GC çalışmadığı için değer hala var olmalı
 | ||
| 	deadline := time.Now().Add(time.Millisecond * 100)
 | ||
| 	for time.Now().Before(deadline) {
 | ||
| 		value, err := db.Conn().Get([]byte("key"), nil)
 | ||
| 		if err == nil && value != nil {
 | ||
| 			return
 | ||
| 		}
 | ||
| 		time.Sleep(time.Millisecond * 10)
 | ||
| 	}
 | ||
| 
 | ||
| 	t.Error("value should still exist as GC hasn't run yet")
 | ||
| }
 | ||
| 
 | ||
| func Test_Close_Channel(t *testing.T) {
 | ||
| 	db := New()
 | ||
| 
 | ||
| 	err := db.Close()
 | ||
| 	require.Nil(t, err)
 | ||
| 
 | ||
| 	select {
 | ||
| 	case _, ok := <-db.done:
 | ||
| 		require.False(t, ok, "channel should be closed")
 | ||
| 	default:
 | ||
| 		t.Error("channel should be closed")
 | ||
| 	}
 | ||
| 
 | ||
| 	err = removeAllFiles("./fiber.leveldb")
 | ||
| 	require.Nil(t, err)
 | ||
| }
 | ||
| 
 | ||
| func Benchmark_Set(b *testing.B) {
 | ||
| 	db := New()
 | ||
| 	defer func() {
 | ||
| 		_ = db.Close()
 | ||
| 		_ = removeAllFiles("./fiber.leveldb")
 | ||
| 	}()
 | ||
| 
 | ||
| 	key := "test_key"
 | ||
| 	value := []byte("test_value")
 | ||
| 
 | ||
| 	b.ResetTimer()
 | ||
| 	b.RunParallel(func(pb *testing.PB) {
 | ||
| 		for pb.Next() {
 | ||
| 			if err := db.Set(key, value, 0); err != nil {
 | ||
| 				b.Fatal(err)
 | ||
| 			}
 | ||
| 		}
 | ||
| 	})
 | ||
| }
 | ||
| 
 | ||
| func Benchmark_Get(b *testing.B) {
 | ||
| 	db := New()
 | ||
| 	defer func() {
 | ||
| 		_ = db.Close()
 | ||
| 		_ = removeAllFiles("./fiber.leveldb")
 | ||
| 	}()
 | ||
| 
 | ||
| 	key := "test_key"
 | ||
| 	value := []byte("test_value")
 | ||
| 	if err := db.Set(key, value, 0); err != nil {
 | ||
| 		b.Fatal(err)
 | ||
| 	}
 | ||
| 
 | ||
| 	b.ResetTimer()
 | ||
| 	b.RunParallel(func(pb *testing.PB) {
 | ||
| 		for pb.Next() {
 | ||
| 			if _, err := db.Get(key); err != nil {
 | ||
| 				b.Fatal(err)
 | ||
| 			}
 | ||
| 		}
 | ||
| 	})
 | ||
| }
 | ||
| 
 | ||
| func Benchmark_Delete(b *testing.B) {
 | ||
| 	db := New()
 | ||
| 	defer func() {
 | ||
| 		_ = db.Close()
 | ||
| 		_ = removeAllFiles("./fiber.leveldb")
 | ||
| 	}()
 | ||
| 
 | ||
| 	key := "test_key"
 | ||
| 	if err := db.Set(key, []byte("test_value"), 0); err != nil {
 | ||
| 		b.Fatal(err)
 | ||
| 	}
 | ||
| 
 | ||
| 	b.ResetTimer()
 | ||
| 	b.RunParallel(func(pb *testing.PB) {
 | ||
| 		for pb.Next() {
 | ||
| 			if err := db.Delete(key); err != nil {
 | ||
| 				b.Fatal(err)
 | ||
| 			}
 | ||
| 		}
 | ||
| 	})
 | ||
| }
 | 
