github.com/kaisenlinux/docker.io@v0.0.0-20230510090727-ea55db55fac7/engine/integration-cli/check_test.go (about)

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