github.com/rawahars/moby@v24.0.4+incompatible/client/image_pull_test.go (about) 1 package client // import "github.com/docker/docker/client" 2 3 import ( 4 "bytes" 5 "context" 6 "fmt" 7 "io" 8 "net/http" 9 "strings" 10 "testing" 11 12 "github.com/docker/docker/api/types" 13 "github.com/docker/docker/api/types/registry" 14 "github.com/docker/docker/errdefs" 15 ) 16 17 func TestImagePullReferenceParseError(t *testing.T) { 18 client := &Client{ 19 client: newMockClient(func(req *http.Request) (*http.Response, error) { 20 return nil, nil 21 }), 22 } 23 // An empty reference is an invalid reference 24 _, err := client.ImagePull(context.Background(), "", types.ImagePullOptions{}) 25 if err == nil || !strings.Contains(err.Error(), "invalid reference format") { 26 t.Fatalf("expected an error, got %v", err) 27 } 28 } 29 30 func TestImagePullAnyError(t *testing.T) { 31 client := &Client{ 32 client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")), 33 } 34 _, err := client.ImagePull(context.Background(), "myimage", types.ImagePullOptions{}) 35 if !errdefs.IsSystem(err) { 36 t.Fatalf("expected a Server Error, got %[1]T: %[1]v", err) 37 } 38 } 39 40 func TestImagePullStatusUnauthorizedError(t *testing.T) { 41 client := &Client{ 42 client: newMockClient(errorMock(http.StatusUnauthorized, "Unauthorized error")), 43 } 44 _, err := client.ImagePull(context.Background(), "myimage", types.ImagePullOptions{}) 45 if !errdefs.IsUnauthorized(err) { 46 t.Fatalf("expected a Unauthorized Error, got %[1]T: %[1]v", err) 47 } 48 } 49 50 func TestImagePullWithUnauthorizedErrorAndPrivilegeFuncError(t *testing.T) { 51 client := &Client{ 52 client: newMockClient(errorMock(http.StatusUnauthorized, "Unauthorized error")), 53 } 54 privilegeFunc := func() (string, error) { 55 return "", fmt.Errorf("Error requesting privilege") 56 } 57 _, err := client.ImagePull(context.Background(), "myimage", types.ImagePullOptions{ 58 PrivilegeFunc: privilegeFunc, 59 }) 60 if err == nil || err.Error() != "Error requesting privilege" { 61 t.Fatalf("expected an error requesting privilege, got %v", err) 62 } 63 } 64 65 func TestImagePullWithUnauthorizedErrorAndAnotherUnauthorizedError(t *testing.T) { 66 client := &Client{ 67 client: newMockClient(errorMock(http.StatusUnauthorized, "Unauthorized error")), 68 } 69 privilegeFunc := func() (string, error) { 70 return "a-auth-header", nil 71 } 72 _, err := client.ImagePull(context.Background(), "myimage", types.ImagePullOptions{ 73 PrivilegeFunc: privilegeFunc, 74 }) 75 if !errdefs.IsUnauthorized(err) { 76 t.Fatalf("expected a Unauthorized Error, got %[1]T: %[1]v", err) 77 } 78 } 79 80 func TestImagePullWithPrivilegedFuncNoError(t *testing.T) { 81 expectedURL := "/images/create" 82 client := &Client{ 83 client: newMockClient(func(req *http.Request) (*http.Response, error) { 84 if !strings.HasPrefix(req.URL.Path, expectedURL) { 85 return nil, fmt.Errorf("expected URL '%s', got '%s'", expectedURL, req.URL) 86 } 87 auth := req.Header.Get(registry.AuthHeader) 88 if auth == "NotValid" { 89 return &http.Response{ 90 StatusCode: http.StatusUnauthorized, 91 Body: io.NopCloser(bytes.NewReader([]byte("Invalid credentials"))), 92 }, nil 93 } 94 if auth != "IAmValid" { 95 return nil, fmt.Errorf("invalid auth header: expected %s, got %s", "IAmValid", auth) 96 } 97 query := req.URL.Query() 98 fromImage := query.Get("fromImage") 99 if fromImage != "myimage" { 100 return nil, fmt.Errorf("fromimage not set in URL query properly. Expected '%s', got %s", "myimage", fromImage) 101 } 102 tag := query.Get("tag") 103 if tag != "latest" { 104 return nil, fmt.Errorf("tag not set in URL query properly. Expected '%s', got %s", "latest", tag) 105 } 106 return &http.Response{ 107 StatusCode: http.StatusOK, 108 Body: io.NopCloser(bytes.NewReader([]byte("hello world"))), 109 }, nil 110 }), 111 } 112 privilegeFunc := func() (string, error) { 113 return "IAmValid", nil 114 } 115 resp, err := client.ImagePull(context.Background(), "myimage", types.ImagePullOptions{ 116 RegistryAuth: "NotValid", 117 PrivilegeFunc: privilegeFunc, 118 }) 119 if err != nil { 120 t.Fatal(err) 121 } 122 body, err := io.ReadAll(resp) 123 if err != nil { 124 t.Fatal(err) 125 } 126 if string(body) != "hello world" { 127 t.Fatalf("expected 'hello world', got %s", string(body)) 128 } 129 } 130 131 func TestImagePullWithoutErrors(t *testing.T) { 132 expectedURL := "/images/create" 133 expectedOutput := "hello world" 134 pullCases := []struct { 135 all bool 136 reference string 137 expectedImage string 138 expectedTag string 139 }{ 140 { 141 all: false, 142 reference: "myimage", 143 expectedImage: "myimage", 144 expectedTag: "latest", 145 }, 146 { 147 all: false, 148 reference: "myimage:tag", 149 expectedImage: "myimage", 150 expectedTag: "tag", 151 }, 152 { 153 all: true, 154 reference: "myimage", 155 expectedImage: "myimage", 156 expectedTag: "", 157 }, 158 { 159 all: true, 160 reference: "myimage:anything", 161 expectedImage: "myimage", 162 expectedTag: "", 163 }, 164 } 165 for _, pullCase := range pullCases { 166 client := &Client{ 167 client: newMockClient(func(req *http.Request) (*http.Response, error) { 168 if !strings.HasPrefix(req.URL.Path, expectedURL) { 169 return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, req.URL) 170 } 171 query := req.URL.Query() 172 fromImage := query.Get("fromImage") 173 if fromImage != pullCase.expectedImage { 174 return nil, fmt.Errorf("fromimage not set in URL query properly. Expected '%s', got %s", pullCase.expectedImage, fromImage) 175 } 176 tag := query.Get("tag") 177 if tag != pullCase.expectedTag { 178 return nil, fmt.Errorf("tag not set in URL query properly. Expected '%s', got %s", pullCase.expectedTag, tag) 179 } 180 return &http.Response{ 181 StatusCode: http.StatusOK, 182 Body: io.NopCloser(bytes.NewReader([]byte(expectedOutput))), 183 }, nil 184 }), 185 } 186 resp, err := client.ImagePull(context.Background(), pullCase.reference, types.ImagePullOptions{ 187 All: pullCase.all, 188 }) 189 if err != nil { 190 t.Fatal(err) 191 } 192 body, err := io.ReadAll(resp) 193 if err != nil { 194 t.Fatal(err) 195 } 196 if string(body) != expectedOutput { 197 t.Fatalf("expected '%s', got %s", expectedOutput, string(body)) 198 } 199 } 200 }