code.gitea.io/gitea@v1.21.7/models/dbfs/dbfs_test.go (about) 1 // Copyright 2022 The Gitea Authors. All rights reserved. 2 // SPDX-License-Identifier: MIT 3 4 package dbfs 5 6 import ( 7 "bufio" 8 "io" 9 "os" 10 "testing" 11 12 "code.gitea.io/gitea/models/db" 13 14 "github.com/stretchr/testify/assert" 15 ) 16 17 func changeDefaultFileBlockSize(n int64) (restore func()) { 18 old := defaultFileBlockSize 19 defaultFileBlockSize = n 20 return func() { 21 defaultFileBlockSize = old 22 } 23 } 24 25 func TestDbfsBasic(t *testing.T) { 26 defer changeDefaultFileBlockSize(4)() 27 28 // test basic write/read 29 f, err := OpenFile(db.DefaultContext, "test.txt", os.O_RDWR|os.O_CREATE) 30 assert.NoError(t, err) 31 32 n, err := f.Write([]byte("0123456789")) // blocks: 0123 4567 89 33 assert.NoError(t, err) 34 assert.EqualValues(t, 10, n) 35 36 _, err = f.Seek(0, io.SeekStart) 37 assert.NoError(t, err) 38 39 buf, err := io.ReadAll(f) 40 assert.NoError(t, err) 41 assert.EqualValues(t, 10, n) 42 assert.EqualValues(t, "0123456789", string(buf)) 43 44 // write some new data 45 _, err = f.Seek(1, io.SeekStart) 46 assert.NoError(t, err) 47 _, err = f.Write([]byte("bcdefghi")) // blocks: 0bcd efgh i9 48 assert.NoError(t, err) 49 50 // read from offset 51 buf, err = io.ReadAll(f) 52 assert.NoError(t, err) 53 assert.EqualValues(t, "9", string(buf)) 54 55 // read all 56 _, err = f.Seek(0, io.SeekStart) 57 assert.NoError(t, err) 58 buf, err = io.ReadAll(f) 59 assert.NoError(t, err) 60 assert.EqualValues(t, "0bcdefghi9", string(buf)) 61 62 // write to new size 63 _, err = f.Seek(-1, io.SeekEnd) 64 assert.NoError(t, err) 65 _, err = f.Write([]byte("JKLMNOP")) // blocks: 0bcd efgh iJKL MNOP 66 assert.NoError(t, err) 67 _, err = f.Seek(0, io.SeekStart) 68 assert.NoError(t, err) 69 buf, err = io.ReadAll(f) 70 assert.NoError(t, err) 71 assert.EqualValues(t, "0bcdefghiJKLMNOP", string(buf)) 72 73 // write beyond EOF and fill with zero 74 _, err = f.Seek(5, io.SeekCurrent) 75 assert.NoError(t, err) 76 _, err = f.Write([]byte("xyzu")) // blocks: 0bcd efgh iJKL MNOP 0000 0xyz u 77 assert.NoError(t, err) 78 _, err = f.Seek(0, io.SeekStart) 79 assert.NoError(t, err) 80 buf, err = io.ReadAll(f) 81 assert.NoError(t, err) 82 assert.EqualValues(t, "0bcdefghiJKLMNOP\x00\x00\x00\x00\x00xyzu", string(buf)) 83 84 // write to the block with zeros 85 _, err = f.Seek(-6, io.SeekCurrent) 86 assert.NoError(t, err) 87 _, err = f.Write([]byte("ABCD")) // blocks: 0bcd efgh iJKL MNOP 000A BCDz u 88 assert.NoError(t, err) 89 _, err = f.Seek(0, io.SeekStart) 90 assert.NoError(t, err) 91 buf, err = io.ReadAll(f) 92 assert.NoError(t, err) 93 assert.EqualValues(t, "0bcdefghiJKLMNOP\x00\x00\x00ABCDzu", string(buf)) 94 95 assert.NoError(t, f.Close()) 96 97 // test rename 98 err = Rename(db.DefaultContext, "test.txt", "test2.txt") 99 assert.NoError(t, err) 100 101 _, err = OpenFile(db.DefaultContext, "test.txt", os.O_RDONLY) 102 assert.Error(t, err) 103 104 f, err = OpenFile(db.DefaultContext, "test2.txt", os.O_RDONLY) 105 assert.NoError(t, err) 106 assert.NoError(t, f.Close()) 107 108 // test remove 109 err = Remove(db.DefaultContext, "test2.txt") 110 assert.NoError(t, err) 111 112 _, err = OpenFile(db.DefaultContext, "test2.txt", os.O_RDONLY) 113 assert.Error(t, err) 114 115 // test stat 116 f, err = OpenFile(db.DefaultContext, "test/test.txt", os.O_RDWR|os.O_CREATE) 117 assert.NoError(t, err) 118 stat, err := f.Stat() 119 assert.NoError(t, err) 120 assert.EqualValues(t, "test.txt", stat.Name()) 121 assert.EqualValues(t, 0, stat.Size()) 122 _, err = f.Write([]byte("0123456789")) 123 assert.NoError(t, err) 124 stat, err = f.Stat() 125 assert.NoError(t, err) 126 assert.EqualValues(t, 10, stat.Size()) 127 } 128 129 func TestDbfsReadWrite(t *testing.T) { 130 defer changeDefaultFileBlockSize(4)() 131 132 f1, err := OpenFile(db.DefaultContext, "test.log", os.O_RDWR|os.O_CREATE) 133 assert.NoError(t, err) 134 defer f1.Close() 135 136 f2, err := OpenFile(db.DefaultContext, "test.log", os.O_RDONLY) 137 assert.NoError(t, err) 138 defer f2.Close() 139 140 _, err = f1.Write([]byte("line 1\n")) 141 assert.NoError(t, err) 142 143 f2r := bufio.NewReader(f2) 144 145 line, err := f2r.ReadString('\n') 146 assert.NoError(t, err) 147 assert.EqualValues(t, "line 1\n", line) 148 _, err = f2r.ReadString('\n') 149 assert.ErrorIs(t, err, io.EOF) 150 151 _, err = f1.Write([]byte("line 2\n")) 152 assert.NoError(t, err) 153 154 line, err = f2r.ReadString('\n') 155 assert.NoError(t, err) 156 assert.EqualValues(t, "line 2\n", line) 157 _, err = f2r.ReadString('\n') 158 assert.ErrorIs(t, err, io.EOF) 159 } 160 161 func TestDbfsSeekWrite(t *testing.T) { 162 defer changeDefaultFileBlockSize(4)() 163 164 f, err := OpenFile(db.DefaultContext, "test2.log", os.O_RDWR|os.O_CREATE) 165 assert.NoError(t, err) 166 defer f.Close() 167 168 n, err := f.Write([]byte("111")) 169 assert.NoError(t, err) 170 171 _, err = f.Seek(int64(n), io.SeekStart) 172 assert.NoError(t, err) 173 174 _, err = f.Write([]byte("222")) 175 assert.NoError(t, err) 176 177 _, err = f.Seek(int64(n), io.SeekStart) 178 assert.NoError(t, err) 179 180 _, err = f.Write([]byte("333")) 181 assert.NoError(t, err) 182 183 fr, err := OpenFile(db.DefaultContext, "test2.log", os.O_RDONLY) 184 assert.NoError(t, err) 185 defer f.Close() 186 187 buf, err := io.ReadAll(fr) 188 assert.NoError(t, err) 189 assert.EqualValues(t, "111333", string(buf)) 190 }