Skip to content

Commit

Permalink
Add a assertJSONEqualsFixture helper to reduce boilerplate
Browse files Browse the repository at this point in the history
Should not change (test) behavior.

Signed-off-by: Miloslav Trmač <mitr@redhat.com>
  • Loading branch information
mtrmac committed May 4, 2023
1 parent 2699a9e commit daa120c
Show file tree
Hide file tree
Showing 4 changed files with 53 additions and 131 deletions.
29 changes: 29 additions & 0 deletions internal/image/common_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package image

import (
"encoding/json"
"os"
"path/filepath"
"testing"

"github.com/stretchr/testify/require"
)

// assertJSONEqualsFixture tests that jsonBytes is structurally equal to fixture,
// possibly ignoring ignoreFields
func assertJSONEqualsFixture(t *testing.T, jsonBytes []byte, fixture string, ignoreFields ...string) {
var contents map[string]any
err := json.Unmarshal(jsonBytes, &contents)
require.NoError(t, err)

fixtureBytes, err := os.ReadFile(filepath.Join("fixtures", fixture))
require.NoError(t, err)
var fixtureContents map[string]any

for _, f := range ignoreFields {
delete(contents, f)
delete(fixtureContents, f)
}
err = json.Unmarshal(fixtureBytes, &fixtureContents)
require.NoError(t, err)
}
65 changes: 8 additions & 57 deletions internal/image/docker_schema1_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package image

import (
"context"
"encoding/json"
"os"
"path/filepath"
"testing"
Expand Down Expand Up @@ -153,23 +152,11 @@ func TestManifestSchema1Serialize(t *testing.T) {
} {
serialized, err := m.serialize()
require.NoError(t, err)
var contents map[string]any
err = json.Unmarshal(serialized, &contents)
require.NoError(t, err)

original, err := os.ReadFile("fixtures/schema1.json")
require.NoError(t, err)
var originalContents map[string]any
err = json.Unmarshal(original, &originalContents)
require.NoError(t, err)

// Drop the signature which is generated by AddDummyV2S1Signature
delete(contents, "signatures")
delete(originalContents, "signatures")
// We would ideally like to compare “serialized” with some transformation of
// original, but the ordering of fields in JSON maps is undefined, so this is
// the original fixture, but the ordering of fields in JSON maps is undefined, so this is
// easier.
assert.Equal(t, originalContents, contents)
assertJSONEqualsFixture(t, serialized, "schema1.json", "signatures")
}
}

Expand Down Expand Up @@ -462,30 +449,12 @@ func TestManifestSchema1ConvertToSchema2(t *testing.T) {
convertedJSON, mt, err := res.Manifest(context.Background())
require.NoError(t, err)
assert.Equal(t, manifest.DockerV2Schema2MediaType, mt)

byHandJSON, err := os.ReadFile("fixtures/schema1-to-schema2.json")
require.NoError(t, err)
var converted, byHand map[string]any
err = json.Unmarshal(byHandJSON, &byHand)
require.NoError(t, err)
err = json.Unmarshal(convertedJSON, &converted)
delete(converted, "config") // We don’t want to hard-code a specific digest and size of the marshaled config here
delete(byHand, "config")
require.NoError(t, err)
assert.Equal(t, byHand, converted)
// Ignore "config": we don’t want to hard-code a specific digest and size of the marshaled config here.
assertJSONEqualsFixture(t, convertedJSON, "schema1-to-schema2.json", "config")

convertedConfig, err := res.ConfigBlob(context.Background())
require.NoError(t, err)

byHandConfig, err := os.ReadFile("fixtures/schema1-to-schema2-config.json")
require.NoError(t, err)
converted = map[string]any{}
byHand = map[string]any{}
err = json.Unmarshal(byHandConfig, &byHand)
require.NoError(t, err)
err = json.Unmarshal(convertedConfig, &converted)
require.NoError(t, err)
assert.Equal(t, byHand, converted)
assertJSONEqualsFixture(t, convertedConfig, "schema1-to-schema2-config.json")

// Conversion to schema2 together with changing LayerInfos works as expected (which requires
// handling schema1 throwaway layers):
Expand Down Expand Up @@ -555,30 +524,12 @@ func TestManifestSchema1ConvertToManifestOCI1(t *testing.T) {
convertedJSON, mt, err := res.Manifest(context.Background())
require.NoError(t, err)
assert.Equal(t, imgspecv1.MediaTypeImageManifest, mt)

byHandJSON, err := os.ReadFile("fixtures/schema1-to-oci1.json")
require.NoError(t, err)
var converted, byHand map[string]any
err = json.Unmarshal(byHandJSON, &byHand)
require.NoError(t, err)
err = json.Unmarshal(convertedJSON, &converted)
delete(converted, "config") // We don’t want to hard-code a specific digest and size of the marshaled config here
delete(byHand, "config")
require.NoError(t, err)
assert.Equal(t, byHand, converted)
// Ignore "config": we don’t want to hard-code a specific digest and size of the marshaled config here.
assertJSONEqualsFixture(t, convertedJSON, "schema1-to-oci1.json", "config")

convertedConfig, err := res.ConfigBlob(context.Background())
require.NoError(t, err)

byHandConfig, err := os.ReadFile("fixtures/schema1-to-oci1-config.json")
require.NoError(t, err)
converted = map[string]any{}
byHand = map[string]any{}
err = json.Unmarshal(byHandConfig, &byHand)
require.NoError(t, err)
err = json.Unmarshal(convertedConfig, &converted)
require.NoError(t, err)
assert.Equal(t, byHand, converted)
assertJSONEqualsFixture(t, convertedConfig, "schema1-to-oci1-config.json")

// Conversion to OCI together with changing LayerInfos works as expected (which requires
// handling schema1 throwaway layers):
Expand Down
48 changes: 6 additions & 42 deletions internal/image/docker_schema2_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import (
"bytes"
"context"
"encoding/hex"
"encoding/json"
"errors"
"io"
"os"
Expand Down Expand Up @@ -92,20 +91,10 @@ func TestManifestSchema2Serialize(t *testing.T) {
} {
serialized, err := m.serialize()
require.NoError(t, err)
var contents map[string]any
err = json.Unmarshal(serialized, &contents)
require.NoError(t, err)

original, err := os.ReadFile("fixtures/schema2.json")
require.NoError(t, err)
var originalContents map[string]any
err = json.Unmarshal(original, &originalContents)
require.NoError(t, err)

// We would ideally like to compare “serialized” with some transformation of
// original, but the ordering of fields in JSON maps is undefined, so this is
// the original fixture, but the ordering of fields in JSON maps is undefined, so this is
// easier.
assert.Equal(t, originalContents, contents)
assertJSONEqualsFixture(t, serialized, "schema2.json")
}
}

Expand Down Expand Up @@ -520,15 +509,7 @@ func TestConvertToManifestOCI(t *testing.T) {
convertedJSON, mt, err := res.Manifest(context.Background())
require.NoError(t, err)
assert.Equal(t, imgspecv1.MediaTypeImageManifest, mt)

byHandJSON, err := os.ReadFile("fixtures/schema2-to-oci1.json")
require.NoError(t, err)
var converted, byHand map[string]any
err = json.Unmarshal(byHandJSON, &byHand)
require.NoError(t, err)
err = json.Unmarshal(convertedJSON, &converted)
require.NoError(t, err)
assert.Equal(t, byHand, converted)
assertJSONEqualsFixture(t, convertedJSON, "schema2-to-oci1.json")
}

func TestConvertToManifestOCIAllMediaTypes(t *testing.T) {
Expand All @@ -541,15 +522,7 @@ func TestConvertToManifestOCIAllMediaTypes(t *testing.T) {
convertedJSON, mt, err := res.Manifest(context.Background())
require.NoError(t, err)
assert.Equal(t, imgspecv1.MediaTypeImageManifest, mt)

byHandJSON, err := os.ReadFile("fixtures/schema2-all-media-types-to-oci1.json")
require.NoError(t, err)
var converted, byHand map[string]any
err = json.Unmarshal(byHandJSON, &byHand)
require.NoError(t, err)
err = json.Unmarshal(convertedJSON, &converted)
require.NoError(t, err)
assert.Equal(t, byHand, converted)
assertJSONEqualsFixture(t, convertedJSON, "schema2-all-media-types-to-oci1.json")
}

func TestConvertToOCIWithInvalidMIMEType(t *testing.T) {
Expand All @@ -573,19 +546,10 @@ func TestConvertToManifestSchema1(t *testing.T) {
require.NoError(t, err)
assert.Equal(t, manifest.DockerV2Schema1SignedMediaType, mt)

// byDockerJSON is the result of asking the Docker Hub for a schema1 manifest,
// schema2-to-schema1-by-docker.json is the result of asking the Docker Hub for a schema1 manifest,
// except that we have replaced "name" to verify that the ref from
// memoryDest, not from originalSrc, is used.
byDockerJSON, err := os.ReadFile("fixtures/schema2-to-schema1-by-docker.json")
require.NoError(t, err)
var converted, byDocker map[string]any
err = json.Unmarshal(byDockerJSON, &byDocker)
require.NoError(t, err)
err = json.Unmarshal(convertedJSON, &converted)
require.NoError(t, err)
delete(byDocker, "signatures")
delete(converted, "signatures")
assert.Equal(t, byDocker, converted)
assertJSONEqualsFixture(t, convertedJSON, "schema2-to-schema1-by-docker.json", "signatures")

assert.Equal(t, GzippedEmptyLayer, memoryDest.storedBlobs[GzippedEmptyLayerDigest])

Expand Down
42 changes: 10 additions & 32 deletions internal/image/oci_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,20 +94,10 @@ func TestManifestOCI1Serialize(t *testing.T) {
} {
serialized, err := m.serialize()
require.NoError(t, err)
var contents map[string]any
err = json.Unmarshal(serialized, &contents)
require.NoError(t, err)

original, err := os.ReadFile("fixtures/oci1.json")
require.NoError(t, err)
var originalContents map[string]any
err = json.Unmarshal(original, &originalContents)
require.NoError(t, err)

// We would ideally like to compare “serialized” with some transformation of
// original, but the ordering of fields in JSON maps is undefined, so this is
// the original fixture, but the ordering of fields in JSON maps is undefined, so this is
// easier.
assert.Equal(t, originalContents, contents)
assertJSONEqualsFixture(t, serialized, "oci1.json")
}
}

Expand Down Expand Up @@ -456,17 +446,7 @@ func TestManifestOCI1ConvertToManifestSchema1(t *testing.T) {
convertedJSON, mt, err := res.Manifest(context.Background())
require.NoError(t, err)
assert.Equal(t, manifest.DockerV2Schema1SignedMediaType, mt)

byHandJSON, err := os.ReadFile("fixtures/oci1-to-schema1.json")
require.NoError(t, err)
var converted, byHand map[string]any
err = json.Unmarshal(byHandJSON, &byHand)
require.NoError(t, err)
err = json.Unmarshal(convertedJSON, &converted)
require.NoError(t, err)
delete(byHand, "signatures")
delete(converted, "signatures")
assert.Equal(t, byHand, converted)
assertJSONEqualsFixture(t, convertedJSON, "oci1-to-schema1.json", "signatures")

assert.Equal(t, GzippedEmptyLayer, memoryDest.storedBlobs[GzippedEmptyLayerDigest])

Expand Down Expand Up @@ -517,6 +497,9 @@ func TestManifestOCI1ConvertToManifestSchema1(t *testing.T) {
var expected manifest.NonImageArtifactError
assert.ErrorAs(t, err, &expected)

// FIXME: Test that conversion of an encrypted image fails
// FIXME: Test that conversion with encryption fails

// FIXME? Test also the other failure cases, if only to see that we don't crash?
}

Expand All @@ -531,15 +514,7 @@ func TestConvertToManifestSchema2(t *testing.T) {
convertedJSON, mt, err := res.Manifest(context.Background())
require.NoError(t, err)
assert.Equal(t, manifest.DockerV2Schema2MediaType, mt)

byHandJSON, err := os.ReadFile("fixtures/oci1-to-schema2.json")
require.NoError(t, err)
var converted, byHand map[string]any
err = json.Unmarshal(byHandJSON, &byHand)
require.NoError(t, err)
err = json.Unmarshal(convertedJSON, &converted)
require.NoError(t, err)
assert.Equal(t, byHand, converted)
assertJSONEqualsFixture(t, convertedJSON, "oci1-to-schema2.json")

// This can share originalSrc because the config digest is the same between oci1-artifact.json and oci1.json
artifact := manifestOCI1FromFixture(t, originalSrc, "oci1-artifact.json")
Expand All @@ -549,6 +524,9 @@ func TestConvertToManifestSchema2(t *testing.T) {
var expected manifest.NonImageArtifactError
assert.ErrorAs(t, err, &expected)

// FIXME: Test that conversion of an encrypted image fails
// FIXME: Test that conversion with encryption fails

// FIXME? Test also the other failure cases, if only to see that we don't crash?
}

Expand Down

0 comments on commit daa120c

Please sign in to comment.