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 }