github.com/rish1988/moby@v25.0.2+incompatible/client/image_list_test.go (about)

     1  package client // import "github.com/docker/docker/client"
     2  
     3  import (
     4  	"bytes"
     5  	"context"
     6  	"encoding/json"
     7  	"fmt"
     8  	"io"
     9  	"net/http"
    10  	"net/url"
    11  	"strings"
    12  	"testing"
    13  
    14  	"github.com/docker/docker/api/types/filters"
    15  	"github.com/docker/docker/api/types/image"
    16  	"github.com/docker/docker/errdefs"
    17  	"gotest.tools/v3/assert"
    18  	is "gotest.tools/v3/assert/cmp"
    19  )
    20  
    21  func TestImageListError(t *testing.T) {
    22  	client := &Client{
    23  		client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")),
    24  	}
    25  
    26  	_, err := client.ImageList(context.Background(), image.ListOptions{})
    27  	assert.Check(t, is.ErrorType(err, errdefs.IsSystem))
    28  }
    29  
    30  func TestImageList(t *testing.T) {
    31  	const expectedURL = "/images/json"
    32  
    33  	listCases := []struct {
    34  		options             image.ListOptions
    35  		expectedQueryParams map[string]string
    36  	}{
    37  		{
    38  			options: image.ListOptions{},
    39  			expectedQueryParams: map[string]string{
    40  				"all":     "",
    41  				"filter":  "",
    42  				"filters": "",
    43  			},
    44  		},
    45  		{
    46  			options: image.ListOptions{
    47  				Filters: filters.NewArgs(
    48  					filters.Arg("label", "label1"),
    49  					filters.Arg("label", "label2"),
    50  					filters.Arg("dangling", "true"),
    51  				),
    52  			},
    53  			expectedQueryParams: map[string]string{
    54  				"all":     "",
    55  				"filter":  "",
    56  				"filters": `{"dangling":{"true":true},"label":{"label1":true,"label2":true}}`,
    57  			},
    58  		},
    59  		{
    60  			options: image.ListOptions{
    61  				Filters: filters.NewArgs(filters.Arg("dangling", "false")),
    62  			},
    63  			expectedQueryParams: map[string]string{
    64  				"all":     "",
    65  				"filter":  "",
    66  				"filters": `{"dangling":{"false":true}}`,
    67  			},
    68  		},
    69  	}
    70  	for _, listCase := range listCases {
    71  		client := &Client{
    72  			client: newMockClient(func(req *http.Request) (*http.Response, error) {
    73  				if !strings.HasPrefix(req.URL.Path, expectedURL) {
    74  					return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, req.URL)
    75  				}
    76  				query := req.URL.Query()
    77  				for key, expected := range listCase.expectedQueryParams {
    78  					actual := query.Get(key)
    79  					if actual != expected {
    80  						return nil, fmt.Errorf("%s not set in URL query properly. Expected '%s', got %s", key, expected, actual)
    81  					}
    82  				}
    83  				content, err := json.Marshal([]image.Summary{
    84  					{
    85  						ID: "image_id2",
    86  					},
    87  					{
    88  						ID: "image_id2",
    89  					},
    90  				})
    91  				if err != nil {
    92  					return nil, err
    93  				}
    94  				return &http.Response{
    95  					StatusCode: http.StatusOK,
    96  					Body:       io.NopCloser(bytes.NewReader(content)),
    97  				}, nil
    98  			}),
    99  		}
   100  
   101  		images, err := client.ImageList(context.Background(), listCase.options)
   102  		if err != nil {
   103  			t.Fatal(err)
   104  		}
   105  		if len(images) != 2 {
   106  			t.Fatalf("expected 2 images, got %v", images)
   107  		}
   108  	}
   109  }
   110  
   111  func TestImageListApiBefore125(t *testing.T) {
   112  	expectedFilter := "image:tag"
   113  	client := &Client{
   114  		client: newMockClient(func(req *http.Request) (*http.Response, error) {
   115  			query := req.URL.Query()
   116  			actualFilter := query.Get("filter")
   117  			if actualFilter != expectedFilter {
   118  				return nil, fmt.Errorf("filter not set in URL query properly. Expected '%s', got %s", expectedFilter, actualFilter)
   119  			}
   120  			actualFilters := query.Get("filters")
   121  			if actualFilters != "" {
   122  				return nil, fmt.Errorf("filters should have not been present, were with value: %s", actualFilters)
   123  			}
   124  			content, err := json.Marshal([]image.Summary{
   125  				{
   126  					ID: "image_id2",
   127  				},
   128  				{
   129  					ID: "image_id2",
   130  				},
   131  			})
   132  			if err != nil {
   133  				return nil, err
   134  			}
   135  			return &http.Response{
   136  				StatusCode: http.StatusOK,
   137  				Body:       io.NopCloser(bytes.NewReader(content)),
   138  			}, nil
   139  		}),
   140  		version: "1.24",
   141  	}
   142  
   143  	options := image.ListOptions{
   144  		Filters: filters.NewArgs(filters.Arg("reference", "image:tag")),
   145  	}
   146  
   147  	images, err := client.ImageList(context.Background(), options)
   148  	if err != nil {
   149  		t.Fatal(err)
   150  	}
   151  	if len(images) != 2 {
   152  		t.Fatalf("expected 2 images, got %v", images)
   153  	}
   154  }
   155  
   156  // Checks if shared-size query parameter is set/not being set correctly
   157  // for /images/json.
   158  func TestImageListWithSharedSize(t *testing.T) {
   159  	t.Parallel()
   160  	const sharedSize = "shared-size"
   161  	for _, tc := range []struct {
   162  		name       string
   163  		version    string
   164  		options    image.ListOptions
   165  		sharedSize string // expected value for the shared-size query param, or empty if it should not be set.
   166  	}{
   167  		{name: "unset after 1.42, no options set", version: "1.42"},
   168  		{name: "set after 1.42, if requested", version: "1.42", options: image.ListOptions{SharedSize: true}, sharedSize: "1"},
   169  		{name: "unset before 1.42, even if requested", version: "1.41", options: image.ListOptions{SharedSize: true}},
   170  	} {
   171  		tc := tc
   172  		t.Run(tc.name, func(t *testing.T) {
   173  			t.Parallel()
   174  			var query url.Values
   175  			client := &Client{
   176  				client: newMockClient(func(req *http.Request) (*http.Response, error) {
   177  					query = req.URL.Query()
   178  					return &http.Response{
   179  						StatusCode: http.StatusOK,
   180  						Body:       io.NopCloser(strings.NewReader("[]")),
   181  					}, nil
   182  				}),
   183  				version: tc.version,
   184  			}
   185  			_, err := client.ImageList(context.Background(), tc.options)
   186  			assert.Check(t, err)
   187  			expectedSet := tc.sharedSize != ""
   188  			assert.Check(t, is.Equal(query.Has(sharedSize), expectedSet))
   189  			assert.Check(t, is.Equal(query.Get(sharedSize), tc.sharedSize))
   190  		})
   191  	}
   192  }