github.com/TeaOSLab/EdgeNode@v1.3.8/internal/caches/list_file_sqlite_test.go (about)

     1  // Copyright 2021 Liuxiangchao iwind.liu@gmail.com. All rights reserved.
     2  
     3  package caches_test
     4  
     5  import (
     6  	"github.com/TeaOSLab/EdgeNode/internal/caches"
     7  	"github.com/TeaOSLab/EdgeNode/internal/goman"
     8  	"github.com/TeaOSLab/EdgeNode/internal/utils/testutils"
     9  	"github.com/iwind/TeaGo/Tea"
    10  	"github.com/iwind/TeaGo/rands"
    11  	"github.com/iwind/TeaGo/types"
    12  	stringutil "github.com/iwind/TeaGo/utils/string"
    13  	"strconv"
    14  	"sync"
    15  	"testing"
    16  	"time"
    17  )
    18  
    19  func TestFileList_Init(t *testing.T) {
    20  	if !testutils.IsSingleTesting() {
    21  		return
    22  	}
    23  
    24  	var list = caches.NewSQLiteFileList(Tea.Root + "/data/cache-index/p1")
    25  
    26  	defer func() {
    27  		_ = list.Close()
    28  	}()
    29  
    30  	err := list.Init()
    31  	if err != nil {
    32  		t.Fatal(err)
    33  	}
    34  	defer func() {
    35  		_ = list.Close()
    36  	}()
    37  	t.Log("ok")
    38  }
    39  
    40  func TestFileList_Add(t *testing.T) {
    41  	if !testutils.IsSingleTesting() {
    42  		return
    43  	}
    44  
    45  	var list = caches.NewSQLiteFileList(Tea.Root + "/data/cache-index/p1").(*caches.SQLiteFileList)
    46  
    47  	defer func() {
    48  		_ = list.Close()
    49  	}()
    50  
    51  	err := list.Init()
    52  	if err != nil {
    53  		t.Fatal(err)
    54  	}
    55  
    56  	defer func() {
    57  		_ = list.Close()
    58  	}()
    59  
    60  	var hash = stringutil.Md5("123456")
    61  	t.Log("db index:", list.GetDBIndex(hash))
    62  	err = list.Add(hash, &caches.Item{
    63  		Key:        "123456",
    64  		ExpiresAt:  time.Now().Unix() + 1,
    65  		HeaderSize: 1,
    66  		MetaSize:   2,
    67  		BodySize:   3,
    68  		Host:       "teaos.cn",
    69  		ServerId:   1,
    70  	})
    71  	if err != nil {
    72  		t.Fatal(err)
    73  	}
    74  
    75  	t.Log(list.Exist(hash))
    76  
    77  	t.Log("ok")
    78  }
    79  
    80  func TestFileList_Add_Many(t *testing.T) {
    81  	if !testutils.IsSingleTesting() {
    82  		return
    83  	}
    84  
    85  	var list = caches.NewSQLiteFileList(Tea.Root + "/data/cache-index/p1")
    86  
    87  	defer func() {
    88  		_ = list.Close()
    89  	}()
    90  
    91  	err := list.Init()
    92  	if err != nil {
    93  		t.Fatal(err)
    94  	}
    95  
    96  	var before = time.Now()
    97  	const offset = 0
    98  	const count = 1_000_000
    99  	for i := offset; i < offset+count; i++ {
   100  		u := "https://edge.teaos.cn/123456" + strconv.Itoa(i)
   101  		_ = list.Add(stringutil.Md5(u), &caches.Item{
   102  			Key:        u,
   103  			ExpiresAt:  time.Now().Unix() + 3600,
   104  			HeaderSize: 1,
   105  			MetaSize:   2,
   106  			BodySize:   3,
   107  		})
   108  		if err != nil {
   109  			t.Fatal(err)
   110  		}
   111  		if i > 0 && i%10_000 == 0 {
   112  			t.Log(i, int(10000/time.Since(before).Seconds()), "qps")
   113  			before = time.Now()
   114  		}
   115  	}
   116  	t.Log("ok")
   117  }
   118  
   119  func TestFileList_Exist(t *testing.T) {
   120  	if !testutils.IsSingleTesting() {
   121  		return
   122  	}
   123  
   124  	var list = caches.NewSQLiteFileList(Tea.Root + "/data/cache-index/p1").(*caches.SQLiteFileList)
   125  	defer func() {
   126  		_ = list.Close()
   127  	}()
   128  
   129  	err := list.Init()
   130  	if err != nil {
   131  		t.Fatal(err)
   132  	}
   133  
   134  	total, _ := list.Count()
   135  	t.Log("total:", total)
   136  
   137  	var before = time.Now()
   138  	defer func() {
   139  		t.Log(time.Since(before).Seconds()*1000, "ms")
   140  	}()
   141  	{
   142  		var hash = stringutil.Md5("123456")
   143  		exists, _, err := list.Exist(hash)
   144  		if err != nil {
   145  			t.Fatal(err)
   146  		}
   147  		t.Log(hash, "exists:", exists)
   148  	}
   149  	{
   150  		var hash = stringutil.Md5("http://edge.teaos.cn/1234561")
   151  		exists, _, err := list.Exist(hash)
   152  		if err != nil {
   153  			t.Fatal(err)
   154  		}
   155  		t.Log(hash, "exists:", exists)
   156  	}
   157  }
   158  
   159  func TestFileList_Exist_Many_DB(t *testing.T) {
   160  	if !testutils.IsSingleTesting() {
   161  		return
   162  	}
   163  
   164  	// 测试在多个数据库下的性能
   165  	var listSlice = []caches.ListInterface{}
   166  	for i := 1; i <= 10; i++ {
   167  		var list = caches.NewSQLiteFileList(Tea.Root + "/data/data" + strconv.Itoa(i))
   168  		err := list.Init()
   169  		if err != nil {
   170  			t.Fatal(err)
   171  		}
   172  		listSlice = append(listSlice, list)
   173  	}
   174  
   175  	defer func() {
   176  		for _, list := range listSlice {
   177  			_ = list.Close()
   178  		}
   179  	}()
   180  
   181  	var wg = sync.WaitGroup{}
   182  	var threads = 8
   183  	wg.Add(threads)
   184  
   185  	var count = 200_000
   186  	var countLocker sync.Mutex
   187  	var tasks = make(chan int, count)
   188  	for i := 0; i < count; i++ {
   189  		tasks <- i
   190  	}
   191  
   192  	var hash = stringutil.Md5("http://edge.teaos.cn/1234561")
   193  
   194  	before := time.Now()
   195  	defer func() {
   196  		t.Log(time.Since(before).Seconds()*1000, "ms")
   197  	}()
   198  
   199  	for i := 0; i < threads; i++ {
   200  		goman.New(func() {
   201  			defer wg.Done()
   202  
   203  			for {
   204  				select {
   205  				case <-tasks:
   206  					countLocker.Lock()
   207  					count--
   208  					countLocker.Unlock()
   209  
   210  					var list = listSlice[rands.Int(0, len(listSlice)-1)]
   211  					_, _, _ = list.Exist(hash)
   212  				default:
   213  					return
   214  				}
   215  			}
   216  		})
   217  	}
   218  	wg.Wait()
   219  	t.Log("left:", count)
   220  }
   221  
   222  func TestFileList_CleanPrefix(t *testing.T) {
   223  	if !testutils.IsSingleTesting() {
   224  		return
   225  	}
   226  
   227  	var list = caches.NewSQLiteFileList(Tea.Root + "/data/cache-index/p1")
   228  
   229  	defer func() {
   230  		_ = list.Close()
   231  	}()
   232  
   233  	err := list.Init()
   234  	if err != nil {
   235  		t.Fatal(err)
   236  	}
   237  
   238  	before := time.Now()
   239  	err = list.CleanPrefix("123")
   240  	if err != nil {
   241  		t.Fatal(err)
   242  	}
   243  	t.Log(time.Since(before).Seconds()*1000, "ms")
   244  }
   245  
   246  func TestFileList_Remove(t *testing.T) {
   247  	if !testutils.IsSingleTesting() {
   248  		return
   249  	}
   250  
   251  	var list = caches.NewSQLiteFileList(Tea.Root + "/data/cache-index/p1").(*caches.SQLiteFileList)
   252  	defer func() {
   253  		_ = list.Close()
   254  	}()
   255  
   256  	err := list.Init()
   257  	if err != nil {
   258  		t.Fatal(err)
   259  	}
   260  
   261  	list.OnRemove(func(item *caches.Item) {
   262  		t.Logf("remove %#v", item)
   263  	})
   264  	err = list.Remove(stringutil.Md5("123456"))
   265  	if err != nil {
   266  		t.Fatal(err)
   267  	}
   268  	t.Log("ok")
   269  
   270  	t.Log("===count===")
   271  	t.Log(list.Count())
   272  }
   273  
   274  func TestFileList_Purge(t *testing.T) {
   275  	if !testutils.IsSingleTesting() {
   276  		return
   277  	}
   278  
   279  	var list = caches.NewSQLiteFileList(Tea.Root + "/data/cache-index/p1")
   280  
   281  	defer func() {
   282  		_ = list.Close()
   283  	}()
   284  
   285  	err := list.Init()
   286  	if err != nil {
   287  		t.Fatal(err)
   288  	}
   289  
   290  	var count = 0
   291  	_, err = list.Purge(caches.CountFileDB*2, func(hash string) error {
   292  		t.Log(hash)
   293  		count++
   294  		return nil
   295  	})
   296  	if err != nil {
   297  		t.Fatal(err)
   298  	}
   299  	t.Log("ok, purged", count, "items")
   300  }
   301  
   302  func TestFileList_PurgeLFU(t *testing.T) {
   303  	if !testutils.IsSingleTesting() {
   304  		return
   305  	}
   306  
   307  	var list = caches.NewSQLiteFileList(Tea.Root + "/data/cache-index/p1")
   308  
   309  	defer func() {
   310  		_ = list.Close()
   311  	}()
   312  
   313  	err := list.Init()
   314  	if err != nil {
   315  		t.Fatal(err)
   316  	}
   317  
   318  	var count = 0
   319  	err = list.PurgeLFU(caches.CountFileDB*2, func(hash string) error {
   320  		t.Log(hash)
   321  		count++
   322  		return nil
   323  	})
   324  	if err != nil {
   325  		t.Fatal(err)
   326  	}
   327  	t.Log("ok, purged", count, "items")
   328  }
   329  
   330  func TestFileList_Stat(t *testing.T) {
   331  	if !testutils.IsSingleTesting() {
   332  		return
   333  	}
   334  
   335  	var list = caches.NewSQLiteFileList(Tea.Root + "/data/cache-index/p1")
   336  
   337  	defer func() {
   338  		_ = list.Close()
   339  	}()
   340  
   341  	err := list.Init()
   342  	if err != nil {
   343  		t.Fatal(err)
   344  	}
   345  
   346  	stat, err := list.Stat(nil)
   347  	if err != nil {
   348  		t.Fatal(err)
   349  	}
   350  	t.Log("count:", stat.Count, "size:", stat.Size, "valueSize:", stat.ValueSize)
   351  }
   352  
   353  func TestFileList_Count(t *testing.T) {
   354  	if !testutils.IsSingleTesting() {
   355  		return
   356  	}
   357  
   358  	var list = caches.NewSQLiteFileList(Tea.Root + "/data")
   359  
   360  	defer func() {
   361  		_ = list.Close()
   362  	}()
   363  
   364  	err := list.Init()
   365  	if err != nil {
   366  		t.Fatal(err)
   367  	}
   368  	var before = time.Now()
   369  	count, err := list.Count()
   370  	if err != nil {
   371  		t.Fatal(err)
   372  	}
   373  	t.Log("count:", count)
   374  	t.Log(time.Since(before).Seconds()*1000, "ms")
   375  }
   376  
   377  func TestFileList_CleanAll(t *testing.T) {
   378  	if !testutils.IsSingleTesting() {
   379  		return
   380  	}
   381  
   382  	var list = caches.NewSQLiteFileList(Tea.Root + "/data")
   383  
   384  	defer func() {
   385  		_ = list.Close()
   386  	}()
   387  
   388  	err := list.Init()
   389  	if err != nil {
   390  		t.Fatal(err)
   391  	}
   392  	err = list.CleanAll()
   393  	if err != nil {
   394  		t.Fatal(err)
   395  	}
   396  	t.Log("ok")
   397  	t.Log(list.Count())
   398  }
   399  
   400  func TestFileList_UpgradeV3(t *testing.T) {
   401  	if !testutils.IsSingleTesting() {
   402  		return
   403  	}
   404  
   405  	var list = caches.NewSQLiteFileList(Tea.Root + "/data/cache-index/p43").(*caches.SQLiteFileList)
   406  
   407  	defer func() {
   408  		_ = list.Close()
   409  	}()
   410  
   411  	err := list.Init()
   412  	if err != nil {
   413  		t.Fatal(err)
   414  	}
   415  
   416  	defer func() {
   417  		_ = list.Close()
   418  	}()
   419  
   420  	err = list.UpgradeV3("/Users/WorkSpace/EdgeProject/EdgeCache/p43", false)
   421  	if err != nil {
   422  		t.Log(err)
   423  		return
   424  	}
   425  	t.Log("ok")
   426  }
   427  
   428  func BenchmarkFileList_Exist(b *testing.B) {
   429  	if !testutils.IsSingleTesting() {
   430  		return
   431  	}
   432  
   433  	var list = caches.NewSQLiteFileList(Tea.Root + "/data/cache-index/p1")
   434  
   435  	defer func() {
   436  		_ = list.Close()
   437  	}()
   438  
   439  	err := list.Init()
   440  	if err != nil {
   441  		b.Fatal(err)
   442  	}
   443  	b.ResetTimer()
   444  	for i := 0; i < b.N; i++ {
   445  		_, _, _ = list.Exist("f0eb5b87e0b0041f3917002c0707475f" + types.String(i))
   446  	}
   447  }