api_test.go 33 KB

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