docker_cli_run_test.go 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386
  1. package main
  2. import (
  3. "fmt"
  4. "os/exec"
  5. "strings"
  6. "testing"
  7. )
  8. // "test123" should be printed by docker run
  9. func TestDockerRunEchoStdout(t *testing.T) {
  10. runCmd := exec.Command(dockerBinary, "run", "busybox", "echo", "test123")
  11. out, _, _, err := runCommandWithStdoutStderr(runCmd)
  12. errorOut(err, t, out)
  13. if out != "test123\n" {
  14. t.Errorf("container should've printed 'test123'")
  15. }
  16. deleteAllContainers()
  17. logDone("run - echo test123")
  18. }
  19. // "test" should be printed
  20. func TestDockerRunEchoStdoutWithMemoryLimit(t *testing.T) {
  21. runCmd := exec.Command(dockerBinary, "run", "-m", "2786432", "busybox", "echo", "test")
  22. out, _, _, err := runCommandWithStdoutStderr(runCmd)
  23. errorOut(err, t, out)
  24. if out != "test\n" {
  25. t.Errorf("container should've printed 'test'")
  26. }
  27. deleteAllContainers()
  28. logDone("run - echo with memory limit")
  29. }
  30. // "test" should be printed
  31. func TestDockerRunEchoStdoutWitCPULimit(t *testing.T) {
  32. runCmd := exec.Command(dockerBinary, "run", "-c", "1000", "busybox", "echo", "test")
  33. out, _, _, err := runCommandWithStdoutStderr(runCmd)
  34. errorOut(err, t, out)
  35. if out != "test\n" {
  36. t.Errorf("container should've printed 'test'")
  37. }
  38. deleteAllContainers()
  39. logDone("run - echo with CPU limit")
  40. }
  41. // "test" should be printed
  42. func TestDockerRunEchoStdoutWithCPUAndMemoryLimit(t *testing.T) {
  43. runCmd := exec.Command(dockerBinary, "run", "-c", "1000", "-m", "2786432", "busybox", "echo", "test")
  44. out, _, _, err := runCommandWithStdoutStderr(runCmd)
  45. errorOut(err, t, out)
  46. if out != "test\n" {
  47. t.Errorf("container should've printed 'test'")
  48. }
  49. deleteAllContainers()
  50. logDone("run - echo with CPU and memory limit")
  51. }
  52. // "test" should be printed
  53. func TestDockerRunEchoNamedContainer(t *testing.T) {
  54. runCmd := exec.Command(dockerBinary, "run", "--name", "testfoonamedcontainer", "busybox", "echo", "test")
  55. out, _, _, err := runCommandWithStdoutStderr(runCmd)
  56. errorOut(err, t, out)
  57. if out != "test\n" {
  58. t.Errorf("container should've printed 'test'")
  59. }
  60. if err := deleteContainer("testfoonamedcontainer"); err != nil {
  61. t.Errorf("failed to remove the named container: %v", err)
  62. }
  63. deleteAllContainers()
  64. logDone("run - echo with named container")
  65. }
  66. // it should be possible to ping Google DNS resolver
  67. // this will fail when Internet access is unavailable
  68. func TestDockerRunPingGoogle(t *testing.T) {
  69. runCmd := exec.Command(dockerBinary, "run", "busybox", "ping", "-c", "1", "8.8.8.8")
  70. out, _, _, err := runCommandWithStdoutStderr(runCmd)
  71. errorOut(err, t, out)
  72. errorOut(err, t, "container should've been able to ping 8.8.8.8")
  73. deleteAllContainers()
  74. logDone("run - ping 8.8.8.8")
  75. }
  76. // the exit code should be 0
  77. // some versions of lxc might make this test fail
  78. func TestDockerRunExitCodeZero(t *testing.T) {
  79. runCmd := exec.Command(dockerBinary, "run", "busybox", "true")
  80. exitCode, err := runCommand(runCmd)
  81. errorOut(err, t, fmt.Sprintf("%s", err))
  82. if exitCode != 0 {
  83. t.Errorf("container should've exited with exit code 0")
  84. }
  85. deleteAllContainers()
  86. logDone("run - exit with 0")
  87. }
  88. // the exit code should be 1
  89. // some versions of lxc might make this test fail
  90. func TestDockerRunExitCodeOne(t *testing.T) {
  91. runCmd := exec.Command(dockerBinary, "run", "busybox", "false")
  92. exitCode, err := runCommand(runCmd)
  93. if err != nil && !strings.Contains("exit status 1", fmt.Sprintf("%s", err)) {
  94. t.Fatal(err)
  95. }
  96. if exitCode != 1 {
  97. t.Errorf("container should've exited with exit code 1")
  98. }
  99. deleteAllContainers()
  100. logDone("run - exit with 1")
  101. }
  102. // it should be possible to pipe in data via stdin to a process running in a container
  103. // some versions of lxc might make this test fail
  104. func TestRunStdinPipe(t *testing.T) {
  105. runCmd := exec.Command("bash", "-c", `echo "blahblah" | docker run -i -a stdin busybox cat`)
  106. out, _, _, err := runCommandWithStdoutStderr(runCmd)
  107. errorOut(err, t, out)
  108. out = stripTrailingCharacters(out)
  109. inspectCmd := exec.Command(dockerBinary, "inspect", out)
  110. inspectOut, _, err := runCommandWithOutput(inspectCmd)
  111. errorOut(err, t, fmt.Sprintf("out should've been a container id: %s %s", out, inspectOut))
  112. waitCmd := exec.Command(dockerBinary, "wait", out)
  113. _, _, err = runCommandWithOutput(waitCmd)
  114. errorOut(err, t, fmt.Sprintf("error thrown while waiting for container: %s", out))
  115. logsCmd := exec.Command(dockerBinary, "logs", out)
  116. containerLogs, _, err := runCommandWithOutput(logsCmd)
  117. errorOut(err, t, fmt.Sprintf("error thrown while trying to get container logs: %s", err))
  118. containerLogs = stripTrailingCharacters(containerLogs)
  119. if containerLogs != "blahblah" {
  120. t.Errorf("logs didn't print the container's logs %s", containerLogs)
  121. }
  122. rmCmd := exec.Command(dockerBinary, "rm", out)
  123. _, _, err = runCommandWithOutput(rmCmd)
  124. errorOut(err, t, fmt.Sprintf("rm failed to remove container %s", err))
  125. deleteAllContainers()
  126. logDone("run - pipe in with -i -a stdin")
  127. }
  128. // the container's ID should be printed when starting a container in detached mode
  129. func TestDockerRunDetachedContainerIDPrinting(t *testing.T) {
  130. runCmd := exec.Command(dockerBinary, "run", "-d", "busybox", "true")
  131. out, _, _, err := runCommandWithStdoutStderr(runCmd)
  132. errorOut(err, t, out)
  133. out = stripTrailingCharacters(out)
  134. inspectCmd := exec.Command(dockerBinary, "inspect", out)
  135. inspectOut, _, err := runCommandWithOutput(inspectCmd)
  136. errorOut(err, t, fmt.Sprintf("out should've been a container id: %s %s", out, inspectOut))
  137. waitCmd := exec.Command(dockerBinary, "wait", out)
  138. _, _, err = runCommandWithOutput(waitCmd)
  139. errorOut(err, t, fmt.Sprintf("error thrown while waiting for container: %s", out))
  140. rmCmd := exec.Command(dockerBinary, "rm", out)
  141. rmOut, _, err := runCommandWithOutput(rmCmd)
  142. errorOut(err, t, "rm failed to remove container")
  143. rmOut = stripTrailingCharacters(rmOut)
  144. if rmOut != out {
  145. t.Errorf("rm didn't print the container ID %s %s", out, rmOut)
  146. }
  147. deleteAllContainers()
  148. logDone("run - print container ID in detached mode")
  149. }
  150. // the working directory should be set correctly
  151. func TestDockerRunWorkingDirectory(t *testing.T) {
  152. runCmd := exec.Command(dockerBinary, "run", "-w", "/root", "busybox", "pwd")
  153. out, _, _, err := runCommandWithStdoutStderr(runCmd)
  154. errorOut(err, t, out)
  155. out = stripTrailingCharacters(out)
  156. if out != "/root" {
  157. t.Errorf("-w failed to set working directory")
  158. }
  159. runCmd = exec.Command(dockerBinary, "run", "--workdir", "/root", "busybox", "pwd")
  160. out, _, _, err = runCommandWithStdoutStderr(runCmd)
  161. errorOut(err, t, out)
  162. out = stripTrailingCharacters(out)
  163. if out != "/root" {
  164. t.Errorf("--workdir failed to set working directory")
  165. }
  166. deleteAllContainers()
  167. logDone("run - run with working directory set by -w")
  168. logDone("run - run with working directory set by --workdir")
  169. }
  170. // pinging Google's DNS resolver should fail when we disable the networking
  171. func TestDockerRunWithoutNetworking(t *testing.T) {
  172. runCmd := exec.Command(dockerBinary, "run", "--networking=false", "busybox", "ping", "-c", "1", "8.8.8.8")
  173. out, _, exitCode, err := runCommandWithStdoutStderr(runCmd)
  174. if err != nil && exitCode != 1 {
  175. t.Fatal(out, err)
  176. }
  177. if exitCode != 1 {
  178. t.Errorf("--networking=false should've disabled the network; the container shouldn't have been able to ping 8.8.8.8")
  179. }
  180. runCmd = exec.Command(dockerBinary, "run", "-n=false", "busybox", "ping", "-c", "1", "8.8.8.8")
  181. out, _, exitCode, err = runCommandWithStdoutStderr(runCmd)
  182. if err != nil && exitCode != 1 {
  183. t.Fatal(out, err)
  184. }
  185. if exitCode != 1 {
  186. t.Errorf("-n=false should've disabled the network; the container shouldn't have been able to ping 8.8.8.8")
  187. }
  188. deleteAllContainers()
  189. logDone("run - disable networking with --networking=false")
  190. logDone("run - disable networking with -n=false")
  191. }
  192. // Regression test for #4741
  193. func TestDockerRunWithVolumesAsFiles(t *testing.T) {
  194. runCmd := exec.Command(dockerBinary, "run", "--name", "test-data", "--volume", "/etc/hosts:/target-file", "busybox", "true")
  195. out, stderr, exitCode, err := runCommandWithStdoutStderr(runCmd)
  196. if err != nil && exitCode != 0 {
  197. t.Fatal("1", out, stderr, err)
  198. }
  199. runCmd = exec.Command(dockerBinary, "run", "--volumes-from", "test-data", "busybox", "cat", "/target-file")
  200. out, stderr, exitCode, err = runCommandWithStdoutStderr(runCmd)
  201. if err != nil && exitCode != 0 {
  202. t.Fatal("2", out, stderr, err)
  203. }
  204. deleteAllContainers()
  205. logDone("run - regression test for #4741 - volumes from as files")
  206. }
  207. // Regression test for #4979
  208. func TestDockerRunWithVolumesFromExited(t *testing.T) {
  209. runCmd := exec.Command(dockerBinary, "run", "--name", "test-data", "--volume", "/some/dir", "busybox", "touch", "/some/dir/file")
  210. out, stderr, exitCode, err := runCommandWithStdoutStderr(runCmd)
  211. if err != nil && exitCode != 0 {
  212. t.Fatal("1", out, stderr, err)
  213. }
  214. runCmd = exec.Command(dockerBinary, "run", "--volumes-from", "test-data", "busybox", "cat", "/some/dir/file")
  215. out, stderr, exitCode, err = runCommandWithStdoutStderr(runCmd)
  216. if err != nil && exitCode != 0 {
  217. t.Fatal("2", out, stderr, err)
  218. }
  219. deleteAllContainers()
  220. logDone("run - regression test for #4979 - volumes-from on exited container")
  221. }
  222. // Regression test for #4830
  223. func TestDockerRunWithRelativePath(t *testing.T) {
  224. runCmd := exec.Command(dockerBinary, "run", "-v", "tmp:/other-tmp", "busybox", "true")
  225. if _, _, _, err := runCommandWithStdoutStderr(runCmd); err == nil {
  226. t.Fatalf("relative path should result in an error")
  227. }
  228. deleteAllContainers()
  229. logDone("run - volume with relative path")
  230. }
  231. func TestVolumesMountedAsReadonly(t *testing.T) {
  232. cmd := exec.Command(dockerBinary, "run", "-v", "/test:/test:ro", "busybox", "touch", "/test/somefile")
  233. if code, err := runCommand(cmd); err == nil || code == 0 {
  234. t.Fatalf("run should fail because volume is ro: exit code %d", code)
  235. }
  236. deleteAllContainers()
  237. logDone("run - volumes as readonly mount")
  238. }
  239. func TestVolumesFromInReadonlyMode(t *testing.T) {
  240. cmd := exec.Command(dockerBinary, "run", "--name", "parent", "-v", "/test", "busybox", "true")
  241. if _, err := runCommand(cmd); err != nil {
  242. t.Fatal(err)
  243. }
  244. cmd = exec.Command(dockerBinary, "run", "--volumes-from", "parent:ro", "busybox", "touch", "/test/file")
  245. if code, err := runCommand(cmd); err == nil || code == 0 {
  246. t.Fatalf("run should fail because volume is ro: exit code %d", code)
  247. }
  248. deleteAllContainers()
  249. logDone("run - volumes from as readonly mount")
  250. }
  251. // Regression test for #1201
  252. func TestVolumesFromInReadWriteMode(t *testing.T) {
  253. cmd := exec.Command(dockerBinary, "run", "--name", "parent", "-v", "/test", "busybox", "true")
  254. if _, err := runCommand(cmd); err != nil {
  255. t.Fatal(err)
  256. }
  257. cmd = exec.Command(dockerBinary, "run", "--volumes-from", "parent", "busybox", "touch", "/test/file")
  258. if _, err := runCommand(cmd); err != nil {
  259. t.Fatal(err)
  260. }
  261. deleteAllContainers()
  262. logDone("run - volumes from as read write mount")
  263. }
  264. // Test for #1351
  265. func TestApplyVolumesFromBeforeVolumes(t *testing.T) {
  266. cmd := exec.Command(dockerBinary, "run", "--name", "parent", "-v", "/test", "busybox", "touch", "/test/foo")
  267. if _, err := runCommand(cmd); err != nil {
  268. t.Fatal(err)
  269. }
  270. cmd = exec.Command(dockerBinary, "run", "--volumes-from", "parent", "-v", "/test", "busybox", "cat", "/test/foo")
  271. if _, err := runCommand(cmd); err != nil {
  272. t.Fatal(err)
  273. }
  274. deleteAllContainers()
  275. logDone("run - volumes from mounted first")
  276. }
  277. func TestMultipleVolumesFrom(t *testing.T) {
  278. cmd := exec.Command(dockerBinary, "run", "--name", "parent1", "-v", "/test", "busybox", "touch", "/test/foo")
  279. if _, err := runCommand(cmd); err != nil {
  280. t.Fatal(err)
  281. }
  282. cmd = exec.Command(dockerBinary, "run", "--name", "parent2", "-v", "/other", "busybox", "touch", "/other/bar")
  283. if _, err := runCommand(cmd); err != nil {
  284. t.Fatal(err)
  285. }
  286. cmd = exec.Command(dockerBinary, "run", "--volumes-from", "parent1", "--volumes-from", "parent2",
  287. "busybox", "sh", "-c", "cat /test/foo && cat /other/bar")
  288. if _, err := runCommand(cmd); err != nil {
  289. t.Fatal(err)
  290. }
  291. deleteAllContainers()
  292. logDone("run - multiple volumes from")
  293. }