github.com/ssdev-go/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 }