container_copy_test.go 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244
  1. package client
  2. import (
  3. "bytes"
  4. "encoding/base64"
  5. "encoding/json"
  6. "fmt"
  7. "io/ioutil"
  8. "net/http"
  9. "strings"
  10. "testing"
  11. "golang.org/x/net/context"
  12. "github.com/docker/docker/api/types"
  13. )
  14. func TestContainerStatPathError(t *testing.T) {
  15. client := &Client{
  16. client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")),
  17. }
  18. _, err := client.ContainerStatPath(context.Background(), "container_id", "path")
  19. if err == nil || err.Error() != "Error response from daemon: Server error" {
  20. t.Fatalf("expected a Server error, got %v", err)
  21. }
  22. }
  23. func TestContainerStatPathNoHeaderError(t *testing.T) {
  24. client := &Client{
  25. client: newMockClient(func(req *http.Request) (*http.Response, error) {
  26. return &http.Response{
  27. StatusCode: http.StatusOK,
  28. Body: ioutil.NopCloser(bytes.NewReader([]byte(""))),
  29. }, nil
  30. }),
  31. }
  32. _, err := client.ContainerStatPath(context.Background(), "container_id", "path/to/file")
  33. if err == nil {
  34. t.Fatalf("expected an error, got nothing")
  35. }
  36. }
  37. func TestContainerStatPath(t *testing.T) {
  38. expectedURL := "/containers/container_id/archive"
  39. expectedPath := "path/to/file"
  40. client := &Client{
  41. client: newMockClient(func(req *http.Request) (*http.Response, error) {
  42. if !strings.HasPrefix(req.URL.Path, expectedURL) {
  43. return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, req.URL)
  44. }
  45. if req.Method != "HEAD" {
  46. return nil, fmt.Errorf("expected HEAD method, got %s", req.Method)
  47. }
  48. query := req.URL.Query()
  49. path := query.Get("path")
  50. if path != expectedPath {
  51. return nil, fmt.Errorf("path not set in URL query properly")
  52. }
  53. content, err := json.Marshal(types.ContainerPathStat{
  54. Name: "name",
  55. Mode: 0700,
  56. })
  57. if err != nil {
  58. return nil, err
  59. }
  60. base64PathStat := base64.StdEncoding.EncodeToString(content)
  61. return &http.Response{
  62. StatusCode: http.StatusOK,
  63. Body: ioutil.NopCloser(bytes.NewReader([]byte(""))),
  64. Header: http.Header{
  65. "X-Docker-Container-Path-Stat": []string{base64PathStat},
  66. },
  67. }, nil
  68. }),
  69. }
  70. stat, err := client.ContainerStatPath(context.Background(), "container_id", expectedPath)
  71. if err != nil {
  72. t.Fatal(err)
  73. }
  74. if stat.Name != "name" {
  75. t.Fatalf("expected container path stat name to be 'name', got '%s'", stat.Name)
  76. }
  77. if stat.Mode != 0700 {
  78. t.Fatalf("expected container path stat mode to be 0700, got '%v'", stat.Mode)
  79. }
  80. }
  81. func TestCopyToContainerError(t *testing.T) {
  82. client := &Client{
  83. client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")),
  84. }
  85. err := client.CopyToContainer(context.Background(), "container_id", "path/to/file", bytes.NewReader([]byte("")), types.CopyToContainerOptions{})
  86. if err == nil || err.Error() != "Error response from daemon: Server error" {
  87. t.Fatalf("expected a Server error, got %v", err)
  88. }
  89. }
  90. func TestCopyToContainerNotStatusOKError(t *testing.T) {
  91. client := &Client{
  92. client: newMockClient(errorMock(http.StatusNoContent, "No content")),
  93. }
  94. err := client.CopyToContainer(context.Background(), "container_id", "path/to/file", bytes.NewReader([]byte("")), types.CopyToContainerOptions{})
  95. if err == nil || err.Error() != "unexpected status code from daemon: 204" {
  96. t.Fatalf("expected an unexpected status code error, got %v", err)
  97. }
  98. }
  99. func TestCopyToContainer(t *testing.T) {
  100. expectedURL := "/containers/container_id/archive"
  101. expectedPath := "path/to/file"
  102. client := &Client{
  103. client: newMockClient(func(req *http.Request) (*http.Response, error) {
  104. if !strings.HasPrefix(req.URL.Path, expectedURL) {
  105. return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, req.URL)
  106. }
  107. if req.Method != "PUT" {
  108. return nil, fmt.Errorf("expected PUT method, got %s", req.Method)
  109. }
  110. query := req.URL.Query()
  111. path := query.Get("path")
  112. if path != expectedPath {
  113. return nil, fmt.Errorf("path not set in URL query properly, expected '%s', got %s", expectedPath, path)
  114. }
  115. noOverwriteDirNonDir := query.Get("noOverwriteDirNonDir")
  116. if noOverwriteDirNonDir != "true" {
  117. return nil, fmt.Errorf("noOverwriteDirNonDir not set in URL query properly, expected true, got %s", noOverwriteDirNonDir)
  118. }
  119. content, err := ioutil.ReadAll(req.Body)
  120. if err != nil {
  121. return nil, err
  122. }
  123. if err := req.Body.Close(); err != nil {
  124. return nil, err
  125. }
  126. if string(content) != "content" {
  127. return nil, fmt.Errorf("expected content to be 'content', got %s", string(content))
  128. }
  129. return &http.Response{
  130. StatusCode: http.StatusOK,
  131. Body: ioutil.NopCloser(bytes.NewReader([]byte(""))),
  132. }, nil
  133. }),
  134. }
  135. err := client.CopyToContainer(context.Background(), "container_id", expectedPath, bytes.NewReader([]byte("content")), types.CopyToContainerOptions{
  136. AllowOverwriteDirWithFile: false,
  137. })
  138. if err != nil {
  139. t.Fatal(err)
  140. }
  141. }
  142. func TestCopyFromContainerError(t *testing.T) {
  143. client := &Client{
  144. client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")),
  145. }
  146. _, _, err := client.CopyFromContainer(context.Background(), "container_id", "path/to/file")
  147. if err == nil || err.Error() != "Error response from daemon: Server error" {
  148. t.Fatalf("expected a Server error, got %v", err)
  149. }
  150. }
  151. func TestCopyFromContainerNotStatusOKError(t *testing.T) {
  152. client := &Client{
  153. client: newMockClient(errorMock(http.StatusNoContent, "No content")),
  154. }
  155. _, _, err := client.CopyFromContainer(context.Background(), "container_id", "path/to/file")
  156. if err == nil || err.Error() != "unexpected status code from daemon: 204" {
  157. t.Fatalf("expected an unexpected status code error, got %v", err)
  158. }
  159. }
  160. func TestCopyFromContainerNoHeaderError(t *testing.T) {
  161. client := &Client{
  162. client: newMockClient(func(req *http.Request) (*http.Response, error) {
  163. return &http.Response{
  164. StatusCode: http.StatusOK,
  165. Body: ioutil.NopCloser(bytes.NewReader([]byte(""))),
  166. }, nil
  167. }),
  168. }
  169. _, _, err := client.CopyFromContainer(context.Background(), "container_id", "path/to/file")
  170. if err == nil {
  171. t.Fatalf("expected an error, got nothing")
  172. }
  173. }
  174. func TestCopyFromContainer(t *testing.T) {
  175. expectedURL := "/containers/container_id/archive"
  176. expectedPath := "path/to/file"
  177. client := &Client{
  178. client: newMockClient(func(req *http.Request) (*http.Response, error) {
  179. if !strings.HasPrefix(req.URL.Path, expectedURL) {
  180. return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, req.URL)
  181. }
  182. if req.Method != "GET" {
  183. return nil, fmt.Errorf("expected GET method, got %s", req.Method)
  184. }
  185. query := req.URL.Query()
  186. path := query.Get("path")
  187. if path != expectedPath {
  188. return nil, fmt.Errorf("path not set in URL query properly, expected '%s', got %s", expectedPath, path)
  189. }
  190. headercontent, err := json.Marshal(types.ContainerPathStat{
  191. Name: "name",
  192. Mode: 0700,
  193. })
  194. if err != nil {
  195. return nil, err
  196. }
  197. base64PathStat := base64.StdEncoding.EncodeToString(headercontent)
  198. return &http.Response{
  199. StatusCode: http.StatusOK,
  200. Body: ioutil.NopCloser(bytes.NewReader([]byte("content"))),
  201. Header: http.Header{
  202. "X-Docker-Container-Path-Stat": []string{base64PathStat},
  203. },
  204. }, nil
  205. }),
  206. }
  207. r, stat, err := client.CopyFromContainer(context.Background(), "container_id", expectedPath)
  208. if err != nil {
  209. t.Fatal(err)
  210. }
  211. if stat.Name != "name" {
  212. t.Fatalf("expected container path stat name to be 'name', got '%s'", stat.Name)
  213. }
  214. if stat.Mode != 0700 {
  215. t.Fatalf("expected container path stat mode to be 0700, got '%v'", stat.Mode)
  216. }
  217. content, err := ioutil.ReadAll(r)
  218. if err != nil {
  219. t.Fatal(err)
  220. }
  221. if err := r.Close(); err != nil {
  222. t.Fatal(err)
  223. }
  224. if string(content) != "content" {
  225. t.Fatalf("expected content to be 'content', got %s", string(content))
  226. }
  227. }