mirror of
https://github.com/moby/moby.git
synced 2022-11-09 12:21:53 -05:00
15a538a627
Use the (new) plugin fixtures for plugin tests rather than pulling plugins from hub. This removes the restriction for platforms/archs since plugin binaries get built in the test environment. Future work would be to add test plugins for the various subsystems so tests that are actually using plugins (e.g. volumes, networks) can be ported to use the fixtures as well. Signed-off-by: Brian Goff <cpuguy83@gmail.com>
496 lines
11 KiB
Go
496 lines
11 KiB
Go
package main
|
|
|
|
import (
|
|
"fmt"
|
|
"net/http/httptest"
|
|
"os"
|
|
"os/exec"
|
|
"path"
|
|
"path/filepath"
|
|
"strings"
|
|
"sync"
|
|
"syscall"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/docker/docker/api/types/swarm"
|
|
"github.com/docker/docker/cli/config"
|
|
"github.com/docker/docker/integration-cli/checker"
|
|
"github.com/docker/docker/integration-cli/cli"
|
|
"github.com/docker/docker/integration-cli/cli/build/fakestorage"
|
|
"github.com/docker/docker/integration-cli/daemon"
|
|
"github.com/docker/docker/integration-cli/environment"
|
|
"github.com/docker/docker/integration-cli/fixtures/plugin"
|
|
"github.com/docker/docker/integration-cli/registry"
|
|
"github.com/docker/docker/pkg/reexec"
|
|
"github.com/go-check/check"
|
|
"golang.org/x/net/context"
|
|
)
|
|
|
|
const (
|
|
// the private registry to use for tests
|
|
privateRegistryURL = "127.0.0.1:5000"
|
|
|
|
// path to containerd's ctr binary
|
|
ctrBinary = "docker-containerd-ctr"
|
|
|
|
// the docker daemon binary to use
|
|
dockerdBinary = "dockerd"
|
|
)
|
|
|
|
var (
|
|
testEnv *environment.Execution
|
|
|
|
// the docker client binary to use
|
|
dockerBinary = ""
|
|
)
|
|
|
|
func init() {
|
|
var err error
|
|
|
|
reexec.Init() // This is required for external graphdriver tests
|
|
|
|
testEnv, err = environment.New()
|
|
if err != nil {
|
|
fmt.Println(err)
|
|
os.Exit(1)
|
|
}
|
|
}
|
|
|
|
func TestMain(m *testing.M) {
|
|
dockerBinary = testEnv.DockerBinary()
|
|
|
|
if testEnv.LocalDaemon() {
|
|
fmt.Println("INFO: Testing against a local daemon")
|
|
} else {
|
|
fmt.Println("INFO: Testing against a remote daemon")
|
|
}
|
|
exitCode := m.Run()
|
|
os.Exit(exitCode)
|
|
}
|
|
|
|
func Test(t *testing.T) {
|
|
cli.EnsureTestEnvIsLoaded(t)
|
|
fakestorage.EnsureTestEnvIsLoaded(t)
|
|
cmd := exec.Command(dockerBinary, "images", "-f", "dangling=false", "--format", "{{.Repository}}:{{.Tag}}")
|
|
cmd.Env = appendBaseEnv(true)
|
|
out, err := cmd.CombinedOutput()
|
|
if err != nil {
|
|
panic(fmt.Errorf("err=%v\nout=%s\n", err, out))
|
|
}
|
|
images := strings.Split(strings.TrimSpace(string(out)), "\n")
|
|
testEnv.ProtectImage(t, images...)
|
|
if testEnv.DaemonPlatform() == "linux" {
|
|
ensureFrozenImagesLinux(t)
|
|
}
|
|
check.TestingT(t)
|
|
}
|
|
|
|
func init() {
|
|
check.Suite(&DockerSuite{})
|
|
}
|
|
|
|
type DockerSuite struct {
|
|
}
|
|
|
|
func (s *DockerSuite) OnTimeout(c *check.C) {
|
|
if testEnv.DaemonPID() > 0 && testEnv.LocalDaemon() {
|
|
daemon.SignalDaemonDump(testEnv.DaemonPID())
|
|
}
|
|
}
|
|
|
|
func (s *DockerSuite) TearDownTest(c *check.C) {
|
|
testEnv.Clean(c, dockerBinary)
|
|
}
|
|
|
|
func init() {
|
|
check.Suite(&DockerRegistrySuite{
|
|
ds: &DockerSuite{},
|
|
})
|
|
}
|
|
|
|
type DockerRegistrySuite struct {
|
|
ds *DockerSuite
|
|
reg *registry.V2
|
|
d *daemon.Daemon
|
|
}
|
|
|
|
func (s *DockerRegistrySuite) OnTimeout(c *check.C) {
|
|
s.d.DumpStackAndQuit()
|
|
}
|
|
|
|
func (s *DockerRegistrySuite) SetUpTest(c *check.C) {
|
|
testRequires(c, DaemonIsLinux, registry.Hosting)
|
|
s.reg = setupRegistry(c, false, "", "")
|
|
s.d = daemon.New(c, dockerBinary, dockerdBinary, daemon.Config{
|
|
Experimental: testEnv.ExperimentalDaemon(),
|
|
})
|
|
}
|
|
|
|
func (s *DockerRegistrySuite) TearDownTest(c *check.C) {
|
|
if s.reg != nil {
|
|
s.reg.Close()
|
|
}
|
|
if s.d != nil {
|
|
s.d.Stop(c)
|
|
}
|
|
s.ds.TearDownTest(c)
|
|
}
|
|
|
|
func init() {
|
|
check.Suite(&DockerSchema1RegistrySuite{
|
|
ds: &DockerSuite{},
|
|
})
|
|
}
|
|
|
|
type DockerSchema1RegistrySuite struct {
|
|
ds *DockerSuite
|
|
reg *registry.V2
|
|
d *daemon.Daemon
|
|
}
|
|
|
|
func (s *DockerSchema1RegistrySuite) OnTimeout(c *check.C) {
|
|
s.d.DumpStackAndQuit()
|
|
}
|
|
|
|
func (s *DockerSchema1RegistrySuite) SetUpTest(c *check.C) {
|
|
testRequires(c, DaemonIsLinux, registry.Hosting, NotArm64)
|
|
s.reg = setupRegistry(c, true, "", "")
|
|
s.d = daemon.New(c, dockerBinary, dockerdBinary, daemon.Config{
|
|
Experimental: testEnv.ExperimentalDaemon(),
|
|
})
|
|
}
|
|
|
|
func (s *DockerSchema1RegistrySuite) TearDownTest(c *check.C) {
|
|
if s.reg != nil {
|
|
s.reg.Close()
|
|
}
|
|
if s.d != nil {
|
|
s.d.Stop(c)
|
|
}
|
|
s.ds.TearDownTest(c)
|
|
}
|
|
|
|
func init() {
|
|
check.Suite(&DockerRegistryAuthHtpasswdSuite{
|
|
ds: &DockerSuite{},
|
|
})
|
|
}
|
|
|
|
type DockerRegistryAuthHtpasswdSuite struct {
|
|
ds *DockerSuite
|
|
reg *registry.V2
|
|
d *daemon.Daemon
|
|
}
|
|
|
|
func (s *DockerRegistryAuthHtpasswdSuite) OnTimeout(c *check.C) {
|
|
s.d.DumpStackAndQuit()
|
|
}
|
|
|
|
func (s *DockerRegistryAuthHtpasswdSuite) SetUpTest(c *check.C) {
|
|
testRequires(c, DaemonIsLinux, registry.Hosting)
|
|
s.reg = setupRegistry(c, false, "htpasswd", "")
|
|
s.d = daemon.New(c, dockerBinary, dockerdBinary, daemon.Config{
|
|
Experimental: testEnv.ExperimentalDaemon(),
|
|
})
|
|
}
|
|
|
|
func (s *DockerRegistryAuthHtpasswdSuite) TearDownTest(c *check.C) {
|
|
if s.reg != nil {
|
|
out, err := s.d.Cmd("logout", privateRegistryURL)
|
|
c.Assert(err, check.IsNil, check.Commentf(out))
|
|
s.reg.Close()
|
|
}
|
|
if s.d != nil {
|
|
s.d.Stop(c)
|
|
}
|
|
s.ds.TearDownTest(c)
|
|
}
|
|
|
|
func init() {
|
|
check.Suite(&DockerRegistryAuthTokenSuite{
|
|
ds: &DockerSuite{},
|
|
})
|
|
}
|
|
|
|
type DockerRegistryAuthTokenSuite struct {
|
|
ds *DockerSuite
|
|
reg *registry.V2
|
|
d *daemon.Daemon
|
|
}
|
|
|
|
func (s *DockerRegistryAuthTokenSuite) OnTimeout(c *check.C) {
|
|
s.d.DumpStackAndQuit()
|
|
}
|
|
|
|
func (s *DockerRegistryAuthTokenSuite) SetUpTest(c *check.C) {
|
|
testRequires(c, DaemonIsLinux, registry.Hosting)
|
|
s.d = daemon.New(c, dockerBinary, dockerdBinary, daemon.Config{
|
|
Experimental: testEnv.ExperimentalDaemon(),
|
|
})
|
|
}
|
|
|
|
func (s *DockerRegistryAuthTokenSuite) TearDownTest(c *check.C) {
|
|
if s.reg != nil {
|
|
out, err := s.d.Cmd("logout", privateRegistryURL)
|
|
c.Assert(err, check.IsNil, check.Commentf(out))
|
|
s.reg.Close()
|
|
}
|
|
if s.d != nil {
|
|
s.d.Stop(c)
|
|
}
|
|
s.ds.TearDownTest(c)
|
|
}
|
|
|
|
func (s *DockerRegistryAuthTokenSuite) setupRegistryWithTokenService(c *check.C, tokenURL string) {
|
|
if s == nil {
|
|
c.Fatal("registry suite isn't initialized")
|
|
}
|
|
s.reg = setupRegistry(c, false, "token", tokenURL)
|
|
}
|
|
|
|
func init() {
|
|
check.Suite(&DockerDaemonSuite{
|
|
ds: &DockerSuite{},
|
|
})
|
|
}
|
|
|
|
type DockerDaemonSuite struct {
|
|
ds *DockerSuite
|
|
d *daemon.Daemon
|
|
}
|
|
|
|
func (s *DockerDaemonSuite) OnTimeout(c *check.C) {
|
|
s.d.DumpStackAndQuit()
|
|
}
|
|
|
|
func (s *DockerDaemonSuite) SetUpTest(c *check.C) {
|
|
testRequires(c, DaemonIsLinux, SameHostDaemon)
|
|
s.d = daemon.New(c, dockerBinary, dockerdBinary, daemon.Config{
|
|
Experimental: testEnv.ExperimentalDaemon(),
|
|
})
|
|
}
|
|
|
|
func (s *DockerDaemonSuite) TearDownTest(c *check.C) {
|
|
testRequires(c, DaemonIsLinux, SameHostDaemon)
|
|
if s.d != nil {
|
|
s.d.Stop(c)
|
|
}
|
|
s.ds.TearDownTest(c)
|
|
}
|
|
|
|
func (s *DockerDaemonSuite) TearDownSuite(c *check.C) {
|
|
filepath.Walk(daemon.SockRoot, func(path string, fi os.FileInfo, err error) error {
|
|
if err != nil {
|
|
// ignore errors here
|
|
// not cleaning up sockets is not really an error
|
|
return nil
|
|
}
|
|
if fi.Mode() == os.ModeSocket {
|
|
syscall.Unlink(path)
|
|
}
|
|
return nil
|
|
})
|
|
os.RemoveAll(daemon.SockRoot)
|
|
}
|
|
|
|
const defaultSwarmPort = 2477
|
|
|
|
func init() {
|
|
check.Suite(&DockerSwarmSuite{
|
|
ds: &DockerSuite{},
|
|
})
|
|
}
|
|
|
|
type DockerSwarmSuite struct {
|
|
server *httptest.Server
|
|
ds *DockerSuite
|
|
daemons []*daemon.Swarm
|
|
daemonsLock sync.Mutex // protect access to daemons
|
|
portIndex int
|
|
}
|
|
|
|
func (s *DockerSwarmSuite) OnTimeout(c *check.C) {
|
|
s.daemonsLock.Lock()
|
|
defer s.daemonsLock.Unlock()
|
|
for _, d := range s.daemons {
|
|
d.DumpStackAndQuit()
|
|
}
|
|
}
|
|
|
|
func (s *DockerSwarmSuite) SetUpTest(c *check.C) {
|
|
testRequires(c, DaemonIsLinux)
|
|
}
|
|
|
|
func (s *DockerSwarmSuite) AddDaemon(c *check.C, joinSwarm, manager bool) *daemon.Swarm {
|
|
d := &daemon.Swarm{
|
|
Daemon: daemon.New(c, dockerBinary, dockerdBinary, daemon.Config{
|
|
Experimental: testEnv.ExperimentalDaemon(),
|
|
}),
|
|
Port: defaultSwarmPort + s.portIndex,
|
|
}
|
|
d.ListenAddr = fmt.Sprintf("0.0.0.0:%d", d.Port)
|
|
args := []string{"--iptables=false", "--swarm-default-advertise-addr=lo"} // avoid networking conflicts
|
|
d.StartWithBusybox(c, args...)
|
|
|
|
if joinSwarm == true {
|
|
if len(s.daemons) > 0 {
|
|
tokens := s.daemons[0].JoinTokens(c)
|
|
token := tokens.Worker
|
|
if manager {
|
|
token = tokens.Manager
|
|
}
|
|
c.Assert(d.Join(swarm.JoinRequest{
|
|
RemoteAddrs: []string{s.daemons[0].ListenAddr},
|
|
JoinToken: token,
|
|
}), check.IsNil)
|
|
} else {
|
|
c.Assert(d.Init(swarm.InitRequest{}), check.IsNil)
|
|
}
|
|
}
|
|
|
|
s.portIndex++
|
|
s.daemonsLock.Lock()
|
|
s.daemons = append(s.daemons, d)
|
|
s.daemonsLock.Unlock()
|
|
|
|
return d
|
|
}
|
|
|
|
func (s *DockerSwarmSuite) TearDownTest(c *check.C) {
|
|
testRequires(c, DaemonIsLinux)
|
|
s.daemonsLock.Lock()
|
|
for _, d := range s.daemons {
|
|
if d != nil {
|
|
d.Stop(c)
|
|
// FIXME(vdemeester) should be handled by SwarmDaemon ?
|
|
// raft state file is quite big (64MB) so remove it after every test
|
|
walDir := filepath.Join(d.Root, "swarm/raft/wal")
|
|
if err := os.RemoveAll(walDir); err != nil {
|
|
c.Logf("error removing %v: %v", walDir, err)
|
|
}
|
|
|
|
d.CleanupExecRoot(c)
|
|
}
|
|
}
|
|
s.daemons = nil
|
|
s.daemonsLock.Unlock()
|
|
|
|
s.portIndex = 0
|
|
s.ds.TearDownTest(c)
|
|
}
|
|
|
|
func init() {
|
|
check.Suite(&DockerTrustSuite{
|
|
ds: &DockerSuite{},
|
|
})
|
|
}
|
|
|
|
type DockerTrustSuite struct {
|
|
ds *DockerSuite
|
|
reg *registry.V2
|
|
not *testNotary
|
|
}
|
|
|
|
func (s *DockerTrustSuite) OnTimeout(c *check.C) {
|
|
s.ds.OnTimeout(c)
|
|
}
|
|
|
|
func (s *DockerTrustSuite) SetUpTest(c *check.C) {
|
|
testRequires(c, registry.Hosting, NotaryServerHosting)
|
|
s.reg = setupRegistry(c, false, "", "")
|
|
s.not = setupNotary(c)
|
|
}
|
|
|
|
func (s *DockerTrustSuite) TearDownTest(c *check.C) {
|
|
if s.reg != nil {
|
|
s.reg.Close()
|
|
}
|
|
if s.not != nil {
|
|
s.not.Close()
|
|
}
|
|
|
|
// Remove trusted keys and metadata after test
|
|
os.RemoveAll(filepath.Join(config.Dir(), "trust"))
|
|
s.ds.TearDownTest(c)
|
|
}
|
|
|
|
func init() {
|
|
ds := &DockerSuite{}
|
|
check.Suite(&DockerTrustedSwarmSuite{
|
|
trustSuite: DockerTrustSuite{
|
|
ds: ds,
|
|
},
|
|
swarmSuite: DockerSwarmSuite{
|
|
ds: ds,
|
|
},
|
|
})
|
|
}
|
|
|
|
type DockerTrustedSwarmSuite struct {
|
|
swarmSuite DockerSwarmSuite
|
|
trustSuite DockerTrustSuite
|
|
reg *registry.V2
|
|
not *testNotary
|
|
}
|
|
|
|
func (s *DockerTrustedSwarmSuite) SetUpTest(c *check.C) {
|
|
s.swarmSuite.SetUpTest(c)
|
|
s.trustSuite.SetUpTest(c)
|
|
}
|
|
|
|
func (s *DockerTrustedSwarmSuite) TearDownTest(c *check.C) {
|
|
s.trustSuite.TearDownTest(c)
|
|
s.swarmSuite.TearDownTest(c)
|
|
}
|
|
|
|
func (s *DockerTrustedSwarmSuite) OnTimeout(c *check.C) {
|
|
s.swarmSuite.OnTimeout(c)
|
|
}
|
|
|
|
func init() {
|
|
check.Suite(&DockerPluginSuite{
|
|
ds: &DockerSuite{},
|
|
})
|
|
}
|
|
|
|
type DockerPluginSuite struct {
|
|
ds *DockerSuite
|
|
registry *registry.V2
|
|
}
|
|
|
|
func (ps *DockerPluginSuite) registryHost() string {
|
|
return privateRegistryURL
|
|
}
|
|
|
|
func (ps *DockerPluginSuite) getPluginRepo() string {
|
|
return path.Join(ps.registryHost(), "plugin", "basic")
|
|
}
|
|
func (ps *DockerPluginSuite) getPluginRepoWithTag() string {
|
|
return ps.getPluginRepo() + ":" + "latest"
|
|
}
|
|
|
|
func (ps *DockerPluginSuite) SetUpSuite(c *check.C) {
|
|
testRequires(c, DaemonIsLinux)
|
|
ps.registry = setupRegistry(c, false, "", "")
|
|
|
|
ctx, cancel := context.WithTimeout(context.Background(), 60*time.Second)
|
|
defer cancel()
|
|
|
|
err := plugin.CreateInRegistry(ctx, ps.getPluginRepo(), nil)
|
|
c.Assert(err, checker.IsNil, check.Commentf("failed to create plugin"))
|
|
}
|
|
|
|
func (ps *DockerPluginSuite) TearDownSuite(c *check.C) {
|
|
if ps.registry != nil {
|
|
ps.registry.Close()
|
|
}
|
|
}
|
|
|
|
func (ps *DockerPluginSuite) TearDownTest(c *check.C) {
|
|
ps.ds.TearDownTest(c)
|
|
}
|
|
|
|
func (ps *DockerPluginSuite) OnTimeout(c *check.C) {
|
|
ps.ds.OnTimeout(c)
|
|
}
|