github.com/GuanceCloud/cliutils@v1.1.21/diskcache/open_test.go (about) 1 // Unless explicitly stated otherwise all files in this repository are licensed 2 // under the MIT License. 3 // This product includes software developed at Guance Cloud (https://www.guance.com/). 4 // Copyright 2021-present Guance, Inc. 5 6 package diskcache 7 8 import ( 9 "os" 10 "path/filepath" 11 "sync" 12 T "testing" 13 "time" 14 15 "github.com/stretchr/testify/assert" 16 ) 17 18 func TestOpen(t *T.T) { 19 t.Run("reopen-with-or-without-pos", func(t *T.T) { 20 p := t.TempDir() 21 22 // lock then no-lock 23 c, err := Open(WithPath(p)) 24 assert.NoError(t, err) 25 assert.NoError(t, c.Close()) 26 27 c2, err := Open(WithPath(p), WithNoPos(true)) 28 assert.NoError(t, err) 29 assert.NoError(t, c2.Close()) 30 31 // no-lock then lock 32 c, err = Open(WithPath(p), WithNoPos(true)) 33 assert.NoError(t, err) 34 assert.NoError(t, c.Close()) 35 36 c2, err = Open(WithPath(p)) 37 assert.NoError(t, err) 38 assert.NoError(t, c2.Close()) 39 }) 40 41 t.Run("reopen-with-or-without-lock", func(t *T.T) { 42 p := t.TempDir() 43 44 // lock then no-lock 45 c, err := Open(WithPath(p)) 46 assert.NoError(t, err) 47 assert.NoError(t, c.Close()) 48 49 c2, err := Open(WithPath(p), WithNoLock(true)) 50 assert.NoError(t, err) 51 assert.NoError(t, c2.Close()) 52 53 // no-lock then lock 54 c, err = Open(WithPath(p), WithNoLock(true)) 55 assert.NoError(t, err) 56 assert.NoError(t, c.Close()) 57 58 c2, err = Open(WithPath(p)) 59 assert.NoError(t, err) 60 assert.NoError(t, c2.Close()) 61 }) 62 63 t.Run("open-with-lock", func(t *T.T) { 64 p := t.TempDir() 65 c, err := Open(WithPath(p)) 66 assert.NoError(t, err) 67 68 fi, err := os.Stat(filepath.Join(p, ".lock")) 69 assert.NoError(t, err) 70 71 t.Logf("lock file info: %+#v", fi) 72 73 t.Cleanup(func() { 74 assert.NoError(t, c.Close()) 75 os.RemoveAll(p) 76 }) 77 }) 78 79 t.Run("open-twice-with-error", func(t *T.T) { 80 p := t.TempDir() 81 c, err := Open(WithPath(p)) 82 assert.NoError(t, err) 83 84 _, err = Open(WithPath(p)) 85 assert.Error(t, err, "expect lock failed") 86 87 t.Logf("[expected] Open: %q", err) 88 89 t.Cleanup(func() { 90 assert.NoError(t, c.Close()) 91 os.RemoveAll(p) 92 }) 93 }) 94 95 t.Run("multi-open-until-ok", func(t *T.T) { 96 p := t.TempDir() 97 c, err := Open(WithPath(p)) 98 assert.NoError(t, err) 99 100 // hold the cache for 5 seconds 101 go func() { 102 time.Sleep(time.Second * 2) 103 assert.NoError(t, c.Close()) 104 t.Logf("c Closed") 105 }() 106 107 var c2 *DiskCache 108 for { // retry until ok 109 c2, err = Open(WithPath(p)) 110 if err != nil { 111 t.Logf("[expected] Open: %q, path: %s", err, p) 112 time.Sleep(time.Second) 113 } else { 114 break 115 } 116 } 117 118 t.Cleanup(func() { 119 assert.NoError(t, c2.Close()) 120 }) 121 }) 122 123 t.Run("multi-open-wihout-lock", func(t *T.T) { 124 p := t.TempDir() 125 c, err := Open(WithPath(p), WithNoLock(true)) 126 assert.NoError(t, err) 127 128 var wg sync.WaitGroup 129 130 wg.Add(1) 131 // hold the cache for 5 seconds 132 go func() { 133 defer wg.Done() 134 time.Sleep(time.Second * 5) 135 assert.NoError(t, c.Close()) 136 }() 137 138 c2, err := Open(WithPath(p), WithNoLock(true)) 139 assert.NoError(t, err) // no error on re-Open() without lock 140 defer c2.Close() 141 142 wg.Wait() 143 }) 144 145 t.Run("test-empty-pos-file", func(t *T.T) { 146 p := t.TempDir() 147 posFile := filepath.Join(p, ".pos") 148 149 f, err := os.Create(posFile) 150 assert.NoError(t, err) 151 152 dq, err := Open(WithPath(p), WithCapacity(1<<29), WithNoFallbackOnError(true)) 153 assert.NoError(t, err) 154 assert.NoError(t, dq.Close()) 155 156 _, err = f.WriteString("1234") 157 assert.NoError(t, err) 158 assert.NoError(t, f.Sync()) 159 160 dq, err = Open(WithPath(p), WithCapacity(1<<29), WithNoFallbackOnError(true)) 161 assert.NoError(t, err) 162 assert.Equal(t, int64(0), dq.pos.Seek) 163 assert.NoError(t, dq.Close()) 164 165 _, err = f.WriteString("5678") 166 assert.NoError(t, err) 167 assert.NoError(t, f.Sync()) 168 169 dq, err = Open(WithPath(p), WithCapacity(1<<29), WithNoFallbackOnError(true)) 170 assert.NoError(t, err) 171 assert.Equal(t, int64(0), dq.pos.Seek) 172 assert.NoError(t, dq.Close()) 173 174 assert.NoError(t, f.Close()) 175 }) 176 } 177 178 func TestClose(t *T.T) { 179 t.Run("multl-close", func(t *T.T) { 180 p := t.TempDir() 181 c, err := Open(WithPath(p)) 182 assert.NoError(t, err) 183 184 assert.NoError(t, c.Close()) 185 assert.NoError(t, c.Close()) 186 187 t.Cleanup(func() { 188 os.RemoveAll(p) 189 }) 190 }) 191 }