container_test.go 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596
  1. package docker
  2. import (
  3. "fmt"
  4. "io"
  5. "io/ioutil"
  6. "strings"
  7. "testing"
  8. "time"
  9. )
  10. func TestStart(t *testing.T) {
  11. docker, err := newTestDocker()
  12. if err != nil {
  13. t.Fatal(err)
  14. }
  15. container, err := docker.Create(
  16. "start_test",
  17. "ls",
  18. []string{"-al"},
  19. []string{testLayerPath},
  20. &Config{
  21. Ram: 33554432,
  22. },
  23. )
  24. if err != nil {
  25. t.Fatal(err)
  26. }
  27. defer docker.Destroy(container)
  28. if container.State.Running {
  29. t.Errorf("Container shouldn't be running")
  30. }
  31. if err := container.Start(); err != nil {
  32. t.Fatal(err)
  33. }
  34. container.Wait()
  35. if container.State.Running {
  36. t.Errorf("Container shouldn't be running")
  37. }
  38. // We should be able to call Wait again
  39. container.Wait()
  40. if container.State.Running {
  41. t.Errorf("Container shouldn't be running")
  42. }
  43. }
  44. func TestRun(t *testing.T) {
  45. docker, err := newTestDocker()
  46. if err != nil {
  47. t.Fatal(err)
  48. }
  49. container, err := docker.Create(
  50. "run_test",
  51. "ls",
  52. []string{"-al"},
  53. []string{testLayerPath},
  54. &Config{
  55. Ram: 33554432,
  56. },
  57. )
  58. if err != nil {
  59. t.Fatal(err)
  60. }
  61. defer docker.Destroy(container)
  62. if container.State.Running {
  63. t.Errorf("Container shouldn't be running")
  64. }
  65. if err := container.Run(); err != nil {
  66. t.Fatal(err)
  67. }
  68. if container.State.Running {
  69. t.Errorf("Container shouldn't be running")
  70. }
  71. }
  72. func TestOutput(t *testing.T) {
  73. docker, err := newTestDocker()
  74. if err != nil {
  75. t.Fatal(err)
  76. }
  77. container, err := docker.Create(
  78. "output_test",
  79. "echo",
  80. []string{"-n", "foobar"},
  81. []string{testLayerPath},
  82. &Config{},
  83. )
  84. if err != nil {
  85. t.Fatal(err)
  86. }
  87. defer docker.Destroy(container)
  88. output, err := container.Output()
  89. if err != nil {
  90. t.Fatal(err)
  91. }
  92. if string(output) != "foobar" {
  93. t.Error(string(output))
  94. }
  95. }
  96. func TestKill(t *testing.T) {
  97. docker, err := newTestDocker()
  98. if err != nil {
  99. t.Fatal(err)
  100. }
  101. container, err := docker.Create(
  102. "stop_test",
  103. "cat",
  104. []string{"/dev/zero"},
  105. []string{testLayerPath},
  106. &Config{},
  107. )
  108. if err != nil {
  109. t.Fatal(err)
  110. }
  111. defer docker.Destroy(container)
  112. if container.State.Running {
  113. t.Errorf("Container shouldn't be running")
  114. }
  115. if err := container.Start(); err != nil {
  116. t.Fatal(err)
  117. }
  118. if !container.State.Running {
  119. t.Errorf("Container should be running")
  120. }
  121. if err := container.Kill(); err != nil {
  122. t.Fatal(err)
  123. }
  124. if container.State.Running {
  125. t.Errorf("Container shouldn't be running")
  126. }
  127. container.Wait()
  128. if container.State.Running {
  129. t.Errorf("Container shouldn't be running")
  130. }
  131. // Try stopping twice
  132. if err := container.Kill(); err != nil {
  133. t.Fatal(err)
  134. }
  135. }
  136. func TestExitCode(t *testing.T) {
  137. docker, err := newTestDocker()
  138. if err != nil {
  139. t.Fatal(err)
  140. }
  141. trueContainer, err := docker.Create(
  142. "exit_test_1",
  143. "/bin/true",
  144. []string{""},
  145. []string{testLayerPath},
  146. &Config{},
  147. )
  148. if err != nil {
  149. t.Fatal(err)
  150. }
  151. defer docker.Destroy(trueContainer)
  152. if err := trueContainer.Run(); err != nil {
  153. t.Fatal(err)
  154. }
  155. falseContainer, err := docker.Create(
  156. "exit_test_2",
  157. "/bin/false",
  158. []string{""},
  159. []string{testLayerPath},
  160. &Config{},
  161. )
  162. if err != nil {
  163. t.Fatal(err)
  164. }
  165. defer docker.Destroy(falseContainer)
  166. if err := falseContainer.Run(); err != nil {
  167. t.Fatal(err)
  168. }
  169. if trueContainer.State.ExitCode != 0 {
  170. t.Errorf("Unexpected exit code %v", trueContainer.State.ExitCode)
  171. }
  172. if falseContainer.State.ExitCode != 1 {
  173. t.Errorf("Unexpected exit code %v", falseContainer.State.ExitCode)
  174. }
  175. }
  176. func TestRestart(t *testing.T) {
  177. docker, err := newTestDocker()
  178. if err != nil {
  179. t.Fatal(err)
  180. }
  181. container, err := docker.Create(
  182. "restart_test",
  183. "echo",
  184. []string{"-n", "foobar"},
  185. []string{testLayerPath},
  186. &Config{},
  187. )
  188. if err != nil {
  189. t.Fatal(err)
  190. }
  191. defer docker.Destroy(container)
  192. output, err := container.Output()
  193. if err != nil {
  194. t.Fatal(err)
  195. }
  196. if string(output) != "foobar" {
  197. t.Error(string(output))
  198. }
  199. // Run the container again and check the output
  200. output, err = container.Output()
  201. if err != nil {
  202. t.Fatal(err)
  203. }
  204. if string(output) != "foobar" {
  205. t.Error(string(output))
  206. }
  207. }
  208. func TestRestartStdin(t *testing.T) {
  209. docker, err := newTestDocker()
  210. if err != nil {
  211. t.Fatal(err)
  212. }
  213. container, err := docker.Create(
  214. "restart_stdin_test",
  215. "cat",
  216. []string{},
  217. []string{testLayerPath},
  218. &Config{
  219. OpenStdin: true,
  220. },
  221. )
  222. if err != nil {
  223. t.Fatal(err)
  224. }
  225. defer docker.Destroy(container)
  226. stdin, err := container.StdinPipe()
  227. stdout, err := container.StdoutPipe()
  228. if err := container.Start(); err != nil {
  229. t.Fatal(err)
  230. }
  231. io.WriteString(stdin, "hello world")
  232. stdin.Close()
  233. container.Wait()
  234. output, err := ioutil.ReadAll(stdout)
  235. stdout.Close()
  236. if string(output) != "hello world" {
  237. t.Fatal(string(output))
  238. }
  239. // Restart and try again
  240. stdin, err = container.StdinPipe()
  241. stdout, err = container.StdoutPipe()
  242. if err := container.Start(); err != nil {
  243. t.Fatal(err)
  244. }
  245. io.WriteString(stdin, "hello world #2")
  246. stdin.Close()
  247. container.Wait()
  248. output, err = ioutil.ReadAll(stdout)
  249. stdout.Close()
  250. if string(output) != "hello world #2" {
  251. t.Fatal(string(output))
  252. }
  253. }
  254. func TestUser(t *testing.T) {
  255. docker, err := newTestDocker()
  256. if err != nil {
  257. t.Fatal(err)
  258. }
  259. // Default user must be root
  260. container, err := docker.Create(
  261. "user_default",
  262. "id",
  263. []string{},
  264. []string{testLayerPath},
  265. &Config{},
  266. )
  267. if err != nil {
  268. t.Fatal(err)
  269. }
  270. defer docker.Destroy(container)
  271. output, err := container.Output()
  272. if err != nil {
  273. t.Fatal(err)
  274. }
  275. if !strings.Contains(string(output), "uid=0(root) gid=0(root)") {
  276. t.Error(string(output))
  277. }
  278. // Set a username
  279. container, err = docker.Create(
  280. "user_root",
  281. "id",
  282. []string{},
  283. []string{testLayerPath},
  284. &Config{
  285. User: "root",
  286. },
  287. )
  288. if err != nil {
  289. t.Fatal(err)
  290. }
  291. defer docker.Destroy(container)
  292. output, err = container.Output()
  293. if err != nil {
  294. t.Fatal(err)
  295. }
  296. if !strings.Contains(string(output), "uid=0(root) gid=0(root)") {
  297. t.Error(string(output))
  298. }
  299. // Set a UID
  300. container, err = docker.Create(
  301. "user_uid0",
  302. "id",
  303. []string{},
  304. []string{testLayerPath},
  305. &Config{
  306. User: "0",
  307. },
  308. )
  309. if err != nil {
  310. t.Fatal(err)
  311. }
  312. defer docker.Destroy(container)
  313. output, err = container.Output()
  314. if err != nil {
  315. t.Fatal(err)
  316. }
  317. if !strings.Contains(string(output), "uid=0(root) gid=0(root)") {
  318. t.Error(string(output))
  319. }
  320. // Set a different user by uid
  321. container, err = docker.Create(
  322. "user_uid1",
  323. "id",
  324. []string{},
  325. []string{testLayerPath},
  326. &Config{
  327. User: "1",
  328. },
  329. )
  330. if err != nil {
  331. t.Fatal(err)
  332. }
  333. defer docker.Destroy(container)
  334. output, err = container.Output()
  335. if err != nil {
  336. t.Fatal(err)
  337. }
  338. if !strings.Contains(string(output), "uid=1(daemon) gid=1(daemon)") {
  339. t.Error(string(output))
  340. }
  341. // Set a different user by username
  342. container, err = docker.Create(
  343. "user_daemon",
  344. "id",
  345. []string{},
  346. []string{testLayerPath},
  347. &Config{
  348. User: "daemon",
  349. },
  350. )
  351. if err != nil {
  352. t.Fatal(err)
  353. }
  354. defer docker.Destroy(container)
  355. output, err = container.Output()
  356. if err != nil {
  357. t.Fatal(err)
  358. }
  359. if !strings.Contains(string(output), "uid=1(daemon) gid=1(daemon)") {
  360. t.Error(string(output))
  361. }
  362. }
  363. func TestMultipleContainers(t *testing.T) {
  364. docker, err := newTestDocker()
  365. if err != nil {
  366. t.Fatal(err)
  367. }
  368. container1, err := docker.Create(
  369. "container1",
  370. "cat",
  371. []string{"/dev/zero"},
  372. []string{testLayerPath},
  373. &Config{},
  374. )
  375. if err != nil {
  376. t.Fatal(err)
  377. }
  378. defer docker.Destroy(container1)
  379. container2, err := docker.Create(
  380. "container2",
  381. "cat",
  382. []string{"/dev/zero"},
  383. []string{testLayerPath},
  384. &Config{},
  385. )
  386. if err != nil {
  387. t.Fatal(err)
  388. }
  389. defer docker.Destroy(container2)
  390. // Start both containers
  391. if err := container1.Start(); err != nil {
  392. t.Fatal(err)
  393. }
  394. if err := container2.Start(); err != nil {
  395. t.Fatal(err)
  396. }
  397. // If we are here, both containers should be running
  398. if !container1.State.Running {
  399. t.Fatal("Container not running")
  400. }
  401. if !container2.State.Running {
  402. t.Fatal("Container not running")
  403. }
  404. // Kill them
  405. if err := container1.Kill(); err != nil {
  406. t.Fatal(err)
  407. }
  408. if err := container2.Kill(); err != nil {
  409. t.Fatal(err)
  410. }
  411. }
  412. func TestStdin(t *testing.T) {
  413. docker, err := newTestDocker()
  414. if err != nil {
  415. t.Fatal(err)
  416. }
  417. container, err := docker.Create(
  418. "stdin_test",
  419. "cat",
  420. []string{},
  421. []string{testLayerPath},
  422. &Config{
  423. OpenStdin: true,
  424. },
  425. )
  426. if err != nil {
  427. t.Fatal(err)
  428. }
  429. defer docker.Destroy(container)
  430. stdin, err := container.StdinPipe()
  431. stdout, err := container.StdoutPipe()
  432. defer stdin.Close()
  433. defer stdout.Close()
  434. if err := container.Start(); err != nil {
  435. t.Fatal(err)
  436. }
  437. io.WriteString(stdin, "hello world")
  438. stdin.Close()
  439. container.Wait()
  440. output, err := ioutil.ReadAll(stdout)
  441. if string(output) != "hello world" {
  442. t.Fatal(string(output))
  443. }
  444. }
  445. func TestTty(t *testing.T) {
  446. docker, err := newTestDocker()
  447. if err != nil {
  448. t.Fatal(err)
  449. }
  450. container, err := docker.Create(
  451. "tty_test",
  452. "cat",
  453. []string{},
  454. []string{testLayerPath},
  455. &Config{
  456. OpenStdin: true,
  457. },
  458. )
  459. if err != nil {
  460. t.Fatal(err)
  461. }
  462. defer docker.Destroy(container)
  463. stdin, err := container.StdinPipe()
  464. stdout, err := container.StdoutPipe()
  465. defer stdin.Close()
  466. defer stdout.Close()
  467. if err := container.Start(); err != nil {
  468. t.Fatal(err)
  469. }
  470. io.WriteString(stdin, "hello world")
  471. stdin.Close()
  472. container.Wait()
  473. output, err := ioutil.ReadAll(stdout)
  474. if string(output) != "hello world" {
  475. t.Fatal(string(output))
  476. }
  477. }
  478. func BenchmarkRunSequencial(b *testing.B) {
  479. docker, err := newTestDocker()
  480. if err != nil {
  481. b.Fatal(err)
  482. }
  483. for i := 0; i < b.N; i++ {
  484. container, err := docker.Create(
  485. fmt.Sprintf("bench_%v", i),
  486. "echo",
  487. []string{"-n", "foo"},
  488. []string{testLayerPath},
  489. &Config{},
  490. )
  491. if err != nil {
  492. b.Fatal(err)
  493. }
  494. defer docker.Destroy(container)
  495. output, err := container.Output()
  496. if err != nil {
  497. b.Fatal(err)
  498. }
  499. if string(output) != "foo" {
  500. b.Fatalf("Unexecpted output: %v", string(output))
  501. }
  502. if err := docker.Destroy(container); err != nil {
  503. b.Fatal(err)
  504. }
  505. }
  506. }
  507. func BenchmarkRunParallel(b *testing.B) {
  508. docker, err := newTestDocker()
  509. if err != nil {
  510. b.Fatal(err)
  511. }
  512. var tasks []chan error
  513. for i := 0; i < b.N; i++ {
  514. complete := make(chan error)
  515. tasks = append(tasks, complete)
  516. go func(i int, complete chan error) {
  517. container, err := docker.Create(
  518. fmt.Sprintf("bench_%v", i),
  519. "echo",
  520. []string{"-n", "foo"},
  521. []string{testLayerPath},
  522. &Config{},
  523. )
  524. if err != nil {
  525. complete <- err
  526. return
  527. }
  528. defer docker.Destroy(container)
  529. if err := container.Start(); err != nil {
  530. complete <- err
  531. return
  532. }
  533. if err := container.WaitTimeout(15 * time.Second); err != nil {
  534. complete <- err
  535. return
  536. }
  537. // if string(output) != "foo" {
  538. // complete <- fmt.Errorf("Unexecpted output: %v", string(output))
  539. // }
  540. if err := docker.Destroy(container); err != nil {
  541. complete <- err
  542. return
  543. }
  544. complete <- nil
  545. }(i, complete)
  546. }
  547. var errors []error
  548. for _, task := range tasks {
  549. err := <-task
  550. if err != nil {
  551. errors = append(errors, err)
  552. }
  553. }
  554. if len(errors) > 0 {
  555. b.Fatal(errors)
  556. }
  557. }