github.com/OpenFlowLabs/moby@v17.12.1-ce-rc2+incompatible/integration-cli/check_test.go (about)

     1  package main
     2  
     3  import (
     4  	"fmt"
     5  	"io/ioutil"
     6  	"net/http/httptest"
     7  	"os"
     8  	"path"
     9  	"path/filepath"
    10  	"strconv"
    11  	"sync"
    12  	"syscall"
    13  	"testing"
    14  	"time"
    15  
    16  	"github.com/docker/docker/api/types/swarm"
    17  	"github.com/docker/docker/cli/config"
    18  	"github.com/docker/docker/integration-cli/checker"
    19  	"github.com/docker/docker/integration-cli/cli"
    20  	"github.com/docker/docker/integration-cli/cli/build/fakestorage"
    21  	"github.com/docker/docker/integration-cli/daemon"
    22  	"github.com/docker/docker/integration-cli/environment"
    23  	"github.com/docker/docker/integration-cli/fixtures/plugin"
    24  	"github.com/docker/docker/integration-cli/registry"
    25  	ienv "github.com/docker/docker/internal/test/environment"
    26  	"github.com/docker/docker/pkg/reexec"
    27  	"github.com/go-check/check"
    28  	"golang.org/x/net/context"
    29  )
    30  
    31  const (
    32  	// the private registry to use for tests
    33  	privateRegistryURL = "127.0.0.1:5000"
    34  
    35  	// path to containerd's ctr binary
    36  	ctrBinary = "docker-containerd-ctr"
    37  
    38  	// the docker daemon binary to use
    39  	dockerdBinary = "dockerd"
    40  )
    41  
    42  var (
    43  	testEnv *environment.Execution
    44  
    45  	// the docker client binary to use
    46  	dockerBinary = ""
    47  )
    48  
    49  func init() {
    50  	var err error
    51  
    52  	reexec.Init() // This is required for external graphdriver tests
    53  
    54  	testEnv, err = environment.New()
    55  	if err != nil {
    56  		fmt.Println(err)
    57  		os.Exit(1)
    58  	}
    59  }
    60  
    61  func TestMain(m *testing.M) {
    62  	dockerBinary = testEnv.DockerBinary()
    63  	err := ienv.EnsureFrozenImagesLinux(&testEnv.Execution)
    64  	if err != nil {
    65  		fmt.Println(err)
    66  		os.Exit(1)
    67  	}
    68  
    69  	testEnv.Print()
    70  	os.Exit(m.Run())
    71  }
    72  
    73  func Test(t *testing.T) {
    74  	cli.SetTestEnvironment(testEnv)
    75  	fakestorage.SetTestEnvironment(&testEnv.Execution)
    76  	ienv.ProtectAll(t, &testEnv.Execution)
    77  	check.TestingT(t)
    78  }
    79  
    80  func init() {
    81  	check.Suite(&DockerSuite{})
    82  }
    83  
    84  type DockerSuite struct {
    85  }
    86  
    87  func (s *DockerSuite) OnTimeout(c *check.C) {
    88  	if !testEnv.IsLocalDaemon() {
    89  		return
    90  	}
    91  	path := filepath.Join(os.Getenv("DEST"), "docker.pid")
    92  	b, err := ioutil.ReadFile(path)
    93  	if err != nil {
    94  		c.Fatalf("Failed to get daemon PID from %s\n", path)
    95  	}
    96  
    97  	rawPid, err := strconv.ParseInt(string(b), 10, 32)
    98  	if err != nil {
    99  		c.Fatalf("Failed to parse pid from %s: %s\n", path, err)
   100  	}
   101  
   102  	daemonPid := int(rawPid)
   103  	if daemonPid > 0 {
   104  		daemon.SignalDaemonDump(daemonPid)
   105  	}
   106  }
   107  
   108  func (s *DockerSuite) TearDownTest(c *check.C) {
   109  	testEnv.Clean(c)
   110  }
   111  
   112  func init() {
   113  	check.Suite(&DockerRegistrySuite{
   114  		ds: &DockerSuite{},
   115  	})
   116  }
   117  
   118  type DockerRegistrySuite struct {
   119  	ds  *DockerSuite
   120  	reg *registry.V2
   121  	d   *daemon.Daemon
   122  }
   123  
   124  func (s *DockerRegistrySuite) OnTimeout(c *check.C) {
   125  	s.d.DumpStackAndQuit()
   126  }
   127  
   128  func (s *DockerRegistrySuite) SetUpTest(c *check.C) {
   129  	testRequires(c, DaemonIsLinux, registry.Hosting, SameHostDaemon)
   130  	s.reg = setupRegistry(c, false, "", "")
   131  	s.d = daemon.New(c, dockerBinary, dockerdBinary, daemon.Config{
   132  		Experimental: testEnv.ExperimentalDaemon(),
   133  	})
   134  }
   135  
   136  func (s *DockerRegistrySuite) TearDownTest(c *check.C) {
   137  	if s.reg != nil {
   138  		s.reg.Close()
   139  	}
   140  	if s.d != nil {
   141  		s.d.Stop(c)
   142  	}
   143  	s.ds.TearDownTest(c)
   144  }
   145  
   146  func init() {
   147  	check.Suite(&DockerSchema1RegistrySuite{
   148  		ds: &DockerSuite{},
   149  	})
   150  }
   151  
   152  type DockerSchema1RegistrySuite struct {
   153  	ds  *DockerSuite
   154  	reg *registry.V2
   155  	d   *daemon.Daemon
   156  }
   157  
   158  func (s *DockerSchema1RegistrySuite) OnTimeout(c *check.C) {
   159  	s.d.DumpStackAndQuit()
   160  }
   161  
   162  func (s *DockerSchema1RegistrySuite) SetUpTest(c *check.C) {
   163  	testRequires(c, DaemonIsLinux, registry.Hosting, NotArm64, SameHostDaemon)
   164  	s.reg = setupRegistry(c, true, "", "")
   165  	s.d = daemon.New(c, dockerBinary, dockerdBinary, daemon.Config{
   166  		Experimental: testEnv.ExperimentalDaemon(),
   167  	})
   168  }
   169  
   170  func (s *DockerSchema1RegistrySuite) TearDownTest(c *check.C) {
   171  	if s.reg != nil {
   172  		s.reg.Close()
   173  	}
   174  	if s.d != nil {
   175  		s.d.Stop(c)
   176  	}
   177  	s.ds.TearDownTest(c)
   178  }
   179  
   180  func init() {
   181  	check.Suite(&DockerRegistryAuthHtpasswdSuite{
   182  		ds: &DockerSuite{},
   183  	})
   184  }
   185  
   186  type DockerRegistryAuthHtpasswdSuite struct {
   187  	ds  *DockerSuite
   188  	reg *registry.V2
   189  	d   *daemon.Daemon
   190  }
   191  
   192  func (s *DockerRegistryAuthHtpasswdSuite) OnTimeout(c *check.C) {
   193  	s.d.DumpStackAndQuit()
   194  }
   195  
   196  func (s *DockerRegistryAuthHtpasswdSuite) SetUpTest(c *check.C) {
   197  	testRequires(c, DaemonIsLinux, registry.Hosting, SameHostDaemon)
   198  	s.reg = setupRegistry(c, false, "htpasswd", "")
   199  	s.d = daemon.New(c, dockerBinary, dockerdBinary, daemon.Config{
   200  		Experimental: testEnv.ExperimentalDaemon(),
   201  	})
   202  }
   203  
   204  func (s *DockerRegistryAuthHtpasswdSuite) TearDownTest(c *check.C) {
   205  	if s.reg != nil {
   206  		out, err := s.d.Cmd("logout", privateRegistryURL)
   207  		c.Assert(err, check.IsNil, check.Commentf(out))
   208  		s.reg.Close()
   209  	}
   210  	if s.d != nil {
   211  		s.d.Stop(c)
   212  	}
   213  	s.ds.TearDownTest(c)
   214  }
   215  
   216  func init() {
   217  	check.Suite(&DockerRegistryAuthTokenSuite{
   218  		ds: &DockerSuite{},
   219  	})
   220  }
   221  
   222  type DockerRegistryAuthTokenSuite struct {
   223  	ds  *DockerSuite
   224  	reg *registry.V2
   225  	d   *daemon.Daemon
   226  }
   227  
   228  func (s *DockerRegistryAuthTokenSuite) OnTimeout(c *check.C) {
   229  	s.d.DumpStackAndQuit()
   230  }
   231  
   232  func (s *DockerRegistryAuthTokenSuite) SetUpTest(c *check.C) {
   233  	testRequires(c, DaemonIsLinux, registry.Hosting, SameHostDaemon)
   234  	s.d = daemon.New(c, dockerBinary, dockerdBinary, daemon.Config{
   235  		Experimental: testEnv.ExperimentalDaemon(),
   236  	})
   237  }
   238  
   239  func (s *DockerRegistryAuthTokenSuite) TearDownTest(c *check.C) {
   240  	if s.reg != nil {
   241  		out, err := s.d.Cmd("logout", privateRegistryURL)
   242  		c.Assert(err, check.IsNil, check.Commentf(out))
   243  		s.reg.Close()
   244  	}
   245  	if s.d != nil {
   246  		s.d.Stop(c)
   247  	}
   248  	s.ds.TearDownTest(c)
   249  }
   250  
   251  func (s *DockerRegistryAuthTokenSuite) setupRegistryWithTokenService(c *check.C, tokenURL string) {
   252  	if s == nil {
   253  		c.Fatal("registry suite isn't initialized")
   254  	}
   255  	s.reg = setupRegistry(c, false, "token", tokenURL)
   256  }
   257  
   258  func init() {
   259  	check.Suite(&DockerDaemonSuite{
   260  		ds: &DockerSuite{},
   261  	})
   262  }
   263  
   264  type DockerDaemonSuite struct {
   265  	ds *DockerSuite
   266  	d  *daemon.Daemon
   267  }
   268  
   269  func (s *DockerDaemonSuite) OnTimeout(c *check.C) {
   270  	s.d.DumpStackAndQuit()
   271  }
   272  
   273  func (s *DockerDaemonSuite) SetUpTest(c *check.C) {
   274  	testRequires(c, DaemonIsLinux, SameHostDaemon)
   275  	s.d = daemon.New(c, dockerBinary, dockerdBinary, daemon.Config{
   276  		Experimental: testEnv.ExperimentalDaemon(),
   277  	})
   278  }
   279  
   280  func (s *DockerDaemonSuite) TearDownTest(c *check.C) {
   281  	testRequires(c, DaemonIsLinux, SameHostDaemon)
   282  	if s.d != nil {
   283  		s.d.Stop(c)
   284  	}
   285  	s.ds.TearDownTest(c)
   286  }
   287  
   288  func (s *DockerDaemonSuite) TearDownSuite(c *check.C) {
   289  	filepath.Walk(daemon.SockRoot, func(path string, fi os.FileInfo, err error) error {
   290  		if err != nil {
   291  			// ignore errors here
   292  			// not cleaning up sockets is not really an error
   293  			return nil
   294  		}
   295  		if fi.Mode() == os.ModeSocket {
   296  			syscall.Unlink(path)
   297  		}
   298  		return nil
   299  	})
   300  	os.RemoveAll(daemon.SockRoot)
   301  }
   302  
   303  const defaultSwarmPort = 2477
   304  
   305  func init() {
   306  	check.Suite(&DockerSwarmSuite{
   307  		ds: &DockerSuite{},
   308  	})
   309  }
   310  
   311  type DockerSwarmSuite struct {
   312  	server      *httptest.Server
   313  	ds          *DockerSuite
   314  	daemons     []*daemon.Swarm
   315  	daemonsLock sync.Mutex // protect access to daemons
   316  	portIndex   int
   317  }
   318  
   319  func (s *DockerSwarmSuite) OnTimeout(c *check.C) {
   320  	s.daemonsLock.Lock()
   321  	defer s.daemonsLock.Unlock()
   322  	for _, d := range s.daemons {
   323  		d.DumpStackAndQuit()
   324  	}
   325  }
   326  
   327  func (s *DockerSwarmSuite) SetUpTest(c *check.C) {
   328  	testRequires(c, DaemonIsLinux, SameHostDaemon)
   329  }
   330  
   331  func (s *DockerSwarmSuite) AddDaemon(c *check.C, joinSwarm, manager bool) *daemon.Swarm {
   332  	d := &daemon.Swarm{
   333  		Daemon: daemon.New(c, dockerBinary, dockerdBinary, daemon.Config{
   334  			Experimental: testEnv.ExperimentalDaemon(),
   335  		}),
   336  		Port: defaultSwarmPort + s.portIndex,
   337  	}
   338  	d.ListenAddr = fmt.Sprintf("0.0.0.0:%d", d.Port)
   339  	args := []string{"--iptables=false", "--swarm-default-advertise-addr=lo"} // avoid networking conflicts
   340  	d.StartWithBusybox(c, args...)
   341  
   342  	if joinSwarm {
   343  		if len(s.daemons) > 0 {
   344  			tokens := s.daemons[0].JoinTokens(c)
   345  			token := tokens.Worker
   346  			if manager {
   347  				token = tokens.Manager
   348  			}
   349  			c.Assert(d.Join(swarm.JoinRequest{
   350  				RemoteAddrs: []string{s.daemons[0].ListenAddr},
   351  				JoinToken:   token,
   352  			}), check.IsNil)
   353  		} else {
   354  			c.Assert(d.Init(swarm.InitRequest{}), check.IsNil)
   355  		}
   356  	}
   357  
   358  	s.portIndex++
   359  	s.daemonsLock.Lock()
   360  	s.daemons = append(s.daemons, d)
   361  	s.daemonsLock.Unlock()
   362  
   363  	return d
   364  }
   365  
   366  func (s *DockerSwarmSuite) TearDownTest(c *check.C) {
   367  	testRequires(c, DaemonIsLinux)
   368  	s.daemonsLock.Lock()
   369  	for _, d := range s.daemons {
   370  		if d != nil {
   371  			d.Stop(c)
   372  			// FIXME(vdemeester) should be handled by SwarmDaemon ?
   373  			// raft state file is quite big (64MB) so remove it after every test
   374  			walDir := filepath.Join(d.Root, "swarm/raft/wal")
   375  			if err := os.RemoveAll(walDir); err != nil {
   376  				c.Logf("error removing %v: %v", walDir, err)
   377  			}
   378  
   379  			d.CleanupExecRoot(c)
   380  		}
   381  	}
   382  	s.daemons = nil
   383  	s.daemonsLock.Unlock()
   384  
   385  	s.portIndex = 0
   386  	s.ds.TearDownTest(c)
   387  }
   388  
   389  func init() {
   390  	check.Suite(&DockerTrustSuite{
   391  		ds: &DockerSuite{},
   392  	})
   393  }
   394  
   395  type DockerTrustSuite struct {
   396  	ds  *DockerSuite
   397  	reg *registry.V2
   398  	not *testNotary
   399  }
   400  
   401  func (s *DockerTrustSuite) OnTimeout(c *check.C) {
   402  	s.ds.OnTimeout(c)
   403  }
   404  
   405  func (s *DockerTrustSuite) SetUpTest(c *check.C) {
   406  	testRequires(c, registry.Hosting, NotaryServerHosting)
   407  	s.reg = setupRegistry(c, false, "", "")
   408  	s.not = setupNotary(c)
   409  }
   410  
   411  func (s *DockerTrustSuite) TearDownTest(c *check.C) {
   412  	if s.reg != nil {
   413  		s.reg.Close()
   414  	}
   415  	if s.not != nil {
   416  		s.not.Close()
   417  	}
   418  
   419  	// Remove trusted keys and metadata after test
   420  	os.RemoveAll(filepath.Join(config.Dir(), "trust"))
   421  	s.ds.TearDownTest(c)
   422  }
   423  
   424  func init() {
   425  	ds := &DockerSuite{}
   426  	check.Suite(&DockerTrustedSwarmSuite{
   427  		trustSuite: DockerTrustSuite{
   428  			ds: ds,
   429  		},
   430  		swarmSuite: DockerSwarmSuite{
   431  			ds: ds,
   432  		},
   433  	})
   434  }
   435  
   436  type DockerTrustedSwarmSuite struct {
   437  	swarmSuite DockerSwarmSuite
   438  	trustSuite DockerTrustSuite
   439  	reg        *registry.V2
   440  	not        *testNotary
   441  }
   442  
   443  func (s *DockerTrustedSwarmSuite) SetUpTest(c *check.C) {
   444  	s.swarmSuite.SetUpTest(c)
   445  	s.trustSuite.SetUpTest(c)
   446  }
   447  
   448  func (s *DockerTrustedSwarmSuite) TearDownTest(c *check.C) {
   449  	s.trustSuite.TearDownTest(c)
   450  	s.swarmSuite.TearDownTest(c)
   451  }
   452  
   453  func (s *DockerTrustedSwarmSuite) OnTimeout(c *check.C) {
   454  	s.swarmSuite.OnTimeout(c)
   455  }
   456  
   457  func init() {
   458  	check.Suite(&DockerPluginSuite{
   459  		ds: &DockerSuite{},
   460  	})
   461  }
   462  
   463  type DockerPluginSuite struct {
   464  	ds       *DockerSuite
   465  	registry *registry.V2
   466  }
   467  
   468  func (ps *DockerPluginSuite) registryHost() string {
   469  	return privateRegistryURL
   470  }
   471  
   472  func (ps *DockerPluginSuite) getPluginRepo() string {
   473  	return path.Join(ps.registryHost(), "plugin", "basic")
   474  }
   475  func (ps *DockerPluginSuite) getPluginRepoWithTag() string {
   476  	return ps.getPluginRepo() + ":" + "latest"
   477  }
   478  
   479  func (ps *DockerPluginSuite) SetUpSuite(c *check.C) {
   480  	testRequires(c, DaemonIsLinux, registry.Hosting)
   481  	ps.registry = setupRegistry(c, false, "", "")
   482  
   483  	ctx, cancel := context.WithTimeout(context.Background(), 60*time.Second)
   484  	defer cancel()
   485  
   486  	err := plugin.CreateInRegistry(ctx, ps.getPluginRepo(), nil)
   487  	c.Assert(err, checker.IsNil, check.Commentf("failed to create plugin"))
   488  }
   489  
   490  func (ps *DockerPluginSuite) TearDownSuite(c *check.C) {
   491  	if ps.registry != nil {
   492  		ps.registry.Close()
   493  	}
   494  }
   495  
   496  func (ps *DockerPluginSuite) TearDownTest(c *check.C) {
   497  	ps.ds.TearDownTest(c)
   498  }
   499  
   500  func (ps *DockerPluginSuite) OnTimeout(c *check.C) {
   501  	ps.ds.OnTimeout(c)
   502  }