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 }