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

     1  package porter
     2  
     3  import (
     4  	"context"
     5  	"os"
     6  	"testing"
     7  
     8  	"get.porter.sh/porter/pkg/linter"
     9  	"get.porter.sh/porter/pkg/manifest"
    10  	"get.porter.sh/porter/pkg/mixin"
    11  	"get.porter.sh/porter/pkg/yaml"
    12  	"get.porter.sh/porter/tests"
    13  	"github.com/stretchr/testify/assert"
    14  	"github.com/stretchr/testify/require"
    15  )
    16  
    17  func TestPorter_Lint_ChecksManifestSchemaVersion(t *testing.T) {
    18  	testcases := []struct {
    19  		name          string
    20  		schemaVersion string
    21  		wantErr       string
    22  	}{
    23  		{name: "valid version", schemaVersion: manifest.DefaultSchemaVersion.String()},
    24  		{name: "invalid version", schemaVersion: "", wantErr: "invalid schema version"},
    25  	}
    26  	for _, tc := range testcases {
    27  		t.Run(tc.name, func(t *testing.T) {
    28  			p := NewTestPorter(t)
    29  			defer p.Close()
    30  
    31  			// Make a bundle with the specified schemaVersion
    32  			p.TestConfig.TestContext.AddTestFileFromRoot("tests/testdata/mybuns/porter.yaml", "porter.yaml")
    33  			e := yaml.NewEditor(p.FileSystem)
    34  			require.NoError(t, e.ReadFile("porter.yaml"))
    35  			require.NoError(t, e.SetValue("schemaVersion", tc.schemaVersion))
    36  			require.NoError(t, e.WriteFile("porter.yaml"))
    37  
    38  			_, err := p.Lint(context.Background(), LintOptions{File: "porter.yaml"})
    39  			if tc.wantErr == "" {
    40  				require.NoError(t, err, "Lint failed")
    41  			} else {
    42  				tests.RequireErrorContains(t, err, tc.wantErr)
    43  			}
    44  		})
    45  	}
    46  }
    47  
    48  func TestPorter_Lint(t *testing.T) {
    49  	p := NewTestPorter(t)
    50  	defer p.Close()
    51  
    52  	p.TestConfig.TestContext.AddTestFile("testdata/porter.yaml", "porter.yaml")
    53  
    54  	mixins := p.Mixins.(*mixin.TestMixinProvider)
    55  	mixins.LintResults = linter.Results{
    56  		{
    57  			Level: linter.LevelError,
    58  		},
    59  	}
    60  
    61  	var opts LintOptions
    62  	err := opts.Validate(p.Context)
    63  	require.NoError(t, err, "Validate failed")
    64  
    65  	results, err := p.Lint(context.Background(), opts)
    66  	require.NoError(t, err, "Lint failed")
    67  	assert.Len(t, results, 1, "Lint returned the wrong number of results")
    68  }
    69  
    70  func TestPorter_PrintLintResults(t *testing.T) {
    71  	lintResults := linter.Results{
    72  		{
    73  			Level: linter.LevelError,
    74  			Location: linter.Location{
    75  				Action:          "install",
    76  				Mixin:           "exec",
    77  				StepNumber:      2,
    78  				StepDescription: "Install Hello World",
    79  			},
    80  			Code:  "exec-100",
    81  			Title: "bash -c argument missing wrapping quotes",
    82  			Message: `The bash -c flag argument must be wrapped in quotes, for example
    83  exec:
    84    description: Say Hello
    85    command: bash
    86    flags:
    87      c: '"echo Hello World"'
    88  `,
    89  			URL: "https://porter.sh/best-practices/exec-mixin/#quoting-escaping-bash-and-yaml",
    90  		},
    91  	}
    92  
    93  	testcases := []struct {
    94  		format         string
    95  		wantOutputFile string
    96  		linterResults  linter.Results
    97  	}{
    98  		{"plaintext", "testdata/lint/results.txt", lintResults},
    99  		{"json", "testdata/lint/results.json", lintResults},
   100  		{"plaintext", "testdata/lint/success.txt", linter.Results{}},
   101  	}
   102  	for _, tc := range testcases {
   103  		t.Run(tc.format, func(t *testing.T) {
   104  			p := NewTestPorter(t)
   105  			defer p.Close()
   106  
   107  			p.TestConfig.TestContext.AddTestFile("testdata/porter.yaml", "porter.yaml")
   108  
   109  			mixins := p.Mixins.(*mixin.TestMixinProvider)
   110  			mixins.LintResults = tc.linterResults
   111  
   112  			var opts LintOptions
   113  			opts.RawFormat = tc.format
   114  			err := opts.Validate(p.Context)
   115  			require.NoError(t, err, "Validate failed")
   116  
   117  			err = p.PrintLintResults(context.Background(), opts)
   118  			require.NoError(t, err, "PrintLintResults failed")
   119  
   120  			wantOutputB, err := os.ReadFile(tc.wantOutputFile)
   121  			require.NoError(t, err, "Reading output file failed")
   122  			gotOutput := p.TestConfig.TestContext.GetOutput()
   123  			assert.Equal(t, string(wantOutputB), gotOutput, "unexpected output printed")
   124  		})
   125  	}
   126  }
   127  
   128  func TestPorter_PrintLintResults_Warning(t *testing.T) {
   129  	lintResults := linter.Results{
   130  		{
   131  			Level: linter.LevelWarning,
   132  			Location: linter.Location{
   133  				Action:          "install",
   134  				Mixin:           "exec",
   135  				StepNumber:      2,
   136  				StepDescription: "Install Hello World",
   137  			},
   138  			Code:  "exec-100",
   139  			Title: "bash -c argument missing wrapping quotes",
   140  			Message: `The bash -c flag argument must be wrapped in quotes, for example
   141  exec:
   142    description: Say Hello
   143    command: bash
   144    flags:
   145      c: '"echo Hello World"'
   146  `,
   147  			URL: "https://porter.sh/best-practices/exec-mixin/#quoting-escaping-bash-and-yaml",
   148  		},
   149  	}
   150  
   151  	testcases := []struct {
   152  		format         string
   153  		wantOutputFile string
   154  		linterResults  linter.Results
   155  	}{
   156  		{"plaintext", "testdata/lint/results_warning.txt", lintResults},
   157  		{"json", "testdata/lint/results_warning.json", lintResults},
   158  		{"plaintext", "testdata/lint/success.txt", linter.Results{}},
   159  	}
   160  	for _, tc := range testcases {
   161  		t.Run(tc.format, func(t *testing.T) {
   162  			p := NewTestPorter(t)
   163  			defer p.Close()
   164  
   165  			p.TestConfig.TestContext.AddTestFile("testdata/porter.yaml", "porter.yaml")
   166  
   167  			mixins := p.Mixins.(*mixin.TestMixinProvider)
   168  			mixins.LintResults = tc.linterResults
   169  
   170  			var opts LintOptions
   171  			opts.RawFormat = tc.format
   172  			err := opts.Validate(p.Context)
   173  			require.NoError(t, err, "Validate failed")
   174  
   175  			err = p.PrintLintResults(context.Background(), opts)
   176  			require.NoError(t, err, "PrintLintResults failed")
   177  
   178  			wantOutputB, err := os.ReadFile(tc.wantOutputFile)
   179  			require.NoError(t, err, "Reading output file failed")
   180  			gotOutput := p.TestConfig.TestContext.GetOutput()
   181  			assert.Equal(t, string(wantOutputB), gotOutput, "unexpected output printed")
   182  		})
   183  	}
   184  }