Skip to content

Commit

Permalink
Fixes #156 - Update os backend to use new io integration test suite
Browse files Browse the repository at this point in the history
  • Loading branch information
funkyshu committed Feb 1, 2024
1 parent d995180 commit 4babf5c
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 20 deletions.
53 changes: 39 additions & 14 deletions backend/os/file.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package os
import (
"fmt"
"io"
"io/fs"
"os"
"path"
"path/filepath"
Expand All @@ -27,6 +28,8 @@ type File struct {
tempFile *os.File
useTempFile bool
fileOpener opener
seekCalled bool
readCalled bool
}

// Delete unlinks the file returning any error or nil.
Expand Down Expand Up @@ -73,6 +76,8 @@ func (f *File) Size() (uint64, error) {
func (f *File) Close() error {
f.useTempFile = false
f.cursorPos = 0
f.seekCalled = false
f.readCalled = false

// check if temp file
if f.tempFile != nil {
Expand Down Expand Up @@ -128,6 +133,7 @@ func (f *File) Read(p []byte) (int, error) {
return read, err
}

f.readCalled = true
f.cursorPos += int64(read)

return read, nil
Expand All @@ -137,6 +143,13 @@ func (f *File) Read(p []byte) (int, error) {
// the file, 1 means relative to the current offset, and 2 means relative to the end. It returns the new offset and
// an error, if any.
func (f *File) Seek(offset int64, whence int) (int64, error) {
exists, err := f.Exists()
if err != nil {
return 0, fmt.Errorf("unable to Seek: %w", err)
}
if !exists && !f.useTempFile {
return 0, fmt.Errorf("unable to Seek: %w", fs.ErrNotExist)
}
useFile, err := f.getInternalFile()
if err != nil {
return 0, err
Expand All @@ -147,6 +160,7 @@ func (f *File) Seek(offset int64, whence int) (int64, error) {
return 0, err
}

f.seekCalled = true
return f.cursorPos, err
}

Expand All @@ -167,6 +181,7 @@ func (f *File) Exists() (bool, error) {

// Write implements the io.Writer interface. It accepts a slice of bytes and returns the number of bytes written and an error, if any.
func (f *File) Write(p []byte) (n int, err error) {
// useTempFile prevents the immediate update of the file until we Close()
f.useTempFile = true

useFile, err := f.getInternalFile()
Expand Down Expand Up @@ -428,23 +443,33 @@ func (f *File) copyToLocalTempReader() (*os.File, error) {
return nil, err
}

openFunc := openOSFile
if f.fileOpener != nil {
openFunc = f.fileOpener
exists, err := f.Exists()
if err != nil {
return nil, err
}
if exists {
openFunc := openOSFile
if f.fileOpener != nil {
openFunc = f.fileOpener
}

if _, err = openFunc(f.Path()); err != nil {
return nil, err
actualFile, err := openFunc(f.Path())
if err != nil {
return nil, err
}
if f.seekCalled || f.readCalled {
if _, err := io.Copy(tmpFile, actualFile); err != nil {
return nil, err
}
}

if f.cursorPos > 0 {
// match cursor position in tmep file
if _, err := tmpFile.Seek(f.cursorPos, 0); err != nil {
return nil, err
}
}
}
// todo: editing in place logic/appending logic (see issue #42)
// if _, err := io.Copy(tmpFile, f.file); err != nil {
// return nil, err
// }
//
// // Return cursor to the beginning of the new temp file
// if _, err := tmpFile.Seek(f.cursorPos, 0); err != nil {
// return nil, err
// }

return tmpFile, nil
}
14 changes: 8 additions & 6 deletions backend/os/file_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -506,6 +506,7 @@ func (s *osFileTest) TestWrite() {
// setup file for err out of opening
f, err := s.tmploc.NewFile("test_files/writeFileFail.txt")
s.NoError(err)
s.NoError(f.Touch())
f.(*File).useTempFile = true
f.(*File).fileOpener = func(filePath string) (*os.File, error) { return nil, errors.New("bad opener") }
data = make([]byte, 4)
Expand Down Expand Up @@ -538,29 +539,30 @@ func (s *osFileTest) TestCursor() {
s.Equal(int64(5), file.(*File).cursorPos)
s.NoError(serr2)

// because seek and/or read were called before write, write is now in in-place edit mode (not truncate-write)
sz, werr = file.Write([]byte("has")) // cursor 8 - tempfile copy of orig - write on tempfile has occurred
s.NoError(werr)
s.Equal(int64(8), file.(*File).cursorPos)
s.Equal(3, sz)

_, serr = file.Seek(0, 0) // cursor 0 - in temp file
s.Equal(int64(0), file.(*File).cursorPos)
_, serr = file.Seek(5, 0) // cursor 0 - in temp file
s.Equal(int64(5), file.(*File).cursorPos)
s.NoError(serr)

data = make([]byte, 3)
sz, rerr = file.Read(data)
s.NoError(rerr)
s.Equal(int64(3), file.(*File).cursorPos)
s.Equal(int64(8), file.(*File).cursorPos)
s.Equal("has", string(data)) // tempFile contents = "has"
s.Equal(3, sz)

s.NoError(file.Close()) // moves tempfile containing "has" over original file

final := make([]byte, 3)
final := make([]byte, 8)
rd, err := file.Read(final)
s.NoError(err)
s.Equal(3, rd)
s.Equal("has", string(final))
s.Equal(8, rd)
s.Equal("mary has", string(final))
s.NoError(file.Close())

// if a file exists and we overwrite with a smaller # of text, then it isn't completely overwritten
Expand Down
2 changes: 2 additions & 0 deletions backend/os/location_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,8 @@ func (s *osLocationTest) TestDeleteFile() {
_, err = file.Write([]byte(expectedText))
s.NoError(err, "Shouldn't fail to write text to file.")

s.NoError(file.Close())

exists, err := file.Exists()
s.NoError(err, "Exists shouldn't throw error.")
s.True(exists, "Exists should return true for test file.")
Expand Down

0 comments on commit 4babf5c

Please sign in to comment.