api_test.go 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221
  1. package docker
  2. import (
  3. "archive/tar"
  4. "bufio"
  5. "bytes"
  6. "encoding/json"
  7. "github.com/dotcloud/docker/auth"
  8. "io"
  9. "net"
  10. "net/http"
  11. "net/http/httptest"
  12. "os"
  13. "path"
  14. "testing"
  15. "time"
  16. )
  17. func TestGetAuth(t *testing.T) {
  18. runtime, err := newTestRuntime()
  19. if err != nil {
  20. t.Fatal(err)
  21. }
  22. defer nuke(runtime)
  23. srv := &Server{runtime: runtime}
  24. r := httptest.NewRecorder()
  25. authConfig := &auth.AuthConfig{
  26. Username: "utest",
  27. Password: "utest",
  28. Email: "utest@yopmail.com",
  29. }
  30. authConfigJson, err := json.Marshal(authConfig)
  31. if err != nil {
  32. t.Fatal(err)
  33. }
  34. req, err := http.NewRequest("POST", "/auth", bytes.NewReader(authConfigJson))
  35. if err != nil {
  36. t.Fatal(err)
  37. }
  38. if err := postAuth(srv, r, req, nil); err != nil {
  39. t.Fatal(err)
  40. }
  41. if r.Code != http.StatusOK && r.Code != 0 {
  42. t.Fatalf("%d OK or 0 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. r := httptest.NewRecorder()
  58. if err := getVersion(srv, r, nil, nil); err != nil {
  59. t.Fatal(err)
  60. }
  61. v := &ApiVersion{}
  62. if err = json.Unmarshal(r.Body.Bytes(), v); err != nil {
  63. t.Fatal(err)
  64. }
  65. if v.Version != VERSION {
  66. t.Errorf("Excepted version %s, %s found", VERSION, v.Version)
  67. }
  68. }
  69. func TestGetInfo(t *testing.T) {
  70. runtime, err := newTestRuntime()
  71. if err != nil {
  72. t.Fatal(err)
  73. }
  74. defer nuke(runtime)
  75. srv := &Server{runtime: runtime}
  76. r := httptest.NewRecorder()
  77. if err := getInfo(srv, r, nil, nil); err != nil {
  78. t.Fatal(err)
  79. }
  80. infos := &ApiInfo{}
  81. err = json.Unmarshal(r.Body.Bytes(), infos)
  82. if err != nil {
  83. t.Fatal(err)
  84. }
  85. if infos.Version != VERSION {
  86. t.Errorf("Excepted version %s, %s found", VERSION, infos.Version)
  87. }
  88. }
  89. func TestGetImagesJson(t *testing.T) {
  90. runtime, err := newTestRuntime()
  91. if err != nil {
  92. t.Fatal(err)
  93. }
  94. defer nuke(runtime)
  95. srv := &Server{runtime: runtime}
  96. // all=0
  97. req, err := http.NewRequest("GET", "/images/json?all=0", nil)
  98. if err != nil {
  99. t.Fatal(err)
  100. }
  101. r := httptest.NewRecorder()
  102. if err := getImagesJson(srv, r, req, nil); err != nil {
  103. t.Fatal(err)
  104. }
  105. images := []ApiImages{}
  106. if err := json.Unmarshal(r.Body.Bytes(), &images); err != nil {
  107. t.Fatal(err)
  108. }
  109. if len(images) != 1 {
  110. t.Errorf("Excepted 1 image, %d found", len(images))
  111. }
  112. if images[0].Repository != unitTestImageName {
  113. t.Errorf("Excepted image %s, %s found", unitTestImageName, images[0].Repository)
  114. }
  115. r2 := httptest.NewRecorder()
  116. // all=1
  117. req2, err := http.NewRequest("GET", "/images/json?all=1", nil)
  118. if err != nil {
  119. t.Fatal(err)
  120. }
  121. if err := getImagesJson(srv, r2, req2, nil); err != nil {
  122. t.Fatal(err)
  123. }
  124. images2 := []ApiImages{}
  125. if err := json.Unmarshal(r2.Body.Bytes(), &images2); err != nil {
  126. t.Fatal(err)
  127. }
  128. if len(images2) != 1 {
  129. t.Errorf("Excepted 1 image, %d found", len(images2))
  130. }
  131. if images2[0].Id != GetTestImage(runtime).Id {
  132. t.Errorf("Retrieved image Id differs, expected %s, received %s", GetTestImage(runtime).Id, images2[0].Id)
  133. }
  134. r3 := httptest.NewRecorder()
  135. // filter=a
  136. req3, err := http.NewRequest("GET", "/images/json?filter=a", nil)
  137. if err != nil {
  138. t.Fatal(err)
  139. }
  140. if err := getImagesJson(srv, r3, req3, nil); err != nil {
  141. t.Fatal(err)
  142. }
  143. images3 := []ApiImages{}
  144. if err := json.Unmarshal(r3.Body.Bytes(), &images3); err != nil {
  145. t.Fatal(err)
  146. }
  147. if len(images3) != 0 {
  148. t.Errorf("Excepted 1 image, %d found", len(images3))
  149. }
  150. }
  151. func TestGetImagesViz(t *testing.T) {
  152. runtime, err := newTestRuntime()
  153. if err != nil {
  154. t.Fatal(err)
  155. }
  156. defer nuke(runtime)
  157. srv := &Server{runtime: runtime}
  158. r := httptest.NewRecorder()
  159. if err := getImagesViz(srv, r, nil, nil); err != nil {
  160. t.Fatal(err)
  161. }
  162. if r.Code != http.StatusOK {
  163. t.Fatalf("%d OK expected, received %d\n", http.StatusOK, r.Code)
  164. }
  165. reader := bufio.NewReader(r.Body)
  166. line, err := reader.ReadString('\n')
  167. if err != nil {
  168. t.Fatal(err)
  169. }
  170. if line != "digraph docker {\n" {
  171. t.Errorf("Excepted digraph docker {\n, %s found", line)
  172. }
  173. }
  174. func TestGetImagesSearch(t *testing.T) {
  175. runtime, err := newTestRuntime()
  176. if err != nil {
  177. t.Fatal(err)
  178. }
  179. defer nuke(runtime)
  180. srv := &Server{runtime: runtime}
  181. r := httptest.NewRecorder()
  182. req, err := http.NewRequest("GET", "/images/search?term=redis", nil)
  183. if err != nil {
  184. t.Fatal(err)
  185. }
  186. if err := getImagesSearch(srv, r, req, nil); err != nil {
  187. t.Fatal(err)
  188. }
  189. results := []ApiSearch{}
  190. if err := json.Unmarshal(r.Body.Bytes(), &results); err != nil {
  191. t.Fatal(err)
  192. }
  193. if len(results) < 2 {
  194. t.Errorf("Excepted at least 2 lines, %d found", len(results))
  195. }
  196. }
  197. func TestGetImagesHistory(t *testing.T) {
  198. runtime, err := newTestRuntime()
  199. if err != nil {
  200. t.Fatal(err)
  201. }
  202. defer nuke(runtime)
  203. srv := &Server{runtime: runtime}
  204. r := httptest.NewRecorder()
  205. if err := getImagesHistory(srv, r, nil, map[string]string{"name": unitTestImageName}); err != nil {
  206. t.Fatal(err)
  207. }
  208. history := []ApiHistory{}
  209. if err := json.Unmarshal(r.Body.Bytes(), &history); err != nil {
  210. t.Fatal(err)
  211. }
  212. if len(history) != 1 {
  213. t.Errorf("Excepted 1 line, %d found", len(history))
  214. }
  215. }
  216. func TestGetImagesByName(t *testing.T) {
  217. runtime, err := newTestRuntime()
  218. if err != nil {
  219. t.Fatal(err)
  220. }
  221. defer nuke(runtime)
  222. srv := &Server{runtime: runtime}
  223. r := httptest.NewRecorder()
  224. if err := getImagesByName(srv, r, nil, map[string]string{"name": unitTestImageName}); err != nil {
  225. t.Fatal(err)
  226. }
  227. img := &Image{}
  228. if err := json.Unmarshal(r.Body.Bytes(), img); err != nil {
  229. t.Fatal(err)
  230. }
  231. if img.Id != GetTestImage(runtime).Id || img.Comment != "Imported from http://get.docker.io/images/busybox" {
  232. t.Errorf("Error inspecting image")
  233. }
  234. }
  235. func TestGetContainersPs(t *testing.T) {
  236. runtime, err := newTestRuntime()
  237. if err != nil {
  238. t.Fatal(err)
  239. }
  240. defer nuke(runtime)
  241. srv := &Server{runtime: runtime}
  242. container, err := NewBuilder(runtime).Create(&Config{
  243. Image: GetTestImage(runtime).Id,
  244. Cmd: []string{"echo", "test"},
  245. })
  246. if err != nil {
  247. t.Fatal(err)
  248. }
  249. defer runtime.Destroy(container)
  250. req, err := http.NewRequest("GET", "/containers?quiet=1&all=1", nil)
  251. if err != nil {
  252. t.Fatal(err)
  253. }
  254. r := httptest.NewRecorder()
  255. if err := getContainersPs(srv, r, req, nil); err != nil {
  256. t.Fatal(err)
  257. }
  258. containers := []ApiContainers{}
  259. if err := json.Unmarshal(r.Body.Bytes(), &containers); err != nil {
  260. t.Fatal(err)
  261. }
  262. if len(containers) != 1 {
  263. t.Fatalf("Excepted %d container, %d found", 1, len(containers))
  264. }
  265. if containers[0].Id != container.Id {
  266. t.Fatalf("Container ID mismatch. Expected: %s, received: %s\n", container.Id, containers[0].Id)
  267. }
  268. }
  269. func TestGetContainersExport(t *testing.T) {
  270. runtime, err := newTestRuntime()
  271. if err != nil {
  272. t.Fatal(err)
  273. }
  274. defer nuke(runtime)
  275. srv := &Server{runtime: runtime}
  276. builder := NewBuilder(runtime)
  277. // Create a container and remove a file
  278. container, err := builder.Create(
  279. &Config{
  280. Image: GetTestImage(runtime).Id,
  281. Cmd: []string{"touch", "/test"},
  282. },
  283. )
  284. if err != nil {
  285. t.Fatal(err)
  286. }
  287. defer runtime.Destroy(container)
  288. if err := container.Run(); err != nil {
  289. t.Fatal(err)
  290. }
  291. r := httptest.NewRecorder()
  292. if err = getContainersExport(srv, r, nil, map[string]string{"name": container.Id}); err != nil {
  293. t.Fatal(err)
  294. }
  295. if r.Code != http.StatusOK {
  296. t.Fatalf("%d OK expected, received %d\n", http.StatusOK, r.Code)
  297. }
  298. found := false
  299. for tarReader := tar.NewReader(r.Body); ; {
  300. h, err := tarReader.Next()
  301. if err != nil {
  302. if err == io.EOF {
  303. break
  304. }
  305. t.Fatal(err)
  306. }
  307. if h.Name == "./test" {
  308. found = true
  309. break
  310. }
  311. }
  312. if !found {
  313. t.Fatalf("The created test file has not been found in the exported image")
  314. }
  315. }
  316. func TestGetContainersChanges(t *testing.T) {
  317. runtime, err := newTestRuntime()
  318. if err != nil {
  319. t.Fatal(err)
  320. }
  321. defer nuke(runtime)
  322. srv := &Server{runtime: runtime}
  323. builder := NewBuilder(runtime)
  324. // Create a container and remove a file
  325. container, err := builder.Create(
  326. &Config{
  327. Image: GetTestImage(runtime).Id,
  328. Cmd: []string{"/bin/rm", "/etc/passwd"},
  329. },
  330. )
  331. if err != nil {
  332. t.Fatal(err)
  333. }
  334. defer runtime.Destroy(container)
  335. if err := container.Run(); err != nil {
  336. t.Fatal(err)
  337. }
  338. r := httptest.NewRecorder()
  339. if err := getContainersChanges(srv, r, nil, map[string]string{"name": container.Id}); err != nil {
  340. t.Fatal(err)
  341. }
  342. changes := []Change{}
  343. if err := json.Unmarshal(r.Body.Bytes(), &changes); err != nil {
  344. t.Fatal(err)
  345. }
  346. // Check the changelog
  347. success := false
  348. for _, elem := range changes {
  349. if elem.Path == "/etc/passwd" && elem.Kind == 2 {
  350. success = true
  351. }
  352. }
  353. if !success {
  354. t.Fatalf("/etc/passwd as been removed but is not present in the diff")
  355. }
  356. }
  357. func TestGetContainersByName(t *testing.T) {
  358. runtime, err := newTestRuntime()
  359. if err != nil {
  360. t.Fatal(err)
  361. }
  362. defer nuke(runtime)
  363. srv := &Server{runtime: runtime}
  364. builder := NewBuilder(runtime)
  365. // Create a container and remove a file
  366. container, err := builder.Create(
  367. &Config{
  368. Image: GetTestImage(runtime).Id,
  369. Cmd: []string{"echo", "test"},
  370. },
  371. )
  372. if err != nil {
  373. t.Fatal(err)
  374. }
  375. defer runtime.Destroy(container)
  376. r := httptest.NewRecorder()
  377. if err := getContainersByName(srv, r, nil, map[string]string{"name": container.Id}); err != nil {
  378. t.Fatal(err)
  379. }
  380. outContainer := &Container{}
  381. if err := json.Unmarshal(r.Body.Bytes(), outContainer); err != nil {
  382. t.Fatal(err)
  383. }
  384. if outContainer.Id != container.Id {
  385. t.Fatalf("Wrong containers retrieved. Expected %s, recieved %s", container.Id, outContainer.Id)
  386. }
  387. }
  388. func TestPostAuth(t *testing.T) {
  389. runtime, err := newTestRuntime()
  390. if err != nil {
  391. t.Fatal(err)
  392. }
  393. defer nuke(runtime)
  394. srv := &Server{runtime: runtime}
  395. authConfigOrig := &auth.AuthConfig{
  396. Username: "utest",
  397. Email: "utest@yopmail.com",
  398. }
  399. runtime.authConfig = authConfigOrig
  400. r := httptest.NewRecorder()
  401. if err := getAuth(srv, r, nil, nil); err != nil {
  402. t.Fatal(err)
  403. }
  404. authConfig := &auth.AuthConfig{}
  405. if err := json.Unmarshal(r.Body.Bytes(), authConfig); err != nil {
  406. t.Fatal(err)
  407. }
  408. if authConfig.Username != authConfigOrig.Username || authConfig.Email != authConfigOrig.Email {
  409. t.Errorf("The retrieve auth mismatch with the one set.")
  410. }
  411. }
  412. func TestPostCommit(t *testing.T) {
  413. runtime, err := newTestRuntime()
  414. if err != nil {
  415. t.Fatal(err)
  416. }
  417. defer nuke(runtime)
  418. srv := &Server{runtime: runtime}
  419. builder := NewBuilder(runtime)
  420. // Create a container and remove a file
  421. container, err := builder.Create(
  422. &Config{
  423. Image: GetTestImage(runtime).Id,
  424. Cmd: []string{"touch", "/test"},
  425. },
  426. )
  427. if err != nil {
  428. t.Fatal(err)
  429. }
  430. defer runtime.Destroy(container)
  431. if err := container.Run(); err != nil {
  432. t.Fatal(err)
  433. }
  434. req, err := http.NewRequest("POST", "/commit?repo=testrepo&testtag=tag&container="+container.Id, bytes.NewReader([]byte{}))
  435. if err != nil {
  436. t.Fatal(err)
  437. }
  438. r := httptest.NewRecorder()
  439. if err := postCommit(srv, r, req, nil); err != nil {
  440. t.Fatal(err)
  441. }
  442. if r.Code != http.StatusCreated {
  443. t.Fatalf("%d Created expected, received %d\n", http.StatusCreated, r.Code)
  444. }
  445. apiId := &ApiId{}
  446. if err := json.Unmarshal(r.Body.Bytes(), apiId); err != nil {
  447. t.Fatal(err)
  448. }
  449. if _, err := runtime.graph.Get(apiId.Id); err != nil {
  450. t.Fatalf("The image has not been commited")
  451. }
  452. }
  453. func TestPostBuild(t *testing.T) {
  454. runtime, err := newTestRuntime()
  455. if err != nil {
  456. t.Fatal(err)
  457. }
  458. defer nuke(runtime)
  459. srv := &Server{runtime: runtime}
  460. stdin, stdinPipe := io.Pipe()
  461. stdout, stdoutPipe := io.Pipe()
  462. c1 := make(chan struct{})
  463. go func() {
  464. defer close(c1)
  465. r := &hijackTester{
  466. ResponseRecorder: httptest.NewRecorder(),
  467. in: stdin,
  468. out: stdoutPipe,
  469. }
  470. if err := postBuild(srv, r, nil, nil); err != nil {
  471. t.Fatal(err)
  472. }
  473. }()
  474. // Acknowledge hijack
  475. setTimeout(t, "hijack acknowledge timed out", 2*time.Second, func() {
  476. stdout.Read([]byte{})
  477. stdout.Read(make([]byte, 4096))
  478. })
  479. setTimeout(t, "read/write assertion timed out", 2*time.Second, func() {
  480. if err := assertPipe("from docker-ut\n", "FROM docker-ut", stdout, stdinPipe, 15); err != nil {
  481. t.Fatal(err)
  482. }
  483. })
  484. // Close pipes (client disconnects)
  485. if err := closeWrap(stdin, stdinPipe, stdout, stdoutPipe); err != nil {
  486. t.Fatal(err)
  487. }
  488. // Wait for build to finish, the client disconnected, therefore, Build finished his job
  489. setTimeout(t, "Waiting for CmdBuild timed out", 2*time.Second, func() {
  490. <-c1
  491. })
  492. }
  493. func TestPostImagesCreate(t *testing.T) {
  494. // FIXME: Use the staging in order to perform tests
  495. // runtime, err := newTestRuntime()
  496. // if err != nil {
  497. // t.Fatal(err)
  498. // }
  499. // defer nuke(runtime)
  500. // srv := &Server{runtime: runtime}
  501. // stdin, stdinPipe := io.Pipe()
  502. // stdout, stdoutPipe := io.Pipe()
  503. // c1 := make(chan struct{})
  504. // go func() {
  505. // defer close(c1)
  506. // r := &hijackTester{
  507. // ResponseRecorder: httptest.NewRecorder(),
  508. // in: stdin,
  509. // out: stdoutPipe,
  510. // }
  511. // req, err := http.NewRequest("POST", "/images/create?fromImage="+unitTestImageName, bytes.NewReader([]byte{}))
  512. // if err != nil {
  513. // t.Fatal(err)
  514. // }
  515. // body, err := postImagesCreate(srv, r, req, nil)
  516. // if err != nil {
  517. // t.Fatal(err)
  518. // }
  519. // if body != nil {
  520. // t.Fatalf("No body expected, received: %s\n", body)
  521. // }
  522. // }()
  523. // // Acknowledge hijack
  524. // setTimeout(t, "hijack acknowledge timed out", 2*time.Second, func() {
  525. // stdout.Read([]byte{})
  526. // stdout.Read(make([]byte, 4096))
  527. // })
  528. // setTimeout(t, "Waiting for imagesCreate output", 5*time.Second, func() {
  529. // reader := bufio.NewReader(stdout)
  530. // line, err := reader.ReadString('\n')
  531. // if err != nil {
  532. // t.Fatal(err)
  533. // }
  534. // if !strings.HasPrefix(line, "Pulling repository d from") {
  535. // t.Fatalf("Expected Pulling repository docker-ut from..., found %s", line)
  536. // }
  537. // })
  538. // // Close pipes (client disconnects)
  539. // if err := closeWrap(stdin, stdinPipe, stdout, stdoutPipe); err != nil {
  540. // t.Fatal(err)
  541. // }
  542. // // Wait for imagesCreate to finish, the client disconnected, therefore, Create finished his job
  543. // setTimeout(t, "Waiting for imagesCreate timed out", 10*time.Second, func() {
  544. // <-c1
  545. // })
  546. }
  547. // func TestPostImagesInsert(t *testing.T) {
  548. // //FIXME: Implement this test (or remove this endpoint)
  549. // t.Log("Test not implemented")
  550. // }
  551. func TestPostImagesPush(t *testing.T) {
  552. //FIXME: Use staging in order to perform tests
  553. // runtime, err := newTestRuntime()
  554. // if err != nil {
  555. // t.Fatal(err)
  556. // }
  557. // defer nuke(runtime)
  558. // srv := &Server{runtime: runtime}
  559. // stdin, stdinPipe := io.Pipe()
  560. // stdout, stdoutPipe := io.Pipe()
  561. // c1 := make(chan struct{})
  562. // go func() {
  563. // r := &hijackTester{
  564. // ResponseRecorder: httptest.NewRecorder(),
  565. // in: stdin,
  566. // out: stdoutPipe,
  567. // }
  568. // req, err := http.NewRequest("POST", "/images/docker-ut/push", bytes.NewReader([]byte{}))
  569. // if err != nil {
  570. // t.Fatal(err)
  571. // }
  572. // body, err := postImagesPush(srv, r, req, map[string]string{"name": "docker-ut"})
  573. // close(c1)
  574. // if err != nil {
  575. // t.Fatal(err)
  576. // }
  577. // if body != nil {
  578. // t.Fatalf("No body expected, received: %s\n", body)
  579. // }
  580. // }()
  581. // // Acknowledge hijack
  582. // setTimeout(t, "hijack acknowledge timed out", 2*time.Second, func() {
  583. // stdout.Read([]byte{})
  584. // stdout.Read(make([]byte, 4096))
  585. // })
  586. // setTimeout(t, "Waiting for imagesCreate output", 5*time.Second, func() {
  587. // reader := bufio.NewReader(stdout)
  588. // line, err := reader.ReadString('\n')
  589. // if err != nil {
  590. // t.Fatal(err)
  591. // }
  592. // if !strings.HasPrefix(line, "Processing checksum") {
  593. // t.Fatalf("Processing checksum..., found %s", line)
  594. // }
  595. // })
  596. // // Close pipes (client disconnects)
  597. // if err := closeWrap(stdin, stdinPipe, stdout, stdoutPipe); err != nil {
  598. // t.Fatal(err)
  599. // }
  600. // // Wait for imagesPush to finish, the client disconnected, therefore, Push finished his job
  601. // setTimeout(t, "Waiting for imagesPush timed out", 10*time.Second, func() {
  602. // <-c1
  603. // })
  604. }
  605. func TestPostImagesTag(t *testing.T) {
  606. // FIXME: Use staging in order to perform tests
  607. // runtime, err := newTestRuntime()
  608. // if err != nil {
  609. // t.Fatal(err)
  610. // }
  611. // defer nuke(runtime)
  612. // srv := &Server{runtime: runtime}
  613. // r := httptest.NewRecorder()
  614. // req, err := http.NewRequest("POST", "/images/docker-ut/tag?repo=testrepo&tag=testtag", bytes.NewReader([]byte{}))
  615. // if err != nil {
  616. // t.Fatal(err)
  617. // }
  618. // body, err := postImagesTag(srv, r, req, map[string]string{"name": "docker-ut"})
  619. // if err != nil {
  620. // t.Fatal(err)
  621. // }
  622. // if body != nil {
  623. // t.Fatalf("No body expected, received: %s\n", body)
  624. // }
  625. // if r.Code != http.StatusCreated {
  626. // t.Fatalf("%d Created expected, received %d\n", http.StatusCreated, r.Code)
  627. // }
  628. }
  629. func TestPostContainersCreate(t *testing.T) {
  630. runtime, err := newTestRuntime()
  631. if err != nil {
  632. t.Fatal(err)
  633. }
  634. defer nuke(runtime)
  635. srv := &Server{runtime: runtime}
  636. configJson, err := json.Marshal(&Config{
  637. Image: GetTestImage(runtime).Id,
  638. Memory: 33554432,
  639. Cmd: []string{"touch", "/test"},
  640. })
  641. if err != nil {
  642. t.Fatal(err)
  643. }
  644. req, err := http.NewRequest("POST", "/containers/create", bytes.NewReader(configJson))
  645. if err != nil {
  646. t.Fatal(err)
  647. }
  648. r := httptest.NewRecorder()
  649. if err := postContainersCreate(srv, r, req, nil); err != nil {
  650. t.Fatal(err)
  651. }
  652. if r.Code != http.StatusCreated {
  653. t.Fatalf("%d Created expected, received %d\n", http.StatusCreated, r.Code)
  654. }
  655. apiRun := &ApiRun{}
  656. if err := json.Unmarshal(r.Body.Bytes(), apiRun); err != nil {
  657. t.Fatal(err)
  658. }
  659. container := srv.runtime.Get(apiRun.Id)
  660. if container == nil {
  661. t.Fatalf("Container not created")
  662. }
  663. if err := container.Run(); err != nil {
  664. t.Fatal(err)
  665. }
  666. if _, err := os.Stat(path.Join(container.rwPath(), "test")); err != nil {
  667. if os.IsNotExist(err) {
  668. utils.Debugf("Err: %s", err)
  669. t.Fatalf("The test file has not been created")
  670. }
  671. t.Fatal(err)
  672. }
  673. }
  674. func TestPostContainersKill(t *testing.T) {
  675. runtime, err := newTestRuntime()
  676. if err != nil {
  677. t.Fatal(err)
  678. }
  679. defer nuke(runtime)
  680. srv := &Server{runtime: runtime}
  681. container, err := NewBuilder(runtime).Create(
  682. &Config{
  683. Image: GetTestImage(runtime).Id,
  684. Cmd: []string{"/bin/cat"},
  685. OpenStdin: true,
  686. },
  687. )
  688. if err != nil {
  689. t.Fatal(err)
  690. }
  691. defer runtime.Destroy(container)
  692. if err := container.Start(); err != nil {
  693. t.Fatal(err)
  694. }
  695. // Give some time to the process to start
  696. container.WaitTimeout(500 * time.Millisecond)
  697. if !container.State.Running {
  698. t.Errorf("Container should be running")
  699. }
  700. r := httptest.NewRecorder()
  701. if err := postContainersKill(srv, r, nil, map[string]string{"name": container.Id}); err != nil {
  702. t.Fatal(err)
  703. }
  704. if r.Code != http.StatusNoContent {
  705. t.Fatalf("%d NO CONTENT expected, received %d\n", http.StatusNoContent, r.Code)
  706. }
  707. if container.State.Running {
  708. t.Fatalf("The container hasn't been killed")
  709. }
  710. }
  711. func TestPostContainersRestart(t *testing.T) {
  712. runtime, err := newTestRuntime()
  713. if err != nil {
  714. t.Fatal(err)
  715. }
  716. defer nuke(runtime)
  717. srv := &Server{runtime: runtime}
  718. container, err := NewBuilder(runtime).Create(
  719. &Config{
  720. Image: GetTestImage(runtime).Id,
  721. Cmd: []string{"/bin/cat"},
  722. OpenStdin: true,
  723. },
  724. )
  725. if err != nil {
  726. t.Fatal(err)
  727. }
  728. defer runtime.Destroy(container)
  729. if err := container.Start(); err != nil {
  730. t.Fatal(err)
  731. }
  732. // Give some time to the process to start
  733. container.WaitTimeout(500 * time.Millisecond)
  734. if !container.State.Running {
  735. t.Errorf("Container should be running")
  736. }
  737. req, err := http.NewRequest("POST", "/containers/"+container.Id+"/restart?t=1", bytes.NewReader([]byte{}))
  738. if err != nil {
  739. t.Fatal(err)
  740. }
  741. r := httptest.NewRecorder()
  742. if err := postContainersRestart(srv, r, req, map[string]string{"name": container.Id}); err != nil {
  743. t.Fatal(err)
  744. }
  745. if r.Code != http.StatusNoContent {
  746. t.Fatalf("%d NO CONTENT expected, received %d\n", http.StatusNoContent, r.Code)
  747. }
  748. // Give some time to the process to restart
  749. container.WaitTimeout(500 * time.Millisecond)
  750. if !container.State.Running {
  751. t.Fatalf("Container should be running")
  752. }
  753. if err := container.Kill(); err != nil {
  754. t.Fatal(err)
  755. }
  756. }
  757. func TestPostContainersStart(t *testing.T) {
  758. runtime, err := newTestRuntime()
  759. if err != nil {
  760. t.Fatal(err)
  761. }
  762. defer nuke(runtime)
  763. srv := &Server{runtime: runtime}
  764. container, err := NewBuilder(runtime).Create(
  765. &Config{
  766. Image: GetTestImage(runtime).Id,
  767. Cmd: []string{"/bin/cat"},
  768. OpenStdin: true,
  769. },
  770. )
  771. if err != nil {
  772. t.Fatal(err)
  773. }
  774. defer runtime.Destroy(container)
  775. r := httptest.NewRecorder()
  776. if err := postContainersStart(srv, r, nil, map[string]string{"name": container.Id}); err != nil {
  777. t.Fatal(err)
  778. }
  779. if r.Code != http.StatusNoContent {
  780. t.Fatalf("%d NO CONTENT expected, received %d\n", http.StatusNoContent, r.Code)
  781. }
  782. // Give some time to the process to start
  783. container.WaitTimeout(500 * time.Millisecond)
  784. if !container.State.Running {
  785. t.Errorf("Container should be running")
  786. }
  787. r = httptest.NewRecorder()
  788. if err = postContainersStart(srv, r, nil, map[string]string{"name": container.Id}); err == nil {
  789. t.Fatalf("A running containter should be able to be started")
  790. }
  791. if err := container.Kill(); err != nil {
  792. t.Fatal(err)
  793. }
  794. }
  795. func TestPostContainersStop(t *testing.T) {
  796. runtime, err := newTestRuntime()
  797. if err != nil {
  798. t.Fatal(err)
  799. }
  800. defer nuke(runtime)
  801. srv := &Server{runtime: runtime}
  802. container, err := NewBuilder(runtime).Create(
  803. &Config{
  804. Image: GetTestImage(runtime).Id,
  805. Cmd: []string{"/bin/cat"},
  806. OpenStdin: true,
  807. },
  808. )
  809. if err != nil {
  810. t.Fatal(err)
  811. }
  812. defer runtime.Destroy(container)
  813. if err := container.Start(); err != nil {
  814. t.Fatal(err)
  815. }
  816. // Give some time to the process to start
  817. container.WaitTimeout(500 * time.Millisecond)
  818. if !container.State.Running {
  819. t.Errorf("Container should be running")
  820. }
  821. // Note: as it is a POST request, it requires a body.
  822. req, err := http.NewRequest("POST", "/containers/"+container.Id+"/stop?t=1", bytes.NewReader([]byte{}))
  823. if err != nil {
  824. t.Fatal(err)
  825. }
  826. r := httptest.NewRecorder()
  827. if err := postContainersStop(srv, r, req, map[string]string{"name": container.Id}); err != nil {
  828. t.Fatal(err)
  829. }
  830. if r.Code != http.StatusNoContent {
  831. t.Fatalf("%d NO CONTENT expected, received %d\n", http.StatusNoContent, r.Code)
  832. }
  833. if container.State.Running {
  834. t.Fatalf("The container hasn't been stopped")
  835. }
  836. }
  837. func TestPostContainersWait(t *testing.T) {
  838. runtime, err := newTestRuntime()
  839. if err != nil {
  840. t.Fatal(err)
  841. }
  842. defer nuke(runtime)
  843. srv := &Server{runtime: runtime}
  844. container, err := NewBuilder(runtime).Create(
  845. &Config{
  846. Image: GetTestImage(runtime).Id,
  847. Cmd: []string{"/bin/sleep", "1"},
  848. OpenStdin: true,
  849. },
  850. )
  851. if err != nil {
  852. t.Fatal(err)
  853. }
  854. defer runtime.Destroy(container)
  855. if err := container.Start(); err != nil {
  856. t.Fatal(err)
  857. }
  858. setTimeout(t, "Wait timed out", 3*time.Second, func() {
  859. r := httptest.NewRecorder()
  860. if err := postContainersWait(srv, r, nil, map[string]string{"name": container.Id}); err != nil {
  861. t.Fatal(err)
  862. }
  863. apiWait := &ApiWait{}
  864. if err := json.Unmarshal(r.Body.Bytes(), apiWait); err != nil {
  865. t.Fatal(err)
  866. }
  867. if apiWait.StatusCode != 0 {
  868. t.Fatalf("Non zero exit code for sleep: %d\n", apiWait.StatusCode)
  869. }
  870. })
  871. if container.State.Running {
  872. t.Fatalf("The container should be stopped after wait")
  873. }
  874. }
  875. func TestPostContainersAttach(t *testing.T) {
  876. runtime, err := newTestRuntime()
  877. if err != nil {
  878. t.Fatal(err)
  879. }
  880. defer nuke(runtime)
  881. srv := &Server{runtime: runtime}
  882. container, err := NewBuilder(runtime).Create(
  883. &Config{
  884. Image: GetTestImage(runtime).Id,
  885. Cmd: []string{"/bin/cat"},
  886. OpenStdin: true,
  887. },
  888. )
  889. if err != nil {
  890. t.Fatal(err)
  891. }
  892. defer runtime.Destroy(container)
  893. // Start the process
  894. if err := container.Start(); err != nil {
  895. t.Fatal(err)
  896. }
  897. stdin, stdinPipe := io.Pipe()
  898. stdout, stdoutPipe := io.Pipe()
  899. // Attach to it
  900. c1 := make(chan struct{})
  901. go func() {
  902. defer close(c1)
  903. r := &hijackTester{
  904. ResponseRecorder: httptest.NewRecorder(),
  905. in: stdin,
  906. out: stdoutPipe,
  907. }
  908. req, err := http.NewRequest("POST", "/containers/"+container.Id+"/attach?stream=1&stdin=1&stdout=1&stderr=1", bytes.NewReader([]byte{}))
  909. if err != nil {
  910. t.Fatal(err)
  911. }
  912. if err := postContainersAttach(srv, r, req, map[string]string{"name": container.Id}); err != nil {
  913. t.Fatal(err)
  914. }
  915. }()
  916. // Acknowledge hijack
  917. setTimeout(t, "hijack acknowledge timed out", 2*time.Second, func() {
  918. stdout.Read([]byte{})
  919. stdout.Read(make([]byte, 4096))
  920. })
  921. setTimeout(t, "read/write assertion timed out", 2*time.Second, func() {
  922. if err := assertPipe("hello\n", "hello", stdout, stdinPipe, 15); err != nil {
  923. t.Fatal(err)
  924. }
  925. })
  926. // Close pipes (client disconnects)
  927. if err := closeWrap(stdin, stdinPipe, stdout, stdoutPipe); err != nil {
  928. t.Fatal(err)
  929. }
  930. // Wait for attach to finish, the client disconnected, therefore, Attach finished his job
  931. setTimeout(t, "Waiting for CmdAttach timed out", 2*time.Second, func() {
  932. <-c1
  933. })
  934. // We closed stdin, expect /bin/cat to still be running
  935. // Wait a little bit to make sure container.monitor() did his thing
  936. err = container.WaitTimeout(500 * time.Millisecond)
  937. if err == nil || !container.State.Running {
  938. t.Fatalf("/bin/cat is not running after closing stdin")
  939. }
  940. // Try to avoid the timeoout in destroy. Best effort, don't check error
  941. cStdin, _ := container.StdinPipe()
  942. cStdin.Close()
  943. container.Wait()
  944. }
  945. // FIXME: Test deleting running container
  946. // FIXME: Test deleting container with volume
  947. // FIXME: Test deleting volume in use by other container
  948. func TestDeleteContainers(t *testing.T) {
  949. runtime, err := newTestRuntime()
  950. if err != nil {
  951. t.Fatal(err)
  952. }
  953. defer nuke(runtime)
  954. srv := &Server{runtime: runtime}
  955. container, err := NewBuilder(runtime).Create(&Config{
  956. Image: GetTestImage(runtime).Id,
  957. Cmd: []string{"touch", "/test"},
  958. })
  959. if err != nil {
  960. t.Fatal(err)
  961. }
  962. defer runtime.Destroy(container)
  963. if err := container.Run(); err != nil {
  964. t.Fatal(err)
  965. }
  966. req, err := http.NewRequest("DELETE", "/containers/"+container.Id, nil)
  967. if err != nil {
  968. t.Fatal(err)
  969. }
  970. r := httptest.NewRecorder()
  971. if err := deleteContainers(srv, r, req, map[string]string{"name": container.Id}); err != nil {
  972. t.Fatal(err)
  973. }
  974. if r.Code != http.StatusNoContent {
  975. t.Fatalf("%d NO CONTENT expected, received %d\n", http.StatusNoContent, r.Code)
  976. }
  977. if c := runtime.Get(container.Id); c != nil {
  978. t.Fatalf("The container as not been deleted")
  979. }
  980. if _, err := os.Stat(path.Join(container.rwPath(), "test")); err == nil {
  981. t.Fatalf("The test file has not been deleted")
  982. }
  983. }
  984. func TestDeleteImages(t *testing.T) {
  985. //FIXME: Implement this test
  986. t.Log("Test not implemented")
  987. }
  988. // Mocked types for tests
  989. type NopConn struct {
  990. io.ReadCloser
  991. io.Writer
  992. }
  993. func (c *NopConn) LocalAddr() net.Addr { return nil }
  994. func (c *NopConn) RemoteAddr() net.Addr { return nil }
  995. func (c *NopConn) SetDeadline(t time.Time) error { return nil }
  996. func (c *NopConn) SetReadDeadline(t time.Time) error { return nil }
  997. func (c *NopConn) SetWriteDeadline(t time.Time) error { return nil }
  998. type hijackTester struct {
  999. *httptest.ResponseRecorder
  1000. in io.ReadCloser
  1001. out io.Writer
  1002. }
  1003. func (t *hijackTester) Hijack() (net.Conn, *bufio.ReadWriter, error) {
  1004. bufrw := bufio.NewReadWriter(bufio.NewReader(t.in), bufio.NewWriter(t.out))
  1005. conn := &NopConn{
  1006. ReadCloser: t.in,
  1007. Writer: t.out,
  1008. }
  1009. return conn, bufrw, nil
  1010. }