Skip to content

Commit

Permalink
First somewhat working solution
Browse files Browse the repository at this point in the history
  • Loading branch information
myxo committed Apr 11, 2024
1 parent 7032006 commit 6d44046
Show file tree
Hide file tree
Showing 10 changed files with 1,394 additions and 5 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
*.out
*.test
12 changes: 12 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
Features:
- performance in non mock path (no interfaces)
- profound testing (we use property based tsting to ensure simularity with real implementation

Non features:
- make a varaity of different backends (like NetFS, s2, etc.). I try to keep package as clean from dependencies as possible
- simulating of concurrent effect of filesystem (e.g. concurrent ReadDir with file removing)

TODO:
- [ ] Make count in test to see how much function envocation we have
- [ ] Document what fileMode are supported
- [ ] O_APPEND
11 changes: 11 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
@@ -1,3 +1,14 @@
module github.com/myxo/gofs

go 1.22.0

require (
github.com/stretchr/testify v1.9.0
pgregory.net/rapid v1.1.0
)

require (
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)
13 changes: 13 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA=
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
pgregory.net/rapid v1.1.0 h1:CMa0sjHSru3puNx+J0MIAuiiEV4N0qj8/cMWGBBCsjw=
pgregory.net/rapid v1.1.0/go.mod h1:PY5XlDGj0+V1FCq0o192FdRhpKHGTRIWBgqjDBTrq04=
245 changes: 244 additions & 1 deletion gofs.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,250 @@
package gofs

import (
"io"
"os"
)

type FS interface {

Create(name string) (*File, error)
CreateTemp(dir, pattern string) (*File, error)
// NewFile(fd uintptr, name string) *File // TODO: ???
Open(name string) (*File, error)
OpenFile(name string, flag int, perm os.FileMode) (*File, error)
Chdir(dir string) error
Chmod(name string, mode os.FileMode) error
Chown(name string, uid, gid int) error
Mkdir(name string, perm os.FileMode) error
MkdirAll(path string, perm os.FileMode) error
MkdirTemp(dir, pattern string) (string, error)
ReadFile(name string) ([]byte, error)
Readlink(name string) (string, error)
ReadDir(name string) ([]os.DirEntry, error)
Remove(name string) error
RemoveAll(path string) error
Rename(oldpath, newpath string) error
Truncate(name string, size int64) error
WriteFile(name string, data []byte, perm os.FileMode) error
}

type File struct {
mockFile *FakeFile
osFile *os.File
}

func NewFromOs(fp *os.File) *File {
return &File{osFile: fp}
}

func (f *File) Fd() uintptr {
if f.osFile != nil {
return f.osFile.Fd()
}
return 0
}

func (f *File) Chdir() error {
if f.osFile != nil {
return f.osFile.Chdir()
}
return f.mockFile.Chdir()
}

func (f *File) Chmod(mode os.FileMode) error {
if f.osFile != nil {
return f.osFile.Chmod(mode)
}
return f.mockFile.Chmod(mode)
}

func (f *File) Chown(uid, gid int) error { panic("todo") }

func (f *File) Close() error {
if f.osFile != nil {
return f.osFile.Close()
}
return f.mockFile.Close()
}

func (f *File) Name() string {
if f.osFile != nil {
return f.osFile.Name()
}
return f.mockFile.Name()
}

func (f *File) Read(b []byte) (n int, err error) {
if f.osFile != nil {
return f.osFile.Read(b)
}
return f.mockFile.Read(b)
}

func (f *File) ReadAt(b []byte, off int64) (n int, err error) {
if f.osFile != nil {
return f.osFile.ReadAt(b, off)
}
return f.mockFile.ReadAt(b, off)
}

func (f *File) ReadDir(n int) ([]os.DirEntry, error) {
if f.osFile != nil {
return f.osFile.ReadDir(n)
}
return f.mockFile.ReadDir(n)
}

func (f *File) ReadFrom(r io.Reader) (n int64, err error) {
if f.osFile != nil {
return f.osFile.ReadFrom(r)
}
return f.mockFile.ReadFrom(r)
}

func (f *File) Readdir(n int) ([]os.FileInfo, error) {
if f.osFile != nil {
return f.osFile.Readdir(n)
}
return f.mockFile.Readdir(n)
}

func (f *File) Readdirnames(n int) (names []string, err error) {
if f.osFile != nil {
return f.osFile.Readdirnames(n)
}
return f.mockFile.Readdirnames(n)
}

func (f *File) Seek(offset int64, whence int) (ret int64, err error) {
if f.osFile != nil {
return f.osFile.Seek(offset, whence)
}
return f.mockFile.Seek(offset, whence)
}

func (f *File) Stat() (os.FileInfo, error) {
if f.osFile != nil {
return f.osFile.Stat()
}
return f.mockFile.Stat()
}

func (f *File) Sync() error {
if f.osFile != nil {
return f.osFile.Sync()
}
return f.mockFile.Sync()
}

func (f *File) Truncate(size int64) error {
if f.osFile != nil {
return f.osFile.Truncate(size)
}
return f.mockFile.Truncate(size)
}

func (f *File) Write(b []byte) (n int, err error) {
if f.osFile != nil {
return f.osFile.Write(b)
}
return f.mockFile.Write(b)
}

func (f *File) WriteAt(b []byte, off int64) (n int, err error) {
if f.osFile != nil {
return f.osFile.WriteAt(b, off)
}
return f.mockFile.WriteAt(b, off)
}

func (f *File) WriteString(s string) (n int, err error) {
if f.osFile != nil {
return f.osFile.WriteString(s)
}
return f.mockFile.WriteString(s)
}
func (f *File) WriteTo(w io.Writer) (n int64, err error) { panic("todo") }

//func (f *File) SetDeadline(t time.Time) error{ panic("todo") }
//func (f *File) SetReadDeadline(t time.Time) error{ panic("todo") }
//func (f *File) SetWriteDeadline(t time.Time) error{ panic("todo") }

type OsFs struct{}

var _ FS = &OsFs{}

func (OsFs) Create(name string) (*File, error) {
fp, err := os.Create(name)
return NewFromOs(fp), err
}

func (OsFs) CreateTemp(dir, pattern string) (*File, error) {
fp, err := os.CreateTemp(dir, pattern)
return NewFromOs(fp), err
}

func (OsFs) Open(name string) (*File, error) {
fp, err := os.Open(name)
return NewFromOs(fp), err
}

func (OsFs) OpenFile(name string, flag int, perm os.FileMode) (*File, error) {
fp, err := os.OpenFile(name, flag, perm)
return NewFromOs(fp), err
}

func (OsFs) Chdir(dir string) error {
return os.Chdir(dir)
}

func (OsFs) Chmod(name string, mode os.FileMode) error {
return os.Chmod(name, mode)
}

func (OsFs) Chown(name string, uid, gid int) error {
return os.Chown(name, uid, gid)
}

func (OsFs) Mkdir(name string, perm os.FileMode) error {
return os.Mkdir(name, perm)
}

func (OsFs) MkdirAll(path string, perm os.FileMode) error {
return os.MkdirAll(path, perm)
}

func (OsFs) MkdirTemp(dir, pattern string) (string, error) {
return os.MkdirTemp(dir, pattern)
}

func (OsFs) ReadFile(name string) ([]byte, error) {
return os.ReadFile(name)
}

func (OsFs) Readlink(name string) (string, error) {
return os.Readlink(name)
}

func (OsFs) Remove(name string) error {
return os.Remove(name)
}

func (OsFs) RemoveAll(path string) error {
return os.RemoveAll(path)
}

func (OsFs) Rename(oldpath, newpath string) error {
return os.Rename(oldpath, newpath)
}

func (OsFs) Truncate(name string, size int64) error {
return os.Truncate(name, size)
}

func (OsFs) WriteFile(name string, data []byte, perm os.FileMode) error {
return os.WriteFile(name, data, perm)
}

func (OsFs) ReadDir(name string) ([]os.DirEntry, error) {
return os.ReadDir(name)
}
Loading

0 comments on commit 6d44046

Please sign in to comment.