Browse code

Build a pre-schema2 registry to test schema1 push/pull

Add DockerSchema1RegistrySuite which uses this registry, and make
applicable integration tests run as part of this suite.

Signed-off-by: Aaron Lehmann <aaron.lehmann@docker.com>

Aaron Lehmann authored on 2015/12/19 08:06:23
Showing 7 changed files
... ...
@@ -142,14 +142,21 @@ RUN set -x \
142 142
 	) \
143 143
 	&& rm -rf "$SECCOMP_PATH"
144 144
 
145
-# Install registry
146
-ENV REGISTRY_COMMIT ec87e9b6971d831f0eff752ddb54fb64693e51cd
145
+# Install two versions of the registry. The first is an older version that
146
+# only supports schema1 manifests. The second is a newer version that supports
147
+# both. This allows integration-cli tests to cover push/pull with both schema1
148
+# and schema2 manifests.
149
+ENV REGISTRY_COMMIT_SCHEMA1 ec87e9b6971d831f0eff752ddb54fb64693e51cd
150
+ENV REGISTRY_COMMIT a7ae88da459b98b481a245e5b1750134724ac67d
147 151
 RUN set -x \
148 152
 	&& export GOPATH="$(mktemp -d)" \
149 153
 	&& git clone https://github.com/docker/distribution.git "$GOPATH/src/github.com/docker/distribution" \
150 154
 	&& (cd "$GOPATH/src/github.com/docker/distribution" && git checkout -q "$REGISTRY_COMMIT") \
151 155
 	&& GOPATH="$GOPATH/src/github.com/docker/distribution/Godeps/_workspace:$GOPATH" \
152 156
 		go build -o /usr/local/bin/registry-v2 github.com/docker/distribution/cmd/registry \
157
+	&& (cd "$GOPATH/src/github.com/docker/distribution" && git checkout -q "$REGISTRY_COMMIT_SCHEMA1") \
158
+	&& GOPATH="$GOPATH/src/github.com/docker/distribution/Godeps/_workspace:$GOPATH" \
159
+		go build -o /usr/local/bin/registry-v2-schema1 github.com/docker/distribution/cmd/registry \
153 160
 	&& rm -rf "$GOPATH"
154 161
 
155 162
 # Install notary server
... ...
@@ -48,7 +48,7 @@ type DockerRegistrySuite struct {
48 48
 
49 49
 func (s *DockerRegistrySuite) SetUpTest(c *check.C) {
50 50
 	testRequires(c, DaemonIsLinux)
51
-	s.reg = setupRegistry(c)
51
+	s.reg = setupRegistry(c, false)
52 52
 	s.d = NewDaemon(c)
53 53
 }
54 54
 
... ...
@@ -63,6 +63,34 @@ func (s *DockerRegistrySuite) TearDownTest(c *check.C) {
63 63
 }
64 64
 
65 65
 func init() {
66
+	check.Suite(&DockerSchema1RegistrySuite{
67
+		ds: &DockerSuite{},
68
+	})
69
+}
70
+
71
+type DockerSchema1RegistrySuite struct {
72
+	ds  *DockerSuite
73
+	reg *testRegistryV2
74
+	d   *Daemon
75
+}
76
+
77
+func (s *DockerSchema1RegistrySuite) SetUpTest(c *check.C) {
78
+	testRequires(c, DaemonIsLinux)
79
+	s.reg = setupRegistry(c, true)
80
+	s.d = NewDaemon(c)
81
+}
82
+
83
+func (s *DockerSchema1RegistrySuite) TearDownTest(c *check.C) {
84
+	if s.reg != nil {
85
+		s.reg.Close()
86
+	}
87
+	if s.ds != nil {
88
+		s.ds.TearDownTest(c)
89
+	}
90
+	s.d.Stop()
91
+}
92
+
93
+func init() {
66 94
 	check.Suite(&DockerDaemonSuite{
67 95
 		ds: &DockerSuite{},
68 96
 	})
... ...
@@ -97,7 +125,7 @@ type DockerTrustSuite struct {
97 97
 }
98 98
 
99 99
 func (s *DockerTrustSuite) SetUpTest(c *check.C) {
100
-	s.reg = setupRegistry(c)
100
+	s.reg = setupRegistry(c, false)
101 101
 	s.not = setupNotary(c)
102 102
 }
103 103
 
... ...
@@ -10,6 +10,7 @@ import (
10 10
 
11 11
 	"github.com/docker/distribution/digest"
12 12
 	"github.com/docker/distribution/manifest/schema1"
13
+	"github.com/docker/distribution/manifest/schema2"
13 14
 	"github.com/docker/docker/pkg/integration/checker"
14 15
 	"github.com/docker/docker/pkg/stringutils"
15 16
 	"github.com/docker/engine-api/types"
... ...
@@ -56,7 +57,7 @@ func setupImageWithTag(c *check.C, tag string) (digest.Digest, error) {
56 56
 	return digest.Digest(pushDigest), nil
57 57
 }
58 58
 
59
-func (s *DockerRegistrySuite) TestPullByTagDisplaysDigest(c *check.C) {
59
+func testPullByTagDisplaysDigest(c *check.C) {
60 60
 	testRequires(c, DaemonIsLinux)
61 61
 	pushDigest, err := setupImage(c)
62 62
 	c.Assert(err, checker.IsNil, check.Commentf("error setting up image"))
... ...
@@ -73,7 +74,15 @@ func (s *DockerRegistrySuite) TestPullByTagDisplaysDigest(c *check.C) {
73 73
 	c.Assert(pushDigest.String(), checker.Equals, pullDigest)
74 74
 }
75 75
 
76
-func (s *DockerRegistrySuite) TestPullByDigest(c *check.C) {
76
+func (s *DockerRegistrySuite) TestPullByTagDisplaysDigest(c *check.C) {
77
+	testPullByTagDisplaysDigest(c)
78
+}
79
+
80
+func (s *DockerSchema1RegistrySuite) TestPullByTagDisplaysDigest(c *check.C) {
81
+	testPullByTagDisplaysDigest(c)
82
+}
83
+
84
+func testPullByDigest(c *check.C) {
77 85
 	testRequires(c, DaemonIsLinux)
78 86
 	pushDigest, err := setupImage(c)
79 87
 	c.Assert(err, checker.IsNil, check.Commentf("error setting up image"))
... ...
@@ -91,7 +100,15 @@ func (s *DockerRegistrySuite) TestPullByDigest(c *check.C) {
91 91
 	c.Assert(pushDigest.String(), checker.Equals, pullDigest)
92 92
 }
93 93
 
94
-func (s *DockerRegistrySuite) TestPullByDigestNoFallback(c *check.C) {
94
+func (s *DockerRegistrySuite) TestPullByDigest(c *check.C) {
95
+	testPullByDigest(c)
96
+}
97
+
98
+func (s *DockerSchema1RegistrySuite) TestPullByDigest(c *check.C) {
99
+	testPullByDigest(c)
100
+}
101
+
102
+func testPullByDigestNoFallback(c *check.C) {
95 103
 	testRequires(c, DaemonIsLinux)
96 104
 	// pull from the registry using the <name>@<digest> reference
97 105
 	imageReference := fmt.Sprintf("%s@sha256:ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", repoName)
... ...
@@ -100,6 +117,14 @@ func (s *DockerRegistrySuite) TestPullByDigestNoFallback(c *check.C) {
100 100
 	c.Assert(out, checker.Contains, "manifest unknown", check.Commentf("expected non-zero exit status and correct error message when pulling non-existing image"))
101 101
 }
102 102
 
103
+func (s *DockerRegistrySuite) TestPullByDigestNoFallback(c *check.C) {
104
+	testPullByDigestNoFallback(c)
105
+}
106
+
107
+func (s *DockerSchema1RegistrySuite) TestPullByDigestNoFallback(c *check.C) {
108
+	testPullByDigestNoFallback(c)
109
+}
110
+
103 111
 func (s *DockerRegistrySuite) TestCreateByDigest(c *check.C) {
104 112
 	pushDigest, err := setupImage(c)
105 113
 	c.Assert(err, checker.IsNil, check.Commentf("error setting up image"))
... ...
@@ -372,6 +397,7 @@ func (s *DockerRegistrySuite) TestDeleteImageByIDOnlyPulledByDigest(c *check.C)
372 372
 
373 373
 // TestPullFailsWithAlteredManifest tests that a `docker pull` fails when
374 374
 // we have modified a manifest blob and its digest cannot be verified.
375
+// This is the schema2 version of the test.
375 376
 func (s *DockerRegistrySuite) TestPullFailsWithAlteredManifest(c *check.C) {
376 377
 	testRequires(c, DaemonIsLinux)
377 378
 	manifestDigest, err := setupImage(c)
... ...
@@ -380,6 +406,46 @@ func (s *DockerRegistrySuite) TestPullFailsWithAlteredManifest(c *check.C) {
380 380
 	// Load the target manifest blob.
381 381
 	manifestBlob := s.reg.readBlobContents(c, manifestDigest)
382 382
 
383
+	var imgManifest schema2.Manifest
384
+	err = json.Unmarshal(manifestBlob, &imgManifest)
385
+	c.Assert(err, checker.IsNil, check.Commentf("unable to decode image manifest from blob"))
386
+
387
+	// Change a layer in the manifest.
388
+	imgManifest.Layers[0].Digest = digest.Digest("sha256:0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef")
389
+
390
+	// Move the existing data file aside, so that we can replace it with a
391
+	// malicious blob of data. NOTE: we defer the returned undo func.
392
+	undo := s.reg.tempMoveBlobData(c, manifestDigest)
393
+	defer undo()
394
+
395
+	alteredManifestBlob, err := json.MarshalIndent(imgManifest, "", "   ")
396
+	c.Assert(err, checker.IsNil, check.Commentf("unable to encode altered image manifest to JSON"))
397
+
398
+	s.reg.writeBlobContents(c, manifestDigest, alteredManifestBlob)
399
+
400
+	// Now try pulling that image by digest. We should get an error about
401
+	// digest verification for the manifest digest.
402
+
403
+	// Pull from the registry using the <name>@<digest> reference.
404
+	imageReference := fmt.Sprintf("%s@%s", repoName, manifestDigest)
405
+	out, exitStatus, _ := dockerCmdWithError("pull", imageReference)
406
+	c.Assert(exitStatus, checker.Not(check.Equals), 0)
407
+
408
+	expectedErrorMsg := fmt.Sprintf("manifest verification failed for digest %s", manifestDigest)
409
+	c.Assert(out, checker.Contains, expectedErrorMsg)
410
+}
411
+
412
+// TestPullFailsWithAlteredManifest tests that a `docker pull` fails when
413
+// we have modified a manifest blob and its digest cannot be verified.
414
+// This is the schema1 version of the test.
415
+func (s *DockerSchema1RegistrySuite) TestPullFailsWithAlteredManifest(c *check.C) {
416
+	testRequires(c, DaemonIsLinux)
417
+	manifestDigest, err := setupImage(c)
418
+	c.Assert(err, checker.IsNil, check.Commentf("error setting up image"))
419
+
420
+	// Load the target manifest blob.
421
+	manifestBlob := s.reg.readBlobContents(c, manifestDigest)
422
+
383 423
 	var imgManifest schema1.Manifest
384 424
 	err = json.Unmarshal(manifestBlob, &imgManifest)
385 425
 	c.Assert(err, checker.IsNil, check.Commentf("unable to decode image manifest from blob"))
... ...
@@ -413,6 +479,7 @@ func (s *DockerRegistrySuite) TestPullFailsWithAlteredManifest(c *check.C) {
413 413
 
414 414
 // TestPullFailsWithAlteredLayer tests that a `docker pull` fails when
415 415
 // we have modified a layer blob and its digest cannot be verified.
416
+// This is the schema2 version of the test.
416 417
 func (s *DockerRegistrySuite) TestPullFailsWithAlteredLayer(c *check.C) {
417 418
 	testRequires(c, DaemonIsLinux)
418 419
 	manifestDigest, err := setupImage(c)
... ...
@@ -421,6 +488,49 @@ func (s *DockerRegistrySuite) TestPullFailsWithAlteredLayer(c *check.C) {
421 421
 	// Load the target manifest blob.
422 422
 	manifestBlob := s.reg.readBlobContents(c, manifestDigest)
423 423
 
424
+	var imgManifest schema2.Manifest
425
+	err = json.Unmarshal(manifestBlob, &imgManifest)
426
+	c.Assert(err, checker.IsNil)
427
+
428
+	// Next, get the digest of one of the layers from the manifest.
429
+	targetLayerDigest := imgManifest.Layers[0].Digest
430
+
431
+	// Move the existing data file aside, so that we can replace it with a
432
+	// malicious blob of data. NOTE: we defer the returned undo func.
433
+	undo := s.reg.tempMoveBlobData(c, targetLayerDigest)
434
+	defer undo()
435
+
436
+	// Now make a fake data blob in this directory.
437
+	s.reg.writeBlobContents(c, targetLayerDigest, []byte("This is not the data you are looking for."))
438
+
439
+	// Now try pulling that image by digest. We should get an error about
440
+	// digest verification for the target layer digest.
441
+
442
+	// Remove distribution cache to force a re-pull of the blobs
443
+	if err := os.RemoveAll(filepath.Join(dockerBasePath, "image", s.d.storageDriver, "distribution")); err != nil {
444
+		c.Fatalf("error clearing distribution cache: %v", err)
445
+	}
446
+
447
+	// Pull from the registry using the <name>@<digest> reference.
448
+	imageReference := fmt.Sprintf("%s@%s", repoName, manifestDigest)
449
+	out, exitStatus, _ := dockerCmdWithError("pull", imageReference)
450
+	c.Assert(exitStatus, checker.Not(check.Equals), 0, check.Commentf("expected a zero exit status"))
451
+
452
+	expectedErrorMsg := fmt.Sprintf("filesystem layer verification failed for digest %s", targetLayerDigest)
453
+	c.Assert(out, checker.Contains, expectedErrorMsg, check.Commentf("expected error message in output: %s", out))
454
+}
455
+
456
+// TestPullFailsWithAlteredLayer tests that a `docker pull` fails when
457
+// we have modified a layer blob and its digest cannot be verified.
458
+// This is the schema1 version of the test.
459
+func (s *DockerSchema1RegistrySuite) TestPullFailsWithAlteredLayer(c *check.C) {
460
+	testRequires(c, DaemonIsLinux)
461
+	manifestDigest, err := setupImage(c)
462
+	c.Assert(err, checker.IsNil)
463
+
464
+	// Load the target manifest blob.
465
+	manifestBlob := s.reg.readBlobContents(c, manifestDigest)
466
+
424 467
 	var imgManifest schema1.Manifest
425 468
 	err = json.Unmarshal(manifestBlob, &imgManifest)
426 469
 	c.Assert(err, checker.IsNil)
... ...
@@ -9,11 +9,11 @@ import (
9 9
 	"github.com/go-check/check"
10 10
 )
11 11
 
12
-// TestPullImageWithAliases pulls a specific image tag and verifies that any aliases (i.e., other
12
+// testPullImageWithAliases pulls a specific image tag and verifies that any aliases (i.e., other
13 13
 // tags for the same image) are not also pulled down.
14 14
 //
15 15
 // Ref: docker/docker#8141
16
-func (s *DockerRegistrySuite) TestPullImageWithAliases(c *check.C) {
16
+func testPullImageWithAliases(c *check.C) {
17 17
 	repoName := fmt.Sprintf("%v/dockercli/busybox", privateRegistryURL)
18 18
 
19 19
 	repos := []string{}
... ...
@@ -40,8 +40,16 @@ func (s *DockerRegistrySuite) TestPullImageWithAliases(c *check.C) {
40 40
 	}
41 41
 }
42 42
 
43
-// TestConcurrentPullWholeRepo pulls the same repo concurrently.
44
-func (s *DockerRegistrySuite) TestConcurrentPullWholeRepo(c *check.C) {
43
+func (s *DockerRegistrySuite) TestPullImageWithAliases(c *check.C) {
44
+	testPullImageWithAliases(c)
45
+}
46
+
47
+func (s *DockerSchema1RegistrySuite) TestPullImageWithAliases(c *check.C) {
48
+	testPullImageWithAliases(c)
49
+}
50
+
51
+// testConcurrentPullWholeRepo pulls the same repo concurrently.
52
+func testConcurrentPullWholeRepo(c *check.C) {
45 53
 	repoName := fmt.Sprintf("%v/dockercli/busybox", privateRegistryURL)
46 54
 
47 55
 	repos := []string{}
... ...
@@ -89,8 +97,16 @@ func (s *DockerRegistrySuite) TestConcurrentPullWholeRepo(c *check.C) {
89 89
 	}
90 90
 }
91 91
 
92
-// TestConcurrentFailingPull tries a concurrent pull that doesn't succeed.
93
-func (s *DockerRegistrySuite) TestConcurrentFailingPull(c *check.C) {
92
+func (s *DockerRegistrySuite) testConcurrentPullWholeRepo(c *check.C) {
93
+	testConcurrentPullWholeRepo(c)
94
+}
95
+
96
+func (s *DockerSchema1RegistrySuite) testConcurrentPullWholeRepo(c *check.C) {
97
+	testConcurrentPullWholeRepo(c)
98
+}
99
+
100
+// testConcurrentFailingPull tries a concurrent pull that doesn't succeed.
101
+func testConcurrentFailingPull(c *check.C) {
94 102
 	repoName := fmt.Sprintf("%v/dockercli/busybox", privateRegistryURL)
95 103
 
96 104
 	// Run multiple pulls concurrently
... ...
@@ -112,9 +128,17 @@ func (s *DockerRegistrySuite) TestConcurrentFailingPull(c *check.C) {
112 112
 	}
113 113
 }
114 114
 
115
-// TestConcurrentPullMultipleTags pulls multiple tags from the same repo
115
+func (s *DockerRegistrySuite) testConcurrentFailingPull(c *check.C) {
116
+	testConcurrentFailingPull(c)
117
+}
118
+
119
+func (s *DockerSchema1RegistrySuite) testConcurrentFailingPull(c *check.C) {
120
+	testConcurrentFailingPull(c)
121
+}
122
+
123
+// testConcurrentPullMultipleTags pulls multiple tags from the same repo
116 124
 // concurrently.
117
-func (s *DockerRegistrySuite) TestConcurrentPullMultipleTags(c *check.C) {
125
+func testConcurrentPullMultipleTags(c *check.C) {
118 126
 	repoName := fmt.Sprintf("%v/dockercli/busybox", privateRegistryURL)
119 127
 
120 128
 	repos := []string{}
... ...
@@ -161,9 +185,17 @@ func (s *DockerRegistrySuite) TestConcurrentPullMultipleTags(c *check.C) {
161 161
 	}
162 162
 }
163 163
 
164
-// TestPullIDStability verifies that pushing an image and pulling it back
164
+func (s *DockerRegistrySuite) TestConcurrentPullMultipleTags(c *check.C) {
165
+	testConcurrentPullMultipleTags(c)
166
+}
167
+
168
+func (s *DockerSchema1RegistrySuite) TestConcurrentPullMultipleTags(c *check.C) {
169
+	testConcurrentPullMultipleTags(c)
170
+}
171
+
172
+// testPullIDStability verifies that pushing an image and pulling it back
165 173
 // preserves the image ID.
166
-func (s *DockerRegistrySuite) TestPullIDStability(c *check.C) {
174
+func testPullIDStability(c *check.C) {
167 175
 	derivedImage := privateRegistryURL + "/dockercli/id-stability"
168 176
 	baseImage := "busybox"
169 177
 
... ...
@@ -229,6 +261,14 @@ func (s *DockerRegistrySuite) TestPullIDStability(c *check.C) {
229 229
 	}
230 230
 }
231 231
 
232
+func (s *DockerRegistrySuite) TestPullIDStability(c *check.C) {
233
+	testPullIDStability(c)
234
+}
235
+
236
+func (s *DockerSchema1RegistrySuite) TestPullIDStability(c *check.C) {
237
+	testPullIDStability(c)
238
+}
239
+
232 240
 // TestPullFallbackOn404 tries to pull a nonexistent manifest and confirms that
233 241
 // the pull falls back to the v1 protocol.
234 242
 //
... ...
@@ -16,7 +16,7 @@ import (
16 16
 )
17 17
 
18 18
 // Pushing an image to a private registry.
19
-func (s *DockerRegistrySuite) TestPushBusyboxImage(c *check.C) {
19
+func testPushBusyboxImage(c *check.C) {
20 20
 	repoName := fmt.Sprintf("%v/dockercli/busybox", privateRegistryURL)
21 21
 	// tag the image to upload it to the private registry
22 22
 	dockerCmd(c, "tag", "busybox", repoName)
... ...
@@ -24,13 +24,21 @@ func (s *DockerRegistrySuite) TestPushBusyboxImage(c *check.C) {
24 24
 	dockerCmd(c, "push", repoName)
25 25
 }
26 26
 
27
+func (s *DockerRegistrySuite) TestPushBusyboxImage(c *check.C) {
28
+	testPushBusyboxImage(c)
29
+}
30
+
31
+func (s *DockerSchema1RegistrySuite) TestPushBusyboxImage(c *check.C) {
32
+	testPushBusyboxImage(c)
33
+}
34
+
27 35
 // pushing an image without a prefix should throw an error
28 36
 func (s *DockerSuite) TestPushUnprefixedRepo(c *check.C) {
29 37
 	out, _, err := dockerCmdWithError("push", "busybox")
30 38
 	c.Assert(err, check.NotNil, check.Commentf("pushing an unprefixed repo didn't result in a non-zero exit status: %s", out))
31 39
 }
32 40
 
33
-func (s *DockerRegistrySuite) TestPushUntagged(c *check.C) {
41
+func testPushUntagged(c *check.C) {
34 42
 	repoName := fmt.Sprintf("%v/dockercli/busybox", privateRegistryURL)
35 43
 	expected := "Repository does not exist"
36 44
 
... ...
@@ -39,7 +47,15 @@ func (s *DockerRegistrySuite) TestPushUntagged(c *check.C) {
39 39
 	c.Assert(out, checker.Contains, expected, check.Commentf("pushing the image failed"))
40 40
 }
41 41
 
42
-func (s *DockerRegistrySuite) TestPushBadTag(c *check.C) {
42
+func (s *DockerRegistrySuite) TestPushUntagged(c *check.C) {
43
+	testPushUntagged(c)
44
+}
45
+
46
+func (s *DockerSchema1RegistrySuite) TestPushUntagged(c *check.C) {
47
+	testPushUntagged(c)
48
+}
49
+
50
+func testPushBadTag(c *check.C) {
43 51
 	repoName := fmt.Sprintf("%v/dockercli/busybox:latest", privateRegistryURL)
44 52
 	expected := "does not exist"
45 53
 
... ...
@@ -48,7 +64,15 @@ func (s *DockerRegistrySuite) TestPushBadTag(c *check.C) {
48 48
 	c.Assert(out, checker.Contains, expected, check.Commentf("pushing the image failed"))
49 49
 }
50 50
 
51
-func (s *DockerRegistrySuite) TestPushMultipleTags(c *check.C) {
51
+func (s *DockerRegistrySuite) TestPushBadTag(c *check.C) {
52
+	testPushBadTag(c)
53
+}
54
+
55
+func (s *DockerSchema1RegistrySuite) TestPushBadTag(c *check.C) {
56
+	testPushBadTag(c)
57
+}
58
+
59
+func testPushMultipleTags(c *check.C) {
52 60
 	repoName := fmt.Sprintf("%v/dockercli/busybox", privateRegistryURL)
53 61
 	repoTag1 := fmt.Sprintf("%v/dockercli/busybox:t1", privateRegistryURL)
54 62
 	repoTag2 := fmt.Sprintf("%v/dockercli/busybox:t2", privateRegistryURL)
... ...
@@ -85,7 +109,15 @@ func (s *DockerRegistrySuite) TestPushMultipleTags(c *check.C) {
85 85
 	}
86 86
 }
87 87
 
88
-func (s *DockerRegistrySuite) TestPushEmptyLayer(c *check.C) {
88
+func (s *DockerRegistrySuite) TestPushMultipleTags(c *check.C) {
89
+	testPushMultipleTags(c)
90
+}
91
+
92
+func (s *DockerSchema1RegistrySuite) TestPushMultipleTags(c *check.C) {
93
+	testPushMultipleTags(c)
94
+}
95
+
96
+func testPushEmptyLayer(c *check.C) {
89 97
 	repoName := fmt.Sprintf("%v/dockercli/emptylayer", privateRegistryURL)
90 98
 	emptyTarball, err := ioutil.TempFile("", "empty_tarball")
91 99
 	c.Assert(err, check.IsNil, check.Commentf("Unable to create test file"))
... ...
@@ -107,6 +139,14 @@ func (s *DockerRegistrySuite) TestPushEmptyLayer(c *check.C) {
107 107
 	c.Assert(err, check.IsNil, check.Commentf("pushing the image to the private registry has failed: %s", out))
108 108
 }
109 109
 
110
+func (s *DockerRegistrySuite) TestPushEmptyLayer(c *check.C) {
111
+	testPushEmptyLayer(c)
112
+}
113
+
114
+func (s *DockerSchema1RegistrySuite) TestPushEmptyLayer(c *check.C) {
115
+	testPushEmptyLayer(c)
116
+}
117
+
110 118
 func (s *DockerTrustSuite) TestTrustedPush(c *check.C) {
111 119
 	repoName := fmt.Sprintf("%v/dockercli/trusted:latest", privateRegistryURL)
112 120
 	// tag the image and upload it to the private registry
... ...
@@ -1554,9 +1554,9 @@ func daemonTime(c *check.C) time.Time {
1554 1554
 	return dt
1555 1555
 }
1556 1556
 
1557
-func setupRegistry(c *check.C) *testRegistryV2 {
1557
+func setupRegistry(c *check.C, schema1 bool) *testRegistryV2 {
1558 1558
 	testRequires(c, RegistryHosting)
1559
-	reg, err := newTestRegistryV2(c)
1559
+	reg, err := newTestRegistryV2(c, schema1)
1560 1560
 	c.Assert(err, check.IsNil)
1561 1561
 
1562 1562
 	// Wait for registry to be ready to serve requests.
... ...
@@ -12,14 +12,17 @@ import (
12 12
 	"github.com/go-check/check"
13 13
 )
14 14
 
15
-const v2binary = "registry-v2"
15
+const (
16
+	v2binary        = "registry-v2"
17
+	v2binarySchema1 = "registry-v2-schema1"
18
+)
16 19
 
17 20
 type testRegistryV2 struct {
18 21
 	cmd *exec.Cmd
19 22
 	dir string
20 23
 }
21 24
 
22
-func newTestRegistryV2(c *check.C) (*testRegistryV2, error) {
25
+func newTestRegistryV2(c *check.C, schema1 bool) (*testRegistryV2, error) {
23 26
 	template := `version: 0.1
24 27
 loglevel: debug
25 28
 storage:
... ...
@@ -41,7 +44,11 @@ http:
41 41
 		return nil, err
42 42
 	}
43 43
 
44
-	cmd := exec.Command(v2binary, confPath)
44
+	binary := v2binary
45
+	if schema1 {
46
+		binary = v2binarySchema1
47
+	}
48
+	cmd := exec.Command(binary, confPath)
45 49
 	if err := cmd.Start(); err != nil {
46 50
 		os.RemoveAll(tmp)
47 51
 		if os.IsNotExist(err) {