container_test.go 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293
  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 containere
  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 containter should be able to be started")
  323. }
  324. // Try to avoid the timeoout 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{"tail", "-f", "/etc/resolv.conf"},
  370. User: "daemon",
  371. },
  372. )
  373. if err != nil {
  374. t.Fatal(err)
  375. }
  376. defer runtime.Destroy(container)
  377. if container.State.Running {
  378. t.Errorf("Container shouldn't be running")
  379. }
  380. hostConfig := &HostConfig{}
  381. if err := container.Start(hostConfig); err != nil {
  382. t.Fatal(err)
  383. }
  384. setTimeout(t, "Waiting for the container to be started timed out", 2*time.Second, func() {
  385. for !container.State.Running {
  386. time.Sleep(10 * time.Millisecond)
  387. }
  388. })
  389. // Even if the state is running, lets give some time to lxc to spawn the process
  390. container.WaitTimeout(500 * time.Millisecond)
  391. if err := container.Kill(); err != nil {
  392. t.Fatal(err)
  393. }
  394. if container.State.Running {
  395. t.Errorf("Container shouldn't be running")
  396. }
  397. container.Wait()
  398. if container.State.Running {
  399. t.Errorf("Container shouldn't be running")
  400. }
  401. // Try stopping twice
  402. if err := container.Kill(); err != nil {
  403. t.Fatal(err)
  404. }
  405. }
  406. // Test that creating a container with a volume doesn't crash. Regression test for #995.
  407. func TestCreateVolume(t *testing.T) {
  408. runtime := mkRuntime(t)
  409. defer nuke(runtime)
  410. config, hc, _, err := ParseRun([]string{"-v", "/var/lib/data", GetTestImage(runtime).ID, "echo", "hello", "world"}, nil)
  411. if err != nil {
  412. t.Fatal(err)
  413. }
  414. c, err := NewBuilder(runtime).Create(config)
  415. if err != nil {
  416. t.Fatal(err)
  417. }
  418. defer runtime.Destroy(c)
  419. if err := c.Start(hc); err != nil {
  420. t.Fatal(err)
  421. }
  422. c.WaitTimeout(500 * time.Millisecond)
  423. c.Wait()
  424. }
  425. func TestKill(t *testing.T) {
  426. runtime := mkRuntime(t)
  427. defer nuke(runtime)
  428. container, err := NewBuilder(runtime).Create(&Config{
  429. Image: GetTestImage(runtime).ID,
  430. Cmd: []string{"sleep", "2"},
  431. },
  432. )
  433. if err != nil {
  434. t.Fatal(err)
  435. }
  436. defer runtime.Destroy(container)
  437. if container.State.Running {
  438. t.Errorf("Container shouldn't be running")
  439. }
  440. hostConfig := &HostConfig{}
  441. if err := container.Start(hostConfig); err != nil {
  442. t.Fatal(err)
  443. }
  444. // Give some time to lxc to spawn the process
  445. container.WaitTimeout(500 * time.Millisecond)
  446. if !container.State.Running {
  447. t.Errorf("Container should be running")
  448. }
  449. if err := container.Kill(); err != nil {
  450. t.Fatal(err)
  451. }
  452. if container.State.Running {
  453. t.Errorf("Container shouldn't be running")
  454. }
  455. container.Wait()
  456. if container.State.Running {
  457. t.Errorf("Container shouldn't be running")
  458. }
  459. // Try stopping twice
  460. if err := container.Kill(); err != nil {
  461. t.Fatal(err)
  462. }
  463. }
  464. func TestExitCode(t *testing.T) {
  465. runtime := mkRuntime(t)
  466. defer nuke(runtime)
  467. builder := NewBuilder(runtime)
  468. trueContainer, err := builder.Create(&Config{
  469. Image: GetTestImage(runtime).ID,
  470. Cmd: []string{"/bin/true", ""},
  471. })
  472. if err != nil {
  473. t.Fatal(err)
  474. }
  475. defer runtime.Destroy(trueContainer)
  476. if err := trueContainer.Run(); err != nil {
  477. t.Fatal(err)
  478. }
  479. if trueContainer.State.ExitCode != 0 {
  480. t.Errorf("Unexpected exit code %d (expected 0)", trueContainer.State.ExitCode)
  481. }
  482. falseContainer, err := builder.Create(&Config{
  483. Image: GetTestImage(runtime).ID,
  484. Cmd: []string{"/bin/false", ""},
  485. })
  486. if err != nil {
  487. t.Fatal(err)
  488. }
  489. defer runtime.Destroy(falseContainer)
  490. if err := falseContainer.Run(); err != nil {
  491. t.Fatal(err)
  492. }
  493. if falseContainer.State.ExitCode != 1 {
  494. t.Errorf("Unexpected exit code %d (expected 1)", falseContainer.State.ExitCode)
  495. }
  496. }
  497. func TestRestart(t *testing.T) {
  498. runtime := mkRuntime(t)
  499. defer nuke(runtime)
  500. container, err := NewBuilder(runtime).Create(&Config{
  501. Image: GetTestImage(runtime).ID,
  502. Cmd: []string{"echo", "-n", "foobar"},
  503. },
  504. )
  505. if err != nil {
  506. t.Fatal(err)
  507. }
  508. defer runtime.Destroy(container)
  509. output, err := container.Output()
  510. if err != nil {
  511. t.Fatal(err)
  512. }
  513. if string(output) != "foobar" {
  514. t.Error(string(output))
  515. }
  516. // Run the container again and check the output
  517. output, err = container.Output()
  518. if err != nil {
  519. t.Fatal(err)
  520. }
  521. if string(output) != "foobar" {
  522. t.Error(string(output))
  523. }
  524. }
  525. func TestRestartStdin(t *testing.T) {
  526. runtime := mkRuntime(t)
  527. defer nuke(runtime)
  528. container, err := NewBuilder(runtime).Create(&Config{
  529. Image: GetTestImage(runtime).ID,
  530. Cmd: []string{"cat"},
  531. OpenStdin: true,
  532. },
  533. )
  534. if err != nil {
  535. t.Fatal(err)
  536. }
  537. defer runtime.Destroy(container)
  538. stdin, err := container.StdinPipe()
  539. if err != nil {
  540. t.Fatal(err)
  541. }
  542. stdout, err := container.StdoutPipe()
  543. if err != nil {
  544. t.Fatal(err)
  545. }
  546. hostConfig := &HostConfig{}
  547. if err := container.Start(hostConfig); err != nil {
  548. t.Fatal(err)
  549. }
  550. if _, err := io.WriteString(stdin, "hello world"); err != nil {
  551. t.Fatal(err)
  552. }
  553. if err := stdin.Close(); err != nil {
  554. t.Fatal(err)
  555. }
  556. container.Wait()
  557. output, err := ioutil.ReadAll(stdout)
  558. if err != nil {
  559. t.Fatal(err)
  560. }
  561. if err := stdout.Close(); err != nil {
  562. t.Fatal(err)
  563. }
  564. if string(output) != "hello world" {
  565. t.Fatalf("Unexpected output. Expected %s, received: %s", "hello world", string(output))
  566. }
  567. // Restart and try again
  568. stdin, err = container.StdinPipe()
  569. if err != nil {
  570. t.Fatal(err)
  571. }
  572. stdout, err = container.StdoutPipe()
  573. if err != nil {
  574. t.Fatal(err)
  575. }
  576. if err := container.Start(hostConfig); err != nil {
  577. t.Fatal(err)
  578. }
  579. if _, err := io.WriteString(stdin, "hello world #2"); err != nil {
  580. t.Fatal(err)
  581. }
  582. if err := stdin.Close(); err != nil {
  583. t.Fatal(err)
  584. }
  585. container.Wait()
  586. output, err = ioutil.ReadAll(stdout)
  587. if err != nil {
  588. t.Fatal(err)
  589. }
  590. if err := stdout.Close(); err != nil {
  591. t.Fatal(err)
  592. }
  593. if string(output) != "hello world #2" {
  594. t.Fatalf("Unexpected output. Expected %s, received: %s", "hello world #2", string(output))
  595. }
  596. }
  597. func TestUser(t *testing.T) {
  598. runtime := mkRuntime(t)
  599. defer nuke(runtime)
  600. builder := NewBuilder(runtime)
  601. // Default user must be root
  602. container, err := builder.Create(&Config{
  603. Image: GetTestImage(runtime).ID,
  604. Cmd: []string{"id"},
  605. },
  606. )
  607. if err != nil {
  608. t.Fatal(err)
  609. }
  610. defer runtime.Destroy(container)
  611. output, err := container.Output()
  612. if err != nil {
  613. t.Fatal(err)
  614. }
  615. if !strings.Contains(string(output), "uid=0(root) gid=0(root)") {
  616. t.Error(string(output))
  617. }
  618. // Set a username
  619. container, err = builder.Create(&Config{
  620. Image: GetTestImage(runtime).ID,
  621. Cmd: []string{"id"},
  622. User: "root",
  623. },
  624. )
  625. if err != nil {
  626. t.Fatal(err)
  627. }
  628. defer runtime.Destroy(container)
  629. output, err = container.Output()
  630. if err != nil || container.State.ExitCode != 0 {
  631. t.Fatal(err)
  632. }
  633. if !strings.Contains(string(output), "uid=0(root) gid=0(root)") {
  634. t.Error(string(output))
  635. }
  636. // Set a UID
  637. container, err = builder.Create(&Config{
  638. Image: GetTestImage(runtime).ID,
  639. Cmd: []string{"id"},
  640. User: "0",
  641. },
  642. )
  643. if err != nil || container.State.ExitCode != 0 {
  644. t.Fatal(err)
  645. }
  646. defer runtime.Destroy(container)
  647. output, err = container.Output()
  648. if err != nil || container.State.ExitCode != 0 {
  649. t.Fatal(err)
  650. }
  651. if !strings.Contains(string(output), "uid=0(root) gid=0(root)") {
  652. t.Error(string(output))
  653. }
  654. // Set a different user by uid
  655. container, err = builder.Create(&Config{
  656. Image: GetTestImage(runtime).ID,
  657. Cmd: []string{"id"},
  658. User: "1",
  659. },
  660. )
  661. if err != nil {
  662. t.Fatal(err)
  663. }
  664. defer runtime.Destroy(container)
  665. output, err = container.Output()
  666. if err != nil {
  667. t.Fatal(err)
  668. } else if container.State.ExitCode != 0 {
  669. t.Fatalf("Container exit code is invalid: %d\nOutput:\n%s\n", container.State.ExitCode, output)
  670. }
  671. if !strings.Contains(string(output), "uid=1(daemon) gid=1(daemon)") {
  672. t.Error(string(output))
  673. }
  674. // Set a different user by username
  675. container, err = builder.Create(&Config{
  676. Image: GetTestImage(runtime).ID,
  677. Cmd: []string{"id"},
  678. User: "daemon",
  679. },
  680. )
  681. if err != nil {
  682. t.Fatal(err)
  683. }
  684. defer runtime.Destroy(container)
  685. output, err = container.Output()
  686. if err != nil || container.State.ExitCode != 0 {
  687. t.Fatal(err)
  688. }
  689. if !strings.Contains(string(output), "uid=1(daemon) gid=1(daemon)") {
  690. t.Error(string(output))
  691. }
  692. // Test an wrong username
  693. container, err = builder.Create(&Config{
  694. Image: GetTestImage(runtime).ID,
  695. Cmd: []string{"id"},
  696. User: "unkownuser",
  697. },
  698. )
  699. if err != nil {
  700. t.Fatal(err)
  701. }
  702. defer runtime.Destroy(container)
  703. output, err = container.Output()
  704. if container.State.ExitCode == 0 {
  705. t.Fatal("Starting container with wrong uid should fail but it passed.")
  706. }
  707. }
  708. func TestMultipleContainers(t *testing.T) {
  709. runtime := mkRuntime(t)
  710. defer nuke(runtime)
  711. builder := NewBuilder(runtime)
  712. container1, err := builder.Create(&Config{
  713. Image: GetTestImage(runtime).ID,
  714. Cmd: []string{"sleep", "2"},
  715. },
  716. )
  717. if err != nil {
  718. t.Fatal(err)
  719. }
  720. defer runtime.Destroy(container1)
  721. container2, err := builder.Create(&Config{
  722. Image: GetTestImage(runtime).ID,
  723. Cmd: []string{"sleep", "2"},
  724. },
  725. )
  726. if err != nil {
  727. t.Fatal(err)
  728. }
  729. defer runtime.Destroy(container2)
  730. // Start both containers
  731. hostConfig := &HostConfig{}
  732. if err := container1.Start(hostConfig); err != nil {
  733. t.Fatal(err)
  734. }
  735. if err := container2.Start(hostConfig); err != nil {
  736. t.Fatal(err)
  737. }
  738. // Make sure they are running before trying to kill them
  739. container1.WaitTimeout(250 * time.Millisecond)
  740. container2.WaitTimeout(250 * time.Millisecond)
  741. // If we are here, both containers should be running
  742. if !container1.State.Running {
  743. t.Fatal("Container not running")
  744. }
  745. if !container2.State.Running {
  746. t.Fatal("Container not running")
  747. }
  748. // Kill them
  749. if err := container1.Kill(); err != nil {
  750. t.Fatal(err)
  751. }
  752. if err := container2.Kill(); err != nil {
  753. t.Fatal(err)
  754. }
  755. }
  756. func TestStdin(t *testing.T) {
  757. runtime := mkRuntime(t)
  758. defer nuke(runtime)
  759. container, err := NewBuilder(runtime).Create(&Config{
  760. Image: GetTestImage(runtime).ID,
  761. Cmd: []string{"cat"},
  762. OpenStdin: true,
  763. },
  764. )
  765. if err != nil {
  766. t.Fatal(err)
  767. }
  768. defer runtime.Destroy(container)
  769. stdin, err := container.StdinPipe()
  770. if err != nil {
  771. t.Fatal(err)
  772. }
  773. stdout, err := container.StdoutPipe()
  774. if err != nil {
  775. t.Fatal(err)
  776. }
  777. hostConfig := &HostConfig{}
  778. if err := container.Start(hostConfig); err != nil {
  779. t.Fatal(err)
  780. }
  781. defer stdin.Close()
  782. defer stdout.Close()
  783. if _, err := io.WriteString(stdin, "hello world"); err != nil {
  784. t.Fatal(err)
  785. }
  786. if err := stdin.Close(); err != nil {
  787. t.Fatal(err)
  788. }
  789. container.Wait()
  790. output, err := ioutil.ReadAll(stdout)
  791. if err != nil {
  792. t.Fatal(err)
  793. }
  794. if string(output) != "hello world" {
  795. t.Fatalf("Unexpected output. Expected %s, received: %s", "hello world", string(output))
  796. }
  797. }
  798. func TestTty(t *testing.T) {
  799. runtime := mkRuntime(t)
  800. defer nuke(runtime)
  801. container, err := NewBuilder(runtime).Create(&Config{
  802. Image: GetTestImage(runtime).ID,
  803. Cmd: []string{"cat"},
  804. OpenStdin: true,
  805. },
  806. )
  807. if err != nil {
  808. t.Fatal(err)
  809. }
  810. defer runtime.Destroy(container)
  811. stdin, err := container.StdinPipe()
  812. if err != nil {
  813. t.Fatal(err)
  814. }
  815. stdout, err := container.StdoutPipe()
  816. if err != nil {
  817. t.Fatal(err)
  818. }
  819. hostConfig := &HostConfig{}
  820. if err := container.Start(hostConfig); err != nil {
  821. t.Fatal(err)
  822. }
  823. defer stdin.Close()
  824. defer stdout.Close()
  825. if _, err := io.WriteString(stdin, "hello world"); err != nil {
  826. t.Fatal(err)
  827. }
  828. if err := stdin.Close(); err != nil {
  829. t.Fatal(err)
  830. }
  831. container.Wait()
  832. output, err := ioutil.ReadAll(stdout)
  833. if err != nil {
  834. t.Fatal(err)
  835. }
  836. if string(output) != "hello world" {
  837. t.Fatalf("Unexpected output. Expected %s, received: %s", "hello world", string(output))
  838. }
  839. }
  840. func TestEnv(t *testing.T) {
  841. runtime := mkRuntime(t)
  842. defer nuke(runtime)
  843. container, err := NewBuilder(runtime).Create(&Config{
  844. Image: GetTestImage(runtime).ID,
  845. Cmd: []string{"env"},
  846. },
  847. )
  848. if err != nil {
  849. t.Fatal(err)
  850. }
  851. defer runtime.Destroy(container)
  852. stdout, err := container.StdoutPipe()
  853. if err != nil {
  854. t.Fatal(err)
  855. }
  856. defer stdout.Close()
  857. hostConfig := &HostConfig{}
  858. if err := container.Start(hostConfig); err != nil {
  859. t.Fatal(err)
  860. }
  861. container.Wait()
  862. output, err := ioutil.ReadAll(stdout)
  863. if err != nil {
  864. t.Fatal(err)
  865. }
  866. actualEnv := strings.Split(string(output), "\n")
  867. if actualEnv[len(actualEnv)-1] == "" {
  868. actualEnv = actualEnv[:len(actualEnv)-1]
  869. }
  870. sort.Strings(actualEnv)
  871. goodEnv := []string{
  872. "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
  873. "HOME=/",
  874. "container=lxc",
  875. "HOSTNAME=" + container.ShortID(),
  876. }
  877. sort.Strings(goodEnv)
  878. if len(goodEnv) != len(actualEnv) {
  879. t.Fatalf("Wrong environment: should be %d variables, not: '%s'\n", len(goodEnv), strings.Join(actualEnv, ", "))
  880. }
  881. for i := range goodEnv {
  882. if actualEnv[i] != goodEnv[i] {
  883. t.Fatalf("Wrong environment variable: should be %s, not %s", goodEnv[i], actualEnv[i])
  884. }
  885. }
  886. }
  887. func TestEntrypoint(t *testing.T) {
  888. runtime := mkRuntime(t)
  889. defer nuke(runtime)
  890. container, err := NewBuilder(runtime).Create(
  891. &Config{
  892. Image: GetTestImage(runtime).ID,
  893. Entrypoint: []string{"/bin/echo"},
  894. Cmd: []string{"-n", "foobar"},
  895. },
  896. )
  897. if err != nil {
  898. t.Fatal(err)
  899. }
  900. defer runtime.Destroy(container)
  901. output, err := container.Output()
  902. if err != nil {
  903. t.Fatal(err)
  904. }
  905. if string(output) != "foobar" {
  906. t.Error(string(output))
  907. }
  908. }
  909. func grepFile(t *testing.T, path string, pattern string) {
  910. f, err := os.Open(path)
  911. if err != nil {
  912. t.Fatal(err)
  913. }
  914. defer f.Close()
  915. r := bufio.NewReader(f)
  916. var (
  917. line string
  918. )
  919. err = nil
  920. for err == nil {
  921. line, err = r.ReadString('\n')
  922. if strings.Contains(line, pattern) == true {
  923. return
  924. }
  925. }
  926. t.Fatalf("grepFile: pattern \"%s\" not found in \"%s\"", pattern, path)
  927. }
  928. func TestLXCConfig(t *testing.T) {
  929. runtime := mkRuntime(t)
  930. defer nuke(runtime)
  931. // Memory is allocated randomly for testing
  932. rand.Seed(time.Now().UTC().UnixNano())
  933. memMin := 33554432
  934. memMax := 536870912
  935. mem := memMin + rand.Intn(memMax-memMin)
  936. // CPU shares as well
  937. cpuMin := 100
  938. cpuMax := 10000
  939. cpu := cpuMin + rand.Intn(cpuMax-cpuMin)
  940. container, err := NewBuilder(runtime).Create(&Config{
  941. Image: GetTestImage(runtime).ID,
  942. Cmd: []string{"/bin/true"},
  943. Hostname: "foobar",
  944. Memory: int64(mem),
  945. CpuShares: int64(cpu),
  946. },
  947. )
  948. if err != nil {
  949. t.Fatal(err)
  950. }
  951. defer runtime.Destroy(container)
  952. container.generateLXCConfig()
  953. grepFile(t, container.lxcConfigPath(), "lxc.utsname = foobar")
  954. grepFile(t, container.lxcConfigPath(),
  955. fmt.Sprintf("lxc.cgroup.memory.limit_in_bytes = %d", mem))
  956. grepFile(t, container.lxcConfigPath(),
  957. fmt.Sprintf("lxc.cgroup.memory.memsw.limit_in_bytes = %d", mem*2))
  958. }
  959. func BenchmarkRunSequencial(b *testing.B) {
  960. runtime := mkRuntime(b)
  961. defer nuke(runtime)
  962. for i := 0; i < b.N; i++ {
  963. container, err := NewBuilder(runtime).Create(&Config{
  964. Image: GetTestImage(runtime).ID,
  965. Cmd: []string{"echo", "-n", "foo"},
  966. },
  967. )
  968. if err != nil {
  969. b.Fatal(err)
  970. }
  971. defer runtime.Destroy(container)
  972. output, err := container.Output()
  973. if err != nil {
  974. b.Fatal(err)
  975. }
  976. if string(output) != "foo" {
  977. b.Fatalf("Unexpected output: %s", output)
  978. }
  979. if err := runtime.Destroy(container); err != nil {
  980. b.Fatal(err)
  981. }
  982. }
  983. }
  984. func BenchmarkRunParallel(b *testing.B) {
  985. runtime := mkRuntime(b)
  986. defer nuke(runtime)
  987. var tasks []chan error
  988. for i := 0; i < b.N; i++ {
  989. complete := make(chan error)
  990. tasks = append(tasks, complete)
  991. go func(i int, complete chan error) {
  992. container, err := NewBuilder(runtime).Create(&Config{
  993. Image: GetTestImage(runtime).ID,
  994. Cmd: []string{"echo", "-n", "foo"},
  995. },
  996. )
  997. if err != nil {
  998. complete <- err
  999. return
  1000. }
  1001. defer runtime.Destroy(container)
  1002. hostConfig := &HostConfig{}
  1003. if err := container.Start(hostConfig); err != nil {
  1004. complete <- err
  1005. return
  1006. }
  1007. if err := container.WaitTimeout(15 * time.Second); err != nil {
  1008. complete <- err
  1009. return
  1010. }
  1011. // if string(output) != "foo" {
  1012. // complete <- fmt.Errorf("Unexecpted output: %v", string(output))
  1013. // }
  1014. if err := runtime.Destroy(container); err != nil {
  1015. complete <- err
  1016. return
  1017. }
  1018. complete <- nil
  1019. }(i, complete)
  1020. }
  1021. var errors []error
  1022. for _, task := range tasks {
  1023. err := <-task
  1024. if err != nil {
  1025. errors = append(errors, err)
  1026. }
  1027. }
  1028. if len(errors) > 0 {
  1029. b.Fatal(errors)
  1030. }
  1031. }
  1032. func tempDir(t *testing.T) string {
  1033. tmpDir, err := ioutil.TempDir("", "docker-test")
  1034. if err != nil {
  1035. t.Fatal(err)
  1036. }
  1037. return tmpDir
  1038. }
  1039. func TestBindMounts(t *testing.T) {
  1040. r := mkRuntime(t)
  1041. defer nuke(r)
  1042. tmpDir := tempDir(t)
  1043. defer os.RemoveAll(tmpDir)
  1044. writeFile(path.Join(tmpDir, "touch-me"), "", t)
  1045. // Test reading from a read-only bind mount
  1046. stdout, _ := runContainer(r, []string{"-v", fmt.Sprintf("%s:/tmp:ro", tmpDir), "_", "ls", "/tmp"}, t)
  1047. if !strings.Contains(stdout, "touch-me") {
  1048. t.Fatal("Container failed to read from bind mount")
  1049. }
  1050. // test writing to bind mount
  1051. runContainer(r, []string{"-v", fmt.Sprintf("%s:/tmp:rw", tmpDir), "_", "touch", "/tmp/holla"}, t)
  1052. readFile(path.Join(tmpDir, "holla"), t) // Will fail if the file doesn't exist
  1053. // test mounting to an illegal destination directory
  1054. if _, err := runContainer(r, []string{"-v", fmt.Sprintf("%s:.", tmpDir), "ls", "."}, nil); err == nil {
  1055. t.Fatal("Container bind mounted illegal directory")
  1056. }
  1057. }
  1058. // Test that VolumesRW values are copied to the new container. Regression test for #1201
  1059. func TestVolumesFromReadonlyMount(t *testing.T) {
  1060. runtime := mkRuntime(t)
  1061. defer nuke(runtime)
  1062. container, err := NewBuilder(runtime).Create(
  1063. &Config{
  1064. Image: GetTestImage(runtime).ID,
  1065. Cmd: []string{"/bin/echo", "-n", "foobar"},
  1066. Volumes: map[string]struct{}{"/test": {}},
  1067. },
  1068. )
  1069. if err != nil {
  1070. t.Fatal(err)
  1071. }
  1072. defer runtime.Destroy(container)
  1073. _, err = container.Output()
  1074. if err != nil {
  1075. t.Fatal(err)
  1076. }
  1077. if !container.VolumesRW["/test"] {
  1078. t.Fail()
  1079. }
  1080. container2, err := NewBuilder(runtime).Create(
  1081. &Config{
  1082. Image: GetTestImage(runtime).ID,
  1083. Cmd: []string{"/bin/echo", "-n", "foobar"},
  1084. VolumesFrom: container.ID,
  1085. },
  1086. )
  1087. if err != nil {
  1088. t.Fatal(err)
  1089. }
  1090. defer runtime.Destroy(container2)
  1091. _, err = container2.Output()
  1092. if err != nil {
  1093. t.Fatal(err)
  1094. }
  1095. if container.Volumes["/test"] != container2.Volumes["/test"] {
  1096. t.Fail()
  1097. }
  1098. actual, exists := container2.VolumesRW["/test"]
  1099. if !exists {
  1100. t.Fail()
  1101. }
  1102. if container.VolumesRW["/test"] != actual {
  1103. t.Fail()
  1104. }
  1105. }
  1106. // Test that restarting a container with a volume does not create a new volume on restart. Regression test for #819.
  1107. func TestRestartWithVolumes(t *testing.T) {
  1108. runtime := mkRuntime(t)
  1109. defer nuke(runtime)
  1110. container, err := NewBuilder(runtime).Create(&Config{
  1111. Image: GetTestImage(runtime).ID,
  1112. Cmd: []string{"echo", "-n", "foobar"},
  1113. Volumes: map[string]struct{}{"/test": {}},
  1114. },
  1115. )
  1116. if err != nil {
  1117. t.Fatal(err)
  1118. }
  1119. defer runtime.Destroy(container)
  1120. for key := range container.Config.Volumes {
  1121. if key != "/test" {
  1122. t.Fail()
  1123. }
  1124. }
  1125. _, err = container.Output()
  1126. if err != nil {
  1127. t.Fatal(err)
  1128. }
  1129. expected := container.Volumes["/test"]
  1130. if expected == "" {
  1131. t.Fail()
  1132. }
  1133. // Run the container again to verify the volume path persists
  1134. _, err = container.Output()
  1135. if err != nil {
  1136. t.Fatal(err)
  1137. }
  1138. actual := container.Volumes["/test"]
  1139. if expected != actual {
  1140. t.Fatalf("Expected volume path: %s Actual path: %s", expected, actual)
  1141. }
  1142. }
  1143. func TestOnlyLoopbackExistsWhenUsingDisableNetworkOption(t *testing.T) {
  1144. runtime := mkRuntime(t)
  1145. defer nuke(runtime)
  1146. config, hc, _, err := ParseRun([]string{"-n=false", GetTestImage(runtime).ID, "ip", "addr", "show"}, nil)
  1147. if err != nil {
  1148. t.Fatal(err)
  1149. }
  1150. c, err := NewBuilder(runtime).Create(config)
  1151. if err != nil {
  1152. t.Fatal(err)
  1153. }
  1154. stdout, err := c.StdoutPipe()
  1155. if err != nil {
  1156. t.Fatal(err)
  1157. }
  1158. defer runtime.Destroy(c)
  1159. if err := c.Start(hc); err != nil {
  1160. t.Fatal(err)
  1161. }
  1162. c.WaitTimeout(500 * time.Millisecond)
  1163. c.Wait()
  1164. output, err := ioutil.ReadAll(stdout)
  1165. if err != nil {
  1166. t.Fatal(err)
  1167. }
  1168. interfaces := regexp.MustCompile(`(?m)^[0-9]+: [a-zA-Z0-9]+`).FindAllString(string(output), -1)
  1169. if len(interfaces) != 1 {
  1170. t.Fatalf("Wrong interface count in test container: expected [1: lo], got [%s]", interfaces)
  1171. }
  1172. if interfaces[0] != "1: lo" {
  1173. t.Fatalf("Wrong interface in test container: expected [1: lo], got [%s]", interfaces)
  1174. }
  1175. }