api_test.go 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877
  1. package docker
  2. import (
  3. "bufio"
  4. "bytes"
  5. "encoding/json"
  6. "github.com/dotcloud/docker/auth"
  7. "io"
  8. "net"
  9. "net/http"
  10. "net/http/httptest"
  11. "os"
  12. "path"
  13. "testing"
  14. "time"
  15. )
  16. func TestGetAuth(t *testing.T) {
  17. runtime, err := newTestRuntime()
  18. if err != nil {
  19. t.Fatal(err)
  20. }
  21. defer nuke(runtime)
  22. srv := &Server{runtime: runtime}
  23. r := httptest.NewRecorder()
  24. authConfig := &auth.AuthConfig{
  25. Username: "utest",
  26. Password: "utest",
  27. Email: "utest@yopmail.com",
  28. }
  29. authConfigJson, err := json.Marshal(authConfig)
  30. if err != nil {
  31. t.Fatal(err)
  32. }
  33. req, err := http.NewRequest("POST", "/auth", bytes.NewReader(authConfigJson))
  34. if err != nil {
  35. t.Fatal(err)
  36. }
  37. body, err := postAuth(srv, r, req, nil)
  38. if err != nil {
  39. t.Fatal(err)
  40. }
  41. if body == nil {
  42. t.Fatalf("No body received\n")
  43. }
  44. if r.Code != http.StatusOK {
  45. t.Fatalf("%d OK expected, received %d\n", http.StatusOK, r.Code)
  46. }
  47. if runtime.authConfig.Username != authConfig.Username ||
  48. runtime.authConfig.Password != authConfig.Password ||
  49. runtime.authConfig.Email != authConfig.Email {
  50. t.Fatalf("The auth configuration hasn't been set correctly")
  51. }
  52. }
  53. func TestGetVersion(t *testing.T) {
  54. runtime, err := newTestRuntime()
  55. if err != nil {
  56. t.Fatal(err)
  57. }
  58. defer nuke(runtime)
  59. srv := &Server{runtime: runtime}
  60. body, err := getVersion(srv, nil, nil, nil)
  61. if err != nil {
  62. t.Fatal(err)
  63. }
  64. v := &ApiVersion{}
  65. err = json.Unmarshal(body, v)
  66. if err != nil {
  67. t.Fatal(err)
  68. }
  69. if v.Version != VERSION {
  70. t.Errorf("Excepted version %s, %s found", VERSION, v.Version)
  71. }
  72. }
  73. func TestGetInfo(t *testing.T) {
  74. runtime, err := newTestRuntime()
  75. if err != nil {
  76. t.Fatal(err)
  77. }
  78. defer nuke(runtime)
  79. srv := &Server{runtime: runtime}
  80. body, err := getInfo(srv, nil, nil, nil)
  81. if err != nil {
  82. t.Fatal(err)
  83. }
  84. infos := &ApiInfo{}
  85. err = json.Unmarshal(body, infos)
  86. if err != nil {
  87. t.Fatal(err)
  88. }
  89. if infos.Version != VERSION {
  90. t.Errorf("Excepted version %s, %s found", VERSION, infos.Version)
  91. }
  92. }
  93. func TestGetImagesJson(t *testing.T) {
  94. runtime, err := newTestRuntime()
  95. if err != nil {
  96. t.Fatal(err)
  97. }
  98. defer nuke(runtime)
  99. srv := &Server{runtime: runtime}
  100. // FIXME: Do more tests with filter
  101. req, err := http.NewRequest("GET", "/images/json?quiet=0&all=0", nil)
  102. if err != nil {
  103. t.Fatal(err)
  104. }
  105. body, err := getImagesJson(srv, nil, req, nil)
  106. if err != nil {
  107. t.Fatal(err)
  108. }
  109. images := []ApiImages{}
  110. err = json.Unmarshal(body, &images)
  111. if err != nil {
  112. t.Fatal(err)
  113. }
  114. if len(images) != 1 {
  115. t.Errorf("Excepted 1 image, %d found", len(images))
  116. }
  117. if images[0].Repository != "docker-ut" {
  118. t.Errorf("Excepted image docker-ut, %s found", images[0].Repository)
  119. }
  120. }
  121. func TestGetImagesViz(t *testing.T) {
  122. //FIXME: Implement this test (or remove this endpoint)
  123. t.Log("Test not implemented")
  124. }
  125. func TestGetImagesSearch(t *testing.T) {
  126. runtime, err := newTestRuntime()
  127. if err != nil {
  128. t.Fatal(err)
  129. }
  130. defer nuke(runtime)
  131. srv := &Server{runtime: runtime}
  132. req, err := http.NewRequest("GET", "/images/search?term=redis", nil)
  133. if err != nil {
  134. t.Fatal(err)
  135. }
  136. body, err := getImagesSearch(srv, nil, req, nil)
  137. if err != nil {
  138. t.Fatal(err)
  139. }
  140. results := []ApiSearch{}
  141. err = json.Unmarshal(body, &results)
  142. if err != nil {
  143. t.Fatal(err)
  144. }
  145. if len(results) < 2 {
  146. t.Errorf("Excepted at least 2 lines, %d found", len(results))
  147. }
  148. }
  149. func TestGetImagesHistory(t *testing.T) {
  150. runtime, err := newTestRuntime()
  151. if err != nil {
  152. t.Fatal(err)
  153. }
  154. defer nuke(runtime)
  155. srv := &Server{runtime: runtime}
  156. body, err := getImagesHistory(srv, nil, nil, map[string]string{"name": unitTestImageName})
  157. if err != nil {
  158. t.Fatal(err)
  159. }
  160. history := []ApiHistory{}
  161. err = json.Unmarshal(body, &history)
  162. if err != nil {
  163. t.Fatal(err)
  164. }
  165. if len(history) != 1 {
  166. t.Errorf("Excepted 1 line, %d found", len(history))
  167. }
  168. }
  169. func TestGetImagesByName(t *testing.T) {
  170. runtime, err := newTestRuntime()
  171. if err != nil {
  172. t.Fatal(err)
  173. }
  174. defer nuke(runtime)
  175. srv := &Server{runtime: runtime}
  176. body, err := getImagesByName(srv, nil, nil, map[string]string{"name": unitTestImageName})
  177. if err != nil {
  178. t.Fatal(err)
  179. }
  180. img := &Image{}
  181. err = json.Unmarshal(body, img)
  182. if err != nil {
  183. t.Fatal(err)
  184. }
  185. if img.Comment != "Imported from http://get.docker.io/images/busybox" {
  186. t.Errorf("Error inspecting image")
  187. }
  188. }
  189. func TestGetContainersPs(t *testing.T) {
  190. runtime, err := newTestRuntime()
  191. if err != nil {
  192. t.Fatal(err)
  193. }
  194. defer nuke(runtime)
  195. srv := &Server{runtime: runtime}
  196. container, err := NewBuilder(runtime).Create(&Config{
  197. Image: GetTestImage(runtime).Id,
  198. Cmd: []string{"echo", "test"},
  199. })
  200. if err != nil {
  201. t.Fatal(err)
  202. }
  203. defer runtime.Destroy(container)
  204. req, err := http.NewRequest("GET", "/containers?quiet=1&all=1", nil)
  205. if err != nil {
  206. t.Fatal(err)
  207. }
  208. body, err := getContainersPs(srv, nil, req, nil)
  209. if err != nil {
  210. t.Fatal(err)
  211. }
  212. containers := []ApiContainers{}
  213. err = json.Unmarshal(body, &containers)
  214. if err != nil {
  215. t.Fatal(err)
  216. }
  217. if len(containers) != 1 {
  218. t.Fatalf("Excepted %d container, %d found", 1, len(containers))
  219. }
  220. if containers[0].Id != container.ShortId() {
  221. t.Fatalf("Container ID mismatch. Expected: %s, received: %s\n", container.ShortId(), containers[0].Id)
  222. }
  223. }
  224. func TestGetContainersExport(t *testing.T) {
  225. //FIXME: Implement this test
  226. t.Log("Test not implemented")
  227. }
  228. func TestGetContainersChanges(t *testing.T) {
  229. runtime, err := newTestRuntime()
  230. if err != nil {
  231. t.Fatal(err)
  232. }
  233. defer nuke(runtime)
  234. srv := &Server{runtime: runtime}
  235. builder := NewBuilder(runtime)
  236. // Create a container and remove a file
  237. container, err := builder.Create(
  238. &Config{
  239. Image: GetTestImage(runtime).Id,
  240. Cmd: []string{"/bin/rm", "/etc/passwd"},
  241. },
  242. )
  243. if err != nil {
  244. t.Fatal(err)
  245. }
  246. defer runtime.Destroy(container)
  247. if err := container.Run(); err != nil {
  248. t.Fatal(err)
  249. }
  250. body, err := getContainersChanges(srv, nil, nil, map[string]string{"name": container.Id})
  251. if err != nil {
  252. t.Fatal(err)
  253. }
  254. changes := []Change{}
  255. if err := json.Unmarshal(body, &changes); err != nil {
  256. t.Fatal(err)
  257. }
  258. // Check the changelog
  259. success := false
  260. for _, elem := range changes {
  261. if elem.Path == "/etc/passwd" && elem.Kind == 2 {
  262. success = true
  263. }
  264. }
  265. if !success {
  266. t.Fatalf("/etc/passwd as been removed but is not present in the diff")
  267. }
  268. }
  269. func TestGetContainersByName(t *testing.T) {
  270. //FIXME: Implement this test
  271. t.Log("Test not implemented")
  272. }
  273. func TestPostAuth(t *testing.T) {
  274. runtime, err := newTestRuntime()
  275. if err != nil {
  276. t.Fatal(err)
  277. }
  278. defer nuke(runtime)
  279. srv := &Server{runtime: runtime}
  280. authConfigOrig := &auth.AuthConfig{
  281. Username: "utest",
  282. Email: "utest@yopmail.com",
  283. }
  284. runtime.authConfig = authConfigOrig
  285. body, err := getAuth(srv, nil, nil, nil)
  286. if err != nil {
  287. t.Fatal(err)
  288. }
  289. authConfig := &auth.AuthConfig{}
  290. err = json.Unmarshal(body, authConfig)
  291. if err != nil {
  292. t.Fatal(err)
  293. }
  294. if authConfig.Username != authConfigOrig.Username || authConfig.Email != authConfigOrig.Email {
  295. t.Errorf("The retrieve auth mismatch with the one set.")
  296. }
  297. }
  298. func TestPostCommit(t *testing.T) {
  299. //FIXME: Implement this test
  300. t.Log("Test not implemented")
  301. }
  302. func TestPostBuild(t *testing.T) {
  303. //FIXME: Implement this test
  304. t.Log("Test not implemented")
  305. }
  306. func TestPostImagesCreate(t *testing.T) {
  307. //FIXME: Implement this test
  308. t.Log("Test not implemented")
  309. }
  310. func TestPostImagesInsert(t *testing.T) {
  311. //FIXME: Implement this test (or remove this endpoint)
  312. t.Log("Test not implemented")
  313. }
  314. func TestPostImagesPush(t *testing.T) {
  315. //FIXME: Implement this test
  316. t.Log("Test not implemented")
  317. }
  318. func TestPostImagesTag(t *testing.T) {
  319. //FIXME: Implement this test
  320. t.Log("Test not implemented")
  321. }
  322. func TestPostContainersCreate(t *testing.T) {
  323. runtime, err := newTestRuntime()
  324. if err != nil {
  325. t.Fatal(err)
  326. }
  327. defer nuke(runtime)
  328. srv := &Server{runtime: runtime}
  329. r := httptest.NewRecorder()
  330. configJson, err := json.Marshal(&Config{
  331. Image: GetTestImage(runtime).Id,
  332. Memory: 33554432,
  333. Cmd: []string{"touch", "/test"},
  334. })
  335. if err != nil {
  336. t.Fatal(err)
  337. }
  338. req, err := http.NewRequest("POST", "/containers/create", bytes.NewReader(configJson))
  339. if err != nil {
  340. t.Fatal(err)
  341. }
  342. body, err := postContainersCreate(srv, r, req, nil)
  343. if err != nil {
  344. t.Fatal(err)
  345. }
  346. if r.Code != http.StatusCreated {
  347. t.Fatalf("%d Created expected, received %d\n", http.StatusCreated, r.Code)
  348. }
  349. apiRun := &ApiRun{}
  350. if err := json.Unmarshal(body, apiRun); err != nil {
  351. t.Fatal(err)
  352. }
  353. container := srv.runtime.Get(apiRun.Id)
  354. if container == nil {
  355. t.Fatalf("Container not created")
  356. }
  357. if err := container.Run(); err != nil {
  358. t.Fatal(err)
  359. }
  360. if _, err := os.Stat(path.Join(container.rwPath(), "test")); err != nil {
  361. if os.IsNotExist(err) {
  362. Debugf("Err: %s", err)
  363. t.Fatalf("The test file has not been created")
  364. }
  365. t.Fatal(err)
  366. }
  367. }
  368. func TestPostContainersKill(t *testing.T) {
  369. runtime, err := newTestRuntime()
  370. if err != nil {
  371. t.Fatal(err)
  372. }
  373. defer nuke(runtime)
  374. srv := &Server{runtime: runtime}
  375. container, err := NewBuilder(runtime).Create(
  376. &Config{
  377. Image: GetTestImage(runtime).Id,
  378. Cmd: []string{"/bin/cat"},
  379. OpenStdin: true,
  380. },
  381. )
  382. if err != nil {
  383. t.Fatal(err)
  384. }
  385. defer runtime.Destroy(container)
  386. if err := container.Start(); err != nil {
  387. t.Fatal(err)
  388. }
  389. // Give some time to the process to start
  390. container.WaitTimeout(500 * time.Millisecond)
  391. if !container.State.Running {
  392. t.Errorf("Container should be running")
  393. }
  394. r := httptest.NewRecorder()
  395. body, err := postContainersKill(srv, r, nil, map[string]string{"name": container.Id})
  396. if err != nil {
  397. t.Fatal(err)
  398. }
  399. if body != nil {
  400. t.Fatalf("No body expected, received: %s\n", body)
  401. }
  402. if r.Code != http.StatusNoContent {
  403. t.Fatalf("%d NO CONTENT expected, received %d\n", http.StatusNoContent, r.Code)
  404. }
  405. if container.State.Running {
  406. t.Fatalf("The container hasn't been killed")
  407. }
  408. }
  409. func TestPostContainersRestart(t *testing.T) {
  410. runtime, err := newTestRuntime()
  411. if err != nil {
  412. t.Fatal(err)
  413. }
  414. defer nuke(runtime)
  415. srv := &Server{runtime: runtime}
  416. container, err := NewBuilder(runtime).Create(
  417. &Config{
  418. Image: GetTestImage(runtime).Id,
  419. Cmd: []string{"/bin/cat"},
  420. OpenStdin: true,
  421. },
  422. )
  423. if err != nil {
  424. t.Fatal(err)
  425. }
  426. defer runtime.Destroy(container)
  427. if err := container.Start(); err != nil {
  428. t.Fatal(err)
  429. }
  430. // Give some time to the process to start
  431. container.WaitTimeout(500 * time.Millisecond)
  432. if !container.State.Running {
  433. t.Errorf("Container should be running")
  434. }
  435. r := httptest.NewRecorder()
  436. req, err := http.NewRequest("POST", "/containers/"+container.Id+"/restart?t=1", bytes.NewReader([]byte{}))
  437. if err != nil {
  438. t.Fatal(err)
  439. }
  440. body, err := postContainersRestart(srv, r, req, map[string]string{"name": container.Id})
  441. if err != nil {
  442. t.Fatal(err)
  443. }
  444. if body != nil {
  445. t.Fatalf("No body expected, received: %s\n", body)
  446. }
  447. if r.Code != http.StatusNoContent {
  448. t.Fatalf("%d NO CONTENT expected, received %d\n", http.StatusNoContent, r.Code)
  449. }
  450. // Give some time to the process to restart
  451. container.WaitTimeout(500 * time.Millisecond)
  452. if !container.State.Running {
  453. t.Fatalf("Container should be running")
  454. }
  455. if err := container.Kill(); err != nil {
  456. t.Fatal(err)
  457. }
  458. }
  459. func TestPostContainersStart(t *testing.T) {
  460. runtime, err := newTestRuntime()
  461. if err != nil {
  462. t.Fatal(err)
  463. }
  464. defer nuke(runtime)
  465. srv := &Server{runtime: runtime}
  466. container, err := NewBuilder(runtime).Create(
  467. &Config{
  468. Image: GetTestImage(runtime).Id,
  469. Cmd: []string{"/bin/cat"},
  470. OpenStdin: true,
  471. },
  472. )
  473. if err != nil {
  474. t.Fatal(err)
  475. }
  476. defer runtime.Destroy(container)
  477. r := httptest.NewRecorder()
  478. body, err := postContainersStart(srv, r, nil, map[string]string{"name": container.Id})
  479. if err != nil {
  480. t.Fatal(err)
  481. }
  482. if body != nil {
  483. t.Fatalf("No body expected, received: %s\n", body)
  484. }
  485. if r.Code != http.StatusNoContent {
  486. t.Fatalf("%d NO CONTENT expected, received %d\n", http.StatusNoContent, r.Code)
  487. }
  488. // Give some time to the process to start
  489. container.WaitTimeout(500 * time.Millisecond)
  490. if !container.State.Running {
  491. t.Errorf("Container should be running")
  492. }
  493. if _, err = postContainersStart(srv, r, nil, map[string]string{"name": container.Id}); err == nil {
  494. t.Fatalf("A running containter should be able to be started")
  495. }
  496. if err := container.Kill(); err != nil {
  497. t.Fatal(err)
  498. }
  499. }
  500. func TestPostContainersStop(t *testing.T) {
  501. runtime, err := newTestRuntime()
  502. if err != nil {
  503. t.Fatal(err)
  504. }
  505. defer nuke(runtime)
  506. srv := &Server{runtime: runtime}
  507. container, err := NewBuilder(runtime).Create(
  508. &Config{
  509. Image: GetTestImage(runtime).Id,
  510. Cmd: []string{"/bin/cat"},
  511. OpenStdin: true,
  512. },
  513. )
  514. if err != nil {
  515. t.Fatal(err)
  516. }
  517. defer runtime.Destroy(container)
  518. if err := container.Start(); err != nil {
  519. t.Fatal(err)
  520. }
  521. // Give some time to the process to start
  522. container.WaitTimeout(500 * time.Millisecond)
  523. if !container.State.Running {
  524. t.Errorf("Container should be running")
  525. }
  526. r := httptest.NewRecorder()
  527. // Note: as it is a POST request, it requires a body.
  528. req, err := http.NewRequest("POST", "/containers/"+container.Id+"/stop?t=1", bytes.NewReader([]byte{}))
  529. if err != nil {
  530. t.Fatal(err)
  531. }
  532. body, err := postContainersStop(srv, r, req, map[string]string{"name": container.Id})
  533. if err != nil {
  534. t.Fatal(err)
  535. }
  536. if body != nil {
  537. t.Fatalf("No body expected, received: %s\n", body)
  538. }
  539. if r.Code != http.StatusNoContent {
  540. t.Fatalf("%d NO CONTENT expected, received %d\n", http.StatusNoContent, r.Code)
  541. }
  542. if container.State.Running {
  543. t.Fatalf("The container hasn't been stopped")
  544. }
  545. }
  546. func TestPostContainersWait(t *testing.T) {
  547. runtime, err := newTestRuntime()
  548. if err != nil {
  549. t.Fatal(err)
  550. }
  551. defer nuke(runtime)
  552. srv := &Server{runtime: runtime}
  553. container, err := NewBuilder(runtime).Create(
  554. &Config{
  555. Image: GetTestImage(runtime).Id,
  556. Cmd: []string{"/bin/sleep", "1"},
  557. OpenStdin: true,
  558. },
  559. )
  560. if err != nil {
  561. t.Fatal(err)
  562. }
  563. defer runtime.Destroy(container)
  564. if err := container.Start(); err != nil {
  565. t.Fatal(err)
  566. }
  567. setTimeout(t, "Wait timed out", 3*time.Second, func() {
  568. body, err := postContainersWait(srv, nil, nil, map[string]string{"name": container.Id})
  569. if err != nil {
  570. t.Fatal(err)
  571. }
  572. apiWait := &ApiWait{}
  573. if err := json.Unmarshal(body, apiWait); err != nil {
  574. t.Fatal(err)
  575. }
  576. if apiWait.StatusCode != 0 {
  577. t.Fatalf("Non zero exit code for sleep: %d\n", apiWait.StatusCode)
  578. }
  579. })
  580. if container.State.Running {
  581. t.Fatalf("The container should be stopped after wait")
  582. }
  583. }
  584. func TestPostContainersAttach(t *testing.T) {
  585. runtime, err := newTestRuntime()
  586. if err != nil {
  587. t.Fatal(err)
  588. }
  589. defer nuke(runtime)
  590. srv := &Server{runtime: runtime}
  591. container, err := NewBuilder(runtime).Create(
  592. &Config{
  593. Image: GetTestImage(runtime).Id,
  594. Cmd: []string{"/bin/cat"},
  595. OpenStdin: true,
  596. },
  597. )
  598. if err != nil {
  599. t.Fatal(err)
  600. }
  601. defer runtime.Destroy(container)
  602. // Start the process
  603. if err := container.Start(); err != nil {
  604. t.Fatal(err)
  605. }
  606. stdin, stdinPipe := io.Pipe()
  607. stdout, stdoutPipe := io.Pipe()
  608. // Attach to it
  609. c1 := make(chan struct{})
  610. go func() {
  611. // We're simulating a disconnect so the return value doesn't matter. What matters is the
  612. // fact that CmdAttach returns.
  613. r := &hijackTester{
  614. ResponseRecorder: httptest.NewRecorder(),
  615. in: stdin,
  616. out: stdoutPipe,
  617. }
  618. req, err := http.NewRequest("POST", "/containers/"+container.Id+"/attach?stream=1&stdin=1&stdout=1&stderr=1", bytes.NewReader([]byte{}))
  619. if err != nil {
  620. t.Fatal(err)
  621. }
  622. body, err := postContainersAttach(srv, r, req, map[string]string{"name": container.Id})
  623. close(c1)
  624. if err != nil {
  625. t.Fatal(err)
  626. }
  627. if body != nil {
  628. t.Fatalf("No body expected, received: %s\n", body)
  629. }
  630. }()
  631. // Acknowledge hijack
  632. setTimeout(t, "hijack acknowledge timed out", 2*time.Second, func() {
  633. stdout.Read([]byte{})
  634. stdout.Read(make([]byte, 4096))
  635. })
  636. setTimeout(t, "read/write assertion timed out", 2*time.Second, func() {
  637. if err := assertPipe("hello\n", "hello", stdout, stdinPipe, 15); err != nil {
  638. t.Fatal(err)
  639. }
  640. })
  641. // Close pipes (client disconnects)
  642. if err := closeWrap(stdin, stdinPipe, stdout, stdoutPipe); err != nil {
  643. t.Fatal(err)
  644. }
  645. // Wait for attach to finish, the client disconnected, therefore, Attach finished his job
  646. setTimeout(t, "Waiting for CmdAttach timed out", 2*time.Second, func() {
  647. <-c1
  648. })
  649. // We closed stdin, expect /bin/cat to still be running
  650. // Wait a little bit to make sure container.monitor() did his thing
  651. err = container.WaitTimeout(500 * time.Millisecond)
  652. if err == nil || !container.State.Running {
  653. t.Fatalf("/bin/cat is not running after closing stdin")
  654. }
  655. // Try to avoid the timeoout in destroy. Best effort, don't check error
  656. cStdin, _ := container.StdinPipe()
  657. cStdin.Close()
  658. container.Wait()
  659. }
  660. // FIXME: Test deleting runnign container
  661. // FIXME: Test deleting container with volume
  662. // FIXME: Test deleting volume in use by other container
  663. func TestDeleteContainers(t *testing.T) {
  664. runtime, err := newTestRuntime()
  665. if err != nil {
  666. t.Fatal(err)
  667. }
  668. defer nuke(runtime)
  669. srv := &Server{runtime: runtime}
  670. container, err := NewBuilder(runtime).Create(&Config{
  671. Image: GetTestImage(runtime).Id,
  672. Cmd: []string{"touch", "/test"},
  673. })
  674. if err != nil {
  675. t.Fatal(err)
  676. }
  677. defer runtime.Destroy(container)
  678. if err := container.Run(); err != nil {
  679. t.Fatal(err)
  680. }
  681. r := httptest.NewRecorder()
  682. req, err := http.NewRequest("DELETE", "/containers/"+container.Id, nil)
  683. if err != nil {
  684. t.Fatal(err)
  685. }
  686. body, err := deleteContainers(srv, r, req, map[string]string{"name": container.Id})
  687. if err != nil {
  688. t.Fatal(err)
  689. }
  690. if body != nil {
  691. t.Fatalf("No body expected, received: %s\n", body)
  692. }
  693. if r.Code != http.StatusNoContent {
  694. t.Fatalf("%d NO CONTENT expected, received %d\n", http.StatusNoContent, r.Code)
  695. }
  696. if c := runtime.Get(container.Id); c != nil {
  697. t.Fatalf("The container as not been deleted")
  698. }
  699. if _, err := os.Stat(path.Join(container.rwPath(), "test")); err == nil {
  700. t.Fatalf("The test file has not been deleted")
  701. }
  702. }
  703. func TestDeleteImages(t *testing.T) {
  704. //FIXME: Implement this test
  705. t.Log("Test not implemented")
  706. }
  707. // Mocked types for tests
  708. type NopConn struct {
  709. io.ReadCloser
  710. io.Writer
  711. }
  712. func (c *NopConn) LocalAddr() net.Addr { return nil }
  713. func (c *NopConn) RemoteAddr() net.Addr { return nil }
  714. func (c *NopConn) SetDeadline(t time.Time) error { return nil }
  715. func (c *NopConn) SetReadDeadline(t time.Time) error { return nil }
  716. func (c *NopConn) SetWriteDeadline(t time.Time) error { return nil }
  717. type hijackTester struct {
  718. *httptest.ResponseRecorder
  719. in io.ReadCloser
  720. out io.Writer
  721. }
  722. func (t *hijackTester) Hijack() (net.Conn, *bufio.ReadWriter, error) {
  723. bufrw := bufio.NewReadWriter(bufio.NewReader(t.in), bufio.NewWriter(t.out))
  724. conn := &NopConn{
  725. ReadCloser: t.in,
  726. Writer: t.out,
  727. }
  728. return conn, bufrw, nil
  729. }