server_test.go 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687
  1. package docker
  2. import (
  3. "github.com/dotcloud/docker"
  4. "github.com/dotcloud/docker/engine"
  5. "strings"
  6. "testing"
  7. "time"
  8. )
  9. func TestImageTagImageDelete(t *testing.T) {
  10. eng := NewTestEngine(t)
  11. defer mkRuntimeFromEngine(eng, t).Nuke()
  12. srv := mkServerFromEngine(eng, t)
  13. initialImages := getAllImages(eng, t)
  14. if err := eng.Job("tag", unitTestImageName, "utest", "tag1").Run(); err != nil {
  15. t.Fatal(err)
  16. }
  17. if err := eng.Job("tag", unitTestImageName, "utest/docker", "tag2").Run(); err != nil {
  18. t.Fatal(err)
  19. }
  20. if err := eng.Job("tag", unitTestImageName, "utest:5000/docker", "tag3").Run(); err != nil {
  21. t.Fatal(err)
  22. }
  23. images := getAllImages(eng, t)
  24. nExpected := len(initialImages.Data[0].GetList("RepoTags")) + 3
  25. nActual := len(images.Data[0].GetList("RepoTags"))
  26. if nExpected != nActual {
  27. t.Errorf("Expected %d images, %d found", nExpected, nActual)
  28. }
  29. if _, err := srv.DeleteImage("utest/docker:tag2", true); err != nil {
  30. t.Fatal(err)
  31. }
  32. images = getAllImages(eng, t)
  33. nExpected = len(initialImages.Data[0].GetList("RepoTags")) + 2
  34. nActual = len(images.Data[0].GetList("RepoTags"))
  35. if nExpected != nActual {
  36. t.Errorf("Expected %d images, %d found", nExpected, nActual)
  37. }
  38. if _, err := srv.DeleteImage("utest:5000/docker:tag3", true); err != nil {
  39. t.Fatal(err)
  40. }
  41. images = getAllImages(eng, t)
  42. nExpected = len(initialImages.Data[0].GetList("RepoTags")) + 1
  43. nActual = len(images.Data[0].GetList("RepoTags"))
  44. if _, err := srv.DeleteImage("utest:tag1", true); err != nil {
  45. t.Fatal(err)
  46. }
  47. images = getAllImages(eng, t)
  48. if images.Len() != initialImages.Len() {
  49. t.Errorf("Expected %d image, %d found", initialImages.Len(), images.Len())
  50. }
  51. }
  52. func TestCreateRm(t *testing.T) {
  53. eng := NewTestEngine(t)
  54. defer mkRuntimeFromEngine(eng, t).Nuke()
  55. config, _, _, err := docker.ParseRun([]string{unitTestImageID, "echo test"}, nil)
  56. if err != nil {
  57. t.Fatal(err)
  58. }
  59. id := createTestContainer(eng, config, t)
  60. job := eng.Job("containers")
  61. job.SetenvBool("all", true)
  62. outs, err := job.Stdout.AddListTable()
  63. if err != nil {
  64. t.Fatal(err)
  65. }
  66. if err := job.Run(); err != nil {
  67. t.Fatal(err)
  68. }
  69. if len(outs.Data) != 1 {
  70. t.Errorf("Expected 1 container, %v found", len(outs.Data))
  71. }
  72. job = eng.Job("container_delete", id)
  73. job.SetenvBool("removeVolume", true)
  74. if err := job.Run(); err != nil {
  75. t.Fatal(err)
  76. }
  77. job = eng.Job("containers")
  78. job.SetenvBool("all", true)
  79. outs, err = job.Stdout.AddListTable()
  80. if err != nil {
  81. t.Fatal(err)
  82. }
  83. if err := job.Run(); err != nil {
  84. t.Fatal(err)
  85. }
  86. if len(outs.Data) != 0 {
  87. t.Errorf("Expected 0 container, %v found", len(outs.Data))
  88. }
  89. }
  90. func TestCreateRmVolumes(t *testing.T) {
  91. eng := NewTestEngine(t)
  92. defer mkRuntimeFromEngine(eng, t).Nuke()
  93. config, hostConfig, _, err := docker.ParseRun([]string{"-v", "/srv", unitTestImageID, "echo", "test"}, nil)
  94. if err != nil {
  95. t.Fatal(err)
  96. }
  97. id := createTestContainer(eng, config, t)
  98. job := eng.Job("containers")
  99. job.SetenvBool("all", true)
  100. outs, err := job.Stdout.AddListTable()
  101. if err != nil {
  102. t.Fatal(err)
  103. }
  104. if err := job.Run(); err != nil {
  105. t.Fatal(err)
  106. }
  107. if len(outs.Data) != 1 {
  108. t.Errorf("Expected 1 container, %v found", len(outs.Data))
  109. }
  110. job = eng.Job("start", id)
  111. if err := job.ImportEnv(hostConfig); err != nil {
  112. t.Fatal(err)
  113. }
  114. if err := job.Run(); err != nil {
  115. t.Fatal(err)
  116. }
  117. job = eng.Job("stop", id)
  118. job.SetenvInt("t", 1)
  119. if err := job.Run(); err != nil {
  120. t.Fatal(err)
  121. }
  122. job = eng.Job("container_delete", id)
  123. job.SetenvBool("removeVolume", true)
  124. if err := job.Run(); err != nil {
  125. t.Fatal(err)
  126. }
  127. job = eng.Job("containers")
  128. job.SetenvBool("all", true)
  129. outs, err = job.Stdout.AddListTable()
  130. if err != nil {
  131. t.Fatal(err)
  132. }
  133. if err := job.Run(); err != nil {
  134. t.Fatal(err)
  135. }
  136. if len(outs.Data) != 0 {
  137. t.Errorf("Expected 0 container, %v found", len(outs.Data))
  138. }
  139. }
  140. func TestCommit(t *testing.T) {
  141. eng := NewTestEngine(t)
  142. defer mkRuntimeFromEngine(eng, t).Nuke()
  143. config, _, _, err := docker.ParseRun([]string{unitTestImageID, "/bin/cat"}, nil)
  144. if err != nil {
  145. t.Fatal(err)
  146. }
  147. id := createTestContainer(eng, config, t)
  148. job := eng.Job("commit", id)
  149. job.Setenv("repo", "testrepo")
  150. job.Setenv("tag", "testtag")
  151. job.SetenvJson("config", config)
  152. if err := job.Run(); err != nil {
  153. t.Fatal(err)
  154. }
  155. }
  156. func TestRestartKillWait(t *testing.T) {
  157. eng := NewTestEngine(t)
  158. srv := mkServerFromEngine(eng, t)
  159. runtime := mkRuntimeFromEngine(eng, t)
  160. defer runtime.Nuke()
  161. config, hostConfig, _, err := docker.ParseRun([]string{"-i", unitTestImageID, "/bin/cat"}, nil)
  162. if err != nil {
  163. t.Fatal(err)
  164. }
  165. id := createTestContainer(eng, config, t)
  166. job := eng.Job("containers")
  167. job.SetenvBool("all", true)
  168. outs, err := job.Stdout.AddListTable()
  169. if err != nil {
  170. t.Fatal(err)
  171. }
  172. if err := job.Run(); err != nil {
  173. t.Fatal(err)
  174. }
  175. if len(outs.Data) != 1 {
  176. t.Errorf("Expected 1 container, %v found", len(outs.Data))
  177. }
  178. job = eng.Job("start", id)
  179. if err := job.ImportEnv(hostConfig); err != nil {
  180. t.Fatal(err)
  181. }
  182. if err := job.Run(); err != nil {
  183. t.Fatal(err)
  184. }
  185. job = eng.Job("kill", id)
  186. if err := job.Run(); err != nil {
  187. t.Fatal(err)
  188. }
  189. eng, err = engine.New(eng.Root())
  190. if err != nil {
  191. t.Fatal(err)
  192. }
  193. job = eng.Job("initapi")
  194. job.Setenv("Root", eng.Root())
  195. job.SetenvBool("AutoRestart", false)
  196. // TestGetEnabledCors and TestOptionsRoute require EnableCors=true
  197. job.SetenvBool("EnableCors", true)
  198. if err := job.Run(); err != nil {
  199. t.Fatal(err)
  200. }
  201. srv = mkServerFromEngine(eng, t)
  202. job = srv.Eng.Job("containers")
  203. job.SetenvBool("all", true)
  204. outs, err = job.Stdout.AddListTable()
  205. if err != nil {
  206. t.Fatal(err)
  207. }
  208. if err := job.Run(); err != nil {
  209. t.Fatal(err)
  210. }
  211. if len(outs.Data) != 1 {
  212. t.Errorf("Expected 1 container, %v found", len(outs.Data))
  213. }
  214. setTimeout(t, "Waiting on stopped container timedout", 5*time.Second, func() {
  215. job = srv.Eng.Job("wait", outs.Data[0].Get("Id"))
  216. var statusStr string
  217. job.Stdout.AddString(&statusStr)
  218. if err := job.Run(); err != nil {
  219. t.Fatal(err)
  220. }
  221. })
  222. }
  223. func TestCreateStartRestartStopStartKillRm(t *testing.T) {
  224. eng := NewTestEngine(t)
  225. srv := mkServerFromEngine(eng, t)
  226. defer mkRuntimeFromEngine(eng, t).Nuke()
  227. config, hostConfig, _, err := docker.ParseRun([]string{"-i", unitTestImageID, "/bin/cat"}, nil)
  228. if err != nil {
  229. t.Fatal(err)
  230. }
  231. id := createTestContainer(eng, config, t)
  232. job := srv.Eng.Job("containers")
  233. job.SetenvBool("all", true)
  234. outs, err := job.Stdout.AddListTable()
  235. if err != nil {
  236. t.Fatal(err)
  237. }
  238. if err := job.Run(); err != nil {
  239. t.Fatal(err)
  240. }
  241. if len(outs.Data) != 1 {
  242. t.Errorf("Expected 1 container, %v found", len(outs.Data))
  243. }
  244. job = eng.Job("start", id)
  245. if err := job.ImportEnv(hostConfig); err != nil {
  246. t.Fatal(err)
  247. }
  248. if err := job.Run(); err != nil {
  249. t.Fatal(err)
  250. }
  251. job = eng.Job("restart", id)
  252. job.SetenvInt("t", 15)
  253. if err := job.Run(); err != nil {
  254. t.Fatal(err)
  255. }
  256. job = eng.Job("stop", id)
  257. job.SetenvInt("t", 15)
  258. if err := job.Run(); err != nil {
  259. t.Fatal(err)
  260. }
  261. job = eng.Job("start", id)
  262. if err := job.ImportEnv(hostConfig); err != nil {
  263. t.Fatal(err)
  264. }
  265. if err := job.Run(); err != nil {
  266. t.Fatal(err)
  267. }
  268. if err := eng.Job("kill", id).Run(); err != nil {
  269. t.Fatal(err)
  270. }
  271. // FIXME: this failed once with a race condition ("Unable to remove filesystem for xxx: directory not empty")
  272. job = eng.Job("container_delete", id)
  273. job.SetenvBool("removeVolume", true)
  274. if err := job.Run(); err != nil {
  275. t.Fatal(err)
  276. }
  277. job = srv.Eng.Job("containers")
  278. job.SetenvBool("all", true)
  279. outs, err = job.Stdout.AddListTable()
  280. if err != nil {
  281. t.Fatal(err)
  282. }
  283. if err := job.Run(); err != nil {
  284. t.Fatal(err)
  285. }
  286. if len(outs.Data) != 0 {
  287. t.Errorf("Expected 0 container, %v found", len(outs.Data))
  288. }
  289. }
  290. func TestRunWithTooLowMemoryLimit(t *testing.T) {
  291. eng := NewTestEngine(t)
  292. defer mkRuntimeFromEngine(eng, t).Nuke()
  293. // Try to create a container with a memory limit of 1 byte less than the minimum allowed limit.
  294. job := eng.Job("create")
  295. job.Setenv("Image", unitTestImageID)
  296. job.Setenv("Memory", "524287")
  297. job.Setenv("CpuShares", "1000")
  298. job.SetenvList("Cmd", []string{"/bin/cat"})
  299. var id string
  300. job.Stdout.AddString(&id)
  301. if err := job.Run(); err == nil {
  302. t.Errorf("Memory limit is smaller than the allowed limit. Container creation should've failed!")
  303. }
  304. }
  305. func TestRmi(t *testing.T) {
  306. eng := NewTestEngine(t)
  307. srv := mkServerFromEngine(eng, t)
  308. defer mkRuntimeFromEngine(eng, t).Nuke()
  309. initialImages := getAllImages(eng, t)
  310. config, hostConfig, _, err := docker.ParseRun([]string{unitTestImageID, "echo", "test"}, nil)
  311. if err != nil {
  312. t.Fatal(err)
  313. }
  314. containerID := createTestContainer(eng, config, t)
  315. //To remove
  316. job := eng.Job("start", containerID)
  317. if err := job.ImportEnv(hostConfig); err != nil {
  318. t.Fatal(err)
  319. }
  320. if err := job.Run(); err != nil {
  321. t.Fatal(err)
  322. }
  323. if err := eng.Job("wait", containerID).Run(); err != nil {
  324. t.Fatal(err)
  325. }
  326. job = eng.Job("commit", containerID)
  327. job.Setenv("repo", "test")
  328. var imageID string
  329. job.Stdout.AddString(&imageID)
  330. if err := job.Run(); err != nil {
  331. t.Fatal(err)
  332. }
  333. if err := eng.Job("tag", imageID, "test", "0.1").Run(); err != nil {
  334. t.Fatal(err)
  335. }
  336. containerID = createTestContainer(eng, config, t)
  337. //To remove
  338. job = eng.Job("start", containerID)
  339. if err := job.ImportEnv(hostConfig); err != nil {
  340. t.Fatal(err)
  341. }
  342. if err := job.Run(); err != nil {
  343. t.Fatal(err)
  344. }
  345. if err := eng.Job("wait", containerID).Run(); err != nil {
  346. t.Fatal(err)
  347. }
  348. job = eng.Job("commit", containerID)
  349. job.Setenv("repo", "test")
  350. if err := job.Run(); err != nil {
  351. t.Fatal(err)
  352. }
  353. images := getAllImages(eng, t)
  354. if images.Len()-initialImages.Len() != 2 {
  355. t.Fatalf("Expected 2 new images, found %d.", images.Len()-initialImages.Len())
  356. }
  357. _, err = srv.DeleteImage(imageID, true)
  358. if err != nil {
  359. t.Fatal(err)
  360. }
  361. images = getAllImages(eng, t)
  362. if images.Len()-initialImages.Len() != 1 {
  363. t.Fatalf("Expected 1 new image, found %d.", images.Len()-initialImages.Len())
  364. }
  365. for _, image := range images.Data {
  366. if strings.Contains(unitTestImageID, image.Get("Id")) {
  367. continue
  368. }
  369. if image.GetList("RepoTags")[0] == "<none>:<none>" {
  370. t.Fatalf("Expected tagged image, got untagged one.")
  371. }
  372. }
  373. }
  374. func TestImagesFilter(t *testing.T) {
  375. eng := NewTestEngine(t)
  376. defer nuke(mkRuntimeFromEngine(eng, t))
  377. if err := eng.Job("tag", unitTestImageName, "utest", "tag1").Run(); err != nil {
  378. t.Fatal(err)
  379. }
  380. if err := eng.Job("tag", unitTestImageName, "utest/docker", "tag2").Run(); err != nil {
  381. t.Fatal(err)
  382. }
  383. if err := eng.Job("tag", unitTestImageName, "utest:5000/docker", "tag3").Run(); err != nil {
  384. t.Fatal(err)
  385. }
  386. images := getImages(eng, t, false, "utest*/*")
  387. if len(images.Data[0].GetList("RepoTags")) != 2 {
  388. t.Fatal("incorrect number of matches returned")
  389. }
  390. images = getImages(eng, t, false, "utest")
  391. if len(images.Data[0].GetList("RepoTags")) != 1 {
  392. t.Fatal("incorrect number of matches returned")
  393. }
  394. images = getImages(eng, t, false, "utest*")
  395. if len(images.Data[0].GetList("RepoTags")) != 1 {
  396. t.Fatal("incorrect number of matches returned")
  397. }
  398. images = getImages(eng, t, false, "*5000*/*")
  399. if len(images.Data[0].GetList("RepoTags")) != 1 {
  400. t.Fatal("incorrect number of matches returned")
  401. }
  402. }
  403. func TestImageInsert(t *testing.T) {
  404. eng := NewTestEngine(t)
  405. defer mkRuntimeFromEngine(eng, t).Nuke()
  406. srv := mkServerFromEngine(eng, t)
  407. // bad image name fails
  408. if err := srv.Eng.Job("insert", "foo", "https://www.docker.io/static/img/docker-top-logo.png", "/foo").Run(); err == nil {
  409. t.Fatal("expected an error and got none")
  410. }
  411. // bad url fails
  412. if err := srv.Eng.Job("insert", unitTestImageID, "http://bad_host_name_that_will_totally_fail.com/", "/foo").Run(); err == nil {
  413. t.Fatal("expected an error and got none")
  414. }
  415. // success returns nil
  416. if err := srv.Eng.Job("insert", unitTestImageID, "https://www.docker.io/static/img/docker-top-logo.png", "/foo").Run(); err != nil {
  417. t.Fatalf("expected no error, but got %v", err)
  418. }
  419. }
  420. func TestListContainers(t *testing.T) {
  421. eng := NewTestEngine(t)
  422. srv := mkServerFromEngine(eng, t)
  423. defer mkRuntimeFromEngine(eng, t).Nuke()
  424. config := docker.Config{
  425. Image: unitTestImageID,
  426. Cmd: []string{"/bin/sh", "-c", "cat"},
  427. OpenStdin: true,
  428. }
  429. firstID := createTestContainer(eng, &config, t)
  430. secondID := createTestContainer(eng, &config, t)
  431. thirdID := createTestContainer(eng, &config, t)
  432. fourthID := createTestContainer(eng, &config, t)
  433. defer func() {
  434. containerKill(eng, firstID, t)
  435. containerKill(eng, secondID, t)
  436. containerKill(eng, fourthID, t)
  437. containerWait(eng, firstID, t)
  438. containerWait(eng, secondID, t)
  439. containerWait(eng, fourthID, t)
  440. }()
  441. startContainer(eng, firstID, t)
  442. startContainer(eng, secondID, t)
  443. startContainer(eng, fourthID, t)
  444. // all
  445. if !assertContainerList(srv, true, -1, "", "", []string{fourthID, thirdID, secondID, firstID}) {
  446. t.Error("Container list is not in the correct order")
  447. }
  448. // running
  449. if !assertContainerList(srv, false, -1, "", "", []string{fourthID, secondID, firstID}) {
  450. t.Error("Container list is not in the correct order")
  451. }
  452. // from here 'all' flag is ignored
  453. // limit
  454. expected := []string{fourthID, thirdID}
  455. if !assertContainerList(srv, true, 2, "", "", expected) ||
  456. !assertContainerList(srv, false, 2, "", "", expected) {
  457. t.Error("Container list is not in the correct order")
  458. }
  459. // since
  460. expected = []string{fourthID, thirdID, secondID}
  461. if !assertContainerList(srv, true, -1, firstID, "", expected) ||
  462. !assertContainerList(srv, false, -1, firstID, "", expected) {
  463. t.Error("Container list is not in the correct order")
  464. }
  465. // before
  466. expected = []string{secondID, firstID}
  467. if !assertContainerList(srv, true, -1, "", thirdID, expected) ||
  468. !assertContainerList(srv, false, -1, "", thirdID, expected) {
  469. t.Error("Container list is not in the correct order")
  470. }
  471. // since & before
  472. expected = []string{thirdID, secondID}
  473. if !assertContainerList(srv, true, -1, firstID, fourthID, expected) ||
  474. !assertContainerList(srv, false, -1, firstID, fourthID, expected) {
  475. t.Error("Container list is not in the correct order")
  476. }
  477. // since & limit
  478. expected = []string{fourthID, thirdID}
  479. if !assertContainerList(srv, true, 2, firstID, "", expected) ||
  480. !assertContainerList(srv, false, 2, firstID, "", expected) {
  481. t.Error("Container list is not in the correct order")
  482. }
  483. // before & limit
  484. expected = []string{thirdID}
  485. if !assertContainerList(srv, true, 1, "", fourthID, expected) ||
  486. !assertContainerList(srv, false, 1, "", fourthID, expected) {
  487. t.Error("Container list is not in the correct order")
  488. }
  489. // since & before & limit
  490. expected = []string{thirdID}
  491. if !assertContainerList(srv, true, 1, firstID, fourthID, expected) ||
  492. !assertContainerList(srv, false, 1, firstID, fourthID, expected) {
  493. t.Error("Container list is not in the correct order")
  494. }
  495. }
  496. func assertContainerList(srv *docker.Server, all bool, limit int, since, before string, expected []string) bool {
  497. job := srv.Eng.Job("containers")
  498. job.SetenvBool("all", all)
  499. job.SetenvInt("limit", limit)
  500. job.Setenv("since", since)
  501. job.Setenv("before", before)
  502. outs, err := job.Stdout.AddListTable()
  503. if err != nil {
  504. return false
  505. }
  506. if err := job.Run(); err != nil {
  507. return false
  508. }
  509. if len(outs.Data) != len(expected) {
  510. return false
  511. }
  512. for i := 0; i < len(outs.Data); i++ {
  513. if outs.Data[i].Get("Id") != expected[i] {
  514. return false
  515. }
  516. }
  517. return true
  518. }
  519. // Regression test for being able to untag an image with an existing
  520. // container
  521. func TestDeleteTagWithExistingContainers(t *testing.T) {
  522. eng := NewTestEngine(t)
  523. defer nuke(mkRuntimeFromEngine(eng, t))
  524. srv := mkServerFromEngine(eng, t)
  525. // Tag the image
  526. if err := eng.Job("tag", unitTestImageID, "utest", "tag1").Run(); err != nil {
  527. t.Fatal(err)
  528. }
  529. // Create a container from the image
  530. config, _, _, err := docker.ParseRun([]string{unitTestImageID, "echo test"}, nil)
  531. if err != nil {
  532. t.Fatal(err)
  533. }
  534. id := createNamedTestContainer(eng, config, t, "testingtags")
  535. if id == "" {
  536. t.Fatal("No id returned")
  537. }
  538. job := srv.Eng.Job("containers")
  539. job.SetenvBool("all", true)
  540. outs, err := job.Stdout.AddListTable()
  541. if err != nil {
  542. t.Fatal(err)
  543. }
  544. if err := job.Run(); err != nil {
  545. t.Fatal(err)
  546. }
  547. if len(outs.Data) != 1 {
  548. t.Fatalf("Expected 1 container got %d", len(outs.Data))
  549. }
  550. // Try to remove the tag
  551. imgs, err := srv.DeleteImage("utest:tag1", true)
  552. if err != nil {
  553. t.Fatal(err)
  554. }
  555. if len(imgs.Data) != 1 {
  556. t.Fatalf("Should only have deleted one untag %d", len(imgs.Data))
  557. }
  558. if untag := imgs.Data[0].Get("Untagged"); untag != unitTestImageID {
  559. t.Fatalf("Expected %s got %s", unitTestImageID, untag)
  560. }
  561. }