Files
docker-cli/components/engine/integration/plugin/volume/main_test.go
Brian Goff 1c3f4cf12c Fixup some issues with plugin refcounting
In some circumstances we were not properly releasing plugin references,
leading to failures in removing a plugin with no way to recover other
than restarting the daemon.

1. If volume create fails (in the driver)
2. If a driver validation fails (should be rare)
3. If trying to get a plugin that does not match the passed in capability

Ideally the test for 1 and 2 would just be a unit test, however the
plugin interfaces are too complicated as `plugingetter` relies on
github.com/pkg/plugin/Client (a concrete type), which will require
spinning up services from within the unit test... it just wouldn't be a
unit test at this point.
I attempted to refactor this a bit, but since both libnetwork and
swarmkit are reliant on `plugingetter` as well, this would not work.
This really requires a re-write of the lower-level plugin management to
decouple these pieces.

Signed-off-by: Brian Goff <cpuguy83@gmail.com>
Upstream-commit: 3816b514387efd24394f0b8e61d55502aa6ac9ac
Component: engine
2017-10-21 15:17:57 -04:00

70 lines
1.6 KiB
Go

package volume
import (
"context"
"os"
"os/exec"
"path/filepath"
"testing"
"time"
"github.com/docker/docker/api/types"
"github.com/docker/docker/integration-cli/fixtures/plugin"
"github.com/docker/docker/pkg/locker"
"github.com/pkg/errors"
)
const dockerdBinary = "dockerd"
var pluginBuildLock = locker.New()
func ensurePlugin(t *testing.T, name string) string {
pluginBuildLock.Lock(name)
defer pluginBuildLock.Unlock(name)
installPath := filepath.Join(os.Getenv("GOPATH"), "bin", name)
if _, err := os.Stat(installPath); err == nil {
return installPath
}
goBin, err := exec.LookPath("go")
if err != nil {
t.Fatal(err)
}
cmd := exec.Command(goBin, "build", "-o", installPath, "./"+filepath.Join("cmd", name))
cmd.Env = append(cmd.Env, "CGO_ENABLED=0")
if out, err := cmd.CombinedOutput(); err != nil {
t.Fatal(errors.Wrapf(err, "error building basic plugin bin: %s", string(out)))
}
return installPath
}
func asVolumeDriver(cfg *plugin.Config) {
cfg.Interface.Types = []types.PluginInterfaceType{
{Capability: "volumedriver", Prefix: "docker", Version: "1.0"},
}
}
func withSockPath(name string) func(*plugin.Config) {
return func(cfg *plugin.Config) {
cfg.Interface.Socket = name
}
}
func createPlugin(t *testing.T, client plugin.CreateClient, alias, bin string, opts ...plugin.CreateOpt) {
pluginBin := ensurePlugin(t, bin)
opts = append(opts, withSockPath("plugin.sock"))
opts = append(opts, plugin.WithBinary(pluginBin))
ctx, cancel := context.WithTimeout(context.Background(), 60*time.Second)
err := plugin.Create(ctx, client, alias, opts...)
cancel()
if err != nil {
t.Fatal(err)
}
}