get.porter.sh/porter@v1.3.0/pkg/porter/cnab_test.go (about) 1 package porter 2 3 import ( 4 "fmt" 5 "path/filepath" 6 "testing" 7 8 "get.porter.sh/porter/pkg" 9 "get.porter.sh/porter/pkg/build" 10 "get.porter.sh/porter/pkg/config" 11 "get.porter.sh/porter/pkg/portercontext" 12 "github.com/stretchr/testify/assert" 13 "github.com/stretchr/testify/require" 14 ) 15 16 func TestSharedOptions_defaultBundleFiles(t *testing.T) { 17 cxt := portercontext.NewTestContext(t) 18 19 _, err := cxt.FileSystem.Create("porter.yaml") 20 require.NoError(t, err) 21 22 opts := installationOptions{} 23 err = opts.defaultBundleFiles(cxt.Context) 24 require.NoError(t, err) 25 26 assert.Equal(t, "porter.yaml", opts.File) 27 assert.Equal(t, filepath.FromSlash(".cnab/bundle.json"), opts.CNABFile) 28 } 29 30 func TestSharedOptions_defaultBundleFiles_AltManifest(t *testing.T) { 31 cxt := portercontext.NewTestContext(t) 32 33 opts := installationOptions{ 34 BundleDefinitionOptions: BundleDefinitionOptions{ 35 File: "mybun/porter.yaml", 36 }, 37 } 38 err := opts.defaultBundleFiles(cxt.Context) 39 require.NoError(t, err) 40 41 assert.Equal(t, filepath.FromSlash(".cnab/bundle.json"), opts.CNABFile) 42 } 43 44 func TestSharedOptions_defaultBundleFiles_CNABFile(t *testing.T) { 45 cxt := portercontext.NewTestContext(t) 46 47 // Add existing porter manifest; ensure it isn't processed when cnab-file is spec'd 48 _, err := cxt.FileSystem.Create("porter.yaml") 49 require.NoError(t, err) 50 _, err = cxt.FileSystem.Create("mycnabfile.json") 51 require.NoError(t, err) 52 53 opts := installationOptions{} 54 opts.CNABFile = "mycnabfile.json" 55 err = opts.defaultBundleFiles(cxt.Context) 56 require.NoError(t, err) 57 58 assert.Equal(t, "", opts.File) 59 assert.Equal(t, "mycnabfile.json", opts.CNABFile) 60 } 61 62 func TestSharedOptions_validateBundleJson(t *testing.T) { 63 cxt := portercontext.NewTestContext(t) 64 65 _, err := cxt.FileSystem.Create("mybun1/bundle.json") 66 require.NoError(t, err) 67 _, err = cxt.FileSystem.Create("bundle1.json") 68 require.NoError(t, err) 69 70 testcases := []struct { 71 name string 72 cnabFile string 73 wantBundleJson string 74 wantError string 75 }{ 76 {name: "absolute file exists", cnabFile: "/mybun1/bundle.json", wantBundleJson: "/mybun1/bundle.json", wantError: ""}, 77 {name: "relative file exists", cnabFile: "bundle1.json", wantBundleJson: "/bundle1.json", wantError: ""}, 78 {name: "absolute file does not exist", cnabFile: "mybun2/bundle.json", wantError: "unable to access --cnab-file mybun2/bundle.json"}, 79 {name: "relative file does not", cnabFile: "bundle2.json", wantError: "unable to access --cnab-file bundle2.json"}, 80 } 81 82 for _, tc := range testcases { 83 t.Run(tc.name, func(t *testing.T) { 84 opts := installationOptions{ 85 BundleDefinitionOptions: BundleDefinitionOptions{ 86 CNABFile: tc.cnabFile, 87 }, 88 } 89 90 err := opts.validateCNABFile(cxt.Context) 91 92 if tc.wantError == "" { 93 require.NoError(t, err) 94 wantBundleJsonAbs, err := filepath.Abs(tc.wantBundleJson) 95 require.NoError(t, err) 96 assert.Equal(t, wantBundleJsonAbs, opts.CNABFile) 97 } else { 98 require.Error(t, err) 99 assert.Contains(t, err.Error(), tc.wantError) 100 } 101 }) 102 } 103 } 104 105 func Test_bundleFileOptions(t *testing.T) { 106 absWantFile := absOSFilepath(t, "/"+config.Name) 107 absWantCNABFile := absOSFilepath(t, "/"+build.LOCAL_BUNDLE) 108 absPathToBundle := absOSFilepath(t, "/path/to/bundle") 109 110 testcases := []struct { 111 name string 112 opts BundleDefinitionOptions 113 setup func(*portercontext.Context, BundleDefinitionOptions) error 114 wantFile string 115 wantCNABFile string 116 wantError string 117 }{ 118 { 119 name: "no opts", 120 opts: BundleDefinitionOptions{}, 121 setup: func(ctx *portercontext.Context, opts BundleDefinitionOptions) error { return nil }, 122 wantFile: absWantFile, 123 wantCNABFile: absWantCNABFile, 124 wantError: "", 125 }, { 126 name: "reference set", 127 opts: BundleDefinitionOptions{ 128 ReferenceSet: true, 129 }, 130 setup: func(ctx *portercontext.Context, opts BundleDefinitionOptions) error { return nil }, 131 wantFile: "", 132 wantCNABFile: "", 133 wantError: "", 134 }, { 135 name: "invalid dir", 136 opts: BundleDefinitionOptions{ 137 Dir: filepath.FromSlash("path/to/bundle"), 138 }, 139 setup: func(ctx *portercontext.Context, opts BundleDefinitionOptions) error { return nil }, 140 wantFile: "", 141 wantCNABFile: "", 142 wantError: fmt.Sprintf("%q is not a valid directory: open %s: file does not exist", filepath.FromSlash("path/to/bundle"), absPathToBundle), 143 }, { 144 name: "invalid file", 145 opts: BundleDefinitionOptions{ 146 File: "alternate/porter.yaml", 147 }, 148 setup: func(ctx *portercontext.Context, opts BundleDefinitionOptions) error { return nil }, 149 wantFile: "", 150 wantCNABFile: "", 151 wantError: fmt.Sprintf("unable to access --file %s: open %s: file does not exist", absOSFilepath(t, "/alternate/porter.yaml"), absOSFilepath(t, "/alternate/porter.yaml")), 152 }, { 153 name: "valid dir", 154 opts: BundleDefinitionOptions{ 155 Dir: absOSFilepath(t, "/path/to/bundle"), 156 }, 157 setup: func(ctx *portercontext.Context, opts BundleDefinitionOptions) error { 158 err := ctx.FileSystem.MkdirAll(filepath.Join(opts.Dir, config.Name), pkg.FileModeDirectory) 159 if err != nil { 160 return err 161 } 162 return ctx.FileSystem.MkdirAll(opts.Dir, pkg.FileModeDirectory) 163 }, 164 wantFile: absOSFilepath(t, "/path/to/bundle/porter.yaml"), 165 wantCNABFile: absOSFilepath(t, "/path/to/bundle/.cnab/bundle.json"), 166 wantError: "", 167 }, { 168 name: "valid file", 169 opts: BundleDefinitionOptions{ 170 File: "alternate/porter.yaml", 171 }, 172 setup: func(ctx *portercontext.Context, opts BundleDefinitionOptions) error { 173 return ctx.FileSystem.MkdirAll(opts.File, pkg.FileModeDirectory) 174 }, 175 wantFile: absOSFilepath(t, "/alternate/porter.yaml"), 176 wantCNABFile: absOSFilepath(t, "/"+build.LOCAL_BUNDLE), 177 wantError: "", 178 }, { 179 name: "valid dir and file", 180 opts: BundleDefinitionOptions{ 181 Dir: absOSFilepath(t, "/path/to/bundle"), 182 File: filepath.FromSlash("alternate/porter.yaml"), 183 }, 184 setup: func(ctx *portercontext.Context, opts BundleDefinitionOptions) error { 185 err := ctx.FileSystem.MkdirAll(filepath.Join(opts.Dir, opts.File), pkg.FileModeDirectory) 186 if err != nil { 187 return err 188 } 189 return ctx.FileSystem.MkdirAll(opts.Dir, pkg.FileModeDirectory) 190 }, 191 wantFile: absOSFilepath(t, "/path/to/bundle/alternate/porter.yaml"), 192 wantCNABFile: absOSFilepath(t, "/path/to/bundle/.cnab/bundle.json"), 193 wantError: "", 194 }} 195 196 for _, tc := range testcases { 197 t.Run(tc.name, func(t *testing.T) { 198 cxt := portercontext.NewTestContext(t) 199 200 // Create default local manifest 201 _, err := cxt.FileSystem.Create(config.Name) 202 require.NoError(t, err) 203 204 err = tc.setup(cxt.Context, tc.opts) 205 require.NoError(t, err) 206 207 err = tc.opts.Validate(cxt.Context) 208 if tc.wantError != "" { 209 require.EqualError(t, err, tc.wantError) 210 } else { 211 require.NoError(t, err) 212 213 require.Equal(t, tc.wantFile, tc.opts.File) 214 require.Equal(t, tc.wantCNABFile, tc.opts.CNABFile) 215 216 // Working Dir assertions 217 wd := cxt.FileSystem.Getwd() 218 if tc.opts.Dir != "" && tc.wantError == "" { 219 require.Equal(t, tc.opts.Dir, wd) 220 } else { 221 path := absOSFilepath(t, "/") 222 require.Equal(t, path, wd) 223 } 224 } 225 }) 226 } 227 } 228 229 func absOSFilepath(t *testing.T, path string) string { 230 result, err := filepath.Abs(filepath.FromSlash(path)) 231 require.NoError(t, err) 232 return result 233 }