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 }