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 }