This repository has been archived by the owner on Jan 21, 2020. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 262
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Manager now uses a late binding proxy for group plugin (#354)
Signed-off-by: David Chung <[email protected]>
- Loading branch information
David Chung
authored
Jan 9, 2017
1 parent
a5967a1
commit 8269243
Showing
7 changed files
with
234 additions
and
29 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
package manager | ||
|
||
import ( | ||
"sync" | ||
|
||
"github.com/docker/infrakit/pkg/spi/group" | ||
) | ||
|
||
// NewProxy returns a plugin interface. The proxy is late-binding in that | ||
// it does not resolve plugin until a method is called. | ||
func NewProxy(finder func() (group.Plugin, error)) group.Plugin { | ||
return &proxy{finder: finder} | ||
} | ||
|
||
type proxy struct { | ||
lock sync.Mutex | ||
client group.Plugin | ||
finder func() (group.Plugin, error) | ||
} | ||
|
||
func (c *proxy) run(f func(group.Plugin) error) error { | ||
c.lock.Lock() | ||
defer c.lock.Unlock() | ||
|
||
if c.client == nil { | ||
if p, err := c.finder(); err == nil { | ||
c.client = p | ||
} else { | ||
return err | ||
} | ||
} | ||
|
||
return f(c.client) | ||
} | ||
|
||
func (c *proxy) CommitGroup(grp group.Spec, pretend bool) (resp string, err error) { | ||
err = c.run(func(g group.Plugin) error { | ||
resp, err = g.CommitGroup(grp, pretend) | ||
return err | ||
}) | ||
return | ||
} | ||
|
||
func (c *proxy) FreeGroup(id group.ID) (err error) { | ||
err = c.run(func(g group.Plugin) error { | ||
err = g.FreeGroup(id) | ||
return err | ||
}) | ||
return | ||
} | ||
|
||
func (c *proxy) DescribeGroup(id group.ID) (desc group.Description, err error) { | ||
err = c.run(func(g group.Plugin) error { | ||
desc, err = g.DescribeGroup(id) | ||
return err | ||
}) | ||
return | ||
} | ||
|
||
func (c *proxy) DestroyGroup(id group.ID) (err error) { | ||
err = c.run(func(g group.Plugin) error { | ||
err = g.DestroyGroup(id) | ||
return err | ||
}) | ||
return | ||
} | ||
|
||
func (c *proxy) InspectGroups() (specs []group.Spec, err error) { | ||
err = c.run(func(g group.Plugin) error { | ||
specs, err = g.InspectGroups() | ||
return err | ||
}) | ||
return | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,110 @@ | ||
package manager | ||
|
||
import ( | ||
"errors" | ||
"testing" | ||
|
||
"github.com/docker/infrakit/pkg/spi/group" | ||
"github.com/stretchr/testify/require" | ||
) | ||
|
||
func TestErrorOnCallsToNilPlugin(t *testing.T) { | ||
|
||
errMessage := "no-plugin" | ||
proxy := NewProxy(func() (group.Plugin, error) { | ||
return nil, errors.New(errMessage) | ||
}) | ||
|
||
err := proxy.FreeGroup(group.ID("test")) | ||
require.Error(t, err) | ||
require.Equal(t, errMessage, err.Error()) | ||
} | ||
|
||
type fakeGroupPlugin struct { | ||
group.Plugin | ||
commitGroup func(grp group.Spec, pretend bool) (string, error) | ||
freeGroup func(id group.ID) error | ||
} | ||
|
||
func (f *fakeGroupPlugin) CommitGroup(grp group.Spec, pretend bool) (string, error) { | ||
return f.commitGroup(grp, pretend) | ||
} | ||
func (f *fakeGroupPlugin) FreeGroup(id group.ID) error { | ||
return f.freeGroup(id) | ||
} | ||
|
||
func TestDelayPluginLookupCallingMethod(t *testing.T) { | ||
|
||
called := false | ||
fake := &fakeGroupPlugin{ | ||
commitGroup: func(grp group.Spec, pretend bool) (string, error) { | ||
called = true | ||
require.Equal(t, group.Spec{ID: "foo"}, grp) | ||
require.Equal(t, true, pretend) | ||
return "some-response", nil | ||
}, | ||
} | ||
|
||
proxy := NewProxy(func() (group.Plugin, error) { return fake, nil }) | ||
|
||
require.False(t, called) | ||
|
||
actualStr, actualErr := proxy.CommitGroup(group.Spec{ID: "foo"}, true) | ||
require.True(t, called) | ||
require.NoError(t, actualErr) | ||
require.Equal(t, "some-response", actualStr) | ||
} | ||
|
||
func TestDelayPluginLookupCallingMethodReturnsError(t *testing.T) { | ||
|
||
called := false | ||
fake := &fakeGroupPlugin{ | ||
freeGroup: func(id group.ID) error { | ||
called = true | ||
require.Equal(t, group.ID("foo"), id) | ||
return errors.New("can't-free") | ||
}, | ||
} | ||
|
||
proxy := NewProxy(func() (group.Plugin, error) { return fake, nil }) | ||
|
||
require.False(t, called) | ||
|
||
actualErr := proxy.FreeGroup(group.ID("foo")) | ||
require.True(t, called) | ||
require.Error(t, actualErr) | ||
require.Equal(t, "can't-free", actualErr.Error()) | ||
} | ||
|
||
func TestDelayPluginLookupCallingMultipleMethods(t *testing.T) { | ||
|
||
called := false | ||
fake := &fakeGroupPlugin{ | ||
commitGroup: func(grp group.Spec, pretend bool) (string, error) { | ||
called = true | ||
require.Equal(t, group.Spec{ID: "foo"}, grp) | ||
require.Equal(t, true, pretend) | ||
return "some-response", nil | ||
}, | ||
freeGroup: func(id group.ID) error { | ||
called = true | ||
require.Equal(t, group.ID("foo"), id) | ||
return errors.New("can't-free") | ||
}, | ||
} | ||
|
||
proxy := NewProxy(func() (group.Plugin, error) { return fake, nil }) | ||
|
||
require.False(t, called) | ||
|
||
actualStr, actualErr := proxy.CommitGroup(group.Spec{ID: "foo"}, true) | ||
require.True(t, called) | ||
require.NoError(t, actualErr) | ||
require.Equal(t, "some-response", actualStr) | ||
|
||
called = false | ||
actualErr = proxy.FreeGroup(group.ID("foo")) | ||
require.True(t, called) | ||
require.Error(t, actualErr) | ||
require.Equal(t, "can't-free", actualErr.Error()) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters