package proot import ( "context" "errors" "reflect" "testing" prootext "sirherobrine23.com.br/go-bds/exec/v2/proot/extensions/extensions" ) type testExtension struct { name string apply func(*prootext.Config) cleanup func() error err error } func (t testExtension) Name() string { return t.name } func (t testExtension) Type() prootext.ExtensionType { return prootext.ExtensionTypePath } func (t testExtension) Apply(_ context.Context, config *prootext.Config) (prootext.Cleanup, error) { if t.apply != nil { t.apply(config) } return t.cleanup, t.err } func TestPrepareExtensionsAppliesConfigAndCleanup(t *testing.T) { cleanupOrder := []string{} rootfs := t.TempDir() bind := t.TempDir() pr := &Proot{ Rootfs: rootfs, Binds: map[string][]string{bind: {"/bind"}}, DefaultBinds: []string{"/dev"}, Extensions: []prootext.Extension{ testExtension{ name: "first", apply: func(config *prootext.Config) { config.Rootfs = "/first" config.AddBind("/tmp/extra", "/extra") }, cleanup: func() error { cleanupOrder = append(cleanupOrder, "first") return nil }, }, testExtension{ name: "second", apply: func(config *prootext.Config) { config.Rootfs = "/second" }, cleanup: func() error { cleanupOrder = append(cleanupOrder, "second") return nil }, }, }, } prepared, err := pr.prepareExtensions() if err != nil { t.Fatalf("prepareExtensions: %v", err) } if prepared.config.Rootfs != "/second" { t.Fatalf("Rootfs = %q, want %q", prepared.config.Rootfs, "/second") } if pr.Rootfs != rootfs { t.Fatalf("prepareExtensions mutated Proot.Rootfs = %q, want %q", pr.Rootfs, rootfs) } if err := prepared.cleanup(); err != nil { t.Fatalf("cleanup: %v", err) } if want := []string{"second", "first"}; !reflect.DeepEqual(cleanupOrder, want) { t.Fatalf("cleanup order = %v, want %v", cleanupOrder, want) } } func TestPrepareExtensionsCleansUpOnApplyError(t *testing.T) { cleaned := false pr := &Proot{ Rootfs: t.TempDir(), Extensions: []prootext.Extension{ testExtension{ name: "mounted", cleanup: func() error { cleaned = true return nil }, }, testExtension{name: "broken", err: errors.New("boom")}, }, } if _, err := pr.prepareExtensions(); err == nil { t.Fatal("prepareExtensions succeeded, want error") } if !cleaned { t.Fatal("cleanup was not called after apply error") } } func TestPrepareExtensionsConvertsLegacyQemu(t *testing.T) { pr := &Proot{ Rootfs: t.TempDir(), Qemu: "/usr/bin/qemu-test", } prepared, err := pr.prepareExtensions() if err != nil { t.Fatalf("prepareExtensions: %v", err) } defer prepared.cleanup() if len(prepared.config.ExecResolvers) != 1 { t.Fatalf("exec resolvers = %d, want 1", len(prepared.config.ExecResolvers)) } }