get.porter.sh/porter@v1.3.0/pkg/cnab/oci_reference_test.go (about)

     1  package cnab
     2  
     3  import (
     4  	"encoding/json"
     5  	"testing"
     6  
     7  	"github.com/opencontainers/go-digest"
     8  	"github.com/stretchr/testify/assert"
     9  	"github.com/stretchr/testify/require"
    10  )
    11  
    12  func TestOCIReference(t *testing.T) {
    13  	tests := []struct {
    14  		Name             string
    15  		Ref              OCIReference
    16  		ExpectedTag      string
    17  		ExpectedDigest   string
    18  		ExpectedVersion  string
    19  		ExpectedRepo     string
    20  		ExpectedRegistry string
    21  	}{
    22  		{
    23  			Name:             "Tag and digest specified",
    24  			Ref:              MustParseOCIReference("carolynvs/whalesayd:v0.1.1@sha256:5cca9dfa8ba540a32537d586651d3918d6f39761cdf4457fbe32c58c36c1defc"),
    25  			ExpectedRegistry: "docker.io",
    26  			ExpectedRepo:     "carolynvs/whalesayd",
    27  			ExpectedTag:      "v0.1.1",
    28  			ExpectedDigest:   "sha256:5cca9dfa8ba540a32537d586651d3918d6f39761cdf4457fbe32c58c36c1defc",
    29  			ExpectedVersion:  "0.1.1",
    30  		},
    31  		{
    32  			Name:             "valid digested reference",
    33  			Ref:              MustParseOCIReference("jeremyrickard/porter-do-bundle@sha256:a808aa4e3508d7129742eefda938249574447cce5403dc12d4cbbfe7f4f31e58"),
    34  			ExpectedRegistry: "docker.io",
    35  			ExpectedRepo:     "jeremyrickard/porter-do-bundle",
    36  			ExpectedDigest:   "sha256:a808aa4e3508d7129742eefda938249574447cce5403dc12d4cbbfe7f4f31e58",
    37  		},
    38  		{
    39  			Name:             "tagged reference",
    40  			Ref:              MustParseOCIReference("jeremyrickard/porter-do-bundle:v0.1.0-pre_build.123"),
    41  			ExpectedRegistry: "docker.io",
    42  			ExpectedRepo:     "jeremyrickard/porter-do-bundle",
    43  			ExpectedTag:      "v0.1.0-pre_build.123",
    44  			ExpectedVersion:  "0.1.0-pre+build.123",
    45  		},
    46  		{
    47  			Name:             "no tag",
    48  			Ref:              MustParseOCIReference("ghcr.io/jeremyrickard/porter-do-bundle"),
    49  			ExpectedRepo:     "ghcr.io/jeremyrickard/porter-do-bundle",
    50  			ExpectedRegistry: "ghcr.io",
    51  		},
    52  	}
    53  
    54  	for _, test := range tests {
    55  		t.Run(test.Name, func(t *testing.T) {
    56  			assert.Equal(t, test.ExpectedRepo, test.Ref.Repository())
    57  
    58  			assert.Equal(t, test.ExpectedRegistry, test.Ref.Registry())
    59  
    60  			assert.Equal(t, test.ExpectedDigest, test.Ref.Digest().String())
    61  			assert.Equal(t, test.ExpectedDigest != "", test.Ref.HasDigest())
    62  
    63  			assert.Equal(t, test.ExpectedTag, test.Ref.Tag())
    64  			assert.Equal(t, test.ExpectedTag != "", test.Ref.HasTag())
    65  
    66  			assert.Equal(t, test.ExpectedVersion, test.Ref.Version())
    67  			assert.Equal(t, test.ExpectedVersion != "", test.Ref.HasVersion())
    68  		})
    69  	}
    70  }
    71  
    72  func TestParseOCIReference(t *testing.T) {
    73  	testcases := []struct {
    74  		Name       string
    75  		Reference  string
    76  		WantRepo   string
    77  		WantTag    string
    78  		WantDigest digest.Digest
    79  		WantErr    string
    80  	}{
    81  		{Name: "version", Reference: "ghcr.io/getporter/examples/porter-hello:v0.2.0", WantRepo: "ghcr.io/getporter/examples/porter-hello", WantTag: "v0.2.0"},
    82  		{Name: "digest", Reference: "ghcr.io/getporter/examples/porter-hello@sha256:88d68ef0bdb9cedc6da3a8e341a33e5d2f8bb19d0cf7ec3f1060d3f9eb73cae9", WantRepo: "ghcr.io/getporter/examples/porter-hello", WantDigest: "sha256:88d68ef0bdb9cedc6da3a8e341a33e5d2f8bb19d0cf7ec3f1060d3f9eb73cae9"},
    83  		{Name: "invalid", Reference: "@v1", WantErr: "invalid reference format"},
    84  	}
    85  
    86  	for _, tc := range testcases {
    87  		t.Run(tc.Name, func(t *testing.T) {
    88  			ref, err := ParseOCIReference(tc.Reference)
    89  			if tc.WantErr != "" {
    90  				require.Error(t, err, "expected ParseOCIReference to fail")
    91  				assert.Contains(t, err.Error(), tc.WantErr)
    92  			} else {
    93  				require.NoError(t, err, "expected ParseOCIReference to succeed")
    94  				assert.Equal(t, tc.WantRepo, ref.Repository(), "incorrect repo")
    95  				assert.Equal(t, tc.WantTag, ref.Tag(), "incorrect tag")
    96  				assert.Equal(t, tc.WantDigest, ref.Digest(), "incorrect digest")
    97  			}
    98  		})
    99  	}
   100  }
   101  
   102  func TestOCIReference_MarshalJSON(t *testing.T) {
   103  	r := MustParseOCIReference("ghcr.io/getporter/examples/porter-hello:v0.2.0")
   104  	data, err := json.Marshal(r)
   105  	require.NoError(t, err)
   106  	assert.Equal(t, `"ghcr.io/getporter/examples/porter-hello:v0.2.0"`, string(data))
   107  }
   108  
   109  func TestOCIReference_UnmarshalJSON(t *testing.T) {
   110  	ref := `"ghcr.io/getporter/examples/porter-hello:v0.2.0"`
   111  	var r OCIReference
   112  	err := json.Unmarshal([]byte(ref), &r)
   113  	require.NoError(t, err)
   114  	assert.Equal(t, "ghcr.io/getporter/examples/porter-hello:v0.2.0", r.String())
   115  }
   116  
   117  func TestOCIReference_WithVersion(t *testing.T) {
   118  	t.Run("prefixed semver", func(t *testing.T) {
   119  		ref := MustParseOCIReference("getporter/porter-hello")
   120  
   121  		result, err := ref.WithVersion("v1.2.3")
   122  		require.NoError(t, err)
   123  		assert.Equal(t, "v1.2.3", result.Tag())
   124  	})
   125  
   126  	t.Run("unprefixed semver", func(t *testing.T) {
   127  		ref := MustParseOCIReference("getporter/porter-hello")
   128  
   129  		result, err := ref.WithVersion("1.2.3")
   130  		require.NoError(t, err)
   131  		assert.Equal(t, "v1.2.3", result.Tag())
   132  	})
   133  
   134  	t.Run("semver with build metadata", func(t *testing.T) {
   135  		ref := MustParseOCIReference("getporter/porter-hello")
   136  
   137  		result, err := ref.WithVersion("1.2.3+git0a2b3c4d")
   138  		require.NoError(t, err)
   139  		assert.Equal(t, "v1.2.3_git0a2b3c4d", result.Tag())
   140  	})
   141  
   142  	t.Run("invalid semver", func(t *testing.T) {
   143  		ref := MustParseOCIReference("getporter/porter-hello")
   144  
   145  		_, err := ref.WithVersion("oops")
   146  		require.Error(t, err)
   147  		assert.Contains(t, err.Error(), "invalid bundle version")
   148  	})
   149  }
   150  
   151  func TestOCIReference_WithTag(t *testing.T) {
   152  	ref := MustParseOCIReference("getporter/porter-hello")
   153  
   154  	result, err := ref.WithTag("latest")
   155  	require.NoError(t, err)
   156  	assert.Equal(t, "latest", result.Tag())
   157  }
   158  
   159  func TestOCIReference_WithDigest(t *testing.T) {
   160  	t.Run("valid digest", func(t *testing.T) {
   161  		ref := MustParseOCIReference("getporter/porter-hello")
   162  
   163  		result, err := ref.WithDigest("sha256:a808aa4e3508d7129742eefda938249574447cce5403dc12d4cbbfe7f4f31e58")
   164  		require.NoError(t, err)
   165  		assert.Equal(t, "sha256:a808aa4e3508d7129742eefda938249574447cce5403dc12d4cbbfe7f4f31e58", result.Digest().String())
   166  	})
   167  
   168  	t.Run("invalid digest", func(t *testing.T) {
   169  		ref := MustParseOCIReference("getporter/porter-hello")
   170  
   171  		_, err := ref.WithDigest("oops")
   172  		require.Error(t, err)
   173  		assert.Contains(t, err.Error(), "invalid digest")
   174  	})
   175  }