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