server_test.go 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467
  1. package docker
  2. import (
  3. "bytes"
  4. "testing"
  5. "time"
  6. "github.com/dotcloud/docker/engine"
  7. "github.com/dotcloud/docker/runconfig"
  8. "github.com/dotcloud/docker/server"
  9. )
  10. func TestCreateNumberHostname(t *testing.T) {
  11. eng := NewTestEngine(t)
  12. defer mkDaemonFromEngine(eng, t).Nuke()
  13. config, _, _, err := runconfig.Parse([]string{"-h", "web.0", unitTestImageID, "echo test"}, nil)
  14. if err != nil {
  15. t.Fatal(err)
  16. }
  17. createTestContainer(eng, config, t)
  18. }
  19. func TestCommit(t *testing.T) {
  20. eng := NewTestEngine(t)
  21. defer mkDaemonFromEngine(eng, t).Nuke()
  22. config, _, _, err := runconfig.Parse([]string{unitTestImageID, "/bin/cat"}, nil)
  23. if err != nil {
  24. t.Fatal(err)
  25. }
  26. id := createTestContainer(eng, config, t)
  27. job := eng.Job("commit", id)
  28. job.Setenv("repo", "testrepo")
  29. job.Setenv("tag", "testtag")
  30. job.SetenvJson("config", config)
  31. if err := job.Run(); err != nil {
  32. t.Fatal(err)
  33. }
  34. }
  35. func TestMergeConfigOnCommit(t *testing.T) {
  36. eng := NewTestEngine(t)
  37. runtime := mkDaemonFromEngine(eng, t)
  38. defer runtime.Nuke()
  39. container1, _, _ := mkContainer(runtime, []string{"-e", "FOO=bar", unitTestImageID, "echo test > /tmp/foo"}, t)
  40. defer runtime.Destroy(container1)
  41. config, _, _, err := runconfig.Parse([]string{container1.ID, "cat /tmp/foo"}, nil)
  42. if err != nil {
  43. t.Error(err)
  44. }
  45. job := eng.Job("commit", container1.ID)
  46. job.Setenv("repo", "testrepo")
  47. job.Setenv("tag", "testtag")
  48. job.SetenvJson("config", config)
  49. var outputBuffer = bytes.NewBuffer(nil)
  50. job.Stdout.Add(outputBuffer)
  51. if err := job.Run(); err != nil {
  52. t.Error(err)
  53. }
  54. container2, _, _ := mkContainer(runtime, []string{engine.Tail(outputBuffer, 1)}, t)
  55. defer runtime.Destroy(container2)
  56. job = eng.Job("container_inspect", container1.Name)
  57. baseContainer, _ := job.Stdout.AddEnv()
  58. if err := job.Run(); err != nil {
  59. t.Error(err)
  60. }
  61. job = eng.Job("container_inspect", container2.Name)
  62. commitContainer, _ := job.Stdout.AddEnv()
  63. if err := job.Run(); err != nil {
  64. t.Error(err)
  65. }
  66. baseConfig := baseContainer.GetSubEnv("Config")
  67. commitConfig := commitContainer.GetSubEnv("Config")
  68. if commitConfig.Get("Env") != baseConfig.Get("Env") {
  69. t.Fatalf("Env config in committed container should be %v, was %v",
  70. baseConfig.Get("Env"), commitConfig.Get("Env"))
  71. }
  72. if baseConfig.Get("Cmd") != "[\"echo test \\u003e /tmp/foo\"]" {
  73. t.Fatalf("Cmd in base container should be [\"echo test \\u003e /tmp/foo\"], was %s",
  74. baseConfig.Get("Cmd"))
  75. }
  76. if commitConfig.Get("Cmd") != "[\"cat /tmp/foo\"]" {
  77. t.Fatalf("Cmd in committed container should be [\"cat /tmp/foo\"], was %s",
  78. commitConfig.Get("Cmd"))
  79. }
  80. }
  81. func TestRestartKillWait(t *testing.T) {
  82. eng := NewTestEngine(t)
  83. srv := mkServerFromEngine(eng, t)
  84. runtime := mkDaemonFromEngine(eng, t)
  85. defer runtime.Nuke()
  86. config, hostConfig, _, err := runconfig.Parse([]string{"-i", unitTestImageID, "/bin/cat"}, nil)
  87. if err != nil {
  88. t.Fatal(err)
  89. }
  90. id := createTestContainer(eng, config, t)
  91. job := eng.Job("containers")
  92. job.SetenvBool("all", true)
  93. outs, err := job.Stdout.AddListTable()
  94. if err != nil {
  95. t.Fatal(err)
  96. }
  97. if err := job.Run(); err != nil {
  98. t.Fatal(err)
  99. }
  100. if len(outs.Data) != 1 {
  101. t.Errorf("Expected 1 container, %v found", len(outs.Data))
  102. }
  103. job = eng.Job("start", id)
  104. if err := job.ImportEnv(hostConfig); err != nil {
  105. t.Fatal(err)
  106. }
  107. if err := job.Run(); err != nil {
  108. t.Fatal(err)
  109. }
  110. job = eng.Job("kill", id)
  111. if err := job.Run(); err != nil {
  112. t.Fatal(err)
  113. }
  114. eng = newTestEngine(t, false, runtime.Config().Root)
  115. srv = mkServerFromEngine(eng, t)
  116. job = srv.Eng.Job("containers")
  117. job.SetenvBool("all", true)
  118. outs, err = job.Stdout.AddListTable()
  119. if err != nil {
  120. t.Fatal(err)
  121. }
  122. if err := job.Run(); err != nil {
  123. t.Fatal(err)
  124. }
  125. if len(outs.Data) != 1 {
  126. t.Errorf("Expected 1 container, %v found", len(outs.Data))
  127. }
  128. setTimeout(t, "Waiting on stopped container timedout", 5*time.Second, func() {
  129. job = srv.Eng.Job("wait", outs.Data[0].Get("Id"))
  130. if err := job.Run(); err != nil {
  131. t.Fatal(err)
  132. }
  133. })
  134. }
  135. func TestCreateStartRestartStopStartKillRm(t *testing.T) {
  136. eng := NewTestEngine(t)
  137. srv := mkServerFromEngine(eng, t)
  138. defer mkDaemonFromEngine(eng, t).Nuke()
  139. config, hostConfig, _, err := runconfig.Parse([]string{"-i", unitTestImageID, "/bin/cat"}, nil)
  140. if err != nil {
  141. t.Fatal(err)
  142. }
  143. id := createTestContainer(eng, config, t)
  144. job := srv.Eng.Job("containers")
  145. job.SetenvBool("all", true)
  146. outs, err := job.Stdout.AddListTable()
  147. if err != nil {
  148. t.Fatal(err)
  149. }
  150. if err := job.Run(); err != nil {
  151. t.Fatal(err)
  152. }
  153. if len(outs.Data) != 1 {
  154. t.Errorf("Expected 1 container, %v found", len(outs.Data))
  155. }
  156. job = eng.Job("start", id)
  157. if err := job.ImportEnv(hostConfig); err != nil {
  158. t.Fatal(err)
  159. }
  160. if err := job.Run(); err != nil {
  161. t.Fatal(err)
  162. }
  163. job = eng.Job("restart", id)
  164. job.SetenvInt("t", 15)
  165. if err := job.Run(); err != nil {
  166. t.Fatal(err)
  167. }
  168. job = eng.Job("stop", id)
  169. job.SetenvInt("t", 15)
  170. if err := job.Run(); err != nil {
  171. t.Fatal(err)
  172. }
  173. job = eng.Job("start", id)
  174. if err := job.ImportEnv(hostConfig); err != nil {
  175. t.Fatal(err)
  176. }
  177. if err := job.Run(); err != nil {
  178. t.Fatal(err)
  179. }
  180. if err := eng.Job("kill", id).Run(); err != nil {
  181. t.Fatal(err)
  182. }
  183. // FIXME: this failed once with a race condition ("Unable to remove filesystem for xxx: directory not empty")
  184. job = eng.Job("container_delete", id)
  185. job.SetenvBool("removeVolume", true)
  186. if err := job.Run(); err != nil {
  187. t.Fatal(err)
  188. }
  189. job = srv.Eng.Job("containers")
  190. job.SetenvBool("all", true)
  191. outs, err = job.Stdout.AddListTable()
  192. if err != nil {
  193. t.Fatal(err)
  194. }
  195. if err := job.Run(); err != nil {
  196. t.Fatal(err)
  197. }
  198. if len(outs.Data) != 0 {
  199. t.Errorf("Expected 0 container, %v found", len(outs.Data))
  200. }
  201. }
  202. func TestRunWithTooLowMemoryLimit(t *testing.T) {
  203. eng := NewTestEngine(t)
  204. defer mkDaemonFromEngine(eng, t).Nuke()
  205. // Try to create a container with a memory limit of 1 byte less than the minimum allowed limit.
  206. job := eng.Job("create")
  207. job.Setenv("Image", unitTestImageID)
  208. job.Setenv("Memory", "524287")
  209. job.Setenv("CpuShares", "1000")
  210. job.SetenvList("Cmd", []string{"/bin/cat"})
  211. if err := job.Run(); err == nil {
  212. t.Errorf("Memory limit is smaller than the allowed limit. Container creation should've failed!")
  213. }
  214. }
  215. func TestImagesFilter(t *testing.T) {
  216. eng := NewTestEngine(t)
  217. defer nuke(mkDaemonFromEngine(eng, t))
  218. if err := eng.Job("tag", unitTestImageName, "utest", "tag1").Run(); err != nil {
  219. t.Fatal(err)
  220. }
  221. if err := eng.Job("tag", unitTestImageName, "utest/docker", "tag2").Run(); err != nil {
  222. t.Fatal(err)
  223. }
  224. if err := eng.Job("tag", unitTestImageName, "utest:5000/docker", "tag3").Run(); err != nil {
  225. t.Fatal(err)
  226. }
  227. images := getImages(eng, t, false, "utest*/*")
  228. if len(images.Data[0].GetList("RepoTags")) != 2 {
  229. t.Fatal("incorrect number of matches returned")
  230. }
  231. images = getImages(eng, t, false, "utest")
  232. if len(images.Data[0].GetList("RepoTags")) != 1 {
  233. t.Fatal("incorrect number of matches returned")
  234. }
  235. images = getImages(eng, t, false, "utest*")
  236. if len(images.Data[0].GetList("RepoTags")) != 1 {
  237. t.Fatal("incorrect number of matches returned")
  238. }
  239. images = getImages(eng, t, false, "*5000*/*")
  240. if len(images.Data[0].GetList("RepoTags")) != 1 {
  241. t.Fatal("incorrect number of matches returned")
  242. }
  243. }
  244. func TestListContainers(t *testing.T) {
  245. eng := NewTestEngine(t)
  246. srv := mkServerFromEngine(eng, t)
  247. defer mkDaemonFromEngine(eng, t).Nuke()
  248. config := runconfig.Config{
  249. Image: unitTestImageID,
  250. Cmd: []string{"/bin/sh", "-c", "cat"},
  251. OpenStdin: true,
  252. }
  253. firstID := createTestContainer(eng, &config, t)
  254. secondID := createTestContainer(eng, &config, t)
  255. thirdID := createTestContainer(eng, &config, t)
  256. fourthID := createTestContainer(eng, &config, t)
  257. defer func() {
  258. containerKill(eng, firstID, t)
  259. containerKill(eng, secondID, t)
  260. containerKill(eng, fourthID, t)
  261. containerWait(eng, firstID, t)
  262. containerWait(eng, secondID, t)
  263. containerWait(eng, fourthID, t)
  264. }()
  265. startContainer(eng, firstID, t)
  266. startContainer(eng, secondID, t)
  267. startContainer(eng, fourthID, t)
  268. // all
  269. if !assertContainerList(srv, true, -1, "", "", []string{fourthID, thirdID, secondID, firstID}) {
  270. t.Error("Container list is not in the correct order")
  271. }
  272. // running
  273. if !assertContainerList(srv, false, -1, "", "", []string{fourthID, secondID, firstID}) {
  274. t.Error("Container list is not in the correct order")
  275. }
  276. // from here 'all' flag is ignored
  277. // limit
  278. expected := []string{fourthID, thirdID}
  279. if !assertContainerList(srv, true, 2, "", "", expected) ||
  280. !assertContainerList(srv, false, 2, "", "", expected) {
  281. t.Error("Container list is not in the correct order")
  282. }
  283. // since
  284. expected = []string{fourthID, thirdID, secondID}
  285. if !assertContainerList(srv, true, -1, firstID, "", expected) ||
  286. !assertContainerList(srv, false, -1, firstID, "", expected) {
  287. t.Error("Container list is not in the correct order")
  288. }
  289. // before
  290. expected = []string{secondID, firstID}
  291. if !assertContainerList(srv, true, -1, "", thirdID, expected) ||
  292. !assertContainerList(srv, false, -1, "", thirdID, expected) {
  293. t.Error("Container list is not in the correct order")
  294. }
  295. // since & before
  296. expected = []string{thirdID, secondID}
  297. if !assertContainerList(srv, true, -1, firstID, fourthID, expected) ||
  298. !assertContainerList(srv, false, -1, firstID, fourthID, expected) {
  299. t.Error("Container list is not in the correct order")
  300. }
  301. // since & limit
  302. expected = []string{fourthID, thirdID}
  303. if !assertContainerList(srv, true, 2, firstID, "", expected) ||
  304. !assertContainerList(srv, false, 2, firstID, "", expected) {
  305. t.Error("Container list is not in the correct order")
  306. }
  307. // before & limit
  308. expected = []string{thirdID}
  309. if !assertContainerList(srv, true, 1, "", fourthID, expected) ||
  310. !assertContainerList(srv, false, 1, "", fourthID, expected) {
  311. t.Error("Container list is not in the correct order")
  312. }
  313. // since & before & limit
  314. expected = []string{thirdID}
  315. if !assertContainerList(srv, true, 1, firstID, fourthID, expected) ||
  316. !assertContainerList(srv, false, 1, firstID, fourthID, expected) {
  317. t.Error("Container list is not in the correct order")
  318. }
  319. }
  320. func assertContainerList(srv *server.Server, all bool, limit int, since, before string, expected []string) bool {
  321. job := srv.Eng.Job("containers")
  322. job.SetenvBool("all", all)
  323. job.SetenvInt("limit", limit)
  324. job.Setenv("since", since)
  325. job.Setenv("before", before)
  326. outs, err := job.Stdout.AddListTable()
  327. if err != nil {
  328. return false
  329. }
  330. if err := job.Run(); err != nil {
  331. return false
  332. }
  333. if len(outs.Data) != len(expected) {
  334. return false
  335. }
  336. for i := 0; i < len(outs.Data); i++ {
  337. if outs.Data[i].Get("Id") != expected[i] {
  338. return false
  339. }
  340. }
  341. return true
  342. }
  343. // Regression test for being able to untag an image with an existing
  344. // container
  345. func TestDeleteTagWithExistingContainers(t *testing.T) {
  346. eng := NewTestEngine(t)
  347. defer nuke(mkDaemonFromEngine(eng, t))
  348. srv := mkServerFromEngine(eng, t)
  349. // Tag the image
  350. if err := eng.Job("tag", unitTestImageID, "utest", "tag1").Run(); err != nil {
  351. t.Fatal(err)
  352. }
  353. // Create a container from the image
  354. config, _, _, err := runconfig.Parse([]string{unitTestImageID, "echo test"}, nil)
  355. if err != nil {
  356. t.Fatal(err)
  357. }
  358. id := createNamedTestContainer(eng, config, t, "testingtags")
  359. if id == "" {
  360. t.Fatal("No id returned")
  361. }
  362. job := srv.Eng.Job("containers")
  363. job.SetenvBool("all", true)
  364. outs, err := job.Stdout.AddListTable()
  365. if err != nil {
  366. t.Fatal(err)
  367. }
  368. if err := job.Run(); err != nil {
  369. t.Fatal(err)
  370. }
  371. if len(outs.Data) != 1 {
  372. t.Fatalf("Expected 1 container got %d", len(outs.Data))
  373. }
  374. // Try to remove the tag
  375. imgs := engine.NewTable("", 0)
  376. if err := srv.DeleteImage("utest:tag1", imgs, true, false, false); err != nil {
  377. t.Fatal(err)
  378. }
  379. if len(imgs.Data) != 1 {
  380. t.Fatalf("Should only have deleted one untag %d", len(imgs.Data))
  381. }
  382. if untag := imgs.Data[0].Get("Untagged"); untag != "utest:tag1" {
  383. t.Fatalf("Expected %s got %s", unitTestImageID, untag)
  384. }
  385. }