memory_test.go 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. // 运行测试:go test -race -v ./cache/ -run "TestMemory" -count=1
  2. package cache
  3. import (
  4. "sync"
  5. "testing"
  6. "time"
  7. "github.com/stretchr/testify/assert"
  8. )
  9. func TestMemoryGet(t *testing.T) {
  10. mem := NewMemory()
  11. err := mem.Set("username", "silenceper", 10*time.Second)
  12. assert.NoError(t, err)
  13. val := mem.Get("username")
  14. assert.Equal(t, "silenceper", val)
  15. val = mem.Get("unknown-key")
  16. assert.Nil(t, val)
  17. }
  18. func TestMemoryIsExist(t *testing.T) {
  19. mem := NewMemory()
  20. err := mem.Set("username", "silenceper", 10*time.Second)
  21. assert.NoError(t, err)
  22. assert.True(t, mem.IsExist("username"))
  23. assert.False(t, mem.IsExist("unknown-key"))
  24. }
  25. func TestMemoryDelete(t *testing.T) {
  26. mem := NewMemory()
  27. err := mem.Set("username", "silenceper", 10*time.Second)
  28. assert.NoError(t, err)
  29. err = mem.Delete("username")
  30. assert.NoError(t, err)
  31. // delete 不存在的 key 不应报错
  32. err = mem.Delete("unknown-key")
  33. assert.NoError(t, err)
  34. }
  35. func TestMemoryExpire(t *testing.T) {
  36. mem := NewMemory()
  37. err := mem.Set("username", "silenceper", 10*time.Millisecond)
  38. assert.NoError(t, err)
  39. assert.True(t, mem.IsExist("username"))
  40. time.Sleep(20 * time.Millisecond)
  41. assert.False(t, mem.IsExist("username"))
  42. assert.Nil(t, mem.Get("username"))
  43. }
  44. // TestMemoryConcurrentOps 验证 Get/IsExist/Set/Delete 并发执行不产生数据竞争
  45. func TestMemoryConcurrentOps(t *testing.T) {
  46. mem := NewMemory()
  47. _ = mem.Set("key", "value", time.Minute)
  48. var wg sync.WaitGroup
  49. for i := 0; i < 100; i++ {
  50. wg.Add(4)
  51. // 并发读
  52. go func() {
  53. defer wg.Done()
  54. _ = mem.Get("key")
  55. }()
  56. // 并发 IsExist
  57. go func() {
  58. defer wg.Done()
  59. _ = mem.IsExist("key")
  60. }()
  61. // 并发写
  62. go func(i int) {
  63. defer wg.Done()
  64. _ = mem.Set("key", i, time.Minute)
  65. }(i)
  66. // 并发删除
  67. go func() {
  68. defer wg.Done()
  69. _ = mem.Delete("key")
  70. }()
  71. }
  72. wg.Wait()
  73. }
  74. // TestMemoryConcurrentExpireAndRead 验证过期惰性删除在并发场景下不会死锁
  75. func TestMemoryConcurrentExpireAndRead(t *testing.T) {
  76. mem := NewMemory()
  77. var wg sync.WaitGroup
  78. for i := 0; i < 50; i++ {
  79. wg.Add(2)
  80. go func(i int) {
  81. defer wg.Done()
  82. key := "expire-key"
  83. _ = mem.Set(key, i, 5*time.Millisecond)
  84. }(i)
  85. go func() {
  86. defer wg.Done()
  87. time.Sleep(3 * time.Millisecond)
  88. // 此时 key 可能已过期,触发 deleteKey,验证不死锁
  89. _ = mem.Get("expire-key")
  90. _ = mem.IsExist("expire-key")
  91. }()
  92. }
  93. wg.Wait()
  94. }