github.com/zuoyebang/bitalosdb@v1.1.1-0.20240516111551-79a8c4d8ce20/internal/manifest/manifest_test.go (about)

     1  // Copyright 2021 The Bitalosdb author(hustxrb@163.com) and other contributors.
     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  package manifest
    16  
    17  import (
    18  	"os"
    19  	"path/filepath"
    20  	"testing"
    21  
    22  	"github.com/stretchr/testify/require"
    23  	"github.com/zuoyebang/bitalosdb/internal/mmap"
    24  	"github.com/zuoyebang/bitalosdb/internal/vfs"
    25  )
    26  
    27  const testDir = "./test-data"
    28  
    29  var testFS = vfs.Default
    30  
    31  func testInitDir() {
    32  	_, err := os.Stat(testDir)
    33  	if os.IsNotExist(err) {
    34  		os.MkdirAll(testDir, 0775)
    35  	}
    36  }
    37  
    38  func TestMetaWrite(t *testing.T) {
    39  	defer os.RemoveAll(testDir)
    40  	testInitDir()
    41  	metaFile := filepath.Join(testDir, "manifest")
    42  	meta, err := NewMetadata(metaFile, testFS)
    43  	require.NoError(t, err)
    44  
    45  	require.Equal(t, metaVersion2, meta.header.version)
    46  
    47  	require.Equal(t, uint8(0), meta.GetFieldFlushedBitable())
    48  	meta.SetFieldFlushedBitable()
    49  	require.Equal(t, uint8(1), meta.GetFieldFlushedBitable())
    50  
    51  	num := 10
    52  	seqNum := uint64(0)
    53  	for i := range meta.Bmes {
    54  		for j := 0; j < num; j++ {
    55  			fn := meta.Bmes[i].GetNextFileNum()
    56  			require.Equal(t, FileNum(j), fn)
    57  			seqNum++
    58  		}
    59  
    60  		me := &MetaEditor{
    61  			LastSeqNum: seqNum,
    62  		}
    63  		sme := &BitowerMetaEditor{
    64  			Index:              i,
    65  			NextFileNum:        meta.Bmes[i].NextFileNum,
    66  			MinUnflushedLogNum: meta.Bmes[i].NextFileNum - 1,
    67  		}
    68  		meta.Write(me, sme)
    69  
    70  		require.Equal(t, FileNum(num), meta.Bmes[i].NextFileNum)
    71  		require.Equal(t, FileNum(num-1), meta.Bmes[i].MinUnflushedLogNum)
    72  	}
    73  
    74  	require.NoError(t, meta.Close())
    75  	meta, err = NewMetadata(metaFile, testFS)
    76  	require.NoError(t, err)
    77  	require.Equal(t, metaVersion2, meta.header.version)
    78  	require.Equal(t, seqNum, meta.LastSeqNum)
    79  	require.Equal(t, uint8(1), meta.GetFieldFlushedBitable())
    80  	for i := range meta.Bmes {
    81  		require.Equal(t, FileNum(num), meta.Bmes[i].NextFileNum)
    82  		require.Equal(t, FileNum(num-1), meta.Bmes[i].MinUnflushedLogNum)
    83  	}
    84  
    85  	require.NoError(t, meta.Close())
    86  }
    87  
    88  func TestMetaUpdateV1toV2(t *testing.T) {
    89  	defer os.RemoveAll(testDir)
    90  	testInitDir()
    91  	filename := filepath.Join(testDir, "manifest")
    92  
    93  	m := &Metadata{fs: testFS}
    94  	require.NoError(t, m.create(filename))
    95  	file, err := mmap.Open(filename, 0)
    96  	require.NoError(t, err)
    97  	file.WriteUInt16At(metaVersion1, metaHeaderOffset)
    98  	file.WriteUInt64At(10, fieldOffsetMinUnflushedLogNumV1)
    99  	file.WriteUInt64At(20, fieldOffsetNextFileNumV1)
   100  	file.WriteUInt64At(30, fieldOffsetLastSeqNumV1)
   101  	file.WriteUInt8At(1, fieldOffsetIsBitableFlushedV1)
   102  	m.file = file
   103  	require.NoError(t, m.Close())
   104  
   105  	meta, err := NewMetadata(filename, testFS)
   106  	require.NoError(t, err)
   107  	require.Equal(t, metaVersion2, meta.header.version)
   108  	require.Equal(t, uint64(30), meta.LastSeqNum)
   109  	require.Equal(t, uint8(1), meta.GetFieldFlushedBitable())
   110  	for i := range meta.Bmes {
   111  		require.Equal(t, FileNum(20), meta.Bmes[i].NextFileNum)
   112  		require.Equal(t, FileNum(10), meta.Bmes[i].MinUnflushedLogNum)
   113  	}
   114  	lastSeqNum := uint64(100)
   115  	lastFileNum := FileNum(200)
   116  	for i := range meta.Bmes {
   117  		fn := meta.Bmes[i].GetNextFileNum()
   118  		require.Equal(t, FileNum(20), fn)
   119  
   120  		me := &MetaEditor{
   121  			LastSeqNum: lastSeqNum,
   122  		}
   123  		sme := &BitowerMetaEditor{
   124  			Index:              i,
   125  			NextFileNum:        lastFileNum,
   126  			MinUnflushedLogNum: lastFileNum,
   127  		}
   128  		meta.Write(me, sme)
   129  
   130  		require.Equal(t, lastSeqNum, meta.LastSeqNum)
   131  		require.Equal(t, lastFileNum, meta.Bmes[i].NextFileNum)
   132  		require.Equal(t, lastFileNum, meta.Bmes[i].MinUnflushedLogNum)
   133  	}
   134  	require.NoError(t, meta.Close())
   135  
   136  	meta, err = NewMetadata(filename, testFS)
   137  	require.NoError(t, err)
   138  	require.Equal(t, metaVersion2, meta.header.version)
   139  	require.Equal(t, lastSeqNum, meta.LastSeqNum)
   140  	require.Equal(t, uint8(1), meta.GetFieldFlushedBitable())
   141  	for i := range meta.Bmes {
   142  		require.Equal(t, lastFileNum, meta.Bmes[i].NextFileNum)
   143  		require.Equal(t, lastFileNum, meta.Bmes[i].MinUnflushedLogNum)
   144  	}
   145  	require.NoError(t, meta.Close())
   146  }