github.com/hasnat/dolt/go@v0.0.0-20210628190320-9eb5d843fbb7/store/nbs/fs_table_cache_test.go (about) 1 // Copyright 2019 Dolthub, 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 // 15 // This file incorporates work covered by the following copyright and 16 // permission notice: 17 // 18 // Copyright 2017 Attic Labs, Inc. All rights reserved. 19 // Licensed under the Apache License, version 2.0: 20 // http://www.apache.org/licenses/LICENSE-2.0 21 22 package nbs 23 24 import ( 25 "bytes" 26 "io" 27 "io/ioutil" 28 "os" 29 "path/filepath" 30 "sort" 31 "testing" 32 33 "github.com/stretchr/testify/assert" 34 "github.com/stretchr/testify/require" 35 ) 36 37 func TestFSTableCache(t *testing.T) { 38 datas := [][]byte{[]byte("hello"), []byte("world"), []byte("goodbye")} 39 sort.SliceStable(datas, func(i, j int) bool { return len(datas[i]) < len(datas[j]) }) 40 41 t.Run("ExpireLRU", func(t *testing.T) { 42 t.Parallel() 43 dir := makeTempDir(t) 44 defer os.RemoveAll(dir) 45 46 sum := 0 47 for _, s := range datas[1:] { 48 sum += len(s) 49 } 50 51 tc, err := newFSTableCache(dir, uint64(sum), len(datas)) 52 require.NoError(t, err) 53 for _, d := range datas { 54 err := tc.store(computeAddr(d), bytes.NewReader(d), uint64(len(d))) 55 require.NoError(t, err) 56 } 57 58 expiredName := computeAddr(datas[0]) 59 r, err := tc.checkout(expiredName) 60 require.NoError(t, err) 61 assert.Nil(t, r) 62 _, fserr := os.Stat(filepath.Join(dir, expiredName.String())) 63 assert.True(t, os.IsNotExist(fserr)) 64 65 for _, d := range datas[1:] { 66 name := computeAddr(d) 67 r, err := tc.checkout(name) 68 require.NoError(t, err) 69 assert.NotNil(t, r) 70 assertDataInReaderAt(t, d, r) 71 _, fserr := os.Stat(filepath.Join(dir, name.String())) 72 assert.False(t, os.IsNotExist(fserr)) 73 } 74 }) 75 76 t.Run("Init", func(t *testing.T) { 77 t.Run("Success", func(t *testing.T) { 78 t.Parallel() 79 dir := makeTempDir(t) 80 defer os.RemoveAll(dir) 81 assert := assert.New(t) 82 83 var names []addr 84 for i := byte(0); i < 4; i++ { 85 name := computeAddr([]byte{i}) 86 require.NoError(t, ioutil.WriteFile(filepath.Join(dir, name.String()), nil, 0666)) 87 names = append(names, name) 88 } 89 90 ftc, err := newFSTableCache(dir, 1024, 4) 91 require.NoError(t, err) 92 assert.NotNil(ftc) 93 94 for _, name := range names { 95 assert.NotNil(ftc.checkout(name)) 96 } 97 }) 98 99 t.Run("BadFile", func(t *testing.T) { 100 t.Parallel() 101 dir := makeTempDir(t) 102 defer os.RemoveAll(dir) 103 104 require.NoError(t, ioutil.WriteFile(filepath.Join(dir, "boo"), nil, 0666)) 105 _, err := newFSTableCache(dir, 1024, 4) 106 assert.Error(t, err) 107 }) 108 109 t.Run("ClearTempFile", func(t *testing.T) { 110 t.Parallel() 111 dir := makeTempDir(t) 112 defer os.RemoveAll(dir) 113 114 tempFile := filepath.Join(dir, tempTablePrefix+"boo") 115 require.NoError(t, ioutil.WriteFile(tempFile, nil, 0666)) 116 _, err := newFSTableCache(dir, 1024, 4) 117 require.NoError(t, err) 118 _, fserr := os.Stat(tempFile) 119 assert.True(t, os.IsNotExist(fserr)) 120 }) 121 122 t.Run("Dir", func(t *testing.T) { 123 t.Parallel() 124 dir := makeTempDir(t) 125 defer os.RemoveAll(dir) 126 require.NoError(t, os.Mkdir(filepath.Join(dir, "sub"), 0777)) 127 _, err := newFSTableCache(dir, 1024, 4) 128 assert.Error(t, err) 129 }) 130 }) 131 } 132 133 func assertDataInReaderAt(t *testing.T, data []byte, r io.ReaderAt) { 134 p := make([]byte, len(data)) 135 n, err := r.ReadAt(p, 0) 136 require.NoError(t, err) 137 assert.Equal(t, len(data), n) 138 assert.Equal(t, data, p) 139 }