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