check_test.go 9.8 KB

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