...

Source file src/github.com/opencontainers/image-spec/schema/manifest_test.go

Documentation: github.com/opencontainers/image-spec/schema

     1  // Copyright 2016 The Linux Foundation
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package schema_test
    16  
    17  import (
    18  	"strings"
    19  	"testing"
    20  
    21  	"github.com/opencontainers/image-spec/schema"
    22  )
    23  
    24  func TestManifest(t *testing.T) {
    25  	for i, tt := range []struct {
    26  		manifest string
    27  		fail     bool
    28  	}{
    29  		// expected failure: mediaType does not match pattern
    30  		{
    31  			manifest: `
    32  {
    33    "schemaVersion": 2,
    34    "mediaType" : "application/vnd.oci.image.manifest.v1+json",
    35    "config": {
    36      "mediaType": "invalid",
    37      "size": 1470,
    38      "digest": "sha256:c86f7763873b6c0aae22d963bab59b4f5debbed6685761b5951584f6efb0633b"
    39    },
    40    "layers": [
    41      {
    42        "mediaType": "application/vnd.oci.image.layer.v1.tar+gzip",
    43        "size": 148,
    44        "digest": "sha256:c57089565e894899735d458f0fd4bb17a0f1e0df8d72da392b85c9b35ee777cd"
    45      }
    46    ]
    47  }
    48  `,
    49  			fail: true,
    50  		},
    51  
    52  		// expected failure: config.size is a string, expected integer
    53  		{
    54  			manifest: `
    55  {
    56    "schemaVersion": 2,
    57    "mediaType" : "application/vnd.oci.image.manifest.v1+json",
    58    "config": {
    59    "config": {
    60      "mediaType": "application/vnd.oci.image.config.v1+json",
    61      "size": "1470",
    62      "digest": "sha256:c86f7763873b6c0aae22d963bab59b4f5debbed6685761b5951584f6efb0633b"
    63    },
    64    "layers": [
    65      {
    66        "mediaType": "application/vnd.oci.image.layer.v1.tar+gzip",
    67        "size": 148,
    68        "digest": "sha256:c57089565e894899735d458f0fd4bb17a0f1e0df8d72da392b85c9b35ee777cd"
    69      }
    70    ]
    71  }
    72  `,
    73  			fail: true,
    74  		},
    75  
    76  		// expected failure: layers.size is string, expected integer
    77  		{
    78  			manifest: `
    79  {
    80    "schemaVersion": 2,
    81    "mediaType" : "application/vnd.oci.image.manifest.v1+json",
    82    "config": {
    83      "mediaType": "application/vnd.oci.image.config.v1+json",
    84      "size": 1470,
    85      "digest": "sha256:c86f7763873b6c0aae22d963bab59b4f5debbed6685761b5951584f6efb0633b"
    86    },
    87    "layers": [
    88      {
    89        "mediaType": "application/vnd.oci.image.layer.v1.tar+gzip",
    90        "size": "675598",
    91        "digest": "sha256:c86f7763873b6c0aae22d963bab59b4f5debbed6685761b5951584f6efb0633b"
    92      }
    93    ]
    94  }
    95  `,
    96  			fail: true,
    97  		},
    98  
    99  		// valid manifest with optional fields
   100  		{
   101  			manifest: `
   102  {
   103    "schemaVersion": 2,
   104    "mediaType" : "application/vnd.oci.image.manifest.v1+json",
   105    "config": {
   106      "mediaType": "application/vnd.oci.image.config.v1+json",
   107      "size": 1470,
   108      "digest": "sha256:c86f7763873b6c0aae22d963bab59b4f5debbed6685761b5951584f6efb0633b"
   109    },
   110    "layers": [
   111      {
   112        "mediaType": "application/vnd.oci.image.layer.v1.tar+gzip",
   113        "size": 675598,
   114        "digest": "sha256:9d3dd9504c685a304985025df4ed0283e47ac9ffa9bd0326fddf4d59513f0827"
   115      },
   116      {
   117        "mediaType": "application/vnd.oci.image.layer.v1.tar+gzip",
   118        "size": 156,
   119        "digest": "sha256:2b689805fbd00b2db1df73fae47562faac1a626d5f61744bfe29946ecff5d73d"
   120      },
   121      {
   122        "mediaType": "application/vnd.oci.image.layer.v1.tar+gzip",
   123        "size": 148,
   124        "digest": "sha256:c57089565e894899735d458f0fd4bb17a0f1e0df8d72da392b85c9b35ee777cd"
   125      }
   126    ],
   127    "annotations": {
   128      "key1": "value1",
   129      "key2": "value2"
   130    }
   131  }
   132  `,
   133  			fail: false,
   134  		},
   135  
   136  		// valid manifest with only required fields
   137  		{
   138  			manifest: `
   139  {
   140    "schemaVersion": 2,
   141    "mediaType" : "application/vnd.oci.image.manifest.v1+json",
   142    "config": {
   143      "mediaType": "application/vnd.oci.image.config.v1+json",
   144      "size": 1470,
   145      "digest": "sha256:c86f7763873b6c0aae22d963bab59b4f5debbed6685761b5951584f6efb0633b"
   146    },
   147    "layers": [
   148      {
   149        "mediaType": "application/vnd.oci.image.layer.v1.tar+gzip",
   150        "size": 675598,
   151        "digest": "sha256:9d3dd9504c685a304985025df4ed0283e47ac9ffa9bd0326fddf4d59513f0827"
   152      },
   153      {
   154        "mediaType": "application/vnd.oci.image.layer.v1.tar+gzip",
   155        "size": 156,
   156        "digest": "sha256:2b689805fbd00b2db1df73fae47562faac1a626d5f61744bfe29946ecff5d73d"
   157      },
   158      {
   159        "mediaType": "application/vnd.oci.image.layer.v1.tar+gzip",
   160        "size": 148,
   161        "digest": "sha256:c57089565e894899735d458f0fd4bb17a0f1e0df8d72da392b85c9b35ee777cd"
   162      }
   163    ]
   164  }
   165  `,
   166  			fail: false,
   167  		},
   168  
   169  		// expected failure: empty layer, expected at least one
   170  		{
   171  			manifest: `
   172  {
   173    "schemaVersion": 2,
   174    "mediaType" : "application/vnd.oci.image.manifest.v1+json",
   175    "config": {
   176      "mediaType": "application/vnd.oci.image.config.v1+json",
   177      "size": 1470,
   178      "digest": "sha256:c86f7763873b6c0aae22d963bab59b4f5debbed6685761b5951584f6efb0633b"
   179    },
   180    "layers": []
   181  }
   182  `,
   183  			fail: true,
   184  		},
   185  
   186  		// expected pass: test bounds of algorithm field in digest.
   187  		{
   188  			manifest: `
   189  {
   190    "schemaVersion": 2,
   191    "mediaType" : "application/vnd.oci.image.manifest.v1+json",
   192    "config": {
   193      "mediaType": "application/vnd.oci.image.config.v1+json",
   194      "size": 1470,
   195      "digest": "sha256+b64:c86f7763873b6c0aae22d963bab59b4f5debbed6685761b5951584f6efb0633b"
   196    },
   197    "layers": [
   198      {
   199        "mediaType": "application/vnd.oci.image.layer.v1.tar+gzip",
   200        "size": 1470,
   201        "digest": "sha256+foo-bar:c86f7763873b6c0aae22d963bab59b4f5debbed6685761b5951584f6efb0633b"
   202      },
   203      {
   204        "mediaType": "application/vnd.oci.image.layer.v1.tar+gzip",
   205        "size": 1470,
   206        "digest": "sha256.foo-bar:c86f7763873b6c0aae22d963bab59b4f5debbed6685761b5951584f6efb0633b"
   207      },
   208      {
   209        "mediaType": "application/vnd.oci.image.layer.v1.tar+gzip",
   210        "size": 1470,
   211  	  "digest": "multihash+base58:QmRZxt2b1FVZPNqd8hsiykDL3TdBDeTSPX9Kv46HmX4Gx8"
   212      }
   213    ]
   214  }
   215  `,
   216  		},
   217  
   218  		// expected success: subject field with a valid descriptor
   219  		{
   220  			manifest: `
   221  {
   222    "schemaVersion": 2,
   223    "mediaType" : "application/vnd.oci.image.manifest.v1+json",
   224    "config": {
   225      "mediaType": "application/vnd.oci.image.config.v1+json",
   226      "size": 1470,
   227      "digest": "sha256:c86f7763873b6c0aae22d963bab59b4f5debbed6685761b5951584f6efb0633b"
   228    },
   229    "layers": [
   230      {
   231        "mediaType": "application/vnd.oci.image.layer.v1.tar+gzip",
   232        "size": 1470,
   233        "digest": "sha256:c86f7763873b6c0aae22d963bab59b4f5debbed6685761b5951584f6efb0633b"
   234      }
   235    ],
   236    "subject" : {
   237      "mediaType": "application/vnd.oci.image.manifest.v1+json",
   238      "size": 1234,
   239      "digest": "sha256:220a60ecd4a3c32c282622a625a54db9ba0ff55b5ba9c29c7064a2bc358b6a3e"
   240    }
   241  }
   242  `,
   243  			fail: false,
   244  		},
   245  
   246  		// expected failure: subject field with invalid value (something that is not a descriptor)
   247  		{
   248  			manifest: `
   249  {
   250    "schemaVersion": 2,
   251    "mediaType" : "application/vnd.oci.image.manifest.v1+json",
   252    "config": {
   253      "mediaType": "application/vnd.oci.image.config.v1+json",
   254      "size": 1470,
   255      "digest": "sha256:c86f7763873b6c0aae22d963bab59b4f5debbed6685761b5951584f6efb0633b"
   256    },
   257    "layers": [
   258      {
   259        "mediaType": "application/vnd.oci.image.layer.v1.tar+gzip",
   260        "size": 1470,
   261        "digest": "sha256:c86f7763873b6c0aae22d963bab59b4f5debbed6685761b5951584f6efb0633b"
   262      }
   263    ],
   264    "subject" : ".nope"
   265  }
   266  `,
   267  			fail: true,
   268  		},
   269  
   270  		// expected failure: push bounds of algorithm field in digest too far.
   271  		{
   272  			manifest: `
   273  {
   274    "schemaVersion": 2,
   275    "mediaType" : "application/vnd.oci.image.manifest.v1+json",
   276    "config": {
   277      "mediaType": "application/vnd.oci.image.config.v1+json",
   278      "size": 1470,
   279      "digest": "sha256+b64:c86f7763873b6c0aae22d963bab59b4f5debbed6685761b5951584f6efb0633b"
   280    },
   281    "layers": [
   282      {
   283        "mediaType": "application/vnd.oci.image.layer.v1.tar+gzip",
   284        "size": 1470,
   285        "digest": "sha256+foo+-b:c86f7763873b6c0aae22d963bab59b4f5debbed6685761b5951584f6efb0633b"
   286      }
   287    ]
   288  }
   289  `,
   290  			fail: true,
   291  		},
   292  
   293  		// valid manifest for an artifact with a dedicated config
   294  		{
   295  			manifest: `
   296  {
   297    "schemaVersion": 2,
   298    "mediaType" : "application/vnd.oci.image.manifest.v1+json",
   299    "config": {
   300      "mediaType": "application/vnd.example.config+json",
   301      "size": 1470,
   302      "digest": "sha256:c86f7763873b6c0aae22d963bab59b4f5debbed6685761b5951584f6efb0633b"
   303    },
   304    "layers": [
   305      {
   306        "mediaType": "application/vnd.example.data+type",
   307        "size": 675598,
   308        "digest": "sha256:9d3dd9504c685a304985025df4ed0283e47ac9ffa9bd0326fddf4d59513f0827"
   309      }
   310    ]
   311  }
   312  `,
   313  			fail: false,
   314  		},
   315  
   316  		// valid manifest for an artifact using the empty config and artifactType
   317  		{
   318  			manifest: `
   319  {
   320    "schemaVersion": 2,
   321    "mediaType" : "application/vnd.oci.image.manifest.v1+json",
   322    "artifactType": "application/vnd.example+type",
   323    "config": {
   324      "mediaType": "application/vnd.oci.empty.v1+json",
   325      "size": 2,
   326      "digest": "sha256:44136fa355b3678a1146ad16f7e8649e94fb4fc21fe77e8310c060f61caaff8a"
   327    },
   328    "layers": [
   329      {
   330        "mediaType": "application/vnd.example+type",
   331        "size": 675598,
   332        "digest": "sha256:9d3dd9504c685a304985025df4ed0283e47ac9ffa9bd0326fddf4d59513f0827"
   333      }
   334    ]
   335  }
   336  `,
   337  			fail: false,
   338  		},
   339  	} {
   340  		r := strings.NewReader(tt.manifest)
   341  		err := schema.ValidatorMediaTypeManifest.Validate(r)
   342  
   343  		if got := err != nil; tt.fail != got {
   344  			t.Errorf("test %d: expected validation failure %t but got %t, err %v", i, tt.fail, got, err)
   345  		}
   346  	}
   347  }
   348  

View as plain text