github.com/zhouyu0/docker-note@v0.0.0-20190722021225-b8d3825084db/client/image_push_test.go (about)

     1  package client // import "github.com/docker/docker/client"
     2  
     3  import (
     4  	"bytes"
     5  	"context"
     6  	"fmt"
     7  	"io/ioutil"
     8  	"net/http"
     9  	"strings"
    10  	"testing"
    11  
    12  	"github.com/docker/docker/api/types"
    13  )
    14  
    15  func TestImagePushReferenceError(t *testing.T) {
    16  	client := &Client{
    17  		client: newMockClient(func(req *http.Request) (*http.Response, error) {
    18  			return nil, nil
    19  		}),
    20  	}
    21  	// An empty reference is an invalid reference
    22  	_, err := client.ImagePush(context.Background(), "", types.ImagePushOptions{})
    23  	if err == nil || !strings.Contains(err.Error(), "invalid reference format") {
    24  		t.Fatalf("expected an error, got %v", err)
    25  	}
    26  	// An canonical reference cannot be pushed
    27  	_, err = client.ImagePush(context.Background(), "repo@sha256:ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", types.ImagePushOptions{})
    28  	if err == nil || err.Error() != "cannot push a digest reference" {
    29  		t.Fatalf("expected an error, got %v", err)
    30  	}
    31  }
    32  
    33  func TestImagePushAnyError(t *testing.T) {
    34  	client := &Client{
    35  		client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")),
    36  	}
    37  	_, err := client.ImagePush(context.Background(), "myimage", types.ImagePushOptions{})
    38  	if err == nil || err.Error() != "Error response from daemon: Server error" {
    39  		t.Fatalf("expected a Server Error, got %v", err)
    40  	}
    41  }
    42  
    43  func TestImagePushStatusUnauthorizedError(t *testing.T) {
    44  	client := &Client{
    45  		client: newMockClient(errorMock(http.StatusUnauthorized, "Unauthorized error")),
    46  	}
    47  	_, err := client.ImagePush(context.Background(), "myimage", types.ImagePushOptions{})
    48  	if err == nil || err.Error() != "Error response from daemon: Unauthorized error" {
    49  		t.Fatalf("expected an Unauthorized Error, got %v", err)
    50  	}
    51  }
    52  
    53  func TestImagePushWithUnauthorizedErrorAndPrivilegeFuncError(t *testing.T) {
    54  	client := &Client{
    55  		client: newMockClient(errorMock(http.StatusUnauthorized, "Unauthorized error")),
    56  	}
    57  	privilegeFunc := func() (string, error) {
    58  		return "", fmt.Errorf("Error requesting privilege")
    59  	}
    60  	_, err := client.ImagePush(context.Background(), "myimage", types.ImagePushOptions{
    61  		PrivilegeFunc: privilegeFunc,
    62  	})
    63  	if err == nil || err.Error() != "Error requesting privilege" {
    64  		t.Fatalf("expected an error requesting privilege, got %v", err)
    65  	}
    66  }
    67  
    68  func TestImagePushWithUnauthorizedErrorAndAnotherUnauthorizedError(t *testing.T) {
    69  	client := &Client{
    70  		client: newMockClient(errorMock(http.StatusUnauthorized, "Unauthorized error")),
    71  	}
    72  	privilegeFunc := func() (string, error) {
    73  		return "a-auth-header", nil
    74  	}
    75  	_, err := client.ImagePush(context.Background(), "myimage", types.ImagePushOptions{
    76  		PrivilegeFunc: privilegeFunc,
    77  	})
    78  	if err == nil || err.Error() != "Error response from daemon: Unauthorized error" {
    79  		t.Fatalf("expected an Unauthorized Error, got %v", err)
    80  	}
    81  }
    82  
    83  func TestImagePushWithPrivilegedFuncNoError(t *testing.T) {
    84  	expectedURL := "/images/myimage/push"
    85  	client := &Client{
    86  		client: newMockClient(func(req *http.Request) (*http.Response, error) {
    87  			if !strings.HasPrefix(req.URL.Path, expectedURL) {
    88  				return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, req.URL)
    89  			}
    90  			auth := req.Header.Get("X-Registry-Auth")
    91  			if auth == "NotValid" {
    92  				return &http.Response{
    93  					StatusCode: http.StatusUnauthorized,
    94  					Body:       ioutil.NopCloser(bytes.NewReader([]byte("Invalid credentials"))),
    95  				}, nil
    96  			}
    97  			if auth != "IAmValid" {
    98  				return nil, fmt.Errorf("Invalid auth header : expected %s, got %s", "IAmValid", auth)
    99  			}
   100  			query := req.URL.Query()
   101  			tag := query.Get("tag")
   102  			if tag != "tag" {
   103  				return nil, fmt.Errorf("tag not set in URL query properly. Expected '%s', got %s", "tag", tag)
   104  			}
   105  			return &http.Response{
   106  				StatusCode: http.StatusOK,
   107  				Body:       ioutil.NopCloser(bytes.NewReader([]byte("hello world"))),
   108  			}, nil
   109  		}),
   110  	}
   111  	privilegeFunc := func() (string, error) {
   112  		return "IAmValid", nil
   113  	}
   114  	resp, err := client.ImagePush(context.Background(), "myimage:tag", types.ImagePushOptions{
   115  		RegistryAuth:  "NotValid",
   116  		PrivilegeFunc: privilegeFunc,
   117  	})
   118  	if err != nil {
   119  		t.Fatal(err)
   120  	}
   121  	body, err := ioutil.ReadAll(resp)
   122  	if err != nil {
   123  		t.Fatal(err)
   124  	}
   125  	if string(body) != "hello world" {
   126  		t.Fatalf("expected 'hello world', got %s", string(body))
   127  	}
   128  }
   129  
   130  func TestImagePushWithoutErrors(t *testing.T) {
   131  	expectedOutput := "hello world"
   132  	expectedURLFormat := "/images/%s/push"
   133  	pullCases := []struct {
   134  		reference     string
   135  		expectedImage string
   136  		expectedTag   string
   137  	}{
   138  		{
   139  			reference:     "myimage",
   140  			expectedImage: "myimage",
   141  			expectedTag:   "",
   142  		},
   143  		{
   144  			reference:     "myimage:tag",
   145  			expectedImage: "myimage",
   146  			expectedTag:   "tag",
   147  		},
   148  	}
   149  	for _, pullCase := range pullCases {
   150  		client := &Client{
   151  			client: newMockClient(func(req *http.Request) (*http.Response, error) {
   152  				expectedURL := fmt.Sprintf(expectedURLFormat, pullCase.expectedImage)
   153  				if !strings.HasPrefix(req.URL.Path, expectedURL) {
   154  					return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, req.URL)
   155  				}
   156  				query := req.URL.Query()
   157  				tag := query.Get("tag")
   158  				if tag != pullCase.expectedTag {
   159  					return nil, fmt.Errorf("tag not set in URL query properly. Expected '%s', got %s", pullCase.expectedTag, tag)
   160  				}
   161  				return &http.Response{
   162  					StatusCode: http.StatusOK,
   163  					Body:       ioutil.NopCloser(bytes.NewReader([]byte(expectedOutput))),
   164  				}, nil
   165  			}),
   166  		}
   167  		resp, err := client.ImagePush(context.Background(), pullCase.reference, types.ImagePushOptions{})
   168  		if err != nil {
   169  			t.Fatal(err)
   170  		}
   171  		body, err := ioutil.ReadAll(resp)
   172  		if err != nil {
   173  			t.Fatal(err)
   174  		}
   175  		if string(body) != expectedOutput {
   176  			t.Fatalf("expected '%s', got %s", expectedOutput, string(body))
   177  		}
   178  	}
   179  }