container_test.go 31 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354
  1. package docker
  2. import (
  3. "bufio"
  4. "fmt"
  5. "io"
  6. "io/ioutil"
  7. "math/rand"
  8. "os"
  9. "path"
  10. "regexp"
  11. "sort"
  12. "strings"
  13. "testing"
  14. "time"
  15. )
  16. func TestIDFormat(t *testing.T) {
  17. runtime := mkRuntime(t)
  18. defer nuke(runtime)
  19. container1, err := NewBuilder(runtime).Create(
  20. &Config{
  21. Image: GetTestImage(runtime).ID,
  22. Cmd: []string{"/bin/sh", "-c", "echo hello world"},
  23. },
  24. )
  25. if err != nil {
  26. t.Fatal(err)
  27. }
  28. match, err := regexp.Match("^[0-9a-f]{64}$", []byte(container1.ID))
  29. if err != nil {
  30. t.Fatal(err)
  31. }
  32. if !match {
  33. t.Fatalf("Invalid container ID: %s", container1.ID)
  34. }
  35. }
  36. func TestMultipleAttachRestart(t *testing.T) {
  37. runtime := mkRuntime(t)
  38. defer nuke(runtime)
  39. container, hostConfig, _ := mkContainer(
  40. runtime,
  41. []string{"_", "/bin/sh", "-c", "i=1; while [ $i -le 5 ]; do i=`expr $i + 1`; echo hello; done"},
  42. t,
  43. )
  44. defer runtime.Destroy(container)
  45. // Simulate 3 client attaching to the container and stop/restart
  46. stdout1, err := container.StdoutPipe()
  47. if err != nil {
  48. t.Fatal(err)
  49. }
  50. stdout2, err := container.StdoutPipe()
  51. if err != nil {
  52. t.Fatal(err)
  53. }
  54. stdout3, err := container.StdoutPipe()
  55. if err != nil {
  56. t.Fatal(err)
  57. }
  58. if err := container.Start(hostConfig); err != nil {
  59. t.Fatal(err)
  60. }
  61. l1, err := bufio.NewReader(stdout1).ReadString('\n')
  62. if err != nil {
  63. t.Fatal(err)
  64. }
  65. if strings.Trim(l1, " \r\n") != "hello" {
  66. t.Fatalf("Unexpected output. Expected [%s], received [%s]", "hello", l1)
  67. }
  68. l2, err := bufio.NewReader(stdout2).ReadString('\n')
  69. if err != nil {
  70. t.Fatal(err)
  71. }
  72. if strings.Trim(l2, " \r\n") != "hello" {
  73. t.Fatalf("Unexpected output. Expected [%s], received [%s]", "hello", l2)
  74. }
  75. l3, err := bufio.NewReader(stdout3).ReadString('\n')
  76. if err != nil {
  77. t.Fatal(err)
  78. }
  79. if strings.Trim(l3, " \r\n") != "hello" {
  80. t.Fatalf("Unexpected output. Expected [%s], received [%s]", "hello", l3)
  81. }
  82. if err := container.Stop(10); err != nil {
  83. t.Fatal(err)
  84. }
  85. stdout1, err = container.StdoutPipe()
  86. if err != nil {
  87. t.Fatal(err)
  88. }
  89. stdout2, err = container.StdoutPipe()
  90. if err != nil {
  91. t.Fatal(err)
  92. }
  93. stdout3, err = container.StdoutPipe()
  94. if err != nil {
  95. t.Fatal(err)
  96. }
  97. if err := container.Start(hostConfig); err != nil {
  98. t.Fatal(err)
  99. }
  100. setTimeout(t, "Timeout reading from the process", 3*time.Second, func() {
  101. l1, err = bufio.NewReader(stdout1).ReadString('\n')
  102. if err != nil {
  103. t.Fatal(err)
  104. }
  105. if strings.Trim(l1, " \r\n") != "hello" {
  106. t.Fatalf("Unexpected output. Expected [%s], received [%s]", "hello", l1)
  107. }
  108. l2, err = bufio.NewReader(stdout2).ReadString('\n')
  109. if err != nil {
  110. t.Fatal(err)
  111. }
  112. if strings.Trim(l2, " \r\n") != "hello" {
  113. t.Fatalf("Unexpected output. Expected [%s], received [%s]", "hello", l2)
  114. }
  115. l3, err = bufio.NewReader(stdout3).ReadString('\n')
  116. if err != nil {
  117. t.Fatal(err)
  118. }
  119. if strings.Trim(l3, " \r\n") != "hello" {
  120. t.Fatalf("Unexpected output. Expected [%s], received [%s]", "hello", l3)
  121. }
  122. })
  123. container.Wait()
  124. }
  125. func TestDiff(t *testing.T) {
  126. runtime := mkRuntime(t)
  127. defer nuke(runtime)
  128. // Create a container and remove a file
  129. container1, _, _ := mkContainer(runtime, []string{"_", "/bin/rm", "/etc/passwd"}, t)
  130. defer runtime.Destroy(container1)
  131. if err := container1.Run(); err != nil {
  132. t.Fatal(err)
  133. }
  134. // Check the changelog
  135. c, err := container1.Changes()
  136. if err != nil {
  137. t.Fatal(err)
  138. }
  139. success := false
  140. for _, elem := range c {
  141. if elem.Path == "/etc/passwd" && elem.Kind == 2 {
  142. success = true
  143. }
  144. }
  145. if !success {
  146. t.Fatalf("/etc/passwd as been removed but is not present in the diff")
  147. }
  148. // Commit the container
  149. rwTar, err := container1.ExportRw()
  150. if err != nil {
  151. t.Error(err)
  152. }
  153. img, err := runtime.graph.Create(rwTar, container1, "unit test commited image - diff", "", nil)
  154. if err != nil {
  155. t.Error(err)
  156. }
  157. // Create a new container from the commited image
  158. container2, _, _ := mkContainer(runtime, []string{img.ID, "cat", "/etc/passwd"}, t)
  159. defer runtime.Destroy(container2)
  160. if err := container2.Run(); err != nil {
  161. t.Fatal(err)
  162. }
  163. // Check the changelog
  164. c, err = container2.Changes()
  165. if err != nil {
  166. t.Fatal(err)
  167. }
  168. for _, elem := range c {
  169. if elem.Path == "/etc/passwd" {
  170. t.Fatalf("/etc/passwd should not be present in the diff after commit.")
  171. }
  172. }
  173. // Create a new container
  174. container3, _, _ := mkContainer(runtime, []string{"_", "rm", "/bin/httpd"}, t)
  175. defer runtime.Destroy(container3)
  176. if err := container3.Run(); err != nil {
  177. t.Fatal(err)
  178. }
  179. // Check the changelog
  180. c, err = container3.Changes()
  181. if err != nil {
  182. t.Fatal(err)
  183. }
  184. success = false
  185. for _, elem := range c {
  186. if elem.Path == "/bin/httpd" && elem.Kind == 2 {
  187. success = true
  188. }
  189. }
  190. if !success {
  191. t.Fatalf("/bin/httpd should be present in the diff after commit.")
  192. }
  193. }
  194. func TestCommitAutoRun(t *testing.T) {
  195. runtime := mkRuntime(t)
  196. defer nuke(runtime)
  197. container1, _, _ := mkContainer(runtime, []string{"_", "/bin/sh", "-c", "echo hello > /world"}, t)
  198. defer runtime.Destroy(container1)
  199. if container1.State.Running {
  200. t.Errorf("Container shouldn't be running")
  201. }
  202. if err := container1.Run(); err != nil {
  203. t.Fatal(err)
  204. }
  205. if container1.State.Running {
  206. t.Errorf("Container shouldn't be running")
  207. }
  208. rwTar, err := container1.ExportRw()
  209. if err != nil {
  210. t.Error(err)
  211. }
  212. img, err := runtime.graph.Create(rwTar, container1, "unit test commited image", "", &Config{Cmd: []string{"cat", "/world"}})
  213. if err != nil {
  214. t.Error(err)
  215. }
  216. // FIXME: Make a TestCommit that stops here and check docker.root/layers/img.id/world
  217. container2, hostConfig, _ := mkContainer(runtime, []string{img.ID}, t)
  218. defer runtime.Destroy(container2)
  219. stdout, err := container2.StdoutPipe()
  220. if err != nil {
  221. t.Fatal(err)
  222. }
  223. stderr, err := container2.StderrPipe()
  224. if err != nil {
  225. t.Fatal(err)
  226. }
  227. if err := container2.Start(hostConfig); err != nil {
  228. t.Fatal(err)
  229. }
  230. container2.Wait()
  231. output, err := ioutil.ReadAll(stdout)
  232. if err != nil {
  233. t.Fatal(err)
  234. }
  235. output2, err := ioutil.ReadAll(stderr)
  236. if err != nil {
  237. t.Fatal(err)
  238. }
  239. if err := stdout.Close(); err != nil {
  240. t.Fatal(err)
  241. }
  242. if err := stderr.Close(); err != nil {
  243. t.Fatal(err)
  244. }
  245. if string(output) != "hello\n" {
  246. t.Fatalf("Unexpected output. Expected %s, received: %s (err: %s)", "hello\n", output, output2)
  247. }
  248. }
  249. func TestCommitRun(t *testing.T) {
  250. runtime := mkRuntime(t)
  251. defer nuke(runtime)
  252. container1, hostConfig, _ := mkContainer(runtime, []string{"_", "/bin/sh", "-c", "echo hello > /world"}, t)
  253. defer runtime.Destroy(container1)
  254. if container1.State.Running {
  255. t.Errorf("Container shouldn't be running")
  256. }
  257. if err := container1.Run(); err != nil {
  258. t.Fatal(err)
  259. }
  260. if container1.State.Running {
  261. t.Errorf("Container shouldn't be running")
  262. }
  263. rwTar, err := container1.ExportRw()
  264. if err != nil {
  265. t.Error(err)
  266. }
  267. img, err := runtime.graph.Create(rwTar, container1, "unit test commited image", "", nil)
  268. if err != nil {
  269. t.Error(err)
  270. }
  271. // FIXME: Make a TestCommit that stops here and check docker.root/layers/img.id/world
  272. container2, hostConfig, _ := mkContainer(runtime, []string{img.ID, "cat", "/world"}, t)
  273. defer runtime.Destroy(container2)
  274. stdout, err := container2.StdoutPipe()
  275. if err != nil {
  276. t.Fatal(err)
  277. }
  278. stderr, err := container2.StderrPipe()
  279. if err != nil {
  280. t.Fatal(err)
  281. }
  282. if err := container2.Start(hostConfig); err != nil {
  283. t.Fatal(err)
  284. }
  285. container2.Wait()
  286. output, err := ioutil.ReadAll(stdout)
  287. if err != nil {
  288. t.Fatal(err)
  289. }
  290. output2, err := ioutil.ReadAll(stderr)
  291. if err != nil {
  292. t.Fatal(err)
  293. }
  294. if err := stdout.Close(); err != nil {
  295. t.Fatal(err)
  296. }
  297. if err := stderr.Close(); err != nil {
  298. t.Fatal(err)
  299. }
  300. if string(output) != "hello\n" {
  301. t.Fatalf("Unexpected output. Expected %s, received: %s (err: %s)", "hello\n", output, output2)
  302. }
  303. }
  304. func TestStart(t *testing.T) {
  305. runtime := mkRuntime(t)
  306. defer nuke(runtime)
  307. container, hostConfig, _ := mkContainer(runtime, []string{"-m", "33554432", "-c", "1000", "-i", "_", "/bin/cat"}, t)
  308. defer runtime.Destroy(container)
  309. cStdin, err := container.StdinPipe()
  310. if err != nil {
  311. t.Fatal(err)
  312. }
  313. if err := container.Start(hostConfig); err != nil {
  314. t.Fatal(err)
  315. }
  316. // Give some time to the process to start
  317. container.WaitTimeout(500 * time.Millisecond)
  318. if !container.State.Running {
  319. t.Errorf("Container should be running")
  320. }
  321. if err := container.Start(hostConfig); err == nil {
  322. t.Fatalf("A running container should be able to be started")
  323. }
  324. // Try to avoid the timeout in destroy. Best effort, don't check error
  325. cStdin.Close()
  326. container.WaitTimeout(2 * time.Second)
  327. }
  328. func TestRun(t *testing.T) {
  329. runtime := mkRuntime(t)
  330. defer nuke(runtime)
  331. container, _, _ := mkContainer(runtime, []string{"_", "ls", "-al"}, t)
  332. defer runtime.Destroy(container)
  333. if container.State.Running {
  334. t.Errorf("Container shouldn't be running")
  335. }
  336. if err := container.Run(); err != nil {
  337. t.Fatal(err)
  338. }
  339. if container.State.Running {
  340. t.Errorf("Container shouldn't be running")
  341. }
  342. }
  343. func TestOutput(t *testing.T) {
  344. runtime := mkRuntime(t)
  345. defer nuke(runtime)
  346. container, err := NewBuilder(runtime).Create(
  347. &Config{
  348. Image: GetTestImage(runtime).ID,
  349. Cmd: []string{"echo", "-n", "foobar"},
  350. },
  351. )
  352. if err != nil {
  353. t.Fatal(err)
  354. }
  355. defer runtime.Destroy(container)
  356. output, err := container.Output()
  357. if err != nil {
  358. t.Fatal(err)
  359. }
  360. if string(output) != "foobar" {
  361. t.Error(string(output))
  362. }
  363. }
  364. func TestKillDifferentUser(t *testing.T) {
  365. runtime := mkRuntime(t)
  366. defer nuke(runtime)
  367. container, err := NewBuilder(runtime).Create(&Config{
  368. Image: GetTestImage(runtime).ID,
  369. Cmd: []string{"cat"},
  370. OpenStdin: true,
  371. User: "daemon",
  372. },
  373. )
  374. if err != nil {
  375. t.Fatal(err)
  376. }
  377. defer runtime.Destroy(container)
  378. defer container.stdin.Close()
  379. if container.State.Running {
  380. t.Errorf("Container shouldn't be running")
  381. }
  382. if err := container.Start(&HostConfig{}); err != nil {
  383. t.Fatal(err)
  384. }
  385. setTimeout(t, "Waiting for the container to be started timed out", 2*time.Second, func() {
  386. for !container.State.Running {
  387. time.Sleep(10 * time.Millisecond)
  388. }
  389. })
  390. setTimeout(t, "read/write assertion timed out", 2*time.Second, func() {
  391. out, _ := container.StdoutPipe()
  392. in, _ := container.StdinPipe()
  393. if err := assertPipe("hello\n", "hello", out, in, 15); err != nil {
  394. t.Fatal(err)
  395. }
  396. })
  397. if err := container.Kill(); err != nil {
  398. t.Fatal(err)
  399. }
  400. if container.State.Running {
  401. t.Errorf("Container shouldn't be running")
  402. }
  403. container.Wait()
  404. if container.State.Running {
  405. t.Errorf("Container shouldn't be running")
  406. }
  407. // Try stopping twice
  408. if err := container.Kill(); err != nil {
  409. t.Fatal(err)
  410. }
  411. }
  412. // Test that creating a container with a volume doesn't crash. Regression test for #995.
  413. func TestCreateVolume(t *testing.T) {
  414. runtime := mkRuntime(t)
  415. defer nuke(runtime)
  416. config, hc, _, err := ParseRun([]string{"-v", "/var/lib/data", GetTestImage(runtime).ID, "echo", "hello", "world"}, nil)
  417. if err != nil {
  418. t.Fatal(err)
  419. }
  420. c, err := NewBuilder(runtime).Create(config)
  421. if err != nil {
  422. t.Fatal(err)
  423. }
  424. defer runtime.Destroy(c)
  425. if err := c.Start(hc); err != nil {
  426. t.Fatal(err)
  427. }
  428. c.WaitTimeout(500 * time.Millisecond)
  429. c.Wait()
  430. }
  431. func TestKill(t *testing.T) {
  432. runtime := mkRuntime(t)
  433. defer nuke(runtime)
  434. container, err := NewBuilder(runtime).Create(&Config{
  435. Image: GetTestImage(runtime).ID,
  436. Cmd: []string{"sleep", "2"},
  437. },
  438. )
  439. if err != nil {
  440. t.Fatal(err)
  441. }
  442. defer runtime.Destroy(container)
  443. if container.State.Running {
  444. t.Errorf("Container shouldn't be running")
  445. }
  446. hostConfig := &HostConfig{}
  447. if err := container.Start(hostConfig); err != nil {
  448. t.Fatal(err)
  449. }
  450. // Give some time to lxc to spawn the process
  451. container.WaitTimeout(500 * time.Millisecond)
  452. if !container.State.Running {
  453. t.Errorf("Container should be running")
  454. }
  455. if err := container.Kill(); err != nil {
  456. t.Fatal(err)
  457. }
  458. if container.State.Running {
  459. t.Errorf("Container shouldn't be running")
  460. }
  461. container.Wait()
  462. if container.State.Running {
  463. t.Errorf("Container shouldn't be running")
  464. }
  465. // Try stopping twice
  466. if err := container.Kill(); err != nil {
  467. t.Fatal(err)
  468. }
  469. }
  470. func TestExitCode(t *testing.T) {
  471. runtime := mkRuntime(t)
  472. defer nuke(runtime)
  473. builder := NewBuilder(runtime)
  474. trueContainer, err := builder.Create(&Config{
  475. Image: GetTestImage(runtime).ID,
  476. Cmd: []string{"/bin/true", ""},
  477. })
  478. if err != nil {
  479. t.Fatal(err)
  480. }
  481. defer runtime.Destroy(trueContainer)
  482. if err := trueContainer.Run(); err != nil {
  483. t.Fatal(err)
  484. }
  485. if trueContainer.State.ExitCode != 0 {
  486. t.Errorf("Unexpected exit code %d (expected 0)", trueContainer.State.ExitCode)
  487. }
  488. falseContainer, err := builder.Create(&Config{
  489. Image: GetTestImage(runtime).ID,
  490. Cmd: []string{"/bin/false", ""},
  491. })
  492. if err != nil {
  493. t.Fatal(err)
  494. }
  495. defer runtime.Destroy(falseContainer)
  496. if err := falseContainer.Run(); err != nil {
  497. t.Fatal(err)
  498. }
  499. if falseContainer.State.ExitCode != 1 {
  500. t.Errorf("Unexpected exit code %d (expected 1)", falseContainer.State.ExitCode)
  501. }
  502. }
  503. func TestRestart(t *testing.T) {
  504. runtime := mkRuntime(t)
  505. defer nuke(runtime)
  506. container, err := NewBuilder(runtime).Create(&Config{
  507. Image: GetTestImage(runtime).ID,
  508. Cmd: []string{"echo", "-n", "foobar"},
  509. },
  510. )
  511. if err != nil {
  512. t.Fatal(err)
  513. }
  514. defer runtime.Destroy(container)
  515. output, err := container.Output()
  516. if err != nil {
  517. t.Fatal(err)
  518. }
  519. if string(output) != "foobar" {
  520. t.Error(string(output))
  521. }
  522. // Run the container again and check the output
  523. output, err = container.Output()
  524. if err != nil {
  525. t.Fatal(err)
  526. }
  527. if string(output) != "foobar" {
  528. t.Error(string(output))
  529. }
  530. }
  531. func TestRestartStdin(t *testing.T) {
  532. runtime := mkRuntime(t)
  533. defer nuke(runtime)
  534. container, err := NewBuilder(runtime).Create(&Config{
  535. Image: GetTestImage(runtime).ID,
  536. Cmd: []string{"cat"},
  537. OpenStdin: true,
  538. },
  539. )
  540. if err != nil {
  541. t.Fatal(err)
  542. }
  543. defer runtime.Destroy(container)
  544. stdin, err := container.StdinPipe()
  545. if err != nil {
  546. t.Fatal(err)
  547. }
  548. stdout, err := container.StdoutPipe()
  549. if err != nil {
  550. t.Fatal(err)
  551. }
  552. hostConfig := &HostConfig{}
  553. if err := container.Start(hostConfig); err != nil {
  554. t.Fatal(err)
  555. }
  556. if _, err := io.WriteString(stdin, "hello world"); err != nil {
  557. t.Fatal(err)
  558. }
  559. if err := stdin.Close(); err != nil {
  560. t.Fatal(err)
  561. }
  562. container.Wait()
  563. output, err := ioutil.ReadAll(stdout)
  564. if err != nil {
  565. t.Fatal(err)
  566. }
  567. if err := stdout.Close(); err != nil {
  568. t.Fatal(err)
  569. }
  570. if string(output) != "hello world" {
  571. t.Fatalf("Unexpected output. Expected %s, received: %s", "hello world", string(output))
  572. }
  573. // Restart and try again
  574. stdin, err = container.StdinPipe()
  575. if err != nil {
  576. t.Fatal(err)
  577. }
  578. stdout, err = container.StdoutPipe()
  579. if err != nil {
  580. t.Fatal(err)
  581. }
  582. if err := container.Start(hostConfig); err != nil {
  583. t.Fatal(err)
  584. }
  585. if _, err := io.WriteString(stdin, "hello world #2"); err != nil {
  586. t.Fatal(err)
  587. }
  588. if err := stdin.Close(); err != nil {
  589. t.Fatal(err)
  590. }
  591. container.Wait()
  592. output, err = ioutil.ReadAll(stdout)
  593. if err != nil {
  594. t.Fatal(err)
  595. }
  596. if err := stdout.Close(); err != nil {
  597. t.Fatal(err)
  598. }
  599. if string(output) != "hello world #2" {
  600. t.Fatalf("Unexpected output. Expected %s, received: %s", "hello world #2", string(output))
  601. }
  602. }
  603. func TestUser(t *testing.T) {
  604. runtime := mkRuntime(t)
  605. defer nuke(runtime)
  606. builder := NewBuilder(runtime)
  607. // Default user must be root
  608. container, err := builder.Create(&Config{
  609. Image: GetTestImage(runtime).ID,
  610. Cmd: []string{"id"},
  611. },
  612. )
  613. if err != nil {
  614. t.Fatal(err)
  615. }
  616. defer runtime.Destroy(container)
  617. output, err := container.Output()
  618. if err != nil {
  619. t.Fatal(err)
  620. }
  621. if !strings.Contains(string(output), "uid=0(root) gid=0(root)") {
  622. t.Error(string(output))
  623. }
  624. // Set a username
  625. container, err = builder.Create(&Config{
  626. Image: GetTestImage(runtime).ID,
  627. Cmd: []string{"id"},
  628. User: "root",
  629. },
  630. )
  631. if err != nil {
  632. t.Fatal(err)
  633. }
  634. defer runtime.Destroy(container)
  635. output, err = container.Output()
  636. if err != nil || container.State.ExitCode != 0 {
  637. t.Fatal(err)
  638. }
  639. if !strings.Contains(string(output), "uid=0(root) gid=0(root)") {
  640. t.Error(string(output))
  641. }
  642. // Set a UID
  643. container, err = builder.Create(&Config{
  644. Image: GetTestImage(runtime).ID,
  645. Cmd: []string{"id"},
  646. User: "0",
  647. },
  648. )
  649. if err != nil || container.State.ExitCode != 0 {
  650. t.Fatal(err)
  651. }
  652. defer runtime.Destroy(container)
  653. output, err = container.Output()
  654. if err != nil || container.State.ExitCode != 0 {
  655. t.Fatal(err)
  656. }
  657. if !strings.Contains(string(output), "uid=0(root) gid=0(root)") {
  658. t.Error(string(output))
  659. }
  660. // Set a different user by uid
  661. container, err = builder.Create(&Config{
  662. Image: GetTestImage(runtime).ID,
  663. Cmd: []string{"id"},
  664. User: "1",
  665. },
  666. )
  667. if err != nil {
  668. t.Fatal(err)
  669. }
  670. defer runtime.Destroy(container)
  671. output, err = container.Output()
  672. if err != nil {
  673. t.Fatal(err)
  674. } else if container.State.ExitCode != 0 {
  675. t.Fatalf("Container exit code is invalid: %d\nOutput:\n%s\n", container.State.ExitCode, output)
  676. }
  677. if !strings.Contains(string(output), "uid=1(daemon) gid=1(daemon)") {
  678. t.Error(string(output))
  679. }
  680. // Set a different user by username
  681. container, err = builder.Create(&Config{
  682. Image: GetTestImage(runtime).ID,
  683. Cmd: []string{"id"},
  684. User: "daemon",
  685. },
  686. )
  687. if err != nil {
  688. t.Fatal(err)
  689. }
  690. defer runtime.Destroy(container)
  691. output, err = container.Output()
  692. if err != nil || container.State.ExitCode != 0 {
  693. t.Fatal(err)
  694. }
  695. if !strings.Contains(string(output), "uid=1(daemon) gid=1(daemon)") {
  696. t.Error(string(output))
  697. }
  698. // Test an wrong username
  699. container, err = builder.Create(&Config{
  700. Image: GetTestImage(runtime).ID,
  701. Cmd: []string{"id"},
  702. User: "unknownuser",
  703. },
  704. )
  705. if err != nil {
  706. t.Fatal(err)
  707. }
  708. defer runtime.Destroy(container)
  709. output, err = container.Output()
  710. if container.State.ExitCode == 0 {
  711. t.Fatal("Starting container with wrong uid should fail but it passed.")
  712. }
  713. }
  714. func TestMultipleContainers(t *testing.T) {
  715. runtime := mkRuntime(t)
  716. defer nuke(runtime)
  717. builder := NewBuilder(runtime)
  718. container1, err := builder.Create(&Config{
  719. Image: GetTestImage(runtime).ID,
  720. Cmd: []string{"sleep", "2"},
  721. },
  722. )
  723. if err != nil {
  724. t.Fatal(err)
  725. }
  726. defer runtime.Destroy(container1)
  727. container2, err := builder.Create(&Config{
  728. Image: GetTestImage(runtime).ID,
  729. Cmd: []string{"sleep", "2"},
  730. },
  731. )
  732. if err != nil {
  733. t.Fatal(err)
  734. }
  735. defer runtime.Destroy(container2)
  736. // Start both containers
  737. hostConfig := &HostConfig{}
  738. if err := container1.Start(hostConfig); err != nil {
  739. t.Fatal(err)
  740. }
  741. if err := container2.Start(hostConfig); err != nil {
  742. t.Fatal(err)
  743. }
  744. // Make sure they are running before trying to kill them
  745. container1.WaitTimeout(250 * time.Millisecond)
  746. container2.WaitTimeout(250 * time.Millisecond)
  747. // If we are here, both containers should be running
  748. if !container1.State.Running {
  749. t.Fatal("Container not running")
  750. }
  751. if !container2.State.Running {
  752. t.Fatal("Container not running")
  753. }
  754. // Kill them
  755. if err := container1.Kill(); err != nil {
  756. t.Fatal(err)
  757. }
  758. if err := container2.Kill(); err != nil {
  759. t.Fatal(err)
  760. }
  761. }
  762. func TestStdin(t *testing.T) {
  763. runtime := mkRuntime(t)
  764. defer nuke(runtime)
  765. container, err := NewBuilder(runtime).Create(&Config{
  766. Image: GetTestImage(runtime).ID,
  767. Cmd: []string{"cat"},
  768. OpenStdin: true,
  769. },
  770. )
  771. if err != nil {
  772. t.Fatal(err)
  773. }
  774. defer runtime.Destroy(container)
  775. stdin, err := container.StdinPipe()
  776. if err != nil {
  777. t.Fatal(err)
  778. }
  779. stdout, err := container.StdoutPipe()
  780. if err != nil {
  781. t.Fatal(err)
  782. }
  783. hostConfig := &HostConfig{}
  784. if err := container.Start(hostConfig); err != nil {
  785. t.Fatal(err)
  786. }
  787. defer stdin.Close()
  788. defer stdout.Close()
  789. if _, err := io.WriteString(stdin, "hello world"); err != nil {
  790. t.Fatal(err)
  791. }
  792. if err := stdin.Close(); err != nil {
  793. t.Fatal(err)
  794. }
  795. container.Wait()
  796. output, err := ioutil.ReadAll(stdout)
  797. if err != nil {
  798. t.Fatal(err)
  799. }
  800. if string(output) != "hello world" {
  801. t.Fatalf("Unexpected output. Expected %s, received: %s", "hello world", string(output))
  802. }
  803. }
  804. func TestTty(t *testing.T) {
  805. runtime := mkRuntime(t)
  806. defer nuke(runtime)
  807. container, err := NewBuilder(runtime).Create(&Config{
  808. Image: GetTestImage(runtime).ID,
  809. Cmd: []string{"cat"},
  810. OpenStdin: true,
  811. },
  812. )
  813. if err != nil {
  814. t.Fatal(err)
  815. }
  816. defer runtime.Destroy(container)
  817. stdin, err := container.StdinPipe()
  818. if err != nil {
  819. t.Fatal(err)
  820. }
  821. stdout, err := container.StdoutPipe()
  822. if err != nil {
  823. t.Fatal(err)
  824. }
  825. hostConfig := &HostConfig{}
  826. if err := container.Start(hostConfig); err != nil {
  827. t.Fatal(err)
  828. }
  829. defer stdin.Close()
  830. defer stdout.Close()
  831. if _, err := io.WriteString(stdin, "hello world"); err != nil {
  832. t.Fatal(err)
  833. }
  834. if err := stdin.Close(); err != nil {
  835. t.Fatal(err)
  836. }
  837. container.Wait()
  838. output, err := ioutil.ReadAll(stdout)
  839. if err != nil {
  840. t.Fatal(err)
  841. }
  842. if string(output) != "hello world" {
  843. t.Fatalf("Unexpected output. Expected %s, received: %s", "hello world", string(output))
  844. }
  845. }
  846. func TestEnv(t *testing.T) {
  847. runtime := mkRuntime(t)
  848. defer nuke(runtime)
  849. container, err := NewBuilder(runtime).Create(&Config{
  850. Image: GetTestImage(runtime).ID,
  851. Cmd: []string{"env"},
  852. },
  853. )
  854. if err != nil {
  855. t.Fatal(err)
  856. }
  857. defer runtime.Destroy(container)
  858. stdout, err := container.StdoutPipe()
  859. if err != nil {
  860. t.Fatal(err)
  861. }
  862. defer stdout.Close()
  863. hostConfig := &HostConfig{}
  864. if err := container.Start(hostConfig); err != nil {
  865. t.Fatal(err)
  866. }
  867. container.Wait()
  868. output, err := ioutil.ReadAll(stdout)
  869. if err != nil {
  870. t.Fatal(err)
  871. }
  872. actualEnv := strings.Split(string(output), "\n")
  873. if actualEnv[len(actualEnv)-1] == "" {
  874. actualEnv = actualEnv[:len(actualEnv)-1]
  875. }
  876. sort.Strings(actualEnv)
  877. goodEnv := []string{
  878. "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
  879. "HOME=/",
  880. "container=lxc",
  881. "HOSTNAME=" + container.ShortID(),
  882. }
  883. sort.Strings(goodEnv)
  884. if len(goodEnv) != len(actualEnv) {
  885. t.Fatalf("Wrong environment: should be %d variables, not: '%s'\n", len(goodEnv), strings.Join(actualEnv, ", "))
  886. }
  887. for i := range goodEnv {
  888. if actualEnv[i] != goodEnv[i] {
  889. t.Fatalf("Wrong environment variable: should be %s, not %s", goodEnv[i], actualEnv[i])
  890. }
  891. }
  892. }
  893. func TestEntrypoint(t *testing.T) {
  894. runtime := mkRuntime(t)
  895. defer nuke(runtime)
  896. container, err := NewBuilder(runtime).Create(
  897. &Config{
  898. Image: GetTestImage(runtime).ID,
  899. Entrypoint: []string{"/bin/echo"},
  900. Cmd: []string{"-n", "foobar"},
  901. },
  902. )
  903. if err != nil {
  904. t.Fatal(err)
  905. }
  906. defer runtime.Destroy(container)
  907. output, err := container.Output()
  908. if err != nil {
  909. t.Fatal(err)
  910. }
  911. if string(output) != "foobar" {
  912. t.Error(string(output))
  913. }
  914. }
  915. func TestEntrypointNoCmd(t *testing.T) {
  916. runtime := mkRuntime(t)
  917. defer nuke(runtime)
  918. container, err := NewBuilder(runtime).Create(
  919. &Config{
  920. Image: GetTestImage(runtime).ID,
  921. Entrypoint: []string{"/bin/echo", "foobar"},
  922. },
  923. )
  924. if err != nil {
  925. t.Fatal(err)
  926. }
  927. defer runtime.Destroy(container)
  928. output, err := container.Output()
  929. if err != nil {
  930. t.Fatal(err)
  931. }
  932. if strings.Trim(string(output), "\r\n") != "foobar" {
  933. t.Error(string(output))
  934. }
  935. }
  936. func grepFile(t *testing.T, path string, pattern string) {
  937. f, err := os.Open(path)
  938. if err != nil {
  939. t.Fatal(err)
  940. }
  941. defer f.Close()
  942. r := bufio.NewReader(f)
  943. var (
  944. line string
  945. )
  946. err = nil
  947. for err == nil {
  948. line, err = r.ReadString('\n')
  949. if strings.Contains(line, pattern) == true {
  950. return
  951. }
  952. }
  953. t.Fatalf("grepFile: pattern \"%s\" not found in \"%s\"", pattern, path)
  954. }
  955. func TestLXCConfig(t *testing.T) {
  956. runtime := mkRuntime(t)
  957. defer nuke(runtime)
  958. // Memory is allocated randomly for testing
  959. rand.Seed(time.Now().UTC().UnixNano())
  960. memMin := 33554432
  961. memMax := 536870912
  962. mem := memMin + rand.Intn(memMax-memMin)
  963. // CPU shares as well
  964. cpuMin := 100
  965. cpuMax := 10000
  966. cpu := cpuMin + rand.Intn(cpuMax-cpuMin)
  967. container, err := NewBuilder(runtime).Create(&Config{
  968. Image: GetTestImage(runtime).ID,
  969. Cmd: []string{"/bin/true"},
  970. Hostname: "foobar",
  971. Memory: int64(mem),
  972. CpuShares: int64(cpu),
  973. },
  974. )
  975. if err != nil {
  976. t.Fatal(err)
  977. }
  978. defer runtime.Destroy(container)
  979. container.generateLXCConfig()
  980. grepFile(t, container.lxcConfigPath(), "lxc.utsname = foobar")
  981. grepFile(t, container.lxcConfigPath(),
  982. fmt.Sprintf("lxc.cgroup.memory.limit_in_bytes = %d", mem))
  983. grepFile(t, container.lxcConfigPath(),
  984. fmt.Sprintf("lxc.cgroup.memory.memsw.limit_in_bytes = %d", mem*2))
  985. }
  986. func BenchmarkRunSequencial(b *testing.B) {
  987. runtime := mkRuntime(b)
  988. defer nuke(runtime)
  989. for i := 0; i < b.N; i++ {
  990. container, err := NewBuilder(runtime).Create(&Config{
  991. Image: GetTestImage(runtime).ID,
  992. Cmd: []string{"echo", "-n", "foo"},
  993. },
  994. )
  995. if err != nil {
  996. b.Fatal(err)
  997. }
  998. defer runtime.Destroy(container)
  999. output, err := container.Output()
  1000. if err != nil {
  1001. b.Fatal(err)
  1002. }
  1003. if string(output) != "foo" {
  1004. b.Fatalf("Unexpected output: %s", output)
  1005. }
  1006. if err := runtime.Destroy(container); err != nil {
  1007. b.Fatal(err)
  1008. }
  1009. }
  1010. }
  1011. func BenchmarkRunParallel(b *testing.B) {
  1012. runtime := mkRuntime(b)
  1013. defer nuke(runtime)
  1014. var tasks []chan error
  1015. for i := 0; i < b.N; i++ {
  1016. complete := make(chan error)
  1017. tasks = append(tasks, complete)
  1018. go func(i int, complete chan error) {
  1019. container, err := NewBuilder(runtime).Create(&Config{
  1020. Image: GetTestImage(runtime).ID,
  1021. Cmd: []string{"echo", "-n", "foo"},
  1022. },
  1023. )
  1024. if err != nil {
  1025. complete <- err
  1026. return
  1027. }
  1028. defer runtime.Destroy(container)
  1029. hostConfig := &HostConfig{}
  1030. if err := container.Start(hostConfig); err != nil {
  1031. complete <- err
  1032. return
  1033. }
  1034. if err := container.WaitTimeout(15 * time.Second); err != nil {
  1035. complete <- err
  1036. return
  1037. }
  1038. // if string(output) != "foo" {
  1039. // complete <- fmt.Errorf("Unexecpted output: %v", string(output))
  1040. // }
  1041. if err := runtime.Destroy(container); err != nil {
  1042. complete <- err
  1043. return
  1044. }
  1045. complete <- nil
  1046. }(i, complete)
  1047. }
  1048. var errors []error
  1049. for _, task := range tasks {
  1050. err := <-task
  1051. if err != nil {
  1052. errors = append(errors, err)
  1053. }
  1054. }
  1055. if len(errors) > 0 {
  1056. b.Fatal(errors)
  1057. }
  1058. }
  1059. func tempDir(t *testing.T) string {
  1060. tmpDir, err := ioutil.TempDir("", "docker-test")
  1061. if err != nil {
  1062. t.Fatal(err)
  1063. }
  1064. return tmpDir
  1065. }
  1066. func TestBindMounts(t *testing.T) {
  1067. r := mkRuntime(t)
  1068. defer nuke(r)
  1069. tmpDir := tempDir(t)
  1070. defer os.RemoveAll(tmpDir)
  1071. writeFile(path.Join(tmpDir, "touch-me"), "", t)
  1072. // Test reading from a read-only bind mount
  1073. stdout, _ := runContainer(r, []string{"-v", fmt.Sprintf("%s:/tmp:ro", tmpDir), "_", "ls", "/tmp"}, t)
  1074. if !strings.Contains(stdout, "touch-me") {
  1075. t.Fatal("Container failed to read from bind mount")
  1076. }
  1077. // test writing to bind mount
  1078. runContainer(r, []string{"-v", fmt.Sprintf("%s:/tmp:rw", tmpDir), "_", "touch", "/tmp/holla"}, t)
  1079. readFile(path.Join(tmpDir, "holla"), t) // Will fail if the file doesn't exist
  1080. // test mounting to an illegal destination directory
  1081. if _, err := runContainer(r, []string{"-v", fmt.Sprintf("%s:.", tmpDir), "_", "ls", "."}, nil); err == nil {
  1082. t.Fatal("Container bind mounted illegal directory")
  1083. }
  1084. }
  1085. // Test that VolumesRW values are copied to the new container. Regression test for #1201
  1086. func TestVolumesFromReadonlyMount(t *testing.T) {
  1087. runtime := mkRuntime(t)
  1088. defer nuke(runtime)
  1089. container, err := NewBuilder(runtime).Create(
  1090. &Config{
  1091. Image: GetTestImage(runtime).ID,
  1092. Cmd: []string{"/bin/echo", "-n", "foobar"},
  1093. Volumes: map[string]struct{}{"/test": {}},
  1094. },
  1095. )
  1096. if err != nil {
  1097. t.Fatal(err)
  1098. }
  1099. defer runtime.Destroy(container)
  1100. _, err = container.Output()
  1101. if err != nil {
  1102. t.Fatal(err)
  1103. }
  1104. if !container.VolumesRW["/test"] {
  1105. t.Fail()
  1106. }
  1107. container2, err := NewBuilder(runtime).Create(
  1108. &Config{
  1109. Image: GetTestImage(runtime).ID,
  1110. Cmd: []string{"/bin/echo", "-n", "foobar"},
  1111. VolumesFrom: container.ID,
  1112. },
  1113. )
  1114. if err != nil {
  1115. t.Fatal(err)
  1116. }
  1117. defer runtime.Destroy(container2)
  1118. _, err = container2.Output()
  1119. if err != nil {
  1120. t.Fatal(err)
  1121. }
  1122. if container.Volumes["/test"] != container2.Volumes["/test"] {
  1123. t.Fail()
  1124. }
  1125. actual, exists := container2.VolumesRW["/test"]
  1126. if !exists {
  1127. t.Fail()
  1128. }
  1129. if container.VolumesRW["/test"] != actual {
  1130. t.Fail()
  1131. }
  1132. }
  1133. // Test that restarting a container with a volume does not create a new volume on restart. Regression test for #819.
  1134. func TestRestartWithVolumes(t *testing.T) {
  1135. runtime := mkRuntime(t)
  1136. defer nuke(runtime)
  1137. container, err := NewBuilder(runtime).Create(&Config{
  1138. Image: GetTestImage(runtime).ID,
  1139. Cmd: []string{"echo", "-n", "foobar"},
  1140. Volumes: map[string]struct{}{"/test": {}},
  1141. },
  1142. )
  1143. if err != nil {
  1144. t.Fatal(err)
  1145. }
  1146. defer runtime.Destroy(container)
  1147. for key := range container.Config.Volumes {
  1148. if key != "/test" {
  1149. t.Fail()
  1150. }
  1151. }
  1152. _, err = container.Output()
  1153. if err != nil {
  1154. t.Fatal(err)
  1155. }
  1156. expected := container.Volumes["/test"]
  1157. if expected == "" {
  1158. t.Fail()
  1159. }
  1160. // Run the container again to verify the volume path persists
  1161. _, err = container.Output()
  1162. if err != nil {
  1163. t.Fatal(err)
  1164. }
  1165. actual := container.Volumes["/test"]
  1166. if expected != actual {
  1167. t.Fatalf("Expected volume path: %s Actual path: %s", expected, actual)
  1168. }
  1169. }
  1170. func TestOnlyLoopbackExistsWhenUsingDisableNetworkOption(t *testing.T) {
  1171. runtime := mkRuntime(t)
  1172. defer nuke(runtime)
  1173. config, hc, _, err := ParseRun([]string{"-n=false", GetTestImage(runtime).ID, "ip", "addr", "show"}, nil)
  1174. if err != nil {
  1175. t.Fatal(err)
  1176. }
  1177. c, err := NewBuilder(runtime).Create(config)
  1178. if err != nil {
  1179. t.Fatal(err)
  1180. }
  1181. stdout, err := c.StdoutPipe()
  1182. if err != nil {
  1183. t.Fatal(err)
  1184. }
  1185. defer runtime.Destroy(c)
  1186. if err := c.Start(hc); err != nil {
  1187. t.Fatal(err)
  1188. }
  1189. c.WaitTimeout(500 * time.Millisecond)
  1190. c.Wait()
  1191. output, err := ioutil.ReadAll(stdout)
  1192. if err != nil {
  1193. t.Fatal(err)
  1194. }
  1195. interfaces := regexp.MustCompile(`(?m)^[0-9]+: [a-zA-Z0-9]+`).FindAllString(string(output), -1)
  1196. if len(interfaces) != 1 {
  1197. t.Fatalf("Wrong interface count in test container: expected [*: lo], got %s", interfaces)
  1198. }
  1199. if !strings.HasSuffix(interfaces[0], ": lo") {
  1200. t.Fatalf("Wrong interface in test container: expected [*: lo], got %s", interfaces)
  1201. }
  1202. }
  1203. func TestPrivilegedCanMknod(t *testing.T) {
  1204. runtime := mkRuntime(t)
  1205. defer nuke(runtime)
  1206. if output, _ := runContainer(runtime, []string{"-privileged", "_", "sh", "-c", "mknod /tmp/sda b 8 0 && echo ok"}, t); output != "ok\n" {
  1207. t.Fatal("Could not mknod into privileged container")
  1208. }
  1209. }
  1210. func TestPrivilegedCanMount(t *testing.T) {
  1211. runtime := mkRuntime(t)
  1212. defer nuke(runtime)
  1213. if output, _ := runContainer(runtime, []string{"-privileged", "_", "sh", "-c", "mount -t tmpfs none /tmp && echo ok"}, t); output != "ok\n" {
  1214. t.Fatal("Could not mount into privileged container")
  1215. }
  1216. }
  1217. func TestPrivilegedCannotMknod(t *testing.T) {
  1218. runtime := mkRuntime(t)
  1219. defer nuke(runtime)
  1220. if output, _ := runContainer(runtime, []string{"_", "sh", "-c", "mknod /tmp/sda b 8 0 || echo ok"}, t); output != "ok\n" {
  1221. t.Fatal("Could mknod into secure container")
  1222. }
  1223. }
  1224. func TestPrivilegedCannotMount(t *testing.T) {
  1225. runtime := mkRuntime(t)
  1226. defer nuke(runtime)
  1227. if output, _ := runContainer(runtime, []string{"_", "sh", "-c", "mount -t tmpfs none /tmp || echo ok"}, t); output != "ok\n" {
  1228. t.Fatal("Could mount into secure container")
  1229. }
  1230. }