api_test.go 32 KB

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