github.com/lacework-dev/go-moby@v20.10.12+incompatible/integration-cli/check_test.go (about)

     1  package main
     2  
     3  import (
     4  	"context"
     5  	"flag"
     6  	"fmt"
     7  	"io/ioutil"
     8  	"net/http/httptest"
     9  	"os"
    10  	"path"
    11  	"path/filepath"
    12  	"strconv"
    13  	"sync"
    14  	"syscall"
    15  	"testing"
    16  	"time"
    17  
    18  	"github.com/docker/docker/integration-cli/cli"
    19  	"github.com/docker/docker/integration-cli/daemon"
    20  	"github.com/docker/docker/integration-cli/environment"
    21  	"github.com/docker/docker/internal/test/suite"
    22  	"github.com/docker/docker/pkg/reexec"
    23  	testdaemon "github.com/docker/docker/testutil/daemon"
    24  	ienv "github.com/docker/docker/testutil/environment"
    25  	"github.com/docker/docker/testutil/fakestorage"
    26  	"github.com/docker/docker/testutil/fixtures/plugin"
    27  	"github.com/docker/docker/testutil/registry"
    28  	"gotest.tools/v3/assert"
    29  )
    30  
    31  const (
    32  	// the private registry to use for tests
    33  	privateRegistryURL = registry.DefaultURL
    34  
    35  	// path to containerd's ctr binary
    36  	ctrBinary = "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  	testEnvOnce sync.Once
    49  )
    50  
    51  func init() {
    52  	var err error
    53  
    54  	reexec.Init() // This is required for external graphdriver tests
    55  
    56  	testEnv, err = environment.New()
    57  	if err != nil {
    58  		fmt.Println(err)
    59  		os.Exit(1)
    60  	}
    61  }
    62  
    63  func TestMain(m *testing.M) {
    64  	flag.Parse()
    65  
    66  	// Global set up
    67  	dockerBinary = testEnv.DockerBinary()
    68  	err := ienv.EnsureFrozenImagesLinux(&testEnv.Execution)
    69  	if err != nil {
    70  		fmt.Println(err)
    71  		os.Exit(1)
    72  	}
    73  
    74  	testEnv.Print()
    75  	os.Exit(m.Run())
    76  }
    77  
    78  func ensureTestEnvSetup(t *testing.T) {
    79  	testEnvOnce.Do(func() {
    80  		cli.SetTestEnvironment(testEnv)
    81  		fakestorage.SetTestEnvironment(&testEnv.Execution)
    82  		ienv.ProtectAll(t, &testEnv.Execution)
    83  	})
    84  }
    85  
    86  func TestDockerSuite(t *testing.T) {
    87  	ensureTestEnvSetup(t)
    88  	suite.Run(t, &DockerSuite{})
    89  }
    90  
    91  func TestDockerRegistrySuite(t *testing.T) {
    92  	ensureTestEnvSetup(t)
    93  	suite.Run(t, &DockerRegistrySuite{ds: &DockerSuite{}})
    94  }
    95  
    96  func TestDockerSchema1RegistrySuite(t *testing.T) {
    97  	ensureTestEnvSetup(t)
    98  	suite.Run(t, &DockerSchema1RegistrySuite{ds: &DockerSuite{}})
    99  }
   100  
   101  func TestDockerRegistryAuthHtpasswdSuite(t *testing.T) {
   102  	ensureTestEnvSetup(t)
   103  	suite.Run(t, &DockerRegistryAuthHtpasswdSuite{ds: &DockerSuite{}})
   104  }
   105  
   106  func TestDockerRegistryAuthTokenSuite(t *testing.T) {
   107  	ensureTestEnvSetup(t)
   108  	suite.Run(t, &DockerRegistryAuthTokenSuite{ds: &DockerSuite{}})
   109  }
   110  
   111  func TestDockerDaemonSuite(t *testing.T) {
   112  	ensureTestEnvSetup(t)
   113  	suite.Run(t, &DockerDaemonSuite{ds: &DockerSuite{}})
   114  }
   115  
   116  func TestDockerSwarmSuite(t *testing.T) {
   117  	ensureTestEnvSetup(t)
   118  	suite.Run(t, &DockerSwarmSuite{ds: &DockerSuite{}})
   119  }
   120  
   121  func TestDockerPluginSuite(t *testing.T) {
   122  	ensureTestEnvSetup(t)
   123  	suite.Run(t, &DockerPluginSuite{ds: &DockerSuite{}})
   124  }
   125  
   126  func TestDockerExternalVolumeSuite(t *testing.T) {
   127  	ensureTestEnvSetup(t)
   128  	testRequires(t, DaemonIsLinux)
   129  	suite.Run(t, &DockerExternalVolumeSuite{ds: &DockerSuite{}})
   130  }
   131  
   132  func TestDockerNetworkSuite(t *testing.T) {
   133  	ensureTestEnvSetup(t)
   134  	testRequires(t, DaemonIsLinux)
   135  	suite.Run(t, &DockerNetworkSuite{ds: &DockerSuite{}})
   136  }
   137  
   138  func TestDockerHubPullSuite(t *testing.T) {
   139  	ensureTestEnvSetup(t)
   140  	// FIXME. Temporarily turning this off for Windows as GH16039 was breaking
   141  	// Windows to Linux CI @icecrime
   142  	testRequires(t, DaemonIsLinux)
   143  	suite.Run(t, newDockerHubPullSuite())
   144  }
   145  
   146  type DockerSuite struct {
   147  }
   148  
   149  func (s *DockerSuite) OnTimeout(c *testing.T) {
   150  	if testEnv.IsRemoteDaemon() {
   151  		return
   152  	}
   153  	path := filepath.Join(os.Getenv("DEST"), "docker.pid")
   154  	b, err := ioutil.ReadFile(path)
   155  	if err != nil {
   156  		c.Fatalf("Failed to get daemon PID from %s\n", path)
   157  	}
   158  
   159  	rawPid, err := strconv.ParseInt(string(b), 10, 32)
   160  	if err != nil {
   161  		c.Fatalf("Failed to parse pid from %s: %s\n", path, err)
   162  	}
   163  
   164  	daemonPid := int(rawPid)
   165  	if daemonPid > 0 {
   166  		testdaemon.SignalDaemonDump(daemonPid)
   167  	}
   168  }
   169  
   170  func (s *DockerSuite) TearDownTest(c *testing.T) {
   171  	testEnv.Clean(c)
   172  }
   173  
   174  type DockerRegistrySuite struct {
   175  	ds  *DockerSuite
   176  	reg *registry.V2
   177  	d   *daemon.Daemon
   178  }
   179  
   180  func (s *DockerRegistrySuite) OnTimeout(c *testing.T) {
   181  	s.d.DumpStackAndQuit()
   182  }
   183  
   184  func (s *DockerRegistrySuite) SetUpTest(c *testing.T) {
   185  	testRequires(c, DaemonIsLinux, RegistryHosting, testEnv.IsLocalDaemon)
   186  	s.reg = registry.NewV2(c)
   187  	s.reg.WaitReady(c)
   188  	s.d = daemon.New(c, dockerBinary, dockerdBinary, testdaemon.WithEnvironment(testEnv.Execution))
   189  }
   190  
   191  func (s *DockerRegistrySuite) TearDownTest(c *testing.T) {
   192  	if s.reg != nil {
   193  		s.reg.Close()
   194  	}
   195  	if s.d != nil {
   196  		s.d.Stop(c)
   197  	}
   198  	s.ds.TearDownTest(c)
   199  }
   200  
   201  type DockerSchema1RegistrySuite struct {
   202  	ds  *DockerSuite
   203  	reg *registry.V2
   204  	d   *daemon.Daemon
   205  }
   206  
   207  func (s *DockerSchema1RegistrySuite) OnTimeout(c *testing.T) {
   208  	s.d.DumpStackAndQuit()
   209  }
   210  
   211  func (s *DockerSchema1RegistrySuite) SetUpTest(c *testing.T) {
   212  	testRequires(c, DaemonIsLinux, RegistryHosting, NotArm64, testEnv.IsLocalDaemon)
   213  	s.reg = registry.NewV2(c, registry.Schema1)
   214  	s.reg.WaitReady(c)
   215  	s.d = daemon.New(c, dockerBinary, dockerdBinary, testdaemon.WithEnvironment(testEnv.Execution))
   216  }
   217  
   218  func (s *DockerSchema1RegistrySuite) TearDownTest(c *testing.T) {
   219  	if s.reg != nil {
   220  		s.reg.Close()
   221  	}
   222  	if s.d != nil {
   223  		s.d.Stop(c)
   224  	}
   225  	s.ds.TearDownTest(c)
   226  }
   227  
   228  type DockerRegistryAuthHtpasswdSuite struct {
   229  	ds  *DockerSuite
   230  	reg *registry.V2
   231  	d   *daemon.Daemon
   232  }
   233  
   234  func (s *DockerRegistryAuthHtpasswdSuite) OnTimeout(c *testing.T) {
   235  	s.d.DumpStackAndQuit()
   236  }
   237  
   238  func (s *DockerRegistryAuthHtpasswdSuite) SetUpTest(c *testing.T) {
   239  	testRequires(c, DaemonIsLinux, RegistryHosting, testEnv.IsLocalDaemon)
   240  	s.reg = registry.NewV2(c, registry.Htpasswd)
   241  	s.reg.WaitReady(c)
   242  	s.d = daemon.New(c, dockerBinary, dockerdBinary, testdaemon.WithEnvironment(testEnv.Execution))
   243  }
   244  
   245  func (s *DockerRegistryAuthHtpasswdSuite) TearDownTest(c *testing.T) {
   246  	if s.reg != nil {
   247  		out, err := s.d.Cmd("logout", privateRegistryURL)
   248  		assert.NilError(c, err, out)
   249  		s.reg.Close()
   250  	}
   251  	if s.d != nil {
   252  		s.d.Stop(c)
   253  	}
   254  	s.ds.TearDownTest(c)
   255  }
   256  
   257  type DockerRegistryAuthTokenSuite struct {
   258  	ds  *DockerSuite
   259  	reg *registry.V2
   260  	d   *daemon.Daemon
   261  }
   262  
   263  func (s *DockerRegistryAuthTokenSuite) OnTimeout(c *testing.T) {
   264  	s.d.DumpStackAndQuit()
   265  }
   266  
   267  func (s *DockerRegistryAuthTokenSuite) SetUpTest(c *testing.T) {
   268  	testRequires(c, DaemonIsLinux, RegistryHosting, testEnv.IsLocalDaemon)
   269  	s.d = daemon.New(c, dockerBinary, dockerdBinary, testdaemon.WithEnvironment(testEnv.Execution))
   270  }
   271  
   272  func (s *DockerRegistryAuthTokenSuite) TearDownTest(c *testing.T) {
   273  	if s.reg != nil {
   274  		out, err := s.d.Cmd("logout", privateRegistryURL)
   275  		assert.NilError(c, err, out)
   276  		s.reg.Close()
   277  	}
   278  	if s.d != nil {
   279  		s.d.Stop(c)
   280  	}
   281  	s.ds.TearDownTest(c)
   282  }
   283  
   284  func (s *DockerRegistryAuthTokenSuite) setupRegistryWithTokenService(c *testing.T, tokenURL string) {
   285  	if s == nil {
   286  		c.Fatal("registry suite isn't initialized")
   287  	}
   288  	s.reg = registry.NewV2(c, registry.Token(tokenURL))
   289  	s.reg.WaitReady(c)
   290  }
   291  
   292  type DockerDaemonSuite struct {
   293  	ds *DockerSuite
   294  	d  *daemon.Daemon
   295  }
   296  
   297  func (s *DockerDaemonSuite) OnTimeout(c *testing.T) {
   298  	s.d.DumpStackAndQuit()
   299  }
   300  
   301  func (s *DockerDaemonSuite) SetUpTest(c *testing.T) {
   302  	testRequires(c, DaemonIsLinux, testEnv.IsLocalDaemon)
   303  	s.d = daemon.New(c, dockerBinary, dockerdBinary, testdaemon.WithEnvironment(testEnv.Execution))
   304  }
   305  
   306  func (s *DockerDaemonSuite) TearDownTest(c *testing.T) {
   307  	testRequires(c, DaemonIsLinux, testEnv.IsLocalDaemon)
   308  	if s.d != nil {
   309  		s.d.Stop(c)
   310  	}
   311  	s.ds.TearDownTest(c)
   312  }
   313  
   314  func (s *DockerDaemonSuite) TearDownSuite(c *testing.T) {
   315  	filepath.Walk(testdaemon.SockRoot, func(path string, fi os.FileInfo, err error) error {
   316  		if err != nil {
   317  			// ignore errors here
   318  			// not cleaning up sockets is not really an error
   319  			return nil
   320  		}
   321  		if fi.Mode() == os.ModeSocket {
   322  			syscall.Unlink(path)
   323  		}
   324  		return nil
   325  	})
   326  	os.RemoveAll(testdaemon.SockRoot)
   327  }
   328  
   329  const defaultSwarmPort = 2477
   330  
   331  type DockerSwarmSuite struct {
   332  	server      *httptest.Server
   333  	ds          *DockerSuite
   334  	daemonsLock sync.Mutex // protect access to daemons and portIndex
   335  	daemons     []*daemon.Daemon
   336  	portIndex   int
   337  }
   338  
   339  func (s *DockerSwarmSuite) OnTimeout(c *testing.T) {
   340  	s.daemonsLock.Lock()
   341  	defer s.daemonsLock.Unlock()
   342  	for _, d := range s.daemons {
   343  		d.DumpStackAndQuit()
   344  	}
   345  }
   346  
   347  func (s *DockerSwarmSuite) SetUpTest(c *testing.T) {
   348  	testRequires(c, DaemonIsLinux, testEnv.IsLocalDaemon)
   349  }
   350  
   351  func (s *DockerSwarmSuite) AddDaemon(c *testing.T, joinSwarm, manager bool) *daemon.Daemon {
   352  	c.Helper()
   353  	d := daemon.New(c, dockerBinary, dockerdBinary,
   354  		testdaemon.WithEnvironment(testEnv.Execution),
   355  		testdaemon.WithSwarmPort(defaultSwarmPort+s.portIndex),
   356  	)
   357  	if joinSwarm {
   358  		if len(s.daemons) > 0 {
   359  			d.StartAndSwarmJoin(c, s.daemons[0].Daemon, manager)
   360  		} else {
   361  			d.StartAndSwarmInit(c)
   362  		}
   363  	} else {
   364  		d.StartNodeWithBusybox(c)
   365  	}
   366  
   367  	s.daemonsLock.Lock()
   368  	s.portIndex++
   369  	s.daemons = append(s.daemons, d)
   370  	s.daemonsLock.Unlock()
   371  
   372  	return d
   373  }
   374  
   375  func (s *DockerSwarmSuite) TearDownTest(c *testing.T) {
   376  	testRequires(c, DaemonIsLinux)
   377  	s.daemonsLock.Lock()
   378  	for _, d := range s.daemons {
   379  		if d != nil {
   380  			d.Stop(c)
   381  			d.Cleanup(c)
   382  		}
   383  	}
   384  	s.daemons = nil
   385  	s.portIndex = 0
   386  	s.daemonsLock.Unlock()
   387  	s.ds.TearDownTest(c)
   388  }
   389  
   390  type DockerPluginSuite struct {
   391  	ds       *DockerSuite
   392  	registry *registry.V2
   393  }
   394  
   395  func (ps *DockerPluginSuite) registryHost() string {
   396  	return privateRegistryURL
   397  }
   398  
   399  func (ps *DockerPluginSuite) getPluginRepo() string {
   400  	return path.Join(ps.registryHost(), "plugin", "basic")
   401  }
   402  func (ps *DockerPluginSuite) getPluginRepoWithTag() string {
   403  	return ps.getPluginRepo() + ":" + "latest"
   404  }
   405  
   406  func (ps *DockerPluginSuite) SetUpSuite(c *testing.T) {
   407  	testRequires(c, DaemonIsLinux, RegistryHosting)
   408  	ps.registry = registry.NewV2(c)
   409  	ps.registry.WaitReady(c)
   410  
   411  	ctx, cancel := context.WithTimeout(context.Background(), 60*time.Second)
   412  	defer cancel()
   413  
   414  	err := plugin.CreateInRegistry(ctx, ps.getPluginRepo(), nil)
   415  	assert.NilError(c, err, "failed to create plugin")
   416  }
   417  
   418  func (ps *DockerPluginSuite) TearDownSuite(c *testing.T) {
   419  	if ps.registry != nil {
   420  		ps.registry.Close()
   421  	}
   422  }
   423  
   424  func (ps *DockerPluginSuite) TearDownTest(c *testing.T) {
   425  	ps.ds.TearDownTest(c)
   426  }
   427  
   428  func (ps *DockerPluginSuite) OnTimeout(c *testing.T) {
   429  	ps.ds.OnTimeout(c)
   430  }