| package schema2 |
| |
| import ( |
| "context" |
| "reflect" |
| "testing" |
| |
| "github.com/docker/distribution" |
| "github.com/opencontainers/go-digest" |
| ) |
| |
| type mockBlobService struct { |
| descriptors map[digest.Digest]distribution.Descriptor |
| } |
| |
| func (bs *mockBlobService) Stat(ctx context.Context, dgst digest.Digest) (distribution.Descriptor, error) { |
| if descriptor, ok := bs.descriptors[dgst]; ok { |
| return descriptor, nil |
| } |
| return distribution.Descriptor{}, distribution.ErrBlobUnknown |
| } |
| |
| func (bs *mockBlobService) Get(ctx context.Context, dgst digest.Digest) ([]byte, error) { |
| panic("not implemented") |
| } |
| |
| func (bs *mockBlobService) Open(ctx context.Context, dgst digest.Digest) (distribution.ReadSeekCloser, error) { |
| panic("not implemented") |
| } |
| |
| func (bs *mockBlobService) Put(ctx context.Context, mediaType string, p []byte) (distribution.Descriptor, error) { |
| d := distribution.Descriptor{ |
| Digest: digest.FromBytes(p), |
| Size: int64(len(p)), |
| MediaType: "application/octet-stream", |
| } |
| bs.descriptors[d.Digest] = d |
| return d, nil |
| } |
| |
| func (bs *mockBlobService) Create(ctx context.Context, options ...distribution.BlobCreateOption) (distribution.BlobWriter, error) { |
| panic("not implemented") |
| } |
| |
| func (bs *mockBlobService) Resume(ctx context.Context, id string) (distribution.BlobWriter, error) { |
| panic("not implemented") |
| } |
| |
| func TestBuilder(t *testing.T) { |
| imgJSON := []byte(`{ |
| "architecture": "amd64", |
| "config": { |
| "AttachStderr": false, |
| "AttachStdin": false, |
| "AttachStdout": false, |
| "Cmd": [ |
| "/bin/sh", |
| "-c", |
| "echo hi" |
| ], |
| "Domainname": "", |
| "Entrypoint": null, |
| "Env": [ |
| "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin", |
| "derived=true", |
| "asdf=true" |
| ], |
| "Hostname": "23304fc829f9", |
| "Image": "sha256:4ab15c48b859c2920dd5224f92aabcd39a52794c5b3cf088fb3bbb438756c246", |
| "Labels": {}, |
| "OnBuild": [], |
| "OpenStdin": false, |
| "StdinOnce": false, |
| "Tty": false, |
| "User": "", |
| "Volumes": null, |
| "WorkingDir": "" |
| }, |
| "container": "e91032eb0403a61bfe085ff5a5a48e3659e5a6deae9f4d678daa2ae399d5a001", |
| "container_config": { |
| "AttachStderr": false, |
| "AttachStdin": false, |
| "AttachStdout": false, |
| "Cmd": [ |
| "/bin/sh", |
| "-c", |
| "#(nop) CMD [\"/bin/sh\" \"-c\" \"echo hi\"]" |
| ], |
| "Domainname": "", |
| "Entrypoint": null, |
| "Env": [ |
| "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin", |
| "derived=true", |
| "asdf=true" |
| ], |
| "Hostname": "23304fc829f9", |
| "Image": "sha256:4ab15c48b859c2920dd5224f92aabcd39a52794c5b3cf088fb3bbb438756c246", |
| "Labels": {}, |
| "OnBuild": [], |
| "OpenStdin": false, |
| "StdinOnce": false, |
| "Tty": false, |
| "User": "", |
| "Volumes": null, |
| "WorkingDir": "" |
| }, |
| "created": "2015-11-04T23:06:32.365666163Z", |
| "docker_version": "1.9.0-dev", |
| "history": [ |
| { |
| "created": "2015-10-31T22:22:54.690851953Z", |
| "created_by": "/bin/sh -c #(nop) ADD file:a3bc1e842b69636f9df5256c49c5374fb4eef1e281fe3f282c65fb853ee171c5 in /" |
| }, |
| { |
| "created": "2015-10-31T22:22:55.613815829Z", |
| "created_by": "/bin/sh -c #(nop) CMD [\"sh\"]" |
| }, |
| { |
| "created": "2015-11-04T23:06:30.934316144Z", |
| "created_by": "/bin/sh -c #(nop) ENV derived=true", |
| "empty_layer": true |
| }, |
| { |
| "created": "2015-11-04T23:06:31.192097572Z", |
| "created_by": "/bin/sh -c #(nop) ENV asdf=true", |
| "empty_layer": true |
| }, |
| { |
| "created": "2015-11-04T23:06:32.083868454Z", |
| "created_by": "/bin/sh -c dd if=/dev/zero of=/file bs=1024 count=1024" |
| }, |
| { |
| "created": "2015-11-04T23:06:32.365666163Z", |
| "created_by": "/bin/sh -c #(nop) CMD [\"/bin/sh\" \"-c\" \"echo hi\"]", |
| "empty_layer": true |
| } |
| ], |
| "os": "linux", |
| "rootfs": { |
| "diff_ids": [ |
| "sha256:c6f988f4874bb0add23a778f753c65efe992244e148a1d2ec2a8b664fb66bbd1", |
| "sha256:5f70bf18a086007016e948b04aed3b82103a36bea41755b6cddfaf10ace3c6ef", |
| "sha256:13f53e08df5a220ab6d13c58b2bf83a59cbdc2e04d0a3f041ddf4b0ba4112d49" |
| ], |
| "type": "layers" |
| } |
| }`) |
| configDigest := digest.FromBytes(imgJSON) |
| |
| descriptors := []distribution.Descriptor{ |
| { |
| Digest: digest.Digest("sha256:a3ed95caeb02ffe68cdd9fd84406680ae93d633cb16422d00e8a7c22955b46d4"), |
| Size: 5312, |
| MediaType: MediaTypeLayer, |
| }, |
| { |
| Digest: digest.Digest("sha256:86e0e091d0da6bde2456dbb48306f3956bbeb2eae1b5b9a43045843f69fe4aaa"), |
| Size: 235231, |
| MediaType: MediaTypeLayer, |
| }, |
| { |
| Digest: digest.Digest("sha256:b4ed95caeb02ffe68cdd9fd84406680ae93d633cb16422d00e8a7c22955b46d4"), |
| Size: 639152, |
| MediaType: MediaTypeLayer, |
| }, |
| } |
| |
| bs := &mockBlobService{descriptors: make(map[digest.Digest]distribution.Descriptor)} |
| builder := NewManifestBuilder(bs, MediaTypeImageConfig, imgJSON) |
| |
| for _, d := range descriptors { |
| if err := builder.AppendReference(d); err != nil { |
| t.Fatalf("AppendReference returned error: %v", err) |
| } |
| } |
| |
| built, err := builder.Build(context.Background()) |
| if err != nil { |
| t.Fatalf("Build returned error: %v", err) |
| } |
| |
| // Check that the config was put in the blob store |
| _, err = bs.Stat(context.Background(), configDigest) |
| if err != nil { |
| t.Fatal("config was not put in the blob store") |
| } |
| |
| manifest := built.(*DeserializedManifest).Manifest |
| |
| if manifest.Versioned.SchemaVersion != 2 { |
| t.Fatal("SchemaVersion != 2") |
| } |
| |
| target := manifest.Target() |
| if target.Digest != configDigest { |
| t.Fatalf("unexpected digest in target: %s", target.Digest.String()) |
| } |
| if target.MediaType != MediaTypeImageConfig { |
| t.Fatalf("unexpected media type in target: %s", target.MediaType) |
| } |
| if target.Size != 3153 { |
| t.Fatalf("unexpected size in target: %d", target.Size) |
| } |
| |
| references := manifest.References() |
| expected := append([]distribution.Descriptor{manifest.Target()}, descriptors...) |
| if !reflect.DeepEqual(references, expected) { |
| t.Fatal("References() does not match the descriptors added") |
| } |
| } |