...

Source file src/github.com/docker/distribution/manifest/ocischema/builder_test.go

Documentation: github.com/docker/distribution/manifest/ocischema

     1  package ocischema
     2  
     3  import (
     4  	"context"
     5  	"reflect"
     6  	"testing"
     7  
     8  	"github.com/docker/distribution"
     9  	"github.com/opencontainers/go-digest"
    10  	v1 "github.com/opencontainers/image-spec/specs-go/v1"
    11  )
    12  
    13  type mockBlobService struct {
    14  	descriptors map[digest.Digest]distribution.Descriptor
    15  }
    16  
    17  func (bs *mockBlobService) Stat(ctx context.Context, dgst digest.Digest) (distribution.Descriptor, error) {
    18  	if descriptor, ok := bs.descriptors[dgst]; ok {
    19  		return descriptor, nil
    20  	}
    21  	return distribution.Descriptor{}, distribution.ErrBlobUnknown
    22  }
    23  
    24  func (bs *mockBlobService) Get(ctx context.Context, dgst digest.Digest) ([]byte, error) {
    25  	panic("not implemented")
    26  }
    27  
    28  func (bs *mockBlobService) Open(ctx context.Context, dgst digest.Digest) (distribution.ReadSeekCloser, error) {
    29  	panic("not implemented")
    30  }
    31  
    32  func (bs *mockBlobService) Put(ctx context.Context, mediaType string, p []byte) (distribution.Descriptor, error) {
    33  	d := distribution.Descriptor{
    34  		Digest:    digest.FromBytes(p),
    35  		Size:      int64(len(p)),
    36  		MediaType: "application/octet-stream",
    37  	}
    38  	bs.descriptors[d.Digest] = d
    39  	return d, nil
    40  }
    41  
    42  func (bs *mockBlobService) Create(ctx context.Context, options ...distribution.BlobCreateOption) (distribution.BlobWriter, error) {
    43  	panic("not implemented")
    44  }
    45  
    46  func (bs *mockBlobService) Resume(ctx context.Context, id string) (distribution.BlobWriter, error) {
    47  	panic("not implemented")
    48  }
    49  
    50  func TestBuilder(t *testing.T) {
    51  	imgJSON := []byte(`{
    52      "created": "2015-10-31T22:22:56.015925234Z",
    53      "author": "Alyssa P. Hacker <alyspdev@example.com>",
    54      "architecture": "amd64",
    55      "os": "linux",
    56      "config": {
    57          "User": "alice",
    58          "ExposedPorts": {
    59              "8080/tcp": {}
    60          },
    61          "Env": [
    62              "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
    63              "FOO=oci_is_a",
    64              "BAR=well_written_spec"
    65          ],
    66          "Entrypoint": [
    67              "/bin/my-app-binary"
    68          ],
    69          "Cmd": [
    70              "--foreground",
    71              "--config",
    72              "/etc/my-app.d/default.cfg"
    73          ],
    74          "Volumes": {
    75              "/var/job-result-data": {},
    76              "/var/log/my-app-logs": {}
    77          },
    78          "WorkingDir": "/home/alice",
    79          "Labels": {
    80              "com.example.project.git.url": "https://example.com/project.git",
    81              "com.example.project.git.commit": "45a939b2999782a3f005621a8d0f29aa387e1d6b"
    82          }
    83      },
    84      "rootfs": {
    85        "diff_ids": [
    86          "sha256:c6f988f4874bb0add23a778f753c65efe992244e148a1d2ec2a8b664fb66bbd1",
    87          "sha256:5f70bf18a086007016e948b04aed3b82103a36bea41755b6cddfaf10ace3c6ef"
    88        ],
    89        "type": "layers"
    90      },
    91      "annotations": {
    92         "hot": "potato"
    93      }
    94      "history": [
    95        {
    96          "created": "2015-10-31T22:22:54.690851953Z",
    97          "created_by": "/bin/sh -c #(nop) ADD file:a3bc1e842b69636f9df5256c49c5374fb4eef1e281fe3f282c65fb853ee171c5 in /"
    98        },
    99        {
   100          "created": "2015-10-31T22:22:55.613815829Z",
   101          "created_by": "/bin/sh -c #(nop) CMD [\"sh\"]",
   102          "empty_layer": true
   103        }
   104      ]
   105  }`)
   106  	configDigest := digest.FromBytes(imgJSON)
   107  
   108  	descriptors := []distribution.Descriptor{
   109  		{
   110  			Digest:      digest.Digest("sha256:a3ed95caeb02ffe68cdd9fd84406680ae93d633cb16422d00e8a7c22955b46d4"),
   111  			Size:        5312,
   112  			MediaType:   v1.MediaTypeImageLayerGzip,
   113  			Annotations: map[string]string{"apple": "orange", "lettuce": "wrap"},
   114  		},
   115  		{
   116  			Digest:    digest.Digest("sha256:86e0e091d0da6bde2456dbb48306f3956bbeb2eae1b5b9a43045843f69fe4aaa"),
   117  			Size:      235231,
   118  			MediaType: v1.MediaTypeImageLayerGzip,
   119  		},
   120  		{
   121  			Digest:    digest.Digest("sha256:b4ed95caeb02ffe68cdd9fd84406680ae93d633cb16422d00e8a7c22955b46d4"),
   122  			Size:      639152,
   123  			MediaType: v1.MediaTypeImageLayerGzip,
   124  		},
   125  	}
   126  	annotations := map[string]string{"hot": "potato"}
   127  
   128  	bs := &mockBlobService{descriptors: make(map[digest.Digest]distribution.Descriptor)}
   129  	builder := NewManifestBuilder(bs, imgJSON, annotations)
   130  
   131  	for _, d := range descriptors {
   132  		if err := builder.AppendReference(d); err != nil {
   133  			t.Fatalf("AppendReference returned error: %v", err)
   134  		}
   135  	}
   136  
   137  	built, err := builder.Build(context.Background())
   138  	if err != nil {
   139  		t.Fatalf("Build returned error: %v", err)
   140  	}
   141  
   142  	// Check that the config was put in the blob store
   143  	_, err = bs.Stat(context.Background(), configDigest)
   144  	if err != nil {
   145  		t.Fatal("config was not put in the blob store")
   146  	}
   147  
   148  	manifest := built.(*DeserializedManifest).Manifest
   149  	if manifest.Annotations["hot"] != "potato" {
   150  		t.Fatalf("unexpected annotation in manifest: %s", manifest.Annotations["hot"])
   151  	}
   152  
   153  	if manifest.Versioned.SchemaVersion != 2 {
   154  		t.Fatal("SchemaVersion != 2")
   155  	}
   156  
   157  	target := manifest.Target()
   158  	if target.Digest != configDigest {
   159  		t.Fatalf("unexpected digest in target: %s", target.Digest.String())
   160  	}
   161  	if target.MediaType != v1.MediaTypeImageConfig {
   162  		t.Fatalf("unexpected media type in target: %s", target.MediaType)
   163  	}
   164  	if target.Size != 1632 {
   165  		t.Fatalf("unexpected size in target: %d", target.Size)
   166  	}
   167  
   168  	references := manifest.References()
   169  	expected := append([]distribution.Descriptor{manifest.Target()}, descriptors...)
   170  	if !reflect.DeepEqual(references, expected) {
   171  		t.Fatal("References() does not match the descriptors added")
   172  	}
   173  }
   174  

View as plain text