container_test.go 29 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292
  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. }
  876. sort.Strings(goodEnv)
  877. if len(goodEnv) != len(actualEnv) {
  878. t.Fatalf("Wrong environment: should be %d variables, not: '%s'\n", len(goodEnv), strings.Join(actualEnv, ", "))
  879. }
  880. for i := range goodEnv {
  881. if actualEnv[i] != goodEnv[i] {
  882. t.Fatalf("Wrong environment variable: should be %s, not %s", goodEnv[i], actualEnv[i])
  883. }
  884. }
  885. }
  886. func TestEntrypoint(t *testing.T) {
  887. runtime := mkRuntime(t)
  888. defer nuke(runtime)
  889. container, err := NewBuilder(runtime).Create(
  890. &Config{
  891. Image: GetTestImage(runtime).ID,
  892. Entrypoint: []string{"/bin/echo"},
  893. Cmd: []string{"-n", "foobar"},
  894. },
  895. )
  896. if err != nil {
  897. t.Fatal(err)
  898. }
  899. defer runtime.Destroy(container)
  900. output, err := container.Output()
  901. if err != nil {
  902. t.Fatal(err)
  903. }
  904. if string(output) != "foobar" {
  905. t.Error(string(output))
  906. }
  907. }
  908. func grepFile(t *testing.T, path string, pattern string) {
  909. f, err := os.Open(path)
  910. if err != nil {
  911. t.Fatal(err)
  912. }
  913. defer f.Close()
  914. r := bufio.NewReader(f)
  915. var (
  916. line string
  917. )
  918. err = nil
  919. for err == nil {
  920. line, err = r.ReadString('\n')
  921. if strings.Contains(line, pattern) == true {
  922. return
  923. }
  924. }
  925. t.Fatalf("grepFile: pattern \"%s\" not found in \"%s\"", pattern, path)
  926. }
  927. func TestLXCConfig(t *testing.T) {
  928. runtime := mkRuntime(t)
  929. defer nuke(runtime)
  930. // Memory is allocated randomly for testing
  931. rand.Seed(time.Now().UTC().UnixNano())
  932. memMin := 33554432
  933. memMax := 536870912
  934. mem := memMin + rand.Intn(memMax-memMin)
  935. // CPU shares as well
  936. cpuMin := 100
  937. cpuMax := 10000
  938. cpu := cpuMin + rand.Intn(cpuMax-cpuMin)
  939. container, err := NewBuilder(runtime).Create(&Config{
  940. Image: GetTestImage(runtime).ID,
  941. Cmd: []string{"/bin/true"},
  942. Hostname: "foobar",
  943. Memory: int64(mem),
  944. CpuShares: int64(cpu),
  945. },
  946. )
  947. if err != nil {
  948. t.Fatal(err)
  949. }
  950. defer runtime.Destroy(container)
  951. container.generateLXCConfig()
  952. grepFile(t, container.lxcConfigPath(), "lxc.utsname = foobar")
  953. grepFile(t, container.lxcConfigPath(),
  954. fmt.Sprintf("lxc.cgroup.memory.limit_in_bytes = %d", mem))
  955. grepFile(t, container.lxcConfigPath(),
  956. fmt.Sprintf("lxc.cgroup.memory.memsw.limit_in_bytes = %d", mem*2))
  957. }
  958. func BenchmarkRunSequencial(b *testing.B) {
  959. runtime := mkRuntime(b)
  960. defer nuke(runtime)
  961. for i := 0; i < b.N; i++ {
  962. container, err := NewBuilder(runtime).Create(&Config{
  963. Image: GetTestImage(runtime).ID,
  964. Cmd: []string{"echo", "-n", "foo"},
  965. },
  966. )
  967. if err != nil {
  968. b.Fatal(err)
  969. }
  970. defer runtime.Destroy(container)
  971. output, err := container.Output()
  972. if err != nil {
  973. b.Fatal(err)
  974. }
  975. if string(output) != "foo" {
  976. b.Fatalf("Unexpected output: %s", output)
  977. }
  978. if err := runtime.Destroy(container); err != nil {
  979. b.Fatal(err)
  980. }
  981. }
  982. }
  983. func BenchmarkRunParallel(b *testing.B) {
  984. runtime := mkRuntime(b)
  985. defer nuke(runtime)
  986. var tasks []chan error
  987. for i := 0; i < b.N; i++ {
  988. complete := make(chan error)
  989. tasks = append(tasks, complete)
  990. go func(i int, complete chan error) {
  991. container, err := NewBuilder(runtime).Create(&Config{
  992. Image: GetTestImage(runtime).ID,
  993. Cmd: []string{"echo", "-n", "foo"},
  994. },
  995. )
  996. if err != nil {
  997. complete <- err
  998. return
  999. }
  1000. defer runtime.Destroy(container)
  1001. hostConfig := &HostConfig{}
  1002. if err := container.Start(hostConfig); err != nil {
  1003. complete <- err
  1004. return
  1005. }
  1006. if err := container.WaitTimeout(15 * time.Second); err != nil {
  1007. complete <- err
  1008. return
  1009. }
  1010. // if string(output) != "foo" {
  1011. // complete <- fmt.Errorf("Unexecpted output: %v", string(output))
  1012. // }
  1013. if err := runtime.Destroy(container); err != nil {
  1014. complete <- err
  1015. return
  1016. }
  1017. complete <- nil
  1018. }(i, complete)
  1019. }
  1020. var errors []error
  1021. for _, task := range tasks {
  1022. err := <-task
  1023. if err != nil {
  1024. errors = append(errors, err)
  1025. }
  1026. }
  1027. if len(errors) > 0 {
  1028. b.Fatal(errors)
  1029. }
  1030. }
  1031. func tempDir(t *testing.T) string {
  1032. tmpDir, err := ioutil.TempDir("", "docker-test")
  1033. if err != nil {
  1034. t.Fatal(err)
  1035. }
  1036. return tmpDir
  1037. }
  1038. func TestBindMounts(t *testing.T) {
  1039. r := mkRuntime(t)
  1040. defer nuke(r)
  1041. tmpDir := tempDir(t)
  1042. defer os.RemoveAll(tmpDir)
  1043. writeFile(path.Join(tmpDir, "touch-me"), "", t)
  1044. // Test reading from a read-only bind mount
  1045. stdout, _ := runContainer(r, []string{"-v", fmt.Sprintf("%s:/tmp:ro", tmpDir), "_", "ls", "/tmp"}, t)
  1046. if !strings.Contains(stdout, "touch-me") {
  1047. t.Fatal("Container failed to read from bind mount")
  1048. }
  1049. // test writing to bind mount
  1050. runContainer(r, []string{"-v", fmt.Sprintf("%s:/tmp:rw", tmpDir), "_", "touch", "/tmp/holla"}, t)
  1051. readFile(path.Join(tmpDir, "holla"), t) // Will fail if the file doesn't exist
  1052. // test mounting to an illegal destination directory
  1053. if _, err := runContainer(r, []string{"-v", fmt.Sprintf("%s:.", tmpDir), "ls", "."}, nil); err == nil {
  1054. t.Fatal("Container bind mounted illegal directory")
  1055. }
  1056. }
  1057. // Test that VolumesRW values are copied to the new container. Regression test for #1201
  1058. func TestVolumesFromReadonlyMount(t *testing.T) {
  1059. runtime := mkRuntime(t)
  1060. defer nuke(runtime)
  1061. container, err := NewBuilder(runtime).Create(
  1062. &Config{
  1063. Image: GetTestImage(runtime).ID,
  1064. Cmd: []string{"/bin/echo", "-n", "foobar"},
  1065. Volumes: map[string]struct{}{"/test": {}},
  1066. },
  1067. )
  1068. if err != nil {
  1069. t.Fatal(err)
  1070. }
  1071. defer runtime.Destroy(container)
  1072. _, err = container.Output()
  1073. if err != nil {
  1074. t.Fatal(err)
  1075. }
  1076. if !container.VolumesRW["/test"] {
  1077. t.Fail()
  1078. }
  1079. container2, err := NewBuilder(runtime).Create(
  1080. &Config{
  1081. Image: GetTestImage(runtime).ID,
  1082. Cmd: []string{"/bin/echo", "-n", "foobar"},
  1083. VolumesFrom: container.ID,
  1084. },
  1085. )
  1086. if err != nil {
  1087. t.Fatal(err)
  1088. }
  1089. defer runtime.Destroy(container2)
  1090. _, err = container2.Output()
  1091. if err != nil {
  1092. t.Fatal(err)
  1093. }
  1094. if container.Volumes["/test"] != container2.Volumes["/test"] {
  1095. t.Fail()
  1096. }
  1097. actual, exists := container2.VolumesRW["/test"]
  1098. if !exists {
  1099. t.Fail()
  1100. }
  1101. if container.VolumesRW["/test"] != actual {
  1102. t.Fail()
  1103. }
  1104. }
  1105. // Test that restarting a container with a volume does not create a new volume on restart. Regression test for #819.
  1106. func TestRestartWithVolumes(t *testing.T) {
  1107. runtime := mkRuntime(t)
  1108. defer nuke(runtime)
  1109. container, err := NewBuilder(runtime).Create(&Config{
  1110. Image: GetTestImage(runtime).ID,
  1111. Cmd: []string{"echo", "-n", "foobar"},
  1112. Volumes: map[string]struct{}{"/test": {}},
  1113. },
  1114. )
  1115. if err != nil {
  1116. t.Fatal(err)
  1117. }
  1118. defer runtime.Destroy(container)
  1119. for key := range container.Config.Volumes {
  1120. if key != "/test" {
  1121. t.Fail()
  1122. }
  1123. }
  1124. _, err = container.Output()
  1125. if err != nil {
  1126. t.Fatal(err)
  1127. }
  1128. expected := container.Volumes["/test"]
  1129. if expected == "" {
  1130. t.Fail()
  1131. }
  1132. // Run the container again to verify the volume path persists
  1133. _, err = container.Output()
  1134. if err != nil {
  1135. t.Fatal(err)
  1136. }
  1137. actual := container.Volumes["/test"]
  1138. if expected != actual {
  1139. t.Fatalf("Expected volume path: %s Actual path: %s", expected, actual)
  1140. }
  1141. }
  1142. func TestOnlyLoopbackExistsWhenUsingDisableNetworkOption(t *testing.T) {
  1143. runtime := mkRuntime(t)
  1144. defer nuke(runtime)
  1145. config, hc, _, err := ParseRun([]string{"-n=false", GetTestImage(runtime).ID, "ip", "addr", "show"}, nil)
  1146. if err != nil {
  1147. t.Fatal(err)
  1148. }
  1149. c, err := NewBuilder(runtime).Create(config)
  1150. if err != nil {
  1151. t.Fatal(err)
  1152. }
  1153. stdout, err := c.StdoutPipe()
  1154. if err != nil {
  1155. t.Fatal(err)
  1156. }
  1157. defer runtime.Destroy(c)
  1158. if err := c.Start(hc); err != nil {
  1159. t.Fatal(err)
  1160. }
  1161. c.WaitTimeout(500 * time.Millisecond)
  1162. c.Wait()
  1163. output, err := ioutil.ReadAll(stdout)
  1164. if err != nil {
  1165. t.Fatal(err)
  1166. }
  1167. interfaces := regexp.MustCompile(`(?m)^[0-9]+: [a-zA-Z0-9]+`).FindAllString(string(output), -1)
  1168. if len(interfaces) != 1 {
  1169. t.Fatalf("Wrong interface count in test container: expected [1: lo], got [%s]", interfaces)
  1170. }
  1171. if interfaces[0] != "1: lo" {
  1172. t.Fatalf("Wrong interface in test container: expected [1: lo], got [%s]", interfaces)
  1173. }
  1174. }