Clean up synced folder implementation to use updated plugin fetch

This commit is contained in:
Chris Roberts 2019-03-14 16:03:05 -07:00
parent 338cf4cc0b
commit bac7689b36
4 changed files with 451 additions and 92 deletions

View File

@ -26,132 +26,145 @@ func ListSyncedFolders() *C.char {
//export SyncedFolderCleanup
func SyncedFolderCleanup(pluginName, machine, opts *C.char) *C.char {
r := &Response{}
p, err := getSyncedFolderPlugin(pluginName)
i, err := Plugins.PluginLookup(to_gs(pluginName), "synced_folder")
if err != nil {
r.Error = err
return r.Dump()
}
m, err := vagrant.LoadMachine(C.GoString(machine), nil)
p, ok := i.(plugin.SyncedFolder)
if !ok {
r.Error = errors.New("failed to load requested plugin")
return r.Dump()
}
m, err := vagrant.LoadMachine(to_gs(machine), nil)
if err != nil {
r.Error = err
return r.Dump()
}
var o vagrant.FolderOptions
r.Error = json.Unmarshal([]byte(C.GoString(opts)), &o)
r.Error = json.Unmarshal([]byte(to_gs(opts)), &o)
if r.Error != nil {
return r.Dump()
}
r.Error = p.SyncedFolder.Cleanup(m, o)
r.Error = p.Cleanup(m, o)
return r.Dump()
}
//export SyncedFolderDisable
func SyncedFolderDisable(pluginName, machine, folders, opts *C.char) *C.char {
r := &Response{}
p, err := getSyncedFolderPlugin(pluginName)
i, err := Plugins.PluginLookup(to_gs(pluginName), "synced_folder")
if err != nil {
r.Error = err
return r.Dump()
}
m, err := vagrant.LoadMachine(C.GoString(machine), nil)
p, ok := i.(plugin.SyncedFolder)
if !ok {
r.Error = errors.New("failed to load requested plugin")
return r.Dump()
}
m, err := vagrant.LoadMachine(to_gs(machine), nil)
if err != nil {
r.Error = err
return r.Dump()
}
var f vagrant.FolderList
r.Error = json.Unmarshal([]byte(C.GoString(folders)), &f)
r.Error = json.Unmarshal([]byte(to_gs(folders)), &f)
if r.Error != nil {
return r.Dump()
}
var o vagrant.FolderOptions
r.Error = json.Unmarshal([]byte(C.GoString(opts)), &o)
r.Error = json.Unmarshal([]byte(to_gs(opts)), &o)
if r.Error != nil {
return r.Dump()
}
r.Error = p.SyncedFolder.Disable(m, f, o)
r.Error = p.Disable(m, f, o)
return r.Dump()
}
//export SyncedFolderEnable
func SyncedFolderEnable(pluginName, machine, folders, opts *C.char) *C.char {
r := &Response{}
p, err := getSyncedFolderPlugin(pluginName)
i, err := Plugins.PluginLookup(to_gs(pluginName), "synced_folder")
if err != nil {
r.Error = err
return r.Dump()
}
m, err := vagrant.LoadMachine(C.GoString(machine), nil)
p, ok := i.(plugin.SyncedFolder)
if !ok {
r.Error = errors.New("failed to load requested plugin")
return r.Dump()
}
m, err := vagrant.LoadMachine(to_gs(machine), nil)
if err != nil {
r.Error = err
return r.Dump()
}
var f vagrant.FolderList
r.Error = json.Unmarshal([]byte(C.GoString(folders)), &f)
r.Error = json.Unmarshal([]byte(to_gs(folders)), &f)
if r.Error != nil {
return r.Dump()
}
var o vagrant.FolderOptions
r.Error = json.Unmarshal([]byte(C.GoString(opts)), &o)
r.Error = json.Unmarshal([]byte(to_gs(opts)), &o)
if r.Error != nil {
return r.Dump()
}
r.Error = p.SyncedFolder.Enable(m, f, o)
r.Error = p.Enable(m, f, o)
return r.Dump()
}
//export SyncedFolderIsUsable
func SyncedFolderIsUsable(pluginName, machine *C.char) *C.char {
r := &Response{}
p, err := getSyncedFolderPlugin(pluginName)
i, err := Plugins.PluginLookup(to_gs(pluginName), "synced_folder")
if err != nil {
r.Error = err
return r.Dump()
}
m, err := vagrant.LoadMachine(C.GoString(machine), nil)
p, ok := i.(plugin.SyncedFolder)
if !ok {
r.Error = errors.New("failed to load requested plugin")
return r.Dump()
}
m, err := vagrant.LoadMachine(to_gs(machine), nil)
if err != nil {
r.Error = err
return r.Dump()
}
r.Result, r.Error = p.SyncedFolder.IsUsable(m)
r.Result, r.Error = p.IsUsable(m)
return r.Dump()
}
//export SyncedFolderPrepare
func SyncedFolderPrepare(pluginName, machine, folders, opts *C.char) *C.char {
r := &Response{}
p, err := getSyncedFolderPlugin(pluginName)
i, err := Plugins.PluginLookup(to_gs(pluginName), "synced_folder")
if err != nil {
r.Error = err
return r.Dump()
}
m, err := vagrant.LoadMachine(C.GoString(machine), nil)
p, ok := i.(plugin.SyncedFolder)
if !ok {
r.Error = errors.New("failed to load requested plugin")
return r.Dump()
}
m, err := vagrant.LoadMachine(to_gs(machine), nil)
if err != nil {
r.Error = err
return r.Dump()
}
var f vagrant.FolderList
r.Error = json.Unmarshal([]byte(C.GoString(folders)), &f)
r.Error = json.Unmarshal([]byte(to_gs(folders)), &f)
if r.Error != nil {
return r.Dump()
}
var o vagrant.FolderOptions
r.Error = json.Unmarshal([]byte(C.GoString(opts)), &o)
r.Error = json.Unmarshal([]byte(to_gs(opts)), &o)
if r.Error != nil {
return r.Dump()
}
r.Error = p.SyncedFolder.Prepare(m, f, o)
r.Error = p.Prepare(m, f, o)
return r.Dump()
}
func getSyncedFolderPlugin(pluginName *C.char) (c *plugin.RemoteSyncedFolder, err error) {
pname := C.GoString(pluginName)
p, ok := Plugins.SyncedFolders[pname]
if !ok {
err = errors.New("Failed to locate requested plugin")
return
}
c = &plugin.RemoteSyncedFolder{
Client: p.Client,
SyncedFolder: p.SyncedFolder}
return
}

View File

@ -0,0 +1,347 @@
package main
import (
"testing"
"github.com/hashicorp/go-plugin"
vplugin "github.com/hashicorp/vagrant/ext/go-plugin/vagrant/plugin"
)
func TestSyncedFolder_ListSyncedFolders(t *testing.T) {
client, server := plugin.TestPluginGRPCConn(t, map[string]plugin.Plugin{
"folder": &vplugin.SyncedFolderPlugin{Impl: &vplugin.MockSyncedFolder{}}})
defer server.Stop()
defer client.Close()
raw, err := client.Dispense("folder")
if err != nil {
t.Fatalf("err: %s", err)
}
impl, ok := raw.(vplugin.SyncedFolder)
if !ok {
t.Fatalf("bad %#v", raw)
}
p := &vplugin.RemoteSyncedFolder{
SyncedFolder: impl}
Plugins = vplugin.VagrantPluginInit()
Plugins.SyncedFolders[impl.Name()] = p
result := ListSyncedFolders()
resp, err := LoadResponse(result)
if err != nil {
t.Fatalf("err: %s", err)
}
if resp.Error != nil {
t.Fatalf("err: %s", err)
}
r, ok := resp.Result.(map[string]interface{})
if !ok {
t.Fatalf("bad %#v", resp.Result)
}
if r["mock_folder"] == nil {
t.Fatalf("bad result")
}
i, ok := r["mock_folder"].(map[string]interface{})
if !ok {
t.Fatalf("bad %#v", r["mock_folder"])
}
if i["description"] != "mock_folder" {
t.Errorf("%s != mock_folder", i["description"])
}
if i["priority"] != 100.0 {
t.Errorf("%d != 100", i["priority"])
}
}
func TestSyncedFolder_SyncedFolderCleanup(t *testing.T) {
client, server := plugin.TestPluginGRPCConn(t, map[string]plugin.Plugin{
"folder": &vplugin.SyncedFolderPlugin{Impl: &vplugin.MockSyncedFolder{}}})
defer server.Stop()
defer client.Close()
raw, err := client.Dispense("folder")
if err != nil {
t.Fatalf("err: %s", err)
}
impl, ok := raw.(vplugin.SyncedFolder)
if !ok {
t.Fatalf("bad %#v", raw)
}
Plugins = vplugin.VagrantPluginInit()
Plugins.PluginLookup = func(_, _ string) (r interface{}, err error) {
r = impl
return
}
result := SyncedFolderCleanup(nil, to_cs("{}"), to_cs("null"))
resp, err := LoadResponse(result)
if err != nil {
t.Fatalf("err: %s", err)
}
if resp.Error != nil {
t.Fatalf("err: %s", resp.Error)
}
}
func TestSyncedFolder_SyncedFolderCleanup_error(t *testing.T) {
client, server := plugin.TestPluginGRPCConn(t, map[string]plugin.Plugin{
"folder": &vplugin.SyncedFolderPlugin{Impl: &vplugin.MockSyncedFolder{}}})
defer server.Stop()
defer client.Close()
raw, err := client.Dispense("folder")
if err != nil {
t.Fatalf("err: %s", err)
}
impl, ok := raw.(vplugin.SyncedFolder)
if !ok {
t.Fatalf("bad %#v", raw)
}
Plugins = vplugin.VagrantPluginInit()
Plugins.PluginLookup = func(_, _ string) (r interface{}, err error) {
r = impl
return
}
result := SyncedFolderCleanup(nil, to_cs("{}"), to_cs("{\"error\":true}"))
resp, err := LoadResponse(result)
if err != nil {
t.Fatalf("err: %s", err)
}
if resp.Error == nil {
t.Fatalf("error expected")
}
}
func TestSyncedFolder_SyncedFolderDisable(t *testing.T) {
client, server := plugin.TestPluginGRPCConn(t, map[string]plugin.Plugin{
"folder": &vplugin.SyncedFolderPlugin{Impl: &vplugin.MockSyncedFolder{}}})
defer server.Stop()
defer client.Close()
raw, err := client.Dispense("folder")
if err != nil {
t.Fatalf("err: %s", err)
}
impl, ok := raw.(vplugin.SyncedFolder)
if !ok {
t.Fatalf("bad %#v", raw)
}
Plugins = vplugin.VagrantPluginInit()
Plugins.PluginLookup = func(_, _ string) (r interface{}, err error) {
r = impl
return
}
result := SyncedFolderDisable(nil, to_cs("{}"), to_cs("{}"), to_cs("null"))
resp, err := LoadResponse(result)
if err != nil {
t.Fatalf("err: %s", err)
}
if resp.Error != nil {
t.Fatalf("err: %s", resp.Error)
}
}
func TestSyncedFolder_SyncedFolderDisable_error(t *testing.T) {
client, server := plugin.TestPluginGRPCConn(t, map[string]plugin.Plugin{
"folder": &vplugin.SyncedFolderPlugin{Impl: &vplugin.MockSyncedFolder{}}})
defer server.Stop()
defer client.Close()
raw, err := client.Dispense("folder")
if err != nil {
t.Fatalf("err: %s", err)
}
impl, ok := raw.(vplugin.SyncedFolder)
if !ok {
t.Fatalf("bad %#v", raw)
}
Plugins = vplugin.VagrantPluginInit()
Plugins.PluginLookup = func(_, _ string) (r interface{}, err error) {
r = impl
return
}
result := SyncedFolderDisable(nil, to_cs("{}"), to_cs("{}"), to_cs("{\"error\":true}"))
resp, err := LoadResponse(result)
if err != nil {
t.Fatalf("err: %s", err)
}
if resp.Error == nil {
t.Fatalf("rror expected")
}
}
func TestSyncedFolder_SyncedFolderEnable(t *testing.T) {
client, server := plugin.TestPluginGRPCConn(t, map[string]plugin.Plugin{
"folder": &vplugin.SyncedFolderPlugin{Impl: &vplugin.MockSyncedFolder{}}})
defer server.Stop()
defer client.Close()
raw, err := client.Dispense("folder")
if err != nil {
t.Fatalf("err: %s", err)
}
impl, ok := raw.(vplugin.SyncedFolder)
if !ok {
t.Fatalf("bad %#v", raw)
}
Plugins = vplugin.VagrantPluginInit()
Plugins.PluginLookup = func(_, _ string) (r interface{}, err error) {
r = impl
return
}
result := SyncedFolderEnable(nil, to_cs("{}"), to_cs("{}"), to_cs("null"))
resp, err := LoadResponse(result)
if err != nil {
t.Fatalf("err: %s", err)
}
if resp.Error != nil {
t.Fatalf("err: %s", resp.Error)
}
}
func TestSyncedFolder_SyncedFolderEnable_error(t *testing.T) {
client, server := plugin.TestPluginGRPCConn(t, map[string]plugin.Plugin{
"folder": &vplugin.SyncedFolderPlugin{Impl: &vplugin.MockSyncedFolder{}}})
defer server.Stop()
defer client.Close()
raw, err := client.Dispense("folder")
if err != nil {
t.Fatalf("err: %s", err)
}
impl, ok := raw.(vplugin.SyncedFolder)
if !ok {
t.Fatalf("bad %#v", raw)
}
Plugins = vplugin.VagrantPluginInit()
Plugins.PluginLookup = func(_, _ string) (r interface{}, err error) {
r = impl
return
}
result := SyncedFolderEnable(nil, to_cs("{}"), to_cs("{}"), to_cs("{\"error\":true}"))
resp, err := LoadResponse(result)
if err != nil {
t.Fatalf("err: %s", err)
}
if resp.Error == nil {
t.Fatalf("rror expected")
}
}
func TestSyncedFolder_SyncedFolderIsUsable(t *testing.T) {
client, server := plugin.TestPluginGRPCConn(t, map[string]plugin.Plugin{
"folder": &vplugin.SyncedFolderPlugin{Impl: &vplugin.MockSyncedFolder{}}})
defer server.Stop()
defer client.Close()
raw, err := client.Dispense("folder")
if err != nil {
t.Fatalf("err: %s", err)
}
impl, ok := raw.(vplugin.SyncedFolder)
if !ok {
t.Fatalf("bad %#v", raw)
}
Plugins = vplugin.VagrantPluginInit()
Plugins.PluginLookup = func(_, _ string) (r interface{}, err error) {
r = impl
return
}
result := SyncedFolderIsUsable(nil, to_cs("{}"))
resp, err := LoadResponse(result)
if err != nil {
t.Fatalf("err: %s", err)
}
if resp.Error != nil {
t.Fatalf("err: %s", resp.Error)
}
usable, ok := resp.Result.(bool)
if !ok {
t.Fatalf("bad %#v", resp.Result)
}
if !usable {
t.Fatalf("bad result")
}
}
func TestSyncedFolder_SyncedFolderPrepare(t *testing.T) {
client, server := plugin.TestPluginGRPCConn(t, map[string]plugin.Plugin{
"folder": &vplugin.SyncedFolderPlugin{Impl: &vplugin.MockSyncedFolder{}}})
defer server.Stop()
defer client.Close()
raw, err := client.Dispense("folder")
if err != nil {
t.Fatalf("err: %s", err)
}
impl, ok := raw.(vplugin.SyncedFolder)
if !ok {
t.Fatalf("bad %#v", raw)
}
Plugins = vplugin.VagrantPluginInit()
Plugins.PluginLookup = func(_, _ string) (r interface{}, err error) {
r = impl
return
}
result := SyncedFolderPrepare(nil, to_cs("{}"), to_cs("{}"), to_cs("null"))
resp, err := LoadResponse(result)
if err != nil {
t.Fatalf("err: %s", err)
}
if resp.Error != nil {
t.Fatalf("err: %s", resp.Error)
}
}
func TestSyncedFolder_SyncedFolderPrepare_error(t *testing.T) {
client, server := plugin.TestPluginGRPCConn(t, map[string]plugin.Plugin{
"folder": &vplugin.SyncedFolderPlugin{Impl: &vplugin.MockSyncedFolder{}}})
defer server.Stop()
defer client.Close()
raw, err := client.Dispense("folder")
if err != nil {
t.Fatalf("err: %s", err)
}
impl, ok := raw.(vplugin.SyncedFolder)
if !ok {
t.Fatalf("bad %#v", raw)
}
Plugins = vplugin.VagrantPluginInit()
Plugins.PluginLookup = func(_, _ string) (r interface{}, err error) {
r = impl
return
}
result := SyncedFolderPrepare(nil, to_cs("{}"), to_cs("{}"), to_cs("{\"error\":true}"))
resp, err := LoadResponse(result)
if err != nil {
t.Fatalf("err: %s", err)
}
if resp.Error == nil {
t.Fatalf("error expected")
}
}

View File

@ -174,3 +174,59 @@ func (c *MockProvider) Info() *vagrant.ProviderInfo {
Description: "Custom",
Priority: 10}
}
type MockSyncedFolder struct {
Core
vagrant.NoGuestCapabilities
vagrant.NoHostCapabilities
}
func (s *MockSyncedFolder) Cleanup(m *vagrant.Machine, opts vagrant.FolderOptions) error {
if opts != nil {
err, _ := opts["error"].(bool)
ui, _ := opts["ui"].(bool)
if err {
return errors.New("cleanup error")
}
if ui {
m.UI.Say("test_output_sf")
return nil
}
}
return nil
}
func (s *MockSyncedFolder) Disable(m *vagrant.Machine, f vagrant.FolderList, opts vagrant.FolderOptions) error {
if opts != nil && opts["error"].(bool) {
return errors.New("disable error")
}
return nil
}
func (s *MockSyncedFolder) Enable(m *vagrant.Machine, f vagrant.FolderList, opts vagrant.FolderOptions) error {
if opts != nil && opts["error"].(bool) {
return errors.New("enable error")
}
return nil
}
func (s *MockSyncedFolder) Info() *vagrant.SyncedFolderInfo {
return &vagrant.SyncedFolderInfo{
Description: "mock_folder",
Priority: 100}
}
func (s *MockSyncedFolder) IsUsable(m *vagrant.Machine) (bool, error) {
return true, nil
}
func (s *MockSyncedFolder) Name() string {
return "mock_folder"
}
func (s *MockSyncedFolder) Prepare(m *vagrant.Machine, f vagrant.FolderList, opts vagrant.FolderOptions) error {
if opts != nil && opts["error"].(bool) {
return errors.New("prepare error")
}
return nil
}

View File

@ -1,7 +1,6 @@
package plugin
import (
"errors"
"strings"
"testing"
@ -9,62 +8,6 @@ import (
"github.com/hashicorp/vagrant/ext/go-plugin/vagrant"
)
type MockSyncedFolder struct {
Core
vagrant.NoGuestCapabilities
vagrant.NoHostCapabilities
}
func (s *MockSyncedFolder) Cleanup(m *vagrant.Machine, opts vagrant.FolderOptions) error {
if opts != nil {
err, _ := opts["error"].(bool)
ui, _ := opts["ui"].(bool)
if err {
return errors.New("cleanup error")
}
if ui {
m.UI.Say("test_output_sf")
return nil
}
}
return nil
}
func (s *MockSyncedFolder) Disable(m *vagrant.Machine, f vagrant.FolderList, opts vagrant.FolderOptions) error {
if opts != nil && opts["error"].(bool) {
return errors.New("disable error")
}
return nil
}
func (s *MockSyncedFolder) Enable(m *vagrant.Machine, f vagrant.FolderList, opts vagrant.FolderOptions) error {
if opts != nil && opts["error"].(bool) {
return errors.New("enable error")
}
return nil
}
func (s *MockSyncedFolder) Info() *vagrant.SyncedFolderInfo {
return &vagrant.SyncedFolderInfo{
Description: "mock_folder",
Priority: 100}
}
func (s *MockSyncedFolder) IsUsable(m *vagrant.Machine) (bool, error) {
return true, nil
}
func (s *MockSyncedFolder) Name() string {
return "mock_folder"
}
func (s *MockSyncedFolder) Prepare(m *vagrant.Machine, f vagrant.FolderList, opts vagrant.FolderOptions) error {
if opts != nil && opts["error"].(bool) {
return errors.New("prepare error")
}
return nil
}
func TestSyncedFolder_Cleanup(t *testing.T) {
client, server := plugin.TestPluginGRPCConn(t, map[string]plugin.Plugin{
"folder": &SyncedFolderPlugin{Impl: &MockSyncedFolder{}}})