github.com/keybase/client/go@v0.0.0-20240309051027-028f7c731f8b/kbfs/libkbfs/disk_journal_test.go (about)

     1  // Copyright 2016 Keybase Inc. All rights reserved.
     2  // Use of this source code is governed by a BSD
     3  // license that can be found in the LICENSE file.
     4  
     5  package libkbfs
     6  
     7  import (
     8  	"os"
     9  	"path/filepath"
    10  	"reflect"
    11  	"testing"
    12  
    13  	"github.com/keybase/client/go/kbfs/ioutil"
    14  	"github.com/keybase/client/go/kbfs/kbfscodec"
    15  	"github.com/stretchr/testify/assert"
    16  	"github.com/stretchr/testify/require"
    17  )
    18  
    19  type testJournalEntry struct {
    20  	I int
    21  }
    22  
    23  func requireEqualOrdinal(t *testing.T, o journalOrdinal, err error,
    24  	oDisk journalOrdinal, errDisk error) {
    25  	require.Equal(t, oDisk, o)
    26  	if ioutil.IsNotExist(err) && ioutil.IsNotExist(errDisk) {
    27  		return
    28  	}
    29  	require.NoError(t, err)
    30  	require.NoError(t, errDisk)
    31  }
    32  
    33  // TestDiskJournalOrdinals makes sure the in-memory ordinals stay in
    34  // sync with the on-disk ones.
    35  func TestDiskJournalOrdinals(t *testing.T) {
    36  	tempdir, err := ioutil.TempDir(os.TempDir(), "disk_journal")
    37  	require.NoError(t, err)
    38  	defer func() {
    39  		err := ioutil.RemoveAll(tempdir)
    40  		assert.NoError(t, err)
    41  	}()
    42  
    43  	codec := kbfscodec.NewMsgpack()
    44  	j, err := makeDiskJournal(
    45  		codec, tempdir, reflect.TypeOf(testJournalEntry{}))
    46  	require.NoError(t, err)
    47  
    48  	readEarliest := func() (journalOrdinal, error) {
    49  		earliest, err := j.readEarliestOrdinal()
    50  		earliestDisk, errDisk := j.readEarliestOrdinalFromDisk()
    51  		requireEqualOrdinal(t, earliest, err, earliestDisk, errDisk)
    52  		return earliest, err
    53  	}
    54  
    55  	readLatest := func() (journalOrdinal, error) {
    56  		latest, err := j.readLatestOrdinal()
    57  		latestDisk, errDisk := j.readLatestOrdinalFromDisk()
    58  		requireEqualOrdinal(t, latest, err, latestDisk, errDisk)
    59  		return latest, err
    60  	}
    61  
    62  	expectEmpty := func() {
    63  		_, err = readEarliest()
    64  		require.True(t, ioutil.IsNotExist(err))
    65  		_, err = readLatest()
    66  		require.True(t, ioutil.IsNotExist(err))
    67  	}
    68  
    69  	expectRange := func(
    70  		expectedEarliest, expectedLatest journalOrdinal) {
    71  		earliest, err := readEarliest()
    72  		require.NoError(t, err)
    73  		require.Equal(t, expectedEarliest, earliest)
    74  
    75  		latest, err := readLatest()
    76  		require.NoError(t, err)
    77  		require.Equal(t, expectedLatest, latest)
    78  	}
    79  
    80  	expectEmpty()
    81  
    82  	o, err := j.appendJournalEntry(nil, testJournalEntry{1})
    83  	require.NoError(t, err)
    84  	require.Equal(t, firstValidJournalOrdinal, o)
    85  
    86  	expectRange(firstValidJournalOrdinal, firstValidJournalOrdinal)
    87  
    88  	o, err = j.appendJournalEntry(nil, testJournalEntry{1})
    89  	require.NoError(t, err)
    90  	require.Equal(t, firstValidJournalOrdinal+1, o)
    91  
    92  	expectRange(firstValidJournalOrdinal, firstValidJournalOrdinal+1)
    93  
    94  	empty, err := j.removeEarliest()
    95  	require.NoError(t, err)
    96  	require.False(t, empty)
    97  
    98  	expectRange(firstValidJournalOrdinal+1, firstValidJournalOrdinal+1)
    99  
   100  	err = j.clear()
   101  	require.NoError(t, err)
   102  
   103  	expectEmpty()
   104  }
   105  
   106  func TestDiskJournalClear(t *testing.T) {
   107  	tempdir, err := ioutil.TempDir(os.TempDir(), "disk_journal")
   108  	require.NoError(t, err)
   109  	defer func() {
   110  		err := ioutil.RemoveAll(tempdir)
   111  		assert.NoError(t, err)
   112  	}()
   113  
   114  	codec := kbfscodec.NewMsgpack()
   115  	j, err := makeDiskJournal(
   116  		codec, tempdir, reflect.TypeOf(testJournalEntry{}))
   117  	require.NoError(t, err)
   118  
   119  	o, err := j.appendJournalEntry(nil, testJournalEntry{1})
   120  	require.NoError(t, err)
   121  	require.Equal(t, firstValidJournalOrdinal, o)
   122  
   123  	o, err = j.appendJournalEntry(nil, testJournalEntry{2})
   124  	require.NoError(t, err)
   125  	require.Equal(t, firstValidJournalOrdinal+1, o)
   126  
   127  	err = j.clear()
   128  	require.NoError(t, err)
   129  
   130  	_, err = ioutil.Stat(tempdir)
   131  	require.True(t, ioutil.IsNotExist(err))
   132  }
   133  
   134  func TestDiskJournalMoveEmpty(t *testing.T) {
   135  	tempdir, err := ioutil.TempDir(os.TempDir(), "disk_journal")
   136  	require.NoError(t, err)
   137  	defer func() {
   138  		err := ioutil.RemoveAll(tempdir)
   139  		assert.NoError(t, err)
   140  	}()
   141  
   142  	oldDir := filepath.Join(tempdir, "journaldir")
   143  	newDir := oldDir + ".new"
   144  
   145  	codec := kbfscodec.NewMsgpack()
   146  	j, err := makeDiskJournal(
   147  		codec, oldDir, reflect.TypeOf(testJournalEntry{}))
   148  	require.NoError(t, err)
   149  	require.Equal(t, oldDir, j.dir)
   150  
   151  	moveOldDir, err := j.move(newDir)
   152  	require.NoError(t, err)
   153  	require.Equal(t, oldDir, moveOldDir)
   154  	require.Equal(t, newDir, j.dir)
   155  }
   156  
   157  func TestDiskJournalMove(t *testing.T) {
   158  	tempdir, err := ioutil.TempDir(os.TempDir(), "disk_journal")
   159  	require.NoError(t, err)
   160  	defer func() {
   161  		err := ioutil.RemoveAll(tempdir)
   162  		assert.NoError(t, err)
   163  	}()
   164  
   165  	oldDir := filepath.Join(tempdir, "journaldir")
   166  	newDir := oldDir + ".new"
   167  
   168  	codec := kbfscodec.NewMsgpack()
   169  	j, err := makeDiskJournal(
   170  		codec, oldDir, reflect.TypeOf(testJournalEntry{}))
   171  	require.NoError(t, err)
   172  	require.Equal(t, oldDir, j.dir)
   173  
   174  	o, err := j.appendJournalEntry(nil, testJournalEntry{1})
   175  	require.NoError(t, err)
   176  	require.Equal(t, firstValidJournalOrdinal, o)
   177  
   178  	moveOldDir, err := j.move(newDir)
   179  	require.NoError(t, err)
   180  	require.Equal(t, oldDir, moveOldDir)
   181  	require.Equal(t, newDir, j.dir)
   182  
   183  	entry, err := j.readJournalEntry(o)
   184  	require.NoError(t, err)
   185  	require.Equal(t, testJournalEntry{1}, entry)
   186  }