github.com/kaisenlinux/docker@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 }