api_test.go 34 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350
  1. package docker
  2. import (
  3. "bufio"
  4. "bytes"
  5. "encoding/json"
  6. "fmt"
  7. "io"
  8. "io/ioutil"
  9. "net"
  10. "net/http"
  11. "net/http/httptest"
  12. "strings"
  13. "testing"
  14. "time"
  15. "github.com/dotcloud/docker/api"
  16. "github.com/dotcloud/docker/api/server"
  17. "github.com/dotcloud/docker/dockerversion"
  18. "github.com/dotcloud/docker/engine"
  19. "github.com/dotcloud/docker/image"
  20. "github.com/dotcloud/docker/runconfig"
  21. "github.com/dotcloud/docker/runtime"
  22. "github.com/dotcloud/docker/utils"
  23. "github.com/dotcloud/docker/vendor/src/code.google.com/p/go/src/pkg/archive/tar"
  24. )
  25. func TestGetVersion(t *testing.T) {
  26. eng := NewTestEngine(t)
  27. defer mkRuntimeFromEngine(eng, t).Nuke()
  28. var err error
  29. r := httptest.NewRecorder()
  30. req, err := http.NewRequest("GET", "/version", nil)
  31. if err != nil {
  32. t.Fatal(err)
  33. }
  34. // FIXME getting the version should require an actual running Server
  35. if err := server.ServeRequest(eng, api.APIVERSION, r, req); err != nil {
  36. t.Fatal(err)
  37. }
  38. assertHttpNotError(r, t)
  39. out := engine.NewOutput()
  40. v, err := out.AddEnv()
  41. if err != nil {
  42. t.Fatal(err)
  43. }
  44. if _, err := io.Copy(out, r.Body); err != nil {
  45. t.Fatal(err)
  46. }
  47. out.Close()
  48. expected := dockerversion.VERSION
  49. if result := v.Get("Version"); result != expected {
  50. t.Errorf("Expected version %s, %s found", expected, result)
  51. }
  52. expected = "application/json"
  53. if result := r.HeaderMap.Get("Content-Type"); result != expected {
  54. t.Errorf("Expected Content-Type %s, %s found", expected, result)
  55. }
  56. }
  57. func TestGetInfo(t *testing.T) {
  58. eng := NewTestEngine(t)
  59. defer mkRuntimeFromEngine(eng, t).Nuke()
  60. job := eng.Job("images")
  61. initialImages, err := job.Stdout.AddListTable()
  62. if err != nil {
  63. t.Fatal(err)
  64. }
  65. if err := job.Run(); err != nil {
  66. t.Fatal(err)
  67. }
  68. req, err := http.NewRequest("GET", "/info", nil)
  69. if err != nil {
  70. t.Fatal(err)
  71. }
  72. r := httptest.NewRecorder()
  73. if err := server.ServeRequest(eng, api.APIVERSION, r, req); err != nil {
  74. t.Fatal(err)
  75. }
  76. assertHttpNotError(r, t)
  77. out := engine.NewOutput()
  78. i, err := out.AddEnv()
  79. if err != nil {
  80. t.Fatal(err)
  81. }
  82. if _, err := io.Copy(out, r.Body); err != nil {
  83. t.Fatal(err)
  84. }
  85. out.Close()
  86. if images := i.GetInt("Images"); images != initialImages.Len() {
  87. t.Errorf("Expected images: %d, %d found", initialImages.Len(), images)
  88. }
  89. expected := "application/json"
  90. if result := r.HeaderMap.Get("Content-Type"); result != expected {
  91. t.Errorf("Expected Content-Type %s, %s found", expected, result)
  92. }
  93. }
  94. func TestGetEvents(t *testing.T) {
  95. eng := NewTestEngine(t)
  96. srv := mkServerFromEngine(eng, t)
  97. // FIXME: we might not need runtime, why not simply nuke
  98. // the engine?
  99. runtime := mkRuntimeFromEngine(eng, t)
  100. defer nuke(runtime)
  101. var events []*utils.JSONMessage
  102. for _, parts := range [][3]string{
  103. {"fakeaction", "fakeid", "fakeimage"},
  104. {"fakeaction2", "fakeid", "fakeimage"},
  105. } {
  106. action, id, from := parts[0], parts[1], parts[2]
  107. ev := srv.LogEvent(action, id, from)
  108. events = append(events, ev)
  109. }
  110. req, err := http.NewRequest("GET", "/events?since=1", nil)
  111. if err != nil {
  112. t.Fatal(err)
  113. }
  114. r := httptest.NewRecorder()
  115. setTimeout(t, "", 500*time.Millisecond, func() {
  116. if err := server.ServeRequest(eng, api.APIVERSION, r, req); err != nil {
  117. t.Fatal(err)
  118. }
  119. assertHttpNotError(r, t)
  120. })
  121. dec := json.NewDecoder(r.Body)
  122. for i := 0; i < 2; i++ {
  123. var jm utils.JSONMessage
  124. if err := dec.Decode(&jm); err == io.EOF {
  125. break
  126. } else if err != nil {
  127. t.Fatal(err)
  128. }
  129. if jm != *events[i] {
  130. t.Fatalf("Event received it different than expected")
  131. }
  132. }
  133. }
  134. func TestGetImagesJSON(t *testing.T) {
  135. eng := NewTestEngine(t)
  136. defer mkRuntimeFromEngine(eng, t).Nuke()
  137. job := eng.Job("images")
  138. initialImages, err := job.Stdout.AddListTable()
  139. if err != nil {
  140. t.Fatal(err)
  141. }
  142. if err := job.Run(); err != nil {
  143. t.Fatal(err)
  144. }
  145. req, err := http.NewRequest("GET", "/images/json?all=0", nil)
  146. if err != nil {
  147. t.Fatal(err)
  148. }
  149. r := httptest.NewRecorder()
  150. if err := server.ServeRequest(eng, api.APIVERSION, r, req); err != nil {
  151. t.Fatal(err)
  152. }
  153. assertHttpNotError(r, t)
  154. images := engine.NewTable("Created", 0)
  155. if _, err := images.ReadListFrom(r.Body.Bytes()); err != nil {
  156. t.Fatal(err)
  157. }
  158. if images.Len() != initialImages.Len() {
  159. t.Errorf("Expected %d image, %d found", initialImages.Len(), images.Len())
  160. }
  161. found := false
  162. for _, img := range images.Data {
  163. if strings.Contains(img.GetList("RepoTags")[0], unitTestImageName) {
  164. found = true
  165. break
  166. }
  167. }
  168. if !found {
  169. t.Errorf("Expected image %s, %+v found", unitTestImageName, images)
  170. }
  171. r2 := httptest.NewRecorder()
  172. // all=1
  173. initialImages = getAllImages(eng, t)
  174. req2, err := http.NewRequest("GET", "/images/json?all=true", nil)
  175. if err != nil {
  176. t.Fatal(err)
  177. }
  178. if err := server.ServeRequest(eng, api.APIVERSION, r2, req2); err != nil {
  179. t.Fatal(err)
  180. }
  181. assertHttpNotError(r2, t)
  182. images2 := engine.NewTable("Id", 0)
  183. if _, err := images2.ReadListFrom(r2.Body.Bytes()); err != nil {
  184. t.Fatal(err)
  185. }
  186. if images2.Len() != initialImages.Len() {
  187. t.Errorf("Expected %d image, %d found", initialImages.Len(), images2.Len())
  188. }
  189. found = false
  190. for _, img := range images2.Data {
  191. if img.Get("Id") == unitTestImageID {
  192. found = true
  193. break
  194. }
  195. }
  196. if !found {
  197. t.Errorf("Retrieved image Id differs, expected %s, received %+v", unitTestImageID, images2)
  198. }
  199. r3 := httptest.NewRecorder()
  200. // filter=a
  201. req3, err := http.NewRequest("GET", "/images/json?filter=aaaaaaaaaa", nil)
  202. if err != nil {
  203. t.Fatal(err)
  204. }
  205. if err := server.ServeRequest(eng, api.APIVERSION, r3, req3); err != nil {
  206. t.Fatal(err)
  207. }
  208. assertHttpNotError(r3, t)
  209. images3 := engine.NewTable("Id", 0)
  210. if _, err := images3.ReadListFrom(r3.Body.Bytes()); err != nil {
  211. t.Fatal(err)
  212. }
  213. if images3.Len() != 0 {
  214. t.Errorf("Expected 0 image, %d found", images3.Len())
  215. }
  216. }
  217. func TestGetImagesHistory(t *testing.T) {
  218. eng := NewTestEngine(t)
  219. defer mkRuntimeFromEngine(eng, t).Nuke()
  220. r := httptest.NewRecorder()
  221. req, err := http.NewRequest("GET", fmt.Sprintf("/images/%s/history", unitTestImageName), nil)
  222. if err != nil {
  223. t.Fatal(err)
  224. }
  225. if err := server.ServeRequest(eng, api.APIVERSION, r, req); err != nil {
  226. t.Fatal(err)
  227. }
  228. assertHttpNotError(r, t)
  229. outs := engine.NewTable("Created", 0)
  230. if _, err := outs.ReadListFrom(r.Body.Bytes()); err != nil {
  231. t.Fatal(err)
  232. }
  233. if len(outs.Data) != 1 {
  234. t.Errorf("Expected 1 line, %d found", len(outs.Data))
  235. }
  236. }
  237. func TestGetImagesByName(t *testing.T) {
  238. eng := NewTestEngine(t)
  239. defer mkRuntimeFromEngine(eng, t).Nuke()
  240. req, err := http.NewRequest("GET", "/images/"+unitTestImageName+"/json", nil)
  241. if err != nil {
  242. t.Fatal(err)
  243. }
  244. r := httptest.NewRecorder()
  245. if err := server.ServeRequest(eng, api.APIVERSION, r, req); err != nil {
  246. t.Fatal(err)
  247. }
  248. assertHttpNotError(r, t)
  249. img := &image.Image{}
  250. if err := json.Unmarshal(r.Body.Bytes(), img); err != nil {
  251. t.Fatal(err)
  252. }
  253. if img.ID != unitTestImageID {
  254. t.Errorf("Error inspecting image")
  255. }
  256. }
  257. func TestGetContainersJSON(t *testing.T) {
  258. eng := NewTestEngine(t)
  259. defer mkRuntimeFromEngine(eng, t).Nuke()
  260. job := eng.Job("containers")
  261. job.SetenvBool("all", true)
  262. outs, err := job.Stdout.AddTable()
  263. if err != nil {
  264. t.Fatal(err)
  265. }
  266. if err := job.Run(); err != nil {
  267. t.Fatal(err)
  268. }
  269. beginLen := len(outs.Data)
  270. containerID := createTestContainer(eng, &runconfig.Config{
  271. Image: unitTestImageID,
  272. Cmd: []string{"echo", "test"},
  273. }, t)
  274. if containerID == "" {
  275. t.Fatalf("Received empty container ID")
  276. }
  277. req, err := http.NewRequest("GET", "/containers/json?all=1", nil)
  278. if err != nil {
  279. t.Fatal(err)
  280. }
  281. r := httptest.NewRecorder()
  282. if err := server.ServeRequest(eng, api.APIVERSION, r, req); err != nil {
  283. t.Fatal(err)
  284. }
  285. assertHttpNotError(r, t)
  286. containers := engine.NewTable("", 0)
  287. if _, err := containers.ReadListFrom(r.Body.Bytes()); err != nil {
  288. t.Fatal(err)
  289. }
  290. if len(containers.Data) != beginLen+1 {
  291. t.Fatalf("Expected %d container, %d found (started with: %d)", beginLen+1, len(containers.Data), beginLen)
  292. }
  293. if id := containers.Data[0].Get("Id"); id != containerID {
  294. t.Fatalf("Container ID mismatch. Expected: %s, received: %s\n", containerID, id)
  295. }
  296. }
  297. func TestGetContainersExport(t *testing.T) {
  298. eng := NewTestEngine(t)
  299. defer mkRuntimeFromEngine(eng, t).Nuke()
  300. // Create a container and remove a file
  301. containerID := createTestContainer(eng,
  302. &runconfig.Config{
  303. Image: unitTestImageID,
  304. Cmd: []string{"touch", "/test"},
  305. },
  306. t,
  307. )
  308. containerRun(eng, containerID, t)
  309. r := httptest.NewRecorder()
  310. req, err := http.NewRequest("GET", "/containers/"+containerID+"/export", nil)
  311. if err != nil {
  312. t.Fatal(err)
  313. }
  314. if err := server.ServeRequest(eng, api.APIVERSION, r, req); err != nil {
  315. t.Fatal(err)
  316. }
  317. assertHttpNotError(r, t)
  318. if r.Code != http.StatusOK {
  319. t.Fatalf("%d OK expected, received %d\n", http.StatusOK, r.Code)
  320. }
  321. found := false
  322. for tarReader := tar.NewReader(r.Body); ; {
  323. h, err := tarReader.Next()
  324. if err != nil {
  325. if err == io.EOF {
  326. break
  327. }
  328. t.Fatal(err)
  329. }
  330. if h.Name == "test" {
  331. found = true
  332. break
  333. }
  334. }
  335. if !found {
  336. t.Fatalf("The created test file has not been found in the exported image")
  337. }
  338. }
  339. func TestSaveImageAndThenLoad(t *testing.T) {
  340. eng := NewTestEngine(t)
  341. defer mkRuntimeFromEngine(eng, t).Nuke()
  342. // save image
  343. r := httptest.NewRecorder()
  344. req, err := http.NewRequest("GET", "/images/"+unitTestImageID+"/get", nil)
  345. if err != nil {
  346. t.Fatal(err)
  347. }
  348. if err := server.ServeRequest(eng, api.APIVERSION, r, req); err != nil {
  349. t.Fatal(err)
  350. }
  351. if r.Code != http.StatusOK {
  352. t.Fatalf("%d OK expected, received %d\n", http.StatusOK, r.Code)
  353. }
  354. tarball := r.Body
  355. // delete the image
  356. r = httptest.NewRecorder()
  357. req, err = http.NewRequest("DELETE", "/images/"+unitTestImageID, nil)
  358. if err != nil {
  359. t.Fatal(err)
  360. }
  361. if err := server.ServeRequest(eng, api.APIVERSION, r, req); err != nil {
  362. t.Fatal(err)
  363. }
  364. if r.Code != http.StatusOK {
  365. t.Fatalf("%d OK expected, received %d\n", http.StatusOK, r.Code)
  366. }
  367. // make sure there is no image
  368. r = httptest.NewRecorder()
  369. req, err = http.NewRequest("GET", "/images/"+unitTestImageID+"/get", nil)
  370. if err != nil {
  371. t.Fatal(err)
  372. }
  373. if err := server.ServeRequest(eng, api.APIVERSION, r, req); err != nil {
  374. t.Fatal(err)
  375. }
  376. if r.Code != http.StatusNotFound {
  377. t.Fatalf("%d NotFound expected, received %d\n", http.StatusNotFound, r.Code)
  378. }
  379. // load the image
  380. r = httptest.NewRecorder()
  381. req, err = http.NewRequest("POST", "/images/load", tarball)
  382. if err != nil {
  383. t.Fatal(err)
  384. }
  385. if err := server.ServeRequest(eng, api.APIVERSION, r, req); err != nil {
  386. t.Fatal(err)
  387. }
  388. if r.Code != http.StatusOK {
  389. t.Fatalf("%d OK expected, received %d\n", http.StatusOK, r.Code)
  390. }
  391. // finally make sure the image is there
  392. r = httptest.NewRecorder()
  393. req, err = http.NewRequest("GET", "/images/"+unitTestImageID+"/get", nil)
  394. if err != nil {
  395. t.Fatal(err)
  396. }
  397. if err := server.ServeRequest(eng, api.APIVERSION, r, req); err != nil {
  398. t.Fatal(err)
  399. }
  400. if r.Code != http.StatusOK {
  401. t.Fatalf("%d OK expected, received %d\n", http.StatusOK, r.Code)
  402. }
  403. }
  404. func TestGetContainersChanges(t *testing.T) {
  405. eng := NewTestEngine(t)
  406. defer mkRuntimeFromEngine(eng, t).Nuke()
  407. // Create a container and remove a file
  408. containerID := createTestContainer(eng,
  409. &runconfig.Config{
  410. Image: unitTestImageID,
  411. Cmd: []string{"/bin/rm", "/etc/passwd"},
  412. },
  413. t,
  414. )
  415. containerRun(eng, containerID, t)
  416. r := httptest.NewRecorder()
  417. req, err := http.NewRequest("GET", "/containers/"+containerID+"/changes", nil)
  418. if err != nil {
  419. t.Fatal(err)
  420. }
  421. if err := server.ServeRequest(eng, api.APIVERSION, r, req); err != nil {
  422. t.Fatal(err)
  423. }
  424. assertHttpNotError(r, t)
  425. outs := engine.NewTable("", 0)
  426. if _, err := outs.ReadListFrom(r.Body.Bytes()); err != nil {
  427. t.Fatal(err)
  428. }
  429. // Check the changelog
  430. success := false
  431. for _, elem := range outs.Data {
  432. if elem.Get("Path") == "/etc/passwd" && elem.GetInt("Kind") == 2 {
  433. success = true
  434. }
  435. }
  436. if !success {
  437. t.Fatalf("/etc/passwd as been removed but is not present in the diff")
  438. }
  439. }
  440. func TestGetContainersTop(t *testing.T) {
  441. eng := NewTestEngine(t)
  442. defer mkRuntimeFromEngine(eng, t).Nuke()
  443. containerID := createTestContainer(eng,
  444. &runconfig.Config{
  445. Image: unitTestImageID,
  446. Cmd: []string{"/bin/sh", "-c", "cat"},
  447. OpenStdin: true,
  448. },
  449. t,
  450. )
  451. defer func() {
  452. // Make sure the process dies before destroying runtime
  453. containerKill(eng, containerID, t)
  454. containerWait(eng, containerID, t)
  455. }()
  456. startContainer(eng, containerID, t)
  457. setTimeout(t, "Waiting for the container to be started timed out", 10*time.Second, func() {
  458. for {
  459. if containerRunning(eng, containerID, t) {
  460. break
  461. }
  462. time.Sleep(10 * time.Millisecond)
  463. }
  464. })
  465. if !containerRunning(eng, containerID, t) {
  466. t.Fatalf("Container should be running")
  467. }
  468. // Make sure sh spawn up cat
  469. setTimeout(t, "read/write assertion timed out", 2*time.Second, func() {
  470. in, out := containerAttach(eng, containerID, t)
  471. if err := assertPipe("hello\n", "hello", out, in, 150); err != nil {
  472. t.Fatal(err)
  473. }
  474. })
  475. r := httptest.NewRecorder()
  476. req, err := http.NewRequest("GET", "/containers/"+containerID+"/top?ps_args=aux", nil)
  477. if err != nil {
  478. t.Fatal(err)
  479. }
  480. if err := server.ServeRequest(eng, api.APIVERSION, r, req); err != nil {
  481. t.Fatal(err)
  482. }
  483. assertHttpNotError(r, t)
  484. var procs engine.Env
  485. if err := procs.Decode(r.Body); err != nil {
  486. t.Fatal(err)
  487. }
  488. if len(procs.GetList("Titles")) != 11 {
  489. t.Fatalf("Expected 11 titles, found %d.", len(procs.GetList("Titles")))
  490. }
  491. if procs.GetList("Titles")[0] != "USER" || procs.GetList("Titles")[10] != "COMMAND" {
  492. t.Fatalf("Expected Titles[0] to be USER and Titles[10] to be COMMAND, found %s and %s.", procs.GetList("Titles")[0], procs.GetList("Titles")[10])
  493. }
  494. processes := [][]string{}
  495. if err := procs.GetJson("Processes", &processes); err != nil {
  496. t.Fatal(err)
  497. }
  498. if len(processes) != 2 {
  499. t.Fatalf("Expected 2 processes, found %d.", len(processes))
  500. }
  501. if processes[0][10] != "/bin/sh -c cat" {
  502. t.Fatalf("Expected `/bin/sh -c cat`, found %s.", processes[0][10])
  503. }
  504. if processes[1][10] != "/bin/sh -c cat" {
  505. t.Fatalf("Expected `/bin/sh -c cat`, found %s.", processes[1][10])
  506. }
  507. }
  508. func TestGetContainersByName(t *testing.T) {
  509. eng := NewTestEngine(t)
  510. defer mkRuntimeFromEngine(eng, t).Nuke()
  511. // Create a container and remove a file
  512. containerID := createTestContainer(eng,
  513. &runconfig.Config{
  514. Image: unitTestImageID,
  515. Cmd: []string{"echo", "test"},
  516. },
  517. t,
  518. )
  519. r := httptest.NewRecorder()
  520. req, err := http.NewRequest("GET", "/containers/"+containerID+"/json", nil)
  521. if err != nil {
  522. t.Fatal(err)
  523. }
  524. if err := server.ServeRequest(eng, api.APIVERSION, r, req); err != nil {
  525. t.Fatal(err)
  526. }
  527. assertHttpNotError(r, t)
  528. outContainer := &runtime.Container{}
  529. if err := json.Unmarshal(r.Body.Bytes(), outContainer); err != nil {
  530. t.Fatal(err)
  531. }
  532. if outContainer.ID != containerID {
  533. t.Fatalf("Wrong containers retrieved. Expected %s, received %s", containerID, outContainer.ID)
  534. }
  535. }
  536. func TestPostCommit(t *testing.T) {
  537. eng := NewTestEngine(t)
  538. defer mkRuntimeFromEngine(eng, t).Nuke()
  539. srv := mkServerFromEngine(eng, t)
  540. // Create a container and remove a file
  541. containerID := createTestContainer(eng,
  542. &runconfig.Config{
  543. Image: unitTestImageID,
  544. Cmd: []string{"touch", "/test"},
  545. },
  546. t,
  547. )
  548. containerRun(eng, containerID, t)
  549. req, err := http.NewRequest("POST", "/commit?repo=testrepo&testtag=tag&container="+containerID, bytes.NewReader([]byte{}))
  550. if err != nil {
  551. t.Fatal(err)
  552. }
  553. r := httptest.NewRecorder()
  554. if err := server.ServeRequest(eng, api.APIVERSION, r, req); err != nil {
  555. t.Fatal(err)
  556. }
  557. assertHttpNotError(r, t)
  558. if r.Code != http.StatusCreated {
  559. t.Fatalf("%d Created expected, received %d\n", http.StatusCreated, r.Code)
  560. }
  561. var env engine.Env
  562. if err := env.Decode(r.Body); err != nil {
  563. t.Fatal(err)
  564. }
  565. if _, err := srv.ImageInspect(env.Get("Id")); err != nil {
  566. t.Fatalf("The image has not been committed")
  567. }
  568. }
  569. func TestPostContainersCreate(t *testing.T) {
  570. eng := NewTestEngine(t)
  571. defer mkRuntimeFromEngine(eng, t).Nuke()
  572. configJSON, err := json.Marshal(&runconfig.Config{
  573. Image: unitTestImageID,
  574. Memory: 33554432,
  575. Cmd: []string{"touch", "/test"},
  576. })
  577. if err != nil {
  578. t.Fatal(err)
  579. }
  580. req, err := http.NewRequest("POST", "/containers/create", bytes.NewReader(configJSON))
  581. if err != nil {
  582. t.Fatal(err)
  583. }
  584. r := httptest.NewRecorder()
  585. if err := server.ServeRequest(eng, api.APIVERSION, r, req); err != nil {
  586. t.Fatal(err)
  587. }
  588. assertHttpNotError(r, t)
  589. if r.Code != http.StatusCreated {
  590. t.Fatalf("%d Created expected, received %d\n", http.StatusCreated, r.Code)
  591. }
  592. var apiRun engine.Env
  593. if err := apiRun.Decode(r.Body); err != nil {
  594. t.Fatal(err)
  595. }
  596. containerID := apiRun.Get("Id")
  597. containerAssertExists(eng, containerID, t)
  598. containerRun(eng, containerID, t)
  599. if !containerFileExists(eng, containerID, "test", t) {
  600. t.Fatal("Test file was not created")
  601. }
  602. }
  603. func TestPostContainersKill(t *testing.T) {
  604. eng := NewTestEngine(t)
  605. defer mkRuntimeFromEngine(eng, t).Nuke()
  606. containerID := createTestContainer(eng,
  607. &runconfig.Config{
  608. Image: unitTestImageID,
  609. Cmd: []string{"/bin/cat"},
  610. OpenStdin: true,
  611. },
  612. t,
  613. )
  614. startContainer(eng, containerID, t)
  615. // Give some time to the process to start
  616. containerWaitTimeout(eng, containerID, t)
  617. if !containerRunning(eng, containerID, t) {
  618. t.Errorf("Container should be running")
  619. }
  620. r := httptest.NewRecorder()
  621. req, err := http.NewRequest("POST", "/containers/"+containerID+"/kill", bytes.NewReader([]byte{}))
  622. if err != nil {
  623. t.Fatal(err)
  624. }
  625. if err := server.ServeRequest(eng, api.APIVERSION, r, req); err != nil {
  626. t.Fatal(err)
  627. }
  628. assertHttpNotError(r, t)
  629. if r.Code != http.StatusNoContent {
  630. t.Fatalf("%d NO CONTENT expected, received %d\n", http.StatusNoContent, r.Code)
  631. }
  632. if containerRunning(eng, containerID, t) {
  633. t.Fatalf("The container hasn't been killed")
  634. }
  635. }
  636. func TestPostContainersRestart(t *testing.T) {
  637. eng := NewTestEngine(t)
  638. defer mkRuntimeFromEngine(eng, t).Nuke()
  639. containerID := createTestContainer(eng,
  640. &runconfig.Config{
  641. Image: unitTestImageID,
  642. Cmd: []string{"/bin/top"},
  643. OpenStdin: true,
  644. },
  645. t,
  646. )
  647. startContainer(eng, containerID, t)
  648. // Give some time to the process to start
  649. containerWaitTimeout(eng, containerID, t)
  650. if !containerRunning(eng, containerID, t) {
  651. t.Errorf("Container should be running")
  652. }
  653. req, err := http.NewRequest("POST", "/containers/"+containerID+"/restart?t=1", bytes.NewReader([]byte{}))
  654. if err != nil {
  655. t.Fatal(err)
  656. }
  657. r := httptest.NewRecorder()
  658. if err := server.ServeRequest(eng, api.APIVERSION, r, req); err != nil {
  659. t.Fatal(err)
  660. }
  661. assertHttpNotError(r, t)
  662. if r.Code != http.StatusNoContent {
  663. t.Fatalf("%d NO CONTENT expected, received %d\n", http.StatusNoContent, r.Code)
  664. }
  665. // Give some time to the process to restart
  666. containerWaitTimeout(eng, containerID, t)
  667. if !containerRunning(eng, containerID, t) {
  668. t.Fatalf("Container should be running")
  669. }
  670. containerKill(eng, containerID, t)
  671. }
  672. func TestPostContainersStart(t *testing.T) {
  673. eng := NewTestEngine(t)
  674. defer mkRuntimeFromEngine(eng, t).Nuke()
  675. containerID := createTestContainer(
  676. eng,
  677. &runconfig.Config{
  678. Image: unitTestImageID,
  679. Cmd: []string{"/bin/cat"},
  680. OpenStdin: true,
  681. },
  682. t,
  683. )
  684. hostConfigJSON, err := json.Marshal(&runconfig.HostConfig{})
  685. req, err := http.NewRequest("POST", "/containers/"+containerID+"/start", bytes.NewReader(hostConfigJSON))
  686. if err != nil {
  687. t.Fatal(err)
  688. }
  689. req.Header.Set("Content-Type", "application/json")
  690. r := httptest.NewRecorder()
  691. if err := server.ServeRequest(eng, api.APIVERSION, r, req); err != nil {
  692. t.Fatal(err)
  693. }
  694. assertHttpNotError(r, t)
  695. if r.Code != http.StatusNoContent {
  696. t.Fatalf("%d NO CONTENT expected, received %d\n", http.StatusNoContent, r.Code)
  697. }
  698. containerAssertExists(eng, containerID, t)
  699. // Give some time to the process to start
  700. // FIXME: use Wait once it's available as a job
  701. containerWaitTimeout(eng, containerID, t)
  702. if !containerRunning(eng, containerID, t) {
  703. t.Errorf("Container should be running")
  704. }
  705. r = httptest.NewRecorder()
  706. if err := server.ServeRequest(eng, api.APIVERSION, r, req); err != nil {
  707. t.Fatal(err)
  708. }
  709. // Starting an already started container should return an error
  710. // FIXME: verify a precise error code. There is a possible bug here
  711. // which causes this to return 404 even though the container exists.
  712. assertHttpError(r, t)
  713. containerAssertExists(eng, containerID, t)
  714. containerKill(eng, containerID, t)
  715. }
  716. // Expected behaviour: using / as a bind mount source should throw an error
  717. func TestRunErrorBindMountRootSource(t *testing.T) {
  718. eng := NewTestEngine(t)
  719. defer mkRuntimeFromEngine(eng, t).Nuke()
  720. containerID := createTestContainer(
  721. eng,
  722. &runconfig.Config{
  723. Image: unitTestImageID,
  724. Cmd: []string{"/bin/cat"},
  725. OpenStdin: true,
  726. },
  727. t,
  728. )
  729. hostConfigJSON, err := json.Marshal(&runconfig.HostConfig{
  730. Binds: []string{"/:/tmp"},
  731. })
  732. req, err := http.NewRequest("POST", "/containers/"+containerID+"/start", bytes.NewReader(hostConfigJSON))
  733. if err != nil {
  734. t.Fatal(err)
  735. }
  736. req.Header.Set("Content-Type", "application/json")
  737. r := httptest.NewRecorder()
  738. if err := server.ServeRequest(eng, api.APIVERSION, r, req); err != nil {
  739. t.Fatal(err)
  740. }
  741. if r.Code != http.StatusInternalServerError {
  742. containerKill(eng, containerID, t)
  743. t.Fatal("should have failed to run when using / as a source for the bind mount")
  744. }
  745. }
  746. func TestPostContainersStop(t *testing.T) {
  747. eng := NewTestEngine(t)
  748. defer mkRuntimeFromEngine(eng, t).Nuke()
  749. containerID := createTestContainer(eng,
  750. &runconfig.Config{
  751. Image: unitTestImageID,
  752. Cmd: []string{"/bin/top"},
  753. OpenStdin: true,
  754. },
  755. t,
  756. )
  757. startContainer(eng, containerID, t)
  758. // Give some time to the process to start
  759. containerWaitTimeout(eng, containerID, t)
  760. if !containerRunning(eng, containerID, t) {
  761. t.Errorf("Container should be running")
  762. }
  763. // Note: as it is a POST request, it requires a body.
  764. req, err := http.NewRequest("POST", "/containers/"+containerID+"/stop?t=1", bytes.NewReader([]byte{}))
  765. if err != nil {
  766. t.Fatal(err)
  767. }
  768. r := httptest.NewRecorder()
  769. if err := server.ServeRequest(eng, api.APIVERSION, r, req); err != nil {
  770. t.Fatal(err)
  771. }
  772. assertHttpNotError(r, t)
  773. if r.Code != http.StatusNoContent {
  774. t.Fatalf("%d NO CONTENT expected, received %d\n", http.StatusNoContent, r.Code)
  775. }
  776. if containerRunning(eng, containerID, t) {
  777. t.Fatalf("The container hasn't been stopped")
  778. }
  779. }
  780. func TestPostContainersWait(t *testing.T) {
  781. eng := NewTestEngine(t)
  782. defer mkRuntimeFromEngine(eng, t).Nuke()
  783. containerID := createTestContainer(eng,
  784. &runconfig.Config{
  785. Image: unitTestImageID,
  786. Cmd: []string{"/bin/sleep", "1"},
  787. OpenStdin: true,
  788. },
  789. t,
  790. )
  791. startContainer(eng, containerID, t)
  792. setTimeout(t, "Wait timed out", 3*time.Second, func() {
  793. r := httptest.NewRecorder()
  794. req, err := http.NewRequest("POST", "/containers/"+containerID+"/wait", bytes.NewReader([]byte{}))
  795. if err != nil {
  796. t.Fatal(err)
  797. }
  798. if err := server.ServeRequest(eng, api.APIVERSION, r, req); err != nil {
  799. t.Fatal(err)
  800. }
  801. assertHttpNotError(r, t)
  802. var apiWait engine.Env
  803. if err := apiWait.Decode(r.Body); err != nil {
  804. t.Fatal(err)
  805. }
  806. if apiWait.GetInt("StatusCode") != 0 {
  807. t.Fatalf("Non zero exit code for sleep: %d\n", apiWait.GetInt("StatusCode"))
  808. }
  809. })
  810. if containerRunning(eng, containerID, t) {
  811. t.Fatalf("The container should be stopped after wait")
  812. }
  813. }
  814. func TestPostContainersAttach(t *testing.T) {
  815. eng := NewTestEngine(t)
  816. defer mkRuntimeFromEngine(eng, t).Nuke()
  817. containerID := createTestContainer(eng,
  818. &runconfig.Config{
  819. Image: unitTestImageID,
  820. Cmd: []string{"/bin/cat"},
  821. OpenStdin: true,
  822. },
  823. t,
  824. )
  825. // Start the process
  826. startContainer(eng, containerID, t)
  827. stdin, stdinPipe := io.Pipe()
  828. stdout, stdoutPipe := io.Pipe()
  829. // Try to avoid the timeout in destroy. Best effort, don't check error
  830. defer func() {
  831. closeWrap(stdin, stdinPipe, stdout, stdoutPipe)
  832. containerKill(eng, containerID, t)
  833. }()
  834. // Attach to it
  835. c1 := make(chan struct{})
  836. go func() {
  837. defer close(c1)
  838. r := &hijackTester{
  839. ResponseRecorder: httptest.NewRecorder(),
  840. in: stdin,
  841. out: stdoutPipe,
  842. }
  843. req, err := http.NewRequest("POST", "/containers/"+containerID+"/attach?stream=1&stdin=1&stdout=1&stderr=1", bytes.NewReader([]byte{}))
  844. if err != nil {
  845. t.Fatal(err)
  846. }
  847. if err := server.ServeRequest(eng, api.APIVERSION, r, req); err != nil {
  848. t.Fatal(err)
  849. }
  850. assertHttpNotError(r.ResponseRecorder, t)
  851. }()
  852. // Acknowledge hijack
  853. setTimeout(t, "hijack acknowledge timed out", 2*time.Second, func() {
  854. stdout.Read([]byte{})
  855. stdout.Read(make([]byte, 4096))
  856. })
  857. setTimeout(t, "read/write assertion timed out", 2*time.Second, func() {
  858. if err := assertPipe("hello\n", string([]byte{1, 0, 0, 0, 0, 0, 0, 6})+"hello", stdout, stdinPipe, 150); err != nil {
  859. t.Fatal(err)
  860. }
  861. })
  862. // Close pipes (client disconnects)
  863. if err := closeWrap(stdin, stdinPipe, stdout, stdoutPipe); err != nil {
  864. t.Fatal(err)
  865. }
  866. // Wait for attach to finish, the client disconnected, therefore, Attach finished his job
  867. setTimeout(t, "Waiting for CmdAttach timed out", 10*time.Second, func() {
  868. <-c1
  869. })
  870. // We closed stdin, expect /bin/cat to still be running
  871. // Wait a little bit to make sure container.monitor() did his thing
  872. containerWaitTimeout(eng, containerID, t)
  873. // Try to avoid the timeout in destroy. Best effort, don't check error
  874. cStdin, _ := containerAttach(eng, containerID, t)
  875. cStdin.Close()
  876. containerWait(eng, containerID, t)
  877. }
  878. func TestPostContainersAttachStderr(t *testing.T) {
  879. eng := NewTestEngine(t)
  880. defer mkRuntimeFromEngine(eng, t).Nuke()
  881. containerID := createTestContainer(eng,
  882. &runconfig.Config{
  883. Image: unitTestImageID,
  884. Cmd: []string{"/bin/sh", "-c", "/bin/cat >&2"},
  885. OpenStdin: true,
  886. },
  887. t,
  888. )
  889. // Start the process
  890. startContainer(eng, containerID, t)
  891. stdin, stdinPipe := io.Pipe()
  892. stdout, stdoutPipe := io.Pipe()
  893. // Try to avoid the timeout in destroy. Best effort, don't check error
  894. defer func() {
  895. closeWrap(stdin, stdinPipe, stdout, stdoutPipe)
  896. containerKill(eng, containerID, t)
  897. }()
  898. // Attach to it
  899. c1 := make(chan struct{})
  900. go func() {
  901. defer close(c1)
  902. r := &hijackTester{
  903. ResponseRecorder: httptest.NewRecorder(),
  904. in: stdin,
  905. out: stdoutPipe,
  906. }
  907. req, err := http.NewRequest("POST", "/containers/"+containerID+"/attach?stream=1&stdin=1&stdout=1&stderr=1", bytes.NewReader([]byte{}))
  908. if err != nil {
  909. t.Fatal(err)
  910. }
  911. if err := server.ServeRequest(eng, api.APIVERSION, r, req); err != nil {
  912. t.Fatal(err)
  913. }
  914. assertHttpNotError(r.ResponseRecorder, t)
  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", string([]byte{2, 0, 0, 0, 0, 0, 0, 6})+"hello", stdout, stdinPipe, 150); 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", 10*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. containerWaitTimeout(eng, containerID, t)
  937. // Try to avoid the timeout in destroy. Best effort, don't check error
  938. cStdin, _ := containerAttach(eng, containerID, t)
  939. cStdin.Close()
  940. containerWait(eng, containerID, t)
  941. }
  942. // FIXME: Test deleting running container
  943. // FIXME: Test deleting container with volume
  944. // FIXME: Test deleting volume in use by other container
  945. func TestDeleteContainers(t *testing.T) {
  946. eng := NewTestEngine(t)
  947. defer mkRuntimeFromEngine(eng, t).Nuke()
  948. containerID := createTestContainer(eng,
  949. &runconfig.Config{
  950. Image: unitTestImageID,
  951. Cmd: []string{"touch", "/test"},
  952. },
  953. t,
  954. )
  955. req, err := http.NewRequest("DELETE", "/containers/"+containerID, nil)
  956. if err != nil {
  957. t.Fatal(err)
  958. }
  959. r := httptest.NewRecorder()
  960. if err := server.ServeRequest(eng, api.APIVERSION, r, req); err != nil {
  961. t.Fatal(err)
  962. }
  963. assertHttpNotError(r, t)
  964. if r.Code != http.StatusNoContent {
  965. t.Fatalf("%d NO CONTENT expected, received %d\n", http.StatusNoContent, r.Code)
  966. }
  967. containerAssertNotExists(eng, containerID, t)
  968. }
  969. func TestOptionsRoute(t *testing.T) {
  970. eng := NewTestEngine(t)
  971. defer mkRuntimeFromEngine(eng, t).Nuke()
  972. r := httptest.NewRecorder()
  973. req, err := http.NewRequest("OPTIONS", "/", nil)
  974. if err != nil {
  975. t.Fatal(err)
  976. }
  977. if err := server.ServeRequest(eng, api.APIVERSION, r, req); err != nil {
  978. t.Fatal(err)
  979. }
  980. assertHttpNotError(r, t)
  981. if r.Code != http.StatusOK {
  982. t.Errorf("Expected response for OPTIONS request to be \"200\", %v found.", r.Code)
  983. }
  984. }
  985. func TestGetEnabledCors(t *testing.T) {
  986. eng := NewTestEngine(t)
  987. defer mkRuntimeFromEngine(eng, t).Nuke()
  988. r := httptest.NewRecorder()
  989. req, err := http.NewRequest("GET", "/version", nil)
  990. if err != nil {
  991. t.Fatal(err)
  992. }
  993. if err := server.ServeRequest(eng, api.APIVERSION, r, req); err != nil {
  994. t.Fatal(err)
  995. }
  996. assertHttpNotError(r, t)
  997. if r.Code != http.StatusOK {
  998. t.Errorf("Expected response for OPTIONS request to be \"200\", %v found.", r.Code)
  999. }
  1000. allowOrigin := r.Header().Get("Access-Control-Allow-Origin")
  1001. allowHeaders := r.Header().Get("Access-Control-Allow-Headers")
  1002. allowMethods := r.Header().Get("Access-Control-Allow-Methods")
  1003. if allowOrigin != "*" {
  1004. t.Errorf("Expected header Access-Control-Allow-Origin to be \"*\", %s found.", allowOrigin)
  1005. }
  1006. if allowHeaders != "Origin, X-Requested-With, Content-Type, Accept" {
  1007. t.Errorf("Expected header Access-Control-Allow-Headers to be \"Origin, X-Requested-With, Content-Type, Accept\", %s found.", allowHeaders)
  1008. }
  1009. if allowMethods != "GET, POST, DELETE, PUT, OPTIONS" {
  1010. t.Errorf("Expected hearder Access-Control-Allow-Methods to be \"GET, POST, DELETE, PUT, OPTIONS\", %s found.", allowMethods)
  1011. }
  1012. }
  1013. func TestDeleteImages(t *testing.T) {
  1014. eng := NewTestEngine(t)
  1015. //we expect errors, so we disable stderr
  1016. eng.Stderr = ioutil.Discard
  1017. defer mkRuntimeFromEngine(eng, t).Nuke()
  1018. initialImages := getImages(eng, t, true, "")
  1019. if err := eng.Job("tag", unitTestImageName, "test", "test").Run(); err != nil {
  1020. t.Fatal(err)
  1021. }
  1022. images := getImages(eng, t, true, "")
  1023. if len(images.Data[0].GetList("RepoTags")) != len(initialImages.Data[0].GetList("RepoTags"))+1 {
  1024. t.Errorf("Expected %d images, %d found", len(initialImages.Data[0].GetList("RepoTags"))+1, len(images.Data[0].GetList("RepoTags")))
  1025. }
  1026. req, err := http.NewRequest("DELETE", "/images/"+unitTestImageID, nil)
  1027. if err != nil {
  1028. t.Fatal(err)
  1029. }
  1030. r := httptest.NewRecorder()
  1031. if err := server.ServeRequest(eng, api.APIVERSION, r, req); err != nil {
  1032. t.Fatal(err)
  1033. }
  1034. if r.Code != http.StatusConflict {
  1035. t.Fatalf("Expected http status 409-conflict, got %v", r.Code)
  1036. }
  1037. req2, err := http.NewRequest("DELETE", "/images/test:test", nil)
  1038. if err != nil {
  1039. t.Fatal(err)
  1040. }
  1041. r2 := httptest.NewRecorder()
  1042. if err := server.ServeRequest(eng, api.APIVERSION, r2, req2); err != nil {
  1043. t.Fatal(err)
  1044. }
  1045. assertHttpNotError(r2, t)
  1046. if r2.Code != http.StatusOK {
  1047. t.Fatalf("%d OK expected, received %d\n", http.StatusOK, r.Code)
  1048. }
  1049. outs := engine.NewTable("Created", 0)
  1050. if _, err := outs.ReadListFrom(r2.Body.Bytes()); err != nil {
  1051. t.Fatal(err)
  1052. }
  1053. if len(outs.Data) != 1 {
  1054. t.Fatalf("Expected %d event (untagged), got %d", 1, len(outs.Data))
  1055. }
  1056. images = getImages(eng, t, false, "")
  1057. if images.Len() != initialImages.Len() {
  1058. t.Errorf("Expected %d image, %d found", initialImages.Len(), images.Len())
  1059. }
  1060. }
  1061. func TestPostContainersCopy(t *testing.T) {
  1062. eng := NewTestEngine(t)
  1063. defer mkRuntimeFromEngine(eng, t).Nuke()
  1064. // Create a container and remove a file
  1065. containerID := createTestContainer(eng,
  1066. &runconfig.Config{
  1067. Image: unitTestImageID,
  1068. Cmd: []string{"touch", "/test.txt"},
  1069. },
  1070. t,
  1071. )
  1072. containerRun(eng, containerID, t)
  1073. r := httptest.NewRecorder()
  1074. var copyData engine.Env
  1075. copyData.Set("Resource", "/test.txt")
  1076. copyData.Set("HostPath", ".")
  1077. jsonData := bytes.NewBuffer(nil)
  1078. if err := copyData.Encode(jsonData); err != nil {
  1079. t.Fatal(err)
  1080. }
  1081. req, err := http.NewRequest("POST", "/containers/"+containerID+"/copy", jsonData)
  1082. if err != nil {
  1083. t.Fatal(err)
  1084. }
  1085. req.Header.Add("Content-Type", "application/json")
  1086. if err := server.ServeRequest(eng, api.APIVERSION, r, req); err != nil {
  1087. t.Fatal(err)
  1088. }
  1089. assertHttpNotError(r, t)
  1090. if r.Code != http.StatusOK {
  1091. t.Fatalf("%d OK expected, received %d\n", http.StatusOK, r.Code)
  1092. }
  1093. found := false
  1094. for tarReader := tar.NewReader(r.Body); ; {
  1095. h, err := tarReader.Next()
  1096. if err != nil {
  1097. if err == io.EOF {
  1098. break
  1099. }
  1100. t.Fatal(err)
  1101. }
  1102. if h.Name == "test.txt" {
  1103. found = true
  1104. break
  1105. }
  1106. }
  1107. if !found {
  1108. t.Fatalf("The created test file has not been found in the copied output")
  1109. }
  1110. }
  1111. func TestPostContainersCopyWhenContainerNotFound(t *testing.T) {
  1112. eng := NewTestEngine(t)
  1113. defer mkRuntimeFromEngine(eng, t).Nuke()
  1114. r := httptest.NewRecorder()
  1115. var copyData engine.Env
  1116. copyData.Set("Resource", "/test.txt")
  1117. copyData.Set("HostPath", ".")
  1118. jsonData := bytes.NewBuffer(nil)
  1119. if err := copyData.Encode(jsonData); err != nil {
  1120. t.Fatal(err)
  1121. }
  1122. req, err := http.NewRequest("POST", "/containers/id_not_found/copy", jsonData)
  1123. if err != nil {
  1124. t.Fatal(err)
  1125. }
  1126. req.Header.Add("Content-Type", "application/json")
  1127. if err := server.ServeRequest(eng, api.APIVERSION, r, req); err != nil {
  1128. t.Fatal(err)
  1129. }
  1130. if r.Code != http.StatusNotFound {
  1131. t.Fatalf("404 expected for id_not_found Container, received %v", r.Code)
  1132. }
  1133. }
  1134. // Mocked types for tests
  1135. type NopConn struct {
  1136. io.ReadCloser
  1137. io.Writer
  1138. }
  1139. func (c *NopConn) LocalAddr() net.Addr { return nil }
  1140. func (c *NopConn) RemoteAddr() net.Addr { return nil }
  1141. func (c *NopConn) SetDeadline(t time.Time) error { return nil }
  1142. func (c *NopConn) SetReadDeadline(t time.Time) error { return nil }
  1143. func (c *NopConn) SetWriteDeadline(t time.Time) error { return nil }
  1144. type hijackTester struct {
  1145. *httptest.ResponseRecorder
  1146. in io.ReadCloser
  1147. out io.Writer
  1148. }
  1149. func (t *hijackTester) Hijack() (net.Conn, *bufio.ReadWriter, error) {
  1150. bufrw := bufio.NewReadWriter(bufio.NewReader(t.in), bufio.NewWriter(t.out))
  1151. conn := &NopConn{
  1152. ReadCloser: t.in,
  1153. Writer: t.out,
  1154. }
  1155. return conn, bufrw, nil
  1156. }