get.porter.sh/porter@v1.3.0/pkg/cache/cache_test.go (about)

     1  package cache
     2  
     3  import (
     4  	"fmt"
     5  	"os"
     6  	"path/filepath"
     7  	"testing"
     8  
     9  	"get.porter.sh/porter/pkg/cnab"
    10  	"get.porter.sh/porter/pkg/config"
    11  	"get.porter.sh/porter/pkg/encoding"
    12  	"github.com/cnabio/cnab-go/bundle"
    13  	"github.com/cnabio/cnab-to-oci/relocation"
    14  	"github.com/opencontainers/go-digest"
    15  	"github.com/stretchr/testify/assert"
    16  	"github.com/stretchr/testify/require"
    17  )
    18  
    19  var (
    20  	kahn1dot0Hash = "887e7e65e39277f8744bd00278760b06"
    21  	kahn1dot01    = cnab.MustParseOCIReference("deislabs/kubekahn:1.0")
    22  	kahnlatest    = cnab.MustParseOCIReference("deislabs/kubekahn:latest")
    23  )
    24  
    25  func TestFindBundleCacheExists(t *testing.T) {
    26  	t.Parallel()
    27  
    28  	cfg := config.NewTestConfig(t)
    29  	home, err := cfg.Config.GetHomeDir()
    30  	require.NoError(t, err, "should have had a porter home dir")
    31  	cacheDir := filepath.Join(home, "cache")
    32  	cfg.TestContext.AddTestDirectory("testdata", cacheDir)
    33  	c := New(cfg.Config)
    34  
    35  	_, ok, err := c.FindBundle(kahnlatest)
    36  	assert.NoError(t, err, "the cache dir should exist, no error should have happened")
    37  	assert.False(t, ok, "the bundle shouldn't exist")
    38  }
    39  
    40  func TestFindBundleCacheDoesNotExist(t *testing.T) {
    41  	t.Parallel()
    42  
    43  	cfg := config.NewTestConfig(t)
    44  	home, err := cfg.Config.GetHomeDir()
    45  	require.NoError(t, err, "should have had a porter home dir")
    46  	cacheDir := filepath.Join(home, "cache")
    47  	cfg.TestContext.AddTestDirectory("testdata", cacheDir)
    48  	c := New(cfg.Config)
    49  
    50  	_, ok, err := c.FindBundle(kahnlatest)
    51  	assert.NoError(t, err, "the cache dir doesn't exist, but this shouldn't be an error")
    52  	assert.False(t, ok, "the bundle shouldn't exist")
    53  }
    54  
    55  func TestFindBundleBundleCached(t *testing.T) {
    56  	t.Parallel()
    57  
    58  	cfg := config.NewTestConfig(t)
    59  	home, err := cfg.Config.GetHomeDir()
    60  	require.NoError(t, err, "should have had a porter home dir")
    61  	cacheDir := filepath.Join(home, "cache")
    62  	cfg.TestContext.AddTestDirectory("testdata", cacheDir)
    63  	expectedCacheDirectory := filepath.Join(cacheDir, kahn1dot0Hash)
    64  	expectedCacheCNABDirectory := filepath.Join(expectedCacheDirectory, "cnab")
    65  	expectedCacheFile := filepath.Join(expectedCacheCNABDirectory, "bundle.json")
    66  	foundIt, err := cfg.Config.FileSystem.Exists(expectedCacheFile)
    67  	require.NoError(t, err, "the cache dir should exist, no error should have happened")
    68  	require.True(t, foundIt, "test data not loaded")
    69  	c := New(cfg.Config)
    70  
    71  	cb, ok, err := c.FindBundle(kahn1dot01)
    72  	require.NoError(t, err, "the cache dir should exist, no error should have happened")
    73  	require.True(t, ok, "the bundle should exist")
    74  	assert.Equal(t, expectedCacheFile, cb.BundlePath)
    75  }
    76  
    77  func TestFindBundleBundleNotCached(t *testing.T) {
    78  	t.Parallel()
    79  
    80  	cfg := config.NewTestConfig(t)
    81  	c := New(cfg.Config)
    82  	cb, ok, err := c.FindBundle(kahnlatest)
    83  	require.NoError(t, err, "the cache dir should exist, no error should have happened")
    84  	assert.False(t, ok, "the bundle should not exist")
    85  	assert.Empty(t, cb.BundlePath, "should not have a path")
    86  }
    87  
    88  func TestCacheWriteNoCacheDir(t *testing.T) {
    89  	t.Parallel()
    90  
    91  	cfg := config.NewTestConfig(t)
    92  	cfg.TestContext.AddTestFile("testdata/cnab/bundle.json", "/cnab/bundle.json")
    93  	bun, err := cnab.LoadBundle(cfg.Context, "/cnab/bundle.json")
    94  	require.NoError(t, err, "bundle should have been valid")
    95  
    96  	c := New(cfg.Config)
    97  	cb, err := c.StoreBundle(cnab.BundleReference{Reference: kahn1dot01, Definition: bun})
    98  	assert.NoError(t, err, "storing bundle should have succeeded")
    99  
   100  	home, err := cfg.Config.GetHomeDir()
   101  	require.NoError(t, err, "should have had a porter home dir")
   102  	cacheDir := filepath.Join(home, "cache")
   103  	expectedCacheDirectory := filepath.Join(cacheDir, kahn1dot0Hash)
   104  	expectedCacheCNABDirectory := filepath.Join(expectedCacheDirectory, "cnab")
   105  	expectedCacheFile := filepath.Join(expectedCacheCNABDirectory, "bundle.json")
   106  
   107  	assert.Equal(t, expectedCacheFile, cb.BundlePath)
   108  }
   109  
   110  func TestCacheWriteCacheDirExists(t *testing.T) {
   111  	t.Parallel()
   112  
   113  	cfg := config.NewTestConfig(t)
   114  	home, err := cfg.Config.GetHomeDir()
   115  	require.NoError(t, err, "should have had a porter home dir")
   116  	cacheDir := filepath.Join(home, "cache")
   117  	cfg.TestContext.AddTestFile("testdata/cnab/bundle.json", "/cnab/bundle.json")
   118  	cfg.TestContext.AddTestDirectory("testdata", cacheDir)
   119  	bun, err := cnab.LoadBundle(cfg.Context, "/cnab/bundle.json")
   120  	require.NoError(t, err, "bundle should have been valid")
   121  
   122  	c := New(cfg.Config)
   123  	var reloMap relocation.ImageRelocationMap
   124  	bundleRef := cnab.BundleReference{
   125  		Reference:     kahn1dot01,
   126  		Definition:    bun,
   127  		RelocationMap: reloMap,
   128  		Digest:        digest.Digest("sha256:2249472f86d0cea9ac8809331931e9100e1d0464afff3d2869bbb8dedfe2d396"),
   129  	}
   130  	cb, err := c.StoreBundle(bundleRef)
   131  
   132  	expectedCacheDirectory := filepath.Join(cacheDir, kahn1dot0Hash)
   133  	expectedCacheCNABDirectory := filepath.Join(expectedCacheDirectory, "cnab")
   134  	expectedCacheFile := filepath.Join(expectedCacheCNABDirectory, "bundle.json")
   135  
   136  	assert.Equal(t, expectedCacheFile, cb.BundlePath)
   137  	assert.NoError(t, err, "storing bundle should have succeeded")
   138  
   139  	var meta Metadata
   140  	expectedMetaFile := filepath.Join(expectedCacheDirectory, "metadata.json")
   141  	require.NoError(t, encoding.UnmarshalFile(cfg.FileSystem, expectedMetaFile, &meta))
   142  	assert.Equal(t, Metadata{Reference: bundleRef.Reference, Digest: bundleRef.Digest}, meta, "incorrect metadata.json persisted")
   143  }
   144  
   145  func TestStoreRelocationMapping(t *testing.T) {
   146  	home, err := os.UserHomeDir()
   147  	assert.NoError(t, err)
   148  	tests := map[string]struct {
   149  		name              string
   150  		relocationMapping relocation.ImageRelocationMap
   151  		tag               cnab.OCIReference
   152  		bundle            cnab.ExtendedBundle
   153  		wantedReloPath    string
   154  		err               error
   155  	}{
   156  		"relocation file gets a path": {
   157  			bundle: cnab.ExtendedBundle{},
   158  			tag:    kahn1dot01,
   159  			relocationMapping: relocation.ImageRelocationMap{
   160  				"asd": "asdf",
   161  			},
   162  			wantedReloPath: filepath.Join(home+"/.porter/cache", kahn1dot0Hash, "cnab", "relocation-mapping.json"),
   163  		},
   164  		"no relocation file gets no path": {
   165  			tag:            kahnlatest,
   166  			bundle:         cnab.ExtendedBundle{},
   167  			wantedReloPath: "",
   168  		},
   169  	}
   170  
   171  	for name, tc := range tests {
   172  		tc := tc
   173  		t.Run(name, func(t *testing.T) {
   174  			t.Parallel()
   175  
   176  			cfg := config.NewTestConfig(t)
   177  			cfg.SetHomeDir(home + "/.porter")
   178  			c := New(cfg.Config)
   179  			cb, err := c.StoreBundle(cnab.BundleReference{Reference: tc.tag, Definition: tc.bundle, RelocationMap: tc.relocationMapping})
   180  			assert.NoError(t, err, fmt.Sprintf("didn't expect storage error for test %s", tc.name))
   181  			assert.Equal(t, tc.wantedReloPath, cb.RelocationFilePath, "didn't get expected path for store")
   182  
   183  			cb, _, err = c.FindBundle(tc.tag)
   184  			assert.NoError(t, err, "didn't expect find bundle error for test %s", tc.tag)
   185  			assert.Equal(t, tc.wantedReloPath, cb.RelocationFilePath, "didn't get expected path for load")
   186  		})
   187  	}
   188  }
   189  
   190  func TestStoreManifest(t *testing.T) {
   191  	tests := []struct {
   192  		name                string
   193  		tag                 cnab.OCIReference
   194  		bundle              cnab.ExtendedBundle
   195  		shouldCacheManifest bool
   196  		err                 error
   197  	}{
   198  		{
   199  			name: "embedded manifest",
   200  			bundle: cnab.NewBundle(bundle.Bundle{
   201  				Custom: map[string]interface{}{
   202  					"sh.porter": map[string]interface{}{
   203  						"manifest": "bmFtZTogSEVMTE9fQ1VTVE9NCnZlcnNpb246IDAuMS4wCmRlc2NyaXB0aW9uOiAiQSBidW5kbGUgd2l0aCBhIGN1c3RvbSBhY3Rpb24iCnRhZzogZ2V0cG9ydGVyL3BvcnRlci1oZWxsbzp2MC4xLjAKaW52b2NhdGlvbkltYWdlOiBnZXRwb3J0ZXIvcG9ydGVyLWhlbGxvLWluc3RhbGxlcjowLjEuMAoKY3JlZGVudGlhbHM6CiAgLSBuYW1lOiBteS1maXJzdC1jcmVkCiAgICBlbnY6IE1ZX0ZJUlNUX0NSRUQKICAtIG5hbWU6IG15LXNlY29uZC1jcmVkCiAgICBkZXNjcmlwdGlvbjogIk15IHNlY29uZCBjcmVkIgogICAgcGF0aDogL3BhdGgvdG8vbXktc2Vjb25kLWNyZWQKCmltYWdlczogCiAgIHNvbWV0aGluZzoKICAgICAgZGVzY3JpcHRpb246ICJhbiBpbWFnZSIKICAgICAgaW1hZ2VUeXBlOiAiZG9ja2VyIgogICAgICByZXBvc2l0b3J5OiAiZ2V0cG9ydGVyL2JvbyIKCnBhcmFtZXRlcnM6CiAgLSBuYW1lOiBteS1maXJzdC1wYXJhbQogICAgdHlwZTogaW50ZWdlcgogICAgZGVmYXVsdDogOQogICAgZW52OiBNWV9GSVJTVF9QQVJBTQogICAgYXBwbHlUbzoKICAgICAgLSAiaW5zdGFsbCIKICAtIG5hbWU6IG15LXNlY29uZC1wYXJhbQogICAgZGVzY3JpcHRpb246ICJNeSBzZWNvbmQgcGFyYW1ldGVyIgogICAgdHlwZTogc3RyaW5nCiAgICBkZWZhdWx0OiBzcHJpbmctbXVzaWMtZGVtbwogICAgcGF0aDogL3BhdGgvdG8vbXktc2Vjb25kLXBhcmFtCiAgICBzZW5zaXRpdmU6IHRydWUKCm91dHB1dHM6CiAgLSBuYW1lOiBteS1maXJzdC1vdXRwdXQKICAgIHR5cGU6IHN0cmluZwogICAgYXBwbHlUbzoKICAgICAgLSAiaW5zdGFsbCIKICAgICAgLSAidXBncmFkZSIKICAgIHNlbnNpdGl2ZTogdHJ1ZQogIC0gbmFtZTogbXktc2Vjb25kLW91dHB1dAogICAgZGVzY3JpcHRpb246ICJNeSBzZWNvbmQgb3V0cHV0IgogICAgdHlwZTogYm9vbGVhbgogICAgc2Vuc2l0aXZlOiBmYWxzZQogIC0gbmFtZToga3ViZWNvbmZpZwogICAgdHlwZTogZmlsZQogICAgcGF0aDogL3Jvb3QvLmt1YmUvY29uZmlnCgptaXhpbnM6CiAgLSBleGVjCgppbnN0YWxsOgogIC0gZXhlYzoKICAgICAgZGVzY3JpcHRpb246ICJJbnN0YWxsIEhlbGxvIFdvcmxkIgogICAgICBjb21tYW5kOiBiYXNoCiAgICAgIGZsYWdzOgogICAgICAgIGM6IGVjaG8gSGVsbG8gV29ybGQKCnVwZ3JhZGU6CiAgLSBleGVjOgogICAgICBkZXNjcmlwdGlvbjogIldvcmxkIDIuMCIKICAgICAgY29tbWFuZDogYmFzaAogICAgICBmbGFnczoKICAgICAgICBjOiBlY2hvIFdvcmxkIDIuMAoKem9tYmllczoKICAtIGV4ZWM6CiAgICAgIGRlc2NyaXB0aW9uOiAiVHJpZ2dlciB6b21iaWUgYXBvY2FseXBzZSIKICAgICAgY29tbWFuZDogYmFzaAogICAgICBmbGFnczoKICAgICAgICBjOiBlY2hvIG9oIG5vZXMgbXkgYnJhaW5zCgp1bmluc3RhbGw6CiAgLSBleGVjOgogICAgICBkZXNjcmlwdGlvbjogIlVuaW5zdGFsbCBIZWxsbyBXb3JsZCIKICAgICAgY29tbWFuZDogYmFzaAogICAgICBmbGFnczoKICAgICAgICBjOiBlY2hvIEdvb2RieWUgV29ybGQK",
   204  					},
   205  				},
   206  			}),
   207  			tag:                 kahn1dot01,
   208  			shouldCacheManifest: true,
   209  		},
   210  		{
   211  			name: "porter stamp, no manifest",
   212  			bundle: cnab.NewBundle(bundle.Bundle{
   213  				Custom: map[string]interface{}{
   214  					"sh.porter": map[string]interface{}{
   215  						"manifestDigest": "abc123",
   216  					},
   217  				},
   218  			}),
   219  			tag:                 kahn1dot01,
   220  			shouldCacheManifest: false,
   221  		},
   222  		{
   223  			name:   "no embedded manifest",
   224  			tag:    kahnlatest,
   225  			bundle: cnab.ExtendedBundle{},
   226  		},
   227  	}
   228  
   229  	for _, tc := range tests {
   230  		t.Run(tc.name, func(t *testing.T) {
   231  			tc := tc
   232  			t.Parallel()
   233  
   234  			cfg := config.NewTestConfig(t)
   235  			home, _ := cfg.Config.GetHomeDir()
   236  			cacheDir := filepath.Join(home, "cache")
   237  			cfg.TestContext.AddTestDirectory("testdata", cacheDir)
   238  			c := New(cfg.Config)
   239  
   240  			cb, err := c.StoreBundle(cnab.BundleReference{Reference: tc.tag, Definition: tc.bundle})
   241  			require.NoError(t, err, "StoreBundle failed")
   242  
   243  			cachedManifestExists, _ := cfg.FileSystem.Exists(cb.BuildManifestPath())
   244  			if tc.shouldCacheManifest {
   245  				assert.Equal(t, cb.BuildManifestPath(), cb.ManifestPath, "CachedBundle.ManifestPath was not set")
   246  				assert.True(t, cachedManifestExists, "Expected the porter.yaml manifest to be cached but it wasn't")
   247  			} else {
   248  				assert.Empty(t, cb.ManifestPath, "CachedBundle.ManifestPath should not be set for non-porter bundles")
   249  				assert.False(t, cachedManifestExists, "Expected porter.yaml manifest to not be cached but one was cached anyway. Not sure what happened there...")
   250  			}
   251  		})
   252  	}
   253  }
   254  
   255  func TestCache_StoreBundle_Overwrite(t *testing.T) {
   256  	t.Parallel()
   257  	var err error
   258  	cfg := config.NewTestConfig(t)
   259  	home, _ := cfg.Config.GetHomeDir()
   260  	cacheDir := filepath.Join(home, "cache")
   261  	cfg.TestContext.AddTestDirectory("testdata", cacheDir)
   262  	c := New(cfg.Config)
   263  
   264  	// Setup an existing bundle with some extraneous junk that would not
   265  	// be overwritten
   266  	cb := CachedBundle{BundleReference: cnab.BundleReference{Reference: kahn1dot01}}
   267  	cb.SetCacheDir(cacheDir)
   268  	_, err = cfg.FileSystem.Create(cb.BuildManifestPath())
   269  	require.NoError(t, err)
   270  	_, err = cfg.FileSystem.Create(cb.BuildRelocationFilePath())
   271  	require.NoError(t, err)
   272  	junkPath := filepath.Join(cb.cacheDir, "junk.txt")
   273  	_, err = cfg.FileSystem.Create(junkPath)
   274  	require.NoError(t, err)
   275  	// Refresh the cache
   276  	cb, err = c.StoreBundle(cb.BundleReference)
   277  	require.NoError(t, err, "StoreBundle failed")
   278  
   279  	exists, _ := cfg.FileSystem.Exists(cb.BuildBundlePath())
   280  	assert.True(t, exists, "bundle.json should have been written in the refreshed cache")
   281  
   282  	exists, _ = cfg.FileSystem.Exists(cb.BuildManifestPath())
   283  	assert.False(t, exists, "porter.yaml should have been deleted from the bundle cache")
   284  
   285  	exists, _ = cfg.FileSystem.Exists(cb.BuildRelocationFilePath())
   286  	assert.False(t, exists, "relocation-mapping.json should have been deleted from the bundle cache")
   287  
   288  	exists, _ = cfg.FileSystem.Exists(junkPath)
   289  	assert.False(t, exists, "the random file should have been deleted from the bundle cache")
   290  }