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 }