Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
| ... | ... |
@@ -3,15 +3,14 @@ package client // import "github.com/docker/docker/client" |
| 3 | 3 |
import ( |
| 4 | 4 |
"bytes" |
| 5 | 5 |
"context" |
| 6 |
- "fmt" |
|
| 7 | 6 |
"io" |
| 8 | 7 |
"net/http" |
| 9 |
- "reflect" |
|
| 10 |
- "strings" |
|
| 8 |
+ "net/url" |
|
| 11 | 9 |
"testing" |
| 12 | 10 |
|
| 13 | 11 |
"github.com/docker/docker/api/types/image" |
| 14 | 12 |
"github.com/docker/docker/errdefs" |
| 13 |
+ ocispec "github.com/opencontainers/image-spec/specs-go/v1" |
|
| 15 | 14 |
"gotest.tools/v3/assert" |
| 16 | 15 |
is "gotest.tools/v3/assert/cmp" |
| 17 | 16 |
) |
| ... | ... |
@@ -25,35 +24,51 @@ func TestImageSaveError(t *testing.T) {
|
| 25 | 25 |
} |
| 26 | 26 |
|
| 27 | 27 |
func TestImageSave(t *testing.T) {
|
| 28 |
- expectedURL := "/images/get" |
|
| 29 |
- client := &Client{
|
|
| 30 |
- client: newMockClient(func(r *http.Request) (*http.Response, error) {
|
|
| 31 |
- if !strings.HasPrefix(r.URL.Path, expectedURL) {
|
|
| 32 |
- return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, r.URL)
|
|
| 33 |
- } |
|
| 34 |
- query := r.URL.Query() |
|
| 35 |
- names := query["names"] |
|
| 36 |
- expectedNames := []string{"image_id1", "image_id2"}
|
|
| 37 |
- if !reflect.DeepEqual(names, expectedNames) {
|
|
| 38 |
- return nil, fmt.Errorf("names not set in URL query properly. Expected %v, got %v", names, expectedNames)
|
|
| 28 |
+ const ( |
|
| 29 |
+ expectedURL = "/images/get" |
|
| 30 |
+ expectedOutput = "outputBody" |
|
| 31 |
+ ) |
|
| 32 |
+ tests := []struct {
|
|
| 33 |
+ doc string |
|
| 34 |
+ options image.SaveOptions |
|
| 35 |
+ expectedQueryParams url.Values |
|
| 36 |
+ }{
|
|
| 37 |
+ {
|
|
| 38 |
+ doc: "no platform", |
|
| 39 |
+ expectedQueryParams: url.Values{
|
|
| 40 |
+ "names": {"image_id1", "image_id2"},
|
|
| 41 |
+ }, |
|
| 42 |
+ }, |
|
| 43 |
+ {
|
|
| 44 |
+ doc: "platform", |
|
| 45 |
+ options: image.SaveOptions{
|
|
| 46 |
+ Platform: &ocispec.Platform{Architecture: "arm64", OS: "linux", Variant: "v8"},
|
|
| 47 |
+ }, |
|
| 48 |
+ expectedQueryParams: url.Values{
|
|
| 49 |
+ "names": {"image_id1", "image_id2"},
|
|
| 50 |
+ "platform": {`{"architecture":"arm64","os":"linux","variant":"v8"}`},
|
|
| 51 |
+ }, |
|
| 52 |
+ }, |
|
| 53 |
+ } |
|
| 54 |
+ for _, tc := range tests {
|
|
| 55 |
+ t.Run(tc.doc, func(t *testing.T) {
|
|
| 56 |
+ client := &Client{
|
|
| 57 |
+ client: newMockClient(func(req *http.Request) (*http.Response, error) {
|
|
| 58 |
+ assert.Check(t, is.Equal(req.URL.Path, expectedURL)) |
|
| 59 |
+ assert.Check(t, is.DeepEqual(req.URL.Query(), tc.expectedQueryParams)) |
|
| 60 |
+ return &http.Response{
|
|
| 61 |
+ StatusCode: http.StatusOK, |
|
| 62 |
+ Body: io.NopCloser(bytes.NewReader([]byte(expectedOutput))), |
|
| 63 |
+ }, nil |
|
| 64 |
+ }), |
|
| 39 | 65 |
} |
| 66 |
+ resp, err := client.ImageSave(context.Background(), []string{"image_id1", "image_id2"}, tc.options)
|
|
| 67 |
+ assert.NilError(t, err) |
|
| 68 |
+ defer assert.NilError(t, resp.Close()) |
|
| 40 | 69 |
|
| 41 |
- return &http.Response{
|
|
| 42 |
- StatusCode: http.StatusOK, |
|
| 43 |
- Body: io.NopCloser(bytes.NewReader([]byte("response"))),
|
|
| 44 |
- }, nil |
|
| 45 |
- }), |
|
| 46 |
- } |
|
| 47 |
- saveResponse, err := client.ImageSave(context.Background(), []string{"image_id1", "image_id2"}, image.SaveOptions{})
|
|
| 48 |
- if err != nil {
|
|
| 49 |
- t.Fatal(err) |
|
| 50 |
- } |
|
| 51 |
- response, err := io.ReadAll(saveResponse) |
|
| 52 |
- if err != nil {
|
|
| 53 |
- t.Fatal(err) |
|
| 54 |
- } |
|
| 55 |
- saveResponse.Close() |
|
| 56 |
- if string(response) != "response" {
|
|
| 57 |
- t.Fatalf("expected response to contain 'response', got %s", string(response))
|
|
| 70 |
+ body, err := io.ReadAll(resp) |
|
| 71 |
+ assert.NilError(t, err) |
|
| 72 |
+ assert.Equal(t, string(body), expectedOutput) |
|
| 73 |
+ }) |
|
| 58 | 74 |
} |
| 59 | 75 |
} |