server_test.go 19 KB

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