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