package mountablefs
import (
"testing"
"github.com/c4pt0r/agfs/agfs-server/pkg/filesystem"
"github.com/c4pt0r/agfs/agfs-server/pkg/plugin"
"github.com/c4pt0r/agfs/agfs-server/pkg/plugin/api"
)
type MockPlugin struct {
name string
}
func (p *MockPlugin) Name() string {
return p.name
}
func (p *MockPlugin) Validate(cfg map[string]interface{}) error {
return nil
}
func (p *MockPlugin) Initialize(cfg map[string]interface{}) error {
return nil
}
func (p *MockPlugin) GetFileSystem() filesystem.FileSystem {
return nil
}
func (p *MockPlugin) GetReadme() string {
return "Mock Plugin"
}
func (p *MockPlugin) GetConfigParams() []plugin.ConfigParameter {
return nil
}
func (p *MockPlugin) Shutdown() error {
return nil
}
func TestMountableFSRouting(t *testing.T) {
mfs := NewMountableFS(api.PoolConfig{})
p1 := &MockPlugin{name: "plugin1"}
p2 := &MockPlugin{name: "plugin2"}
pRoot := &MockPlugin{name: "rootPlugin"}
err := mfs.Mount("/data", p1)
if err != nil {
t.Fatalf("Failed to mount: %v", err)
}
mount, relPath, found := mfs.findMount("/data")
if !found {
t.Errorf("Expected to find mount at /data")
}
if mount.Plugin != p1 {
t.Errorf("Expected plugin1, got %s", mount.Plugin.Name())
}
if relPath != "/" {
t.Errorf("Expected relPath /, got %s", relPath)
}
mount, relPath, found = mfs.findMount("/data/file.txt")
if !found {
t.Errorf("Expected to find mount at /data/file.txt")
}
if mount.Plugin != p1 {
t.Errorf("Expected plugin1, got %s", mount.Plugin.Name())
}
if relPath != "/file.txt" {
t.Errorf("Expected relPath /file.txt, got %s", relPath)
}
mount, _, found = mfs.findMount("/dataset")
if found {
t.Errorf("Should NOT find mount for /dataset (partial match of /data)")
}
err = mfs.Mount("/data/users", p2)
if err != nil {
t.Fatalf("Failed to mount nested: %v", err)
}
mount, _, found = mfs.findMount("/data/config")
if !found || mount.Plugin != p1 {
t.Errorf("Expected /data/config to map to plugin1")
}
mount, relPath, found = mfs.findMount("/data/users/alice")
if !found {
t.Errorf("Expected to find mount at /data/users/alice")
}
if mount.Plugin != p2 {
t.Errorf("Expected plugin2, got %s", mount.Plugin.Name())
}
if relPath != "/alice" {
t.Errorf("Expected relPath /alice, got %s", relPath)
}
err = mfs.Mount("/", pRoot)
if err != nil {
t.Fatalf("Failed to mount root: %v", err)
}
mount, relPath, found = mfs.findMount("/other/file")
if !found {
t.Errorf("Expected to find mount at /other/file")
}
if mount.Plugin != pRoot {
t.Errorf("Expected rootPlugin, got %s", mount.Plugin.Name())
}
if relPath != "/other/file" {
t.Errorf("Expected relPath /other/file, got %s", relPath)
}
mount, _, found = mfs.findMount("/data/users/alice")
if !found || mount.Plugin != p2 {
t.Errorf("Root mount broke specific mount routing")
}
err = mfs.Unmount("/data")
if err != nil {
t.Fatalf("Failed to unmount: %v", err)
}
mount, _, found = mfs.findMount("/data/file")
if !found {
t.Errorf("Expected /data/file to be found (fallback to root)")
}
if mount.Plugin != pRoot {
t.Errorf("Expected fallback to rootPlugin, got %s", mount.Plugin.Name())
}
mount, _, found = mfs.findMount("/data/users/bob")
if !found || mount.Plugin != p2 {
t.Errorf("Unmounting parent should not affect child mount")
}
}