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  }