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  }