update
This commit is contained in:
parent
7b1863109c
commit
ef751771d2
107 changed files with 9435 additions and 850 deletions
src/host/vfs
|
@ -1,235 +1,237 @@
|
|||
package vfs
|
||||
package vfs_test
|
||||
|
||||
import (
|
||||
"archive/zip"
|
||||
"bytes"
|
||||
"context"
|
||||
"io/fs"
|
||||
"os"
|
||||
"path"
|
||||
"testing"
|
||||
|
||||
"git.kmsign.ru/royalcat/tstor/src/host/vfs"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
type Dummy struct {
|
||||
name string
|
||||
}
|
||||
func createZip(files map[string][]byte) ([]byte, error) {
|
||||
buf := bytes.NewBuffer(nil)
|
||||
zw := zip.NewWriter(buf)
|
||||
|
||||
// Stat implements File.
|
||||
func (d *Dummy) Stat() (fs.FileInfo, error) {
|
||||
return newFileInfo(d.name, 0), nil
|
||||
}
|
||||
for name, data := range files {
|
||||
fw, err := zw.Create(name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
func (d *Dummy) Size() int64 {
|
||||
return 0
|
||||
}
|
||||
|
||||
func (d *Dummy) IsDir() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (d *Dummy) Close(ctx context.Context) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (d *Dummy) Read(ctx context.Context, p []byte) (n int, err error) {
|
||||
return 0, nil
|
||||
}
|
||||
|
||||
func (d *Dummy) ReadAt(ctx context.Context, p []byte, off int64) (n int, err error) {
|
||||
return 0, nil
|
||||
}
|
||||
|
||||
var _ File = &Dummy{}
|
||||
|
||||
type DummyFs struct {
|
||||
name string
|
||||
}
|
||||
|
||||
// Stat implements Filesystem.
|
||||
func (*DummyFs) Stat(ctx context.Context, filename string) (fs.FileInfo, error) {
|
||||
return newFileInfo(path.Base(filename), 0), nil // TODO
|
||||
}
|
||||
|
||||
func (d *DummyFs) Open(ctx context.Context, filename string) (File, error) {
|
||||
return &Dummy{}, nil
|
||||
}
|
||||
|
||||
func (d *DummyFs) Unlink(ctx context.Context, filename string) error {
|
||||
return ErrNotImplemented
|
||||
}
|
||||
|
||||
func (d *DummyFs) ReadDir(ctx context.Context, path string) ([]fs.DirEntry, error) {
|
||||
if path == "/dir/here" {
|
||||
return []fs.DirEntry{
|
||||
newFileInfo("file1.txt", 0),
|
||||
newFileInfo("file2.txt", 0),
|
||||
}, nil
|
||||
_, err = fw.Write(data)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
err := zw.Flush()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return nil, os.ErrNotExist
|
||||
err = zw.Close()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return buf.Bytes(), nil
|
||||
}
|
||||
|
||||
// Info implements Filesystem.
|
||||
func (d *DummyFs) Info() (fs.FileInfo, error) {
|
||||
return newDirInfo(d.name), nil
|
||||
}
|
||||
|
||||
// IsDir implements Filesystem.
|
||||
func (d *DummyFs) IsDir() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
// Name implements Filesystem.
|
||||
func (d *DummyFs) Name() string {
|
||||
return d.name
|
||||
}
|
||||
|
||||
// Type implements Filesystem.
|
||||
func (d *DummyFs) Type() fs.FileMode {
|
||||
return fs.ModeDir
|
||||
}
|
||||
|
||||
var _ Filesystem = &DummyFs{}
|
||||
|
||||
func TestResolver(t *testing.T) {
|
||||
func TestResolverFs(t *testing.T) {
|
||||
t.Parallel()
|
||||
resolver := newResolver(ArchiveFactories)
|
||||
ctx := context.Background()
|
||||
|
||||
t.Run("nested fs", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
require := require.New(t)
|
||||
|
||||
fsPath, nestedFs, nestedFsPath, err := resolver.resolvePath(ctx, "/f1.rar/f2.rar", func(_ context.Context, path string) (File, error) {
|
||||
require.Equal("/f1.rar", path)
|
||||
return &Dummy{}, nil
|
||||
})
|
||||
require.NoError(err)
|
||||
require.Equal("/f1.rar", fsPath)
|
||||
require.Equal("/f2.rar", nestedFsPath)
|
||||
require.IsType(&ArchiveFS{}, nestedFs)
|
||||
testZip, err := createZip(map[string][]byte{
|
||||
"123.txt": []byte("123"),
|
||||
"files/321.txt": []byte("321"),
|
||||
})
|
||||
t.Run("root", func(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
|
||||
fs := vfs.NewResolveFS(vfs.NewMemoryFS("/", map[string]*vfs.MemoryFile{
|
||||
"/data/123.zip": vfs.NewMemoryFile("123.zip", testZip),
|
||||
}), vfs.ArchiveFactories)
|
||||
|
||||
t.Run("dir", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
require := require.New(t)
|
||||
|
||||
fsPath, nestedFs, nestedFsPath, err := resolver.resolvePath(ctx, "/", func(_ context.Context, path string) (File, error) {
|
||||
require.Equal("/", path)
|
||||
return &Dummy{}, nil
|
||||
})
|
||||
require.NoError(err)
|
||||
require.Nil(nestedFs)
|
||||
require.Equal("/", fsPath)
|
||||
require.Equal("", nestedFsPath)
|
||||
})
|
||||
dirs := []string{
|
||||
"/data", "/", "/.",
|
||||
"/data/123.zip", "/data/123.zip/files", "/data/123.zip/files/.",
|
||||
}
|
||||
|
||||
t.Run("root dirty", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
require := require.New(t)
|
||||
for _, dir := range dirs {
|
||||
file, err := fs.Open(ctx, dir)
|
||||
require.NoError(err)
|
||||
require.True(file.IsDir())
|
||||
|
||||
fsPath, nestedFs, nestedFsPath, err := resolver.resolvePath(ctx, "//.//", func(_ context.Context, path string) (File, error) {
|
||||
require.Equal("/", path)
|
||||
return &Dummy{}, nil
|
||||
})
|
||||
require.NoError(err)
|
||||
require.Nil(nestedFs)
|
||||
require.Equal("/", fsPath)
|
||||
require.Equal("", nestedFsPath)
|
||||
})
|
||||
t.Run("fs dirty", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
require := require.New(t)
|
||||
stat, err := file.Info()
|
||||
require.NoError(err)
|
||||
require.True(stat.IsDir())
|
||||
}
|
||||
|
||||
fsPath, nestedFs, nestedFsPath, err := resolver.resolvePath(ctx, "//.//f1.rar", func(_ context.Context, path string) (File, error) {
|
||||
require.Equal("/f1.rar", path)
|
||||
return &Dummy{}, nil
|
||||
})
|
||||
entries, err := fs.ReadDir(ctx, "/data")
|
||||
require.NoError(err)
|
||||
require.Equal("/f1.rar", fsPath)
|
||||
require.Equal("/", nestedFsPath)
|
||||
require.IsType(&ArchiveFS{}, nestedFs)
|
||||
})
|
||||
t.Run("inside folder", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
require := require.New(t)
|
||||
require.Len(entries, 1)
|
||||
|
||||
fsPath, nestedFs, nestedFsPath, err := resolver.resolvePath(ctx, "//test1/f1.rar", func(_ context.Context, path string) (File, error) {
|
||||
require.Equal("/test1/f1.rar", path)
|
||||
return &Dummy{}, nil
|
||||
})
|
||||
for _, e := range entries {
|
||||
switch e.Name() {
|
||||
case "123.zip":
|
||||
require.True(e.IsDir())
|
||||
require.IsType(&vfs.ArchiveFS{}, e)
|
||||
}
|
||||
}
|
||||
|
||||
entries, err = fs.ReadDir(ctx, "/data/123.zip/files")
|
||||
require.NoError(err)
|
||||
require.IsType(&ArchiveFS{}, nestedFs)
|
||||
require.Equal("/test1/f1.rar", fsPath)
|
||||
require.Equal("/", nestedFsPath)
|
||||
require.Len(entries, 1)
|
||||
|
||||
entries, err = fs.ReadDir(ctx, "/data/123.zip")
|
||||
require.NoError(err)
|
||||
require.Len(entries, 3)
|
||||
|
||||
for _, e := range entries {
|
||||
switch e.Name() {
|
||||
case "files":
|
||||
require.True(e.IsDir())
|
||||
case "123.txt":
|
||||
require.False(e.IsDir())
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func TestArchiveFactories(t *testing.T) {
|
||||
t.Parallel()
|
||||
// func TestResolver(t *testing.T) {
|
||||
// t.Parallel()
|
||||
// resolver := newResolver(ArchiveFactories)
|
||||
// ctx := context.Background()
|
||||
|
||||
ctx := context.Background()
|
||||
// t.Run("nested fs", func(t *testing.T) {
|
||||
// t.Parallel()
|
||||
// require := require.New(t)
|
||||
|
||||
require := require.New(t)
|
||||
// fsPath, nestedFs, nestedFsPath, err := resolver.resolvePath(ctx, "/f1.rar/f2.rar", func(_ context.Context, path string) (File, error) {
|
||||
// require.Equal("/f1.rar", path)
|
||||
// return &vfs.Dummy{}, nil
|
||||
// })
|
||||
// require.NoError(err)
|
||||
// require.Equal("/f1.rar", fsPath)
|
||||
// require.Equal("/f2.rar", nestedFsPath)
|
||||
// require.IsType(&vfs.ArchiveFS{}, nestedFs)
|
||||
// })
|
||||
// t.Run("root", func(t *testing.T) {
|
||||
// t.Parallel()
|
||||
// require := require.New(t)
|
||||
|
||||
require.Contains(ArchiveFactories, ".zip")
|
||||
require.Contains(ArchiveFactories, ".rar")
|
||||
require.Contains(ArchiveFactories, ".7z")
|
||||
// fsPath, nestedFs, nestedFsPath, err := resolver.resolvePath(ctx, "/", func(_ context.Context, path string) (File, error) {
|
||||
// require.Equal("/", path)
|
||||
// return &Dummy{}, nil
|
||||
// })
|
||||
// require.NoError(err)
|
||||
// require.Nil(nestedFs)
|
||||
// require.Equal("/", fsPath)
|
||||
// require.Equal("", nestedFsPath)
|
||||
// })
|
||||
|
||||
fs, err := ArchiveFactories[".zip"](ctx, &Dummy{})
|
||||
require.NoError(err)
|
||||
require.NotNil(fs)
|
||||
// t.Run("root dirty", func(t *testing.T) {
|
||||
// t.Parallel()
|
||||
// require := require.New(t)
|
||||
|
||||
fs, err = ArchiveFactories[".rar"](ctx, &Dummy{})
|
||||
require.NoError(err)
|
||||
require.NotNil(fs)
|
||||
// fsPath, nestedFs, nestedFsPath, err := resolver.resolvePath(ctx, "//.//", func(_ context.Context, path string) (File, error) {
|
||||
// require.Equal("/", path)
|
||||
// return &Dummy{}, nil
|
||||
// })
|
||||
// require.NoError(err)
|
||||
// require.Nil(nestedFs)
|
||||
// require.Equal("/", fsPath)
|
||||
// require.Equal("", nestedFsPath)
|
||||
// })
|
||||
|
||||
fs, err = ArchiveFactories[".7z"](ctx, &Dummy{})
|
||||
require.NoError(err)
|
||||
require.NotNil(fs)
|
||||
}
|
||||
// t.Run("root dirty 2", func(t *testing.T) {
|
||||
// t.Parallel()
|
||||
// require := require.New(t)
|
||||
|
||||
func TestFiles(t *testing.T) {
|
||||
t.Parallel()
|
||||
require := require.New(t)
|
||||
// fsPath, nestedFs, nestedFsPath, err := resolver.resolvePath(ctx, "/.", func(_ context.Context, path string) (File, error) {
|
||||
// require.Equal("/", path)
|
||||
// return &Dummy{}, nil
|
||||
// })
|
||||
// require.NoError(err)
|
||||
// require.Nil(nestedFs)
|
||||
// require.Equal("/", fsPath)
|
||||
// require.Equal("", nestedFsPath)
|
||||
// })
|
||||
|
||||
files := map[string]*Dummy{
|
||||
"/test/file.txt": &Dummy{},
|
||||
"/test/file2.txt": &Dummy{},
|
||||
"/test1/file.txt": &Dummy{},
|
||||
}
|
||||
{
|
||||
file, err := getFile(files, "/test")
|
||||
require.NoError(err)
|
||||
require.Equal(&dir{name: "test"}, file)
|
||||
}
|
||||
{
|
||||
file, err := getFile(files, "/test/file.txt")
|
||||
require.NoError(err)
|
||||
require.Equal(&Dummy{}, file)
|
||||
}
|
||||
{
|
||||
out, err := listDirFromFiles(files, "/test")
|
||||
require.NoError(err)
|
||||
require.Len(out, 2)
|
||||
require.Equal("file.txt", out[0].Name())
|
||||
require.Equal("file2.txt", out[1].Name())
|
||||
require.False(out[0].IsDir())
|
||||
require.False(out[1].IsDir())
|
||||
}
|
||||
{
|
||||
out, err := listDirFromFiles(files, "/test1")
|
||||
require.NoError(err)
|
||||
require.Len(out, 1)
|
||||
require.Equal("file.txt", out[0].Name())
|
||||
require.False(out[0].IsDir())
|
||||
}
|
||||
{
|
||||
out, err := listDirFromFiles(files, "/")
|
||||
require.NoError(err)
|
||||
require.Len(out, 2)
|
||||
require.Equal("test", out[0].Name())
|
||||
require.Equal("test1", out[1].Name())
|
||||
require.True(out[0].IsDir())
|
||||
require.True(out[1].IsDir())
|
||||
}
|
||||
}
|
||||
// t.Run("fs dirty", func(t *testing.T) {
|
||||
// t.Parallel()
|
||||
// require := require.New(t)
|
||||
|
||||
// fsPath, nestedFs, nestedFsPath, err := resolver.resolvePath(ctx, "//.//f1.rar", func(_ context.Context, path string) (File, error) {
|
||||
// require.Equal("/f1.rar", path)
|
||||
// return &Dummy{}, nil
|
||||
// })
|
||||
// require.NoError(err)
|
||||
// require.Equal("/f1.rar", fsPath)
|
||||
// require.Equal("/", nestedFsPath)
|
||||
// require.IsType(&ArchiveFS{}, nestedFs)
|
||||
// })
|
||||
// t.Run("inside folder", func(t *testing.T) {
|
||||
// t.Parallel()
|
||||
// require := require.New(t)
|
||||
|
||||
// fsPath, nestedFs, nestedFsPath, err := resolver.resolvePath(ctx, "//test1/f1.rar", func(_ context.Context, path string) (File, error) {
|
||||
// require.Equal("/test1/f1.rar", path)
|
||||
// return &Dummy{}, nil
|
||||
// })
|
||||
// require.NoError(err)
|
||||
// require.IsType(&ArchiveFS{}, nestedFs)
|
||||
// require.Equal("/test1/f1.rar", fsPath)
|
||||
// require.Equal("/", nestedFsPath)
|
||||
// })
|
||||
// }
|
||||
|
||||
// func TestFiles(t *testing.T) {
|
||||
// t.Parallel()
|
||||
// require := require.New(t)
|
||||
|
||||
// files := map[string]*vfs.DummyFile{
|
||||
// "/test/file.txt": &vfs.DummyFile{},
|
||||
// "/test/file2.txt": &vfs.DummyFile{},
|
||||
// "/test1/file.txt": &vfs.DummyFile{},
|
||||
// }
|
||||
// {
|
||||
// file, err := getFile(files, "/test")
|
||||
// require.NoError(err)
|
||||
// require.Equal(&dir{name: "test"}, file)
|
||||
// }
|
||||
// {
|
||||
// file, err := getFile(files, "/test/file.txt")
|
||||
// require.NoError(err)
|
||||
// require.Equal(&Dummy{}, file)
|
||||
// }
|
||||
// {
|
||||
// out, err := listDirFromFiles(files, "/test")
|
||||
// require.NoError(err)
|
||||
// require.Len(out, 2)
|
||||
// require.Equal("file.txt", out[0].Name())
|
||||
// require.Equal("file2.txt", out[1].Name())
|
||||
// require.False(out[0].IsDir())
|
||||
// require.False(out[1].IsDir())
|
||||
// }
|
||||
// {
|
||||
// out, err := listDirFromFiles(files, "/test1")
|
||||
// require.NoError(err)
|
||||
// require.Len(out, 1)
|
||||
// require.Equal("file.txt", out[0].Name())
|
||||
// require.False(out[0].IsDir())
|
||||
// }
|
||||
// {
|
||||
// out, err := listDirFromFiles(files, "/")
|
||||
// require.NoError(err)
|
||||
// require.Len(out, 2)
|
||||
// require.Equal("test", out[0].Name())
|
||||
// require.Equal("test1", out[1].Name())
|
||||
// require.True(out[0].IsDir())
|
||||
// require.True(out[1].IsDir())
|
||||
// }
|
||||
// }
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue