container_test.go 29 KB

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