get.porter.sh/porter@v1.3.0/pkg/runtime/runtime_test.go (about) 1 package runtime 2 3 import ( 4 "context" 5 "fmt" 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/manifest" 12 "get.porter.sh/porter/pkg/portercontext" 13 "github.com/cnabio/cnab-go/bundle" 14 "github.com/cnabio/cnab-go/bundle/definition" 15 "github.com/stretchr/testify/assert" 16 "github.com/stretchr/testify/require" 17 ) 18 19 func TestPorterRuntime_Execute_readMixinOutputs(t *testing.T) { 20 r := NewTestPorterRuntime(t) 21 22 testFiles := []string{ 23 "emptyoutput", 24 "jsonoutput", 25 "multiliner", 26 "oneliner", 27 } 28 29 for _, testFile := range testFiles { 30 r.TestContext.AddTestFile( 31 fmt.Sprintf("testdata/outputs/%s.txt", testFile), 32 filepath.Join(portercontext.MixinOutputsDir, testFile)) 33 } 34 35 gotOutputs, err := r.readMixinOutputs() 36 require.NoError(t, err) 37 38 for _, testFile := range testFiles { 39 if exists, _ := r.config.FileSystem.Exists(testFile); exists { 40 require.Fail(t, fmt.Sprintf("file %s should not exist after reading outputs", testFile)) 41 } 42 } 43 44 wantOutputs := map[string]string{ 45 "emptyoutput": "", 46 "jsonoutput": `{ 47 "foo": true, 48 "things": [ 49 123, 50 "abc", 51 false 52 ] 53 }`, 54 "multiliner": `FOO 55 56 BAR 57 BAZ`, 58 "oneliner": "ABC", 59 } 60 61 assert.Equal(t, wantOutputs, gotOutputs) 62 } 63 64 func TestPorterRuntime_ApplyStepOutputsToBundle_None(t *testing.T) { 65 r := NewTestPorterRuntime(t) 66 m := &manifest.Manifest{Name: "mybun"} 67 r.RuntimeManifest = r.NewRuntimeManifest(cnab.ActionInstall, m) 68 69 outputs := map[string]string{ 70 "foo": "bar", 71 "123": "abc", 72 } 73 74 err := r.applyStepOutputsToBundle(outputs) 75 assert.NoError(t, err) 76 } 77 78 func TestPorterRuntime_ApplyStepOutputsToBundle_Some_Match(t *testing.T) { 79 r := NewTestPorterRuntime(t) 80 m := &manifest.Manifest{ 81 Name: "mybun", 82 Outputs: manifest.OutputDefinitions{ 83 "foo": { 84 Name: "foo", 85 Schema: definition.Schema{ 86 Type: "string", 87 }, 88 Sensitive: true, 89 }, 90 "123": { 91 Name: "123", 92 Schema: definition.Schema{ 93 Type: "string", 94 }, 95 Sensitive: false, 96 }, 97 }, 98 } 99 r.RuntimeManifest = r.NewRuntimeManifest(cnab.ActionInstall, m) 100 101 outputs := map[string]string{ 102 "foo": "bar", 103 "123": "abc", 104 } 105 106 err := r.applyStepOutputsToBundle(outputs) 107 assert.NoError(t, err) 108 109 want := map[string]string{ 110 "foo": "bar", 111 "123": "abc", 112 } 113 114 for _, outputName := range []string{"foo", "123"} { 115 bytes, err := r.config.FileSystem.ReadFile(filepath.Join(config.BundleOutputsDir, outputName)) 116 assert.NoError(t, err) 117 118 assert.Equal(t, want[outputName], string(bytes)) 119 } 120 } 121 122 func TestPorterRuntime_ApplyStepOutputsToBundle_Some_NoMatch(t *testing.T) { 123 r := NewTestPorterRuntime(t) 124 m := &manifest.Manifest{ 125 Name: "mybun", 126 Outputs: manifest.OutputDefinitions{ 127 "bar": { 128 Name: "bar", 129 }, 130 "456": { 131 Name: "456", 132 }, 133 }, 134 } 135 r.RuntimeManifest = r.NewRuntimeManifest(cnab.ActionInstall, m) 136 137 outputs := map[string]string{ 138 "foo": "bar", 139 "123": "abc", 140 } 141 142 err := r.applyStepOutputsToBundle(outputs) 143 assert.NoError(t, err) 144 145 // No outputs declared in the manifest match those in outputs, 146 // so no output file is expected to be written 147 for _, output := range []string{"foo", "bar", "123", "456"} { 148 _, err := r.config.FileSystem.ReadFile(filepath.Join(config.BundleOutputsDir, output)) 149 assert.Error(t, err) 150 } 151 } 152 153 func TestPorterRuntime_ApplyStepOutputsToBundle_ApplyTo_True(t *testing.T) { 154 r := NewTestPorterRuntime(t) 155 m := &manifest.Manifest{ 156 Name: "mybun", 157 Outputs: manifest.OutputDefinitions{ 158 "foo": { 159 Name: "foo", 160 ApplyTo: []string{ 161 "upgrade", 162 }, 163 }, 164 "123": { 165 Name: "123", 166 ApplyTo: []string{ 167 "install", 168 }, 169 Schema: definition.Schema{ 170 Type: "string", 171 }, 172 Sensitive: false, 173 }, 174 }, 175 } 176 r.RuntimeManifest = r.NewRuntimeManifest(cnab.ActionInstall, m) 177 178 outputs := map[string]string{ 179 "foo": "bar", 180 "123": "abc", 181 } 182 183 err := r.applyStepOutputsToBundle(outputs) 184 assert.NoError(t, err) 185 186 // foo output should not exist (applyTo doesn't match) 187 _, err = r.config.FileSystem.ReadFile(filepath.Join(config.BundleOutputsDir, "foo")) 188 assert.Error(t, err) 189 190 // 123 output should exist (applyTo matches) 191 bytes, err := r.config.FileSystem.ReadFile(filepath.Join(config.BundleOutputsDir, "123")) 192 assert.NoError(t, err) 193 194 want := "abc" 195 assert.Equal(t, want, string(bytes)) 196 } 197 198 func TestRuntimeManifest_ApplyUnboundBundleOutputs_File(t *testing.T) { 199 const srcPath = "/home/nonroot/.kube/config" 200 const outputName = "kubeconfig" 201 202 ctx := context.Background() 203 testcases := []struct { 204 name string 205 shouldBind bool 206 def manifest.OutputDefinition 207 }{ 208 {name: "file with applyto", 209 shouldBind: true, 210 def: manifest.OutputDefinition{ 211 Name: outputName, 212 ApplyTo: []string{ 213 "install", 214 }, 215 Schema: definition.Schema{ 216 Type: "file", 217 }, 218 Path: srcPath, 219 }, 220 }, 221 {name: "file no applyto", 222 shouldBind: true, 223 def: manifest.OutputDefinition{ 224 Name: outputName, 225 Schema: definition.Schema{ 226 Type: "file", 227 }, 228 Path: srcPath, 229 }, 230 }, 231 {name: "not file", 232 shouldBind: true, 233 def: manifest.OutputDefinition{ 234 Name: outputName, 235 Schema: definition.Schema{ 236 Type: "string", 237 }, 238 Path: srcPath, 239 }, 240 }, 241 {name: "file no path", 242 shouldBind: false, 243 def: manifest.OutputDefinition{ 244 Name: outputName, 245 Schema: definition.Schema{ 246 Type: "string", 247 }, 248 Path: "", 249 }, 250 }, 251 } 252 253 for _, tc := range testcases { 254 t.Run(tc.name, func(t *testing.T) { 255 m := &manifest.Manifest{ 256 Name: "mybun", 257 Outputs: manifest.OutputDefinitions{ 258 tc.def.Name: tc.def, 259 }, 260 } 261 cfg := NewConfigFor(config.NewTestConfig(t).Config) 262 rm := NewRuntimeManifest(cfg, cnab.ActionInstall, m) 263 rm.bundle = cnab.NewBundle(bundle.Bundle{ 264 Definitions: map[string]*definition.Schema{ 265 tc.def.Name: &tc.def.Schema, 266 }, 267 Outputs: map[string]bundle.Output{ 268 tc.def.Name: { 269 Definition: tc.def.Name, 270 Path: tc.def.Path, 271 }, 272 }, 273 }) 274 275 _, err := rm.config.FileSystem.Create(srcPath) 276 require.NoError(t, err) 277 278 err = rm.applyUnboundBundleOutputs(ctx) 279 require.NoError(t, err) 280 281 exists, _ := rm.config.FileSystem.Exists("/cnab/app/outputs/" + outputName) 282 assert.Equal(t, exists, tc.shouldBind) 283 }) 284 } 285 } 286 287 func TestPorterRuntime_LoadImageMappingFilesNoRelo(t *testing.T) { 288 r := NewTestPorterRuntime(t) 289 r.TestContext.AddTestFile("testdata/bundle-images.json", "/cnab/bundle.json") 290 bun, reloMap, err := r.getImageMappingFiles() 291 assert.NoError(t, err) 292 assert.Empty(t, reloMap) 293 assert.Equal(t, "mysql", bun.Name) 294 } 295 296 func TestLoadImageMappingFilesNoBundle(t *testing.T) { 297 r := NewTestPorterRuntime(t) 298 r.TestContext.AddTestFile("testdata/relocation-mapping.json", "/cnab/app/relocation-mapping.json") 299 _, _, err := r.getImageMappingFiles() 300 require.Error(t, err) 301 assert.Contains(t, err.Error(), "cannot read bundle") 302 } 303 304 func TestLoadImageMappingFilesBadBundle(t *testing.T) { 305 r := NewTestPorterRuntime(t) 306 r.TestContext.AddTestFileFromRoot("pkg/porter/testdata/porter.yaml", "/cnab/bundle.json") 307 r.TestContext.AddTestFile("testdata/relocation-mapping.json", "/cnab/app/relocation-mapping.json") 308 _, _, err := r.getImageMappingFiles() 309 require.Error(t, err) 310 assert.Contains(t, err.Error(), "cannot load bundle") 311 } 312 313 func TestLoadImageMappingFilesGoodFiles(t *testing.T) { 314 r := NewTestPorterRuntime(t) 315 r.TestContext.AddTestFile("testdata/bundle-images.json", "/cnab/bundle.json") 316 r.TestContext.AddTestFile("testdata/relocation-mapping.json", "/cnab/app/relocation-mapping.json") 317 318 bun, reloMap, err := r.getImageMappingFiles() 319 assert.NoError(t, err) 320 assert.NotEmpty(t, reloMap) 321 assert.Equal(t, "mysql", bun.Name) 322 }