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