get.porter.sh/porter@v1.3.0/pkg/cnab/config-adapter/stamp_test.go (about)

     1  package configadapter
     2  
     3  import (
     4  	"context"
     5  	"sort"
     6  	"testing"
     7  
     8  	"get.porter.sh/porter/pkg"
     9  	"get.porter.sh/porter/pkg/cnab"
    10  	"get.porter.sh/porter/pkg/config"
    11  	"get.porter.sh/porter/pkg/manifest"
    12  	"get.porter.sh/porter/pkg/mixin"
    13  	"get.porter.sh/porter/pkg/pkgmgmt"
    14  	"github.com/cnabio/cnab-go/bundle"
    15  	"github.com/stretchr/testify/assert"
    16  	"github.com/stretchr/testify/require"
    17  )
    18  
    19  var simpleManifestDigest = "4a748b8ac237b4af8f1eb3a327a82dfdd7eb70f3a1126e97a9e5d9b584cd048a"
    20  
    21  func TestConfig_GenerateStamp(t *testing.T) {
    22  	// Do not run this test in parallel
    23  	// Still need to figure out what is introducing flakey-ness
    24  	testcases := []struct {
    25  		name         string
    26  		preserveTags bool
    27  	}{
    28  		{name: "not preserving tags", preserveTags: false},
    29  		{name: "preserving tags", preserveTags: true},
    30  	}
    31  
    32  	for _, tc := range testcases {
    33  		tc := tc
    34  		t.Run(tc.name, func(t *testing.T) {
    35  			c := config.NewTestConfig(t)
    36  			c.TestContext.AddTestFileFromRoot("pkg/manifest/testdata/simple.porter.yaml", config.Name)
    37  
    38  			ctx := context.Background()
    39  			m, err := manifest.LoadManifestFrom(ctx, c.Config, config.Name)
    40  			require.NoError(t, err, "could not load manifest")
    41  
    42  			installedMixins := []mixin.Metadata{
    43  				{Name: "exec", VersionInfo: pkgmgmt.VersionInfo{Version: "v1.2.3"}},
    44  			}
    45  
    46  			a := NewManifestConverter(c.Config, m, nil, installedMixins, tc.preserveTags)
    47  			stamp, err := a.GenerateStamp(ctx, tc.preserveTags)
    48  			require.NoError(t, err, "DigestManifest failed")
    49  			assert.Equal(t, simpleManifestDigest, stamp.ManifestDigest)
    50  			assert.Equal(t, map[string]MixinRecord{"exec": {Name: "exec", Version: "v1.2.3"}}, stamp.Mixins, "Stamp.Mixins was not populated properly")
    51  			assert.Equal(t, pkg.Version, stamp.Version)
    52  			assert.Equal(t, pkg.Commit, stamp.Commit)
    53  			assert.Equal(t, tc.preserveTags, stamp.PreserveTags)
    54  
    55  			gotManifestContentsB, err := stamp.DecodeManifest()
    56  			require.NoError(t, err, "DecodeManifest failed")
    57  			wantManifestContentsB, err := c.FileSystem.ReadFile(config.Name)
    58  			require.NoError(t, err, "could not read %s", config.Name)
    59  			assert.Equal(t, string(wantManifestContentsB), string(gotManifestContentsB), "Stamp.EncodedManifest was not popluated and decoded properly")
    60  		})
    61  	}
    62  }
    63  
    64  func TestConfig_LoadStamp(t *testing.T) {
    65  	t.Parallel()
    66  
    67  	bun := cnab.NewBundle(bundle.Bundle{
    68  		Custom: map[string]interface{}{
    69  			config.CustomPorterKey: map[string]interface{}{
    70  				"manifestDigest": "somedigest",
    71  				"manifest":       "abc123",
    72  				"mixins": map[string]interface{}{
    73  					"exec": struct{}{},
    74  				},
    75  				"preserveTags": true,
    76  			},
    77  		},
    78  	})
    79  
    80  	stamp, err := LoadStamp(bun)
    81  	require.NoError(t, err)
    82  	assert.Equal(t, "somedigest", stamp.ManifestDigest)
    83  	assert.Equal(t, map[string]MixinRecord{"exec": {}}, stamp.Mixins, "Stamp.Mixins was not populated properly")
    84  	assert.Equal(t, "abc123", stamp.EncodedManifest)
    85  	assert.Equal(t, true, stamp.PreserveTags)
    86  }
    87  
    88  func TestConfig_LoadStamp_Invalid(t *testing.T) {
    89  	t.Parallel()
    90  
    91  	bun := cnab.NewBundle(bundle.Bundle{
    92  		Custom: map[string]interface{}{
    93  			config.CustomPorterKey: []string{
    94  				"somedigest",
    95  			},
    96  		},
    97  	})
    98  
    99  	stamp, err := LoadStamp(bun)
   100  	require.Error(t, err)
   101  	assert.Contains(t, err.Error(), "could not unmarshal the porter stamp")
   102  	assert.Equal(t, Stamp{}, stamp)
   103  }
   104  
   105  func TestStamp_DecodeManifest(t *testing.T) {
   106  	t.Parallel()
   107  
   108  	t.Run("manifest populated", func(t *testing.T) {
   109  		t.Parallel()
   110  
   111  		c := config.NewTestConfig(t)
   112  		s := Stamp{
   113  			EncodedManifest: "bmFtZTogaGVsbG8=", // name: hello
   114  		}
   115  
   116  		data, err := s.DecodeManifest()
   117  		require.NoError(t, err, "DecodeManifest failed")
   118  
   119  		m, err := manifest.UnmarshalManifest(c.TestContext.Context, data)
   120  		require.NoError(t, err, "UnmarshalManifest failed")
   121  
   122  		require.NotNil(t, m, "expected manifest to be populated")
   123  		assert.Equal(t, "hello", m.Name, "expected the manifest name to be populated")
   124  	})
   125  
   126  	t.Run("manifest empty", func(t *testing.T) {
   127  		t.Parallel()
   128  
   129  		s := Stamp{}
   130  
   131  		data, err := s.DecodeManifest()
   132  		require.EqualError(t, err, "no Porter manifest was embedded in the bundle")
   133  
   134  		assert.Nil(t, data, "No manifest data should be returned")
   135  	})
   136  
   137  	t.Run("manifest invalid", func(t *testing.T) {
   138  		t.Parallel()
   139  
   140  		s := Stamp{
   141  			EncodedManifest: "name: hello", // this should be base64 encoded
   142  		}
   143  
   144  		data, err := s.DecodeManifest()
   145  		require.Error(t, err, "DecodeManifest should fail for invalid data")
   146  
   147  		assert.Contains(t, err.Error(), "could not base64 decode the manifest in the stamp")
   148  		assert.Nil(t, data, "No manifest data should be returned")
   149  	})
   150  
   151  }
   152  
   153  func TestConfig_DigestManifest(t *testing.T) {
   154  	// Do not run in parallel, it modifies global state
   155  	defer func() { pkg.Version = "" }()
   156  
   157  	t.Run("updated version", func(t *testing.T) {
   158  		c := config.NewTestConfig(t)
   159  		c.TestContext.AddTestFileFromRoot("pkg/manifest/testdata/simple.porter.yaml", config.Name)
   160  
   161  		m, err := manifest.LoadManifestFrom(context.Background(), c.Config, config.Name)
   162  		require.NoError(t, err, "could not load manifest")
   163  
   164  		a := NewManifestConverter(c.Config, m, nil, nil, false)
   165  		digest, err := a.DigestManifest()
   166  		require.NoError(t, err, "DigestManifest failed")
   167  
   168  		pkg.Version = "foo"
   169  		defer func() { pkg.Version = "" }()
   170  		newDigest, err := a.DigestManifest()
   171  		require.NoError(t, err, "DigestManifest failed")
   172  		assert.NotEqual(t, newDigest, digest, "expected the digest to be different due to the updated pkg version")
   173  	})
   174  }
   175  
   176  func TestConfig_GenerateStamp_IncludeVersion(t *testing.T) {
   177  	// Do not run this test in parallel
   178  	// Still need to figure out what is introducing flakey-ness
   179  
   180  	pkg.Version = "v1.2.3"
   181  	pkg.Commit = "abc123"
   182  	defer func() {
   183  		pkg.Version = ""
   184  		pkg.Commit = ""
   185  	}()
   186  
   187  	c := config.NewTestConfig(t)
   188  	c.TestContext.AddTestFileFromRoot("pkg/manifest/testdata/simple.porter.yaml", config.Name)
   189  
   190  	ctx := context.Background()
   191  	m, err := manifest.LoadManifestFrom(ctx, c.Config, config.Name)
   192  	require.NoError(t, err, "could not load manifest")
   193  
   194  	a := NewManifestConverter(c.Config, m, nil, nil, false)
   195  	stamp, err := a.GenerateStamp(ctx, false)
   196  	require.NoError(t, err, "DigestManifest failed")
   197  	assert.Equal(t, "v1.2.3", stamp.Version)
   198  	assert.Equal(t, "abc123", stamp.Commit)
   199  }
   200  
   201  func TestMixinRecord_Sort(t *testing.T) {
   202  	records := MixinRecords{
   203  		{Name: "helm", Version: "0.1.13"},
   204  		{Name: "helm", Version: "v0.1.2"},
   205  		{Name: "testmixin", Version: "1.2.3"},
   206  		{Name: "exec", Version: "2.1.0"},
   207  		// These won't parse as valid semver, so just sort them by the string representation instead
   208  		{
   209  			Name:    "az",
   210  			Version: "invalid-version2",
   211  		},
   212  		{
   213  			Name:    "az",
   214  			Version: "invalid-version1",
   215  		},
   216  	}
   217  
   218  	sort.Sort(records)
   219  
   220  	wantRecords := MixinRecords{
   221  		{
   222  			Name:    "az",
   223  			Version: "invalid-version1",
   224  		},
   225  		{
   226  			Name:    "az",
   227  			Version: "invalid-version2",
   228  		},
   229  		{
   230  			Name:    "exec",
   231  			Version: "2.1.0",
   232  		},
   233  		{
   234  			Name:    "helm",
   235  			Version: "v0.1.2",
   236  		},
   237  		{
   238  			Name:    "helm",
   239  			Version: "0.1.13",
   240  		},
   241  		{
   242  			Name:    "testmixin",
   243  			Version: "1.2.3",
   244  		},
   245  	}
   246  
   247  	assert.Equal(t, wantRecords, records)
   248  }