Use consts to make clear these values are fixed, and improve the output to make it clearer which part is the expected output, and which part the actual. Before this: === RUN TestManifest manifest_test.go:87: manifest bytes not equal: "{\n \"schemaVersion\": 2,\n \"mediaType\": \"application/vnd.oci.image.manifest.v1+json\",\n \"config\": {\n \"mediaType\": \"application/vnd.oci.image.config.v1+json\",\n \"size\": 985,\n \"digest\": \"sha256:1a9ec845ee94c202b2d5da74a24f0ed2058318bfa9879fa541efaecba272e86b\",\n \"annotations\": {\n \"apple\": \"orange\"\n }\n },\n \"layers\": [\n {\n \"mediaType\": \"application/vnd.oci.image.layer.v1.tar+gzip\",\n \"size\": 153263,\n \"digest\": \"sha256:62d8908bee94c202b2d35224a221aaa2058318bfa9879fa541efaecba272331b\",\n \"annotations\": {\n \"lettuce\": \"wrap\"\n }\n }\n ],\n \"annotations\": {\n \"hot\": \"potato\"\n }\n}" != "{\n \"schemaVersion\": 2,\n \"mediaType\": \"application/vnd.oci.image.manifest.v1+json\",\n \"config\": {\n \"mediaType\": \"application/vnd.oci.image.config.v1+json\",\n \"size\": 985,\n \"digest\": \"sha256:1a9ec845ee94c202b2d5da74a24f0ed2058318bfa9879fa541efaecba272e86b\",\n \"annotations\": {\n \"apple\": \"orange\"\n }\n },\n \"layers\": [\n {\n \"mediaType\": \"application/vnd.oci.image.layer.v1.tar+gzip\",\n \"size\": 153263,\n \"digest\": \"sha256:62d8908bee94c202b2d35224a221aaa2058318bfa9879fa541efaecba272331b\",\n \"annotations\": {\n \"lettuce\": \"wrap\"\n }\n }\n ],\n \"annotations\": {\n \"hot\": \"potato\"\n }\n}" --- FAIL: TestManifest (0.00s) After this: === RUN TestManifest manifest_test.go:72: manifest bytes not equal: expected: { "schemaVersion": 2, "mediaType": "application/vnd.docker.distribution.manifest.v2+json", "config": { "mediaType": "application/vnd.docker.container.image.v1+json", "size": 985, "digest": "sha256:1a9ec845ee94c202b2d5da74a24f0ed2058318bfa9879fa541efaecba272e86b" }, "layers": [ { "mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip", "size": 153263, "digest": "sha256:62d8908bee94c202b2d35224a221aaa2058318bfa9879fa541efaecba272331b" } ] } actual: { "schemaVersion": 2, "mediaType": "application/vnd.docker.distribution.manifest.v2+json", "config": { "mediaType": "application/vnd.docker.container.image.v1+json", "size": 985, "digest": "sha256:1a9ec845ee94c202b2d5da74a24f0ed2058318bfa9879fa541efaecba272e86b" }, "layers": [ { "mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip", "size": 153263, "digest": "sha256:62d8908bee94c202b2d35224a221aaa2058318bfa9879fa541efaecba272331b" } ] } --- FAIL: TestManifest (0.00s) Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
135 lines
2.7 KiB
Go
135 lines
2.7 KiB
Go
package schema1
|
|
|
|
import (
|
|
"bytes"
|
|
"encoding/json"
|
|
"reflect"
|
|
"testing"
|
|
|
|
"github.com/docker/libtrust"
|
|
)
|
|
|
|
type testEnv struct {
|
|
name, tag string
|
|
invalidSigned *SignedManifest
|
|
signed *SignedManifest
|
|
pk libtrust.PrivateKey
|
|
}
|
|
|
|
func TestManifestMarshaling(t *testing.T) {
|
|
env := genEnv(t)
|
|
|
|
// Check that the all field is the same as json.MarshalIndent with these
|
|
// parameters.
|
|
expected, err := json.MarshalIndent(env.signed, "", " ")
|
|
if err != nil {
|
|
t.Fatalf("error marshaling manifest: %v", err)
|
|
}
|
|
|
|
if !bytes.Equal(expected, env.signed.all) {
|
|
t.Fatalf("manifest bytes not equal:\nexpected:\n%s\nactual:\n%s\n", string(expected), string(env.signed.all))
|
|
}
|
|
}
|
|
|
|
func TestManifestUnmarshaling(t *testing.T) {
|
|
env := genEnv(t)
|
|
|
|
var signed SignedManifest
|
|
if err := json.Unmarshal(env.signed.all, &signed); err != nil {
|
|
t.Fatalf("error unmarshaling signed manifest: %v", err)
|
|
}
|
|
|
|
if !reflect.DeepEqual(&signed, env.signed) {
|
|
t.Fatalf("manifests are different after unmarshaling: %v != %v", signed, env.signed)
|
|
}
|
|
}
|
|
|
|
func TestManifestVerification(t *testing.T) {
|
|
env := genEnv(t)
|
|
|
|
publicKeys, err := Verify(env.signed)
|
|
if err != nil {
|
|
t.Fatalf("error verifying manifest: %v", err)
|
|
}
|
|
|
|
if len(publicKeys) == 0 {
|
|
t.Fatalf("no public keys found in signature")
|
|
}
|
|
|
|
var found bool
|
|
publicKey := env.pk.PublicKey()
|
|
// ensure that one of the extracted public keys matches the private key.
|
|
for _, candidate := range publicKeys {
|
|
if candidate.KeyID() == publicKey.KeyID() {
|
|
found = true
|
|
break
|
|
}
|
|
}
|
|
|
|
if !found {
|
|
t.Fatalf("expected public key, %v, not found in verified keys: %v", publicKey, publicKeys)
|
|
}
|
|
|
|
// Check that an invalid manifest fails verification
|
|
_, err = Verify(env.invalidSigned)
|
|
if err != nil {
|
|
t.Fatalf("Invalid manifest should not pass Verify()")
|
|
}
|
|
}
|
|
|
|
func genEnv(t *testing.T) *testEnv {
|
|
pk, err := libtrust.GenerateECP256PrivateKey()
|
|
if err != nil {
|
|
t.Fatalf("error generating test key: %v", err)
|
|
}
|
|
|
|
name, tag := "foo/bar", "test"
|
|
|
|
invalid := Manifest{
|
|
Versioned: SchemaVersion,
|
|
Name: name,
|
|
Tag: tag,
|
|
FSLayers: []FSLayer{
|
|
{
|
|
BlobSum: "asdf",
|
|
},
|
|
{
|
|
BlobSum: "qwer",
|
|
},
|
|
},
|
|
}
|
|
|
|
valid := Manifest{
|
|
Versioned: SchemaVersion,
|
|
Name: name,
|
|
Tag: tag,
|
|
FSLayers: []FSLayer{
|
|
{
|
|
BlobSum: "asdf",
|
|
},
|
|
},
|
|
History: []History{
|
|
{
|
|
V1Compatibility: "",
|
|
},
|
|
},
|
|
}
|
|
|
|
sm, err := Sign(&valid, pk)
|
|
if err != nil {
|
|
t.Fatalf("error signing manifest: %v", err)
|
|
}
|
|
|
|
invalidSigned, err := Sign(&invalid, pk)
|
|
if err != nil {
|
|
t.Fatalf("error signing manifest: %v", err)
|
|
}
|
|
|
|
return &testEnv{
|
|
name: name,
|
|
tag: tag,
|
|
invalidSigned: invalidSigned,
|
|
signed: sm,
|
|
pk: pk,
|
|
}
|
|
}
|