api_test.go 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732
  1. package docker
  2. import (
  3. "bytes"
  4. "encoding/json"
  5. "github.com/dotcloud/docker/auth"
  6. "net/http"
  7. "net/http/httptest"
  8. "os"
  9. "path"
  10. "testing"
  11. "time"
  12. )
  13. func TestGetAuth(t *testing.T) {
  14. runtime, err := newTestRuntime()
  15. if err != nil {
  16. t.Fatal(err)
  17. }
  18. defer nuke(runtime)
  19. srv := &Server{runtime: runtime}
  20. r := httptest.NewRecorder()
  21. authConfig := &auth.AuthConfig{
  22. Username: "utest",
  23. Password: "utest",
  24. Email: "utest@yopmail.com",
  25. }
  26. authConfigJson, err := json.Marshal(authConfig)
  27. if err != nil {
  28. t.Fatal(err)
  29. }
  30. req, err := http.NewRequest("POST", "/auth", bytes.NewReader(authConfigJson))
  31. if err != nil {
  32. t.Fatal(err)
  33. }
  34. body, err := postAuth(srv, r, req, nil)
  35. if err != nil {
  36. t.Fatal(err)
  37. }
  38. if body == nil {
  39. t.Fatalf("No body received\n")
  40. }
  41. if r.Code != http.StatusOK {
  42. t.Fatalf("%d OK expected, received %d\n", http.StatusOK, r.Code)
  43. }
  44. if runtime.authConfig.Username != authConfig.Username ||
  45. runtime.authConfig.Password != authConfig.Password ||
  46. runtime.authConfig.Email != authConfig.Email {
  47. t.Fatalf("The auth configuration hasn't been set correctly")
  48. }
  49. }
  50. func TestGetVersion(t *testing.T) {
  51. runtime, err := newTestRuntime()
  52. if err != nil {
  53. t.Fatal(err)
  54. }
  55. defer nuke(runtime)
  56. srv := &Server{runtime: runtime}
  57. body, err := getVersion(srv, nil, nil, nil)
  58. if err != nil {
  59. t.Fatal(err)
  60. }
  61. v := &ApiVersion{}
  62. err = json.Unmarshal(body, v)
  63. if err != nil {
  64. t.Fatal(err)
  65. }
  66. if v.Version != VERSION {
  67. t.Errorf("Excepted version %s, %s found", VERSION, v.Version)
  68. }
  69. }
  70. func TestGetInfo(t *testing.T) {
  71. runtime, err := newTestRuntime()
  72. if err != nil {
  73. t.Fatal(err)
  74. }
  75. defer nuke(runtime)
  76. srv := &Server{runtime: runtime}
  77. body, err := getInfo(srv, nil, nil, nil)
  78. if err != nil {
  79. t.Fatal(err)
  80. }
  81. infos := &ApiInfo{}
  82. err = json.Unmarshal(body, infos)
  83. if err != nil {
  84. t.Fatal(err)
  85. }
  86. if infos.Version != VERSION {
  87. t.Errorf("Excepted version %s, %s found", VERSION, infos.Version)
  88. }
  89. }
  90. func TestGetImagesJson(t *testing.T) {
  91. runtime, err := newTestRuntime()
  92. if err != nil {
  93. t.Fatal(err)
  94. }
  95. defer nuke(runtime)
  96. srv := &Server{runtime: runtime}
  97. // FIXME: Do more tests with filter
  98. req, err := http.NewRequest("GET", "/images/json?quiet=0&all=0", nil)
  99. if err != nil {
  100. t.Fatal(err)
  101. }
  102. body, err := getImagesJson(srv, nil, req, nil)
  103. if err != nil {
  104. t.Fatal(err)
  105. }
  106. images := []ApiImages{}
  107. err = json.Unmarshal(body, &images)
  108. if err != nil {
  109. t.Fatal(err)
  110. }
  111. if len(images) != 1 {
  112. t.Errorf("Excepted 1 image, %d found", len(images))
  113. }
  114. if images[0].Repository != "docker-ut" {
  115. t.Errorf("Excepted image docker-ut, %s found", images[0].Repository)
  116. }
  117. }
  118. func TestGetImagesViz(t *testing.T) {
  119. //FIXME: Implement this test (or remove this endpoint)
  120. t.Log("Test on implemented")
  121. }
  122. func TestGetImagesSearch(t *testing.T) {
  123. runtime, err := newTestRuntime()
  124. if err != nil {
  125. t.Fatal(err)
  126. }
  127. defer nuke(runtime)
  128. srv := &Server{runtime: runtime}
  129. req, err := http.NewRequest("GET", "/images/search?term=redis", nil)
  130. if err != nil {
  131. t.Fatal(err)
  132. }
  133. body, err := getImagesSearch(srv, nil, req, nil)
  134. if err != nil {
  135. t.Fatal(err)
  136. }
  137. results := []ApiSearch{}
  138. err = json.Unmarshal(body, &results)
  139. if err != nil {
  140. t.Fatal(err)
  141. }
  142. if len(results) < 2 {
  143. t.Errorf("Excepted at least 2 lines, %d found", len(results))
  144. }
  145. }
  146. func TestGetImagesHistory(t *testing.T) {
  147. runtime, err := newTestRuntime()
  148. if err != nil {
  149. t.Fatal(err)
  150. }
  151. defer nuke(runtime)
  152. srv := &Server{runtime: runtime}
  153. body, err := getImagesHistory(srv, nil, nil, map[string]string{"name": unitTestImageName})
  154. if err != nil {
  155. t.Fatal(err)
  156. }
  157. history := []ApiHistory{}
  158. err = json.Unmarshal(body, &history)
  159. if err != nil {
  160. t.Fatal(err)
  161. }
  162. if len(history) != 1 {
  163. t.Errorf("Excepted 1 line, %d found", len(history))
  164. }
  165. }
  166. func TestGetImagesByName(t *testing.T) {
  167. runtime, err := newTestRuntime()
  168. if err != nil {
  169. t.Fatal(err)
  170. }
  171. defer nuke(runtime)
  172. srv := &Server{runtime: runtime}
  173. body, err := getImagesByName(srv, nil, nil, map[string]string{"name": unitTestImageName})
  174. if err != nil {
  175. t.Fatal(err)
  176. }
  177. img := &Image{}
  178. err = json.Unmarshal(body, img)
  179. if err != nil {
  180. t.Fatal(err)
  181. }
  182. if img.Comment != "Imported from http://get.docker.io/images/busybox" {
  183. t.Errorf("Error inspecting image")
  184. }
  185. }
  186. func TestGetContainersPs(t *testing.T) {
  187. runtime, err := newTestRuntime()
  188. if err != nil {
  189. t.Fatal(err)
  190. }
  191. defer nuke(runtime)
  192. srv := &Server{runtime: runtime}
  193. container, err := NewBuilder(runtime).Create(&Config{
  194. Image: GetTestImage(runtime).Id,
  195. Cmd: []string{"echo", "test"},
  196. })
  197. if err != nil {
  198. t.Fatal(err)
  199. }
  200. defer runtime.Destroy(container)
  201. req, err := http.NewRequest("GET", "/containers?quiet=1&all=1", nil)
  202. if err != nil {
  203. t.Fatal(err)
  204. }
  205. body, err := getContainersPs(srv, nil, req, nil)
  206. if err != nil {
  207. t.Fatal(err)
  208. }
  209. containers := []ApiContainers{}
  210. err = json.Unmarshal(body, &containers)
  211. if err != nil {
  212. t.Fatal(err)
  213. }
  214. if len(containers) != 1 {
  215. t.Fatalf("Excepted %d container, %d found", 1, len(containers))
  216. }
  217. if containers[0].Id != container.ShortId() {
  218. t.Fatalf("Container ID mismatch. Expected: %s, received: %s\n", container.ShortId(), containers[0].Id)
  219. }
  220. }
  221. func TestGetContainersExport(t *testing.T) {
  222. //FIXME: Implement this test
  223. t.Log("Test on implemented")
  224. }
  225. func TestGetContainerChanges(t *testing.T) {
  226. // FIXME: Implement this test
  227. t.Log("Test on implemented")
  228. // r := httptest.NewRecorder()
  229. // req, err := http.NewRequest("GET", "/containers/"+id+"/changes", nil)
  230. // if err != nil {
  231. // t.Fatal(err)
  232. // }
  233. // body, err := getContainersChanges(srv, r, req, nil)
  234. // if err != nil {
  235. // t.Fatal(err)
  236. // }
  237. // if body == nil {
  238. // t.Fatalf("Body expected, received: nil\n")
  239. // }
  240. // if r.Code != http.StatusOK {
  241. // t.Fatalf("%d OK expected, received %d\n", http.StatusNoContent, r.Code)
  242. // }
  243. }
  244. func TestPostAuth(t *testing.T) {
  245. runtime, err := newTestRuntime()
  246. if err != nil {
  247. t.Fatal(err)
  248. }
  249. defer nuke(runtime)
  250. srv := &Server{runtime: runtime}
  251. authConfigOrig := &auth.AuthConfig{
  252. Username: "utest",
  253. Email: "utest@yopmail.com",
  254. }
  255. runtime.authConfig = authConfigOrig
  256. body, err := getAuth(srv, nil, nil, nil)
  257. if err != nil {
  258. t.Fatal(err)
  259. }
  260. authConfig := &auth.AuthConfig{}
  261. err = json.Unmarshal(body, authConfig)
  262. if err != nil {
  263. t.Fatal(err)
  264. }
  265. if authConfig.Username != authConfigOrig.Username || authConfig.Email != authConfigOrig.Email {
  266. t.Errorf("The retrieve auth mismatch with the one set.")
  267. }
  268. }
  269. func TestPostCommit(t *testing.T) {
  270. //FIXME: Implement this test
  271. t.Log("Test on implemented")
  272. }
  273. func TestPostBuild(t *testing.T) {
  274. //FIXME: Implement this test
  275. t.Log("Test on implemented")
  276. }
  277. func TestPostImagesCreate(t *testing.T) {
  278. //FIXME: Implement this test
  279. t.Log("Test on implemented")
  280. }
  281. func TestPostImagesInsert(t *testing.T) {
  282. //FIXME: Implement this test (or remove this endpoint)
  283. t.Log("Test on implemented")
  284. }
  285. func TestPostImagesPush(t *testing.T) {
  286. //FIXME: Implement this test
  287. t.Log("Test on implemented")
  288. }
  289. func TestPostImagesTag(t *testing.T) {
  290. //FIXME: Implement this test
  291. t.Log("Test on implemented")
  292. }
  293. func TestPostContainersCreate(t *testing.T) {
  294. runtime, err := newTestRuntime()
  295. if err != nil {
  296. t.Fatal(err)
  297. }
  298. defer nuke(runtime)
  299. srv := &Server{runtime: runtime}
  300. r := httptest.NewRecorder()
  301. configJson, err := json.Marshal(&Config{
  302. Image: GetTestImage(runtime).Id,
  303. Memory: 33554432,
  304. Cmd: []string{"touch", "/test"},
  305. })
  306. if err != nil {
  307. t.Fatal(err)
  308. }
  309. req, err := http.NewRequest("POST", "/containers/create", bytes.NewReader(configJson))
  310. if err != nil {
  311. t.Fatal(err)
  312. }
  313. body, err := postContainersCreate(srv, r, req, nil)
  314. if err != nil {
  315. t.Fatal(err)
  316. }
  317. if r.Code != http.StatusCreated {
  318. t.Fatalf("%d Created expected, received %d\n", http.StatusCreated, r.Code)
  319. }
  320. apiRun := &ApiRun{}
  321. if err := json.Unmarshal(body, apiRun); err != nil {
  322. t.Fatal(err)
  323. }
  324. container := srv.runtime.Get(apiRun.Id)
  325. if container == nil {
  326. t.Fatalf("Container not created")
  327. }
  328. if err := container.Run(); err != nil {
  329. t.Fatal(err)
  330. }
  331. if _, err := os.Stat(path.Join(container.rwPath(), "test")); err != nil {
  332. if os.IsNotExist(err) {
  333. Debugf("Err: %s", err)
  334. t.Fatalf("The test file has not been created")
  335. }
  336. t.Fatal(err)
  337. }
  338. }
  339. func TestPostContainersKill(t *testing.T) {
  340. runtime, err := newTestRuntime()
  341. if err != nil {
  342. t.Fatal(err)
  343. }
  344. defer nuke(runtime)
  345. srv := &Server{runtime: runtime}
  346. container, err := NewBuilder(runtime).Create(
  347. &Config{
  348. Image: GetTestImage(runtime).Id,
  349. Cmd: []string{"/bin/cat"},
  350. OpenStdin: true,
  351. },
  352. )
  353. if err != nil {
  354. t.Fatal(err)
  355. }
  356. defer runtime.Destroy(container)
  357. if err := container.Start(); err != nil {
  358. t.Fatal(err)
  359. }
  360. // Give some time to the process to start
  361. container.WaitTimeout(500 * time.Millisecond)
  362. if !container.State.Running {
  363. t.Errorf("Container should be running")
  364. }
  365. r := httptest.NewRecorder()
  366. body, err := postContainersKill(srv, r, nil, map[string]string{"name": container.Id})
  367. if err != nil {
  368. t.Fatal(err)
  369. }
  370. if body != nil {
  371. t.Fatalf("No body expected, received: %s\n", body)
  372. }
  373. if r.Code != http.StatusNoContent {
  374. t.Fatalf("%d NO CONTENT expected, received %d\n", http.StatusNoContent, r.Code)
  375. }
  376. if container.State.Running {
  377. t.Fatalf("The container hasn't been killed")
  378. }
  379. }
  380. func TestPostContainersRestart(t *testing.T) {
  381. runtime, err := newTestRuntime()
  382. if err != nil {
  383. t.Fatal(err)
  384. }
  385. defer nuke(runtime)
  386. srv := &Server{runtime: runtime}
  387. container, err := NewBuilder(runtime).Create(
  388. &Config{
  389. Image: GetTestImage(runtime).Id,
  390. Cmd: []string{"/bin/cat"},
  391. OpenStdin: true,
  392. },
  393. )
  394. if err != nil {
  395. t.Fatal(err)
  396. }
  397. defer runtime.Destroy(container)
  398. if err := container.Start(); err != nil {
  399. t.Fatal(err)
  400. }
  401. // Give some time to the process to start
  402. container.WaitTimeout(500 * time.Millisecond)
  403. if !container.State.Running {
  404. t.Errorf("Container should be running")
  405. }
  406. r := httptest.NewRecorder()
  407. req, err := http.NewRequest("POST", "/containers/"+container.Id+"/restart?t=1", bytes.NewReader([]byte{}))
  408. if err != nil {
  409. t.Fatal(err)
  410. }
  411. body, err := postContainersRestart(srv, r, req, map[string]string{"name": container.Id})
  412. if err != nil {
  413. t.Fatal(err)
  414. }
  415. if body != nil {
  416. t.Fatalf("No body expected, received: %s\n", body)
  417. }
  418. if r.Code != http.StatusNoContent {
  419. t.Fatalf("%d NO CONTENT expected, received %d\n", http.StatusNoContent, r.Code)
  420. }
  421. // Give some time to the process to restart
  422. container.WaitTimeout(500 * time.Millisecond)
  423. if !container.State.Running {
  424. t.Fatalf("Container should be running")
  425. }
  426. if err := container.Kill(); err != nil {
  427. t.Fatal(err)
  428. }
  429. }
  430. func TestPostContainersStart(t *testing.T) {
  431. runtime, err := newTestRuntime()
  432. if err != nil {
  433. t.Fatal(err)
  434. }
  435. defer nuke(runtime)
  436. srv := &Server{runtime: runtime}
  437. container, err := NewBuilder(runtime).Create(
  438. &Config{
  439. Image: GetTestImage(runtime).Id,
  440. Cmd: []string{"/bin/cat"},
  441. OpenStdin: true,
  442. },
  443. )
  444. if err != nil {
  445. t.Fatal(err)
  446. }
  447. defer runtime.Destroy(container)
  448. r := httptest.NewRecorder()
  449. body, err := postContainersStart(srv, r, nil, map[string]string{"name": container.Id})
  450. if err != nil {
  451. t.Fatal(err)
  452. }
  453. if body != nil {
  454. t.Fatalf("No body expected, received: %s\n", body)
  455. }
  456. if r.Code != http.StatusNoContent {
  457. t.Fatalf("%d NO CONTENT expected, received %d\n", http.StatusNoContent, r.Code)
  458. }
  459. // Give some time to the process to start
  460. container.WaitTimeout(500 * time.Millisecond)
  461. if !container.State.Running {
  462. t.Errorf("Container should be running")
  463. }
  464. if _, err = postContainersStart(srv, r, nil, map[string]string{"name": container.Id}); err == nil {
  465. t.Fatalf("A running containter should be able to be started")
  466. }
  467. if err := container.Kill(); err != nil {
  468. t.Fatal(err)
  469. }
  470. }
  471. func TestPostContainersStop(t *testing.T) {
  472. runtime, err := newTestRuntime()
  473. if err != nil {
  474. t.Fatal(err)
  475. }
  476. defer nuke(runtime)
  477. srv := &Server{runtime: runtime}
  478. container, err := NewBuilder(runtime).Create(
  479. &Config{
  480. Image: GetTestImage(runtime).Id,
  481. Cmd: []string{"/bin/cat"},
  482. OpenStdin: true,
  483. },
  484. )
  485. if err != nil {
  486. t.Fatal(err)
  487. }
  488. defer runtime.Destroy(container)
  489. if err := container.Start(); err != nil {
  490. t.Fatal(err)
  491. }
  492. // Give some time to the process to start
  493. container.WaitTimeout(500 * time.Millisecond)
  494. if !container.State.Running {
  495. t.Errorf("Container should be running")
  496. }
  497. r := httptest.NewRecorder()
  498. // Note: as it is a POST request, it requires a body.
  499. req, err := http.NewRequest("POST", "/containers/"+container.Id+"/stop?t=1", bytes.NewReader([]byte{}))
  500. if err != nil {
  501. t.Fatal(err)
  502. }
  503. body, err := postContainersStop(srv, r, req, map[string]string{"name": container.Id})
  504. if err != nil {
  505. t.Fatal(err)
  506. }
  507. if body != nil {
  508. t.Fatalf("No body expected, received: %s\n", body)
  509. }
  510. if r.Code != http.StatusNoContent {
  511. t.Fatalf("%d NO CONTENT expected, received %d\n", http.StatusNoContent, r.Code)
  512. }
  513. if container.State.Running {
  514. t.Fatalf("The container hasn't been stopped")
  515. }
  516. }
  517. func TestPostContainersWait(t *testing.T) {
  518. runtime, err := newTestRuntime()
  519. if err != nil {
  520. t.Fatal(err)
  521. }
  522. defer nuke(runtime)
  523. srv := &Server{runtime: runtime}
  524. container, err := NewBuilder(runtime).Create(
  525. &Config{
  526. Image: GetTestImage(runtime).Id,
  527. Cmd: []string{"/bin/sleep", "1"},
  528. OpenStdin: true,
  529. },
  530. )
  531. if err != nil {
  532. t.Fatal(err)
  533. }
  534. defer runtime.Destroy(container)
  535. if err := container.Start(); err != nil {
  536. t.Fatal(err)
  537. }
  538. setTimeout(t, "Wait timed out", 3*time.Second, func() {
  539. body, err := postContainersWait(srv, nil, nil, nil)
  540. if err != nil {
  541. t.Fatal(err)
  542. }
  543. apiWait := &ApiWait{}
  544. if err := json.Unmarshal(body, apiWait); err != nil {
  545. t.Fatal(err)
  546. }
  547. if apiWait.StatusCode != 0 {
  548. t.Fatalf("Non zero exit code for sleep: %d\n", apiWait.StatusCode)
  549. }
  550. })
  551. if container.State.Running {
  552. t.Fatalf("The container should be stopped after wait")
  553. }
  554. }
  555. func TestPostContainersAttach(t *testing.T) {
  556. //FIXME: Implement this test
  557. t.Log("Test on implemented")
  558. }
  559. // FIXME: Test deleting runnign container
  560. // FIXME: Test deleting container with volume
  561. // FIXME: Test deleting volume in use by other container
  562. func TestDeleteContainers(t *testing.T) {
  563. runtime, err := newTestRuntime()
  564. if err != nil {
  565. t.Fatal(err)
  566. }
  567. defer nuke(runtime)
  568. srv := &Server{runtime: runtime}
  569. container, err := NewBuilder(runtime).Create(&Config{
  570. Image: GetTestImage(runtime).Id,
  571. Cmd: []string{"touch", "/test"},
  572. })
  573. if err != nil {
  574. t.Fatal(err)
  575. }
  576. defer runtime.Destroy(container)
  577. if err := container.Run(); err != nil {
  578. t.Fatal(err)
  579. }
  580. r := httptest.NewRecorder()
  581. req, err := http.NewRequest("DELETE", "/containers/"+container.Id, nil)
  582. if err != nil {
  583. t.Fatal(err)
  584. }
  585. body, err := deleteContainers(srv, r, req, map[string]string{"name": container.Id})
  586. if err != nil {
  587. t.Fatal(err)
  588. }
  589. if body != nil {
  590. t.Fatalf("No body expected, received: %s\n", body)
  591. }
  592. if r.Code != http.StatusNoContent {
  593. t.Fatalf("%d NO CONTENT expected, received %d\n", http.StatusNoContent, r.Code)
  594. }
  595. if c := runtime.Get(container.Id); c != nil {
  596. t.Fatalf("The container as not been deleted")
  597. }
  598. if _, err := os.Stat(path.Join(container.rwPath(), "test")); err == nil {
  599. t.Fatalf("The test file has not been deleted")
  600. }
  601. }
  602. func TestDeleteImages(t *testing.T) {
  603. //FIXME: Implement this test
  604. t.Log("Test on implemented")
  605. }