github.com/uber/kraken@v0.1.4/lib/store/cleanup_test.go (about) 1 // Copyright (c) 2016-2019 Uber Technologies, Inc. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 package store 15 16 import ( 17 "io/ioutil" 18 "os" 19 "testing" 20 "time" 21 22 "github.com/uber/kraken/core" 23 "github.com/uber/kraken/lib/store/base" 24 "github.com/uber/kraken/lib/store/metadata" 25 "github.com/uber/kraken/utils/testutil" 26 27 "github.com/andres-erbsen/clock" 28 "github.com/stretchr/testify/require" 29 "github.com/uber-go/tally" 30 ) 31 32 func fileOpFixture(clk clock.Clock) (base.FileState, base.FileOp, func()) { 33 var cleanup testutil.Cleanup 34 defer cleanup.Recover() 35 36 dir, err := ioutil.TempDir("/tmp", "cleanup_test") 37 if err != nil { 38 panic(err) 39 } 40 cleanup.Add(func() { os.RemoveAll(dir) }) 41 42 state := base.NewFileState(dir) 43 44 store := base.NewLocalFileStore(clk) 45 46 return state, store.NewFileOp().AcceptState(state), cleanup.Run 47 } 48 49 func TestCleanupManagerAddJob(t *testing.T) { 50 require := require.New(t) 51 52 clk := clock.New() 53 54 m, err := newCleanupManager(clk, tally.NoopScope) 55 require.NoError(err) 56 defer m.stop() 57 58 state, op, cleanup := fileOpFixture(clk) 59 defer cleanup() 60 61 config := CleanupConfig{ 62 Interval: time.Second, 63 TTI: time.Second, 64 } 65 m.addJob("test_cleanup", config, op) 66 67 name := "test_file" 68 69 require.NoError(op.CreateFile(name, state, 0)) 70 71 time.Sleep(2 * time.Second) 72 73 _, err = op.GetFileStat(name) 74 require.True(os.IsNotExist(err)) 75 } 76 77 func TestCleanupManagerDeleteIdleFiles(t *testing.T) { 78 require := require.New(t) 79 80 clk := clock.NewMock() 81 clk.Set(time.Now()) 82 tti := 6 * time.Hour 83 ttl := 24 * time.Hour 84 85 m, err := newCleanupManager(clk, tally.NoopScope) 86 require.NoError(err) 87 defer m.stop() 88 89 state, op, cleanup := fileOpFixture(clk) 90 defer cleanup() 91 92 var names []string 93 for i := 0; i < 100; i++ { 94 names = append(names, core.DigestFixture().Hex()) 95 } 96 97 idle := names[:50] 98 for _, name := range idle { 99 require.NoError(op.CreateFile(name, state, 0)) 100 } 101 102 clk.Add(tti + 1) 103 104 active := names[50:] 105 for _, name := range active { 106 require.NoError(op.CreateFile(name, state, 0)) 107 } 108 109 _, err = m.scan(op, tti, ttl) 110 require.NoError(err) 111 112 for _, name := range idle { 113 _, err := op.GetFileStat(name) 114 require.True(os.IsNotExist(err)) 115 } 116 for _, name := range active { 117 _, err := op.GetFileStat(name) 118 require.NoError(err) 119 } 120 } 121 122 func TestCleanupManagerDeleteExpiredFiles(t *testing.T) { 123 require := require.New(t) 124 125 clk := clock.NewMock() 126 clk.Set(time.Now()) 127 tti := 6 * time.Hour 128 ttl := 24 * time.Hour 129 130 m, err := newCleanupManager(clk, tally.NoopScope) 131 require.NoError(err) 132 defer m.stop() 133 134 state, op, cleanup := fileOpFixture(clk) 135 defer cleanup() 136 137 var names []string 138 for i := 0; i < 10; i++ { 139 names = append(names, core.DigestFixture().Hex()) 140 } 141 for _, name := range names { 142 require.NoError(op.CreateFile(name, state, 0)) 143 } 144 145 _, err = m.scan(op, tti, ttl) 146 require.NoError(err) 147 148 for _, name := range names { 149 _, err := op.GetFileStat(name) 150 require.NoError(err) 151 } 152 153 clk.Add(ttl + 1) 154 155 _, err = m.scan(op, tti, ttl) 156 require.NoError(err) 157 158 for _, name := range names { 159 _, err := op.GetFileStat(name) 160 require.True(os.IsNotExist(err)) 161 } 162 } 163 164 func TestCleanupManagerSkipsPersistedFiles(t *testing.T) { 165 require := require.New(t) 166 167 clk := clock.NewMock() 168 clk.Set(time.Now()) 169 tti := 48 * time.Hour 170 ttl := 24 * time.Hour 171 172 m, err := newCleanupManager(clk, tally.NoopScope) 173 require.NoError(err) 174 defer m.stop() 175 176 state, op, cleanup := fileOpFixture(clk) 177 defer cleanup() 178 179 var names []string 180 for i := 0; i < 100; i++ { 181 names = append(names, core.DigestFixture().Hex()) 182 } 183 184 idle := names[:50] 185 for _, name := range idle { 186 require.NoError(op.CreateFile(name, state, 0)) 187 } 188 189 persisted := names[50:] 190 for _, name := range persisted { 191 require.NoError(op.CreateFile(name, state, 0)) 192 _, err := op.SetFileMetadata(name, metadata.NewPersist(true)) 193 require.NoError(err) 194 } 195 196 clk.Add(tti + 1) 197 198 _, err = m.scan(op, tti, ttl) 199 require.NoError(err) 200 201 for _, name := range idle { 202 _, err := op.GetFileStat(name) 203 require.True(os.IsNotExist(err)) 204 } 205 for _, name := range persisted { 206 _, err := op.GetFileStat(name) 207 require.NoError(err) 208 } 209 } 210 211 func TestCleanupManageDiskUsage(t *testing.T) { 212 require := require.New(t) 213 214 clk := clock.New() 215 216 m, err := newCleanupManager(clk, tally.NoopScope) 217 require.NoError(err) 218 defer m.stop() 219 220 state, op, cleanup := fileOpFixture(clk) 221 defer cleanup() 222 223 for i := 0; i < 100; i++ { 224 require.NoError(op.CreateFile(core.DigestFixture().Hex(), state, 5)) 225 } 226 227 usage, err := m.scan(op, time.Hour, time.Hour) 228 require.NoError(err) 229 require.Equal(int64(500), usage) 230 }