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  }