Browse code

Adding unit tests for pin by digest (client)

Signed-off-by: Nishant Totla <nishanttotla@gmail.com>

Nishant Totla authored on 2017/05/19 09:10:49
Showing 1 changed files
... ...
@@ -13,6 +13,7 @@ import (
13 13
 	"github.com/docker/docker/api/types"
14 14
 	registrytypes "github.com/docker/docker/api/types/registry"
15 15
 	"github.com/docker/docker/api/types/swarm"
16
+	"github.com/opencontainers/go-digest"
16 17
 	"github.com/opencontainers/image-spec/specs-go/v1"
17 18
 	"golang.org/x/net/context"
18 19
 )
... ...
@@ -121,3 +122,92 @@ func TestServiceCreateCompatiblePlatforms(t *testing.T) {
121 121
 		t.Fatalf("expected `service_amd64`, got %s", r.ID)
122 122
 	}
123 123
 }
124
+
125
+func TestServiceCreateDigestPinning(t *testing.T) {
126
+	dgst := "sha256:c0537ff6a5218ef531ece93d4984efc99bbf3f7497c0a7726c88e2bb7584dc96"
127
+	dgstAlt := "sha256:37ffbf3f7497c07584dc9637ffbf3f7497c0758c0537ffbf3f7497c0c88e2bb7"
128
+	serviceCreateImage := ""
129
+	pinByDigestTests := []struct {
130
+		img      string // input image provided by the user
131
+		expected string // expected image after digest pinning
132
+	}{
133
+		// default registry returns familiar string
134
+		{"docker.io/library/alpine", "alpine:latest@" + dgst},
135
+		// provided tag is preserved and digest added
136
+		{"alpine:edge", "alpine:edge@" + dgst},
137
+		// image with provided alternative digest remains unchanged
138
+		{"alpine@" + dgstAlt, "alpine@" + dgstAlt},
139
+		// image with provided tag and alternative digest remains unchanged
140
+		{"alpine:edge@" + dgstAlt, "alpine:edge@" + dgstAlt},
141
+		// image on alternative registry does not result in familiar string
142
+		{"alternate.registry/library/alpine", "alternate.registry/library/alpine:latest@" + dgst},
143
+		// unresolvable image does not get a digest
144
+		{"cannotresolve", "cannotresolve:latest"},
145
+	}
146
+
147
+	client := &Client{
148
+		client: newMockClient(func(req *http.Request) (*http.Response, error) {
149
+			if strings.HasPrefix(req.URL.Path, "/services/create") {
150
+				// reset and set image received by the service create endpoint
151
+				serviceCreateImage = ""
152
+				var service swarm.ServiceSpec
153
+				if err := json.NewDecoder(req.Body).Decode(&service); err != nil {
154
+					return nil, fmt.Errorf("could not parse service create request")
155
+				}
156
+				serviceCreateImage = service.TaskTemplate.ContainerSpec.Image
157
+
158
+				b, err := json.Marshal(types.ServiceCreateResponse{
159
+					ID: "service_id",
160
+				})
161
+				if err != nil {
162
+					return nil, err
163
+				}
164
+				return &http.Response{
165
+					StatusCode: http.StatusOK,
166
+					Body:       ioutil.NopCloser(bytes.NewReader(b)),
167
+				}, nil
168
+			} else if strings.HasPrefix(req.URL.Path, "/distribution/cannotresolve") {
169
+				// unresolvable image
170
+				return nil, fmt.Errorf("cannot resolve image")
171
+			} else if strings.HasPrefix(req.URL.Path, "/distribution/") {
172
+				// resolvable images
173
+				b, err := json.Marshal(registrytypes.DistributionInspect{
174
+					Descriptor: v1.Descriptor{
175
+						Digest: digest.Digest(dgst),
176
+					},
177
+				})
178
+				if err != nil {
179
+					return nil, err
180
+				}
181
+				return &http.Response{
182
+					StatusCode: http.StatusOK,
183
+					Body:       ioutil.NopCloser(bytes.NewReader(b)),
184
+				}, nil
185
+			}
186
+			return nil, fmt.Errorf("unexpected URL '%s'", req.URL.Path)
187
+		}),
188
+	}
189
+
190
+	// run pin by digest tests
191
+	for _, p := range pinByDigestTests {
192
+		r, err := client.ServiceCreate(context.Background(), swarm.ServiceSpec{
193
+			TaskTemplate: swarm.TaskSpec{
194
+				ContainerSpec: swarm.ContainerSpec{
195
+					Image: p.img,
196
+				},
197
+			},
198
+		}, types.ServiceCreateOptions{QueryRegistry: true})
199
+
200
+		if err != nil {
201
+			t.Fatal(err)
202
+		}
203
+
204
+		if r.ID != "service_id" {
205
+			t.Fatalf("expected `service_id`, got %s", r.ID)
206
+		}
207
+
208
+		if p.expected != serviceCreateImage {
209
+			t.Fatalf("expected image %s, got %s", p.expected, serviceCreateImage)
210
+		}
211
+	}
212
+}