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  }