check_test.go 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416
  1. package main
  2. import (
  3. "fmt"
  4. "io/ioutil"
  5. "net/http/httptest"
  6. "os"
  7. "path"
  8. "path/filepath"
  9. "strconv"
  10. "sync"
  11. "syscall"
  12. "testing"
  13. "time"
  14. "github.com/docker/docker/integration-cli/checker"
  15. "github.com/docker/docker/integration-cli/cli"
  16. "github.com/docker/docker/integration-cli/cli/build/fakestorage"
  17. "github.com/docker/docker/integration-cli/daemon"
  18. "github.com/docker/docker/integration-cli/environment"
  19. "github.com/docker/docker/integration-cli/fixtures/plugin"
  20. testdaemon "github.com/docker/docker/internal/test/daemon"
  21. ienv "github.com/docker/docker/internal/test/environment"
  22. "github.com/docker/docker/internal/test/registry"
  23. "github.com/docker/docker/pkg/reexec"
  24. "github.com/go-check/check"
  25. "golang.org/x/net/context"
  26. )
  27. const (
  28. // the private registry to use for tests
  29. privateRegistryURL = registry.DefaultURL
  30. // path to containerd's ctr binary
  31. ctrBinary = "docker-containerd-ctr"
  32. // the docker daemon binary to use
  33. dockerdBinary = "dockerd"
  34. )
  35. var (
  36. testEnv *environment.Execution
  37. // the docker client binary to use
  38. dockerBinary = ""
  39. )
  40. func init() {
  41. var err error
  42. reexec.Init() // This is required for external graphdriver tests
  43. testEnv, err = environment.New()
  44. if err != nil {
  45. fmt.Println(err)
  46. os.Exit(1)
  47. }
  48. }
  49. func TestMain(m *testing.M) {
  50. dockerBinary = testEnv.DockerBinary()
  51. err := ienv.EnsureFrozenImagesLinux(&testEnv.Execution)
  52. if err != nil {
  53. fmt.Println(err)
  54. os.Exit(1)
  55. }
  56. testEnv.Print()
  57. os.Exit(m.Run())
  58. }
  59. func Test(t *testing.T) {
  60. cli.SetTestEnvironment(testEnv)
  61. fakestorage.SetTestEnvironment(&testEnv.Execution)
  62. ienv.ProtectAll(t, &testEnv.Execution)
  63. check.TestingT(t)
  64. }
  65. func init() {
  66. check.Suite(&DockerSuite{})
  67. }
  68. type DockerSuite struct {
  69. }
  70. func (s *DockerSuite) OnTimeout(c *check.C) {
  71. if testEnv.IsRemoteDaemon() {
  72. return
  73. }
  74. path := filepath.Join(os.Getenv("DEST"), "docker.pid")
  75. b, err := ioutil.ReadFile(path)
  76. if err != nil {
  77. c.Fatalf("Failed to get daemon PID from %s\n", path)
  78. }
  79. rawPid, err := strconv.ParseInt(string(b), 10, 32)
  80. if err != nil {
  81. c.Fatalf("Failed to parse pid from %s: %s\n", path, err)
  82. }
  83. daemonPid := int(rawPid)
  84. if daemonPid > 0 {
  85. testdaemon.SignalDaemonDump(daemonPid)
  86. }
  87. }
  88. func (s *DockerSuite) TearDownTest(c *check.C) {
  89. testEnv.Clean(c)
  90. }
  91. func init() {
  92. check.Suite(&DockerRegistrySuite{
  93. ds: &DockerSuite{},
  94. })
  95. }
  96. type DockerRegistrySuite struct {
  97. ds *DockerSuite
  98. reg *registry.V2
  99. d *daemon.Daemon
  100. }
  101. func (s *DockerRegistrySuite) OnTimeout(c *check.C) {
  102. s.d.DumpStackAndQuit()
  103. }
  104. func (s *DockerRegistrySuite) SetUpTest(c *check.C) {
  105. testRequires(c, DaemonIsLinux, RegistryHosting, SameHostDaemon)
  106. s.reg = registry.NewV2(c)
  107. s.reg.WaitReady(c)
  108. s.d = daemon.New(c, dockerBinary, dockerdBinary, testdaemon.WithEnvironment(testEnv.Execution))
  109. }
  110. func (s *DockerRegistrySuite) TearDownTest(c *check.C) {
  111. if s.reg != nil {
  112. s.reg.Close()
  113. }
  114. if s.d != nil {
  115. s.d.Stop(c)
  116. }
  117. s.ds.TearDownTest(c)
  118. }
  119. func init() {
  120. check.Suite(&DockerSchema1RegistrySuite{
  121. ds: &DockerSuite{},
  122. })
  123. }
  124. type DockerSchema1RegistrySuite struct {
  125. ds *DockerSuite
  126. reg *registry.V2
  127. d *daemon.Daemon
  128. }
  129. func (s *DockerSchema1RegistrySuite) OnTimeout(c *check.C) {
  130. s.d.DumpStackAndQuit()
  131. }
  132. func (s *DockerSchema1RegistrySuite) SetUpTest(c *check.C) {
  133. testRequires(c, DaemonIsLinux, RegistryHosting, NotArm64, SameHostDaemon)
  134. s.reg = registry.NewV2(c, registry.Schema1)
  135. s.reg.WaitReady(c)
  136. s.d = daemon.New(c, dockerBinary, dockerdBinary, testdaemon.WithEnvironment(testEnv.Execution))
  137. }
  138. func (s *DockerSchema1RegistrySuite) TearDownTest(c *check.C) {
  139. if s.reg != nil {
  140. s.reg.Close()
  141. }
  142. if s.d != nil {
  143. s.d.Stop(c)
  144. }
  145. s.ds.TearDownTest(c)
  146. }
  147. func init() {
  148. check.Suite(&DockerRegistryAuthHtpasswdSuite{
  149. ds: &DockerSuite{},
  150. })
  151. }
  152. type DockerRegistryAuthHtpasswdSuite struct {
  153. ds *DockerSuite
  154. reg *registry.V2
  155. d *daemon.Daemon
  156. }
  157. func (s *DockerRegistryAuthHtpasswdSuite) OnTimeout(c *check.C) {
  158. s.d.DumpStackAndQuit()
  159. }
  160. func (s *DockerRegistryAuthHtpasswdSuite) SetUpTest(c *check.C) {
  161. testRequires(c, DaemonIsLinux, RegistryHosting, SameHostDaemon)
  162. s.reg = registry.NewV2(c, registry.Htpasswd)
  163. s.reg.WaitReady(c)
  164. s.d = daemon.New(c, dockerBinary, dockerdBinary, testdaemon.WithEnvironment(testEnv.Execution))
  165. }
  166. func (s *DockerRegistryAuthHtpasswdSuite) TearDownTest(c *check.C) {
  167. if s.reg != nil {
  168. out, err := s.d.Cmd("logout", privateRegistryURL)
  169. c.Assert(err, check.IsNil, check.Commentf(out))
  170. s.reg.Close()
  171. }
  172. if s.d != nil {
  173. s.d.Stop(c)
  174. }
  175. s.ds.TearDownTest(c)
  176. }
  177. func init() {
  178. check.Suite(&DockerRegistryAuthTokenSuite{
  179. ds: &DockerSuite{},
  180. })
  181. }
  182. type DockerRegistryAuthTokenSuite struct {
  183. ds *DockerSuite
  184. reg *registry.V2
  185. d *daemon.Daemon
  186. }
  187. func (s *DockerRegistryAuthTokenSuite) OnTimeout(c *check.C) {
  188. s.d.DumpStackAndQuit()
  189. }
  190. func (s *DockerRegistryAuthTokenSuite) SetUpTest(c *check.C) {
  191. testRequires(c, DaemonIsLinux, RegistryHosting, SameHostDaemon)
  192. s.d = daemon.New(c, dockerBinary, dockerdBinary, testdaemon.WithEnvironment(testEnv.Execution))
  193. }
  194. func (s *DockerRegistryAuthTokenSuite) TearDownTest(c *check.C) {
  195. if s.reg != nil {
  196. out, err := s.d.Cmd("logout", privateRegistryURL)
  197. c.Assert(err, check.IsNil, check.Commentf(out))
  198. s.reg.Close()
  199. }
  200. if s.d != nil {
  201. s.d.Stop(c)
  202. }
  203. s.ds.TearDownTest(c)
  204. }
  205. func (s *DockerRegistryAuthTokenSuite) setupRegistryWithTokenService(c *check.C, tokenURL string) {
  206. if s == nil {
  207. c.Fatal("registry suite isn't initialized")
  208. }
  209. s.reg = registry.NewV2(c, registry.Token(tokenURL))
  210. s.reg.WaitReady(c)
  211. }
  212. func init() {
  213. check.Suite(&DockerDaemonSuite{
  214. ds: &DockerSuite{},
  215. })
  216. }
  217. type DockerDaemonSuite struct {
  218. ds *DockerSuite
  219. d *daemon.Daemon
  220. }
  221. func (s *DockerDaemonSuite) OnTimeout(c *check.C) {
  222. s.d.DumpStackAndQuit()
  223. }
  224. func (s *DockerDaemonSuite) SetUpTest(c *check.C) {
  225. testRequires(c, DaemonIsLinux, SameHostDaemon)
  226. s.d = daemon.New(c, dockerBinary, dockerdBinary, testdaemon.WithEnvironment(testEnv.Execution))
  227. }
  228. func (s *DockerDaemonSuite) TearDownTest(c *check.C) {
  229. testRequires(c, DaemonIsLinux, SameHostDaemon)
  230. if s.d != nil {
  231. s.d.Stop(c)
  232. }
  233. s.ds.TearDownTest(c)
  234. }
  235. func (s *DockerDaemonSuite) TearDownSuite(c *check.C) {
  236. filepath.Walk(testdaemon.SockRoot, func(path string, fi os.FileInfo, err error) error {
  237. if err != nil {
  238. // ignore errors here
  239. // not cleaning up sockets is not really an error
  240. return nil
  241. }
  242. if fi.Mode() == os.ModeSocket {
  243. syscall.Unlink(path)
  244. }
  245. return nil
  246. })
  247. os.RemoveAll(testdaemon.SockRoot)
  248. }
  249. const defaultSwarmPort = 2477
  250. func init() {
  251. check.Suite(&DockerSwarmSuite{
  252. ds: &DockerSuite{},
  253. })
  254. }
  255. type DockerSwarmSuite struct {
  256. server *httptest.Server
  257. ds *DockerSuite
  258. daemons []*daemon.Daemon
  259. daemonsLock sync.Mutex // protect access to daemons
  260. portIndex int
  261. }
  262. func (s *DockerSwarmSuite) OnTimeout(c *check.C) {
  263. s.daemonsLock.Lock()
  264. defer s.daemonsLock.Unlock()
  265. for _, d := range s.daemons {
  266. d.DumpStackAndQuit()
  267. }
  268. }
  269. func (s *DockerSwarmSuite) SetUpTest(c *check.C) {
  270. testRequires(c, DaemonIsLinux, SameHostDaemon)
  271. }
  272. func (s *DockerSwarmSuite) AddDaemon(c *check.C, joinSwarm, manager bool) *daemon.Daemon {
  273. d := daemon.New(c, dockerBinary, dockerdBinary,
  274. testdaemon.WithEnvironment(testEnv.Execution),
  275. testdaemon.WithSwarmPort(defaultSwarmPort+s.portIndex),
  276. )
  277. if joinSwarm {
  278. if len(s.daemons) > 0 {
  279. d.StartAndSwarmJoin(c, s.daemons[0].Daemon, manager)
  280. } else {
  281. d.StartAndSwarmInit(c)
  282. }
  283. } else {
  284. d.StartWithBusybox(c, "--iptables=false", "--swarm-default-advertise-addr=lo")
  285. }
  286. s.portIndex++
  287. s.daemonsLock.Lock()
  288. s.daemons = append(s.daemons, d)
  289. s.daemonsLock.Unlock()
  290. return d
  291. }
  292. func (s *DockerSwarmSuite) TearDownTest(c *check.C) {
  293. testRequires(c, DaemonIsLinux)
  294. s.daemonsLock.Lock()
  295. for _, d := range s.daemons {
  296. if d != nil {
  297. d.Stop(c)
  298. // FIXME(vdemeester) should be handled by SwarmDaemon ?
  299. // raft state file is quite big (64MB) so remove it after every test
  300. walDir := filepath.Join(d.Root, "swarm/raft/wal")
  301. if err := os.RemoveAll(walDir); err != nil {
  302. c.Logf("error removing %v: %v", walDir, err)
  303. }
  304. d.CleanupExecRoot(c)
  305. }
  306. }
  307. s.daemons = nil
  308. s.daemonsLock.Unlock()
  309. s.portIndex = 0
  310. s.ds.TearDownTest(c)
  311. }
  312. func init() {
  313. check.Suite(&DockerPluginSuite{
  314. ds: &DockerSuite{},
  315. })
  316. }
  317. type DockerPluginSuite struct {
  318. ds *DockerSuite
  319. registry *registry.V2
  320. }
  321. func (ps *DockerPluginSuite) registryHost() string {
  322. return privateRegistryURL
  323. }
  324. func (ps *DockerPluginSuite) getPluginRepo() string {
  325. return path.Join(ps.registryHost(), "plugin", "basic")
  326. }
  327. func (ps *DockerPluginSuite) getPluginRepoWithTag() string {
  328. return ps.getPluginRepo() + ":" + "latest"
  329. }
  330. func (ps *DockerPluginSuite) SetUpSuite(c *check.C) {
  331. testRequires(c, DaemonIsLinux, RegistryHosting)
  332. ps.registry = registry.NewV2(c)
  333. ps.registry.WaitReady(c)
  334. ctx, cancel := context.WithTimeout(context.Background(), 60*time.Second)
  335. defer cancel()
  336. err := plugin.CreateInRegistry(ctx, ps.getPluginRepo(), nil)
  337. c.Assert(err, checker.IsNil, check.Commentf("failed to create plugin"))
  338. }
  339. func (ps *DockerPluginSuite) TearDownSuite(c *check.C) {
  340. if ps.registry != nil {
  341. ps.registry.Close()
  342. }
  343. }
  344. func (ps *DockerPluginSuite) TearDownTest(c *check.C) {
  345. ps.ds.TearDownTest(c)
  346. }
  347. func (ps *DockerPluginSuite) OnTimeout(c *check.C) {
  348. ps.ds.OnTimeout(c)
  349. }